private void PullAudioFrameThread() { var avsync_type = 0; var bytesPerSample = 2; var type = AUDIO_FRAME_TYPE.FRAME_TYPE_PCM16; var channels = CHANNEL; var samples = SAMPLE_RATE / PULL_FREQ_PER_SEC * CHANNEL; var samplesPerSec = SAMPLE_RATE; var buffer = Marshal.AllocHGlobal(samples * bytesPerSample); var freq = 1000 / PULL_FREQ_PER_SEC; var tic = new TimeSpan(DateTime.Now.Ticks); while (_pullAudioFrameThreadSignal) { var toc = new TimeSpan(DateTime.Now.Ticks); if (toc.Subtract(tic).Duration().Milliseconds >= freq) { tic = new TimeSpan(DateTime.Now.Ticks); _audioRawDataManager.PullAudioFrame(buffer, (int)type, samples, bytesPerSample, channels, samplesPerSec, 0, avsync_type); var byteArray = new byte[samples * bytesPerSample]; Marshal.Copy(buffer, byteArray, 0, samples * bytesPerSample); var floatArray = ConvertByteToFloat16(byteArray); lock (audioBuffer) { audioBuffer.Put(floatArray); } writeCount += floatArray.Length; count += 1; } if (count == 100) { _startSignal = true; } } Marshal.FreeHGlobal(buffer); }
unsafe void PullAudioFrameThread() { int sampleRate = _sampleRate; int channels = _channelCount; var frameType = AUDIO_FRAME_TYPE.FRAME_TYPE_PCM16; var bytesPerSample = 2; // PCM16 var samplesPerChannel = (int)(sampleRate * _frameDurationMs / 1000.0f); var frameBufferPointer = Marshal.AllocHGlobal(samplesPerChannel * channels * bytesPerSample); var pcmBuffer = new float[samplesPerChannel * channels]; _ringBuffer = new RingBuffer <float>(samplesPerChannel * channels * 4); // 4[frames] var tic = new TimeSpan(DateTime.Now.Ticks); while (_pullAudioFrame) { var toc = new TimeSpan(DateTime.Now.Ticks); if (toc.Subtract(tic).Duration().Milliseconds >= _frameDurationMs) { tic = new TimeSpan(DateTime.Now.Ticks); _audioRawDataManager.PullAudioFrame(frameBufferPointer, (int)frameType, samplesPerChannel, bytesPerSample, channels, sampleRate, 0, 0); var span = new ReadOnlySpan <Byte>((void *)frameBufferPointer, samplesPerChannel * channels * bytesPerSample); // Convert 16bit PCM data bytes to 32bit float PCM data. for (var i = 0; i < pcmBuffer.Length; i++) { pcmBuffer[i] = ConvertBytesToInt16(span.Slice(2 * i)) / 32768f; // The maximum absolute value of Int16 is 32768. } lock (_ringBuffer) { _ringBuffer.Enqueue(pcmBuffer); } } } Marshal.FreeHGlobal(frameBufferPointer); }