// 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); }