Merge branch 'audiorecorder-3.5.0'
This commit is contained in:
commit
875cfb1339
32 changed files with 337 additions and 124 deletions
|
|
@ -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' }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
android:roundIcon="@mipmap/ic_launcher"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Translucent">
|
||||
<service android:name=".services.RecordingService" />
|
||||
<service android:name=".services.RecordingService" android:foregroundServiceType="mediaProjection" />
|
||||
<service android:name=".services.EncodingService" />
|
||||
<service android:name=".services.ControlsService" />
|
||||
<service
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ import com.github.axet.androidlibrary.widgets.ErrorDialog;
|
|||
import com.github.axet.androidlibrary.widgets.OpenFileDialog;
|
||||
import com.github.axet.androidlibrary.widgets.SearchView;
|
||||
import com.github.axet.audiolibrary.app.RawSamples;
|
||||
import com.github.axet.audiolibrary.app.Sound;
|
||||
import com.github.axet.audiolibrary.encoders.FormatWAV;
|
||||
import com.github.axet.audiorecorder.R;
|
||||
import com.github.axet.audiorecorder.app.AudioApplication;
|
||||
|
|
@ -663,7 +664,7 @@ public class MainActivity extends AppCompatThemeActivity {
|
|||
void updateHeader() {
|
||||
Uri uri = storage.getStoragePath();
|
||||
long free = Storage.getFree(this, uri);
|
||||
long sec = Storage.average(this, free);
|
||||
long sec = Storage.average(this, Sound.getAudioFormat(this), free);
|
||||
TextView text = (TextView) findViewById(R.id.space_left);
|
||||
text.setText(AudioApplication.formatFree(this, free, sec));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import android.content.Intent;
|
|||
import android.content.SharedPreferences;
|
||||
import android.graphics.Rect;
|
||||
import android.media.AudioFormat;
|
||||
import android.media.MediaRecorder;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
|
|
@ -63,6 +64,7 @@ public class RecordingActivity extends AppCompatThemeActivity {
|
|||
public static final String TAG = RecordingActivity.class.getSimpleName();
|
||||
|
||||
public static final int RESULT_START = 1;
|
||||
public static final int RESULT_INTERNAL = 2;
|
||||
|
||||
public static final String[] PERMISSIONS_AUDIO = new String[]{
|
||||
Manifest.permission.RECORD_AUDIO
|
||||
|
|
@ -357,7 +359,7 @@ public class RecordingActivity extends AppCompatThemeActivity {
|
|||
public void onClick(DialogInterface dialog, int which) {
|
||||
File to = new File(d.getCurrentPath(), Storage.getName(RecordingActivity.this, recording.targetUri));
|
||||
recording.targetUri = Uri.fromFile(to);
|
||||
EncodingService.saveAsWAV(RecordingActivity.this, recording.storage.getTempRecording(), to, recording.getInfo());
|
||||
EncodingService.saveAsWAV(RecordingActivity.this, recording.storage.getTempRecording(), to, recording.info);
|
||||
}
|
||||
});
|
||||
d.show();
|
||||
|
|
@ -517,7 +519,7 @@ public class RecordingActivity extends AppCompatThemeActivity {
|
|||
editor.commit();
|
||||
}
|
||||
Log.d(TAG, "create recording at: " + targetUri);
|
||||
app.recording = new RecordingStorage(this, pitch.getPitchTime(), targetUri);
|
||||
app.recording = new RecordingStorage(this, Sound.getAudioFormat(this), pitch.getPitchTime(), targetUri);
|
||||
}
|
||||
recording = app.recording;
|
||||
synchronized (recording.handlers) {
|
||||
|
|
@ -556,21 +558,21 @@ public class RecordingActivity extends AppCompatThemeActivity {
|
|||
return;
|
||||
}
|
||||
|
||||
RawSamples rs = new RawSamples(f);
|
||||
recording.samplesTime = rs.getSamples() / Sound.getChannels(this);
|
||||
RawSamples rs = new RawSamples(f, recording.info);
|
||||
recording.samplesTime = rs.getSamples() / rs.info.channels;
|
||||
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
||||
|
||||
int count = pitch.getMaxPitchCount(metrics.widthPixels);
|
||||
|
||||
short[] buf = new short[count * recording.samplesUpdateStereo];
|
||||
long cut = recording.samplesTime * Sound.getChannels(this) - buf.length;
|
||||
AudioTrack.SamplesBuffer buf = new AudioTrack.SamplesBuffer(rs.info.format, count * recording.samplesUpdateStereo);
|
||||
long cut = recording.samplesTime * Sound.getChannels(this) - buf.count;
|
||||
|
||||
if (cut < 0)
|
||||
cut = 0;
|
||||
|
||||
rs.open(cut, buf.length);
|
||||
rs.open(cut, buf.count);
|
||||
int len = rs.read(buf);
|
||||
rs.close();
|
||||
|
||||
|
|
@ -584,7 +586,7 @@ public class RecordingActivity extends AppCompatThemeActivity {
|
|||
|
||||
int diff = len - lenUpdate;
|
||||
if (diff > 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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ public class EncodingStorage extends HashMap<File, EncodingStorage.Info> {
|
|||
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<File, EncodingStorage.Info> {
|
|||
|
||||
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<File, EncodingStorage.Info> {
|
|||
|
||||
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() {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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<CharSequence> tt = new ArrayList<>();
|
||||
ArrayList<CharSequence> 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
Przyjazny dla systemu Android!
|
||||
</p>
|
||||
|
||||
<p>Audio Recorder with custom recording folder, nice recording volume indicator, recording notification, recording lock screen activity.</p>
|
||||
<p>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.</p>
|
||||
|
||||
<dl>
|
||||
<dt><b>Licencja:</b></dt>
|
||||
|
|
|
|||
23
app/src/main/res/raw-pt-rBR/about.html
Normal file
23
app/src/main/res/raw-pt-rBR/about.html
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<style>
|
||||
a { white-space: pre-wrap; word-wrap:break-word; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h3>Sobre</h3>
|
||||
<p>
|
||||
Compatível com Android!
|
||||
</p>
|
||||
|
||||
<p>Gravador de áudio com pasta de gravação personalizada, controle na tela de bloqueio, indicador de volume e notificação de gravação.</p>
|
||||
|
||||
<dl>
|
||||
<dt><b>Licença:</b></dt>
|
||||
<dd>GPLv3</dd>
|
||||
<dt><b>Código fonte:</b></dt>
|
||||
<dd><a href="https://gitlab.com/axet/android-audio-recorder">https://gitlab.com/axet/android-audio-recorder</a></dd>
|
||||
</dl>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,5 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string-array name="source_text">
|
||||
<item>Mikrofon</item>
|
||||
<item>Unprocessed</item>
|
||||
<item>Bluetooth</item>
|
||||
<item>Internal Audio</item>
|
||||
</string-array>
|
||||
<string name="app_name">Audio Optager</string>
|
||||
<string name="auto_close">Auto luk om (%1$d)</string>
|
||||
<string name="recording_list_is_empty">Optagelseslisten er tom\n\nKlik Optag for at starte optagelse</string>
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
<item>Mikrofon</item>
|
||||
<item>Unprocessed</item>
|
||||
<item>Bluetooth</item>
|
||||
<item>Internal Audio</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="themes_text">
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
<item>Μικρόφωνο</item>
|
||||
<item>Unprocessed</item>
|
||||
<item>Bluetooth</item>
|
||||
<item>Internal Audio</item>
|
||||
</string-array>
|
||||
<string-array name="themes_text">
|
||||
<item>Φωτεινό</item>
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
<item>Mic</item>
|
||||
<item>Unprocessed</item>
|
||||
<item>Bluetooth</item>
|
||||
<item>Internal Audio</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="themes_text">
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
<item>Mikrofonoa</item>
|
||||
<item>Prozesatu gabea</item>
|
||||
<item>Bluetooth</item>
|
||||
<item>Internal Audio</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="themes_text">
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
<item>Mic</item>
|
||||
<item>Unprocessed</item>
|
||||
<item>Bluetooth</item>
|
||||
<item>Internal Audio</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="themes_text">
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
<item>Mik</item>
|
||||
<item>Tidak diproses</item>
|
||||
<item>Bluetooth</item>
|
||||
<item>Internal Audio</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="themes_text">
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
<item>Mic</item>
|
||||
<item>Unprocessed</item>
|
||||
<item>Bluetooth</item>
|
||||
<item>Internal Audio</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="themes_text">
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
<item>Mic</item>
|
||||
<item>Unprocessed</item>
|
||||
<item>Bluetooth</item>
|
||||
<item>Internal Audio</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="themes_text">
|
||||
|
|
|
|||
|
|
@ -13,8 +13,9 @@
|
|||
|
||||
<string-array name="source_text">
|
||||
<item>Mikrofon</item>
|
||||
<item>Unprocessed</item>
|
||||
<item>Nieprzetworzone</item>
|
||||
<item>Bluetooth</item>
|
||||
<item>Internal Audio</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="themes_text">
|
||||
|
|
@ -27,52 +28,52 @@
|
|||
<item>Stereo</item>
|
||||
</string-array>
|
||||
|
||||
<string name="no_folder_app">No folder view application installed</string>
|
||||
<string name="no_folder_app">Brak zainstalowanej aplikacji do przeglądania folderów</string>
|
||||
<string name="hold_by_call">pauza (wstrzymane przez połączenie)</string>
|
||||
<string name="recording_status_recording">nagrywanie</string>
|
||||
<string name="recording_status_encoding">enkodowanie</string>
|
||||
<string name="recording_status_encoding">kodowanie</string>
|
||||
<string name="recording_status_pause">pauza</string>
|
||||
<string name="recording_status_edit">edytuj</string>
|
||||
<string name="confirm_cancel">Potwierdź anulowanie</string>
|
||||
<string name="encoding_title">Enkodowanie...</string>
|
||||
<string name="encoding_title">Kodowanie...</string>
|
||||
<string name="pause_title">Pauza...</string>
|
||||
<string name="recording_title">Nagrywanie</string>
|
||||
<string name="open_recording_folder">Otwórz Folder Nagrywania</string>
|
||||
<string name="recording_list_is_empty">Lista nagrań jest pusta\n\nKliknij Nagraj, aby rozpocząć nagrywanie</string>
|
||||
<string name="open_recording_folder">Otwórz folder z nagraniami</string>
|
||||
<string name="recording_list_is_empty">Lista nagrań jest pusta\n\nDotknij ikonki "mikrofonu", aby rozpocząć nagrywanie</string>
|
||||
<string name="record_button">Nagrywaj</string>
|
||||
<string name="cut_button">Wytnij</string>
|
||||
<string name="stop_button">Stop</string>
|
||||
<string name="stop_button">Zatrzymaj</string>
|
||||
<string name="cancel_button">Anuluj</string>
|
||||
<string name="pause_button">Pauza</string>
|
||||
|
||||
<string name="pref_storage_title">Ścieżka Przechowywania</string>
|
||||
<string name="pref_storage_title">Folder nagrań</string>
|
||||
<string name="pref_rate_title">Tempo Próbkowania</string>
|
||||
<string name="pref_encoding_title">Enkodowanie</string>
|
||||
<string name="pref_encoding_title">Kodowanie</string>
|
||||
<string name="pref_encoding_summary">Wyjściowy format pliku (.wav, .m4a, ...)</string>
|
||||
<string name="pref_mode_title">Tryb</string>
|
||||
<string name="pref_mode_summary">Recording channels</string>
|
||||
<string name="pref_nameformat_title">Format Nazwy</string>
|
||||
<string name="pref_mode_title">Kanały audio</string>
|
||||
<string name="pref_mode_summary">Kanały nagrywania</string>
|
||||
<string name="pref_nameformat_title">Format pliku</string>
|
||||
<string name="pref_pausecalls_title">Wstrzymaj podczas połączeń</string>
|
||||
<string name="pref_pausecalls_summary">Zatrzymaj nagrywanie po odebraniu i kontynuuj podcas rozłączania</string>
|
||||
<string name="pref_silence_title">Tryb Wyciszenia</string>
|
||||
<string name="pref_silence_summary">Przełącz telefon w \'tryb ciszy\' podczas nagrywania</string>
|
||||
<string name="pref_pausecalls_summary">Zatrzymaj nagrywanie po odebraniu i kontynuuj po rozłączeniu</string>
|
||||
<string name="pref_silence_title">Tryb cichy</string>
|
||||
<string name="pref_silence_summary">Załącz \'tryb cichy\' podczas nagrywania</string>
|
||||
<string name="pref_lockscreen_title">Sterowanie z ekranu blokady</string>
|
||||
<string name="pref_lockscreen_summary">Pokaż elementy sterujące, gdy telefon jest zablokowany</string>
|
||||
<string name="pref_theme_title">Motyw Aplikacji</string>
|
||||
<string name="pref_theme_summary">Ustaw motyw aplikacji (ciemny / jasny)</string>
|
||||
<string name="pref_theme_summary">Ustaw motyw aplikacji (ciemny/jasny)</string>
|
||||
<string name="pref_application">Aplikacja</string>
|
||||
<string name="pref_recordings">Nagrania</string>
|
||||
<string name="pref_fly_title">Enkodowanie w Locie</string>
|
||||
<string name="pref_fly_summary">Włączając enkodowanie w locie, wyłącza edytowanie i odzyskiwanie po awarii</string>
|
||||
<string name="pref_fly_title">Kodowanie "w locie"</string>
|
||||
<string name="pref_fly_summary">Włączając kodowanie "w locie", wyłącza edytowanie i odzyskiwanie po awarii</string>
|
||||
<string name="hold_by_bluetooth">pauza (bluetooth rozłaczony)</string>
|
||||
<string name="menu_search">Szukaj</string>
|
||||
<string name="save_as_wav">Zapisz jako WAV</string>
|
||||
<string name="auto_close">Auto close in (%1$d)</string>
|
||||
<string name="mic_muted_error">Mic muted</string>
|
||||
<string name="mic_muted_pie">Android Pie and above prevent idle background apps from using microphone. Please disable selinux or install previous android version!</string>
|
||||
<string name="mic_paused">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</string>
|
||||
<string name="tile_start_recording">Start Recording</string>
|
||||
<string name="tile_stop_recording">Stop Recording</string>
|
||||
<string name="encoding_optimization">Background encoding paused due to android Battery Optimization settings, please allow this application work in background</string>
|
||||
<string name="auto_close">Zamknij automatycznie za (%1$d)</string>
|
||||
<string name="mic_muted_error">Mikrofon wyciszony</string>
|
||||
<string name="mic_muted_pie">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!</string>
|
||||
<string name="mic_paused">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ń</string>
|
||||
<string name="tile_start_recording">Rozpocznij nagrywanie</string>
|
||||
<string name="tile_stop_recording">Zakończ nagrywanie</string>
|
||||
<string name="encoding_optimization">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)</string>
|
||||
<string name="per_second">/s</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<resources>
|
||||
<string name="app_name">Audio Recorder</string>
|
||||
<string name="app_name">Gravador de áudio</string>
|
||||
|
||||
<string-array name="sample_rate_text">
|
||||
<item>48 kHz</item>
|
||||
|
|
@ -8,18 +8,19 @@
|
|||
<item>22 kHz</item>
|
||||
<item>16 kHz (padrão)</item>
|
||||
<item>11 kHz</item>
|
||||
<item>8 kHz (ligação de tel.)</item>
|
||||
<item>8 kHz (tipo ligação)</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="source_text">
|
||||
<item>Mic</item>
|
||||
<item>Não processado</item>
|
||||
<item>Bluetooth</item>
|
||||
<item>Internal Audio</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="themes_text">
|
||||
<item>Tema Claro</item>
|
||||
<item>Tema Escuro</item>
|
||||
<item>Tema claro</item>
|
||||
<item>Tema escuro</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="channels_text">
|
||||
|
|
@ -27,52 +28,52 @@
|
|||
<item>Estéreo</item>
|
||||
</string-array>
|
||||
|
||||
<string name="no_folder_app">Não foi encontrado nenhum aplicativo para explorar os arquivos</string>
|
||||
<string name="hold_by_call">pausado (chamada atendida)</string>
|
||||
<string name="no_folder_app">Não foi encontrado nenhum app para abrir os arquivos</string>
|
||||
<string name="hold_by_call">pausado (ligação atendida)</string>
|
||||
<string name="recording_status_recording">gravando</string>
|
||||
<string name="recording_status_encoding">codificando</string>
|
||||
<string name="recording_status_pause">pausado</string>
|
||||
<string name="recording_status_edit">editando</string>
|
||||
<string name="confirm_cancel">Deseja cancelar</string>
|
||||
<string name="confirm_cancel">Quer cancelar</string>
|
||||
<string name="encoding_title">Codificando...</string>
|
||||
<string name="pause_title">Pausado...</string>
|
||||
<string name="recording_title">Gravando</string>
|
||||
<string name="open_recording_folder">Abrir pasta das gravações</string>
|
||||
<string name="recording_list_is_empty">A lista das gravações está vazia\n\nToque no ícone do microfone para começar a gravar</string>
|
||||
<string name="open_recording_folder">Abrir pasta de gravações</string>
|
||||
<string name="recording_list_is_empty">A lista de gravações está vazia\n\nToque no ícone do microfone para começar a gravar</string>
|
||||
<string name="record_button">Gravar</string>
|
||||
<string name="cut_button">Cortar</string>
|
||||
<string name="stop_button">Parar</string>
|
||||
<string name="cancel_button">Cancelar</string>
|
||||
<string name="pause_button">Pausar</string>
|
||||
|
||||
<string name="pref_storage_title">Pasta das gravações</string>
|
||||
<string name="pref_storage_title">Pasta de gravações</string>
|
||||
<string name="pref_rate_title">Taxa de amostragem</string>
|
||||
<string name="pref_encoding_title">Codificação</string>
|
||||
<string name="pref_encoding_summary">Formato de saída do arquivo (.wav, .mp3, etc.)</string>
|
||||
<string name="pref_encoding_summary">Tipo de arquivo de áudio (.wav, .mp3, etc.)</string>
|
||||
<string name="pref_mode_title">Canais de áudio</string>
|
||||
<string name="pref_mode_summary">Canais de gravação</string>
|
||||
<string name="pref_nameformat_title">Formato do nome de arquivo</string>
|
||||
<string name="pref_pausecalls_title">Pausar durante a chamada</string>
|
||||
<string name="pref_pausecalls_summary">e voltar a gravar quando a chamada for desligada</string>
|
||||
<string name="pref_nameformat_title">Formato de nome de arquivo</string>
|
||||
<string name="pref_pausecalls_title">Pausar durante a ligação</string>
|
||||
<string name="pref_pausecalls_summary">e voltar a gravar quando a ligação for concluída</string>
|
||||
<string name="pref_silence_title">Modo silencioso</string>
|
||||
<string name="pref_silence_summary">Ativar o \'modo silencioso\' durante a gravação</string>
|
||||
<string name="pref_lockscreen_title">Controle da tela bloqueada</string>
|
||||
<string name="pref_lockscreen_summary">Mostrar os controles quando a tela estiver bloqueada</string>
|
||||
<string name="pref_lockscreen_title">Controle na tela de bloqueio</string>
|
||||
<string name="pref_lockscreen_summary">Mostrar menu de controle quando a tela for bloqueada</string>
|
||||
<string name="pref_theme_title">Tema do App</string>
|
||||
<string name="pref_theme_summary">Definir o tema (claro ou escuro)</string>
|
||||
<string name="pref_application">Aplicativo</string>
|
||||
<string name="pref_recordings">Gravações</string>
|
||||
<string name="pref_fly_title">Codificação em tempo real</string>
|
||||
<string name="pref_fly_summary">Ativando codificação em tempo real desabilitará a edição e recuperação após a falha</string>
|
||||
<string name="pref_fly_summary">Ao permitir codificação em tempo real você desabilitará a edição e recuperação após uma falha</string>
|
||||
<string name="hold_by_bluetooth">pausado (bluetooth desconectado)</string>
|
||||
<string name="menu_search">Pesquisar</string>
|
||||
<string name="save_as_wav">Salvar como WAV</string>
|
||||
<string name="auto_close">Auto-fechar em (%1$d)</string>
|
||||
<string name="save_as_wav">Salvar como .wav</string>
|
||||
<string name="auto_close">Fechar autom. em (%1$d)</string>
|
||||
<string name="mic_muted_error">Mic silenciado</string>
|
||||
<string name="mic_muted_pie">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!</string>
|
||||
<string name="mic_paused">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</string>
|
||||
<string name="tile_start_recording">Iniciar Gravação</string>
|
||||
<string name="tile_stop_recording">Parar a Gravação</string>
|
||||
<string name="encoding_optimization">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</string>
|
||||
<string name="mic_muted_pie">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</string>
|
||||
<string name="mic_paused">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</string>
|
||||
<string name="tile_start_recording">Iniciar uma gravação</string>
|
||||
<string name="tile_stop_recording">Parar a gravação</string>
|
||||
<string name="encoding_optimization">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</string>
|
||||
<string name="per_second">/s</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
<item>Микрофон</item>
|
||||
<item>Необработанный</item>
|
||||
<item>Bluetooth</item>
|
||||
<item>Internal Audio</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="channels_text">
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
<item>Mikrofón</item>
|
||||
<item>Bez spracovania (surové)</item>
|
||||
<item>Bluetooth</item>
|
||||
<item>Internal Audio</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="themes_text">
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
<item>Mikrofon</item>
|
||||
<item>İşlenmemiş</item>
|
||||
<item>Bluetooth</item>
|
||||
<item>Internal Audio</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="themes_text">
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
<item>话筒</item>
|
||||
<item>未处理</item>
|
||||
<item>蓝牙</item>
|
||||
<item>Internal Audio</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="themes_text">
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
<item>麥克風</item>
|
||||
<item>未處理</item>
|
||||
<item>藍牙</item>
|
||||
<item>Internal Audio</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="themes_text">
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
<string name="source_default" translatable="false">default</string>
|
||||
<string name="source_raw" translatable="false">raw</string>
|
||||
<string name="source_bluetooth" translatable="false">bluetooth</string>
|
||||
<string name="source_internal" translatable="false">internal</string>
|
||||
|
||||
<string-array name="sample_rate_values" translatable="false">
|
||||
<item>48000</item>
|
||||
|
|
@ -22,6 +23,17 @@
|
|||
<item>@string/source_mic</item>
|
||||
<item>@string/source_raw</item>
|
||||
<item>@string/source_bluetooth</item>
|
||||
<item>@string/source_internal</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="audioformat_text">
|
||||
<item>16-bit PCM</item>
|
||||
<item>24-bit PCM (float)</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="audioformat_values" translatable="false">
|
||||
<item>16</item>
|
||||
<item>float</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="themes_values" translatable="false">
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
<item>Mic</item>
|
||||
<item>Unprocessed</item>
|
||||
<item>Bluetooth</item>
|
||||
<item>Internal Audio</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="themes_text">
|
||||
|
|
|
|||
|
|
@ -8,6 +8,16 @@
|
|||
android:title="@string/pref_storage_title" />
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="16"
|
||||
android:entries="@array/audioformat_text"
|
||||
android:entryValues="@array/audioformat_values"
|
||||
android:key="audioformat"
|
||||
android:negativeButtonText="@null"
|
||||
android:positiveButtonText="@null"
|
||||
android:summary=""
|
||||
android:title="Audio Format" />
|
||||
|
||||
<com.github.axet.audiorecorder.widgets.RecordingSourcePreferenceCompat
|
||||
android:defaultValue="mic"
|
||||
android:entries="@array/source_text"
|
||||
android:entryValues="@array/source_values"
|
||||
|
|
@ -17,7 +27,7 @@
|
|||
android:summary=""
|
||||
android:title="@string/pref_source_title" />
|
||||
|
||||
<ListPreference
|
||||
<com.github.axet.audiolibrary.widgets.SampleRatePreferenceCompat
|
||||
android:defaultValue="16000"
|
||||
android:entries="@array/sample_rate_text"
|
||||
android:entryValues="@array/sample_rate_values"
|
||||
|
|
|
|||
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
Loading…
Add table
Add a link
Reference in a new issue