0

play()以下は、任意の周波数セットを単純に生成し、それらを 1 つのトーンにブレンドする私のメソッドのコードです。

問題は、それがほんの一瞬しか再生されないことです-私はそれを連続して再生する必要があります. Android で AudioTrack クラスを使用して常にサウンドを生成する方法についての提案をいただければ幸いです。定数と関係があると思いますが、どうすればいいのMODE_STREAMかわかりません。

AudioTrack クラスのドキュメントへのリンクは次のとおりです。

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

編集: 1 つの重要な側面について言及するのを忘れていました。ループすることはできません。場合によっては最大 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;
}
4

1 に答える 1

0

コードはほとんどそこにあるようです。サンプルを生成し続け、バッファに入れ、AudioTrack に書き込むためのループが必要なだけです。現在、終了する前に1つのバッファがいっぱいになるだけで書き込まれるため、すぐに停止します。

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;
}
于 2012-10-11T04:31:35.993 に答える