add stereo/mono

This commit is contained in:
Alexey Kuznetsov 2016-10-16 15:15:11 +03:00
commit 9755c13ea3
14 changed files with 76 additions and 36 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -111,7 +111,7 @@ public class FormatWAV implements Encoder {
}
}
public void flush() {
public void end() {
try {
outFile.seek(0);
save();

View file

@ -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() {

View file

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

View file

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

View file

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

View file

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