播放自定义生成的声音 - AudioTrack.play抛出异常

时间:2017-09-20 03:51:51

标签: c# android xamarin

我需要从我的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上测试。

1 个答案:

答案 0 :(得分:0)

问题的原因是您的track州状态为AudioTrackState.NoStaticData

您已经创建了一个长度为bufferSize / 2的来源,但是当您将来源写入AudioTrack时,您尝试编写长度为bufferSize的数据,但数据不是补充。

只需将代码track.Write(source, 0, bufferSize);更改为track.Write(source, 0, source.Length);