<Android>pcm格式音频编解码及播放,socket文件传输通讯,soundTouch变声框架 合成的一款仿微信语音按住说话的demo

   pcm格式音频编解码及播放,socket文件传输通讯,soundTouch变声框架 合成的一款仿微信语音按住播放的demo

效果:

  ——————————————

代码:

MainActivity

public class MainActivity extends AppCompatActivity {
    private RelativeLayout mStartRecordBtn;
    private Button mStopRecordBtn;
    private Button mPlayAudioBtn;
    private Button mStopAudioBtn;
    private AudioUtil mAudioUtil;
    private static final int BUFFER_SIZE = 1024 * 2;
    private static byte[] mBuffer;
    private static File mAudioFile;
    private static ExecutorService mExecutorService;
    private static final String TAG = "MainActivity";
    private TextView ting;
    private TextView send;
    private ListView lv;
    int chat_index = 0;
    int revice_index = 0;
    private String local = Environment.getExternalStorageDirectory().getAbsolutePath() + "/record/local";
    private String message = Environment.getExternalStorageDirectory().getAbsolutePath() + "/record/message";
    private HashMap<String, File> datas;
    private ArrayList<DatasBean> datasBeans = new ArrayList<>();
    private MainActivity.myAdapter myAdapter;
    private File file_local;
    private File file_lmessage;
    private TextView ip_change;
    private AlertDialog show;
    private TextView ip_ssds;
    private LinearLayout show1;
    private LinearLayout show2;
    boolean TAG_T = true;
    int FileProt = 55239;
    String sdPath = Environment.getExternalStorageDirectory().getAbsolutePath()
            + "/record/message";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mStartRecordBtn = (RelativeLayout) findViewById(R.id.start_record_button);
        mStopRecordBtn = (Button) findViewById(R.id.stop_record_button);
        mPlayAudioBtn = (Button) findViewById(R.id.play_audio_button);
        mStopAudioBtn = (Button) findViewById(R.id.stop_audio_button);
        ting = (TextView) findViewById(R.id.ting);
        send = (TextView) findViewById(R.id.send);
        ip_change = (TextView) findViewById(R.id.ip_change);
        ip_ssds = (TextView) findViewById(R.id.ip_ssds);
        lv = (ListView) findViewById(R.id.lv);
        show1 = (LinearLayout) findViewById(R.id.show1);
        show2 = (LinearLayout) findViewById(R.id.show2);
        mBuffer = new byte[BUFFER_SIZE];

        file_local = new File(local);
        file_lmessage = new File(message);
        if (!file_local.exists()) {
            file_local.mkdir();
        }

        if (!file_lmessage.exists()) {
            file_lmessage.mkdir();
        }

        SharedPreferences userSettings = getSharedPreferences("ip_db", 0);
        SharedPreferences.Editor editor = userSettings.edit();
        editor.putString("ip", "192.168.199.159");
        editor.commit();

        getFileSize(file_local, file_lmessage);
        myAdapter = new myAdapter();
        lv.setAdapter(myAdapter);
        lv.setSelection(datasBeans.size() - 1);
        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {

                if (datasBeans.get(i).getType() == 1) {
                    mAudioFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
                            + "/record/local/selfRecord_" + datasBeans.get(i).getOrder() + ".pcm");
                } else if (datasBeans.get(i).getType() == 2) {
                    mAudioFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
                            + "/record/message/message_" + datasBeans.get(i).getOrder() + ".pcm");
                }
                playAudio(mAudioFile);
            }
        });


        ip_change.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                View doialogx = View.inflate(MainActivity.this, R.layout.doialog, null);
                builder.setView(doialogx);
                show = builder.show();

                TextView sava = (TextView) doialogx.findViewById(R.id.sava);
                final EditText et_v = (EditText) doialogx.findViewById(R.id.et_v);
                Log.e("", "" + et_v.getText().toString());

                sava.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        SharedPreferences userSettings = getSharedPreferences("ip_db", 0);
                        SharedPreferences.Editor editor = userSettings.edit();
                        editor.putString("ip", et_v.getText().toString().trim());
                        editor.commit();
                        show.dismiss();
                        SharedPreferences userSettingsxz = getSharedPreferences("ip_db", 0);
                        String name = userSettingsxz.getString("ip", "null");
                        ip_change.setText(name);
                        IP = name;
                    }
                });


            }
        });

        mStartRecordBtn.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent event) {

                // TODO Auto-generated methodstub
                switch (event.getAction()) {

                    case KeyEvent.ACTION_UP: {

                        mAudioUtil.stopRecord();
                        mAudioUtil.convertWavFile();
                        TAG_T = false;
                        show1.setVisibility(View.INVISIBLE);
                        show2.setVisibility(View.INVISIBLE);
                    }
                    case KeyEvent.ACTION_DOWN: {
                        //松开事件发生后执行代码的区域
                    }
                    default:

                        break;
                }
                return false;
            }
        });

        ip_ssds.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                getFileSize(file_local, file_lmessage);
                myAdapter.notifyDataSetChanged();
                lv.setSelection(datasBeans.size() - 1);
            }
        });
        mStartRecordBtn.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                Log.e("执行zh9ixing执行zh9ixing", "执行zh9ixing");

                TAG_T = true;
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        while (TAG_T) {
                            try {
                                Thread.sleep(100);
                                runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        if (show1.getVisibility() == View.VISIBLE) {
                                            show1.setVisibility(View.INVISIBLE);
                                            show2.setVisibility(View.INVISIBLE);
                                        } else {
                                            show1.setVisibility(View.VISIBLE);
                                            show2.setVisibility(View.VISIBLE);
                                        }
                                    }
                                });
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }).start();

                mAudioFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
                        + "/record/local/selfRecord_" + chat_index + ".pcm");
                mAudioUtil = new AudioUtil(chat_index);
                mAudioUtil.startRecord();
                mAudioUtil.recordData();
                chat_index++;
                return false;
            }
        });

        ting.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                playAudio(mAudioFile);
            }
        });
        send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                sendFileMessage();
                getFileSize(file_local, file_lmessage);
                myAdapter.notifyDataSetChanged();
                lv.setSelection(datasBeans.size() - 1);
            }
        });
        createFileServerSocket();//监听 收文件
    }


    class myAdapter extends BaseAdapter {
        @Override
        public int getCount() {
            return datasBeans.size();
        }

        @Override
        public Object getItem(int i) {
            return null;
        }

        @Override
        public long getItemId(int i) {
            return 0;
        }

        @Override
        public View getView(int i, View view, ViewGroup viewGroup) {
            View item = null;
            if (datasBeans.get(i).getType() == 2) {
                item = View.inflate(viewGroup.getContext(), R.layout.item_left, null);
            } else if (datasBeans.get(i).getType() == 1) {
                item = View.inflate(viewGroup.getContext(), R.layout.item_right, null);
            }
            TextView time = (TextView) item.findViewById(R.id.time);
            TextView tie_vice = (TextView) item.findViewById(R.id.tie_vice);
            ImageView llls = (ImageView) item.findViewById(R.id.llls);
            time.setText(getDateTimeByMillisecond(datasBeans.get(i).getCreateTime()));

            long count = datasBeans.get(i).getFile().length() / 44100 / 4;
            if (count < 1)
                count = 1;
            tie_vice.setText(count + "s");

            if (count < 2)
                count = 2;

            if (count > 7)
                count = 7;
            ViewGroup.LayoutParams para = llls.getLayoutParams();
            para.width = 100 * (int) count + 100;
            llls.setLayoutParams(para);
            return item;
        }
    }


    @Override
    protected void onResume() {
        super.onResume();
        SharedPreferences userSettings = getSharedPreferences("ip_db", 0);
        String name = userSettings.getString("ip", "192.168.199.159");
        ip_change.setText(name);
        IP = name;
    }

    // 获得文件夹内文件的个数。
    public void getFileSize(File file_local, File file_lmessage) {
        datasBeans.clear();
        try {
            File[] flist1 = file_local.listFiles();
            File[] flist2 = file_lmessage.listFiles();

            for (int i = 0; i < flist1.length; i++) {
                DatasBean datasBean = new DatasBean();
                datasBean.setFile(flist1[i]);
                datasBean.setType(1);
                datasBean.setCreateTime(flist1[i].lastModified());
                datasBean.setOrder(i);
                datasBeans.add(datasBean);
            }

            for (int i = 0; i < flist2.length; i++) {
                DatasBean datasBean = new DatasBean();
                datasBean.setFile(flist2[i]);
                datasBean.setType(2);
                datasBean.setCreateTime(flist2[i].lastModified());
                datasBean.setOrder(i);
                datasBeans.add(datasBean);
            }
            Comparator<DatasBean> comparator = new Comparator<DatasBean>() {
                public int compare(DatasBean s1, DatasBean s2) {
                    //先排年龄
                    if (s1.getCreateTime() < s2.getCreateTime()) {
                        return (int) (s1.getCreateTime() - s2.getCreateTime());
                    }
                    return 0;
                }
            };
            Collections.sort(datasBeans, comparator);
            for (int i = 0; i < datasBeans.size(); i++) {
                Log.e("", "时间跑徐:" + getDateTimeByMillisecond(datasBeans.get(i).getCreateTime()));
            }
        } catch (Exception e) {

        }
    }


    private boolean delZSPic(String filePath) {
        boolean flag = true;
        if (filePath != null) {
            File file = new File(filePath);
            if (file.exists()) {
                File[] filePaths = file.listFiles();
                for (File f : filePaths) {
                    if (f.isFile()) {
                        f.delete();
                    }
                    if (f.isDirectory()) {
                        String fpath = f.getPath();
                        delZSPic(fpath);
                        f.delete();
                    }
                }
            }
        } else {
            flag = false;
        }
        return flag;
    }

    private static void playAudio(File audioFile) {
        Log.d("MainActivity", "lu yin kaishi");
        int streamType = AudioManager.STREAM_MUSIC;
        int simpleRate = 44100;
        int channelConfig = AudioFormat.CHANNEL_OUT_STEREO;
        int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
        int mode = AudioTrack.MODE_STREAM;

        int minBufferSize = AudioTrack.getMinBufferSize(simpleRate, channelConfig, audioFormat);
        AudioTrack audioTrack = new AudioTrack(streamType, simpleRate, channelConfig, audioFormat,
                Math.max(minBufferSize, BUFFER_SIZE), mode);
        audioTrack.play();
        Log.d(TAG, minBufferSize + " is the min buffer size , " + BUFFER_SIZE + " is the read buffer size");
        FileInputStream inputStream = null;
        try {
            inputStream = new FileInputStream(audioFile);
            int read;
            while ((read = inputStream.read(mBuffer)) > 0) {
                Log.d("MainActivity", "lu yin kaishi11111");

                audioTrack.write(mBuffer, 0, read);
            }
        } catch (RuntimeException | IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        delZSPic(local);
        delZSPic(message);
    }


    /**
     * 启动线程 向服务器发送文件
     */
    private void sendFileMessage() {
        new Thread(runx).start();
    }

    //发送 线程等
    String IP = "192.168.199.159";
    String fliePath = Environment.getExternalStorageDirectory().getAbsolutePath()
            + "/record";
    int PORT = 55239;
    Runnable runx = new Runnable() {
        @Override
        public void run() {
            try {
                Socket socket = new Socket();
                socket.connect(new InetSocketAddress(IP, PORT));
                //获取输出流
                OutputStream ou = socket.getOutputStream();
                //读取服务器响应
                BufferedReader bff = new BufferedReader(new InputStreamReader(
                        socket.getInputStream()));
                String line = null;
                String buffer = "";
                while ((line = bff.readLine()) != null) {
                    buffer = line + buffer;
                }
                //向服务器发送文件
                File file = new File(fliePath);
                if (file.exists()) {
                    FileInputStream fileInput = new FileInputStream(mAudioFile);
                    DataOutputStream dos = new DataOutputStream(ou);
                    // 文件名
                    dos.writeUTF(file.getName());
                    byte[] bytes = new byte[1024];
                    int length = 0;
                    while ((length = fileInput.read(bytes)) != -1) {
                        dos.write(bytes, 0, length);
                    }
                    //告诉服务端,文件已传输完毕
                    socket.shutdownOutput();
                    fileInput.close();
                    dos.close();
                    //服务器返回码
                    Message message = new Message();
                    message.what = 2;
                    message.obj = buffer;
//                        handler.sendMessage(message);
                }
                //关闭各种输入输出流
                ou.flush();
                bff.close();
                ou.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    };



    /**
     * 创建服务端ServerSocket
     * 接收文件
     */
    private void createFileServerSocket() {
        new Thread(runs).start();
    }

    Handler handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message message) {
            getFileSize(file_local, file_lmessage);
            myAdapter.notifyDataSetChanged();
            lv.setSelection(datasBeans.size() - 1);
            return false;
        }
    });


    Runnable runs = new Runnable() {
        @Override
        public void run() {
            //给发送端返回一个消息,告诉他链接接收成功。
            String str = "200";
            try {
                ServerSocket serverSocket = new ServerSocket(FileProt);
                while (true) {
                    try {
                        //此处是线程阻塞的,所以需要在子线程中
                        Socket socket = serverSocket.accept();
                        //请求成功,响应客户端的请求
                        OutputStream out = socket.getOutputStream();
                        out.write(str.getBytes("utf-8"));
                        out.flush();
                        socket.shutdownOutput();
                        //获取输入流,读取客户端发送来的文件
                        DataInputStream dis = new DataInputStream(socket.getInputStream());
                        // 文件名和长度
                        String fileName = dis.readUTF();
                        //接收到的文件要存储的位置
                        File directory = new File(sdPath);
                        if (!directory.exists()) {
                            directory.mkdirs();
                        }
                        FileOutputStream fos = new FileOutputStream(directory.getAbsolutePath() + "/message_" + revice_index + ".pcm");
                        // 开始接收文件
                        byte[] bytes = new byte[1024];
                        int length = 0;
                        while ((length = dis.read(bytes, 0, bytes.length)) != -1) {
                            fos.write(bytes, 0, length);
                            fos.flush();
                        }
                        revice_index++;
                        handler.sendEmptyMessage(1);

                        dis.close();
                        fos.close();
                        out.close();
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }
    };

    public String getDateTimeByMillisecond(long str) {
        Date date = new Date(str);
        SimpleDateFormat format = new SimpleDateFormat("MM月dd日 HH:mm:ss");
        String time = format.format(date);
        return time;
    }

录制类:

public class AudioUtil
{
    private static AudioUtil mInstance;
    private AudioRecord recorder;
    //声音源
    private static int audioSource = MediaRecorder.AudioSource.MIC;
    //录音的采样频率
    private static int audioRate = 44100;
    //录音的声道,单声道
    private static int audioChannel = AudioFormat.CHANNEL_IN_STEREO;
    //量化的精度
    private static int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
    //缓存的大小
    private static int bufferSize = AudioRecord.getMinBufferSize(audioRate , audioChannel , audioFormat);
    //记录播放状态
    private boolean isRecording = false;
    //数字信号数组
    private byte[] noteArray;
    //PCM文件
    private File pcmFile;
    //wav文件
    private File wavFile;
    //文件输出流
    private OutputStream os;
    //文件根目录
    private String basePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/record/";
    //wav文件目录
    private String outFileName = basePath + "/encode.wav";
    //pcm文件目录
    private String inFileName = basePath + "/encode.pcm";

    int mIndex=0;
    public AudioUtil(int index)
    {
        this.mIndex=index;
        //创建文件
        createFile();
        recorder = new AudioRecord(audioSource , audioRate ,
                audioChannel , audioFormat , bufferSize);
    }

    //创建文件夹,首先创建目录,然后创建对应的文件
    private void createFile()
    {
        File baseFile = new File(basePath);
        if (!baseFile.exists())
            baseFile.mkdirs();
        pcmFile = new File(basePath + "/local/selfRecord_"+mIndex+".pcm");
        wavFile = new File(basePath + "/encode.wav");

        if (pcmFile.exists())
            pcmFile.delete();
        if (wavFile.exists())
            wavFile.delete();

        try
        {
            pcmFile.createNewFile();
            wavFile.createNewFile();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }








    //读取录音数字数据线程
    class WriteThread implements Runnable
    {
        @Override
        public void run()
        {
            writeData();
        }
    }

    //录音线程执行体
    private void writeData()
    {
        noteArray = new byte[bufferSize];
        //建立文件输出流
        try
        {
            os = new BufferedOutputStream(new FileOutputStream(pcmFile));
        }
        catch (FileNotFoundException e)
        {
            e.printStackTrace();
        }

        while (isRecording)
        {
            int recordSize = recorder.read(noteArray , 0 , bufferSize);
            if (recordSize > 0)
            {
                try
                {
                    os.write(noteArray);
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }




        if (os != null)
        {
            try
            {
                os.close();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
    }

    //开始录音
    public void startRecord()
    {
        isRecording = true;
        recorder.startRecording();
    }

    //记录数据
    public void recordData()
    {
        new Thread(new WriteThread()).start();
    }

    //停止录音
    public void stopRecord()
    {
        if (recorder != null)
        {
            isRecording = false;
            recorder.stop();
            recorder.release();
        }
    }

    //将pcm文件转换为wav文件
    public void convertWavFile()
    {
        FileInputStream in = null;
        FileOutputStream out = null;

        long totalAudioLen;
        long totalDataLen;
        long longSampleRate = AudioUtil.audioRate;
        int channels = 2;
        long byteRate = 16 * AudioUtil.audioRate * channels / 8;
        byte[] data = new byte[bufferSize];

        try
        {
            in = new FileInputStream(inFileName);
            out = new FileOutputStream(outFileName);
            totalAudioLen = in.getChannel().size();
            //由于不包括RIFF和WAV
            totalDataLen = totalAudioLen + 36;
            writeWaveFileHeader(out , totalAudioLen , totalDataLen , longSampleRate , channels , byteRate);
            while (in.read(data) != -1)
            {
                out.write(data);
            }

            in.close();
            out.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    private void writeWaveFileHeader(FileOutputStream out, long totalAudioLen, long totalDataLen,
                                     long longSampleRate, int channels, long byteRate) throws IOException
    {
        byte[] header = new byte[44];
        header[0] = 'R'; // RIFF
        header[1] = 'I';
        header[2] = 'F';
        header[3] = 'F';
        header[4] = (byte) (totalDataLen & 0xff);//数据大小
        header[5] = (byte) ((totalDataLen >> 8) & 0xff);
        header[6] = (byte) ((totalDataLen >> 16) & 0xff);
        header[7] = (byte) ((totalDataLen >> 24) & 0xff);
        header[8] = 'W';//WAVE
        header[9] = 'A';
        header[10] = 'V';
        header[11] = 'E';
        //FMT Chunk
        header[12] = 'f'; // 'fmt '
        header[13] = 'm';
        header[14] = 't';
        header[15] = ' ';//过渡字节
        //数据大小
        header[16] = 16; // 4 bytes: size of 'fmt ' chunk
        header[17] = 0;
        header[18] = 0;
        header[19] = 0;
        //编码方式 10H为PCM编码格式
        header[20] = 1; // format = 1
        header[21] = 0;
        //通道数
        header[22] = (byte) channels;
        header[23] = 0;
        //采样率,每个通道的播放速度
        header[24] = (byte) (longSampleRate & 0xff);
        header[25] = (byte) ((longSampleRate >> 8) & 0xff);
        header[26] = (byte) ((longSampleRate >> 16) & 0xff);
        header[27] = (byte) ((longSampleRate >> 24) & 0xff);
        //音频数据传送速率,采样率*通道数*采样位数/8
        header[28] = (byte) (byteRate & 0xff);
        header[29] = (byte) ((byteRate >> 8) & 0xff);
        header[30] = (byte) ((byteRate >> 16) & 0xff);
        header[31] = (byte) ((byteRate >> 24) & 0xff);
        //数据块的调整数(按字节算的),其值为通道数×每样本的数据位值/8
        header[32] = (byte) (16 / 8);
        header[33] = 0;
        //每个样本的数据位数
        header[34] = 16;
        header[35] = 0;
        //Data chunk
        header[36] = 'd';//data
        header[37] = 'a';
        header[38] = 't';
        header[39] = 'a';
        //语音数据大小
        header[40] = (byte) (totalAudioLen & 0xff);
        header[41] = (byte) ((totalAudioLen >> 8) & 0xff);
        header[42] = (byte) ((totalAudioLen >> 16) & 0xff);
        header[43] = (byte) ((totalAudioLen >> 24) & 0xff);
        out.write(header, 0, 44);
    }

播放类:

public class VoicePlayer
{
    private AudioTrack mAudioTrack;      //AudioTrack对象
    private AudioPlayThread mAudioPlayThread = null;
    private AudioParam mAudioParam;      //音频参数
    private int mPrimePlaySize = 0;      //较优播放块大小

    //设置音频参数
    public void setAudioParam(AudioParam audioParam)
    {
        mAudioParam = audioParam;
    }

    private void createAudioTrack()
    {
        if (mAudioTrack == null)
        {
            // 获得构建对象的最小缓冲区大小
            int minBufSize = AudioTrack.getMinBufferSize(mAudioParam.mFrequency ,
                    mAudioParam.mChannel , mAudioParam.mSampleBit);
            mPrimePlaySize = minBufSize;
            mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC , mAudioParam.mFrequency ,
                    mAudioParam.mChannel , mAudioParam.mSampleBit , mPrimePlaySize  , AudioTrack.MODE_STREAM);
        }
    }

    private void releaseAudioTrack()
    {
        if (mAudioTrack != null)
        {
            mAudioTrack.stop();
            mAudioTrack.release();
            mAudioTrack = null;
        }
    }

    //就绪播放源
    public void prepare()
    {
        if (mAudioParam != null)
        {
            createAudioTrack();
        }
    }

    public void play()
    {
        if (mAudioPlayThread == null)
        {
            mAudioPlayThread = new AudioPlayThread();
            mAudioPlayThread.start();
            if (mAudioPlayThread.mPlayHandler == null)
            {
                try
                {
                    Thread.sleep(1000);
                }
                catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
            }
        }
    }

    private void stop()
    {
        if (mAudioPlayThread != null)
        {
            mAudioPlayThread = null;
        }
    }

    public void release()
    {
        stop();
        releaseAudioTrack();
    }

    //设置音频源
    public void setDataSource(byte[] data)
    {
        if (mAudioPlayThread.mPlayHandler != null)
        {
            Message message = mAudioPlayThread.mPlayHandler.obtainMessage();
            message.what = 0x123;
            message.obj = data;
            mAudioPlayThread.mPlayHandler.sendMessage(message);
        }
    }

    class AudioPlayThread extends Thread
    {
        private Handler mPlayHandler;
        @Override
        public void run()
        {
            mAudioTrack.play();
            Looper.prepare();
            mPlayHandler = new Handler()
            {
                @Override
                public void handleMessage(Message msg)
                {
                    if (msg.what == 0x123)
                    {
                        mAudioTrack.write((byte[]) msg.obj, 0, ((byte[]) msg.obj).length);
                    }
                }
            };
            Looper.loop();
        }
    }

猜你喜欢

转载自blog.csdn.net/csdn_lg_one/article/details/86000547