diff options
Diffstat (limited to 'md/writeup')
-rw-r--r-- | md/writeup/web_assembly_audio_with_fir_filter.md | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/md/writeup/web_assembly_audio_with_fir_filter.md b/md/writeup/web_assembly_audio_with_fir_filter.md new file mode 100644 index 0000000..ab23db9 --- /dev/null +++ b/md/writeup/web_assembly_audio_with_fir_filter.md @@ -0,0 +1,137 @@ +title: WebAssembly Audio +keywords:c,webassembly,js,SDL,FIR,WebAudio,FIR,DSP + +# Web assembly audio + +## Intro + +After learning how to calculate basic FIR filter, the best demo to play with is compiled to wasm with emcc. +It suppose to be compatible with all platforms that have modern browsers. This is combo of two posts + +[/writeup/calculate_fir_coefficients_with_c.md](/writeup/calculate_fir_coefficients_with_c.md) +and +[/writeup/web_assembly_sdl_example.md](/writeup/web_assembly_sdl_example.md) + +joined up filter calculations with SDL_Audio and compiled to wasm make things more interactive. + + +## Implementation + +### FIR filter + +FIR filter is done as its mentioned in [/writeup/calculate_fir_coefficients_with_c.md](/writeup/calculate_fir_coefficients_with_c.md) +Its compiled to web assembly without any modifications. + +### Browser main gui loop + +When write in C and trying to make compatible code for non-wasm platforms there is few things +that need to take in considerations. Browser have main gui thread and programms SDL event loop +is passed as callback, while running main loop just on pc is no issue. But this does +change logic how main loop is invocated to make it compatible between platforms +for emscripten main loop is passed as callback + +``` +emscripten_set_main_loop(main_tick, 25, 1); +``` + +in usual case its can be run as + +``` +while (quit = 0) { + main_tick(); +} +``` + +### Event handler + +Event handler in emscripten part are passing all events to SDL, and if there is text boxes they cannot be filled in, +as main loop is handling events. + +``` +//all events are handled and passed to this routine + while (SDL_PollEvent(&event) != 0) + { + + switch (event.type) + { + case SDL_QUIT: + { + quit = 1; + break; + } + case SDL_KEYDOWN: + { + } + } +``` + +### Audio buffer + +There is some differences in SDL_Audio for web, browser is playing last part of submitted data to buffer for ever, +so before stop playing sound, there is submitted "silence" to buffer to fix this issue. + +```c + if (audio_buf_position+len <(audio_rec_buffer_size)) { + memcpy( outsamples, audio_rec_buffer+audio_buf_position,len); + audio_buf_position += len; + } else { + //silence the playback + memset( outsamples, 0, len*sizeof(double)); + audio_buf_full = 1; + } + +} +``` + +## Demo + +Here is demo compiled to Web assembly and uploaded http://wasm.main.lv/wasmfir/index.html. + +Unfortunately as here is no https then better to run it locally and enable +chrome://flags/#unsafely-treat-insecure-origin-as-secure + +So far its not ideal interactive way, but things works. +Steps to make thing work are to press buttons +r(record) ,then q(apply filter to audio buffer), s(play back buffer) + +http://wasm.main.lv/wasmfir/index.html + +## Source + +Web interface: +http://git.main.lv/cgit.cgi/WasmAudio.git + +### Get source + +``` +git clone http://git.main.lv/cgit.cgi/WasmAudio.git/ +``` + +### Build Linux + +``` +cd Build +make +``` + +### Build Macos + +Open with XCode + +### Build Web assembly + +``` +cd Build +make emcc +``` + +## Testing + +## Links +[/writeup/calculate_fir_coefficients_with_c.md](/writeup/calculate_fir_coefficients_with_c.md) +[/writeup/web_assembly_sdl_example.md](/writeup/web_assembly_sdl_example.md) +[/writeup/dsp_lp_filter.md](/writeup/dsp_lp_filter.md) +[https://lazyfoo.net/tutorials/SDL/34_audio_recording/index.php](https://lazyfoo.net/tutorials/SDL/34_audio_recording/index.php) +[https://gist.github.com/armornick/3447121](https://gist.github.com/armornick/3447121) +[https://wiki.libsdl.org/SDL_AudioSpec](https://wiki.libsdl.org/SDL_AudioSpec) + |