2013-07-31 20 views
0

我需要在Android上實時生成具有少量頻率(疊加)的複雜聲音。我怎樣才能使用Android SDK(首選)或NDK?如何在Android上生成複雜的聲音?

看來,使用ToneGenerator不夠靈活。 使用生成的聲音數據錄製AudioTrack並播放它似乎是正確的方向,但我實時需要它,錄製和播放似乎不是實時的。

回答

0

由肖恩·範·每次從書「臨Android的媒體」的一個例子:

import android.app.Activity; 
import android.media.AudioFormat; 
import android.media.AudioManager; 
import android.media.AudioTrack; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 

public class AudioSynthesis extends Activity implements OnClickListener { 
    Button startSound; 
    Button endSound; 

AudioSynthesisTask audioSynth; 
boolean keepGoing = false; 
float synth_frequency = 440; // 440 Hz, Middle A 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    startSound = (Button) this.findViewById(R.id.StartSound); 
    startSound.setOnClickListener(this); 
    endSound = (Button) this.findViewById(R.id.EndSound); 
    endSound.setOnClickListener(this); 
    endSound.setEnabled(false); 
} 

@Override 
public void onPause() { 
    super.onPause(); 
    keepGoing = false; 
    endSound.setEnabled(false); 
    startSound.setEnabled(true); 
} 

public void onClick(View v) { 
    if (v == startSound) { 
     keepGoing = true; 
     audioSynth = new AudioSynthesisTask(); 
     audioSynth.execute(); 
     endSound.setEnabled(true); 
     startSound.setEnabled(false); 
    } else if (v == endSound) { 
     keepGoing = false; 
     endSound.setEnabled(false); 
     startSound.setEnabled(true); 
    } 
} 

private class AudioSynthesisTask extends AsyncTask<Void, Void, Void> 
{ 
    @Override 
    protected Void doInBackground(Void... params) { 
     final int SAMPLE_RATE= 11025; 
     int minSize = AudioTrack.getMinBufferSize(SAMPLE_RATE, 
       AudioFormat.CHANNEL_CONFIGURATION_MONO, 
       AudioFormat.ENCODING_PCM_16BIT); 
     AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 
      SAMPLE_RATE, 
      AudioFormat.CHANNEL_CONFIGURATION_MONO, 
      AudioFormat.ENCODING_PCM_16BIT, 
      minSize, 
      AudioTrack.MODE_STREAM); 
    audioTrack.play(); 
    short[] buffer = new short[minSize]; 
    float angular_frequency = 
     (float)(2*Math.PI) * synth_frequency/SAMPLE_RATE; 
    float angle = 0; 
    while (keepGoing) { 
     for (int i = 0; i < buffer.length; i++) 
     { 
      buffer[i] = (short)(Short.MAX_VALUE * ((float) Math.sin(angle))); 
      angle += angular_frequency; 
     } 
     audioTrack.write(buffer, 0, buffer.length); 
    } 
    return null; 
} 
} }