public virtual void Reset() { if (_input == null) { return; } _input.Reset(); }
/// <summary> /// Calculate the weighted volume of a sound source. /// NB: this consumes lots of memory for long sources. /// </summary> /// <param name="src"></param> /// <param name="dbSPL"></param> /// <returns>Volume (units, not dB)</returns> public static double WeightedVolume(ISoundObj src, double dbSPL, double dbSPLBase) { double wv = 0; for (ushort c = 0; c < src.NumChannels; c++) { SingleChannel channel = src.Channel(c); wv += Loudness.WeightedVolume1(channel, dbSPL, dbSPLBase); } src.Reset(); wv = wv / src.NumChannels; return(wv); }
/// <summary> /// Calculate the weighted volume of a sound source. /// NB: this consumes lots of memory for long sources. /// </summary> /// <param name="src"></param> /// <param name="dbSPL"></param> /// <returns>Volume (units, not dB)</returns> public static double WeightedVolume(ISoundObj src, double dbSPL, double dbSPLBase) { double wv = 0; for (ushort c = 0; c < src.NumChannels; c++) { SingleChannel channel = src.Channel(c); wv += Loudness.WeightedVolume1(channel, dbSPL, dbSPLBase); } src.Reset(); wv = wv / src.NumChannels; return wv; }
static ISoundObj SlidingLowPass(ISoundObj impulse, int peakPos) { // Filter the impulse response with a sliding lowpass filter // - Take the first (peakpos) samples unchanged // - Take the next 2.5ms (~110 samples @ 44100) unchanged // - Fade to a lowpass-filtered version uint sampleRate = impulse.SampleRate; int startpos1 = (int)(sampleRate * 0.0025); // 2.5mS, 110 samples int startpos2 = (int)(sampleRate * 0.0050); int startpos3 = (int)(sampleRate * 0.0100); int startpos4 = (int)(sampleRate * 0.0200); int startpos5 = (int)(sampleRate * 0.0400); List<IEnumerator<ISample>> filters = null; int nFilter = 0; int nFilters = 0; int x = 0; int f0len = 0; ISoundObj filteredImpulse = new CallbackSource(1, sampleRate, delegate(long j) { if(j==0) { // initialize the list of filters impulse.Reset(); filters = new List<IEnumerator<ISample>>(6); ISoundObj f0 = LowPassFiltered(impulse, 20, 0); f0len = f0.Iterations; filters.Add(f0.Samples); // unfiltered filters.Add(LowPassFiltered(impulse, 640, -10).Samples); // LPF from 640Hz, kick in at +110 filters.Add(LowPassFiltered(impulse, 320, -20).Samples); // LPF from 320Hz, kick in at +220 (etc) filters.Add(LowPassFiltered(impulse, 160, -30).Samples); // +440 filters.Add(LowPassFiltered(impulse, 80, -40).Samples); // +880 filters.Add(LowPassFiltered(impulse, 40, -50).Samples); // +1760 = 40ms nFilter = 0; nFilters = filters.Count; } // Move the filters along a notch. // (or, right at the beginning, move all the filters along by a lot, compensating for their center) // For perf, we don't need to keep enumerating the filters we've finished using. bool moreData = true; int nSkip = 1; if (j == 0) { nSkip = (f0len/2)+1; } for (int skip = 0; skip < nSkip; skip++) { int nStart = (nFilter == 0) ? 0 : nFilter - 1; // Keep moving even the old filters along so mixing works later for (int f = nStart; f < nFilters; f++) { moreData &= filters[f].MoveNext(); } } if (!moreData) return null; // Decide which filter we'll use x++; if (j == peakPos + startpos1) { nFilter = 1; x = 0; } if (j == peakPos + startpos2) { nFilter = 2; x = 0; } if (j == peakPos + startpos3) { nFilter = 3; x = 0; } if (j == peakPos + startpos4) { nFilter = 4; x = 0; } if (j == peakPos + startpos5) { nFilter = 5; x = 0; } // Pick the sample from the current filter ISample s = filters[nFilter].Current; // For a short region after switch-over, mix slowly with the sample from the previous filter int w = 20; if (x < w && nFilter > 0) { ISample sPrev = filters[nFilter-1].Current; for (int c = 0; c < s.NumChannels; c++) { s[c] = ((double)x/w)*s[c] + ((double)(w-x)/w)*sPrev[c]; } } return s; }); return filteredImpulse; }
public void Reset() { _obj.Reset(); _enum = _obj.Samples; }
private static ISoundObj GenerateFlatnessFilter(string impulsePath, ISoundObj impulseObj, double nFlatness) { // Flatness-filters are single channel // nFlatness is from 0 to 100 // 0: follow the contours of the impulse // 100: completely flat DateTime dtStart = DateTime.Now; ISoundObj filterImpulse = null; uint nSR = impulseObj.SampleRate; uint nSR2 = nSR / 2; string sPath = FlatnessFilterPath(impulsePath, nSR, nFlatness); // Low flatness values (to 0) => very un-smooth // High flatness values (to 100) => very smooth double detail = (nFlatness / 50) + 0.05; // Get profile of the impulse FilterProfile lfg = new FilterProfile(impulseObj, detail); // Scale by the flatness values lfg = lfg * ((100 - nFlatness) / 100); // Invert lfg = lfg.Inverse(20); // Zero at HF lfg.Add(new FreqGain(nSR2 - 100, 0)); // Build the flatness filter filterImpulse = new FilterImpulse(8192, lfg, FilterInterpolation.COSINE, nSR); try { // Write the filter impulse to disk WaveWriter wri = new WaveWriter(sPath); wri.Input = filterImpulse; wri.Format = WaveFormat.IEEE_FLOAT; wri.BitsPerSample = 64; wri.Run(); wri.Close(); if (_debug) { // DEBUG: Write the flatness impulse as wav16 wri = new WaveWriter(sPath + ".wav"); wri.Input = filterImpulse; wri.Format = WaveFormat.PCM; wri.BitsPerSample = 16; wri.Normalization = -1.0; wri.Dither = DitherType.NONE;//.TRIANGULAR; wri.Run(); wri.Close(); } } catch (Exception e) { if (_debug) { Trace.WriteLine("GenerateFlatnessFilter: " + e.Message); } } impulseObj.Reset(); if (_debug) { TimeSpan ts = DateTime.Now.Subtract(dtStart); Trace.WriteLine("GenerateFlatnessFilter " + ts.TotalMilliseconds); } return filterImpulse; }