How to achieve PCM playback on .NET Android using AudioTrack

1 week ago 8
ARTICLE AD BOX

I'm trying to implement simple PCM player for some synth notes that should be able to play independently.

public void Play() { var playToken = new CancellationTokenSource(); playToken.CancelAfter(3000); Task.Run(() => { var left = new float[1024]; //smaller buffer because rendering to larger ones causes android to freeze var right = new float[1024]; var minBufferSize = AudioTrack.GetMinBufferSize( SAMPLE_RATE, ChannelOut.Stereo, AndroidMedia.Encoding.Pcm16bit); var audioAttributes = new AudioAttributes.Builder() .SetUsage(AudioUsageKind.Media) .SetContentType(AudioContentType.Music) .Build()!; var audioFormat = new AudioFormat.Builder() .SetEncoding(AndroidMedia.Encoding.Pcm16bit) .SetSampleRate(SAMPLE_RATE) .SetChannelMask(ChannelOut.Stereo) .Build()!; _audioTrack = new AudioTrack.Builder() .SetAudioAttributes(audioAttributes) .SetAudioFormat(audioFormat) .SetTransferMode(AudioTrackMode.Stream) .SetBufferSizeInBytes(minBufferSize) .Build(); _audioTrack.Play(); _inner.NoteOn(0, 60, 100); //generate noteon event while (!playToken.IsCancellationRequested) { lock(mutex){ _inner.Render(left, right); //render to left and right var pcm = Helper.InterlacePcm(left, right); //interlace to one buffer _audioTrack.Write(pcm, 0, pcm.Length); //write to AudioTrack sync } } }); } public static short[] InterlacePcm(float[] left, float[] right) { var pcm = new short[left.Length * 2]; for (int i = 0; i < left.Length; i++) { pcm[i * 2] = (short)(Math.Clamp(left[i], -1f, 1f) * short.MaxValue); pcm[i * 2 + 1] = (short)(Math.Clamp(right[i], -1f, 1f) * short.MaxValue); } return pcm; }

It is intended that we call Play multiple times whenever we want to so every call creates it's own AudioTrack instance. The synth _inner is an instance of MetylSynth generating some simple PCM waveform. This behaves erratically, with the sound aggressively buffering , stuttering on consecutive Play calls at any interval. Any help getting this right would be appreciated.

Read Entire Article