音频应用

 找回密码
 快速注册

QQ登录

只需一步,快速开始

查看: 18550|回复: 0
收起左侧

[技术] android 设置线程的优先级

[复制链接]

6882

积分

3

听众

-1016

音贝

音频应用注册会员

Rank: 4Rank: 4

积分
6882
发表于 2006-6-26 00:58:00 | 显示全部楼层 |阅读模式
只能在真机上实现,模拟机不支持
本代码是俺借鉴的,并加入了详细的注解,主要用到AudioRecord,和AudioTrack两个类
简单说一下两个类的构造函数和基本方法:
AudioRecord
public AudioRecord (int audioSource, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes) 四个参数分别是
audioSource

音频源:指的是从哪里采集音频。这里我们当然是从麦克风采集音频,所以此参数的值为MIC
sampleRateInHz

采样率:音频的采样频率,每秒钟能够采样的次数,采样率越高,音质越高。给出的实例是44100、22050、11025但不限于这几个参数。例如要采集低质量的音频就可以使用4000、8000等低采样率。
channelConfig
声道设置:android支持双声道立体声和单声道。MONO单声道,STEREO立体声
audioFormat


编码制式和采样大小:采集来的数据当然使用PCM编码(脉冲代码调制编码,即PCM编码。PCM通过抽样、量化、编码三个步骤将连续变化的模拟信号转换为数字编码。) android支持的采样大小16bit 或者8bit。当然采样大小越大,那么信息量越多,音质也越高,现在主流的采样大小都是16bit,在低质量的语音传输的时候8bit 足够了。
bufferSizeInBytes
采集数据需要的缓冲区的大小,如果不知道最小需要的大小可以在getMinBufferSize()查看。
getMinBufferSize(frequency, channelConfiguration, audioEncoding);
AudioTrack类
AudioTrack比AudioRecord多出来一个参数
public AudioTrack (int streamType, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes,int mode)
其中streamType
<!--[if !supportLists]-->l         <!--[endif]-->STREAM_ALARM:警告声
<!--[if !supportLists]-->l         <!--[endif]-->STREAM_MUSCI:音乐声,例如music等
<!--[if !supportLists]-->l         <!--[endif]-->STREAM_RING:铃声
<!--[if !supportLists]-->l         <!--[endif]-->STREAM_SYSTEM:系统声音
<!--[if !supportLists]-->l         <!--[endif]-->STREAM_VOCIE_CALL:电话声音
其中mode
AudioTrack中有MODE_STATIC和MODE_STREAM两种分类。STREAM的意思是由用户在应用程序通过write方式把数据一次一次得写到audiotrack中。这个和我们在socket中发送数据一样,应用层从某个地方获取数据,例如通过编解码得到PCM数据,然后write到audiotrack。
这种方式的坏处就是总是在JAVA层和Native层交互,效率损失较大。
而STATIC的意思是一开始创建的时候,就把音频数据放到一个固定的buffer,然后直接传给audiotrack,后续就不用一次次得write了。AudioTrack会自己播放这个buffer中的数据。
这种方法对于铃声等内存占用较小,延时要求较高的声音来说很适用。
代码部分:
1.布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/hello"
    />
<Button android:text="开始边录边放" android:id="@+id/recordButton" android:layout_width="fill_parent" android:layout_height="wrap_content"></Button>
<Button android:text="停止" android:id="@+id/stopButton" android:layout_width="fill_parent" android:layout_height="wrap_content"></Button>
<Button android:text="退出" android:id="@+id/exitButton" android:layout_width="fill_parent" android:layout_height="wrap_content"></Button>
<TextView android:text="音量调节" android:id="@+id/textView1" android:layout_width="fill_parent" android:layout_height="wrap_content"></TextView>
<SeekBar android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/seekBar1"></SeekBar>
</LinearLayout>
2.为AudioRecord申请许可,修该AndroidManifes.xml如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.testrecord"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="9" />
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".textRecord"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
         
        </activity>
     <uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>
    </application>
</manifest>
3.主要实现代码:
import android.app.Activity;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.Toast;
public class textRecord extends Activity {
   Button recordButton,stopButton,exitButton;
   SeekBar skbVolume;
   boolean isRecording = false;
   static final int frequency = 44100;
   static final int channelConfiguration=AudioFormat.CHANNEL_CONFIGURATION_MONO;
   static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
   int recBufSize,playBufSize;
   AudioRecord audioRecord;
   AudioTrack audioTrack;
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        setTitle("助听器");
        //用getMinBufferSize()方法得到采集数据所需要的最小缓冲区的大小
        recBufSize = AudioRecord.getMinBufferSize(frequency, channelConfiguration, audioEncoding);
        playBufSize = AudioTrack.getMinBufferSize(frequency, channelConfiguration, audioEncoding);
        //实例化AudioRecord(声音来源,采样率,声道设置,采样声音编码,缓存大小)
        audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,frequency,channelConfiguration,audioEncoding,recBufSize);
        audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,frequency,channelConfiguration,audioEncoding,playBufSize,AudioTrack.MODE_STREAM);
        recordButton =(Button)this.findViewById(R.id.recordButton);
        stopButton =(Button) this.findViewById(R.id.stopButton);
        exitButton =(Button)this.findViewById(R.id.exitButton);
        recordButton.setOnClickListener(new ClickEvent());
        stopButton.setOnClickListener(new ClickEvent());
        exitButton.setOnClickListener(new ClickEvent());
        skbVolume = (SeekBar)this.findViewById(R.id.seekBar1);
        skbVolume.setMax(100);
        skbVolume.setProgress(70);
    // 设置声音大小
        audioTrack.setStereoVolume(0.7f, 0.7f);
        skbVolume.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
   
   
   public void onStopTrackingTouch(SeekBar seekBar) {
    float vol = (float)(seekBar.getProgress())/(float)(seekBar.getMax());
    audioTrack.setStereoVolume(vol, vol);
   
   }
   
   @Override
   public void onStartTrackingTouch(SeekBar seekBar) {
    // TODO Auto-generated method stub
   
   }
   
   @Override
   public void onProgressChanged(SeekBar seekBar, int progress,
     boolean fromUser) {
    // TODO Auto-generated method stub
   
   }
  });
    }
    protected void onDestroy(){
     super.onDestroy();
// 杀死当前进程
     android.os.Process.killProcess(android.os.Process.myPid());
    }
    class ClickEvent implements View.OnClickListener{
     public void onClick(View v){
      if(v == recordButton){
       isRecording = true;
       new RecordPlayThread().start();
      }else if(v == stopButton){
       isRecording = false;
      }else if(v== exitButton){
       isRecording = false;
       textRecord.this.finish();
      }
     }
    }
    class RecordPlayThread extends Thread{
     public void run(){
      try{
//byte 文件来存储声音
       byte[] buffer = new byte[recBufSize];
//开始采集声音
       audioRecord.startRecording();
//播放声音
       audioTrack.play();
       while(isRecording){
//从MIC存储到缓存区
        int bufferReadResult = audioRecord.read(buffer,0, recBufSize);
        byte[] tmpBuf = new byte[bufferReadResult];
        System.arraycopy(buffer, 0, tmpBuf, 0, bufferReadResult);
//播放缓存区的数据
        audioTrack.write(tmpBuf, 0, tmpBuf.length);

       }
       audioTrack.stop();
       audioRecord.stop();
      }catch(Throwable t){
       Toast.makeText(textRecord.this, t.getMessage(), 1000);
      }
     }
    };
}
音频应用
您需要登录后才可以回帖 登录 | 快速注册

本版积分规则

音频应用搜索

QQ|小黑屋|手机版|音频应用官网微博|音频应用 ( 鄂ICP备16002437号 )

GMT+8, 2025-6-7 15:04 , Processed in 0.022372 second(s), 6 queries , Redis On.

Powered by Audio app

快速回复 返回顶部 返回列表