public async Task Start() { m_isFlushing = false; m_isRunning = false; m_waveBufferReader = null; var settings = new AudioGraphSettings(AudioRenderCategory.Media); var result = await AudioGraph.CreateAsync(settings); if (result.Status != AudioGraphCreationStatus.Success) { throw new Exception("AudioGraph creation error: " + result.Status); } m_audioGraph = result.Graph; var outputDeviceResult = await m_audioGraph.CreateDeviceOutputNodeAsync(); if (outputDeviceResult.Status != AudioDeviceNodeCreationStatus.Success) { throw new Exception("Unable to create audio playback device: " + result.Status); } m_deviceOutputNode = outputDeviceResult.DeviceOutputNode; // Create the FrameInputNode at the same format as the graph, var nodeEncodingProperties = m_audioGraph.EncodingProperties; nodeEncodingProperties.ChannelCount = 1; nodeEncodingProperties.SampleRate = 16000; m_frameInputNode = m_audioGraph.CreateFrameInputNode(nodeEncodingProperties); m_frameInputNode.AddOutgoingConnection(m_deviceOutputNode); m_frameInputNode.QuantumStarted += OnQuantumStarted; m_isRunning = true; m_isFlushing = false; m_audioGraph.Start(); }
private unsafe AudioFrame GenerateAudioData(int samples) { var frame = new AudioFrame((uint)samples * sizeof(float)); try { using (var buffer = frame.LockBuffer(AudioBufferAccessMode.Read)) using (var reference = buffer.CreateReference()) { byte * dataInBytes; uint capacity; float *dataInFloat; // Get the buffer from the AudioFrame ((IMemoryBufferByteAccess)reference).GetBuffer(out dataInBytes, out capacity); dataInFloat = (float *)dataInBytes; var sampleIndex = 0; while ((m_audioData.Count() > 0 || m_waveBufferReader != null) && sampleIndex < samples) { // extract the next audio buffer from the queue if (m_waveBufferReader == null) { m_audioDataMutex.WaitOne(); m_waveBufferReader = WaveBufferReader.Create(m_audioData[0]); m_audioData.RemoveAt(0); m_audioDataMutex.ReleaseMutex(); } // read samples from WaveBufferReader until output buffer is full // or input buffer is empty var eof = false; while (sampleIndex < samples && !eof) { var temp = m_waveBufferReader.ReadShort(ref eof); if (!eof) { dataInFloat[sampleIndex++] = temp / 32768.0f; } else { // current reader is empty so delete it m_waveBufferReader = null; } } } // fill remainder of buffer with silence while (sampleIndex < samples) { dataInFloat[sampleIndex++] = 0.0f; // check if we are done flushing audio after Stop() if (!m_isRunning && m_isFlushing && m_audioData.Count() == 0 && m_waveBufferReader == null) { m_isFlushing = false; } } } } catch (Exception ex) { Debug.WriteLine(ex.Message); } return(frame); }