4

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();
Redth
  • 5,464
  • 6
  • 34
  • 54

1 Answers1

4

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.

Mark Heath
  • 48,273
  • 29
  • 137
  • 194
  • 1
    Any suggestions on how to do this? I just want to grab the metering info on the WaveIn()... I can't seem to find a way to do this in any samples (they all show metering from a WaveFileReader) – Redth Mar 28 '12 at 12:48
  • So my solution was to simply call .Read on my MeteringSampleProvider right after I added a sample to it, in the DataAvailable callback on the original WaveIn Stream. This way I always read out the exact data that was put into the sample provider, and it causes my events to fire. The data just goes into a buffer that's never used, so it may not be the best way, but it works! Thanks for your help! – Redth Mar 28 '12 at 15:57