add stereo/mono
This commit is contained in:
parent
04185ab9f2
commit
9755c13ea3
14 changed files with 76 additions and 36 deletions
|
|
@ -427,7 +427,7 @@ public class RecordingActivity extends AppCompatActivity {
|
|||
final SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
|
||||
int rate = Integer.parseInt(shared.getString(MainApplication.PREFERENCE_RATE, ""));
|
||||
int m = RawSamples.CHANNEL_CONFIG == AudioFormat.CHANNEL_IN_MONO ? 1 : 2;
|
||||
int m = MainApplication.getChannels(this);
|
||||
int c = RawSamples.AUDIO_FORMAT == AudioFormat.ENCODING_PCM_16BIT ? 2 : 1;
|
||||
|
||||
long perSec = (c * m * rate);
|
||||
|
|
@ -582,15 +582,15 @@ public class RecordingActivity extends AppCompatActivity {
|
|||
|
||||
rs.open(samplesTime);
|
||||
|
||||
int min = AudioRecord.getMinBufferSize(sampleRate, RawSamples.CHANNEL_CONFIG, RawSamples.AUDIO_FORMAT);
|
||||
int min = AudioRecord.getMinBufferSize(sampleRate, MainApplication.getMode(RecordingActivity.this), RawSamples.AUDIO_FORMAT);
|
||||
if (min <= 0) {
|
||||
throw new RuntimeException("Unable to initialize AudioRecord: Bad audio values");
|
||||
}
|
||||
|
||||
// min = 1 sec
|
||||
min = Math.max(sampleRate * (RawSamples.CHANNEL_CONFIG == AudioFormat.CHANNEL_IN_MONO ? 1 : 2), min);
|
||||
min = Math.max(sampleRate * (MainApplication.getChannels(RecordingActivity.this)), min);
|
||||
|
||||
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRate, RawSamples.CHANNEL_CONFIG, RawSamples.AUDIO_FORMAT, min);
|
||||
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRate, MainApplication.getMode(RecordingActivity.this), RawSamples.AUDIO_FORMAT, min);
|
||||
if (recorder.getState() != AudioRecord.STATE_INITIALIZED) {
|
||||
throw new RuntimeException("Unable to initialize AudioRecord");
|
||||
}
|
||||
|
|
@ -600,7 +600,7 @@ public class RecordingActivity extends AppCompatActivity {
|
|||
|
||||
int samplesTimeCount = 0;
|
||||
// how many samples we need to update 'samples'. time clock. every 1000ms.
|
||||
int samplesTimeUpdate = 1000 / 1000 * sampleRate * (RawSamples.CHANNEL_CONFIG == AudioFormat.CHANNEL_IN_MONO ? 1 : 2);
|
||||
int samplesTimeUpdate = 1000 / 1000 * sampleRate * MainApplication.getChannels(RecordingActivity.this);
|
||||
|
||||
short[] buffer = null;
|
||||
|
||||
|
|
@ -622,15 +622,16 @@ public class RecordingActivity extends AppCompatActivity {
|
|||
|
||||
start = end;
|
||||
|
||||
int s = RawSamples.CHANNEL_CONFIG == AudioFormat.CHANNEL_IN_MONO ? readSize : readSize / 2;
|
||||
int s = readSize / MainApplication.getChannels(RecordingActivity.this);
|
||||
|
||||
if (stableRefresh || diff >= s) {
|
||||
stableRefresh = true;
|
||||
|
||||
rs.write(buffer);
|
||||
|
||||
for (int i = 0; i < readSize; i += samplesUpdate) {
|
||||
final double dB = RawSamples.getDB(buffer, i, samplesUpdate);
|
||||
int ps = samplesUpdate * MainApplication.getChannels(RecordingActivity.this);
|
||||
for (int i = 0; i < readSize; i += ps) {
|
||||
final double dB = RawSamples.getDB(buffer, i, ps);
|
||||
handle.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
|
@ -707,7 +708,7 @@ public class RecordingActivity extends AppCompatActivity {
|
|||
samplesUpdate = this.samplesUpdate;
|
||||
}
|
||||
|
||||
bufferSize = RawSamples.CHANNEL_CONFIG == AudioFormat.CHANNEL_IN_MONO ? samplesUpdate : samplesUpdate * 2;
|
||||
bufferSize = samplesUpdate * MainApplication.getChannels(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -756,7 +757,7 @@ public class RecordingActivity extends AppCompatActivity {
|
|||
}
|
||||
|
||||
EncoderInfo getInfo() {
|
||||
final int channels = RawSamples.CHANNEL_CONFIG == AudioFormat.CHANNEL_IN_STEREO ? 2 : 1;
|
||||
final int channels = MainApplication.getChannels(this);
|
||||
final int bps = RawSamples.AUDIO_FORMAT == AudioFormat.ENCODING_PCM_16BIT ? 16 : 8;
|
||||
|
||||
return new EncoderInfo(channels, sampleRate, bps);
|
||||
|
|
@ -768,7 +769,7 @@ public class RecordingActivity extends AppCompatActivity {
|
|||
|
||||
File parent = targetFile.getParentFile();
|
||||
|
||||
if(!parent.exists()) {
|
||||
if (!parent.exists()) {
|
||||
if (!parent.mkdirs()) { // in case if it were manually deleted
|
||||
throw new RuntimeException("Unable to create: " + parent);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -262,6 +262,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity implements Sha
|
|||
|
||||
bindPreferenceSummaryToValue(findPreference(MainApplication.PREFERENCE_RATE));
|
||||
bindPreferenceSummaryToValue(findPreference(MainApplication.PREFERENCE_THEME));
|
||||
bindPreferenceSummaryToValue(findPreference(MainApplication.PREFERENCE_CHANNELS));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -3,10 +3,8 @@ package com.github.axet.audiorecorder.app;
|
|||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.TypedArray;
|
||||
import android.media.AudioFormat;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
|
||||
import com.github.axet.androidlibrary.widgets.ThemeUtils;
|
||||
import com.github.axet.audiorecorder.R;
|
||||
|
|
@ -19,6 +17,7 @@ public class MainApplication extends Application {
|
|||
public static final String PREFERENCE_ENCODING = "encoding";
|
||||
public static final String PREFERENCE_LAST = "last_recording";
|
||||
public static final String PREFERENCE_THEME = "theme";
|
||||
public static final String PREFERENCE_CHANNELS = "channels";
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
|
|
@ -109,4 +108,20 @@ public class MainApplication extends Application {
|
|||
return str;
|
||||
}
|
||||
|
||||
public static int getChannels(Context context) {
|
||||
final SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
int i = Integer.parseInt(shared.getString(MainApplication.PREFERENCE_CHANNELS, "1"));
|
||||
return i;
|
||||
}
|
||||
|
||||
public static int getMode(Context context) {
|
||||
switch (getChannels(context)) {
|
||||
case 1:
|
||||
return AudioFormat.CHANNEL_IN_MONO;
|
||||
case 2:
|
||||
return AudioFormat.CHANNEL_IN_STEREO;
|
||||
default:
|
||||
throw new RuntimeException("unknown mode");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ import java.nio.channels.FileChannel;
|
|||
|
||||
public class RawSamples {
|
||||
public static int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
|
||||
public static int CHANNEL_CONFIG = AudioFormat.CHANNEL_IN_MONO;
|
||||
|
||||
// quite root gives me 20db
|
||||
public static int NOISE_DB = 20;
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@ import android.media.AudioManager;
|
|||
import android.media.AudioTrack;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
import com.github.axet.audiorecorder.activities.RecordingActivity;
|
||||
|
||||
public class Sound {
|
||||
Context context;
|
||||
|
||||
|
|
@ -56,11 +54,16 @@ public class Sound {
|
|||
|
||||
int c = 0;
|
||||
|
||||
if (RawSamples.CHANNEL_CONFIG == AudioFormat.CHANNEL_IN_MONO)
|
||||
c = AudioFormat.CHANNEL_OUT_MONO;
|
||||
|
||||
if (RawSamples.CHANNEL_CONFIG == AudioFormat.CHANNEL_IN_STEREO)
|
||||
c = AudioFormat.CHANNEL_OUT_STEREO;
|
||||
switch (MainApplication.getChannels(context)) {
|
||||
case 1:
|
||||
c = AudioFormat.CHANNEL_OUT_MONO;
|
||||
break;
|
||||
case 2:
|
||||
c = AudioFormat.CHANNEL_OUT_STEREO;
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("unknown mode");
|
||||
}
|
||||
|
||||
// old phones bug.
|
||||
// http://stackoverflow.com/questions/27602492
|
||||
|
|
|
|||
|
|
@ -209,13 +209,13 @@ public class Storage {
|
|||
long x = rate;
|
||||
long y = (x - x1) * (y2 - y1) / (x2 - x1) + y1;
|
||||
|
||||
int m = RawSamples.CHANNEL_CONFIG == AudioFormat.CHANNEL_IN_MONO ? 1 : 2;
|
||||
int m = MainApplication.getChannels(context);
|
||||
long perSec = (y / 60) * m;
|
||||
return free / perSec * 1000;
|
||||
}
|
||||
|
||||
// default raw
|
||||
int m = RawSamples.CHANNEL_CONFIG == AudioFormat.CHANNEL_IN_MONO ? 1 : 2;
|
||||
int m = MainApplication.getChannels(context);
|
||||
int c = RawSamples.AUDIO_FORMAT == AudioFormat.ENCODING_PCM_16BIT ? 2 : 1;
|
||||
long perSec = (c * m * rate);
|
||||
return free / perSec * 1000;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package com.github.axet.audiorecorder.encoders;
|
|||
public interface Encoder {
|
||||
void encode(short[] buf, int len);
|
||||
|
||||
void flush();
|
||||
void end(); // flush stream. may throw state exceptions
|
||||
|
||||
void close();
|
||||
void close(); // release native resources, sholud not throw exceptions
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ public class FileEncoder {
|
|||
while (!Thread.currentThread().isInterrupted()) {
|
||||
int len = rs.read(buf);
|
||||
if (len <= 0) {
|
||||
encoder.flush();
|
||||
encoder.end();
|
||||
handler.post(done);
|
||||
return;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ public class FormatWAV implements Encoder {
|
|||
}
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
public void end() {
|
||||
try {
|
||||
outFile.seek(0);
|
||||
save();
|
||||
|
|
|
|||
|
|
@ -138,12 +138,6 @@ public class MuxerMP4 implements Encoder {
|
|||
return true;
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
end();
|
||||
encoder.stop();
|
||||
muxer.stop();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
encoder.release();
|
||||
muxer.release();
|
||||
|
|
@ -153,7 +147,7 @@ public class MuxerMP4 implements Encoder {
|
|||
return NumSamples * 1000 * 1000 / info.sampleRate;
|
||||
}
|
||||
|
||||
void end() {
|
||||
public void end() {
|
||||
if (input != null) {
|
||||
queue();
|
||||
}
|
||||
|
|
@ -165,6 +159,8 @@ public class MuxerMP4 implements Encoder {
|
|||
}
|
||||
while (encode())
|
||||
;// do encode()
|
||||
encoder.stop();
|
||||
muxer.stop();
|
||||
}
|
||||
|
||||
public EncoderInfo getInfo() {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,11 @@
|
|||
<item>.m4a</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="channels_text">
|
||||
<item>Моно (по умолчанию)</item>
|
||||
<item>Стерео</item>
|
||||
</string-array>
|
||||
|
||||
<string name="title_activity_main">Аудио Рекордер</string>
|
||||
<string name="action_settings">Настройки</string>
|
||||
<string name="not_permitted">Доступ запрещен</string>
|
||||
|
|
|
|||
|
|
@ -41,6 +41,16 @@
|
|||
<item>Theme_Dark</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="channels_text">
|
||||
<item>Mono (default)</item>
|
||||
<item>Stereo</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="channels_values" translatable="false">
|
||||
<item>1</item>
|
||||
<item>2</item>
|
||||
</string-array>
|
||||
|
||||
<string name="title_activity_main">Audio Recorder</string>
|
||||
<string name="action_settings">Settings</string>
|
||||
<string name="not_permitted">Not permitted</string>
|
||||
|
|
|
|||
|
|
@ -26,6 +26,16 @@
|
|||
android:summary="Output file formats (.wav, .m4a, ...)"
|
||||
android:title="Encoding" />
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="1"
|
||||
android:entries="@array/channels_text"
|
||||
android:entryValues="@array/channels_values"
|
||||
android:key="channels"
|
||||
android:negativeButtonText="@null"
|
||||
android:positiveButtonText="@null"
|
||||
android:summary="Recording channels"
|
||||
android:title="Mode" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="call"
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ buildscript {
|
|||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:2.2.0'
|
||||
classpath 'com.android.tools.build:gradle:2.2.1'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue