我需要从我的Xamarin应用程序播放自定义生成的声音。我目前的代码如下:
public class NotePlayer {
private const int sampleRate = 44100;
private const int bufferSize = 22050;
private Task<AudioTrack> track = null;
public double Frequency { get; private set; }
public NotePlayer(double frequency) {
this.Frequency = frequency;
}
public void Play() {
short[] source = new short[bufferSize/2];
for(int i= 0; i<source.Length; i++) {
source[i] = (short)(Math.Sin(((double)i) / sampleRate * Frequency* Math.PI*2)*Int16.MaxValue);
}
var track = new AudioTrack(Stream.Music, sampleRate, ChannelOut.Mono, Android.Media.Encoding.Pcm16bit, bufferSize, AudioTrackMode.Static);
track.Write(source, 0, bufferSize);
track.SetLoopPoints(0, bufferSize / 2, -1);
track.Play();
this.track = Task.FromResult(track);
}
//Some more methods here
}
问题在于我一直在线路track.play()上获得Java.Lang.IllegalStateException: play() called on uninitialized AudioTrack.
例外。
我已经看到this问题,从我的理解,我可能需要对我的样本的字节顺序做一些事情,但这不应该在这一点上,以及接受的答案中的代码看起来几乎就像我的例子,这让我更加困惑。即使尝试评论SetLoopPoints
行以使其看起来完全相同,也没有帮助。
在Android 5.1上测试。
答案 0 :(得分:0)
问题的原因是您的track
州状态为AudioTrackState.NoStaticData
。
您已经创建了一个长度为bufferSize / 2
的来源,但是当您将来源写入AudioTrack
时,您尝试编写长度为bufferSize
的数据,但数据不是补充。
只需将代码track.Write(source, 0, bufferSize);
更改为track.Write(source, 0, source.Length);
。