/// <summary> /// Sends a pseudo-random sample to replicate white noise. /// </summary> private void SendNoiseSample(object state) { lock (_audioStreamTimer) { int bufferSize = SAMPLE_RATE / 1000 * AUDIO_SAMPLE_PERIOD_MILLISECONDS; float[] linear = new float[bufferSize]; _signalGenerator.Read(linear, 0, bufferSize); byte[] encodedSample = new byte[bufferSize]; short[] pcm = linear.Select(x => (short)(x * 32767f)).ToArray(); if (_sendingFormat.FormatCodec == SDPMediaFormatsEnum.G722) { _g722Codec.Encode(_g722CodecState, encodedSample, pcm, bufferSize); } else { for (int index = 0; index < bufferSize; index++) { if (_sendingFormat.FormatCodec == SDPMediaFormatsEnum.PCMA) { encodedSample[index] = ALawEncoder.LinearToALawSample(pcm[index]); } else { encodedSample[index] = MuLawEncoder.LinearToMuLawSample(pcm[index]); } } } SendAudioFrame((uint)bufferSize, (int)_sendingFormat.FormatCodec, encodedSample); } }
/// <summary> /// Sends a sample from a signal generator generated waveform. /// </summary> private void SendSignalGeneratorSample(object state) { if (!_streamSendInProgress) { lock (_audioStreamTimer) { int sourceSampleRate = _sourceAudioSampleRate == AudioSamplingRatesEnum.Rate8KHz ? 8000 : 16000; int inputBufferSize = sourceSampleRate / 1000 * AUDIO_SAMPLE_PERIOD_MILLISECONDS; uint outputBufferSize = (uint)(_sendingAudioRtpRate / 1000 * AUDIO_SAMPLE_PERIOD_MILLISECONDS); // Get the signal generator to generate the samples and then convert from // signed linear to PCM. float[] linear = new float[inputBufferSize]; _signalGenerator.Read(linear, 0, inputBufferSize); short[] pcm = linear.Select(x => (short)(x * LINEAR_MAXIMUM)).ToArray(); byte[] encodedSample = _audioEncoder.EncodeAudio(pcm, _sendingFormat, _sourceAudioSampleRate); OnAudioSourceEncodedSample?.Invoke(outputBufferSize, encodedSample); } } }
/// <summary> /// Sends a sample from a signal generator generated waveform. /// </summary> private void SendSignalGeneratorSample(object state) { if (!_streamSendInProgress) { lock (_audioStreamTimer) { int inputBufferSize = _sendingAudioSampleRate / 1000 * AUDIO_SAMPLE_PERIOD_MILLISECONDS; int outputBufferSize = _sendingAudioRtpRate / 1000 * AUDIO_SAMPLE_PERIOD_MILLISECONDS; // Get the signal generator to generate the samples and then convert from // signed linear to PCM. float[] linear = new float[inputBufferSize]; _signalGenerator.Read(linear, 0, inputBufferSize); short[] pcm = linear.Select(x => (short)(x * 32767f)).ToArray(); // Both G711 (lossless) and G722 (lossy) encode to 64Kbps (unless the // hard coded G722 rate of 64000 is changed). byte[] encodedSample = new byte[outputBufferSize]; if (_sendingFormat.FormatCodec == SDPMediaFormatsEnum.G722) { _g722Codec.Encode(_g722CodecState, encodedSample, pcm, inputBufferSize); } else { Func <short, byte> encode = (_sendingFormat.FormatCodec == SDPMediaFormatsEnum.PCMA) ? (Func <short, byte>)ALawEncoder.LinearToALawSample : MuLawEncoder.LinearToMuLawSample; for (int index = 0; index < inputBufferSize; index++) { encodedSample[index] = encode(pcm[index]); } } SendAudioFrame((uint)outputBufferSize, (int)_sendingFormat.FormatCodec, encodedSample); } } }