diff --git a/app/build.gradle b/app/build.gradle
index 741d6a9..a675ff8 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -2,15 +2,15 @@ apply plugin: 'com.android.application'
apply plugin: 'com.github.axet.dxplugin'
android {
- compileSdkVersion 29
- buildToolsVersion '28.0.3'
+ compileSdkVersion 30
+ ndkVersion "16.1.4479499" // strip debug symbols
defaultConfig {
applicationId "com.github.axet.audiorecorder"
minSdkVersion 9
- targetSdkVersion 29
- versionCode 355
- versionName "3.4.5"
+ targetSdkVersion 30
+ versionCode 356
+ versionName "3.5.0"
}
signingConfigs {
release {
@@ -53,8 +53,7 @@ android {
dependencies {
testImplementation 'junit:junit:4.12'
- implementation 'com.github.axet:android-library:1.33.6'
- implementation ('com.github.axet:android-audio-library:1.0.180') { exclude module: 'android-library' } // implementation project(':android-audio-library')
+ implementation ('com.github.axet:android-audio-library:1.1.1') // implementation project(':android-audio-library')
implementation ('com.github.axet:wget:1.7.0') { exclude group: 'org.json', module: 'json' }
assets('com.google.android.exoplayer:exoplayer:2.7.3') { exclude group: 'com.android.support' }
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 60ca36d..d2c9784 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -23,7 +23,7 @@
android:roundIcon="@mipmap/ic_launcher"
android:supportsRtl="true"
android:theme="@style/Translucent">
-
+
0) {
- recording.dbBuffer = ShortBuffer.allocate(recording.samplesUpdateStereo);
+ recording.dbBuffer = new AudioTrack.SamplesBuffer(rs.info.format, recording.samplesUpdateStereo);
recording.dbBuffer.put(buf, lenUpdate, diff);
}
}
@@ -745,14 +747,14 @@ public class RecordingActivity extends AppCompatThemeActivity {
int rate = Integer.parseInt(shared.getString(AudioApplication.PREFERENCE_RATE, ""));
int m = Sound.getChannels(this);
- int c = Sound.DEFAULT_AUDIOFORMAT == AudioFormat.ENCODING_PCM_16BIT ? 2 : 1;
+ int c = RawSamples.getBytes(recording.info.format);
long perSec;
String ext = shared.getString(AudioApplication.PREFERENCE_ENCODING, "");
if (shared.getBoolean(AudioApplication.PREFERENCE_FLY, false)) {
- perSec = Factory.getEncoderRate(ext, recording.sampleRate);
+ perSec = Factory.getEncoderRate(Sound.getAudioFormat(this), ext, recording.sampleRate);
try {
free = Storage.getFree(this, recording.targetUri);
} catch (RuntimeException e) { // IllegalArgumentException
@@ -780,8 +782,8 @@ public class RecordingActivity extends AppCompatThemeActivity {
int playUpdate = PitchView.UPDATE_SPEED * recording.sampleRate / 1000;
- RawSamples rs = new RawSamples(recording.storage.getTempRecording());
- int len = (int) (rs.getSamples() - editSample * Sound.getChannels(this)); // in samples
+ RawSamples rs = new RawSamples(recording.storage.getTempRecording(), recording.info);
+ int len = (int) (rs.getSamples() - editSample * rs.info.channels); // in samples
final AudioTrack.OnPlaybackPositionUpdateListener listener = new AudioTrack.OnPlaybackPositionUpdateListener() {
@Override
@@ -799,8 +801,8 @@ public class RecordingActivity extends AppCompatThemeActivity {
}
};
- AudioTrack.AudioBuffer buf = new AudioTrack.AudioBuffer(recording.sampleRate, Sound.getOutMode(this), Sound.DEFAULT_AUDIOFORMAT, len);
- rs.open(editSample * Sound.getChannels(this), buf.len); // len in samples
+ AudioTrack.AudioBuffer buf = new AudioTrack.AudioBuffer(recording.sampleRate, Sound.getOutMode(this), rs.info.format, len);
+ rs.open(editSample * rs.info.channels, buf.len); // len in samples
int r = rs.read(buf.buffer); // r in samples
if (r != buf.len)
throw new RuntimeException("unable to read data");
@@ -827,8 +829,8 @@ public class RecordingActivity extends AppCompatThemeActivity {
if (editSample == -1)
return;
- RawSamples rs = new RawSamples(recording.storage.getTempRecording());
- rs.trunk((editSample + recording.samplesUpdate) * Sound.getChannels(this));
+ RawSamples rs = new RawSamples(recording.storage.getTempRecording(), recording.info);
+ rs.trunk((editSample + recording.samplesUpdate) * rs.info.channels);
rs.close();
edit(false, true);
@@ -924,8 +926,28 @@ public class RecordingActivity extends AppCompatThemeActivity {
editor.commit();
}
- void startRecording() {
+ boolean startRecording() {
try {
+ final SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(this);
+ String source = shared.getString(AudioApplication.PREFERENCE_SOURCE, getString(R.string.source_mic));
+ int user;
+ if (source.equals(getString(R.string.source_raw))) {
+ if (Sound.isUnprocessedSupported(this))
+ user = MediaRecorder.AudioSource.UNPROCESSED;
+ else
+ user = MediaRecorder.AudioSource.VOICE_RECOGNITION;
+ } else if (source.equals(this.getString(R.string.source_internal))) {
+ user = Sound.SOURCE_INTERNAL_AUDIO;
+ } else {
+ user = MediaRecorder.AudioSource.MIC;
+ }
+ if (user == Sound.SOURCE_INTERNAL_AUDIO && !recording.sound.permitted()) {
+ Sound.showInternalAudio(this, RESULT_INTERNAL);
+ return false;
+ }
+
+ recording.startRecording(user);
+
edit(false, true);
pitch.setOnTouchListener(null);
@@ -938,13 +960,13 @@ public class RecordingActivity extends AppCompatThemeActivity {
headset(true, true);
- recording.startRecording();
-
RecordingService.startService(this, Storage.getName(this, recording.targetUri), true, duration);
ControlsService.hideIcon(this);
+ return true;
} catch (RuntimeException e) {
Toast.Error(RecordingActivity.this, e);
finish();
+ return false;
}
}
@@ -970,6 +992,23 @@ public class RecordingActivity extends AppCompatThemeActivity {
Toast.makeText(this, R.string.not_permitted, Toast.LENGTH_SHORT).show();
finish();
}
+ break;
+ }
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ switch (requestCode) {
+ case RESULT_INTERNAL:
+ if (resultCode == RESULT_OK) {
+ recording.sound.onActivityResult(data);
+ startRecording();
+ } else {
+ Toast.makeText(this, R.string.not_permitted, Toast.LENGTH_SHORT).show();
+ finish();
+ }
+ break;
}
}
@@ -1042,7 +1081,7 @@ public class RecordingActivity extends AppCompatThemeActivity {
} else {
done.run();
}
- encoding = EncodingService.startEncoding(this, in, recording.targetUri, recording.getInfo());
+ encoding = EncodingService.startEncoding(this, in, recording.targetUri, recording.info);
}
@Override
diff --git a/app/src/main/java/com/github/axet/audiorecorder/activities/SettingsActivity.java b/app/src/main/java/com/github/axet/audiorecorder/activities/SettingsActivity.java
index f3a0944..4252431 100644
--- a/app/src/main/java/com/github/axet/audiorecorder/activities/SettingsActivity.java
+++ b/app/src/main/java/com/github/axet/audiorecorder/activities/SettingsActivity.java
@@ -99,7 +99,7 @@ public class SettingsActivity extends AppCompatSettingsThemeActivity implements
storage.migrateLocalStorageDialog(this);
if (key.equals(AudioApplication.PREFERENCE_RATE)) {
int sampleRate = Integer.parseInt(sharedPreferences.getString(AudioApplication.PREFERENCE_RATE, ""));
- if (sampleRate != Sound.getValidRecordRate(Sound.getInMode(this), sampleRate))
+ if (sampleRate != Sound.getValidRecordRate(Sound.getAudioFormat(this), Sound.getInMode(this), sampleRate))
Toast.Text(this, "Not supported Hz");
}
}
@@ -163,6 +163,7 @@ public class SettingsActivity extends AppCompatSettingsThemeActivity implements
bindPreferenceSummaryToValue(pm.findPreference(AudioApplication.PREFERENCE_CHANNELS));
bindPreferenceSummaryToValue(pm.findPreference(AudioApplication.PREFERENCE_FORMAT));
bindPreferenceSummaryToValue(pm.findPreference(AudioApplication.PREFERENCE_VOLUME));
+ bindPreferenceSummaryToValue(pm.findPreference(AudioApplication.PREFERENCE_AUDIOFORMAT));
StoragePathPreferenceCompat s = (StoragePathPreferenceCompat) pm.findPreference(AudioApplication.PREFERENCE_STORAGE);
s.setStorage(new Storage(getContext()));
@@ -189,6 +190,10 @@ public class SettingsActivity extends AppCompatSettingsThemeActivity implements
return true;
}
});
+
+ Preference af = pm.findPreference(AudioApplication.PREFERENCE_AUDIOFORMAT);
+ if (Build.VERSION.SDK_INT < 23 && af != null)
+ af.setVisible(false);
}
@Override
diff --git a/app/src/main/java/com/github/axet/audiorecorder/app/EncodingStorage.java b/app/src/main/java/com/github/axet/audiorecorder/app/EncodingStorage.java
index 82f760e..1cf7ac9 100644
--- a/app/src/main/java/com/github/axet/audiorecorder/app/EncodingStorage.java
+++ b/app/src/main/java/com/github/axet/audiorecorder/app/EncodingStorage.java
@@ -140,7 +140,7 @@ public class EncodingStorage extends HashMap {
for (File in : keySet()) {
EncodingStorage.Info info = get(in);
final OnFlyEncoding fly = new OnFlyEncoding(this.storage, info.targetUri, info.info);
- encoder = new FileEncoder(storage.getContext(), in, fly);
+ encoder = new FileEncoder(storage.getContext(), in, info.info, fly);
filters(encoder, info.info);
encoding(encoder, fly, info.info, new Runnable() {
@Override
@@ -208,7 +208,7 @@ public class EncodingStorage extends HashMap {
public void encoding(File in, Uri targetUri, RawSamples.Info info) {
OnFlyEncoding fly = new OnFlyEncoding(storage, targetUri, info);
- encoder = new FileEncoder(storage.getContext(), in, fly);
+ encoder = new FileEncoder(storage.getContext(), in, info, fly);
filters(encoder, info);
encoding(encoder, fly, info, new Runnable() {
@Override
@@ -220,7 +220,7 @@ public class EncodingStorage extends HashMap {
public void saveAsWAV(File in, File out, RawSamples.Info info) {
OnFlyEncoding fly = new OnFlyEncoding(storage, out, info);
- encoder = new FileEncoder(storage.getContext(), in, fly);
+ encoder = new FileEncoder(storage.getContext(), in, info, fly);
encoding(encoder, fly, info, new Runnable() {
@Override
public void run() {
diff --git a/app/src/main/java/com/github/axet/audiorecorder/app/RecordingStorage.java b/app/src/main/java/com/github/axet/audiorecorder/app/RecordingStorage.java
index 693affa..fd6e6ef 100644
--- a/app/src/main/java/com/github/axet/audiorecorder/app/RecordingStorage.java
+++ b/app/src/main/java/com/github/axet/audiorecorder/app/RecordingStorage.java
@@ -1,14 +1,18 @@
package com.github.axet.audiorecorder.app;
+import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
+import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.net.Uri;
+import android.os.Build;
import android.os.Handler;
import android.os.PowerManager;
import android.os.Process;
+import com.github.axet.androidlibrary.sound.AudioTrack;
import com.github.axet.audiolibrary.app.RawSamples;
import com.github.axet.audiolibrary.app.Sound;
import com.github.axet.audiolibrary.encoders.Encoder;
@@ -16,8 +20,18 @@ import com.github.axet.audiolibrary.encoders.OnFlyEncoding;
import com.github.axet.audiorecorder.BuildConfig;
import com.github.axet.audiorecorder.R;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.FilenameUtils;
+import org.json.JSONException;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.ByteBuffer;
import java.nio.ShortBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
+import java.util.Locale;
import java.util.concurrent.atomic.AtomicBoolean;
public class RecordingStorage {
@@ -35,7 +49,7 @@ public class RecordingStorage {
public Sound sound;
public Storage storage;
- public Encoder e;
+ public Encoder e; // recording encoder (onfly or raw data)
public AtomicBoolean interrupt = new AtomicBoolean(); // nio throws ClosedByInterruptException if thread interrupted
public Thread thread;
@@ -46,12 +60,13 @@ public class RecordingStorage {
public int samplesUpdateStereo; // samplesUpdate * number of channels
public Uri targetUri = null; // output target file 2016-01-01 01.01.01.wav
public long samplesTime; // how many samples passed for current recording, stereo = samplesTime * 2
+ public RawSamples.Info info;
- public ShortBuffer dbBuffer = null; // PinchView samples buffer
+ public AudioTrack.SamplesBuffer dbBuffer = null; // PinchView samples buffer
public int pitchTime; // screen width
- public RecordingStorage(Context context, int pitchTime, Uri targetUri) {
+ public RecordingStorage(Context context, int format, int pitchTime, Uri targetUri) {
this.context = context;
this.pitchTime = pitchTime;
this.targetUri = targetUri;
@@ -60,36 +75,26 @@ public class RecordingStorage {
sampleRate = Sound.getSampleRate(context);
samplesUpdate = (int) (pitchTime * sampleRate / 1000f);
samplesUpdateStereo = samplesUpdate * Sound.getChannels(context);
+ info = new RawSamples.Info(format, sampleRate, Sound.getChannels(context));
}
- public void startRecording() {
- sound.silent();
-
+ public void startRecording(int source) {
final SharedPreferences shared = android.preference.PreferenceManager.getDefaultSharedPreferences(context);
- int user;
-
- if (shared.getString(AudioApplication.PREFERENCE_SOURCE, context.getString(R.string.source_mic)).equals(context.getString(R.string.source_raw))) {
- if (Sound.isUnprocessedSupported(context))
- user = MediaRecorder.AudioSource.UNPROCESSED;
- else
- user = MediaRecorder.AudioSource.VOICE_RECOGNITION;
- } else {
- user = MediaRecorder.AudioSource.MIC;
- }
+ sound.silent();
int[] ss = new int[]{
- user,
+ source,
MediaRecorder.AudioSource.MIC,
MediaRecorder.AudioSource.DEFAULT
};
if (shared.getBoolean(AudioApplication.PREFERENCE_FLY, false)) {
- final OnFlyEncoding fly = new OnFlyEncoding(storage, targetUri, getInfo());
if (e == null) { // do not recreate encoder if on-fly mode enabled
+ final OnFlyEncoding fly = new OnFlyEncoding(storage, targetUri, info);
e = new Encoder() {
@Override
- public void encode(short[] buf, int pos, int len) {
+ public void encode(AudioTrack.SamplesBuffer buf, int pos, int len) {
fly.encode(buf, pos, len);
}
@@ -100,11 +105,11 @@ public class RecordingStorage {
};
}
} else {
- final RawSamples rs = new RawSamples(storage.getTempRecording());
- rs.open(samplesTime * Sound.getChannels(context));
+ final RawSamples rs = new RawSamples(storage.getTempRecording(), info);
+ rs.open(samplesTime * rs.info.channels);
e = new Encoder() {
@Override
- public void encode(short[] buf, int pos, int len) {
+ public void encode(AudioTrack.SamplesBuffer buf, int pos, int len) {
rs.write(buf, pos, len);
}
@@ -115,7 +120,7 @@ public class RecordingStorage {
};
}
- final AudioRecord recorder = Sound.createAudioRecorder(context, sampleRate, ss, 0);
+ final AudioRecord recorder = sound.createAudioRecorder(info.format, sampleRate, ss, 0);
final Thread old = thread;
final AtomicBoolean oldb = interrupt;
@@ -154,17 +159,34 @@ public class RecordingStorage {
int samplesTimeCount = 0;
final int samplesTimeUpdate = 1000 * sampleRate / 1000; // how many samples we need to update 'samples'. time clock. every 1000ms.
- short[] buffer = null;
+ AudioTrack.SamplesBuffer buffer = null;
boolean stableRefresh = false;
while (!interrupt.get()) {
synchronized (bufferSizeLock) {
- if (buffer == null || buffer.length != bufferSize)
- buffer = new short[bufferSize];
+ if (buffer == null || buffer.size() != bufferSize)
+ buffer = new AudioTrack.SamplesBuffer(info.format, bufferSize);
+ }
+
+ int readSize = -1;
+ switch (buffer.format) {
+ case AudioFormat.ENCODING_PCM_8BIT:
+ break;
+ case AudioFormat.ENCODING_PCM_16BIT:
+ readSize = recorder.read(buffer.shorts, 0, buffer.shorts.length);
+ case Sound.ENCODING_PCM_24BIT_PACKED:
+ break;
+ case Sound.ENCODING_PCM_32BIT:
+ break;
+ case AudioFormat.ENCODING_PCM_FLOAT:
+ if (Build.VERSION.SDK_INT >= 23)
+ readSize = recorder.read(buffer.floats, 0, buffer.floats.length, AudioRecord.READ_BLOCKING);
+ break;
+ default:
+ throw new RuntimeException("Unknown format");
}
- int readSize = recorder.read(buffer, 0, buffer.length);
if (readSize < 0)
return;
long now = System.currentTimeMillis();
@@ -178,18 +200,18 @@ public class RecordingStorage {
e.encode(buffer, 0, readSize);
- short[] dbBuf;
+ AudioTrack.SamplesBuffer dbBuf;
int dbSize;
int readSizeUpdate;
if (dbBuffer != null) {
- ShortBuffer bb = ShortBuffer.allocate(dbBuffer.position() + readSize);
+ AudioTrack.SamplesBuffer bb = new AudioTrack.SamplesBuffer(info.format, dbBuffer.position + readSize);
dbBuffer.flip();
bb.put(dbBuffer);
bb.put(buffer, 0, readSize);
- dbBuf = new short[bb.position()];
- dbSize = dbBuf.length;
+ dbBuf = new AudioTrack.SamplesBuffer(info.format, bb.position);
+ dbSize = dbBuf.count;
bb.flip();
- bb.get(dbBuf, 0, dbBuf.length);
+ bb.get(dbBuf, 0, dbBuf.count);
} else {
dbBuf = buffer;
dbSize = readSize;
@@ -204,7 +226,7 @@ public class RecordingStorage {
}
int readSizeLen = dbSize - readSizeUpdate;
if (readSizeLen > 0) {
- dbBuffer = ShortBuffer.allocate(readSizeLen);
+ dbBuffer = new AudioTrack.SamplesBuffer(info.format, readSizeLen);
dbBuffer.put(dbBuf, readSizeUpdate, readSizeLen);
} else {
dbBuffer = null;
@@ -277,10 +299,6 @@ public class RecordingStorage {
sound.unsilent();
}
- public RawSamples.Info getInfo() {
- return new RawSamples.Info(sampleRate, Sound.getChannels(context));
- }
-
// calcuale buffer length dynamically, this way we can reduce thread cycles when activity in background
// or phone screen is off.
public void updateBufferSize(boolean pause) {
diff --git a/app/src/main/java/com/github/axet/audiorecorder/services/BluetoothReceiver.java b/app/src/main/java/com/github/axet/audiorecorder/services/BluetoothReceiver.java
index 3a11598..ac4c380 100644
--- a/app/src/main/java/com/github/axet/audiorecorder/services/BluetoothReceiver.java
+++ b/app/src/main/java/com/github/axet/audiorecorder/services/BluetoothReceiver.java
@@ -86,9 +86,8 @@ public class BluetoothReceiver extends BroadcastReceiver {
String a = intent.getAction();
if (a == null)
return;
- if (bluetoothSource && a.equals(BluetoothDevice.ACTION_ACL_CONNECTED)) {
+ if (bluetoothSource && a.equals(BluetoothDevice.ACTION_ACL_CONNECTED))
handler.postDelayed(connected, CONNECT_DELAY);
- }
if (bluetoothSource && a.equals(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED)) {
int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1);
switch (state) {
diff --git a/app/src/main/java/com/github/axet/audiorecorder/services/ControlsService.java b/app/src/main/java/com/github/axet/audiorecorder/services/ControlsService.java
index 2880a81..f7efdd7 100644
--- a/app/src/main/java/com/github/axet/audiorecorder/services/ControlsService.java
+++ b/app/src/main/java/com/github/axet/audiorecorder/services/ControlsService.java
@@ -27,6 +27,7 @@ import com.github.axet.androidlibrary.services.PersistentService;
import com.github.axet.androidlibrary.widgets.NotificationChannelCompat;
import com.github.axet.androidlibrary.widgets.RemoteNotificationCompat;
import com.github.axet.androidlibrary.widgets.RemoteViewsCompat;
+import com.github.axet.audiolibrary.app.Sound;
import com.github.axet.audiolibrary.app.Storage;
import com.github.axet.audiorecorder.R;
import com.github.axet.audiorecorder.activities.MainActivity;
@@ -128,7 +129,7 @@ public class ControlsService extends PersistentService {
title = getString(R.string.app_name);
Uri f = storage.getStoragePath();
long free = Storage.getFree(context, f);
- long sec = Storage.average(context, free);
+ long sec = Storage.average(context, Sound.getAudioFormat(context), free);
text = AudioApplication.formatFree(context, free, sec);
builder = new RemoteNotificationCompat.Low(context, R.layout.notifictaion);
builder.setViewVisibility(R.id.notification_record, View.VISIBLE);
diff --git a/app/src/main/java/com/github/axet/audiorecorder/widgets/RecordingSourcePreferenceCompat.java b/app/src/main/java/com/github/axet/audiorecorder/widgets/RecordingSourcePreferenceCompat.java
new file mode 100644
index 0000000..60c571c
--- /dev/null
+++ b/app/src/main/java/com/github/axet/audiorecorder/widgets/RecordingSourcePreferenceCompat.java
@@ -0,0 +1,79 @@
+package com.github.axet.audiorecorder.widgets;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.res.TypedArray;
+import android.os.Build;
+import android.preference.PreferenceManager;
+import android.support.v7.preference.ListPreference;
+import android.support.v7.preference.ListPreferenceDialogFragmentCompat;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.util.AttributeSet;
+
+import com.github.axet.audiolibrary.app.Sound;
+import com.github.axet.audiorecorder.R;
+import com.github.axet.audiorecorder.app.AudioApplication;
+import com.github.axet.audiorecorder.app.Storage;
+
+import java.util.ArrayList;
+import java.util.Date;
+
+public class RecordingSourcePreferenceCompat extends ListPreference {
+ public RecordingSourcePreferenceCompat(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ public RecordingSourcePreferenceCompat(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ public RecordingSourcePreferenceCompat(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public RecordingSourcePreferenceCompat(Context context) {
+ super(context);
+ }
+
+ @Override
+ public boolean callChangeListener(Object newValue) {
+ update(newValue);
+ return super.callChangeListener(newValue);
+ }
+
+ @Override
+ protected Object onGetDefaultValue(TypedArray a, int index) {
+ Object def = super.onGetDefaultValue(a, index);
+ update(def);
+ return def;
+ }
+
+ @Override
+ protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+ super.onSetInitialValue(restoreValue, defaultValue);
+ CharSequence[] text = getEntries();
+ CharSequence[] values = getEntryValues();
+ ArrayList tt = new ArrayList<>();
+ ArrayList vv = new ArrayList<>();
+ String raw = getContext().getString(R.string.source_raw);
+ String internal = getContext().getString(R.string.source_internal);
+ for (int i = 0; i < values.length; i++) {
+ String v = values[i].toString();
+ String t = text[i].toString();
+ if (v.equals(raw) && !Sound.isUnprocessedSupported(getContext()))
+ continue;
+ if (v.equals(internal) && Build.VERSION.SDK_INT < 29)
+ continue;
+ vv.add(v);
+ tt.add(t);
+ }
+ setEntryValues(vv.toArray(new CharSequence[0]));
+ setEntries(tt.toArray(new CharSequence[0]));
+ update(getValue()); // defaultValue null after defaults set
+ }
+
+ public void update(Object value) {
+ String v = (String) value;
+ setSummary(v);
+ }
+}
diff --git a/app/src/main/res/raw-pl/about.html b/app/src/main/res/raw-pl/about.html
index acd95e2..52ec077 100644
--- a/app/src/main/res/raw-pl/about.html
+++ b/app/src/main/res/raw-pl/about.html
@@ -12,7 +12,7 @@
Przyjazny dla systemu Android!
-Audio Recorder with custom recording folder, nice recording volume indicator, recording notification, recording lock screen activity.
+Rejestrator dźwięku z własnym folderem nagrywania, ładnym wskaźnikiem głośności nagrywania, powiadomieniem o nagrywaniu oraz sterowaniem nagrywania z poziomu blokady ekranu.
- Licencja:
diff --git a/app/src/main/res/raw-pt-rBR/about.html b/app/src/main/res/raw-pt-rBR/about.html
new file mode 100644
index 0000000..77f223b
--- /dev/null
+++ b/app/src/main/res/raw-pt-rBR/about.html
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+Sobre
+
+ Compatível com Android!
+
+
+Gravador de áudio com pasta de gravação personalizada, controle na tela de bloqueio, indicador de volume e notificação de gravação.
+
+
+ - Licença:
+ - GPLv3
+ - Código fonte:
+ - https://gitlab.com/axet/android-audio-recorder
+
+
+
diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml
index e6aff55..2b598a0 100644
--- a/app/src/main/res/values-da/strings.xml
+++ b/app/src/main/res/values-da/strings.xml
@@ -1,5 +1,11 @@
+
+ - Mikrofon
+ - Unprocessed
+ - Bluetooth
+ - Internal Audio
+
Audio Optager
Auto luk om (%1$d)
Optagelseslisten er tom\n\nKlik Optag for at starte optagelse
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 741d234..6a38a48 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -15,6 +15,7 @@
- Mikrofon
- Unprocessed
- Bluetooth
+ - Internal Audio
diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml
index e0c0786..5044801 100644
--- a/app/src/main/res/values-el/strings.xml
+++ b/app/src/main/res/values-el/strings.xml
@@ -13,6 +13,7 @@
- Μικρόφωνο
- Unprocessed
- Bluetooth
+ - Internal Audio
- Φωτεινό
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index f608f07..11ab498 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -15,6 +15,7 @@
- Mic
- Unprocessed
- Bluetooth
+ - Internal Audio
diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml
index 5b4600a..adce86c 100644
--- a/app/src/main/res/values-eu/strings.xml
+++ b/app/src/main/res/values-eu/strings.xml
@@ -15,6 +15,7 @@
- Mikrofonoa
- Prozesatu gabea
- Bluetooth
+ - Internal Audio
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 362a604..85d62e4 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -15,6 +15,7 @@
- Mic
- Unprocessed
- Bluetooth
+ - Internal Audio
diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml
index 8fa4e50..a0aeb3e 100644
--- a/app/src/main/res/values-in/strings.xml
+++ b/app/src/main/res/values-in/strings.xml
@@ -15,6 +15,7 @@
- Mik
- Tidak diproses
- Bluetooth
+ - Internal Audio
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 75cc319..21dd6fb 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -15,6 +15,7 @@
- Mic
- Unprocessed
- Bluetooth
+ - Internal Audio
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index 1a19220..0818aff 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -15,6 +15,7 @@
- Mic
- Unprocessed
- Bluetooth
+ - Internal Audio
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index c6899c4..e09d887 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -13,8 +13,9 @@
- Mikrofon
- - Unprocessed
+ - Nieprzetworzone
- Bluetooth
+ - Internal Audio
@@ -27,52 +28,52 @@
- Stereo
- No folder view application installed
+ Brak zainstalowanej aplikacji do przeglądania folderów
pauza (wstrzymane przez połączenie)
nagrywanie
- enkodowanie
+ kodowanie
pauza
edytuj
Potwierdź anulowanie
- Enkodowanie...
+ Kodowanie...
Pauza...
Nagrywanie
- Otwórz Folder Nagrywania
- Lista nagrań jest pusta\n\nKliknij Nagraj, aby rozpocząć nagrywanie
+ Otwórz folder z nagraniami
+ Lista nagrań jest pusta\n\nDotknij ikonki "mikrofonu", aby rozpocząć nagrywanie
Nagrywaj
Wytnij
- Stop
+ Zatrzymaj
Anuluj
Pauza
- Ścieżka Przechowywania
+ Folder nagrań
Tempo Próbkowania
- Enkodowanie
+ Kodowanie
Wyjściowy format pliku (.wav, .m4a, ...)
- Tryb
- Recording channels
- Format Nazwy
+ Kanały audio
+ Kanały nagrywania
+ Format pliku
Wstrzymaj podczas połączeń
- Zatrzymaj nagrywanie po odebraniu i kontynuuj podcas rozłączania
- Tryb Wyciszenia
- Przełącz telefon w \'tryb ciszy\' podczas nagrywania
+ Zatrzymaj nagrywanie po odebraniu i kontynuuj po rozłączeniu
+ Tryb cichy
+ Załącz \'tryb cichy\' podczas nagrywania
Sterowanie z ekranu blokady
Pokaż elementy sterujące, gdy telefon jest zablokowany
Motyw Aplikacji
- Ustaw motyw aplikacji (ciemny / jasny)
+ Ustaw motyw aplikacji (ciemny/jasny)
Aplikacja
Nagrania
- Enkodowanie w Locie
- Włączając enkodowanie w locie, wyłącza edytowanie i odzyskiwanie po awarii
+ Kodowanie "w locie"
+ Włączając kodowanie "w locie", wyłącza edytowanie i odzyskiwanie po awarii
pauza (bluetooth rozłaczony)
Szukaj
Zapisz jako WAV
- Auto close in (%1$d)
- Mic muted
- Android Pie and above prevent idle background apps from using microphone. Please disable selinux or install previous android version!
- Mic paused by OS, recording time is less then data recorded, check if you device supports background recording or it is fast enougth for selected settings
- Start Recording
- Stop Recording
- Background encoding paused due to android Battery Optimization settings, please allow this application work in background
+ Zamknij automatycznie za (%1$d)
+ Mikrofon wyciszony
+ Android 9 (Pie) i nowsze wersje uniemożliwiają bezczynnym aplikacjom działającym w tle korzystanie z mikrofonu. Prosimy o wyłączenie SeLinux lub aktualizację do wcześniejszej wersji Androida!
+ Mikrofon został wstrzymany przez system Android, czas nagrywania jest krótszy niż zapisane dane, sprawdź czy urządzenie obsługuje nagrywanie w tle lub czy jest wystarczająco szybkie dla wybranych ustawień
+ Rozpocznij nagrywanie
+ Zakończ nagrywanie
+ Kodowanie w tle zostało wstrzymane przez system Android w celu oszczędzania energii, proszę pozwolić tej aplikacji pracować w tle (ustawienia systemu: optymalizacja baterii)
/s
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index 2e3d367..cb1b487 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -1,5 +1,5 @@
- Audio Recorder
+ Gravador de áudio
- 48 kHz
@@ -8,18 +8,19 @@
- 22 kHz
- 16 kHz (padrão)
- 11 kHz
- - 8 kHz (ligação de tel.)
+ - 8 kHz (tipo ligação)
- Mic
- Não processado
- Bluetooth
+ - Internal Audio
- - Tema Claro
- - Tema Escuro
+ - Tema claro
+ - Tema escuro
@@ -27,52 +28,52 @@
- Estéreo
- Não foi encontrado nenhum aplicativo para explorar os arquivos
- pausado (chamada atendida)
+ Não foi encontrado nenhum app para abrir os arquivos
+ pausado (ligação atendida)
gravando
codificando
pausado
editando
- Deseja cancelar
+ Quer cancelar
Codificando...
Pausado...
Gravando
- Abrir pasta das gravações
- A lista das gravações está vazia\n\nToque no ícone do microfone para começar a gravar
+ Abrir pasta de gravações
+ A lista de gravações está vazia\n\nToque no ícone do microfone para começar a gravar
Gravar
Cortar
Parar
Cancelar
Pausar
- Pasta das gravações
+ Pasta de gravações
Taxa de amostragem
Codificação
- Formato de saída do arquivo (.wav, .mp3, etc.)
+ Tipo de arquivo de áudio (.wav, .mp3, etc.)
Canais de áudio
Canais de gravação
- Formato do nome de arquivo
- Pausar durante a chamada
- e voltar a gravar quando a chamada for desligada
+ Formato de nome de arquivo
+ Pausar durante a ligação
+ e voltar a gravar quando a ligação for concluída
Modo silencioso
Ativar o \'modo silencioso\' durante a gravação
- Controle da tela bloqueada
- Mostrar os controles quando a tela estiver bloqueada
+ Controle na tela de bloqueio
+ Mostrar menu de controle quando a tela for bloqueada
Tema do App
Definir o tema (claro ou escuro)
Aplicativo
Gravações
Codificação em tempo real
- Ativando codificação em tempo real desabilitará a edição e recuperação após a falha
+ Ao permitir codificação em tempo real você desabilitará a edição e recuperação após uma falha
pausado (bluetooth desconectado)
Pesquisar
- Salvar como WAV
- Auto-fechar em (%1$d)
+ Salvar como .wav
+ Fechar autom. em (%1$d)
Mic silenciado
- Android 9 (Pie) e mais recente impedem que os Apps em segundo plano utilizem o microfone. Solução: ou desabilitar o SeLinux ou usar a versão anterior do Android!
- Microfone foi pausado pelo Android, o tempo de gravação é menor do que o conteúdo gravado. Verifique se seu dispositivo suporta gravação em segundo plano ou se é o suficiente rápido para utilizar as configurações selecionadas
- Iniciar Gravação
- Parar a Gravação
- Codificação em segundo plano foi pausada devido a configuração do Android de otimização da bateria, por favor permita que o App funcione em segundo plano
+ Android 9 (Pie) e mais recentes impedem que os apps usem o microfone em segundo plano. Solução: desabilite o SeLinux ou use uma versão mais antiga do Android
+ O microfone foi pausado pelo Android, o tempo de gravação é menor do que o conteúdo gravado. Verifique se seu dispositivo suporta gravação em segundo plano ou se é o suficientemente rápido para usar as configurações selecionadas
+ Iniciar uma gravação
+ Parar a gravação
+ A codificação em segundo plano foi pausada pela configuração de otimização da bateria do Android, por favor permita que o App funcione em segundo plano
/s
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 437e954..cf590ef 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -20,6 +20,7 @@
- Микрофон
- Необработанный
- Bluetooth
+ - Internal Audio
diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml
index 1de6978..8982d5d 100644
--- a/app/src/main/res/values-sk/strings.xml
+++ b/app/src/main/res/values-sk/strings.xml
@@ -15,6 +15,7 @@
- Mikrofón
- Bez spracovania (surové)
- Bluetooth
+ - Internal Audio
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index 11a0e36..bd58eb2 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -15,6 +15,7 @@
- Mikrofon
- İşlenmemiş
- Bluetooth
+ - Internal Audio
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 0c946de..156469e 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -15,6 +15,7 @@
- 话筒
- 未处理
- 蓝牙
+ - Internal Audio
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index 16deea3..e7bb31a 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -15,6 +15,7 @@
- 麥克風
- 未處理
- 藍牙
+ - Internal Audio
diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml
index 003ca07..570c35f 100644
--- a/app/src/main/res/values/attrs.xml
+++ b/app/src/main/res/values/attrs.xml
@@ -7,6 +7,7 @@
default
raw
bluetooth
+ internal
- 48000
@@ -22,6 +23,17 @@
- @string/source_mic
- @string/source_raw
- @string/source_bluetooth
+ - @string/source_internal
+
+
+
+ - 16-bit PCM
+ - 24-bit PCM (float)
+
+
+
+ - 16
+ - float
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 73d78fd..f52d4bd 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -15,6 +15,7 @@
- Mic
- Unprocessed
- Bluetooth
+ - Internal Audio
diff --git a/app/src/main/res/xml/pref_general.xml b/app/src/main/res/xml/pref_general.xml
index 7cf8dc3..f1c7715 100644
--- a/app/src/main/res/xml/pref_general.xml
+++ b/app/src/main/res/xml/pref_general.xml
@@ -8,6 +8,16 @@
android:title="@string/pref_storage_title" />
+
+
-