GithubHelp home page GithubHelp logo

igorski / mwengine Goto Github PK

View Code? Open in Web Editor NEW
253.0 20.0 45.0 2.11 MB

Audio engine and DSP library for Android, written in C++ providing low latency performance within a musical context, while providing a Java/Kotlin API. Supports both OpenSL and AAudio.

License: MIT License

C++ 92.77% C 1.90% Java 4.01% CMake 0.87% SWIG 0.45%
android audio-engine opensl low-latency c-plus-plus aaudio java ndk cpp cplusplus

mwengine's Introduction

Hello kind visitor ๐Ÿ‘‹

In my GitHub repositories, you can find most of my personal projects, be it audio plugins, web based applications or libraries of any kind (for various languages/platforms). All of it for you to see and to get your grubby hands on. All code is production ready without hidden secrets and comes with (varying degrees of) documentation and test coverage. Consult the README of each repo in case you have questions, bug reports or requests. Likewise, if you see something horribly wrong, inefficient or containing a crude oversight, feel free to contribute!

If you don't feel like tinkering with code, you can just go to my website and run the web applications directly from your browser, or download the audio plugins there.

If you like what I'm doing and would like to show your appreciation, you can always:

"Buy Me A Coffee"

Though it's up to you to do so, everything that I do/make will remain both free to use and fully open source.

What Iโ€™m currently working on:

  • a "swarm of howling voices"-synthesizer
  • my next record (you can always stream my music on the platform of your choice)
  • a browser based RTS game (nothing world shocking, just to amuse myself)

mwengine's People

Contributors

igorski avatar robtize avatar teotigraphix 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mwengine's Issues

example app crashes when screen is rotated

I run the example app, started the sequencer and rotated the screen.

Logcat output:

09-29 21:02:29.943 24187 24214 D MWENGINE: seq. position: 11, buffer offset: 216, elapsed samples: 66456
09-29 21:02:29.964 24187 24214 E libOpenSLES: frameworks/wilhelm/src/itf/IBufferQueue.c:57: pthread_mutex_lock_timeout_np returned 110
09-29 21:02:29.975 24187 24187 D MWENGINE: initing MWEngineActivity
09-29 21:02:29.975 24187 24187 D AndroidRuntime: Shutting down VM
09-29 21:02:29.976 24187 24187 E AndroidRuntime: FATAL EXCEPTION: main
09-29 21:02:29.976 24187 24187 E AndroidRuntime: Process: nl.igorski.example, PID: 24187
09-29 21:02:29.976 24187 24187 E AndroidRuntime: java.lang.Error: MWEngine already instantiated
09-29 21:02:29.976 24187 24187 E AndroidRuntime: at nl.igorski.lib.audio.MWEngine.(MWEngine.java:110)
09-29 21:02:29.976 24187 24187 E AndroidRuntime: at nl.igorski.example.MWEngineActivity.init(MWEngineActivity.java:80)
09-29 21:02:29.976 24187 24187 E AndroidRuntime: at nl.igorski.example.MWEngineActivity.onCreate(MWEngineActivity.java:68)
09-29 21:02:29.976 24187 24187 E AndroidRuntime: at android.app.Activity.performCreate(Activity.java:6285)
09-29 21:02:29.976 24187 24187 E AndroidRuntime: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108)
09-29 21:02:29.976 24187 24187 E AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2417)
09-29 21:02:29.976 24187 24187 E AndroidRuntime: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2524)
09-29 21:02:29.976 24187 24187 E AndroidRuntime: at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4176)
09-29 21:02:29.976 24187 24187 E AndroidRuntime: at android.app.ActivityThread.access$1000(ActivityThread.java:154)
09-29 21:02:29.976 24187 24187 E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1397)
09-29 21:02:29.976 24187 24187 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:102)
09-29 21:02:29.976 24187 24187 E AndroidRuntime: at android.os.Looper.loop(Looper.java:234)
09-29 21:02:29.976 24187 24187 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5526)
09-29 21:02:29.976 24187 24187 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
09-29 21:02:29.976 24187 24187 E AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
09-29 21:02:29.976 24187 24187 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
09-29 21:02:29.981 925 3341 D ActivityManager: New dropbox entry: nl.igorski.example, data_app_crash, a024b8ad-0efb-4d27-a227-485d05b4bc49
09-29 21:02:29.984 925 3341 W ActivityManager: Force finishing activity nl.igorski.example/.MWEngineActivity
09-29 21:02:30.009 23810 24256 W ContextImpl: Calling a method in the system process without a qualified user: android.app.ContextImpl.bindService:1271 android.content.ContextWrapper.bindService:604 com.sonyericsson.crashmonitor.MiscTaAdapter.open:90 com.sonyericsson.crashmonitor.service.CrashMonitorService.onInit:127 com.sonyericsson.crashmonitor.service.CrashMonitorService.onHandleIntent:192
09-29 21:02:30.018 925 2731 I OpenGLRenderer: Initialized EGL, version 1.4
09-29 21:02:30.040 24187 24214 D MWENGINE: seq. position: 12, buffer offset: 954, elapsed samples: 71994
09-29 21:02:30.095 16523 20542 E AsyncOperation: serviceID=40, operation=LogOperation
09-29 21:02:30.095 16523 20542 E AsyncOperation: OperationException[Status{statusCode=Storage full, resolution=null}]
09-29 21:02:30.095 16523 20542 E AsyncOperation: at oqf.a(:com.google.android.gms@[email protected] (040306-211705629):87)
09-29 21:02:30.095 16523 20542 E AsyncOperation: at wwk.run(:com.google.android.gms@[email protected] (040306-211705629):29)
09-29 21:02:30.095 16523 20542 E AsyncOperation: at bdbk.run(:com.google.android.gms@[email protected] (040306-211705629):2)
09-29 21:02:30.095 16523 20542 E AsyncOperation: at qcr.run(:com.google.android.gms@[email protected] (040306-211705629):21)
09-29 21:02:30.095 16523 20542 E AsyncOperation: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
09-29 21:02:30.095 16523 20542 E AsyncOperation: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
09-29 21:02:30.095 16523 20542 E AsyncOperation: at qiv.run(:com.google.android.gms@[email protected] (040306-211705629))
09-29 21:02:30.095 16523 20542 E AsyncOperation: at java.lang.Thread.run(Thread.java:818)
09-29 21:02:30.098 16523 20542 E AsyncOperation: serviceID=40, operation=LogOperation
09-29 21:02:30.098 16523 20542 E AsyncOperation: OperationException[Status{statusCode=Storage full, resolution=null}]
09-29 21:02:30.098 16523 20542 E AsyncOperation: at oqf.a(:com.google.android.gms@[email protected] (040306-211705629):87)
09-29 21:02:30.098 16523 20542 E AsyncOperation: at wwk.run(:com.google.android.gms@[email protected] (040306-211705629):29)
09-29 21:02:30.098 16523 20542 E AsyncOperation: at bdbk.run(:com.google.android.gms@[email protected] (040306-211705629):2)
09-29 21:02:30.098 16523 20542 E AsyncOperation: at qcr.run(:com.google.android.gms@[email protected] (040306-211705629):21)
09-29 21:02:30.098 16523 20542 E AsyncOperation: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
09-29 21:02:30.098 16523 20542 E AsyncOperation: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
09-29 21:02:30.098 16523 20542 E AsyncOperation: at qiv.run(:com.google.android.gms@[email protected] (040306-211705629))
09-29 21:02:30.098 16523 20542 E AsyncOperation: at java.lang.Thread.run(Thread.java:818)
09-29 21:02:30.122 925 1020 I WindowManager: Screen frozen for +271ms due to Window{f2a59ad u0 NavigationBar}
09-29 21:02:30.161 24187 24214 D MWENGINE: seq. position: 13, buffer offset: 732, elapsed samples: 77532
09-29 21:02:30.283 24187 24214 D MWENGINE: seq. position: 14, buffer offset: 510, elapsed samples: 83070
09-29 21:02:30.400 24187 24214 D MWENGINE: seq. position: 15, buffer offset: 288, elapsed samples: 88608
09-29 21:02:30.401 24187 24214 D MWENGINE: seq. position: 0, buffer offset: 292, elapsed samples: 0

Logger - com.teotigraphix.mwenginetest1 D/AudioTrack: stop() called with 720 frames delivered

Hey,

I cannot for the life of me figure out where this log is. The log is being produced as you can see many times a second.

I don't understand why it's calling stop() on AudioTrack, where ever this is, is it actually AudioTrack?

2018-11-07 14:27:09.874 24656-24680/com.teotigraphix.mwenginetest1 D/AudioTrack: stop() called with 720 frames delivered
2018-11-07 14:27:09.889 24656-24680/com.teotigraphix.mwenginetest1 D/AudioTrack: stop() called with 720 frames delivered
2018-11-07 14:27:09.906 24656-24680/com.teotigraphix.mwenginetest1 D/AudioTrack: stop() called with 720 frames delivered
2018-11-07 14:27:09.921 24656-24680/com.teotigraphix.mwenginetest1 D/AudioTrack: stop() called with 720 frames delivered
2018-11-07 14:27:09.934 24656-24680/com.teotigraphix.mwenginetest1 D/AudioTrack: stop() called with 720 frames delivered
2018-11-07 14:27:09.949 24656-24680/com.teotigraphix.mwenginetest1 D/AudioTrack: stop() called with 720 frames delivered
2018-11-07 14:27:09.964 24656-24680/com.teotigraphix.mwenginetest1 D/AudioTrack: stop() called with 720 frames delivered
2018-11-07 14:27:09.979 24656-24680/com.teotigraphix.mwenginetest1 D/AudioTrack: stop() called with 720 frames delivered
2018-11-07 14:27:09.995 24656-24680/com.teotigraphix.mwenginetest1 D/AudioTrack: stop() called with 720 frames delivered
2018-11-07 14:27:10.010 24656-24680/com.teotigraphix.mwenginetest1 D/AudioTrack: stop() called with 720 frames delivered
2018-11-07 14:27:10.024 24656-24680/com.teotigraphix.mwenginetest1 D/AudioTrack: stop() called with 720 frames delivered
2018-11-07 14:27:10.040 24656-24680/com.teotigraphix.mwenginetest1 D/AudioTrack: stop() called with 720 frames delivered
2018-11-07 14:27:10.055 24656-24680/com.teotigraphix.mwenginetest1 D/AudioTrack: stop() called with 720 frames delivered
2018-11-07 14:27:10.070 24656-24680/com.teotigraphix.mwenginetest1 D/AudioTrack: stop() called with 720 frames delivered
2018-11-07 14:27:10.085 24656-24680/com.teotigraphix.mwenginetest1 D/AudioTrack: stop() called with 720 frames delivered
2018-11-07 14:27:10.100 24656-24680/com.teotigraphix.mwenginetest1 D/AudioTrack: stop() called with 720 frames delivered
2018-11-07 14:27:10.114 24656-24680/com.teotigraphix.mwenginetest1 D/AudioTrack: stop() called with 720 frames delivered

sometimes sound is interrupted for a few ms

there are some sound glitches from time to time. in the log I see:

IBufferQueue.c:57: pthread_mutex_lock_timeout_np returned 110

Google says that's a general problem but maybe you have some hints to prevent this. My app is using up to 5% of cpu power and I'm working with SampleEvents only.

Sample - Runtime Permissions

I am pretty sure a comment or something should be added that as of Nov 1st, all apps must be compiled with API 26 or greater to be released on the play store.

The sample app does not handle run-time file access and crashes on non debug devices.

This is not asking to add the code since it's a sample but some people may scratch their heads.

_engine.dispose lets crash app when called 2 times

How to reproduce:

  1. start the example app (hitting play button not necessary)
  2. send app in background
  3. bring the app back in foreground (everything seems still fine)
  4. send it in background again
  5. bring it back in foreground
  6. now the gui is not responding anymore and the app crashes after some seconds

Phone: Sony Z3 Compact
OS: 6.0.1, BN: 23.5.A.1.291

native crash at audioengine.cpp line 357

This happens randomly. I'm using SampleEvents which are deleted and added while the sequencer is running.

********** Crash dump: **********
Build fingerprint: 'Sony/D5803/D5803:6.0.1/23.5.A.1.291/2769308465:user/release-keys'
pid: 24168, tid: 24218, name: Thread-118809 >>> com.harthorst.compas <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x9
Stack frame #00 pc 0003060c /data/app/com.harthorst.compas-2/lib/arm/libmwengine.so (_ZN11AudioEngine6renderEi+811): Routine AudioEngine::render(int) at /Users/thf/tmp/compas-app/mwengine/src/main/cpp/./audioengine.cpp:357
Stack frame #1 pc 00030187 /data/app/com.harthorst.compas-2/lib/arm/libmwengine.so (_ZN11AudioEngine5startEv+306): Routine AudioEngine::start() at /Users/thf/tmp/compas-app/mwengine/src/main/cpp/./audioengine.cpp:156
Stack frame #2 pc 00d4203d /data/app/com.harthorst.compas-2/oat/arm/base.odex (offset 0x934000) (void nl.igorski.lib.audio.mwengine.MWEngineCoreJNI.start()+72)
Stack frame #3 pc 010faf89 /data/app/com.harthorst.compas-2/oat/arm/base.odex (offset 0x934000) (void nl.igorski.lib.audio.mwengine.MWEngineCore.start()+84)
Stack frame #4 pc 00d12959 /data/app/com.harthorst.compas-2/oat/arm/base.odex (offset 0x934000) (void nl.igorski.lib.audio.MWEngine.run()+852)
Stack frame #5 pc 000e6401 /system/lib/libart.so (art_quick_invoke_stub_internal+64)
Stack frame #6 pc 00403305 /system/lib/libart.so (art_quick_invoke_stub+188)
Stack frame #7 pc 00102774 [stack:24218]

local.properties should not be included in version control

local.properties: You can put information about the SDK location but also, your sensitive data like username and password of your repo access and the location of your Key to sign the Apks.

You have hard coded values for the sdk location that are not universal. This file needs to be gitignored as well so users like myself can override properties locally.

Sometime sound is distorted at the beginning of the loop

I have a sequence of sample events running in an infinite loop. Sometimes I hear a distortion when the loop returns to the beginning. Sometimes not. This happens randomly. I don't change speed nor do I do anything else. It's just the engine running.

Do you have any hints about that? I tried the limiter but it does not help here.

Sequencer events

Again excuse my noobness but I am trying to wrap my head around the sequencer implementation.

I guess giving an example is easier then asking the question.

I am trying to figure out how I would maintain patterns(with step length) per channel and piano roll per channel, then be able to real-time sequence the pattern data along with the piano roll of each sequencer data model that holds the individual events.

I think I can pretty much wrap my head around the pattern stuff.

  1. Is this sequencer just a container for any event and it's the client's responsibility to separate the data on the client side and somehow shove events into the main sequencer as needed?

  2. How do you setup non quantized beats without using a grid?

Crash on startup

Hello, I'm trying to import mwengine to my project.

I copied c++ and java source as same directory structure and swig build script and build was successful.

When I try to start the activity from my app, it crashes.

The activity and asserts resources are almost same as sample. (MWEngineActivity.java, hihat.wav, clap.wav)

The logcat said

12-20 15:07:31.230 30870-30870/net.gerosyab.guitaroid A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x4 in tid 30870 (osyab.guitaroid)
12-20 15:07:31.230 3313-3477/? D/audio_hw_primary: out_set_parameters: enter: kvpairs: routing=2
12-20 15:07:31.230 3313-3477/? D/AudioFlinger: setCurDevice() 0x2
                                               [ 12-20 15:07:31.233  3121: 3121 W/         ]
                                               debuggerd: handling request: pid=30870 uid=10568 gid=10568 tid=30870
12-20 15:07:31.234 30870-31001/net.gerosyab.guitaroid V/MWENGINE: STARTED engine
12-20 15:07:31.235 3313-3477/? V/audio_hw_primary: start_output_stream+, out->device : 00000002 , out->type = 1
12-20 15:07:31.235 30870-31002/net.gerosyab.guitaroid I/AudioTrack: Skip ramp
12-20 15:07:31.235 3313-3477/? D/audio_hw_primary: start_output_stream jack_skip_check false
12-20 15:07:31.236 30870-31002/net.gerosyab.guitaroid I/AudioTrack: Skip ramp
12-20 15:07:31.262 3313-3477/? D/audio_hw_primary: start_output_stream (0xeeaa89a0) out->pcm_device:6 out->config.rate:48000 out->config.format:0 out->period_size:240
12-20 15:07:31.262 3313-3477/? D/audio_hw_primary: start_output_stream (0xeeaa89a0) out->config.rate:48000 out->config.format:0 out->period_size:240
12-20 15:07:31.262 3313-3477/? V/audio_hw_primary: select_devices output_scenario:0 input_scenario:-1 out_snd_device 0x2 in_snd_device:0x0
12-20 15:07:31.263 3313-3477/? I/audio_route: > audio_route_reset :
12-20 15:07:31.263 3313-3477/? I/audio_route: > audio_route_apply_path : "media-speaker"
12-20 15:07:31.375 3313-3477/? V/audio_hw_primary: select_devices() output_route "media-speaker" 
12-20 15:07:31.375 3313-3477/? I/audio_route: > audio_route_apply_path : "gain-media-speaker"
12-20 15:07:31.375 3313-3477/? V/audio_hw_primary: select_devices() output_gain "gain-media-speaker" 
12-20 15:07:31.375 3313-3477/? I/audio_route: > audio_route_update_mixer : +
12-20 15:07:31.376 3313-3477/? I/audio_route: > audio_route_update_mixer : changed(0) -
12-20 15:07:31.376 3313-3477/? I/audio_hw_primary: select_devices - 
12-20 15:07:31.376 3313-3477/? V/audio_hw_primary: start_output_stream-
12-20 15:07:31.405 3313-3477/? D/AudioFlinger: mixer(0xed883040) Spend too much time to write: delta 170(effect 0, stage 0)
12-20 15:07:31.423 31003-31003/? A/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
12-20 15:07:31.424 31003-31003/? A/DEBUG: Build fingerprint: 'samsung/herolteskt/herolteskt:7.0/NRD90M/G930SKSU1DQJ1:user/release-keys'
12-20 15:07:31.424 31003-31003/? A/DEBUG: Revision: '8'
12-20 15:07:31.424 31003-31003/? A/DEBUG: ABI: 'arm64'
12-20 15:07:31.424 31003-31003/? A/DEBUG: pid: 30870, tid: 30870, name: osyab.guitaroid  >>> net.gerosyab.guitaroid <<<
12-20 15:07:31.424 31003-31003/? A/DEBUG: signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x4
12-20 15:07:31.424 31003-31003/? A/DEBUG:     x0   00000074fb896620  x1   0000000000000000  x2   00000074fb896620  x3   0000007fd1c68f08
12-20 15:07:31.424 31003-31003/? A/DEBUG:     x4   0000000000000000  x5   0000000000000001  x6   0000000100000000  x7   0000000000000000
12-20 15:07:31.424 31003-31003/? A/DEBUG:     x8   0000000000000001  x9   0000000000000000  x10  0000000000430000  x11  0000000000000000
12-20 15:07:31.424 31003-31003/? A/DEBUG:     x12  000000000000018c  x13  0000000000000048  x14  0000007520d1d470  x15  76205267d1c3e4e7
12-20 15:07:31.424 31003-31003/? A/DEBUG:     x16  00000074fbcdde88  x17  00000074fbc1f00c  x18  0000000071666f10  x19  00000074fb896620
12-20 15:07:31.424 31003-31003/? A/DEBUG:     x20  0000007510d1ab68  x21  0000000000000000  x22  0000000000000000  x23  000000751b2258cc
12-20 15:07:31.424 31003-31003/? A/DEBUG:     x24  0000000000000014  x25  d77d57c4ab9dcb4c  x26  000000751c8c7a98  x27  d77d57c4ab9dcb4c
12-20 15:07:31.424 31003-31003/? A/DEBUG:     x28  0000007fd1c68f10  x29  0000007fd1c68ed0  x30  000000751c2b0494
12-20 15:07:31.425 31003-31003/? A/DEBUG:     sp   0000007fd1c68eb0  pc   00000074fbc1f030  pstate 0000000020000000
12-20 15:07:31.442 31003-31003/? A/DEBUG: backtrace:
12-20 15:07:31.442 31003-31003/? A/DEBUG:     #00 pc 0000000000046030  /data/app/net.gerosyab.guitaroid-2/lib/arm64/libmwengine.so (_ZN11SampleEvent9setSampleEP11AudioBuffer+36)
12-20 15:07:31.442 31003-31003/? A/DEBUG:     #01 pc 00000000000db490  /system/lib64/libart.so (art_quick_generic_jni_trampoline+144)
12-20 15:07:31.442 31003-31003/? A/DEBUG:     #02 pc 00000000000d2168  /system/lib64/libart.so (art_quick_invoke_static_stub+600)
12-20 15:07:31.442 31003-31003/? A/DEBUG:     #03 pc 00000000000dec20  /system/lib64/libart.so (_ZN3art9ArtMethod6InvokeEPNS_6ThreadEPjjPNS_6JValueEPKc+256)
12-20 15:07:31.442 31003-31003/? A/DEBUG:     #04 pc 0000000000291020  /system/lib64/libart.so (_ZN3art11interpreter34ArtInterpreterToCompiledCodeBridgeEPNS_6ThreadEPNS_9ArtMethodEPKNS_7DexFile8CodeItemEPNS_11ShadowFrameEPNS_6JValueE+312)
12-20 15:07:31.443 31003-31003/? A/DEBUG:     #05 pc 0000000000289fe0  /system/lib64/libart.so (_ZN3art11interpreter6DoCallILb0ELb0EEEbPNS_9ArtMethodEPNS_6ThreadERNS_11ShadowFrameEPKNS_11InstructionEtPNS_6JValueE+592)
12-20 15:07:31.443 31003-31003/? A/DEBUG:     #06 pc 000000000055d9cc  /system/lib64/libart.so (MterpInvokeStatic+356)
12-20 15:07:31.443 31003-31003/? A/DEBUG:     #07 pc 00000000000c4a14  /system/lib64/libart.so (ExecuteMterpImpl+14612)

I added more information to logcat. And I think I found the occuring point.

12-20 16:01:45.806 9054-9054/net.gerosyab.guitaroid D/MWENGINE: initing MWEngineActivity
12-20 16:01:45.816 9054-9054/net.gerosyab.guitaroid V/MWENGINE: JNI INITED OK
12-20 16:01:45.825 9054-9538/net.gerosyab.guitaroid D/MWENGINE: STARTING NATIVE AUDIO RENDER THREAD
12-20 16:01:45.826 9054-9538/net.gerosyab.guitaroid D/MWENGINE: STARTING NATIVE THREAD @ 48000 Hz using 240 samples per buffer
12-20 16:01:45.826 9054-9538/net.gerosyab.guitaroid V/MWENGINE: STARTING engine
12-20 16:01:45.837 9054-9054/net.gerosyab.guitaroid V/MWENGINE: WaveReader::Error not a valid WAVE file
12-20 16:01:45.838 9054-9054/net.gerosyab.guitaroid V/MWENGINE: WaveReader::Error not a valid WAVE file
12-20 16:01:45.841 9054-9054/net.gerosyab.guitaroid D/mwSampleEvent: SampleEvent Construnctor Entry1
12-20 16:01:45.841 9054-9054/net.gerosyab.guitaroid D/mwSampleEvent: SampleEvent Construnctor Entry3
12-20 16:01:45.841 9054-9054/net.gerosyab.guitaroid D/mwSampleEvent: SampleEvent.setSample() 1
12-20 16:01:45.842 9054-9054/net.gerosyab.guitaroid D/mwSampleEvent: SampleEvent.setSample() this : nl.igorski.lib.audio.mwengine.SampleEvent@327abf6
12-20 16:01:45.842 9054-9054/net.gerosyab.guitaroid D/mwSampleEvent: SampleEvent.setSample() sampleBuffer : null
12-20 16:01:45.842 9054-9054/net.gerosyab.guitaroid D/mwNDK: Java_nl_igorski_lib_audio_mwengine_MWEngineCoreJNI_SampleEvent_1setSample start
12-20 16:01:45.842 9054-9054/net.gerosyab.guitaroid D/mwNDK: 111
12-20 16:01:45.842 9054-9054/net.gerosyab.guitaroid D/mwNDK: 222
12-20 16:01:45.845 9054-9538/net.gerosyab.guitaroid V/MWENGINE: STARTED engine

Wav files are same as in the sample's asserts folder but don't know why the WaveReader says not a valid WAVE file.

Anyway the location is "Java_nl_igorski_lib_audio_mwengine_MWEngineCoreJNI_SampleEvent_1setSample()" in "java_interface_wrapper.cpp"

When setSample() method in SampleEvent.cpp is called, it crashed.

Could you give me any advice?

Oboe integration

Was wondering now that it's production ready if you were going to integrate it.

I have a couple demos I have compiling that is working with the stream and callbacks.

I wouldn't know how to get it in this project correctly at this point and time of my learning. :)

Build Project

hi guy,

I'm Nguyen, i enjoy the project very much. Howerver, i download it, and import, i get some errors about project when building project. There are images for project in Eclipse and Android Studio
image
image

I downloaded Android NDK.
Can you help me about this or guide me to step by step build project?
Thanks!

Automation Parameters

Hi,

I don't know if the current framework can handle it but having an automation framework that can use a table or linked list for key/value pairs that real-time adjust synth parameters or audio event parameters.

Have you daydreamed about this before in context of MWEngine?

Unit Tests - Running / Develop

Hey,

I use Windows for dev, is there any advice you can give for a setup? I am trying to figure out how to use Android Studio as the IDE with code completion/error checking and run a single test or the whole suite.

  • Do you just use a text editor and "run" in place?
  • How do you run 1 test at a time when you are doing TDD (mind you I do this but not as religion)?
  • I have tried to understand how AS works with NDK testing but it doesn't seem to jive with what you have going.

SampleEvent seems to play files not in correct speed

What I did:
final SampleEvent drumEvent = new SampleEvent( _sampler );
drumEvent.setSample( SampleManager.getSample( "2"));
//drumEvent.setPlaybackRate(0.9f);
drumEvent.setVolume(1f);
drumEvent.play();

The played tone is a little bit higher than it should be. When I set the playback rate to 0.9 it's almost perfect.
I tried resampling the wav file (44100 <-> 48k) but that did not help.

Tested on Sony Xperia Z3 Compact

Arpeggiator - How To

Hey!

I have been studying this code and cannot seem to understand how or what triggers the Arppegiator.

Simple setup;

       synth1.setArpeggiatorActive(true);
        synth1.getArpeggiator().setAmountOfSteps(16);
        synth1.getArpeggiator().setShiftForStep(0, 1);
        synth1.getArpeggiator().setShiftForStep(1, 1);
        synth1.getArpeggiator().setShiftForStep(2, 5);
        synth1.getArpeggiator().setShiftForStep(3, 1);
        synth1.getArpeggiator().setShiftForStep(4, 1);
        synth1.getArpeggiator().setShiftForStep(5, 7);
        synth1.getArpeggiator().setShiftForStep(6, 1);
        synth1.getArpeggiator().setShiftForStep(7, 1);
        synth1.getArpeggiator().setShiftForStep(8, 10);
        synth1.getArpeggiator().setShiftForStep(9, 1);
        synth1.getArpeggiator().setShiftForStep(10, 1);
        synth1.getArpeggiator().setShiftForStep(11, 6);
        synth1.getArpeggiator().setShiftForStep(12, 1);
        synth1.getArpeggiator().setShiftForStep(13, 1);
        synth1.getArpeggiator().setShiftForStep(14, 1);
        synth1.getArpeggiator().setShiftForStep(15, 1);

I get what it's doing but I can't get it to do it. :) I have sequenced 1 audio event for a synth for 8 steps in a 16 step grid for tests.

I also have the sequencer controller playing.

AudioChannel mixVolume issues

the mixVolume property of the AudioChannel should allow its level to be balanced against all other channels. The property however, seems to do nothing... (for now instrument volumes can be usedto control channel volume).

Tips for improving stability when playing audio in background app

Hello,

I'm working on an Android metronome app using SampleEvents and the SequencerController. It's working quite well when the Android app is in the foreground, but when the app goes to the background the stability of the audio stream suffers a bit. The tempo will vary a bit at times, and some notes get dropped. This gets much worse when performing CPU-intensive actions in another app, like scrolling around on in Google Maps for example.

I think I've noticed some improvements by doing two things so far:

  1. Increasing the buffer size, up to 24 times the value returned by getRecommendedBufferSize
  2. Using smaller audio samples

Are there any other things you can recommended to improve audio stability, especially when MWEngine is running in a background Android app?

Thank you!

Audio Driver for Windows

Hey,

I know you read the title and said, huh? :)

What I was wondering is if it's basically a process of writing a new driver that hooked into something like FMOD library to get this running on Windows.

I use multi-platform libraries for some apps and was curious if I could get this running on the desktop for testing. (UI is multi-platform)

It seems from looking through the source code, even with a new driver it's invasive to the framework? What I mean is you have flags for SL and AA Audio, those are kind of hard coded in the engine it seems?

Thanks

Custom c++ observer is not receiving notifications

When trying to use a custom observer in c++, no notification is received.

The problem seems to be in two places.

  1. It's not possible to override the observer functions handleNotification(int aNotificationType) and handleNotification(int aNotificationType, int aValue) because these are not declared as virtual in observer.h. When these functions later are called the parent functions will be invoked, the virtual declaration is needed to achieve late binding of these functions.

  2. The vector list of observers in notifier.cpp will never be filled. This line:
    std::vector<Observer*> observers = it->second;
    will create a copy of the observer vector, and subsequent calls to observers.push_back( aObserver ); will be executed on the copy and not the vector in the map. Calling push_back directly on it->second will work.

Ableton Link integration with the sequencer

Hi,

This is really just a question if you have thought about this implementation?

I am going to try it myself but I thought I would get your input first to see if there were any problems you see or even that you haven't thought about it. :) (either way)

Mike

Unable to control measure subdivision

aStepsPerBar parameter in updateMeasures method seem to has no effect.
Subdivision seems to be controlled by AudioEngine::beat_subdivision which is not modifiable from API.
Sequencer always notifies about 16 steps.

setTempo creates invalid boundaries if loop is not starting at buffer position 0

if a loop is running from start > 0 to end > start (set by setLoopRange()) and setTempo() is called I observed:

  1. buffer positions of audio events are scaled according to ratio (oldTempo/newTempo)
  2. min_buffer_position stays untouched (but should be scaled too?)
  3. max_buffer_position is samples_per_bar * amount_of_bars bout should be min_buffer_position + samples_per_bar * amount_of_bars

Maybe I'm not using it correctly. But changing handleTempoUpdate() to:
float ratio = tempo / aQueuedTempo;
....
min_buffer_position = min_buffer_position * ratio;
max_buffer_position = ( min_buffer_position + samples_per_bar * amount_of_bars ) - 1;

Helped me.

Feature request: add volume control to SampleEvent

I need to control volume of each (sample) event, to make accents. With current API I can achieve it with many samples with adjusted volume in buffers (memory overhead) or many instruments with different volumes (not flexible, code overhead).
I suggest to add volume control to all events, like in SynthEvent.

Use CMake to generate Makefiles

By moving the library Makefiles to CMake, it will be easier to integrate building of the native code within Android Studio (and relying on Gradle as the single build system, rather than having to manually execute shell scripts). CMake will also cater fine to those who work outside of AS.

Some inspiration can be found here

Synth Legato - Portamento

I was playing around today and realized we can set frequencies real-time and you also mentioned 'legato' in the code comments.

You would need a place on audio event for flags, since you need to specify which event IS legato.

This would also have to be mono synth as well.

So as with most of my other issues, I am just looking for some conversation and direction.

Bounced WAVs should be merged.

When bouncing the engine's audio output, as long as there is content to be generated, the engine will write a .WAV file at the length of the specified maximum buffer size. At the end of the operation this leaves us with a lot of split .WAV files on the device. These should be merged into a single file.

Loading wav files.

Hi,

I'm working on a small Android project, and this engine seems to fit my needs !

I've been playing with it and after some changes I was able to compile it.

Now I'm trying to load some wav files to simply loop / sequence. But I can't get it done somehow.
I couldn't load them from the assets or res or local filesystem of my phone.

Is there a more hands on example that I can follow, or can someone point me in the correct direction ?

Koert.

Sequencer accidentally stopped after engine stop and start again

setPlaying( false );

If stop the engine and dispose it in java (for example on activity stop), destructor of SequencerController will be called later with GC. So if we stop the activity and the open it again, next scenario became possible:

  1. Run audio engine
  2. Stop activity, stop and dispose audio engine
  3. Resume activity, init and start audio engine again
  4. Play sound
  5. SequencerController destructor called (for old object), but it affects global audio engine namespace and sound will be stopped

C++ Convention - 0 used as null pointer

Is this legacy in the code that you use 0 as nullptr?

I am coding convention OCD sometimes and I have read not using nullptr is bad form.

Here again, I am just getting into the deeper nuances of C++ now and I want to do things correct.

Stress Testing DSP

Hi,

I was curious if you have tried to break this on devices to see how many oscillators etc. you can have going.

This is more just an informative question.

If you haven't I guess I will, I have a Pixel and Samsung tablet that I will test on (and my other beta testers).

Failed to build example

I've installed NDK and SWIG, cloned master branch
Running build.sh gives me the following errors

jni/utilities/bufferutility.cpp:186:5: error: use of undeclared identifier
      'memset'; did you mean 'wmemset'?
    memset( out, 0, aBufferSize * sizeof( SAMPLE_TYPE )); // zero bits s...
    ^~~~~~
    wmemset
/Users/rostopira/android/sdk/ndk-bundle/sysroot/usr/include/wchar.h:159:10: note: 
      'wmemset' declared here
wchar_t* wmemset(wchar_t* __dst, wchar_t __wc, size_t __n);
         ^
jni/utilities/bufferutility.cpp:186:13: error: cannot initialize a parameter of
      type 'wchar_t *' with an lvalue of type 'double *'
    memset( out, 0, aBufferSize * sizeof( SAMPLE_TYPE )); // zero bits s...
            ^~~
/Users/rostopira/android/sdk/ndk-bundle/sysroot/usr/include/wchar.h:159:27: note: 
      passing argument to parameter '__dst' here
wchar_t* wmemset(wchar_t* __dst, wchar_t __wc, size_t __n);
                          ^
2 errors generated.
make: *** [obj/local/x86_64/objs/mwengine/utilities/bufferutility.o] Error 1

Is the MWEngine suitable for multitrack daw?

Hi,
I'm trying to implement a ordinary multitrack daw.

E.g i have 12 Tracks,
Each tracks have different time range with seconds
(track1: 0-45, track2: 10-30,..., track12: 120-150)

Can the MWengine play files with time manipulation?
thanks.

Position notification improvements

  1. When sequencer started, first notification will be about position 1. So, in demo app position changed from 1 to 15, and then from 0 to 15. If I need some events to sync with audio, notifications about 0 position at start simplifies client code.

  2. If I need to sync with audio with best precision, I need also position start offset in buffer. I've implemented this feature in my fork (songsterr@86ad204). We can talk about it. Now API is not so good, but can be improved in java part of lib.

AudioEngine.pause() causes native crash

This only happens on Cat S60. I call _engine.pause() when app goes into background.
Model: Cat S60
Android Version: 6.0.1

This also happens with the MWEngine Example App

********** Crash dump: **********
Build fingerprint: 'Cat/CatS60/CatS60:6.0.1/MMB29M/LTE_S0201121.0_S60_0.030.01:user/release-keys'
pid: 15359, tid: 15432, name: Thread-17525 >>> com.harthorst.compas <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xdeadbaad
Stack frame #00 pc 0000000000047548 /system/lib64/libc.so (dlfree+408)
Stack frame #1 pc 0000000000019568 /system/lib64/libc.so (free+20)
Stack frame #2 pc 0000000000041238 /data/app/com.harthorst.compas-2/lib/arm64/libmwengine.so (_ZN13DriverAdapter7destroyEv+36)
Stack frame #3 pc 0000000000042280 /data/app/com.harthorst.compas-2/lib/arm64/libmwengine.so (_ZN11AudioEngine5startEv+496)
Stack frame #4 pc 0000000000129ea8 /system/lib64/libart.so (art_quick_generic_jni_trampoline+152)
Stack frame #5 pc 0000000000120518 /system/lib64/libart.so (art_quick_invoke_static_stub+600)
Stack frame #6 pc 00000000001301c4 /system/lib64/libart.so (_ZN3art9ArtMethod6InvokeEPNS_6ThreadEPjjPNS_6JValueEPKc+344)
Stack frame #7 pc 00000000004d23f0 /system/lib64/libart.so (artInterpreterToCompiledCodeBridge+212)
Stack frame #8 pc 00000000002abb00 /system/lib64/libart.so (_ZN3art11interpreter6DoCallILb0ELb0EEEbPNS_9ArtMethodEPNS_6ThreadERNS_11ShadowFrameEPKNS_11InstructionEtPNS_6JValueE+480)
Stack frame #9 pc 00000000000dd548 /system/lib64/libart.so (ZN3art11interpreter15ExecuteGotoImplILb0ELb0EEENS_6JValueEPNS_6ThreadEPKNS_7DexFile8CodeItemERNS_11ShadowFrameES2+22200)
Stack frame #10 pc 0000000000289908 /system/lib64/libart.so (artInterpreterToInterpreterBridge+220)
Stack frame #11 pc 00000000002abb00 /system/lib64/libart.so (_ZN3art11interpreter6DoCallILb0ELb0EEEbPNS_9ArtMethodEPNS_6ThreadERNS_11ShadowFrameEPKNS_11InstructionEtPNS_6JValueE+480)
Stack frame #12 pc 00000000000dd548 /system/lib64/libart.so (ZN3art11interpreter15ExecuteGotoImplILb0ELb0EEENS_6JValueEPNS_6ThreadEPKNS_7DexFile8CodeItemERNS_11ShadowFrameES2+22200)
Stack frame #13 pc 0000000000289510 /system/lib64/libart.so (_ZN3art11interpreter30EnterInterpreterFromEntryPointEPNS_6ThreadEPKNS_7DexFile8CodeItemEPNS_11ShadowFrameE+96)
Stack frame #14 pc 000000000053ef00 /system/lib64/libart.so (artQuickToInterpreterBridge+632)
Stack frame #15 pc 0000000000129fe4 /system/lib64/libart.so (art_quick_to_interpreter_bridge+100)
Stack frame #16 pc 0000000000120264 /system/lib64/libart.so (art_quick_invoke_stub+580)
Stack frame #17 pc 000000000013011c /system/lib64/libart.so (_ZN3art9ArtMethod6InvokeEPNS_6ThreadEPjjPNS_6JValueEPKc+176)
Stack frame #18 pc 00000000004312e8 /system/lib64/libart.so (_ZN3art35InvokeVirtualOrInterfaceWithJValuesERKNS_33ScopedObjectAccessAlreadyRunnableEP8_jobjectP10_jmethodIDP6jvalue+460)
Stack frame #19 pc 000000000045f994 /system/lib64/libart.so (_ZN3art6Thread14CreateCallbackEPv+744)
Stack frame #20 pc 0000000000067784 /system/lib64/libc.so (_ZL15__pthread_startPv+52)
Stack frame #21 pc 000000000001c604 /system/lib64/libc.so (__start_thread+16)

NDK build version

Hi,

I was just curious what version of the NDK you are building this with?

Mike

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.