示例#1
0
 public void SetParameters(float[] timeDomain, ref Spectrograms s, int res, int maxwidth)
 {
     m_in     = timeDomain;
     m_s      = s;
     m_res    = res;
     m_maxwid = maxwidth;
 }
示例#2
0
        protected void Assemble(Spectrograms s, Cutting cutting, ref double[][] rmat, int x, int y, int w, int h)
        {
            switch (cutting.cut)
            {
            case Cutting.Cut.Finished:
                for (int i = 0; i < w; ++i)
                {
                    for (int j = 0; j < h; ++j)
                    {
                        rmat[x + i][y + j] = cutting.value;
                    }
                }
                return;

            case Cutting.Cut.Horizontal:
                Assemble(s, cutting.first, ref rmat, x, y, w / 2, h);
                Assemble(s, cutting.second, ref rmat, x + w / 2, y, w / 2, h);
                break;

            case Cutting.Cut.Vertical:
                Assemble(s, cutting.first, ref rmat, x, y + h / 2, w, h / 2);
                Assemble(s, cutting.second, ref rmat, x, y, w, h / 2);
                break;
            }
        }
示例#3
0
            public void StartCalculation(float[] timeDomain, ref Spectrograms s, int res, int maxwidth)
            {
                SetParameters(timeDomain, ref s, res, maxwidth);
                //startTask();

                task = new Task(PerformTask);
                task.Start();
            }
示例#4
0
            public void Cut(Spectrograms s, int res, int x, int y, int h)
            {
                m_s   = s;
                m_res = res;
                m_x   = x;
                m_y   = y;
                m_h   = h;

                task = new Task(PerformTask);
                task.Start();
                //task = Task.Factory.StartNew(PerformTask);
                // startTask();
            }
示例#5
0
        protected bool IsResolutionWanted(Spectrograms s, int res)
        {
            if (!m_coarse)
            {
                return(true);
            }
            if (res == s.minres || res == s.maxres)
            {
                return(true);
            }
            int n = 0;

            for (int r = res; r > s.minres; r >>= 1)
            {
                ++n;
            }
            return((n & 0x1) == 0);
        }
示例#6
0
        protected void GetSubCuts(Spectrograms s, int res, int x, int y, int h, ref Cutting top, ref Cutting bottom, ref Cutting left, ref Cutting right)
        {
            if (m_threaded && !m_threadsInUse)
            {
                m_threadsInUse = true;

                if (m_cutThreads.Count == 0)
                {
                    for (int i = 0; i < 4; ++i)
                    {
                        var t = new CutThread(this);
                        m_cutThreads.Add(t);
                    }
                }

                // Cut threads 0 and 1 calculate the top and bottom halves;
                // threads 2 and 3 calculate left and right. See notes in
                // unthreaded code below for more information.

                if (top != null)
                {
                    m_cutThreads[0].Cut(s, res, x, y + h / 2, h / 2);
                }
                if (bottom != null)
                {
                    m_cutThreads[1].Cut(s, res, x, y, h / 2);
                }
                if (left != null)
                {
                    m_cutThreads[2].Cut(s, res / 2, 2 * x, y / 2, h / 2);
                }
                if (right != null)
                {
                    m_cutThreads[3].Cut(s, res / 2, 2 * x + 1, y / 2, h / 2);
                }


                // you shouldn't get here before all the cut threads have finished

                if (top != null)
                {
                    top = m_cutThreads[0].Get();
                }
                if (bottom != null)
                {
                    bottom = m_cutThreads[1].Get();
                }
                if (left != null)
                {
                    left = m_cutThreads[2].Get();
                }
                if (right != null)
                {
                    right = m_cutThreads[3].Get();
                }
            }
            else
            {
                // Unthreaded version

                // The "vertical" division is a top/bottom split.
                // Splitting this way keeps us in the same resolution,
                // but with two vertical subregions of height h/2.

                if (top != null)
                {
                    top = Cut(s, res, x, y + h / 2, h / 2);
                }

                if (bottom != null)
                {
                    bottom = Cut(s, res, x, y, h / 2);
                }

                // The "horizontal" division is a left/right split.
                // Splitting this way places us in resolution res/2, which has lower
                // vertical resolution but higher horizontal resolution.
                // We need to double x accordingly.

                if (left != null)
                {
                    left = Cut(s, res / 2, 2 * x, y / 2, h / 2);
                }

                if (right != null)
                {
                    right = Cut(s, res / 2, 2 * x + 1, y / 2, h / 2);
                }
            }
        }
示例#7
0
        // recursively cut the spectrogram into small pieces
        protected Cutting Cut(Spectrograms s, int res, int x, int y, int h)
        {
                        #if DEBUGVERBOSE
            Console.WriteLine("res = {0}, x = {1}, y = {2}, h = {3}", res, x, y, h);
                        #endif

            var cutting = new Cutting();

            if (h > 1 && res > s.minres)
            {
                if (!IsResolutionWanted(s, res))
                {
                    var left  = new Cutting();
                    var right = new Cutting();
                    //GetSubCuts(s, res, x, y, h, null, null, ref left, ref right);

                    double hcost   = left.cost + right.cost;
                    double henergy = left.value + right.value;
                    hcost = Normalize(hcost, henergy);

                    cutting.cut    = Cutting.Cut.Horizontal;
                    cutting.first  = left;
                    cutting.second = right;
                    cutting.cost   = hcost;
                    cutting.value  = left.value + right.value;
                }
                else if (h == 2 && !IsResolutionWanted(s, res / 2))
                {
                    var top    = new Cutting();
                    var bottom = new Cutting();
                    //GetSubCuts(s, res, x, y, h, ref top, ref bottom, null, null);

                    double vcost   = top.cost + bottom.cost;
                    double venergy = top.value + bottom.value;
                    vcost = Normalize(vcost, venergy);

                    cutting.cut    = Cutting.Cut.Vertical;
                    cutting.first  = top;
                    cutting.second = bottom;
                    cutting.cost   = vcost;
                    cutting.value  = top.value + bottom.value;
                }
                else
                {
                    var top    = new Cutting();
                    var bottom = new Cutting();
                    var left   = new Cutting();
                    var right  = new Cutting();
                    GetSubCuts(s, res, x, y, h, ref top, ref bottom, ref left, ref right);

                    double vcost   = top.cost + bottom.cost;
                    double venergy = top.value + bottom.value;
                    vcost = Normalize(vcost, venergy);

                    double hcost   = left.cost + right.cost;
                    double henergy = left.value + right.value;
                    hcost = Normalize(hcost, henergy);

                    if (vcost > hcost)
                    {
                        cutting.cut    = Cutting.Cut.Horizontal;
                        cutting.first  = left;
                        cutting.second = right;
                        cutting.cost   = hcost;
                        cutting.value  = left.value + right.value;
                        top.Erase();
                        bottom.Erase();
                        return(cutting);
                    }
                    else
                    {
                        cutting.cut    = Cutting.Cut.Vertical;
                        cutting.first  = top;
                        cutting.second = bottom;
                        cutting.cost   = vcost;
                        cutting.value  = top.value + bottom.value;
                        left.Erase();
                        right.Erase();
                        return(cutting);
                    }
                }
            }
            else
            {
                // no cuts possible from this level
                cutting.cut    = Cutting.Cut.Finished;
                cutting.first  = null;
                cutting.second = null;

                int n = 0;
                for (int r = res; r > s.minres; r >>= 1)
                {
                    ++n;
                }

                Spectrogram spectrogram = s.spectrograms[n];
                cutting.cost  = Cost(spectrogram, x, y);
                cutting.value = Value(spectrogram, x, y);
            }

            return(cutting);
        }
示例#8
0
        public double[][] Process(float[] inputBuffers)
        {
            int minwid = (2 << m_w);                            // m_w: 8 => 512, 9 => 1024
            int maxwid = ((2 << m_w) << m_n);                   // m_w: 8, m_n: 2 => 2048

            // m_w: 9, m_n: 3 => 8192

                        #if DEBUGVERBOSE
            Console.WriteLine("Widths from {0} to {1} ({2} to {3} in real parts)", minwid, maxwid, minwid / 2, maxwid / 2);
                        #endif

            var s = new Spectrograms(minwid / 2, maxwid / 2, 1);

            int w     = minwid;
            int index = 0;

            while (w <= maxwid)
            {
                if (!IsResolutionWanted(s, w / 2))
                {
                    w *= 2;
                    ++index;
                    continue;
                }

                if (!m_fftThreads.ContainsKey(w))
                {
                    m_fftThreads.Add(w, new FFTThread(w));
                }
                if (m_threaded)
                {
                    m_fftThreads[w].StartCalculation(inputBuffers, ref s, index, maxwid);
                }
                else
                {
                    m_fftThreads[w].SetParameters(inputBuffers, ref s, index, maxwid);
                    m_fftThreads[w].PerformTask();
                }
                w *= 2;
                ++index;
            }

            if (m_threaded)
            {
                w     = minwid;
                index = 0;
                while (w <= maxwid)
                {
                    if (!IsResolutionWanted(s, w / 2))
                    {
                        w *= 2;
                        ++index;
                        continue;
                    }
                    m_fftThreads[w].Await();
                    w *= 2;
                    ++index;
                }
            }

            m_threadsInUse = false;

                        #if DEBUGVERBOSE
            Console.WriteLine("maxwid/2 = {0}, minwid/2 = {1}, n+1 = {2}, 2^(n+1) = {3}", maxwid / 2, minwid / 2, m_n + 1, (2 << m_n));
                        #endif

            int cutwid = maxwid / 2;

            Cutting cutting = Cut(s, cutwid, 0, 0, cutwid);

                        #if DEBUGVERBOSE
            PrintCutting(cutting, "  ");
                        #endif

            var rmat = new double[maxwid / minwid][];
            for (int i = 0; i < maxwid / minwid; ++i)
            {
                rmat[i] = new double[maxwid / 2];
            }

            Assemble(s, cutting, ref rmat, 0, 0, maxwid / minwid, cutwid);
            cutting.Erase();

            return(rmat);
        }