SlideShare une entreprise Scribd logo
1  sur  12
JS: Audio Data Processing
Ingvar Stepanyan
Web Developer, MSP
@RReverser (http://rreverser.com/)
Native implementations:
[Mozilla] Audio Data API (low-level processing)
[WebKit] Web Audio API (+ some high-level sugar)
[Flash] Sound API (low-level processing)
Unifying wrappers:
dynamicaudio.js (Audio Data API + Flash)
XAudioJS (Audio Data API + Web Audio API + Flash)
sink.js & co. (Audio Data API + Web Audio API)
Current status
Low
Level
<audio id=“audio” ... />
....................................
var audio = document.getElementById(‘audio’),
channels, rate, bufferLength;
audio.addEventListener('loadedmetadata', function () {
channels = audio.mozChannels;
rate = audio.mozSampleRate;
bufferLength = audio.mozFrameBufferLength;
// ...
});
Reading audio data
audio.addEventListener('MozAudioAvailable', function () {
var buffer = event.frameBuffer,
time = event.time;
for (var i = 0; i < bufferLength / channels; i++ ) {
// use buffer[i * channels + channelNumber]
}
});
Reading audio data
0.409862111297023, 0.259322117331362, -0.008777887762307, -0.984780922682458, -0.739880137997811, -0.393993360534229, -
0.698508825498069, -0.393512581774658, 0.073465971474621, -0.774029495474732, -0.068926253092157, 0.698052197232118,
0.450745893413682, 0.731625352383412, -0.633931102362129, 0.882738533608791, -0.493848309462582, -0.668645515465273,
0.271953939580002, 0.246314079650827, -0.645711462859856, 0.736913698005765, 0.872459503967142, -0.482284551106221,
0.661431378511110, -0.291951234239424, 0.669216884142705, -0.341110225783700, -0.165754738005617, -0.986556649848787,
0.803597140689702, -0.813939097068497, 0.297290844923532, -0.434373616658307, -0.820145776933725, -0.351005880456336,
0.380713105392354, -0.721515454501945, 0.066484189654290, 0.642101001764223, -0.597205735590506, -0.200460217995576,
0.491272422617811, 0.480988687186248, 0.227128301563507, 0.685168802023231, 0.075880282193273, -0.749673188605156,
0.702223692201174, -0.184544172051190, -0.506130812375945, -0.686331843733017, -0.791173541823365, 0.886386883125611,
0.042702665517532, 0.573126318821646, 0.576012637739739, -0.329392317046949, -0.560594547513062, -0.223420931279321,
0.652487040645743, 0.403985003945232, 0.881201502984618, 0.992330609078359, 0.157417714187382, 0.133725348839930,
0.343408728622162, 0.005933505310489, -0.914475827505964, 0.154820823526593, 0.148971641643792, 0.841135222645066,
0.095968894389784, -0.234891692775066, -0.055960466199662, -0.133320485223315, -0.945514113185999, 0.485242740877991,
0.933864235656065, 0.022960704882891, -0.139667183659487, 0.618401839172406, -0.195349340573667, 0.587291626042564,
0.158475194222853, 0.565554351499445, 0.101859803696333, 0.593813833398595, -0.349654793639986, 0.665640345371317,
0.814509967148215, 0.533843529155366, -0.631997214437279, -0.503973088121093, -0.180033876163095, -0.715287970025233,
0.739453218066262, -0.452880703839526, -0.112778265491663, -0.650074534874509, -0.925708286102557, 0.976021772837429,
0.768202886746198, -0.559265634778471, 0.004451442257993, 0.747659266125223, -0.692840193163558, -0.811031246931423,
0.064833012476722, -0.112213849236344, -0.045264398268911, 0.353260515196007, 0.150881652218966, -0.199176332305722,
0.680000507648084, 0.265540158726514, -0.692481536406930, -0.353516025899132, 0.548221585427517, 0.461960884430420,
0.983277137292909, 0.622653444743655, 0.480297639150934, 0.452168428463840, -0.823544922845037, -0.331975377216007,
0.358569546837979, -0.596899627797886, 0.301496127117938, 0.576480504549117, 0.150743674405126, -0.851734411492563,
0.127175797857987, 0.806251938739738, 0.360201361643523, 0.380717789492329, 0.759847187611911, -0.629616985016364,
0.179681096205048, 0.147705467636446, 0.793359439243774, -0.888943630149254, -0.768200353474536, 0.837243925007694,
0.601330942636268, -0.611155192762695, 0.176371159373866, 0.731621908979866, 0.294121659309740, 0.758972133758613,
0.226735505828943, -0.099879270352797, 0.716827038775917, -0.439818898014638, -0.845310989782625, 0.712989203634548,
0.040939664050535, -0.492177661587544, -0.611892969959734, -0.419016380589113, 0.526549046576405, -0.638706291747430,
0.611630316089939, -0.340452683930807, 0.833273571181310, 0.526974765301767, 0.462530036158461, -0.796029844105523,
0.604456871305559, 0.061317570172945, 0.642369077263937, -0.978365729885714, -0.468053997163355, 0.954769747262937,
0.446717706860744, -0.960283148953476, -0.751094692845392, 0.805721468166348, -0.290676951057867, 0.391488310207055,
0.099343420640492, 0.034684411420110, 0.463771493683684, -0.378392748975848, -0.830120263808777, -0.357574609519144,
0.755175701837563, -0.379417718802803, 0.295501263679325, 0.181793810178941, -0.116752805641118, -0.279166790263324,
0.938534135910232, 0.091496919686446, -0.107904426032210, -0.978447352332630, -0.180865072441111, 0.831093166130408,
0.099057141660298, 0.456832343000489, -0.652587456595693, 0.359989313981682, -0.951405226971930, 0.381285879196237,
0.182679971280062, -0.580757635269123, 0.879272667221741, -0.480336023774189, 0.833228235340136, .......................................
Low-level Data Format
WTF???
Samples ( not “examples” :) )
𝑆(𝑡) =
𝐴(𝑡)
𝐴 𝑚𝑎𝑥
𝑇𝑠𝑎𝑚𝑝𝑙𝑒 =
1
𝑓𝑠𝑎𝑚𝑝𝑙𝑒
𝑡 =
𝑁𝑠𝑎𝑚𝑝𝑙𝑒𝑠
𝑓𝑠𝑎𝑚𝑝𝑙𝑒
Sample analysis
https://github.com/corbanbrook/dsp.js/
Nyquist–Shannon sampling theorem:
𝑓𝑠𝑎𝑚𝑝𝑙𝑒 ≥ 2𝑓𝑚𝑎𝑥
Sample rate
http://bartus.org/akustyk/adc.html
audio.mozSetup(channels, sampleRate);
// …
audio.mozWriteAudio(samples1);
// …
audio.mozWriteAudio(samples2);
Writing audio
function AudioStream(readFn, bufSize) {
var audio = new Audio();
audio.mozSetup(1, sampleRate);
readFn = readFn.bind(audio, bufSize);
audio.writeAudio = function(soundData, callback) {
var written = this.mozWriteAudio(soundData),
length = soundData.length;
written < length
? setTimeout(this.writeAudio.bind(this, soundData.subarray(written), callback),
written ? 1000 * written / sampleRate : 0)
: callback(readFn());
}
readFn();
return audio;
}
Buffered writing
Main
Thread
Write
Audio
setTimeout
Read
Function
Calculation
Worker
Concurrency
Demonstration
http://rreverser.com/dev/piano/

Contenu connexe

En vedette

Programer Dusan Zivanovic VII1
Programer Dusan Zivanovic VII1Programer Dusan Zivanovic VII1
Programer Dusan Zivanovic VII1
dulovci
 
multimedia chapter1
multimedia chapter1multimedia chapter1
multimedia chapter1
nes
 
IV_WORKSHOP_NVIDIA-Audio_Processing
IV_WORKSHOP_NVIDIA-Audio_ProcessingIV_WORKSHOP_NVIDIA-Audio_Processing
IV_WORKSHOP_NVIDIA-Audio_Processing
diegogee
 
Digitization of Audio.ppt
Digitization of Audio.pptDigitization of Audio.ppt
Digitization of Audio.ppt
Videoguy
 

En vedette (14)

MMT Audio Technology and Applications
MMT Audio Technology and ApplicationsMMT Audio Technology and Applications
MMT Audio Technology and Applications
 
Digital signal processing through speech, hearing, and Python
Digital signal processing through speech, hearing, and PythonDigital signal processing through speech, hearing, and Python
Digital signal processing through speech, hearing, and Python
 
Programer Dusan Zivanovic VII1
Programer Dusan Zivanovic VII1Programer Dusan Zivanovic VII1
Programer Dusan Zivanovic VII1
 
multimedia chapter1
multimedia chapter1multimedia chapter1
multimedia chapter1
 
Samplers
SamplersSamplers
Samplers
 
Music Industry & Technology
Music Industry & TechnologyMusic Industry & Technology
Music Industry & Technology
 
IV_WORKSHOP_NVIDIA-Audio_Processing
IV_WORKSHOP_NVIDIA-Audio_ProcessingIV_WORKSHOP_NVIDIA-Audio_Processing
IV_WORKSHOP_NVIDIA-Audio_Processing
 
Application of digital_signal_processing_in_audio_processing[1]
Application of digital_signal_processing_in_audio_processing[1]Application of digital_signal_processing_in_audio_processing[1]
Application of digital_signal_processing_in_audio_processing[1]
 
Sound of Safety
Sound of SafetySound of Safety
Sound of Safety
 
Audio Processing and Music Recognition
Audio Processing and Music RecognitionAudio Processing and Music Recognition
Audio Processing and Music Recognition
 
Digitization of Audio.ppt
Digitization of Audio.pptDigitization of Audio.ppt
Digitization of Audio.ppt
 
Chapter 4 - Digital Transmission
Chapter 4 - Digital TransmissionChapter 4 - Digital Transmission
Chapter 4 - Digital Transmission
 
Speech Recognition Technology
Speech Recognition TechnologySpeech Recognition Technology
Speech Recognition Technology
 
Digital audio
Digital audioDigital audio
Digital audio
 

Similaire à JS: Audio Data Processing

Quick Wikipedia Mining using Elastic Map Reduce
Quick Wikipedia Mining using Elastic Map ReduceQuick Wikipedia Mining using Elastic Map Reduce
Quick Wikipedia Mining using Elastic Map Reduce
ohkura
 
[FrontInBH 2012] Por uma web mais rápida: técnicas de otimizações de sites - ...
[FrontInBH 2012] Por uma web mais rápida: técnicas de otimizações de sites - ...[FrontInBH 2012] Por uma web mais rápida: técnicas de otimizações de sites - ...
[FrontInBH 2012] Por uma web mais rápida: técnicas de otimizações de sites - ...
Caelum
 
Browser Wars Episode 1: The Phantom Menace
Browser Wars Episode 1: The Phantom MenaceBrowser Wars Episode 1: The Phantom Menace
Browser Wars Episode 1: The Phantom Menace
Nicholas Zakas
 
Search engines (icadwt 2009)
Search engines (icadwt 2009)Search engines (icadwt 2009)
Search engines (icadwt 2009)
Belal Al-Khateeb
 

Similaire à JS: Audio Data Processing (20)

Whirlwind Tour of SVG (plus RaphaelJS)
Whirlwind Tour of SVG (plus RaphaelJS)Whirlwind Tour of SVG (plus RaphaelJS)
Whirlwind Tour of SVG (plus RaphaelJS)
 
Spark Summit Dublin 2017 - MemSQL - Real-Time Image Recognition
Spark Summit Dublin 2017 - MemSQL - Real-Time Image RecognitionSpark Summit Dublin 2017 - MemSQL - Real-Time Image Recognition
Spark Summit Dublin 2017 - MemSQL - Real-Time Image Recognition
 
Build Better Responsive websites. Hrvoje Jurišić
Build Better Responsive websites. Hrvoje JurišićBuild Better Responsive websites. Hrvoje Jurišić
Build Better Responsive websites. Hrvoje Jurišić
 
report aboput sequencing of raw data.pptx
report aboput sequencing of raw data.pptxreport aboput sequencing of raw data.pptx
report aboput sequencing of raw data.pptx
 
Quick Wikipedia Mining using Elastic Map Reduce
Quick Wikipedia Mining using Elastic Map ReduceQuick Wikipedia Mining using Elastic Map Reduce
Quick Wikipedia Mining using Elastic Map Reduce
 
[FrontInBH 2012] Por uma web mais rápida: técnicas de otimizações de sites - ...
[FrontInBH 2012] Por uma web mais rápida: técnicas de otimizações de sites - ...[FrontInBH 2012] Por uma web mais rápida: técnicas de otimizações de sites - ...
[FrontInBH 2012] Por uma web mais rápida: técnicas de otimizações de sites - ...
 
Browser Wars Episode 1: The Phantom Menace
Browser Wars Episode 1: The Phantom MenaceBrowser Wars Episode 1: The Phantom Menace
Browser Wars Episode 1: The Phantom Menace
 
HTML5: friend or foe (to Flash)?
HTML5: friend or foe (to Flash)?HTML5: friend or foe (to Flash)?
HTML5: friend or foe (to Flash)?
 
Using Amazon Machine Learning to Identify Trends in IoT Data - Technical 201
Using Amazon Machine Learning to Identify Trends in IoT Data - Technical 201Using Amazon Machine Learning to Identify Trends in IoT Data - Technical 201
Using Amazon Machine Learning to Identify Trends in IoT Data - Technical 201
 
Using amazon machine learning to identify trends in io t data technical 201
Using amazon machine learning to identify trends in io t data   technical 201Using amazon machine learning to identify trends in io t data   technical 201
Using amazon machine learning to identify trends in io t data technical 201
 
The Future of the Web - Cold Front conference 2016
The Future of the Web - Cold Front conference 2016The Future of the Web - Cold Front conference 2016
The Future of the Web - Cold Front conference 2016
 
About Best friends - HTML, CSS and JS
About Best friends - HTML, CSS and JSAbout Best friends - HTML, CSS and JS
About Best friends - HTML, CSS and JS
 
Finding Evil In DNS Traffic
Finding  Evil In DNS TrafficFinding  Evil In DNS Traffic
Finding Evil In DNS Traffic
 
realestate and MySQL devops melbourne
realestate and MySQL devops melbournerealestate and MySQL devops melbourne
realestate and MySQL devops melbourne
 
Search engines (icadwt 2009)
Search engines (icadwt 2009)Search engines (icadwt 2009)
Search engines (icadwt 2009)
 
Voices that matter: High Performance Web Sites
Voices that matter: High Performance Web SitesVoices that matter: High Performance Web Sites
Voices that matter: High Performance Web Sites
 
Make your website 2 times faster
Make your website 2 times fasterMake your website 2 times faster
Make your website 2 times faster
 
Top-5-production-devconMunich-2023-v2.pptx
Top-5-production-devconMunich-2023-v2.pptxTop-5-production-devconMunich-2023-v2.pptx
Top-5-production-devconMunich-2023-v2.pptx
 
Bringing the JAMstack to the Enterprise
Bringing the JAMstack to the EnterpriseBringing the JAMstack to the Enterprise
Bringing the JAMstack to the Enterprise
 
Browsers with Wings
Browsers with WingsBrowsers with Wings
Browsers with Wings
 

Plus de Ingvar Stepanyan

AST - the only true tool for building JavaScript
AST - the only true tool for building JavaScriptAST - the only true tool for building JavaScript
AST - the only true tool for building JavaScript
Ingvar Stepanyan
 

Plus de Ingvar Stepanyan (10)

A very quick intro to astrophotography
A very quick intro to astrophotographyA very quick intro to astrophotography
A very quick intro to astrophotography
 
Asyncifying WebAssembly for the modern Web
Asyncifying WebAssembly for the modern WebAsyncifying WebAssembly for the modern Web
Asyncifying WebAssembly for the modern Web
 
Building fast interpreters in Rust
Building fast interpreters in RustBuilding fast interpreters in Rust
Building fast interpreters in Rust
 
Rust ⇋ JavaScript
Rust ⇋ JavaScriptRust ⇋ JavaScript
Rust ⇋ JavaScript
 
How I tried to compile JavaScript
How I tried to compile JavaScriptHow I tried to compile JavaScript
How I tried to compile JavaScript
 
Your code is not a string
Your code is not a stringYour code is not a string
Your code is not a string
 
es6.concurrency()
es6.concurrency()es6.concurrency()
es6.concurrency()
 
React for WinRT apps
React for WinRT appsReact for WinRT apps
React for WinRT apps
 
AST - the only true tool for building JavaScript
AST - the only true tool for building JavaScriptAST - the only true tool for building JavaScript
AST - the only true tool for building JavaScript
 
Creating own language made easy
Creating own language made easyCreating own language made easy
Creating own language made easy
 

Dernier

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
Enterprise Knowledge
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
giselly40
 

Dernier (20)

Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Evaluating the top large language models.pdf
Evaluating the top large language models.pdfEvaluating the top large language models.pdf
Evaluating the top large language models.pdf
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 

JS: Audio Data Processing

  • 1. JS: Audio Data Processing Ingvar Stepanyan Web Developer, MSP @RReverser (http://rreverser.com/)
  • 2. Native implementations: [Mozilla] Audio Data API (low-level processing) [WebKit] Web Audio API (+ some high-level sugar) [Flash] Sound API (low-level processing) Unifying wrappers: dynamicaudio.js (Audio Data API + Flash) XAudioJS (Audio Data API + Web Audio API + Flash) sink.js & co. (Audio Data API + Web Audio API) Current status Low Level
  • 3. <audio id=“audio” ... /> .................................... var audio = document.getElementById(‘audio’), channels, rate, bufferLength; audio.addEventListener('loadedmetadata', function () { channels = audio.mozChannels; rate = audio.mozSampleRate; bufferLength = audio.mozFrameBufferLength; // ... }); Reading audio data
  • 4. audio.addEventListener('MozAudioAvailable', function () { var buffer = event.frameBuffer, time = event.time; for (var i = 0; i < bufferLength / channels; i++ ) { // use buffer[i * channels + channelNumber] } }); Reading audio data
  • 5. 0.409862111297023, 0.259322117331362, -0.008777887762307, -0.984780922682458, -0.739880137997811, -0.393993360534229, - 0.698508825498069, -0.393512581774658, 0.073465971474621, -0.774029495474732, -0.068926253092157, 0.698052197232118, 0.450745893413682, 0.731625352383412, -0.633931102362129, 0.882738533608791, -0.493848309462582, -0.668645515465273, 0.271953939580002, 0.246314079650827, -0.645711462859856, 0.736913698005765, 0.872459503967142, -0.482284551106221, 0.661431378511110, -0.291951234239424, 0.669216884142705, -0.341110225783700, -0.165754738005617, -0.986556649848787, 0.803597140689702, -0.813939097068497, 0.297290844923532, -0.434373616658307, -0.820145776933725, -0.351005880456336, 0.380713105392354, -0.721515454501945, 0.066484189654290, 0.642101001764223, -0.597205735590506, -0.200460217995576, 0.491272422617811, 0.480988687186248, 0.227128301563507, 0.685168802023231, 0.075880282193273, -0.749673188605156, 0.702223692201174, -0.184544172051190, -0.506130812375945, -0.686331843733017, -0.791173541823365, 0.886386883125611, 0.042702665517532, 0.573126318821646, 0.576012637739739, -0.329392317046949, -0.560594547513062, -0.223420931279321, 0.652487040645743, 0.403985003945232, 0.881201502984618, 0.992330609078359, 0.157417714187382, 0.133725348839930, 0.343408728622162, 0.005933505310489, -0.914475827505964, 0.154820823526593, 0.148971641643792, 0.841135222645066, 0.095968894389784, -0.234891692775066, -0.055960466199662, -0.133320485223315, -0.945514113185999, 0.485242740877991, 0.933864235656065, 0.022960704882891, -0.139667183659487, 0.618401839172406, -0.195349340573667, 0.587291626042564, 0.158475194222853, 0.565554351499445, 0.101859803696333, 0.593813833398595, -0.349654793639986, 0.665640345371317, 0.814509967148215, 0.533843529155366, -0.631997214437279, -0.503973088121093, -0.180033876163095, -0.715287970025233, 0.739453218066262, -0.452880703839526, -0.112778265491663, -0.650074534874509, -0.925708286102557, 0.976021772837429, 0.768202886746198, -0.559265634778471, 0.004451442257993, 0.747659266125223, -0.692840193163558, -0.811031246931423, 0.064833012476722, -0.112213849236344, -0.045264398268911, 0.353260515196007, 0.150881652218966, -0.199176332305722, 0.680000507648084, 0.265540158726514, -0.692481536406930, -0.353516025899132, 0.548221585427517, 0.461960884430420, 0.983277137292909, 0.622653444743655, 0.480297639150934, 0.452168428463840, -0.823544922845037, -0.331975377216007, 0.358569546837979, -0.596899627797886, 0.301496127117938, 0.576480504549117, 0.150743674405126, -0.851734411492563, 0.127175797857987, 0.806251938739738, 0.360201361643523, 0.380717789492329, 0.759847187611911, -0.629616985016364, 0.179681096205048, 0.147705467636446, 0.793359439243774, -0.888943630149254, -0.768200353474536, 0.837243925007694, 0.601330942636268, -0.611155192762695, 0.176371159373866, 0.731621908979866, 0.294121659309740, 0.758972133758613, 0.226735505828943, -0.099879270352797, 0.716827038775917, -0.439818898014638, -0.845310989782625, 0.712989203634548, 0.040939664050535, -0.492177661587544, -0.611892969959734, -0.419016380589113, 0.526549046576405, -0.638706291747430, 0.611630316089939, -0.340452683930807, 0.833273571181310, 0.526974765301767, 0.462530036158461, -0.796029844105523, 0.604456871305559, 0.061317570172945, 0.642369077263937, -0.978365729885714, -0.468053997163355, 0.954769747262937, 0.446717706860744, -0.960283148953476, -0.751094692845392, 0.805721468166348, -0.290676951057867, 0.391488310207055, 0.099343420640492, 0.034684411420110, 0.463771493683684, -0.378392748975848, -0.830120263808777, -0.357574609519144, 0.755175701837563, -0.379417718802803, 0.295501263679325, 0.181793810178941, -0.116752805641118, -0.279166790263324, 0.938534135910232, 0.091496919686446, -0.107904426032210, -0.978447352332630, -0.180865072441111, 0.831093166130408, 0.099057141660298, 0.456832343000489, -0.652587456595693, 0.359989313981682, -0.951405226971930, 0.381285879196237, 0.182679971280062, -0.580757635269123, 0.879272667221741, -0.480336023774189, 0.833228235340136, ....................................... Low-level Data Format WTF???
  • 6. Samples ( not “examples” :) ) 𝑆(𝑡) = 𝐴(𝑡) 𝐴 𝑚𝑎𝑥 𝑇𝑠𝑎𝑚𝑝𝑙𝑒 = 1 𝑓𝑠𝑎𝑚𝑝𝑙𝑒 𝑡 = 𝑁𝑠𝑎𝑚𝑝𝑙𝑒𝑠 𝑓𝑠𝑎𝑚𝑝𝑙𝑒
  • 8. Nyquist–Shannon sampling theorem: 𝑓𝑠𝑎𝑚𝑝𝑙𝑒 ≥ 2𝑓𝑚𝑎𝑥 Sample rate http://bartus.org/akustyk/adc.html
  • 10. function AudioStream(readFn, bufSize) { var audio = new Audio(); audio.mozSetup(1, sampleRate); readFn = readFn.bind(audio, bufSize); audio.writeAudio = function(soundData, callback) { var written = this.mozWriteAudio(soundData), length = soundData.length; written < length ? setTimeout(this.writeAudio.bind(this, soundData.subarray(written), callback), written ? 1000 * written / sampleRate : 0) : callback(readFn()); } readFn(); return audio; } Buffered writing

Notes de l'éditeur

  1. Доброго дня.Мене звати Ігор Степанян.Сьогодні я хотів би коротко розповісти про основи обробки звуку за допомогою JavaScript (наперед прошу побачення за невеликі математичні викладки, без них тут просто не обійтись).
  2. На даний момент у нас є три реалізації для роботи з аудіоданими на клієнтській частині:це дві, абсолютно різні реалізації Audio API у Firefox та Chromeну і, звісно ж, Flash (підтримка Sound API у ньому наявна в 10-й версії та вищих).При цьому Firefox та Flash дають можливості для низькорівневої обробки аудіоданих, в той час як Chrome, окрім них, надає API і для різноманітних стандартних високорівневих операцій над звуком.Звісно ж, цих всіх розбіжностей у реалізації не могла помітити JavaScript-спільнота, і тому невдовзі з’явились бібліотеки, що об’єднують доступ до тих чи інших операцій через єдине API – dynamicaudio.js, що дозволяє виводити звук за допомогою Mozilla API та Flash-fallback для інших браузерів, XAudioJS, що аналогічним чином об’єднує уже всі три реалізації, sink.js з декількома дочірніми бібліотеками, що надає можливості для синхронного та асинхронного виводу аудіоданих та інші.Але яку б бібліотеку ви не використовували, вам доведеться якимсь чином створювати чи оброблювати існуючі аудіодані перед їх виводом. На щастя, ця частина коду незалежна від конкретної реалізації Audio API.Для демонстрації я використовуватиму Audio Data API, представлене Mozilla. Воно було обране практично випадково – просто хотілось випробувати низькорівневу обробку даних в «чистих» умовах, не покладаючись на високорівневі плюшки, специфічні тільки для Chrome.
  3. Для початку розглянемо, як відбувається читання даних з аудіопотоку і що вони собою представляють.Для цього в FF використовуються дві події.Перша – стандартна подія HTML5 – loadedmetadata, яка відбувається після розпізнавання заголовку з метаданими. Ми можем зберегти ці дані у змінні, провести ініціалізацію даних, бібліотек, всього що приймає за параметри якісь з наведених властивостей аудіофайлу.
  4. Друга подія – уже більшспецифічна – MozAudioAvailable – вона повертає черговий уривок декодованих аудіоданих (вони можуть бути як уже програні, так і ні), а також час в секундах відносно початку програвання.
  5. Коли я вперше завантажив таким способом музичний файл і отримав в буфері, здавалось би, випадковий набір чисел між -1 та 1, виникло досить закономірне питання – гм... скажімо, «а що це?» :)
  6. Для тих хто досі ніколи не мав справи зі звуковими даними – ці числа називаються «семплами». Семпл являє собою значення хвилі у моменти часу, розділені періодом дискретизації (обернене до частоти дискретизації). У нашому випадку семпли даються уже нормалізованими значеннями відносно максимально можливої амплітуди хвилі.Таким чином, ми можемо оперувати самими цими значеннями, якщо хочемо змінювати загальну амплітуду – домножувати/ділити на сталий коефіцієнт, здійснити затухання чи, навпаки, плавне наростання за власним законом від часу тощо.
  7. Якщо ж ми захочемо отримати частотну характеристику вхідного сигналу, наприклад, для візуалізації його спектру чи реалізації еквалайзеру, то доведеться використати перетворення Фур’є (для не-математиків – воно розкладає будь-яку функцію на суму синусоїд, що у нашому випадку якраз і дасть бажаний розклад по частотах). В принципі реалізацію цього алгоритму вам вручну писати не доведеться, вони є готові, в тому числі в бібліотеці DSP.js, посилання для якої наведене на екрані.
  8. Окремий момент про частоту дискретизації. Для виводу звуку вам необхідно спершу задати частоту дискретизації, на якій буде здійснюватись вивід. Звісно, можна використовувати стандартні значення типу 44100 Hz, 48000 Hz тощо, але якщо ви наперед знаєте максимальну частоту звуків, що будуть виводитись, то є сенс скористатись теоремою Найквіста-Шеннона, яка стверджує, що для успішної інтерполяції хвилі з дискретизованих даних достатньо частоти дискретизації, що лише вдвічі більша за максимальну з частот хвиль, з яких складається дана (з цього ж закону і зрозуміло, звідки взявся стандарт в 44100 Hz). Це може дозволити відчутно скоротити час генерації аудіо, адже кожна секунда звуку представляється масивом з f_sampleелементів.На малюнку вище можна побачити приклад правильно (знизу) і неправильно (зверху) підібраних частот дискретизаціїта ефектів від цього.
  9. Цієї теорії нам досить, перейдем до власне виводу аудіо.На перший погляд, тут все просто.Маємо функцію mozSetup, що задає налаштування для аудіопотоку – кількість каналів і частоту дискретизації, та є функція mozWriteAudio для запису масиву семплів. Відповідно, для програвання звуку хотілось би писати в такому вигляді: ...
  10. Та проблема в тому, що дані для mozWriteAudio мають передаватись у порціях, що не перевищують внутрішній буфер аудіопотоку (його ми наперед визначити не можем). При цьому при передачі завеликого масиву семплів функція поверне кількість семплів, що були успішно записані. Відповідно усі інші доведеться зберегти і спробувати вивести повторно пізніше. Можна зберігати цей «хвіст» в окрему змінну і повісити обробник, що буде намагатись через деякий час знову або вивести цей хвіст, або, якщо він порожній – викликатиме наш callback для генерації нового набору семплів.В принципі на цьому можна було б зупинитись і уже використовувати цю функцію для виводу звуку. Та є ще один момент.
  11. Та є ще один неприємний момент. Якщо проводити складні обчислення у тому ж потоці, що і сам UI, звук може починати тріщати, приторможувати тощо. Тому є сенс винести самі обчислення у Web Worker і викликати його за необхідності, а на callback від нього уже вішати наш writeAudio. Таким чином отримуєм наступну схему.
  12. (демонстрація)