问题
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