我目前正在为手机编写一款Android应用来控制2台伺服电机。
因此我需要在50hz处创建一个高振幅的方波。 我已经看了一下AudioManager和AudioTrack类的一些示例代码,但我真的不知道如何在50hz下实现具有可测量振幅的基本方波。
这是我到目前为止所得到的:
package com.example.rollerball;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.support.v7.app.ActionBarActivity;
public class ToneGenerator
{
Thread t;
int sr = 44100;
boolean isRunning = true;
public void startTone()
{
isRunning = true;
t = new Thread() {
public void run() {
// set process priority
setPriority(Thread.MAX_PRIORITY);
int buffsize = AudioTrack.getMinBufferSize(sr,
AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT);
// create an audiotrack object
AudioTrack audioTrack = new AudioTrack(
AudioManager.STREAM_MUSIC, sr,
AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT, buffsize,
AudioTrack.MODE_STREAM);
short samples[] = new short[buffsize];
int amp = 10000;
double twopi = 8. * Math.atan(1.);
double fr = 440.f;
double ph = 0.0;
// start audio
audioTrack.play();
while (isRunning) {
for (int i = 0; i < buffsize; i++) {
samples[i] = (short) (amp * Math.sin(ph));
ph += twopi * fr / sr;
}
audioTrack.write(samples, 0, buffsize);
}
audioTrack.stop();
audioTrack.release();
}
};
t.start();
}
public void stopTone(){
isRunning = false;
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
t = null;
}
}
也许你们中的一些人可以帮助我!
提前致谢!
答案 0 :(得分:2)
现在,您的代码会产生一个漂亮的干净正弦波,峰值幅度为±10000
。可以用16位PCM表示的最大样本值是±1^15-1 = ±32767
,它是FSD的〜-10dB。
你想要一个方波。下面的代码实现了它(不是特别有效)。
for (int i = 0; i < buffsize; i++) {
short s = (amp * Math.sin(ph));
if (s > 0.0) {
sample[i] = 32767;
};
if (s < 0.0) {
sample[i] = -32767;
}
ph += twopi * fr / sr;
}
答案 1 :(得分:0)
我有一个来自我的项目的代码示例。生成的音调的开始/结束由开关控制。我认为Thread部分对你有用。
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Switch;
import android.widget.CompoundButton;
public class MainActivity extends AppCompatActivity {
Thread t; //Object that hold the audio processing thread
int sr = 44100; //sampling rate
boolean isRunning = true; //means of switching on and off
public Switch switch1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//switch
switch1 = (Switch) findViewById(R.id.switch1);
//attach a listener to it
switch1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
isRunning = true;
t = createToneThread();
t.start();
} else {
isRunning = false;
}
}
});
}
Thread createToneThread()
{
t = new Thread() {
public void run() {
//set process priority to maximum to get good performance
setPriority(Thread.MAX_PRIORITY);
//set the buffer size
int buffsize = AudioTrack.getMinBufferSize(sr, AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT);
//create an audiotrack object
AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sr,
AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT, buffsize,
AudioTrack.MODE_STREAM);
//create signal buffer and define the parameters
short samples[] = new short[buffsize];
short amp = 10000;
for (int i = 0; i < buffsize; i+=4) {
samples[i] = (short)-amp;
samples[i+1] = (short)-amp;
samples[i+2] = amp;
samples[i+3] = amp;
}
//start audio
audioTrack.play();
//define the synthesis loop
while (isRunning) {
audioTrack.write(samples, 0, buffsize);
}
//closing of the audio device
audioTrack.stop();
audioTrack.release();
}
};
return t;
}
}