【问题标题】:Continuous synthesis of static waveform in Android using AudioTrack classAndroid中使用AudioTrack类连续合成静态波形
【发布时间】:2012-10-11 12:31:35
【问题描述】:

下面是我的play() 方法的代码,它简单地生成一组任意频率并将它们混合成一个音调。

问题是它只播放一瞬间 - 我需要的是连续播放它。我将不胜感激有关如何使用 Android 中的 AudioTrack 类不断生成声音的建议。我相信它与 MODE_STREAM 常量有关,但我不太清楚如何。

这里是 AudioTrack 类文档的链接:

http://developer.android.com/reference/android/media/AudioTrack.html

编辑:我忘了提到一个重要方面,它不能循环。由于有时会混合多达 50 多个频率,因此听起来会很不稳定,因为所有频率峰值都没有最小的公分母 - 或者它离波形太远而无法存储为一个声音。

/**
 * play - begins playing the sound
 */
public void play() {
    // Get array of frequencies with their relative strengths
    double[][] soundData = getData();

    // Track samples array
    final double samples[] = new double[1024];

    // Calculate the average sum in the array and write it to sample
    for (int i = 0; i < samples.length; ++i) {
            double valueSum = 0;

            for (int j = 0; j < soundData.length; j++) {
                valueSum += Math.sin(2 * Math.PI * i / (SAMPLE_RATE / soundData[j][0]));
            }

            samples[i] = valueSum / soundData.length;
    }

    // Obtain a minimum buffer size
    int minBuffer = AudioTrack.getMinBufferSize(SAMPLE_RATE, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);

    if (minBuffer > 0) {

        // Create an AudioTrack
        mTrack = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLE_RATE, AudioFormat.CHANNEL_CONFIGURATION_MONO, 
                AudioFormat.ENCODING_PCM_16BIT, minBuffer, AudioTrack.MODE_STREAM);

        // Begin playing track
        mTrack.play();

        // Fill the buffer
        if (mBuffer.length < samples.length) {
             mBuffer = new short[samples.length];
        }

        for (int k = 0; k < samples.length; k++) {
            mBuffer[k] = (short) (samples[k] * Short.MAX_VALUE);
        }

        // Write audio data to track for real-time audio sythesis
        mTrack.write(mBuffer, 0, samples.length);

    }

    // Once everything has successfully begun, indicate such.
    isPlaying = true;
}

【问题讨论】:

    标签: android audio audiotrack


    【解决方案1】:

    看起来代码差不多了。它只需要一个循环来不断生成样本,将它们放入缓冲区,然后将它们写入 AudioTrack。现在只有一个完整的缓冲区在退出之前被写入,这就是它停止如此迅速的原因。

    void getSamples(double[] samples) {
        // Get array of frequencies with their relative strengths
        double[][] soundData = getData();
    
        // Calculate the average sum in the array and write it to sample
        for (int i = 0; i < samples.length; ++i) {
                double valueSum = 0;
    
                for (int j = 0; j < soundData.length; j++) {
                    valueSum += Math.sin(2 * Math.PI * i / (SAMPLE_RATE / soundData[j][0]));
                }
    
                samples[i] = valueSum / soundData.length;
        }
    }
    
    public void endPlay() {
        done = true;
    }
    
    /**
     * play - begins playing the sound
     */
    public void play() {
        // Obtain a minimum buffer size
        int minBuffer = AudioTrack.getMinBufferSize(SAMPLE_RATE, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
    
        if (minBuffer > 0) {
    
            // Create an AudioTrack
            mTrack = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLE_RATE, AudioFormat.CHANNEL_CONFIGURATION_MONO, 
                AudioFormat.ENCODING_PCM_16BIT, minBuffer, AudioTrack.MODE_STREAM);
    
            // Begin playing track
            mTrack.play();
    
            // Track samples array
            final double samples[] = new double[1024];
    
            while (!done) {
                // Fill the buffer
                if (mBuffer.length < samples.length) {
                     mBuffer = new short[samples.length];
                }
    
                getSamples(samples);
    
                for (int k = 0; k < samples.length; k++) {
                    mBuffer[k] = (short) (samples[k] * Short.MAX_VALUE);
                }
    
                // Write audio data to track for real-time audio sythesis
                mTrack.write(mBuffer, 0, samples.length);
    
                // Once everything has successfully begun, indicate such.
                isPlaying = true;
            }
        }
    
        // Once everything is done, indicate such.
        isPlaying = false;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-08
      • 2018-01-23
      • 1970-01-01
      • 2014-11-15
      • 1970-01-01
      • 1970-01-01
      • 2011-04-28
      • 1970-01-01
      相关资源
      最近更新 更多