Android 简单的生产者消费者示例
我正在开发简单的生产者消费者示例。一个线程使用Android 简单的生产者消费者示例,android,audiorecord,Android,Audiorecord,我正在开发简单的生产者消费者示例。一个线程使用AudioRecord类记录音频样本,并将它们写入缓冲区。第二个只读取缓冲区,什么也不做。当用户想要停止记录时,第一个线程将特殊字符写入缓冲区,并指示另一个线程的读取结束。这是我的密码 public class SpellCollectorActivity extends Activity implements OnClickListener{ private ArrayBlockingQueue<byte[] > audioq;
AudioRecord
类记录音频样本,并将它们写入缓冲区。第二个只读取缓冲区,什么也不做。当用户想要停止记录时,第一个线程将特殊字符写入缓冲区,并指示另一个线程的读取结束。这是我的密码
public class SpellCollectorActivity extends Activity implements OnClickListener{
private ArrayBlockingQueue<byte[] > audioq;
boolean needToBeStopped = false;
Button generate, action;
private MyRecorder rec;
private MyReader mr;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
action = (Button) findViewById(R.id.actionButton);
action.setOnClickListener(this);
needToBeStopped = false;
audioq = new ArrayBlockingQueue<byte[]>(CAPACITY);
}
public void onClick(View arg0){
switch(arg0.getId()){
case R.id.generateButton:
generateContentToSpell();
break;
case R.id.actionButton:
if(needToBeStopped){
rec.stopThread();
needToBeStopped = false;
action.setText(this.getString(R.string.start));
}else{
rec = new MyRecorder(audioq);
mr = new MyReader(audioq);
rec.start();
mr.start();
needToBeStopped = true;
action.setText(this.getString(R.string.stop));
}
break;
}
}
private class MyRecorder extends Thread{
private static final int freq = 22050;
private static final int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
private static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
private final BlockingQueue<byte[] > myRecAudioq;
private AudioRecord recorder;
private boolean recording = false;
int bufferSize;
/*konstruktor*/
public MyRecorder(BlockingQueue<byte[]> q ){
bufferSize = AudioRecord.getMinBufferSize(freq, channelConfiguration, audioEncoding);
myRecAudioq = q;
}
public void run(){
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
freq, channelConfiguration,
audioEncoding, 3*bufferSize);
recorder.startRecording();
recording = true;
byte[] buffer = new byte[bufferSize];
while(recording){
int readBufferSize = recorder.read(buffer, 0, bufferSize);
if(readBufferSize>0){
try {
myRecAudioq.put(buffer);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public void stopThread(){
recorder.stop();
recording = false;
byte[] buffer = new byte[bufferSize];
for(int i=0;i<bufferSize;i++){
buffer[i] =(byte) 0xff;
}
try {
myRecAudioq.put(buffer);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private class MyReader extends Thread{
private final BlockingQueue<byte[]> bq;
private static final int freq = 22050;
private static final int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
private static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
private int counter = 0;
public MyReader(BlockingQueue<byte[]> q){
bq = q;
}
public void run(){
int buffSize = AudioRecord.getMinBufferSize(freq, channelConfiguration, audioEncoding);
byte[] compareBuffer= new byte[buffSize];
for(int i=0;i<buffSize;i++){
compareBuffer[i] = (byte)0xff;
}
boolean reading = true;
byte[] buffer = null;
do{
try {
buffer = bq.take();
reading = buffer.equals(compareBuffer);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(reading){
int c=1;
}
}while(!reading);
int a=5;
}
}
}
公共类SpellCollectorActivity扩展了活动实现OnClickListener{
专用ArrayBlockingQueue audioq;
布尔值needToBeStopped=false;
按钮生成,动作;
私人MyRecorder rec;
私人读物mr;
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
action=(按钮)findViewById(R.id.actionButton);
action.setOnClickListener(this);
needToBeStopped=false;
audioq=新阵列锁定队列(容量);
}
公共void onClick(视图arg0){
开关(arg0.getId()){
案例R.id.generateButton:
generateContentsPell();
打破
案例R.id.actionButton:
如果(需要禁用){
建议停止线程();
needToBeStopped=false;
action.setText(this.getString(R.string.start));
}否则{
rec=新的MyRecorder(audioq);
mr=新MyReader(audioq);
rec.start();
斯塔特先生();
needtobstopped=true;
action.setText(this.getString(R.string.stop));
}
打破
}
}
私有类MyRecorder扩展线程{
专用静态最终内部频率=22050;
专用静态最终int通道配置=AudioFormat.CHANNEL\u CONFIGURATION\u MONO;
专用静态最终整数音频编码=AudioFormat.ENCODING_PCM_16位;
私有最终阻塞队列myRecAudioq;
私人录音机;
私有布尔记录=假;
int缓冲区大小;
/*康斯特鲁克托*/
公共MyRecorder(阻塞队列q){
bufferSize=AudioRecord.getMinBufferSize(频率、通道配置、音频编码);
myRecAudioq=q;
}
公开募捐{
录音机=新的录音机(MediaRecorder.AudioSource.MIC,
频率,信道配置,
音频编码,3*缓冲区大小);
记录器。开始记录();
记录=真;
字节[]缓冲区=新字节[bufferSize];
同时(录音){
int readBufferSize=recorder.read(buffer,0,bufferSize);
如果(readBufferSize>0){
试一试{
myRecAudioq.put(缓冲区);
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
}
}
公共void stopThread(){
录音机。停止();
记录=假;
字节[]缓冲区=新字节[bufferSize];
对于(int i=0;i而言,'reading'的值是两个字节[]之间的比较
只有当它们都是相同的对象(指针,如果您愿意),也就是说,如果您首先调用buffer=compareBuffer
实际上,您要做的是比较缓冲区的所有元素,例如使用java.util.Arrays
类:
reading = Arrays.equals(compareBuffer, buffer);
谢谢。但我发现了一件有趣的事情。阅读在一瞬间变得同样正确,但我的问题中的代码行还没有到达。我刚刚记得我的朋友在Eclipse中调试代码时遇到了类似的问题,阅读正确的唯一时刻是在声明之后