From 111d22efed4bfda9e35402d131334259df0761ce Mon Sep 17 00:00:00 2001 From: John Peterson Date: Fri, 3 Mar 2023 00:31:44 +0000 Subject: [PATCH 1/3] Provisionary writing to a file --- .idea/gradle.xml | 4 +-- .idea/misc.xml | 2 +- .idea/runConfigurations.xml | 12 ------- .../com/theeasiestway/opusapp/MainActivity.kt | 3 +- build.gradle | 4 +-- gradle/wrapper/gradle-wrapper.properties | 2 +- opus/src/main/cpp/codec/CodecOpus.cpp | 31 +++++++++++++------ opus/src/main/cpp/codec/CodecOpus.h | 9 ++++-- opus/src/main/cpp/easyopus.cpp | 12 +++---- 9 files changed, 42 insertions(+), 37 deletions(-) delete mode 100644 .idea/runConfigurations.xml diff --git a/.idea/gradle.xml b/.idea/gradle.xml index c5a320f..5986aa6 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -4,9 +4,10 @@ diff --git a/.idea/misc.xml b/.idea/misc.xml index 37a7509..6199cc2 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,6 @@ - + diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml deleted file mode 100644 index 7f68460..0000000 --- a/.idea/runConfigurations.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/java/com/theeasiestway/opusapp/MainActivity.kt b/app/src/main/java/com/theeasiestway/opusapp/MainActivity.kt index 5a09c42..c5a399c 100644 --- a/app/src/main/java/com/theeasiestway/opusapp/MainActivity.kt +++ b/app/src/main/java/com/theeasiestway/opusapp/MainActivity.kt @@ -33,6 +33,7 @@ class MainActivity : AppCompatActivity() { private lateinit var vConvert: CheckBox private val codec = Opus() + private val TOFILE = true private val APPLICATION = Constants.Application.audio() private var CHUNK_SIZE = 0 private lateinit var SAMPLE_RATE: Constants.SampleRate @@ -140,7 +141,7 @@ class MainActivity : AppCompatActivity() { val handleShorts = vShorts.isChecked recalculateCodecValues() - codec.encoderInit(SAMPLE_RATE, CHANNELS, APPLICATION) + codec.encoderInit(SAMPLE_RATE, CHANNELS, APPLICATION, TOFILE) codec.decoderInit(SAMPLE_RATE, CHANNELS) ControllerAudio.initRecorder(SAMPLE_RATE.v, CHUNK_SIZE, CHANNELS.v == 1) diff --git a/build.gradle b/build.gradle index 3aaad6f..4e7e314 100644 --- a/build.gradle +++ b/build.gradle @@ -1,14 +1,14 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.3.61' + ext.kotlin_version = '1.6.20' repositories { google() jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:4.2.0-beta03' + classpath 'com.android.tools.build:gradle:7.3.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 4dbfc67..32f00a0 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https://services.gradle.org/distributions/gradle-6.7.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip diff --git a/opus/src/main/cpp/codec/CodecOpus.cpp b/opus/src/main/cpp/codec/CodecOpus.cpp index 047c6aa..5ff1699 100644 --- a/opus/src/main/cpp/codec/CodecOpus.cpp +++ b/opus/src/main/cpp/codec/CodecOpus.cpp @@ -10,7 +10,7 @@ // Encoder // -int CodecOpus::encoderInit(int sampleRate, int numChannels, int application) { +int CodecOpus::encoderInit(int sampleRate, int numChannels, int application, bool toFile = false) { if (numChannels != 1 && numChannels != 2) LOGE(TAG, "[encoderInit] numChannels is incorrect: %d - it must be either 1 or 2, otherwise the encoder may works incorrectly", numChannels); @@ -21,12 +21,20 @@ int CodecOpus::encoderInit(int sampleRate, int numChannels, int application) { return size; } - encoder = (OpusEncoder*) malloc((size_t) size); + int error; - int ret = opus_encoder_init(encoder, sampleRate, numChannels, application); + if (toFile) { + OggOpusComments *comments; + comments = ope_comments_create(); + fileEncoder = (OggOpusEnc*) malloc((size_t) size); + fileEncoder = ope_encoder_create_file("rec.opus", comments, sampleRate, numChannels, 0, &error); + } else { + encoder = (OpusEncoder*) malloc((size_t) size); + error = opus_encoder_init(encoder, sampleRate, numChannels, application); + } - if (ret) { - LOGE(TAG, "[encoderInit] couldn't init encoder ret: %d; error: %s", ret, opus_strerror(ret)); + if (error) { + LOGE(TAG, "[encoderInit] couldn't init encoder ret: %d; error: %s", error, opus_strerror(error)); free(encoder); return -1; } else LOGD(TAG, "[encoderInit] encoder successfully initialized"); @@ -49,14 +57,14 @@ int CodecOpus::encoderSetComplexity(int complexity) { return opus_encoder_ctl(encoder, OPUS_SET_COMPLEXITY(complexity)); } -std::vector CodecOpus::encode(short *shorts, int length, int frameSize) { +std::vector CodecOpus::encode(short *shorts, int length, int frameSize, bool toFile = false) { std::vector bytes = SamplesConverter::convert(&shorts, length); - std::vector encoded = encode(bytes.data(), frameSize); + std::vector encoded = encode(bytes.data(), frameSize, toFile); uint8_t *data = encoded.data(); return SamplesConverter::convert(&data, encoded.size()); } -std::vector CodecOpus::encode(uint8_t *bytes, int frameSize) { +std::vector CodecOpus::encode(uint8_t *bytes, int frameSize, bool toFile = false) { std::vector result; int ret = checkForNull("encode", true); @@ -65,7 +73,12 @@ std::vector CodecOpus::encode(uint8_t *bytes, int frameSize) { int maxBytesCount = sizeof(unsigned char) * 1024; unsigned char *outBuffer = (unsigned char*) malloc((size_t) maxBytesCount); - int resultLength = opus_encode(encoder, (opus_int16 *) bytes, frameSize, outBuffer, maxBytesCount); + int resultLength; + if (toFile) { + resultLength = ope_encoder_write(fileEncoder, (opus_int16 *) bytes, frameSize); + } else { + resultLength = opus_encode(encoder, (opus_int16 *) bytes, frameSize, outBuffer, maxBytesCount); + } if (resultLength <= 0) { LOGE(TAG, "[encode] error: %s", opus_strerror(resultLength)); return result; diff --git a/opus/src/main/cpp/codec/CodecOpus.h b/opus/src/main/cpp/codec/CodecOpus.h index 7c7b5b6..e07867e 100644 --- a/opus/src/main/cpp/codec/CodecOpus.h +++ b/opus/src/main/cpp/codec/CodecOpus.h @@ -8,12 +8,14 @@ #include #include #include +#include class CodecOpus { private: const char *TAG = "CodecOpus"; OpusEncoder* encoder; + OggOpusEnc* fileEncoder; OpusDecoder* decoder; int decoderNumChannels = -1; @@ -21,11 +23,12 @@ class CodecOpus { int checkForNull(const char *methodName, bool isEncoder); public: - int encoderInit(int sampleRate, int numChannels, int application); + int encoderCreateFile(int sampleRate, int numChannels, int application); + int encoderInit(int sampleRate, int numChannels, int application, bool toFile); int encoderSetBitrate(int bitrate); int encoderSetComplexity(int complexity); - std::vector encode(uint8_t *bytes, int frameSize); - std::vector encode(short *shorts, int length, int frameSize); + std::vector encode(uint8_t *bytes, int frameSize, bool toFile); + std::vector encode(short *shorts, int length, int frameSize, bool toFile); void encoderRelease(); int decoderInit(int sampleRate, int numChannels); diff --git a/opus/src/main/cpp/easyopus.cpp b/opus/src/main/cpp/easyopus.cpp index ee92d86..5a2fef2 100644 --- a/opus/src/main/cpp/easyopus.cpp +++ b/opus/src/main/cpp/easyopus.cpp @@ -14,8 +14,8 @@ CodecOpus codec; // extern "C" -JNIEXPORT jint JNICALL Java_com_theeasiestway_opus_Opus_encoderInit(JNIEnv *env, jobject thiz, jint sample_rate, jint num_channels, jint application) { - return codec.encoderInit(sample_rate, num_channels, application); +JNIEXPORT jint JNICALL Java_com_theeasiestway_opus_Opus_encoderInit(JNIEnv *env, jobject thiz, jint sample_rate, jint num_channels, jint application, jboolean toFile) { + return codec.encoderInit(sample_rate, num_channels, application, toFile); } extern "C" @@ -32,9 +32,9 @@ Java_com_theeasiestway_opus_Opus_encoderSetComplexity(JNIEnv *env, jobject thiz, extern "C" JNIEXPORT jbyteArray JNICALL -Java_com_theeasiestway_opus_Opus_encode___3BI(JNIEnv *env, jobject thiz, jbyteArray bytes, jint frame_size) { +Java_com_theeasiestway_opus_Opus_encode___3BI(JNIEnv *env, jobject thiz, jbyteArray bytes, jint frame_size, jboolean toFile) { jbyte *nativeBytes = env->GetByteArrayElements(bytes, 0); - std::vector encodedData = codec.encode((uint8_t *) nativeBytes, frame_size); + std::vector encodedData = codec.encode((uint8_t *) nativeBytes, frame_size, toFile); int encodedSize = encodedData.size(); if (encodedSize <= 0) return nullptr; @@ -47,11 +47,11 @@ Java_com_theeasiestway_opus_Opus_encode___3BI(JNIEnv *env, jobject thiz, jbyteAr extern "C" JNIEXPORT jshortArray JNICALL -Java_com_theeasiestway_opus_Opus_encode___3SI(JNIEnv *env, jobject thiz, jshortArray shorts, jint frame_size) { +Java_com_theeasiestway_opus_Opus_encode___3SI(JNIEnv *env, jobject thiz, jshortArray shorts, jint frame_size, jboolean toFile) { jshort *nativeShorts = env->GetShortArrayElements(shorts, 0); jint length = env->GetArrayLength(shorts); - std::vector encodedData = codec.encode(nativeShorts, length, frame_size); + std::vector encodedData = codec.encode(nativeShorts, length, frame_size, toFile); int encodedSize = encodedData.size(); if (encodedSize <= 0) return nullptr; From 06adfddd24b66aa2083c79e3a2294a5254d6b843 Mon Sep 17 00:00:00 2001 From: John Peterson Date: Sat, 11 Mar 2023 09:25:09 +0000 Subject: [PATCH 2/3] And the last function --- .../com/theeasiestway/opusapp/MainActivity.kt | 3 +- opus/src/main/cpp/codec/CodecOpus.cpp | 35 +++++++++---------- opus/src/main/cpp/codec/CodecOpus.h | 6 ++-- opus/src/main/cpp/easyopus.cpp | 12 +++---- 4 files changed, 27 insertions(+), 29 deletions(-) diff --git a/app/src/main/java/com/theeasiestway/opusapp/MainActivity.kt b/app/src/main/java/com/theeasiestway/opusapp/MainActivity.kt index c5a399c..5a09c42 100644 --- a/app/src/main/java/com/theeasiestway/opusapp/MainActivity.kt +++ b/app/src/main/java/com/theeasiestway/opusapp/MainActivity.kt @@ -33,7 +33,6 @@ class MainActivity : AppCompatActivity() { private lateinit var vConvert: CheckBox private val codec = Opus() - private val TOFILE = true private val APPLICATION = Constants.Application.audio() private var CHUNK_SIZE = 0 private lateinit var SAMPLE_RATE: Constants.SampleRate @@ -141,7 +140,7 @@ class MainActivity : AppCompatActivity() { val handleShorts = vShorts.isChecked recalculateCodecValues() - codec.encoderInit(SAMPLE_RATE, CHANNELS, APPLICATION, TOFILE) + codec.encoderInit(SAMPLE_RATE, CHANNELS, APPLICATION) codec.decoderInit(SAMPLE_RATE, CHANNELS) ControllerAudio.initRecorder(SAMPLE_RATE.v, CHUNK_SIZE, CHANNELS.v == 1) diff --git a/opus/src/main/cpp/codec/CodecOpus.cpp b/opus/src/main/cpp/codec/CodecOpus.cpp index 5ff1699..44ed7b2 100644 --- a/opus/src/main/cpp/codec/CodecOpus.cpp +++ b/opus/src/main/cpp/codec/CodecOpus.cpp @@ -10,7 +10,7 @@ // Encoder // -int CodecOpus::encoderInit(int sampleRate, int numChannels, int application, bool toFile = false) { +int CodecOpus::encoderInit(int sampleRate, int numChannels, int application) { if (numChannels != 1 && numChannels != 2) LOGE(TAG, "[encoderInit] numChannels is incorrect: %d - it must be either 1 or 2, otherwise the encoder may works incorrectly", numChannels); @@ -23,15 +23,13 @@ int CodecOpus::encoderInit(int sampleRate, int numChannels, int application, boo int error; - if (toFile) { - OggOpusComments *comments; - comments = ope_comments_create(); - fileEncoder = (OggOpusEnc*) malloc((size_t) size); - fileEncoder = ope_encoder_create_file("rec.opus", comments, sampleRate, numChannels, 0, &error); - } else { - encoder = (OpusEncoder*) malloc((size_t) size); - error = opus_encoder_init(encoder, sampleRate, numChannels, application); - } + OggOpusComments *comments; + comments = ope_comments_create(); + fileEncoder = (OggOpusEnc*) malloc((size_t) size); + fileEncoder = ope_encoder_create_file("rec.opus", comments, sampleRate, numChannels, 0, &error); + + encoder = (OpusEncoder*) malloc((size_t) size); + error = opus_encoder_init(encoder, sampleRate, numChannels, application); if (error) { LOGE(TAG, "[encoderInit] couldn't init encoder ret: %d; error: %s", error, opus_strerror(error)); @@ -57,14 +55,14 @@ int CodecOpus::encoderSetComplexity(int complexity) { return opus_encoder_ctl(encoder, OPUS_SET_COMPLEXITY(complexity)); } -std::vector CodecOpus::encode(short *shorts, int length, int frameSize, bool toFile = false) { +std::vector CodecOpus::encode(short *shorts, int length, int frameSize) { std::vector bytes = SamplesConverter::convert(&shorts, length); - std::vector encoded = encode(bytes.data(), frameSize, toFile); + std::vector encoded = encode(bytes.data(), frameSize); uint8_t *data = encoded.data(); return SamplesConverter::convert(&data, encoded.size()); } -std::vector CodecOpus::encode(uint8_t *bytes, int frameSize, bool toFile = false) { +std::vector CodecOpus::encode(uint8_t *bytes, int frameSize) { std::vector result; int ret = checkForNull("encode", true); @@ -74,11 +72,8 @@ std::vector CodecOpus::encode(uint8_t *bytes, int frameSize, bool toFil unsigned char *outBuffer = (unsigned char*) malloc((size_t) maxBytesCount); int resultLength; - if (toFile) { - resultLength = ope_encoder_write(fileEncoder, (opus_int16 *) bytes, frameSize); - } else { - resultLength = opus_encode(encoder, (opus_int16 *) bytes, frameSize, outBuffer, maxBytesCount); - } + resultLength = ope_encoder_write(fileEncoder, (opus_int16 *) bytes, frameSize); + resultLength = opus_encode(encoder, (opus_int16 *) bytes, frameSize, outBuffer, maxBytesCount); if (resultLength <= 0) { LOGE(TAG, "[encode] error: %s", opus_strerror(resultLength)); return result; @@ -90,6 +85,10 @@ std::vector CodecOpus::encode(uint8_t *bytes, int frameSize, bool toFil } void CodecOpus::encoderRelease() { + ope_encoder_drain(fileEncoder); + ope_encoder_destroy(fileEncoder); + fileEncoder = nullptr; + if (encoder) opus_encoder_destroy(encoder); encoder = nullptr; } diff --git a/opus/src/main/cpp/codec/CodecOpus.h b/opus/src/main/cpp/codec/CodecOpus.h index e07867e..d56f5e3 100644 --- a/opus/src/main/cpp/codec/CodecOpus.h +++ b/opus/src/main/cpp/codec/CodecOpus.h @@ -24,11 +24,11 @@ class CodecOpus { public: int encoderCreateFile(int sampleRate, int numChannels, int application); - int encoderInit(int sampleRate, int numChannels, int application, bool toFile); + int encoderInit(int sampleRate, int numChannels, int application); int encoderSetBitrate(int bitrate); int encoderSetComplexity(int complexity); - std::vector encode(uint8_t *bytes, int frameSize, bool toFile); - std::vector encode(short *shorts, int length, int frameSize, bool toFile); + std::vector encode(uint8_t *bytes, int frameSize); + std::vector encode(short *shorts, int length, int frameSize); void encoderRelease(); int decoderInit(int sampleRate, int numChannels); diff --git a/opus/src/main/cpp/easyopus.cpp b/opus/src/main/cpp/easyopus.cpp index 5a2fef2..ee92d86 100644 --- a/opus/src/main/cpp/easyopus.cpp +++ b/opus/src/main/cpp/easyopus.cpp @@ -14,8 +14,8 @@ CodecOpus codec; // extern "C" -JNIEXPORT jint JNICALL Java_com_theeasiestway_opus_Opus_encoderInit(JNIEnv *env, jobject thiz, jint sample_rate, jint num_channels, jint application, jboolean toFile) { - return codec.encoderInit(sample_rate, num_channels, application, toFile); +JNIEXPORT jint JNICALL Java_com_theeasiestway_opus_Opus_encoderInit(JNIEnv *env, jobject thiz, jint sample_rate, jint num_channels, jint application) { + return codec.encoderInit(sample_rate, num_channels, application); } extern "C" @@ -32,9 +32,9 @@ Java_com_theeasiestway_opus_Opus_encoderSetComplexity(JNIEnv *env, jobject thiz, extern "C" JNIEXPORT jbyteArray JNICALL -Java_com_theeasiestway_opus_Opus_encode___3BI(JNIEnv *env, jobject thiz, jbyteArray bytes, jint frame_size, jboolean toFile) { +Java_com_theeasiestway_opus_Opus_encode___3BI(JNIEnv *env, jobject thiz, jbyteArray bytes, jint frame_size) { jbyte *nativeBytes = env->GetByteArrayElements(bytes, 0); - std::vector encodedData = codec.encode((uint8_t *) nativeBytes, frame_size, toFile); + std::vector encodedData = codec.encode((uint8_t *) nativeBytes, frame_size); int encodedSize = encodedData.size(); if (encodedSize <= 0) return nullptr; @@ -47,11 +47,11 @@ Java_com_theeasiestway_opus_Opus_encode___3BI(JNIEnv *env, jobject thiz, jbyteAr extern "C" JNIEXPORT jshortArray JNICALL -Java_com_theeasiestway_opus_Opus_encode___3SI(JNIEnv *env, jobject thiz, jshortArray shorts, jint frame_size, jboolean toFile) { +Java_com_theeasiestway_opus_Opus_encode___3SI(JNIEnv *env, jobject thiz, jshortArray shorts, jint frame_size) { jshort *nativeShorts = env->GetShortArrayElements(shorts, 0); jint length = env->GetArrayLength(shorts); - std::vector encodedData = codec.encode(nativeShorts, length, frame_size, toFile); + std::vector encodedData = codec.encode(nativeShorts, length, frame_size); int encodedSize = encodedData.size(); if (encodedSize <= 0) return nullptr; From 1c1d4e2c76d864c6ad0c230cf61d0e556ae570df Mon Sep 17 00:00:00 2001 From: John Sebastian Peterson Date: Mon, 13 Mar 2023 12:08:00 +0000 Subject: [PATCH 3/3] Add the missing objects --- .idea/gradle.xml | 2 +- opus/build.gradle | 3 ++- opus/src/main/cpp/CMakeLists.txt | 4 ++-- opus/src/main/cpp/codec/CodecOpus.cpp | 7 ++++++- opus/src/main/cpp/lib/x86_64/libopusenc.a | Bin 0 -> 232190 bytes 5 files changed, 11 insertions(+), 5 deletions(-) create mode 100644 opus/src/main/cpp/lib/x86_64/libopusenc.a diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 5986aa6..068bb52 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -7,7 +7,7 @@