Wartość szczytowa próbki audio, jak pobrać?

0

Witam, piszę program do nagrywania dźwięku z bibloteką NAudio w C#, i potrzebuje pobrać najwyższą wartość w danej próbce, żeby to po prostu odwzorować w VolumeMeter,
Zapis próbek dźwiękowych wygląda tak:

   void OnDataAvailable(object sender, WaveInEventArgs e)
        {
            if (FileChkBox.Checked && waveIn != null &&writer!=null) writer.Write(e.Buffer, 0, e.BytesRecorded);

        } 

są to próbki Float32 przekazane w tablicy bajtów (czyli 4 wartości w tablicy=jedna wartość próbki). i teraz moje pytanie jak na tej podstawie określić głośność, aby pokazywane dane były w miarę poprawne?

0

skoro masz bufor, to najprościej będzie go przejrzeć i znaleźć maksimum i minimum w tablicy...

zakładając że e.Buffer jest typu Byte[], jeśli możesz sobie pozwolić na /unchecked to najbardziej wydajnie będzie pobrać wskaźnik na bufor, rzutować go na float* i przeiterować jak tablicę.

fixed (float* p = (float*)(void*)&e.Buffer[0])
{
    // tutaj traktujesz p jak tablicę floatów
}
0

Z pomocą internetu udało mi się zrobić takie coś, i nawet działa:
Może komuś się przyda.

 
  if (waveIn == null) return;
            bufferedWaveProvider = new BufferedWaveProvider(waveIn.WaveFormat);
            bufferedWaveProvider.DiscardOnBufferOverflow = true;
            sampleChannel = new SampleChannel(bufferedWaveProvider);
            sampleChannel.PreVolumeMeter += OnPreVolumeMeter;
            //Create the metering sample provider
            meteringSampleProvider = new MeteringSampleProvider(sampleChannel);

            meteringSampleProvider.StreamVolume += OnPostVolumeMeter;
            waveIn.DataAvailable += OnDataAvailable;
            waveIn.RecordingStopped += OnRecordingStopped;
            sampleChannel.Volume = 1.0f;
...
void OnPostVolumeMeter(object sender, StreamVolumeEventArgs e)
        {
            // we know it is stereo
            bufferedWaveProvider.ClearBuffer();
            if (e.MaxSampleValues.Length <= 0) return;
            volumeMeter1.Amplitude = e.MaxSampleValues[0];
            if (e.MaxSampleValues.Length <= 1) return;
            volumeMeter2.Amplitude = e.MaxSampleValues[1];
            
            //Debug.Print("CRC:{0}/{1}",e.MaxSampleValues[0],e.MaxSampleValues[1]);
            //waveformPainter2.AddMax(e.MaxSampleValues[1]);
        }
...
 float[] BytesToFloat(byte[] B,int mLen)
        {
            if (mLen <= 1) return null;
            int Len = mLen / 2;
            float[] F = new float[Len];
            for (int index = 0, i = 0; index < mLen; index += 2, i++)
            {
                short sample = (short)((B[index + 1] << 8) |
                                        B[index + 0]);
                float sample32 = sample / 32768f;
                F[i] = sample32;
                // ProcessSample(sample32);
            }
            return F;
        }
        void OnDataAvailable(object sender, WaveInEventArgs e)
        {
            if (FileChkBox.Checked && waveIn != null && writer != null) writer.Write(e.Buffer, 0, e.BytesRecorded);
            bufferedWaveProvider.AddSamples(e.Buffer, 0, e.BytesRecorded);
            float[] F = BytesToFloat(e.Buffer, e.BytesRecorded);
            meteringSampleProvider.Read(F, 0, F.Length);
            F = null;

        }

1 użytkowników online, w tym zalogowanych: 0, gości: 1