Record audio played on AudioTrack?

大兔子大兔子 提交于 2019-12-13 04:44:08

问题


I have an android app that plays a generated tone on an AudioTrack, so my question is: is there a way to record whatever is played on that AudioTrack(it's started, stopped, written to, and released frequently), be able to play it back, and save it to the music library?

The class that plays the music:

package com.example.test;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.Bundle;
import android.os.Handler;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;

public class Afspl extends Activity {

    public DrawView vi;
    private Point size;
    Display disp;
    public int wide, high, cx, cy;
    boolean doPlay = false;
    Thread soundPlayer;


    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        disp = getWindowManager().getDefaultDisplay();
        try{
            disp.getSize(size);
            wide = size.x;
            high = size.y;
        }catch(Exception e){
            wide = disp.getWidth();
            high = disp.getHeight();
        }

        cx = 0; //tracks mouse x
        cy = 0; //tracks mouse y
        vi = new DrawView(getApplicationContext());
        setContentView(vi);
        soundPlayer = new Thread(new Runnable(){
            public void run(){
                int count = 0;
                while(true){
                    try{
                    Thread.sleep((long)(duration * 10));
                    }catch(Exception e){}
                    if(!doPlay){
                        if(count==1)track.stop();
                        continue;
                    }
                    int note = cy * 24 / high;
                    int freq = (int)(440 * Math.pow(1.059463, note));
                    genTone(freq);
                    if(count==0){
                    handler.post(new Runnable(){
                        public void run(){
                            playSound();
                        }
                    });
                    count++;
                    }else{
                        handler.post(new Runnable(){
                            public void run(){
                                track.release();
                                playSound();
                            }
                        });
                    }
                }
            }
        });
        soundPlayer.start();
    }

    class DrawView extends View{
        Paint paint = new Paint();

        public DrawView(Context context){
            super(context);
        }

        public void onDraw(final Canvas c){
            for(int i=0; i<24; i++){

            }
        }

        public String rgbToString(float r, float g, float b){
            return Integer.toHexString((int)(r * 256)) + Integer.toHexString((int)(g * 256)) + Integer.toHexString((int)(b * 256));
        }

    }

    public boolean onTouchEvent(MotionEvent me){
        int type = me.getActionMasked();
        switch(type){
        case MotionEvent.ACTION_DOWN:
            doPlay = true;
            cx = (int)me.getX();
            cy = (int)me.getY();
            return true;
        case MotionEvent.ACTION_UP:
            doPlay = false;
            return true;
        case MotionEvent.ACTION_MOVE:
            cx = (int)me.getX();
            cy = (int)me.getY();
            return true;
        default:
            return super.onTouchEvent(me);
        }
    }

    public double duration = 1;
    public int sampleRate = 8000;
    public int numSamples = (int)duration * sampleRate;
    public final double[] samples = new double[numSamples];
    public final byte[] generatedSnd = new byte[numSamples * 2];
    public Handler handler = new Handler();
    AudioTrack track;


    public void genTone(int freq){
        for(int i = 0; i<numSamples; i++){
            samples[i] = Math.pow(-1, i / (sampleRate/freq));
        }
        int idx = 0;
        int volume = 32767 * cx/wide;
        for (final double dVal : samples) {
            final short val = (short) ((dVal+1) * volume);

            generatedSnd[idx++] = (byte) (val & 0x00ff);
            generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8);
        }
    }


    public void playSound(){
        track = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, generatedSnd.length, AudioTrack.MODE_STATIC);
        track.write(generatedSnd, 0, generatedSnd.length);
        track.play();
    }


}

So can you give me some code that will allow me to record what's played on the AudioTrack 'track', with as little modification to what code I already have? Thanks(Just ignore the onDraw for now).

EDIT: I suppose this will make the question more specific: if I write a bunch of individual audio samples onto an ArrayList, how can I then write those samples onto a music file and save it to the music library?

来源:https://stackoverflow.com/questions/27296929/record-audio-played-on-audiotrack

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!