mirror of https://github.com/tasks/tasks
Infrastructure for general recording, but getting buffer overflows
parent
82b24dd977
commit
e542b985b3
@ -0,0 +1,87 @@
|
|||||||
|
package com.todoroo.aacenc;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.media.AudioFormat;
|
||||||
|
import android.media.AudioRecord;
|
||||||
|
import android.media.MediaRecorder.AudioSource;
|
||||||
|
|
||||||
|
public class AACRecorder implements AudioRecord.OnRecordPositionUpdateListener {
|
||||||
|
|
||||||
|
private AudioRecord audioRecord;
|
||||||
|
private AACEncoder encoder;
|
||||||
|
private Context context;
|
||||||
|
private String tempFile;
|
||||||
|
|
||||||
|
private boolean recording;
|
||||||
|
|
||||||
|
private static final int SAMPLE_RATE = 16000;
|
||||||
|
private static final int NOTIFICATION_PERIOD = 160;
|
||||||
|
private static final int MIN_BUFFER_SIZE = AudioRecord.getMinBufferSize(SAMPLE_RATE,
|
||||||
|
AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT) * 3;
|
||||||
|
|
||||||
|
private byte[] buffer = new byte[NOTIFICATION_PERIOD * 2];
|
||||||
|
|
||||||
|
public AACRecorder(Context context) {
|
||||||
|
encoder = new AACEncoder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void startRecording(String tempFile) {
|
||||||
|
if (recording)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.tempFile = tempFile;
|
||||||
|
audioRecord = new AudioRecord(AudioSource.MIC, SAMPLE_RATE, AudioFormat.CHANNEL_CONFIGURATION_MONO,
|
||||||
|
AudioFormat.ENCODING_PCM_16BIT, MIN_BUFFER_SIZE);
|
||||||
|
|
||||||
|
audioRecord.setPositionNotificationPeriod(NOTIFICATION_PERIOD);
|
||||||
|
audioRecord.setRecordPositionUpdateListener(this);
|
||||||
|
|
||||||
|
encoder.init(64000, 1, SAMPLE_RATE, 16, tempFile);
|
||||||
|
|
||||||
|
recording = true;
|
||||||
|
audioRecord.startRecording();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void stopRecording() {
|
||||||
|
if (!recording)
|
||||||
|
return;
|
||||||
|
|
||||||
|
audioRecord.stop();
|
||||||
|
audioRecord.release();
|
||||||
|
recording = false;
|
||||||
|
encoder.uninit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized boolean convert(String outFile) {
|
||||||
|
if (recording || tempFile == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
new AACToM4A().convert(context, tempFile, outFile);
|
||||||
|
tempFile = null;
|
||||||
|
return true;
|
||||||
|
} catch (IOException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMarkerReached(AudioRecord recorder) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPeriodicNotification(AudioRecord recorder) {
|
||||||
|
int bytesRead = recorder.read(buffer, 0, buffer.length);
|
||||||
|
if (bytesRead < 0) {
|
||||||
|
System.err.println("ERROR " + bytesRead);
|
||||||
|
stopRecording();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
encoder.encode(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,107 @@
|
|||||||
|
package com.todoroo.astrid.files;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.ProgressDialog;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.View.OnClickListener;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.timsu.astrid.R;
|
||||||
|
import com.todoroo.aacenc.AACRecorder;
|
||||||
|
import com.todoroo.aacenc.AACToM4A;
|
||||||
|
import com.todoroo.andlib.utility.DateUtilities;
|
||||||
|
import com.todoroo.andlib.utility.DialogUtilities;
|
||||||
|
import com.todoroo.astrid.service.ThemeService;
|
||||||
|
|
||||||
|
public class AACRecordingActivity extends Activity {
|
||||||
|
|
||||||
|
public static final String EXTRA_TEMP_FILE = "tempFile"; //$NON-NLS-1$
|
||||||
|
public static final String EXTRA_TASK_ID = "taskId"; //$NON-NLS-1$
|
||||||
|
public static final String RESULT_OUTFILE = "outfile"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
private AACRecorder recorder;
|
||||||
|
private String tempFile;
|
||||||
|
private long taskId;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
setContentView(R.layout.aac_record_activity);
|
||||||
|
|
||||||
|
setupUi();
|
||||||
|
|
||||||
|
tempFile = getIntent().getStringExtra(EXTRA_TEMP_FILE);
|
||||||
|
taskId = getIntent().getLongExtra(EXTRA_TASK_ID, 0L);
|
||||||
|
|
||||||
|
recorder = new AACRecorder(this);
|
||||||
|
recorder.startRecording(tempFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupUi() {
|
||||||
|
View stopRecording = findViewById(R.id.stop_recording);
|
||||||
|
stopRecording.setBackgroundColor(getResources().getColor(ThemeService.getThemeColor()));
|
||||||
|
|
||||||
|
stopRecording.setOnClickListener(new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
System.err.println("On click");
|
||||||
|
stopRecording();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
View dismiss = findViewById(R.id.dismiss);
|
||||||
|
dismiss.setOnClickListener(new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
recorder.stopRecording();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
TextView speechBubble = (TextView) findViewById(R.id.reminder_message);
|
||||||
|
speechBubble.setText(R.string.audio_speak_now);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("nls")
|
||||||
|
private void stopRecording() {
|
||||||
|
System.err.println("Stopping...");
|
||||||
|
recorder.stopRecording();
|
||||||
|
System.err.println("Stopped recorder");
|
||||||
|
|
||||||
|
ProgressDialog pd = DialogUtilities.progressDialog(this, "Encoding...");
|
||||||
|
pd.show();
|
||||||
|
System.err.println("Passed pd");
|
||||||
|
try {
|
||||||
|
StringBuilder filePathBuilder = new StringBuilder();
|
||||||
|
filePathBuilder.append(getExternalFilesDir("audio").toString())
|
||||||
|
.append("/")
|
||||||
|
.append(taskId)
|
||||||
|
.append("_")
|
||||||
|
.append(DateUtilities.now())
|
||||||
|
.append("_audio.mp4");
|
||||||
|
|
||||||
|
String outFile = filePathBuilder.toString();
|
||||||
|
System.err.println("Converting");
|
||||||
|
new AACToM4A().convert(this, tempFile, outFile);
|
||||||
|
System.err.println("Finished Converting");
|
||||||
|
|
||||||
|
Intent result = new Intent();
|
||||||
|
result.putExtra(RESULT_OUTFILE, outFile);
|
||||||
|
setResult(RESULT_OK, result);
|
||||||
|
System.err.println("Finishing");
|
||||||
|
finish();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
Toast.makeText(this, "Error :(", Toast.LENGTH_LONG);
|
||||||
|
}
|
||||||
|
pd.dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:gravity="center">
|
||||||
|
|
||||||
|
<include layout="@layout/astrid_record_audio_view"/>
|
||||||
|
</LinearLayout>
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/reminder_root"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="10dip"
|
||||||
|
android:layout_marginRight="10dip"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:background="@drawable/reminder_dialog_background">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_marginTop="5dip"
|
||||||
|
android:layout_marginRight="5dip"
|
||||||
|
android:layout_marginBottom="15dip"
|
||||||
|
android:layout_marginLeft="10dip">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/reminder_title"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="1dip"
|
||||||
|
android:textSize="24sp"
|
||||||
|
android:textColor="@android:color/white"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/audio_recording_title"/>
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/dismiss"
|
||||||
|
android:layout_width="25dip"
|
||||||
|
android:layout_height="25dip"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
android:src="@drawable/ic_menu_close"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/stop_recording"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="35dip"
|
||||||
|
android:layout_marginLeft="10dip"
|
||||||
|
android:layout_marginRight="10dip"
|
||||||
|
android:layout_marginBottom="10dip"
|
||||||
|
android:textColor="@android:color/white"
|
||||||
|
android:textSize="24sp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/audio_stop_recording"/>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/missed_calls_speech_bubble"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
<include layout="@layout/astrid_speech_bubble" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
Loading…
Reference in New Issue