public void SetParameters(float[] timeDomain, ref Spectrograms s, int res, int maxwidth) { m_in = timeDomain; m_s = s; m_res = res; m_maxwid = maxwidth; }
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; } }
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(); }
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(); }
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); }
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); } } }
// 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); }
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); }