问题
private void receiveAudio(object sender)
{
IPEndPoint senderEP = new IPEndPoint(IPAddress.Any, 0);
MemoryStream audioDataStream;
BufferedWaveProvider bufferedWaveProvider;
//RawSourceWaveStream receivedRawAudioData;
byte[] receivedAudioData;
waveOutStream = new WaveOut();
while (IsAudioTransferActive)
{
receivedAudioData = audioUDPClient.Receive(ref senderEP);
audioDataStream = new MemoryStream(receivedAudioData);
//receivedRawAudioData = new RawSourceWaveStream(audioDataStream, audioFormat);
bufferedWaveProvider = new BufferedWaveProvider(audioFormat);
//How can I feed "audioDataStream " to "bufferedWaveProvider "
waveOutStream.Init(bufferedWaveProvider);
waveOutStream.Play();
}
waveOutStream.Stop();
waveOutStream.Dispose();
}
@Mark Heath :- As u said I have tried using BufferedWaveProvider but how can i feed the bufferedWaveProvider with "audioDataStream "
回答1:
You are constantly creating WaveOut objects inside your while loop that are not disposed, which is part of the issue. The best approach in this situation is to create a single WaveOut object and to feed it using a BufferedWaveProvider. Then as audio becomes available, write it into the BufferedWaveProvider.
回答2:
I was facing a similar problem when initializing new WaveOut
objects with SineWaveProviders. I came across the idea of using something like a ringlist to swap the different provider's values (frequency and amplitude) as, at least in my case, I couldn't hear any difference above 5 constant sine waves. Furthermore, in my tests on different machines, using more than 6-7 WaveOut
objects at once usually resulted in MemoryAllocationError
s thus the ringlist. This is, what I came out with:
private Queue<SineWaveGenerator> generators;
// constructor
public Player()
{
for (int i = 0; i < 5; i++)
{
var generator = new SineWaveGenerator();
generator.Amplitude = 0.25f;
generators.Enqueue(generator);
}
}
// just a helper method
private SineWaveGenerator GetGenerator(int frequency)
{
return generators.FirstOrDefault(x => x.Frequency == frequency);
}
private void Play(int frequency)
{
var generator = GetGenerator(frequency);
if (generator == null)
{
generator = generators.Dequeue(); // get generator from the top of the list
generator.Frequency = GetFrequency(key); // modify the generator
generators.Enqueue(generator); // and append it to the back
}
generator.Play();
}
private void Stop(int frequency)
{
var generator = GetGenerator(frequency);
if (generator != null)
{
generator.Stop();
}
}
Note: The SineWaveGenerator
initializes a new WaveOut
in its constructor.
来源:https://stackoverflow.com/questions/11113216/alreadyallocated-calling-waveoutopen-error