@ozdemirburak/morse-code-translator 5.0.2 → 5.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- "use strict";const e={1:{A:"01",B:"1000",C:"1010",D:"100",E:"0",F:"0010",G:"110",H:"0000",I:"00",J:"0111",K:"101",L:"0100",M:"11",N:"10",O:"111",P:"0110",Q:"1101",R:"010",S:"000",T:"1",U:"001",V:"0001",W:"011",X:"1001",Y:"1011",Z:"1100"},2:{0:"11111",1:"01111",2:"00111",3:"00011",4:"00001",5:"00000",6:"10000",7:"11000",8:"11100",9:"11110"},3:{".":"010101",",":"110011","?":"001100","'":"011110","!":"101011","/":"10010","(":"10110",")":"101101","&":"01000",":":"111000",";":"101010","=":"10001","+":"01010","-":"100001",_:"001101",'"':"010010",$:"0001001","@":"011010","¿":"00101","¡":"110001"},4:{"Ã":"01101","Á":"01101","Å":"01101","À":"01101","Â":"01101","Ä":"0101","Ą":"0101","Æ":"0101","Ç":"10100","Ć":"10100","Ĉ":"10100","Č":"110","Ð":"00110","È":"01001","Ę":"00100","Ë":"00100","É":"00100","Ê":"10010","Ğ":"11010","Ĝ":"11010","Ĥ":"1111","İ":"01001","Ï":"10011","Ì":"01110","Ĵ":"01110","Ł":"01001","Ń":"11011","Ñ":"11011","Ó":"1110","Ò":"1110","Ö":"1110","Ô":"1110","Ø":"1110","Ś":"0001000","Ş":"01100","Ș":"1111","Š":"1111","Ŝ":"00010","ß":"000000","Þ":"01100","Ü":"0011","Ù":"0011","Ŭ":"0011","Ž":"11001","Ź":"110010","Ż":"11001"},5:{"А":"01","Б":"1000","В":"011","Г":"110","Д":"100","Е":"0","Ж":"0001","З":"1100","И":"00","Й":"0111","К":"101","Л":"0100","М":"11","Н":"10","О":"111","П":"0110","Р":"010","С":"000","Т":"1","У":"001","Ф":"0010","Х":"0000","Ц":"1010","Ч":"1110","Ш":"1111","Щ":"1101","Ъ":"11011","Ы":"1011","Ь":"1001","Э":"00100","Ю":"0011","Я":"0101","Ї":"01110","Є":"00100","І":"00","Ґ":"110"},6:{"Α":"01","Β":"1000","Γ":"110","Δ":"100","Ε":"0","Ζ":"1100","Η":"0000","Θ":"1010","Ι":"00","Κ":"101","Λ":"0100","Μ":"11","Ν":"10","Ξ":"1001","Ο":"111","Π":"0110","Ρ":"010","Σ":"000","Τ":"1","Υ":"1011","Φ":"0010","Χ":"1111","Ψ":"1101","Ω":"011"},7:{"א":"01","ב":"1000","ג":"110","ד":"100","ה":"111","ו":"0","ז":"1100","ח":"0000","ט":"001","י":"00","כ":"101","ל":"0100","מ":"11","נ":"10","ס":"1010","ע":"0111","פ":"0110","צ":"011","ק":"1101","ר":"010","ש":"000","ת":"1"},8:{"ا":"01","ب":"1000","ت":"1","ث":"1010","ج":"0111","ح":"0000","خ":"111","د":"100","ذ":"1100","ر":"010","ز":"1110","س":"000","ش":"1111","ص":"1001","ض":"0001","ط":"001","ظ":"1011","ع":"0101","غ":"110","ف":"0010","ق":"1101","ك":"101","ل":"0100","م":"11","ن":"10","ه":"00100","و":"011","ي":"00","ﺀ":"0"},9:{"ا":"01","ب":"1000","پ":"0110","ت":"1","ث":"1010","ج":"0111","چ":"1110","ح":"0000","خ":"1001","د":"100","ذ":"0001","ر":"010","ز":"1100","ژ":"110","س":"000","ش":"1111","ص":"0101","ض":"00100","ط":"001","ظ":"1011","ع":"111","غ":"0011","ف":"0010","ق":"111000","ک":"101","گ":"1101","ل":"0100","م":"11","ن":"10","و":"011","ه":"0","ی":"00"},10:{"ア":"11011","カ":"0100","サ":"10101","タ":"10","ナ":"010","ハ":"1000","マ":"1001","ヤ":"011","ラ":"000","ワ":"101","イ":"01","キ":"10100","シ":"11010","チ":"0010","ニ":"1010","ヒ":"11001","ミ":"00101","リ":"110","ヰ":"01001","ウ":"001","ク":"0001","ス":"11101","ツ":"0110","ヌ":"0000","フ":"1100","ム":"1","ユ":"10011","ル":"10110","ン":"01010","エ":"10111","ケ":"1011","セ":"01110","テ":"01011","ネ":"1101","ヘ":"0","メ":"10001","レ":"111","ヱ":"01100","オ":"01000","コ":"1111","ソ":"1110","ト":"00100","ノ":"0011","ホ":"100","モ":"10010","ヨ":"11","ロ":"0101","ヲ":"0111","゛":"00","゜":"00110","。":"010100","ー":"01101","、":"010101","(":"101101",")":"010010"},11:{"ㄱ":"0100","ㄴ":"0010","ㄷ":"1000","ㄹ":"0001","ㅁ":"11","ㅂ":"011","ㅅ":"110","ㅇ":"101","ㅈ":"0110","ㅊ":"1010","ㅋ":"1001","ㅌ":"1100","ㅍ":"111","ㅎ":"0111","ㅏ":"0","ㅑ":"00","ㅓ":"1","ㅕ":"000","ㅗ":"01","ㅛ":"10","ㅜ":"0000","ㅠ":"010","ㅡ":"100","ㅣ":"001"},12:{"ก":"110","ข":"1010","ค":"101","ง":"10110","จ":"10010","ฉ":"1111","ช":"1001","ซ":"1100","ญ":"0111","ด":"100","ต":"1","ถ":"10100","ท":"10011","น":"10","บ":"1000","ป":"0110","ผ":"1101","ฝ":"10101","พ":"01100","ฟ":"0010","ม":"11","ย":"1011","ร":"010","ล":"0100","ว":"011","ส":"000","ห":"0000","อ":"10001","ฮ":"11011","ฤ":"01011","ะ":"01000","า":"01","ิ":"00100","ี":"00","ึ":"00110","ื":"0011","ุ":"00101","ู":"1110","เ":"0","แ":"0101","ไ":"01001","โ":"111","ำ":"00010","่":"001","้":"0001","๊":"11000","๋":"01010","ั":"01101","็":"11100","์":"11001","ๆ":"10111","ฯ":"11010"}},t=t=>Object.assign(Object.assign({},e),{0:e[t.priority],1:Object.assign(Object.assign({},e[1]),{[t.separator]:t.space})}),n=(e,n)=>{const o={},r=t(e);for(const t in r){o[t]={};for(const n in r[t])o[t][n]=r[t][n].replace(/0/g,e.dot).replace(/1/g,e.dash)}return n||delete o[0],o},o=(e={})=>{var t,n,o;return Object.assign(Object.assign({},e),{dash:e.dash||"-",dot:e.dot||".",space:e.space||"/",separator:e.separator||" ",invalid:e.invalid||"#",priority:e.priority||1,wpm:e.wpm,unit:e.unit||.08,fwUnit:e.fwUnit||e.unit||.08,volume:e.volume||100,oscillator:Object.assign(Object.assign({},e.oscillator),{type:(null===(t=e.oscillator)||void 0===t?void 0:t.type)||"sine",frequency:(null===(n=e.oscillator)||void 0===n?void 0:n.frequency)||500,onended:(null===(o=e.oscillator)||void 0===o?void 0:o.onended)||null})})},r=(e,t)=>{let n,o=null,r=null,i=null,a=null;const[s,c]=((e,t,n=0)=>{const o=[];let{unit:r,fwUnit:i}=t,a=0;t.wpm&&(r=i=60/(50*t.wpm)),o.push([0,a]);const s=e=>{o.push([t.volume/100*1,n+a]),a+=e*r},c=e=>{o.push([0,n+a]),a+=e*r},l=e=>{o.push([0,n+a]),a+=e*i};for(let n=0,o=!1;n<=e.length;n++)e[n]===t.space?(l(7),o=!1):e[n]===t.dot?(o?c(1):o=!0,s(1)):e[n]===t.dash?(o?c(1):o=!0,s(3)):void 0!==e[n+1]&&e[n+1]!==t.space&&void 0!==e[n-1]&&e[n-1]!==t.space&&(l(3),o=!1);return[o,a]})(e,t);if(null===o&&"undefined"!=typeof window&&(o=window.AudioContext||window.webkitAudioContext,i=new o),null===r&&"undefined"!=typeof window&&(r=window.OfflineAudioContext||window.webkitOfflineAudioContext,a=new r(1,44100*c,44100)),!i||!a)throw new Error("Web Audio API is not supported in this browser");n=i.createBufferSource(),n.connect(i.destination);const l=a.createOscillator(),d=a.createGain();l.type=t.oscillator.type,l.frequency.value=t.oscillator.frequency,s.forEach((([e,t])=>d.gain.setValueAtTime(e,t))),l.connect(d),d.connect(a.destination),n.onended=t.oscillator.onended;const u=new Promise((e=>{l.start(0),a.startRendering(),a.oncomplete=t=>{n.buffer=t.renderedBuffer,e()}}));let p;const f=()=>{clearTimeout(p),p=0,n.stop(0)},w=async()=>{await u;const e=((e,t)=>{const n=new ArrayBuffer(44+2*t.length),o=new DataView(n),r=(e,t,n)=>{for(let o=0;o<n.length;o++)e.setUint8(t+o,n.charCodeAt(o))};return r(o,0,"RIFF"),o.setUint32(4,36+2*t.length,!0),r(o,8,"WAVE"),r(o,12,"fmt "),o.setUint32(16,16,!0),o.setUint16(20,1,!0),o.setUint16(22,1,!0),o.setUint32(24,e,!0),o.setUint32(28,4*e,!0),o.setUint16(32,2,!0),o.setUint16(34,16,!0),r(o,36,"data"),o.setUint32(40,2*t.length,!0),((e,t,n)=>{for(let o=0;o<n.length;o++,t+=2){const r=Math.max(-1,Math.min(1,n[o]));e.setInt16(t,r<0?32768*r:32767*r,!0)}})(o,44,t),o})(a.sampleRate,n.buffer.getChannelData(0));return new Blob([e],{type:"audio/wav"})},g=async()=>{const e=await w();return URL.createObjectURL(e)};return{play:async()=>{await u,n.start(i.currentTime),p=setTimeout((()=>{f()}),1e3*c)},stop:f,getWaveBlob:w,getWaveUrl:g,exportWave:async e=>{const t=await g(),n=document.createElement("a");n.href=t,n.target="_blank",n.download=e||"morse.wav",n.click()},context:i,oscillator:l,gainNode:d}};var i,a;i=globalThis,a=()=>{const e=(e,n)=>{const r=o(n),i=t(r);return[...e.replace(/\s+/g,r.separator).trim().toLocaleUpperCase()].map((function(e){for(const t in i)if(void 0!==i[t]&&void 0!==i[t][e])return i[t][e];return r.invalid})).join(r.separator).replace(/0/g,r.dot).replace(/1/g,r.dash)};return{characters:(e,t)=>n(o(e),t),decode:(e,t)=>{const r=o(t),i=(e=>{const t={},o=n(e,!0);for(const e in o)for(const n in o[e])void 0===t[o[e][n]]&&(t[o[e][n]]=n);return t})(r);return e.replace(/\s+/g,r.separator).trim().split(r.separator).map((function(e){return void 0!==i[e]?i[e]:r.invalid})).join("")},encode:e,audio:(t,n,i)=>{const a=i||e(t,n),s=o(n);return r(a,s)}}},"object"==typeof exports?module.exports=a():"function"==typeof define&&define.amd?define(a):void 0!==i&&(i["morse-code-translator"]=a());
1
+ "use strict";const e={1:{A:"01",B:"1000",C:"1010",D:"100",E:"0",F:"0010",G:"110",H:"0000",I:"00",J:"0111",K:"101",L:"0100",M:"11",N:"10",O:"111",P:"0110",Q:"1101",R:"010",S:"000",T:"1",U:"001",V:"0001",W:"011",X:"1001",Y:"1011",Z:"1100"},2:{0:"11111",1:"01111",2:"00111",3:"00011",4:"00001",5:"00000",6:"10000",7:"11000",8:"11100",9:"11110"},3:{".":"010101",",":"110011","?":"001100","'":"011110","!":"101011","/":"10010","(":"10110",")":"101101","&":"01000",":":"111000",";":"101010","=":"10001","+":"01010","-":"100001",_:"001101",'"':"010010",$:"0001001","@":"011010","¿":"00101","¡":"110001"},4:{"Ã":"01101","Á":"01101","Å":"01101","À":"01101","Â":"01101","Ä":"0101","Ą":"0101","Æ":"0101","Ç":"10100","Ć":"10100","Ĉ":"10100","Č":"110","Ð":"00110","È":"01001","Ę":"00100","Ë":"00100","É":"00100","Ê":"10010","Ğ":"11010","Ĝ":"11010","Ĥ":"1111","İ":"01001","Ï":"10011","Ì":"01110","Ĵ":"01110","Ł":"01001","Ń":"11011","Ñ":"11011","Ó":"1110","Ò":"1110","Ö":"1110","Ô":"1110","Ø":"1110","Ś":"0001000","Ş":"01100","Ș":"1111","Š":"1111","Ŝ":"00010","ß":"000000","Þ":"01100","Ü":"0011","Ù":"0011","Ŭ":"0011","Ž":"11001","Ź":"110010","Ż":"11001"},5:{"А":"01","Б":"1000","В":"011","Г":"110","Д":"100","Е":"0","Ж":"0001","З":"1100","И":"00","Й":"0111","К":"101","Л":"0100","М":"11","Н":"10","О":"111","П":"0110","Р":"010","С":"000","Т":"1","У":"001","Ф":"0010","Х":"0000","Ц":"1010","Ч":"1110","Ш":"1111","Щ":"1101","Ъ":"11011","Ы":"1011","Ь":"1001","Э":"00100","Ю":"0011","Я":"0101","Ї":"01110","Є":"00100","І":"00","Ґ":"110"},6:{"Α":"01","Β":"1000","Γ":"110","Δ":"100","Ε":"0","Ζ":"1100","Η":"0000","Θ":"1010","Ι":"00","Κ":"101","Λ":"0100","Μ":"11","Ν":"10","Ξ":"1001","Ο":"111","Π":"0110","Ρ":"010","Σ":"000","Τ":"1","Υ":"1011","Φ":"0010","Χ":"1111","Ψ":"1101","Ω":"011"},7:{"א":"01","ב":"1000","ג":"110","ד":"100","ה":"111","ו":"0","ז":"1100","ח":"0000","ט":"001","י":"00","כ":"101","ל":"0100","מ":"11","נ":"10","ס":"1010","ע":"0111","פ":"0110","צ":"011","ק":"1101","ר":"010","ש":"000","ת":"1"},8:{"ا":"01","ب":"1000","ت":"1","ث":"1010","ج":"0111","ح":"0000","خ":"111","د":"100","ذ":"1100","ر":"010","ز":"1110","س":"000","ش":"1111","ص":"1001","ض":"0001","ط":"001","ظ":"1011","ع":"0101","غ":"110","ف":"0010","ق":"1101","ك":"101","ل":"0100","م":"11","ن":"10","ه":"00100","و":"011","ي":"00","ﺀ":"0"},9:{"ا":"01","ب":"1000","پ":"0110","ت":"1","ث":"1010","ج":"0111","چ":"1110","ح":"0000","خ":"1001","د":"100","ذ":"0001","ر":"010","ز":"1100","ژ":"110","س":"000","ش":"1111","ص":"0101","ض":"00100","ط":"001","ظ":"1011","ع":"111","غ":"0011","ف":"0010","ق":"111000","ک":"101","گ":"1101","ل":"0100","م":"11","ن":"10","و":"011","ه":"0","ی":"00"},10:{"ア":"11011","カ":"0100","サ":"10101","タ":"10","ナ":"010","ハ":"1000","マ":"1001","ヤ":"011","ラ":"000","ワ":"101","イ":"01","キ":"10100","シ":"11010","チ":"0010","ニ":"1010","ヒ":"11001","ミ":"00101","リ":"110","ヰ":"01001","ウ":"001","ク":"0001","ス":"11101","ツ":"0110","ヌ":"0000","フ":"1100","ム":"1","ユ":"10011","ル":"10110","ン":"01010","エ":"10111","ケ":"1011","セ":"01110","テ":"01011","ネ":"1101","ヘ":"0","メ":"10001","レ":"111","ヱ":"01100","オ":"01000","コ":"1111","ソ":"1110","ト":"00100","ノ":"0011","ホ":"100","モ":"10010","ヨ":"11","ロ":"0101","ヲ":"0111","゛":"00","゜":"00110","。":"010100","ー":"01101","、":"010101","(":"101101",")":"010010"},11:{"ㄱ":"0100","ㄴ":"0010","ㄷ":"1000","ㄹ":"0001","ㅁ":"11","ㅂ":"011","ㅅ":"110","ㅇ":"101","ㅈ":"0110","ㅊ":"1010","ㅋ":"1001","ㅌ":"1100","ㅍ":"111","ㅎ":"0111","ㅏ":"0","ㅑ":"00","ㅓ":"1","ㅕ":"000","ㅗ":"01","ㅛ":"10","ㅜ":"0000","ㅠ":"010","ㅡ":"100","ㅣ":"001"},12:{"ก":"110","ข":"1010","ค":"101","ง":"10110","จ":"10010","ฉ":"1111","ช":"1001","ซ":"1100","ญ":"0111","ด":"100","ต":"1","ถ":"10100","ท":"10011","น":"10","บ":"1000","ป":"0110","ผ":"1101","ฝ":"10101","พ":"01100","ฟ":"0010","ม":"11","ย":"1011","ร":"010","ล":"0100","ว":"011","ส":"000","ห":"0000","อ":"10001","ฮ":"11011","ฤ":"01011","ะ":"01000","า":"01","ิ":"00100","ี":"00","ึ":"00110","ื":"0011","ุ":"00101","ู":"1110","เ":"0","แ":"0101","ไ":"01001","โ":"111","ำ":"00010","่":"001","้":"0001","๊":"11000","๋":"01010","ั":"01101","็":"11100","์":"11001","ๆ":"10111","ฯ":"11010"}},t=t=>Object.assign(Object.assign({},e),{0:e[t.priority],1:Object.assign(Object.assign({},e[1]),{[t.separator]:t.space})}),n=(e,n)=>{const o={},r=t(e);for(const t in r){o[t]={};for(const n in r[t])o[t][n]=r[t][n].replace(/0/g,e.dot).replace(/1/g,e.dash)}return n||delete o[0],o},o=(e={})=>{var t,n,o;return Object.assign(Object.assign({},e),{dash:e.dash||"-",dot:e.dot||".",space:e.space||"/",separator:e.separator||" ",invalid:e.invalid||"#",priority:e.priority||1,wpm:e.wpm,unit:e.unit||.08,fwUnit:e.fwUnit||e.unit||.08,volume:e.volume||100,oscillator:Object.assign(Object.assign({},e.oscillator),{type:(null===(t=e.oscillator)||void 0===t?void 0:t.type)||"sine",frequency:(null===(n=e.oscillator)||void 0===n?void 0:n.frequency)||500,onended:(null===(o=e.oscillator)||void 0===o?void 0:o.onended)||null})})},r=(e,t)=>{let n=window.AudioContext||window.webkitAudioContext,o=window.OfflineAudioContext||window.webkitOfflineAudioContext;if(!n||!o)throw new Error("Web Audio API is not supported in this browser");const r=new n,[a,i]=((e,t,n=0)=>{const o=[];let{unit:r,fwUnit:a}=t,i=0;t.wpm&&(r=a=60/(50*t.wpm)),o.push([0,i]);const s=e=>{o.push([t.volume/100*1,n+i]),i+=e*r},c=e=>{o.push([0,n+i]),i+=e*r},l=e=>{o.push([0,n+i]),i+=e*a};for(let n=0,o=!1;n<=e.length;n++)e[n]===t.space?(l(7),o=!1):e[n]===t.dot?(o?c(1):o=!0,s(1)):e[n]===t.dash?(o?c(1):o=!0,s(3)):void 0!==e[n+1]&&e[n+1]!==t.space&&void 0!==e[n-1]&&e[n-1]!==t.space&&(l(3),o=!1);return[o,i]})(e,t),s=new o(1,44100*i,44100),c=s.createOscillator(),l=s.createGain();let d;c.type=t.oscillator.type,c.frequency.value=t.oscillator.frequency,a.forEach((([e,t])=>l.gain.setValueAtTime(e,t))),c.connect(l),l.connect(s.destination);const u=new Promise(((e,n)=>{c.start(0),s.startRendering(),s.oncomplete=o=>{try{d=r.createBufferSource(),d.buffer=o.renderedBuffer,d.connect(r.destination),d.onended=t.oscillator.onended,e()}catch(e){n(e)}},s.onerror=e=>{n(e)}}));let p;const f=()=>{clearTimeout(p),d&&d.stop(0)},w=async()=>{await u;const e=((e,t)=>{const n=new ArrayBuffer(44+2*t.length),o=new DataView(n),r=(e,t,n)=>{for(let o=0;o<n.length;o++)e.setUint8(t+o,n.charCodeAt(o))};return r(o,0,"RIFF"),o.setUint32(4,36+2*t.length,!0),r(o,8,"WAVE"),r(o,12,"fmt "),o.setUint32(16,16,!0),o.setUint16(20,1,!0),o.setUint16(22,1,!0),o.setUint32(24,e,!0),o.setUint32(28,4*e,!0),o.setUint16(32,2,!0),o.setUint16(34,16,!0),r(o,36,"data"),o.setUint32(40,2*t.length,!0),((e,t,n)=>{for(let o=0;o<n.length;o++,t+=2){const r=Math.max(-1,Math.min(1,n[o]));e.setInt16(t,r<0?32768*r:32767*r,!0)}})(o,44,t),o})(s.sampleRate,d.buffer.getChannelData(0));return new Blob([e],{type:"audio/wav"})},g=async()=>{const e=await w();return URL.createObjectURL(e)};return{play:async()=>{await u,"suspended"===r.state&&await r.resume(),d.start(r.currentTime),p=window.setTimeout((()=>{f()}),1e3*i)},stop:f,getWaveBlob:w,getWaveUrl:g,exportWave:async e=>{const t=await g(),n=document.createElement("a");n.href=t,n.target="_blank",n.download=e||"morse.wav",n.click()},context:r,oscillator:c,gainNode:l}};var a,i;a=globalThis,i=()=>{const e=(e,n)=>{const r=o(n),a=t(r);return[...e.replace(/\s+/g,r.separator).trim().toLocaleUpperCase()].map((function(e){for(const t in a)if(void 0!==a[t]&&void 0!==a[t][e])return a[t][e];return r.invalid})).join(r.separator).replace(/0/g,r.dot).replace(/1/g,r.dash)};return{characters:(e,t)=>n(o(e),t),decode:(e,t)=>{const r=o(t),a=(e=>{const t={},o=n(e,!0);for(const e in o)for(const n in o[e])void 0===t[o[e][n]]&&(t[o[e][n]]=n);return t})(r);return e.replace(/\s+/g,r.separator).trim().split(r.separator).map((function(e){return void 0!==a[e]?a[e]:r.invalid})).join("")},encode:e,audio:(t,n,a)=>{const i=a||e(t,n),s=o(n);return r(i,s)}}},"object"==typeof exports?module.exports=i():"function"==typeof define&&define.amd?define(i):void 0!==a&&(a["morse-code-translator"]=i());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ozdemirburak/morse-code-translator",
3
- "version": "5.0.2",
3
+ "version": "5.0.3",
4
4
  "description": "Morse code translator helps you convert text to Morse code and vice versa, with the option to play Morse code audio.",
5
5
  "keywords": [
6
6
  "morse",
package/src/audio.ts CHANGED
@@ -94,37 +94,16 @@ const encodeWAV = (sampleRate: number, samples: Float32Array) => {
94
94
  };
95
95
 
96
96
  const audio = (morse: string, options: Options) => {
97
- let AudioContext: {
98
- new(contextOptions?: AudioContextOptions): AudioContext;
99
- prototype: AudioContext;
100
- } = null;
101
- let OfflineAudioContext: {
102
- new(contextOptions: OfflineAudioContextOptions): OfflineAudioContext;
103
- new(numberOfChannels: number, length: number, sampleRate: number): OfflineAudioContext;
104
- prototype: OfflineAudioContext;
105
- } = null;
106
- let context: AudioContext = null;
107
- let offlineContext: OfflineAudioContext = null;
108
- let source: AudioBufferSourceNode;
109
-
110
- const [gainValues, totalTime] = getGainTimings(morse, options);
111
-
112
- if (AudioContext === null && typeof window !== 'undefined') {
113
- AudioContext = window.AudioContext || (window as any).webkitAudioContext;
114
- context = new AudioContext();
115
- }
116
-
117
- if (OfflineAudioContext === null && typeof window !== 'undefined') {
118
- OfflineAudioContext = window.OfflineAudioContext || (window as any).webkitOfflineAudioContext;
119
- offlineContext = new OfflineAudioContext(1, 44100 * totalTime, 44100);
120
- }
97
+ let AudioContextClass = window.AudioContext || (window as any).webkitAudioContext;
98
+ let OfflineAudioContextClass = window.OfflineAudioContext || (window as any).webkitOfflineAudioContext;
121
99
 
122
- if (!context || !offlineContext) {
100
+ if (!AudioContextClass || !OfflineAudioContextClass) {
123
101
  throw new Error('Web Audio API is not supported in this browser');
124
102
  }
125
103
 
126
- source = context.createBufferSource();
127
- source.connect(context.destination);
104
+ const context = new AudioContextClass();
105
+ const [gainValues, totalTime] = getGainTimings(morse, options);
106
+ const offlineContext = new OfflineAudioContextClass(1, 44100 * totalTime, 44100);
128
107
 
129
108
  const oscillator = offlineContext.createOscillator();
130
109
  const gainNode = offlineContext.createGain();
@@ -136,15 +115,26 @@ const audio = (morse: string, options: Options) => {
136
115
 
137
116
  oscillator.connect(gainNode);
138
117
  gainNode.connect(offlineContext.destination);
139
- source.onended = options.oscillator.onended;
140
118
 
141
- // Inspired by: http://joesul.li/van/tale-of-no-clocks/
142
- const render = new Promise<void>(resolve => {
119
+ let source: AudioBufferSourceNode;
120
+
121
+ // Render the audio buffer
122
+ const render = new Promise<void>((resolve, reject) => {
143
123
  oscillator.start(0);
144
124
  offlineContext.startRendering();
145
125
  offlineContext.oncomplete = (e) => {
146
- source.buffer = e.renderedBuffer;
147
- resolve();
126
+ try {
127
+ source = context.createBufferSource();
128
+ source.buffer = e.renderedBuffer;
129
+ source.connect(context.destination);
130
+ source.onended = options.oscillator.onended;
131
+ resolve();
132
+ } catch (err) {
133
+ reject(err);
134
+ }
135
+ };
136
+ offlineContext.onerror = (err) => {
137
+ reject(err);
148
138
  };
149
139
  });
150
140
 
@@ -152,20 +142,24 @@ const audio = (morse: string, options: Options) => {
152
142
 
153
143
  const play = async () => {
154
144
  await render;
145
+ if (context.state === 'suspended') {
146
+ await context.resume();
147
+ }
155
148
  source.start(context.currentTime);
156
- timeout = setTimeout(() => { stop() }, totalTime * 1000);
149
+ timeout = window.setTimeout(() => { stop(); }, totalTime * 1000);
157
150
  };
158
151
 
159
152
  const stop = () => {
160
153
  clearTimeout(timeout);
161
- timeout = 0;
162
- source.stop(0);
154
+ if (source) {
155
+ source.stop(0);
156
+ }
163
157
  };
164
158
 
165
159
  const getWaveBlob = async () => {
166
160
  await render;
167
161
  const waveData = encodeWAV(offlineContext.sampleRate, source.buffer.getChannelData(0));
168
- return new Blob([waveData], { 'type': 'audio/wav' });
162
+ return new Blob([waveData], { type: 'audio/wav' });
169
163
  };
170
164
 
171
165
  const getWaveUrl = async () => {
@@ -173,7 +167,7 @@ const audio = (morse: string, options: Options) => {
173
167
  return URL.createObjectURL(audioBlob);
174
168
  };
175
169
 
176
- const exportWave = async (filename) => {
170
+ const exportWave = async (filename: string) => {
177
171
  const waveUrl = await getWaveUrl();
178
172
  const anchor = document.createElement('a');
179
173
  anchor.href = waveUrl;
package/src/index.js CHANGED
@@ -224,25 +224,14 @@ const encodeWAV = (sampleRate, samples) => {
224
224
  return view;
225
225
  };
226
226
  const audio = (morse, options) => {
227
- let AudioContext = null;
228
- let OfflineAudioContext = null;
229
- let context = null;
230
- let offlineContext = null;
231
- let source;
232
- const [gainValues, totalTime] = getGainTimings(morse, options);
233
- if (AudioContext === null && typeof window !== 'undefined') {
234
- AudioContext = window.AudioContext || window.webkitAudioContext;
235
- context = new AudioContext();
236
- }
237
- if (OfflineAudioContext === null && typeof window !== 'undefined') {
238
- OfflineAudioContext = window.OfflineAudioContext || window.webkitOfflineAudioContext;
239
- offlineContext = new OfflineAudioContext(1, 44100 * totalTime, 44100);
240
- }
241
- if (!context || !offlineContext) {
227
+ let AudioContextClass = window.AudioContext || window.webkitAudioContext;
228
+ let OfflineAudioContextClass = window.OfflineAudioContext || window.webkitOfflineAudioContext;
229
+ if (!AudioContextClass || !OfflineAudioContextClass) {
242
230
  throw new Error('Web Audio API is not supported in this browser');
243
231
  }
244
- source = context.createBufferSource();
245
- source.connect(context.destination);
232
+ const context = new AudioContextClass();
233
+ const [gainValues, totalTime] = getGainTimings(morse, options);
234
+ const offlineContext = new OfflineAudioContextClass(1, 44100 * totalTime, 44100);
246
235
  const oscillator = offlineContext.createOscillator();
247
236
  const gainNode = offlineContext.createGain();
248
237
  oscillator.type = options.oscillator.type;
@@ -250,31 +239,46 @@ const audio = (morse, options) => {
250
239
  gainValues.forEach(([value, time]) => gainNode.gain.setValueAtTime(value, time));
251
240
  oscillator.connect(gainNode);
252
241
  gainNode.connect(offlineContext.destination);
253
- source.onended = options.oscillator.onended;
254
- // Inspired by: http://joesul.li/van/tale-of-no-clocks/
255
- const render = new Promise(resolve => {
242
+ let source;
243
+ // Render the audio buffer
244
+ const render = new Promise((resolve, reject) => {
256
245
  oscillator.start(0);
257
246
  offlineContext.startRendering();
258
247
  offlineContext.oncomplete = (e) => {
259
- source.buffer = e.renderedBuffer;
260
- resolve();
248
+ try {
249
+ source = context.createBufferSource();
250
+ source.buffer = e.renderedBuffer;
251
+ source.connect(context.destination);
252
+ source.onended = options.oscillator.onended;
253
+ resolve();
254
+ }
255
+ catch (err) {
256
+ reject(err);
257
+ }
258
+ };
259
+ offlineContext.onerror = (err) => {
260
+ reject(err);
261
261
  };
262
262
  });
263
263
  let timeout;
264
264
  const play = async () => {
265
265
  await render;
266
+ if (context.state === 'suspended') {
267
+ await context.resume();
268
+ }
266
269
  source.start(context.currentTime);
267
- timeout = setTimeout(() => { stop(); }, totalTime * 1000);
270
+ timeout = window.setTimeout(() => { stop(); }, totalTime * 1000);
268
271
  };
269
272
  const stop = () => {
270
273
  clearTimeout(timeout);
271
- timeout = 0;
272
- source.stop(0);
274
+ if (source) {
275
+ source.stop(0);
276
+ }
273
277
  };
274
278
  const getWaveBlob = async () => {
275
279
  await render;
276
280
  const waveData = encodeWAV(offlineContext.sampleRate, source.buffer.getChannelData(0));
277
- return new Blob([waveData], { 'type': 'audio/wav' });
281
+ return new Blob([waveData], { type: 'audio/wav' });
278
282
  };
279
283
  const getWaveUrl = async () => {
280
284
  const audioBlob = await getWaveBlob();