Search code examples
c#.netaudionaudiowave

NAudio MeteringSampleProvider not firing events?


From all the samples I've seen using NAudio's MeteringSampleProvider to update a VolumeMeter control, I think I've got the right code, but it seems that the event for the MeteringSampleProvider as well as the SampleChannel never fire. I'm writing to a wav file at the same time and when I play it back, the recording has worked fine. Any ideas?

IWaveIn wavStream;
WaveFileWriter wavWriter;
BufferedWaveProvider bufferedWaveProvider;
SampleChannel sampleChannel;
MeteringSampleProvider meteringSampleProvider;

wavStream = new WaveIn();
wavWriter = new WaveFileWriter(CurrentRecording.Filename, wavStream.WaveFormat);

wavStream.DataAvailable += new EventHandler<WaveInEventArgs>((s2, e2) =>
{
  //Add sample to the buffered provider
  bufferedWaveProvider.AddSamples(e2.Buffer, 0, e2.BytesRecorded);

  //************************************************************
  //EDIT: This is how I solved the issue!!!      
  var tmpBuffer = new float[e2.BytesRecorded];
  if (meteringSampleProvider != null)
    meteringSampleProvider.Read(tmpBuffer, 0, e2.BytesRecorded);
  //END EDIT
  //************************************************************

  //Write to the wave file
  wavWriter.Write(e2.Buffer, 0, e2.BytesRecorded);  
});

//Create our Buffered provider
bufferedWaveProvider = new BufferedWaveProvider(wavStream.WaveFormat);
bufferedWaveProvider.DiscardOnBufferOverflow = true;

//Create the sample channel
sampleChannel = new SampleChannel(bufferedWaveProvider);
sampleChannel.PreVolumeMeter += new EventHandler<StreamVolumeEventArgs>((s2, e2) =>
{
  Console.WriteLine("PreVolumeMeter");
});

//Create the metering sample provider
meteringSampleProvider = new MeteringSampleProvider(sampleChannel);
meteringSampleProvider.StreamVolume += new EventHandler<StreamVolumeEventArgs>((s2, e2) =>
{
  Console.WriteLine("PostVolumeMeter");
});


//Start Recording
wavStream.StartRecording();

Solution

  • You're not reading from the meteringSampleProvider, so no events will be raised. Normally of course this would be the IWavePlayer that is calling Read, but if you are not playing audio, you'll need to pull the audio through your pipeline some other way.