Coder Social home page Coder Social logo

louisyonge / opus_android Goto Github PK

View Code? Open in Web Editor NEW
222.0 10.0 82.0 8.97 MB

This is an Android library transplanted from official Opus codec. With this library, Opus format audio can be operated in an easy way. Application level function includes audio record, playback, encode and decode.

License: Apache License 2.0

Java 2.92% Makefile 1.18% C 90.23% Perl 0.28% Assembly 0.67% C++ 4.05% CSS 0.50% HTML 0.08% M4 0.09%

opus_android's Introduction

NOTE: THIS PROJECT IS DEPRECATED. This project is no longer being maintained.

Opus for Android

Welcome to the Opus library for Android.

Summary

This is an Android library transplanted from official Opus codec. With this library, Opus format audio can be operated in an easy way. Application level function includes audio record, playback, encode and decode.

Integration

Add the following dependency to your project.

compile 'top.oply.opuslib:opuslib:1.0.2'

How to use the OpusLib codes (Method 1)

OpusService is the highest level interface to programmer. It's a background Server running automatically. All you need to do is sending Intents to it, and receiving the feedback messages through a Broadcast Receiver. The approach is recommended over the Method 2.

Sending message.

Many static public method can be called directly. For details, please refer to the source code of OpusService.java

OpusService.play(Context context, String fileName);
OpusService.record(Context context, String fileName);
......

Receiving message.

A Broadcast Receiver is needed to receive the feadback messages while playing, recording or converting a opus file. Below is an example.

//register a broadcast receiver
mReceiver = new OpusReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(OpusEvent.ACTION_OPUS_UI_RECEIVER);
registerReceiver(mReceiver, filter);

//define a broadcast receiver
class OpusReceiver extends BroadcastReceiver {
        public void onReceive(Context context, Intent intent) {
            Bundle bundle = intent.getExtras();
            int type = bundle.getInt(OpusEvent.EVENT_TYPE, 0);
            switch (type) {
                case OpusEvent.CONVERT_FINISHED:
                    break;
                case OpusEvent.CONVERT_FAILED:
                    break;
                case OpusEvent.CONVERT_STARTED:
                    break;
                case OpusEvent.RECORD_FAILED:
                    break;
                case OpusEvent.RECORD_FINISHED:
                    break;
                case OpusEvent.RECORD_STARTED:
                    break;
                case OpusEvent.RECORD_PROGRESS_UPDATE:
                    break;
                case OpusEvent.PLAY_PROGRESS_UPDATE:
                    break;
                case OpusEvent.PLAY_GET_AUDIO_TRACK_INFO:
                    break;
                case OpusEvent.PLAYING_FAILED:
                    break;
                case OpusEvent.PLAYING_FINISHED:
                    break;
                case OpusEvent.PLAYING_PAUSED:
                    break;
                case OpusEvent.PLAYING_STARTED:
                    break;
                default:
                    Log.d(TAG, intent.toString() + "Invalid request,discarded");
                    break;
            }
        }
    }

How to use the OpusLib codes (Method 2)

  • Encode and Decode
OpusTool oTool = new OpusTool();
oTool.decode(fileName,fileNameOut, null);
oTool.encode(fileName, fileNameOut, null);
  • Playback
OpusPlayer opusPlayer = OpusPlayer.getInstance();
opusPlayer.play(fileName);
opusPlayer.stop();
  • Record
OpusRecorder opusRecorder = OpusRecorder.getInstance();
opusRecorder.startRecording(fileName);
opusRecorder.stopRecording();

Well, you can stop reading if you don't need to modify the library code. Your project should be working if you follow the steps above.

##Project Compilation

  • pre-requisites
  1. JDK v1.8 or higher
  2. SDK v2.2.1 or higher
  3. NDK r10d or higher (Note: remember to export NDK's path)
  4. Android Studio (with SDK) 1.2.1 or higher
  • Summary of set up:
  1. Get the source code.[Git] (https://github.com/louisyonge/opus_android.git)
    2 remember to export NDK's path. Take Linux for example, add the following code to the end of the file "/etc/profile", and then reboot your system.
NDK_ROOT=/usr/local/lib/android-ndk-r9d
export PATH=$NDK_ROOT:$PATH
  1. Open it in Android Studio, and modify the path of SDK and NDK in the file "local.properties"
  2. Compile and run.
  • Testing Hints:
  1. This demo use external storage to store audio file. Be sure your Android device has a SD card when testing this demo. You could also store them in internal storage by changing source code.
  2. Recommend to use a real Android device instead of Android virtual device. . Some times AVD has no sound system supports.
  3. When testing the master branch, firstly you need to copy at least one wav file and an opus file to the folder "OpusPlayer" under the root of SD card. Secondly, launch the demo. Then you can play or encode/decode these audio files.

NDK Compilation

Development Environment

SDK, NDK, Android Studio, Eclipse

Note: Android Studio 1.2 does not support the debug of Native code. So it is wise to develop the C&C++ code in Eclipse. For this project, codes under the folder "OpusPlayer\opuslib\src\main\jni" are Native codes. The rest of this project is Java codes, developed by Android Studio.(deprecated)

How to debug Native code

  • Android NDK compiler
  1. cd "OpusPlayer\opuslib\src\main\jni".
  2. Issure command "ndk-build".
  3. Click build in Android Studio.
  4. Watch logs in logcat.
  • Linux As Android Studio does not support JNI debugging(for version 1.2 and earlier), using Eclipse in Linux is a good way to debug Native codes. There is a valid Makefile under the JNI folder of this project. So you can ether import the JNI code to a Eclipse project, or just cd to the folder and issue compile command "make". When compiling for Linux, Comment out "#define ANDROID_V" in the file "\OpusPlayer\opuslib\src\main\jni\include\config.h", and uncomment it when compiling by for Android. This Macro is a switch to redirect std-stream to logcat, and vice versa. "Opus_demo.c" is the console demo of testing opuslib for Linux. Cygwin is not recommended, because you might encounter some strange compilation problem.

Open Project Reference

  1. Opus (git://git.opus-codec.org/opus.git)

  2. Opus-tools (git://git.xiph.org/opus-tools.git)

  3. Opusfile (git://git.xiph.org/opusfile.git)

##Licence

Project uses Apache 2.0 License

###Have fun!

opus_android's People

Contributors

louisyonge avatar robertplant avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

opus_android's Issues

测试录音然后播放opus文件发现声音急促

非常感谢你写的这个demo,能够将pcm流编码为opus文件输出。目前测试中发现录音后播放文件听到声音比较急促,像是录制的声音间隔太长被截取导致。从日志中发现录制间隔较长,试着把录制的buffer调整为较小的320,然后每次直接全部wirteFrame,发现编码出来的声音不正常。目前没有十分了解opusaudio.c中实现int writeFrame(uint8_t *framePcmBytes, unsigned int frameByteCount) 的逻辑。实现中每次写入buffer编码后都调整文件头是否必须,能否在终止录音时再补充(不考虑中间异常退出情况)? 另外,实现中感觉像是每次写入是重采样,是否是需要的。
为何调整写入的buffer大小会造成编码出来的声音不正常?(demo中默认时1920)

Encoded data in WAV format

Apologize for raising a question as issue (only bcoz of the unavailability of contact a user).
Have you tried the opus encoded data in wav file itself ?

Opus -->(to)--> Wav-> (to)-->Opus

Hi作者你好感谢你提供这么好用的库

我现在发现一个问题,使用demo录制opus文件,然后decode成wav,再将wav文件encode成opus
[round 1] recoder opus
[round 2]decode opus to wav
[round 3]encode wav(the same round 2) to opus

发现round3 的opus文件会比 round1 的opus文件大一倍,具体是哪些参数影响呢?

Seeking to a specific position not possible

I'm coding a chat app and using that library for voice notes in this app. For better functionality, it wouldn't be bad to have a seeking functionality there. I've found a seeking function, but it is not that, what I need. Is the seeking function in the code and I am still not finding it or is there a method to make a workaround?
Thanks for answering!

NPE in service (v.1.0.2)

Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'void java.util.Timer.cancel()' on a null object reference
at top.oply.opuslib.OpusRecorder.stopRecording(SourceFile:162)
at top.oply.opuslib.OpusService.handleActionStopRecording(SourceFile:278)
at top.oply.opuslib.OpusService.onHandleIntent(SourceFile:218)
at top.oply.opuslib.OpusService.access$000(SourceFile:15)
at top.oply.opuslib.OpusService$ServiceHandler.handleMessage(SourceFile:294)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:179)
at android.os.HandlerThread.run(HandlerThread.java:61)

Reproduced on Android 4, 5 and 6. Exact steps are unknown, this in formation is from Fabric.

Error

E/AndroidRuntime: FATAL EXCEPTION: main java.lang.UnsatisfiedLinkError: Native method not found: top.oply.opuslib.OpusTool.openOpusFile:(Ljava/lang/String;)I
at top.oply.opuslib.OpusTool.openOpusFile(Native Method)

the log is too much,how to close?

07-07 19:33:45.595 32278-32462/com.bolin.pcmconvert E/libOpusTool: argc is :3
07-07 19:33:45.595 32278-32462/com.bolin.pcmconvert E/libOpusTool: argv0 isopus:
07-07 19:33:45.595 32278-32462/com.bolin.pcmconvert E/libOpusTool: argv1 is/storage/emulated/0/Atemp/output_slice_0062.wav:
07-07 19:33:45.595 32278-32462/com.bolin.pcmconvert E/libOpusTool: argv2 is:/storage/emulated/0/Atemp/output_slice_0062.wav.opus
07-07 19:33:45.600 32278-32462/com.bolin.pcmconvert E/libOpusTool: Encoding using libopus 1.1
07-07 19:33:45.600 32278-32462/com.bolin.pcmconvert E/libOpusTool: (audio)
07-07 19:33:45.600 32278-32462/com.bolin.pcmconvert E/libOpusTool: -----------------------------------------------------
07-07 19:33:45.600 32278-32462/com.bolin.pcmconvert E/libOpusTool: Input: 44.1kHz 2 channels
07-07 19:33:45.600 32278-32462/com.bolin.pcmconvert E/libOpusTool: Output: 2 channels (
07-07 19:33:45.600 32278-32462/com.bolin.pcmconvert E/libOpusTool: 2 coupled
07-07 19:33:45.600 32278-32462/com.bolin.pcmconvert E/libOpusTool: )
20ms packets, 96kbit/sec VBR
07-07 19:33:45.600 32278-32462/com.bolin.pcmconvert E/libOpusTool: Preskip: 356
07-07 19:33:45.603 32278-32462/com.bolin.pcmconvert E/libOpusTool: [|] 00:00:00.02 2e+04x realtime, 91.5kbit/s
07-07 19:33:45.604 32278-32462/com.bolin.pcmconvert E/libOpusTool:
07-07 19:33:45.604 32278-32462/com.bolin.pcmconvert E/libOpusTool:

OpusServiceHander java.lang.IllegalStateException: startRecording() called on an uninitialized AudioRecord.

in some devices (like nexus one)
inside opus recorder class when create new object of AudioRecorder, this solution can solve the error

private static int[] mSampleRates = new int[] { 8000, 11025, 22050, 44100 };
public AudioRecord findAudioRecord() {
    for (int rate : mSampleRates) {
        for (short audioFormat : new short[] { AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT }) {
            for (short channelConfig : new short[] { AudioFormat.CHANNEL_IN_MONO, AudioFormat.CHANNEL_IN_STEREO }) {
                try {
                    Log.d(C.TAG, "Attempting rate " + rate + "Hz, bits: " + audioFormat + ", channel: "
                            + channelConfig);
                    int bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat);

                    if (bufferSize != AudioRecord.ERROR_BAD_VALUE) {
                        // check if we can instantiate and have a success
                        AudioRecord recorder = new AudioRecord(AudioSource.DEFAULT, rate, channelConfig, audioFormat, bufferSize);

                        if (recorder.getState() == AudioRecord.STATE_INITIALIZED)
                            return recorder;
                    }
                } catch (Exception e) {
                    Log.e(C.TAG, rate + "Exception, keep trying.",e);
                }
            }
        }
    }
    return null;
}

AudioRecord recorder = findAudioRecord();
recorder.release();

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.