diff --git a/examples/helpers.js b/examples/helpers.js index 03b3a85..98cc5c6 100644 --- a/examples/helpers.js +++ b/examples/helpers.js @@ -145,7 +145,15 @@ function loadRemote(url, dst, size_mb, cbProgress, cbReady, cbCancel, cbPrint) { var db = event.target.result; var tx = db.transaction(['models'], 'readwrite'); var os = tx.objectStore('models'); - var rq = os.put(data, url); + + var rq = null; + try { + var rq = os.put(data, url); + } catch (e) { + cbPrint('loadRemote: failed to store "' + url + '" in the IndexedDB: \n' + e); + cbCancel(); + return; + } rq.onsuccess = function (event) { cbPrint('loadRemote: "' + url + '" stored in the IndexedDB'); @@ -180,7 +188,6 @@ function loadRemote(url, dst, size_mb, cbProgress, cbReady, cbCancel, cbPrint) { rq.onabort = function (event) { cbPrint('loadRemote: failed to open IndexedDB: abort'); - + cbCancel(); }; } - diff --git a/examples/whisper.wasm/CMakeLists.txt b/examples/whisper.wasm/CMakeLists.txt index d598dd6..75e5a8d 100644 --- a/examples/whisper.wasm/CMakeLists.txt +++ b/examples/whisper.wasm/CMakeLists.txt @@ -31,7 +31,7 @@ endif() set_target_properties(${TARGET} PROPERTIES LINK_FLAGS " \ --bind \ -s USE_PTHREADS=1 \ - -s PTHREAD_POOL_SIZE=8 \ + -s PTHREAD_POOL_SIZE_STRICT=0 \ -s INITIAL_MEMORY=2000MB \ -s TOTAL_MEMORY=2000MB \ -s FORCE_FILESYSTEM=1 \ diff --git a/examples/whisper.wasm/emscripten.cpp b/examples/whisper.wasm/emscripten.cpp index f92d814..db1ff78 100644 --- a/examples/whisper.wasm/emscripten.cpp +++ b/examples/whisper.wasm/emscripten.cpp @@ -10,6 +10,12 @@ std::thread g_worker; std::vector g_contexts(4, nullptr); +static inline int mpow2(int n) { + int p = 1; + while (p <= n) p *= 2; + return p/2; +} + EMSCRIPTEN_BINDINGS(whisper) { emscripten::function("init", emscripten::optional_override([](const std::string & path_model) { if (g_worker.joinable()) { @@ -43,7 +49,7 @@ EMSCRIPTEN_BINDINGS(whisper) { } })); - emscripten::function("full_default", emscripten::optional_override([](size_t index, const emscripten::val & audio, const std::string & lang, bool translate) { + emscripten::function("full_default", emscripten::optional_override([](size_t index, const emscripten::val & audio, const std::string & lang, int nthreads, bool translate) { if (g_worker.joinable()) { g_worker.join(); } @@ -66,7 +72,7 @@ EMSCRIPTEN_BINDINGS(whisper) { params.print_special = false; params.translate = translate; params.language = whisper_is_multilingual(g_contexts[index]) ? lang.c_str() : "en"; - params.n_threads = std::min(8, (int) std::thread::hardware_concurrency()); + params.n_threads = std::min(nthreads, std::min(16, mpow2(std::thread::hardware_concurrency()))); params.offset_ms = 0; std::vector pcmf32; diff --git a/examples/whisper.wasm/index-tmpl.html b/examples/whisper.wasm/index-tmpl.html index 34a2a96..d399beb 100644 --- a/examples/whisper.wasm/index-tmpl.html +++ b/examples/whisper.wasm/index-tmpl.html @@ -43,7 +43,7 @@ Important: @@ -174,6 +174,12 @@ + + + Threads: + + 8 + @@ -281,6 +287,8 @@ document.getElementById('model-whisper-status').innerHTML = 'loaded "' + model_whisper + '"!'; printTextarea('storeFS: stored model: ' + fname + ' size: ' + buf.length); + + document.getElementById('model').innerHTML = 'Model fetched: ' + model_whisper; } function loadFile(event, fname) { @@ -384,6 +392,7 @@ cbCancel = function() { var el; + el = document.getElementById('fetch-whisper-tiny-en' ); if (el) el.style.display = 'inline-block'; el = document.getElementById('fetch-whisper-base-en' ); if (el) el.style.display = 'inline-block'; el = document.getElementById('fetch-whisper-small-en'); if (el) el.style.display = 'inline-block'; @@ -391,7 +400,13 @@ el = document.getElementById('fetch-whisper-base' ); if (el) el.style.display = 'inline-block'; el = document.getElementById('fetch-whisper-small' ); if (el) el.style.display = 'inline-block'; - el = document.getElementById('fetch-whisper-large-q4_0'); if (el) el.style.display = 'inline-block'; + el = document.getElementById('fetch-whisper-base-en-q4_0' ); if (el) el.style.display = 'inline-block'; + el = document.getElementById('fetch-whisper-base-q4_0' ); if (el) el.style.display = 'inline-block'; + el = document.getElementById('fetch-whisper-small-en-q4_0' ); if (el) el.style.display = 'inline-block'; + el = document.getElementById('fetch-whisper-small-q4_0' ); if (el) el.style.display = 'inline-block'; + el = document.getElementById('fetch-whisper-medium-en-q4_0'); if (el) el.style.display = 'inline-block'; + el = document.getElementById('fetch-whisper-medium-q4_0' ); if (el) el.style.display = 'inline-block'; + el = document.getElementById('fetch-whisper-large-q4_0' ); if (el) el.style.display = 'inline-block'; el = document.getElementById('whisper-file' ); if (el) el.style.display = 'inline-block'; el = document.getElementById('model-whisper-status' ); if (el) el.innerHTML = ''; @@ -405,6 +420,7 @@ // const kMaxAudio_s = 30*60; + const kMaxRecording_s = 2*60; const kSampleRate = 16000; window.AudioContext = window.AudioContext || window.webkitAudioContext; @@ -473,7 +489,7 @@ doRecording = false; } - // record up to kMaxAudio_s seconds of audio from the microphone + // record up to kMaxRecording_s seconds of audio from the microphone // check if doRecording is false every 1000 ms and stop recording if so // update progress information function startRecording() { @@ -529,9 +545,9 @@ printTextarea('js: audio recorded, size: ' + audio.length); // truncate to first 30 seconds - if (audio.length > kMaxAudio_s*kSampleRate) { - audio = audio.slice(0, kMaxAudio_s*kSampleRate); - printTextarea('js: truncated audio to first ' + kMaxAudio_s + ' seconds'); + if (audio.length > kMaxRecording_s*kSampleRate) { + audio = audio.slice(0, kMaxRecording_s*kSampleRate); + printTextarea('js: truncated audio to first ' + kMaxRecording_s + ' seconds'); } setAudio(audio); }); @@ -559,24 +575,31 @@ }); } - document.getElementById('progress-bar').style.width = (100*(Date.now() - startTime)/1000/kMaxAudio_s) + '%'; - document.getElementById('progress-text').innerHTML = (100*(Date.now() - startTime)/1000/kMaxAudio_s).toFixed(0) + '%'; + document.getElementById('progress-bar').style.width = (100*(Date.now() - startTime)/1000/kMaxRecording_s) + '%'; + document.getElementById('progress-text').innerHTML = (100*(Date.now() - startTime)/1000/kMaxRecording_s).toFixed(0) + '%'; }, 1000); printTextarea('js: recording ...'); setTimeout(function() { if (doRecording) { - printTextarea('js: recording stopped after ' + kMaxAudio_s + ' seconds'); + printTextarea('js: recording stopped after ' + kMaxRecording_s + ' seconds'); stopRecording(); } - }, kMaxAudio_s*1000); + }, kMaxRecording_s*1000); } // // transcribe // + var nthreads = 8; + + function changeThreads(value) { + nthreads = value; + document.getElementById('threads-value').innerHTML = nthreads; + } + function onProcess(translate) { if (!instance) { instance = Module.init('whisper.bin'); @@ -603,7 +626,7 @@ printTextarea(''); setTimeout(function() { - var ret = Module.full_default(instance, audio, document.getElementById('language').value, translate); + var ret = Module.full_default(instance, audio, document.getElementById('language').value, nthreads, translate); console.log('js: full_default returned: ' + ret); if (ret) { printTextarea("js: whisper returned: " + ret);