Infrastructure for general recording, but getting buffer overflows

pull/14/head
Sam Bosley 13 years ago
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);
}
}

@ -500,6 +500,12 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<!-- files -->
<activity android:name="com.todoroo.astrid.files.AACRecordingActivity"
android:configChanges="orientation|screenSize"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Dialog"/>
<!-- locale -->
<activity android:name="com.todoroo.astrid.locale.LocaleEditAlerts"

@ -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();
}
}

@ -60,6 +60,11 @@ public class FilesControlSet extends PopupControlSet {
@Override
public void readFromTask(Task task) {
super.readFromTask(task);
refreshDisplayView();
}
public void refreshMetadata() {
TodorooCursor<Metadata> cursor = metadataService.query(
Query.select(Metadata.PROPERTIES)
.where(MetadataCriteria.byTaskAndwithKey(model.getId(), FileMetadata.METADATA_KEY)));
@ -73,7 +78,8 @@ public class FilesControlSet extends PopupControlSet {
} finally {
cursor.close();
}
refreshDisplayView();
if (initialized)
afterInflate();
}
@Override

@ -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>

@ -9,4 +9,7 @@
<string name="premium_attach_file">Attach a file</string>
<string name="premium_record_audio">Record a note</string>
<string name="audio_recording_title">Recording Audio</string>
<string name="audio_stop_recording">Stop Recording</string>
<string name="audio_speak_now">Speak Now!</string>
</resources>

@ -69,7 +69,10 @@ import com.todoroo.andlib.utility.DialogUtilities;
import com.todoroo.andlib.utility.Preferences;
import com.todoroo.astrid.actfm.EditPeopleControlSet;
import com.todoroo.astrid.actfm.sync.ActFmPreferenceService;
import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.files.AACRecordingActivity;
import com.todoroo.astrid.files.FileMetadata;
import com.todoroo.astrid.files.FilesControlSet;
import com.todoroo.astrid.gcal.GCalControlSet;
import com.todoroo.astrid.helper.TaskEditControlSet;
@ -151,6 +154,7 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener {
public static final int REQUEST_LOG_IN = 0;
private static final int REQUEST_VOICE_RECOG = 10;
public static final int REQUEST_CODE_CONTACT = 20;
public static final int REQUEST_CODE_RECORD = 30;
// --- menu codes
@ -205,6 +209,7 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener {
private EditNotesControlSet notesControlSet = null;
private HideUntilControlSet hideUntilControls = null;
private TagsControlSet tagsControlSet = null;
private FilesControlSet filesControlSet = null;
private TimerActionControlSet timerAction;
private EditText title;
private TaskEditMoreControls moreControls;
@ -553,12 +558,12 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener {
controls.add(timerControl);
controlSetMap.put(getString(R.string.TEA_ctrl_timer_pref), timerControl);
FilesControlSet filesControl = new FilesControlSet(getActivity(),
filesControlSet = new FilesControlSet(getActivity(),
R.layout.control_set_files,
R.layout.control_set_files_display,
R.string.TEA_control_files);
controls.add(filesControl);
controlSetMap.put(getString(R.string.TEA_ctrl_files_pref), filesControl);
controls.add(filesControlSet);
controlSetMap.put(getString(R.string.TEA_ctrl_files_pref), filesControlSet);
try {
if (ProducteevUtilities.INSTANCE.isLoggedIn()) {
@ -990,6 +995,13 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener {
Toast.LENGTH_SHORT).show();
}
private void startRecordingAudio() {
Intent recordAudio = new Intent(getActivity(), AACRecordingActivity.class);
recordAudio.putExtra(AACRecordingActivity.EXTRA_TEMP_FILE, getActivity().getFilesDir() + "/" + "audio.aac");
recordAudio.putExtra(AACRecordingActivity.EXTRA_TASK_ID, model.getId());
startActivityForResult(recordAudio, REQUEST_CODE_RECORD);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
@ -1006,7 +1018,7 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener {
System.err.println("Attach file!"); //$NON-NLS-1$
return true;
case MENU_RECORD_ID:
System.err.println("Record audio!"); //$NON-NLS-1$
startRecordingAudio();
return true;
case MENU_COMMENTS_REFRESH_ID: {
editNotes.refreshData(true, null);
@ -1098,6 +1110,11 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener {
// onResume.populateFields
// (due to the activity-change)
notesControlSet.writeToModel(model);
} else if (requestCode == REQUEST_CODE_RECORD && resultCode == Activity.RESULT_OK) {
String recordedAudio = data.getStringExtra(AACRecordingActivity.RESULT_OUTFILE);
Metadata fileMetadata = FileMetadata.createNewFileMetadata(model.getId(), recordedAudio, FileMetadata.FILE_TYPE_AUDIO);
metadataService.save(fileMetadata);
filesControlSet.refreshMetadata();
}
// respond to sharing logoin

Loading…
Cancel
Save