【发布时间】:2016-04-14 13:46:42
【问题描述】:
我正在使合成器能够生成三种基本类型的声音,并且当我播放声音时,在它完成播放之前和之后会发生点击。而且我不知道为什么。
发生在每种类型的声音中.. 正弦最响亮。
这是我用来生成声音的代码
int amp = 32767;
double phase = 0.0;
protected void onCreate(Bundle savedInstanceState) {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
AudioManager myAudioMgr = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
String nativeParam = myAudioMgr.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE);
sampleRate = Integer.parseInt(nativeParam);
nativeParam = myAudioMgr.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER);
bufSize = Integer.parseInt(nativeParam);
}
else {
sampleRate = 44100;
bufSize = AudioTrack.getMinBufferSize(sampleRate,
AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
}
audioOutput = new AudioOutput();
audioOutput.Start(sampleRate, bufSize);
samples = new short[bufSize]; // buffer size is 512
playTask.execute();
}
class PlayTask extends AsyncTask<Object, Void, Void> {
@Override
protected Void doInBackground(Object[] params) {
android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND + Process.THREAD_PRIORITY_MORE_FAVORABLE);
while (!this.isCancelled()) {
while (touched) {
generateTone();
audioOutput.write(samples, 0, samples.length);
}
}
return null;
}
}
private void generateTone() {
double phaseIncrement = (2 * Math.PI) / sampleRate;
switch (currentShape) {
case SINE:
for (int i = 0; i < bufSize; i++) {
samples[i] = (short) (amp * Math.sin(phase));
phase += phaseIncrement * freq;
if (phase > 2 * Math.PI)
phase -= 2 * Math.PI;
}
break;
case SAWTOOTH:
for (int i = 0; i < bufSize; i++) {
samples[i] = (short) (amp * (phase - amp));
phase += phaseIncrement * freq;
if (phase > 2 * Math.PI)
phase -= 2 * Math.PI;
}
break;
case SQUARE:
for (int i = 0; i < bufSize; i++) {
if (phase < Math.PI)
samples[i] = (short) amp;
else
samples[i] = (short) -amp;
phase += phaseIncrement * freq;
if (phase > 2 * Math.PI)
phase -= 2 * Math.PI;
}
break;
}
}
public class AudioOutput {
private AudioTrack mAudioTrack;
private int mFrameRate;
public void Start(int sampleRate, int bufferSize) {
Stop();
mFrameRate = sampleRate;
mAudioTrack = createAudioTrack(bufferSize);
mAudioTrack.play();
}
private AudioTrack createAudioTrack(int buffsize) {
return new AudioTrack(AudioManager.STREAM_MUSIC,
mFrameRate, AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT, buffsize,
AudioTrack.MODE_STREAM);
}
public int write(short[] buffer, int offset, int length) {
return write = mAudioTrack.write(buffer, offset, length);
}
public void Stop() {
if (mAudioTrack != null) {
mAudioTrack.stop();
mAudioTrack.release();
mAudioTrack = null;
}
}
}
音频示例:https://soundcloud.com/syntey/sinewavetest
有人知道哪里有问题吗?
谢谢
【问题讨论】:
-
你能给个实际波形文件的链接吗?我认为看它比听它可以收集到更多信息。
-
您是否在未列出的代码中的任何位置进行淡入/淡出?生成的信号显然具有某种包络。正弦也有很多失真。
-
不,每个生成声音的代码都在这篇文章中
-
淡化可能来自麦克风录音,我打印了缓冲区内容,没关系。那个结局是唯一困扰我的事情
标签: android audio signal-processing audiotrack