Код: Выделить всё
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;
}