Exemple #1
0
    public Bitmap make_image(List <double[]> data)
    {
        Console.Out.WriteLine("Generating image");

        int height = data.Count;
        int width  = data[0].Length;

        Console.Write("image size: ");
        Console.Write(width);
        Console.Write(" x ");
        Console.Write(height);
        Console.Write("\n");

        Bitmap @out = new Bitmap(width, height);

        BrightCorrection correction = BrightCorrection.BRIGHT_NONE;

        for (int y = 0; y < height; ++y)
        {
            Debug.Assert(data[y].Length == width);

            for (int x = 0; x < width; ++x)
            {
                double intensity = GlobalMembersSpectrogram.calc_intensity(data[y][x], intensity_axis);
                intensity = GlobalMembersSpectrogram.brightness_correction(intensity, correction);
                @out.SetPixel(x, (int)(height - 1 - y), palette.get_color(intensity));
            }
        }

        //@out.SetText("Spectrogram", serialized()); // save parameters
        return(@out);
    }
Exemple #2
0
    public static double window_coef(double x, Window window)
    {
        Debug.Assert(x >= 0 && x <= 1);

        if (window == Window.WINDOW_RECTANGULAR)
        {
            return(1.0);
        }
        switch (window)
        {
        case Window.WINDOW_HANN:
            return(GlobalMembersSpectrogram.hann_window(x));

        case Window.WINDOW_BLACKMAN:
            return(GlobalMembersSpectrogram.blackman_window(x));

        case Window.WINDOW_TRIANGULAR:
            return(GlobalMembersSpectrogram.triangular_window(x));

        default:
            Debug.Assert(false);
            break;
        }
        return(0.0);
    }
Exemple #3
0
 public double[] envelope_from_spectrogram(Bitmap image, int row)
 {
     double[] envelope = new double[image.Width];
     for (int x = 0; x < image.Width; ++x)
     {
         envelope[x] = GlobalMembersSpectrogram.calc_intensity_inv(
             palette.get_intensity(image.GetPixel(x, image.Height - row - 1)), intensity_axis);
     }
     return(envelope);
 }
Exemple #4
0
    public LogFilterbank(double scale, double @base, double centsperband, double overlap)
    {
        scale_        = scale;
        centsperband_ = centsperband;
        logstart_     = GlobalMembersSpectrogram.freq2cent(@base);
        logstep_      = (1 - overlap) * centsperband_;

        Console.Out.WriteLine("centsperband_: {0}", centsperband_);
        Console.Out.WriteLine("logstep_: {0}", logstep_);
        Debug.Assert(logstep_ > 0);
    }
Exemple #5
0
 public static Complex[] get_pink_noise(int size)
 {
     Complex[] res = new Complex[size];
     for (int i = 0; i < (size + 1) / 2; ++i)
     {
         double  mag     = Math.Pow((double)i, -0.5f);
         double  phase   = (2 * GlobalMembersSpectrogram.random_double() - 1) * Math.PI;       //+-pi random phase
         Complex complex = new Complex(mag * Math.Cos(phase), mag * Math.Sin(phase));
         res[i] = complex;
     }
     return(res);
 }
Exemple #6
0
    public override Pair <int, int> get_band(int i)
    {
        double          logcenter = logstart_ + i * logstep_;
        double          loglow    = logcenter - centsperband_ / 2.0;
        double          loghigh   = loglow + centsperband_;
        Pair <int, int> @out      = new Pair <int, int>();

        @out.First  = (int)(GlobalMembersSpectrogram.cent2freq(loglow) * scale_);
        @out.Second = (int)(GlobalMembersSpectrogram.cent2freq(loghigh) * scale_);

        Console.Out.WriteLine("centerfreq: {0}", GlobalMembersSpectrogram.cent2freq(logcenter));
        Console.Out.WriteLine("lowfreq: {0}, highfreq: {1}", GlobalMembersSpectrogram.cent2freq(loglow), GlobalMembersSpectrogram.cent2freq(loghigh));
        return(@out);
    }
Exemple #7
0
    public static double calc_intensity_inv(double val, AxisScale intensity_axis)
    {
        Debug.Assert(val >= 0 && val <= 1);
        switch (intensity_axis)
        {
        case AxisScale.SCALE_LOGARITHMIC:
            return(GlobalMembersSpectrogram.log10scale_inv(val));

        case AxisScale.SCALE_LINEAR:
            return(val);

        default:
            Debug.Assert(false);
            break;
        }
        return(0.0);
    }
Exemple #8
0
    public double[] synt_noise(Bitmap image, int samplerate)
    {
        int samples = (int)image.Width * samplerate / pixpersec;

        Complex[] noise = GlobalMembersSpectrogram.get_pink_noise(samplerate * 10);        // 10 sec loop

        double     filterscale = ((double)noise.Length * 2) / samplerate;
        Filterbank filterbank  = Filterbank.get_filterbank(frequency_axis, filterscale, basefreq, bandwidth, overlap);

        int top_index = (int)(maxfreq * filterscale);

        double[] @out = new double[samples];

        for (int bandidx = 0; bandidx < image.Height; ++bandidx)
        {
            //if (cancelled())
            //	return List<int>();
            band_progress(bandidx, image.Height - 1);

            // filter noise
            Pair <int, int> range = filterbank.get_band(bandidx);
            //std::cout << bandidx << "/"<<image.height()<<"\n";
            Console.Out.WriteLine("(noise) sample: {0}", range.Second - range.First);

            double[] filtered_noise = new double[noise.Length];
            //std.copy(noise.begin()+range.first, noise.begin()+Math.Min(range.second, top_index), filtered_noise.begin()+range.first);

            // ifft noise
            double[] noise_mod = GlobalMembersSpectrogram.padded_IFFT(filtered_noise);

            // resample spectrogram band
            double[] envelope = GlobalMembersSpectrogram.resample(envelope_from_spectrogram(image, bandidx), samples);

            // modulate with looped noise
            for (uint i = 0; i < samples; ++i)
            {
                @out[i] += envelope[i] * noise_mod[i % noise_mod.Length];
            }
        }

        GlobalMembersSpectrogram.normalize_signal(ref @out);
        return(@out);
    }
Exemple #9
0
    public void apply_window(ref Complex[] chunk, int lowidx, double filterscale)
    {
        int highidx = lowidx + chunk.Length;

        if (frequency_axis == AxisScale.SCALE_LINEAR)
        {
            for (int i = 0; i < chunk.Length; ++i)
            {
                chunk[i] *= GlobalMembersSpectrogram.window_coef((double)i / (chunk.Length - 1), window);
            }
        }
        else
        {
            double rloglow  = GlobalMembersSpectrogram.freq2cent(lowidx / filterscale);          // after rounding
            double rloghigh = GlobalMembersSpectrogram.freq2cent((highidx - 1) / filterscale);
            for (int i = 0; i < chunk.Length; ++i)
            {
                double logidx = GlobalMembersSpectrogram.freq2cent((lowidx + i) / filterscale);
                double winidx = (logidx - rloglow) / (rloghigh - rloglow);
                chunk[i] *= GlobalMembersSpectrogram.window_coef(winidx, window);
            }
        }
    }
Exemple #10
0
    public override double get_center(int i)
    {
        double logcenter = logstart_ + i * logstep_;

        return(GlobalMembersSpectrogram.cent2freq(logcenter) * scale_);
    }
Exemple #11
0
 public override double num_bands_est(double maxfreq)
 {
     return((GlobalMembersSpectrogram.freq2cent(maxfreq) - logstart_) / logstep_ + 4);
 }
Exemple #12
0
    public double[] synt_sine(Bitmap image, int samplerate)
    {
        int samples = image.Width * samplerate / pixpersec;

        Complex[] spectrum = new Complex[samples / 2 + 1];

        double filterscale = ((double)spectrum.Length * 2) / samplerate;

        Filterbank filterbank = Filterbank.get_filterbank(frequency_axis, filterscale, basefreq, bandwidth, overlap);

        for (int bandidx = 0; bandidx < image.Height; ++bandidx)
        {
            //if (cancelled())
            //	return List<int>();
            band_progress(bandidx, image.Height - 1);

            double[] envelope = envelope_from_spectrogram(image, bandidx);

            // random phase between +-pi
            double phase = (2 * GlobalMembersSpectrogram.random_double() - 1) * Math.PI;

            double[] bandsignal = new double[envelope.Length * 2];
            for (int j = 0; j < 4; ++j)
            {
                double sine = Math.Cos(j * Math.PI / 2 + phase);
                for (int i = j; i < bandsignal.Length; i += 4)
                {
                    bandsignal[i] = envelope[i / 2] * sine;
                }
            }

            Complex[] filterband = GlobalMembersSpectrogram.padded_FFT(bandsignal);

            for (int i = 0; i < filterband.Length; ++i)
            {
                double x = (double)i / filterband.Length;

                // normalized blackman window antiderivative
                filterband[i] *= x - ((0.5 / (2.0 * Math.PI)) * Math.Sin(2.0 * Math.PI * x) + (0.08 / (4.0 * Math.PI)) * Math.Sin(4.0 * Math.PI * x) / 0.42);
            }

            Console.Out.WriteLine("spectrum size: {0}", spectrum.Length);
            //std::cout << bandidx << ". filterband size: " << filterband.Length << "; start: " << filterbank->get_band(bandidx).first <<"; end: " << filterbank->get_band(bandidx).second << "\n";

            double center = filterbank.get_center(bandidx);
            double offset = Math.Max((uint)0, center - filterband.Length / 2);

            Console.Out.WriteLine("offset: {0} = {1} hz", offset, offset / filterscale);

            for (uint i = 0; i < filterband.Length; ++i)
            {
                if (offset + i > 0 && offset + i < spectrum.Length)
                {
                    spectrum[(int)(offset + i)] += filterband[i];
                }
            }
        }

        double[] @out = GlobalMembersSpectrogram.padded_IFFT(spectrum);

        Console.Out.WriteLine("samples: {0} -> {1}", @out.Length, samples);

        GlobalMembersSpectrogram.normalize_signal(ref @out);
        return(@out);
    }
Exemple #13
0
    public Bitmap to_image(ref double[] signal, int samplerate)
    {
        Console.Out.WriteLine("Transforming input");

        Complex[] spectrum = GlobalMembersSpectrogram.padded_FFT(signal);

        //const size_t width = (spectrum.size()-1)*2*pixpersec/samplerate;
        double w1    = spectrum.Length - 1;
        double w2    = (double)pixpersec / (double)samplerate;
        double w3    = w1 * 2 * w2;
        int    width = (int)w3;

        // transformation of frequency in hz to index in spectrum
        //const double filterscale = ((double)spectrum.size()*2)/samplerate;
        double filterscale = ((double)spectrum.Length * 2) / samplerate;

        Console.Out.WriteLine("filterscale: {0}", filterscale);

        Filterbank filterbank = Filterbank.get_filterbank(frequency_axis, filterscale, basefreq, bandwidth, overlap);
        int        bands      = (int)filterbank.num_bands_est(maxfreq);
        int        top_index  = (int)(maxfreq * filterscale);

        // maxfreq has to be at most nyquist
        Debug.Assert(top_index <= spectrum.Length);

        //std::vector<real_vec> image_data;
        List <double[]> image_data = new List <double[]>();

        for (int bandidx = 0;; ++bandidx)
        {
            band_progress(bandidx, bands);

            // filtering
            Pair <int, int> range = filterbank.get_band(bandidx);

            Console.Out.WriteLine("-----");
            Console.Out.WriteLine("spectrum size: {0}", spectrum.Length);
            Console.Out.WriteLine("lowidx: {0:0.00} highidx: {1:0.00}", range.First, range.Second);
            Console.Out.WriteLine("(real)lowfreq: {0:0.00} (real)highfreq: {1:0.00}", range.First / filterscale, range.Second / filterscale);
            Console.Out.WriteLine("actual width: {0:0.00} hz", (range.Second - range.First) / filterscale);
            Console.Out.WriteLine("vertical values: {0:0.00}", (range.Second - range.First));
            Console.Out.WriteLine("crowd sample: {0:0.00}", (range.Second - range.First - 1) * 2);
            Console.Out.WriteLine("theoretically staci: {0:0.00} hz samplerate", 2 * (range.Second - range.First) / filterscale);
            Console.Out.WriteLine("width: {0}", width);

            int       filterbandLength = range.Second - range.First;
            Complex[] filterband       = new Complex[filterbandLength];
            //std::copy(spectrum.begin()+range.first,
            //          spectrum.begin()+std::min(range.second, top_index),
            //          filterband.begin());
            int sourceIndexStart = range.First;
            int sourceIndexEnd   = Math.Min(range.Second, top_index);
            int length           = sourceIndexEnd - sourceIndexStart;
            Array.Copy(spectrum, sourceIndexStart, filterband, 0, length);

            if (range.First > top_index)
            {
                break;
            }
            if (range.Second > top_index)
            {
                int start = top_index - range.First;
                //std::fill(filterband.begin()+top_index-range.first,
                //          filterband.end(), Complex(0,0));
                break;                 // TODO: fix above
            }

            // windowing
            apply_window(ref filterband, range.First, filterscale);

            // envelope detection + resampling
            double[] envelope = GlobalMembersSpectrogram.resample(GlobalMembersSpectrogram.get_envelope(ref filterband), width);

            image_data.Add(envelope);
        }

        GlobalMembersSpectrogram.normalize_image_cutoff_negative(ref image_data);

        return(make_image(image_data));
    }