【问题标题】:Xamarin: Playing sound for a minuteXamarin:播放声音一分钟
【发布时间】:2014-08-12 20:13:23
【问题描述】:

我正在尝试播放一分钟的声音。我可以这样做,但我这样做的方式会首先生成声音缓冲区然后播放它,这需要太多时间,有很大的延迟。所以现在我正在尝试在播放时生成声音缓冲区。所以不会有延迟。它播放了 4 秒然后停止,但我无法再次单击我的按钮一分钟。所以我认为即使我什么都听不见,代码仍在运行。

这是我的代码:

public void play()
    {   
        short[] buffer = new short[44100];
        track = new AudioTrack (Stream.Music, 44100, ChannelOut.Mono, Encoding.Pcm16bit, 5292000, AudioTrackMode.Static);
        track.SetPlaybackRate (44100);
        while (n2 < 5292000) {
            for (int n = 0; n < 44100; n++) {

                float temp1 = (float)( Amplitude * Math.Sin ((2 * Math.PI * Frequency * n2) / 44100D));
                byte[] bytes = BitConverter.GetBytes (temp1);
                buffer [n] = (short)(temp1 * short.MaxValue);
                n2++;
            }
            int buffer_number = track.Write (buffer, 0, buffer.Length);
            track.Play();
        }

        track.Release();
    }

我尝试使用 AudioTrackMode Stream 但是当程序到达 Track.play 时会抛出运行时错误: play() 在未初始化的 AudioTrack 上调用。

那我做错了什么?

【问题讨论】:

    标签: c# android audio xamarin xamarin-studio


    【解决方案1】:

    以下是我如何在 c# 中使用基于 android 示例的压缩版本:

    http://marblemice.blogspot.fr/2010/04/generate-and-play-tone-in-android.html

    public void playSound()
            {   
                var duration = 1;
                var sampleRate = 8000;
                var numSamples = duration * sampleRate;
                var sample = new double[numSamples];
                var freqOfTone = 1900;
                byte[] generatedSnd = new byte[2 * numSamples];
    
                for (int i = 0; i < numSamples; ++i) {
                    sample[i] = Math.Sin(2 * Math.PI * i / (sampleRate/freqOfTone));
                }
    
                int idx = 0;
                foreach (double dVal in sample) {
                    short val = (short) (dVal * 32767);
                    generatedSnd[idx++] = (byte) (val & 0x00ff);
                    generatedSnd[idx++] = (byte) ((val & 0xff00) >> 8);
                }
    
                var track = new AudioTrack (global::Android.Media.Stream.Music, sampleRate, ChannelOut.Mono, Encoding.Pcm16bit, numSamples, AudioTrackMode.Static);
                track.Write(generatedSnd, 0, numSamples);
                track.Play ();
            }
    

    根据您的需要调整duration和`freqOfTone``。

    【讨论】:

    • 我猜在new AudioTracktrack.Write 你必须输入generatedSnd.Length 而不是numSamples,因为它要求以字节为单位的音频大小(这是此处样本的两倍)。否则,您只会复制/播放创建的声音缓冲区的前半部分。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多