Previous 199869 Revisions Next

r44661 Thursday 4th February, 2016 at 04:56:27 UTC by Robbbert
Merge branch 'master' of https://github.com/mamedev/mame
[scripts/src]main.lua
[src/osd/modules/sound]js_sound.cpp js_sound.js*

trunk/scripts/src/main.lua
r253172r253173
8888      targetextension ".bc" 
8989      if os.getenv("EMSCRIPTEN") then
9090         postbuildcommands {
91            os.getenv("EMSCRIPTEN") .. "/emcc -O3 -s DISABLE_EXCEPTION_CATCHING=2 -s USE_SDL=2 --memory-init-file 0 -s ALLOW_MEMORY_GROWTH=0 -s TOTAL_MEMORY=268435456 -s EXCEPTION_CATCHING_WHITELIST='[\"__ZN15running_machine17start_all_devicesEv\"]' -s EXPORTED_FUNCTIONS=\"['_main', '_malloc', '__Z14js_get_machinev', '__Z9js_get_uiv', '__Z12js_get_soundv', '__ZN10ui_manager12set_show_fpsEb', '__ZNK10ui_manager8show_fpsEv', '__ZN13sound_manager4muteEbh', '_SDL_PauseAudio']\" $(TARGET) -o " .. _MAKE.esc(MAME_DIR) .. _OPTIONS["target"] .. _OPTIONS["subtarget"] .. ".js --post-js " .. _MAKE.esc(MAME_DIR) .. "src/osd/sdl/emscripten_post.js",
91            os.getenv("EMSCRIPTEN") .. "/emcc -O3 -s DISABLE_EXCEPTION_CATCHING=2 -s USE_SDL=2 --memory-init-file 0 -s ALLOW_MEMORY_GROWTH=0 -s TOTAL_MEMORY=268435456 -s EXCEPTION_CATCHING_WHITELIST='[\"__ZN15running_machine17start_all_devicesEv\"]' -s EXPORTED_FUNCTIONS=\"['_main', '_malloc', '__Z14js_get_machinev', '__Z9js_get_uiv', '__Z12js_get_soundv', '__ZN10ui_manager12set_show_fpsEb', '__ZNK10ui_manager8show_fpsEv', '__ZN13sound_manager4muteEbh', '_SDL_PauseAudio']\" $(TARGET) -o " .. _MAKE.esc(MAME_DIR) .. _OPTIONS["target"] .. _OPTIONS["subtarget"] .. ".js --pre-js " .. _MAKE.esc(MAME_DIR) .. "src/osd/modules/sound/js_sound.js --post-js " .. _MAKE.esc(MAME_DIR) .. "src/osd/sdl/emscripten_post.js",
9292         }
9393      end
9494
trunk/src/osd/modules/sound/js_sound.cpp
r253172r253173
66
77    Shim for native JavaScript sound interface implementations (Emscripten only).
88
9*******************************************************************c********/
9****************************************************************************/
1010
1111#include "sound_module.h"
1212#include "modules/osdmodule.h"
r253172r253173
3434   {
3535      EM_ASM_ARGS({
3636      // Forward audio stream update on to JS backend implementation.
37      jsmess_update_audio_stream($0, $1);
37      jsmame_update_audio_stream($0, $1);
3838      }, (unsigned int)buffer, samples_this_frame);
3939   }
4040   virtual void set_mastervolume(int attenuation)
4141   {
4242      EM_ASM_ARGS({
4343      // Forward volume update on to JS backend implementation.
44      jsmess_set_mastervolume($0);
44      jsmame_set_mastervolume($0);
4545      }, attenuation);
4646   }
4747
trunk/src/osd/modules/sound/js_sound.js
r0r253173
1// license:BSD-3-Clause
2// copyright-holders:Grant Galitz, Katelyn Gadd
3/***************************************************************************
4
5    JSMAME web audio backend v0.3
6
7    Original by katelyn gadd - kg at luminance dot org ; @antumbral on twitter
8    Substantial changes by taisel
9
10***************************************************************************/
11
12var jsmame_web_audio = (function () {
13
14var context = null;
15var gain_node = null;
16var eventNode = null;
17var sampleScale = 32766;
18var inputBuffer = new Float32Array(44100);
19var bufferSize = 44100;
20var start = 0;
21var rear = 0;
22var watchDogDateLast = null;
23var watchDogTimerEvent = null;
24
25function lazy_init () {
26  //Make
27  if (context) {
28    //Return if already created:
29    return;
30  }
31  if (typeof AudioContext != "undefined") {
32    //Standard context creation:
33    context = new AudioContext();
34  }
35  else if (typeof webkitAudioContext != "undefined") {
36    //Older webkit context creation:
37    context = new webkitAudioContext();
38  }
39  else {
40    //API not found!
41    return;
42  }
43  //Generate a volume control node:
44  gain_node = context.createGain();
45  //Set initial volume to 1:
46  gain_node.gain.value = 1.0;
47  //Connect volume node to output:
48  gain_node.connect(context.destination);
49  //Initialize the streaming event:
50  init_event();
51};
52
53function init_event() {
54    //Generate a streaming node point:
55    if (typeof context.createScriptProcessor == "function") {
56 //Current standard compliant way:
57 eventNode = context.createScriptProcessor(4096, 0, 2);
58    }
59    else {
60 //Deprecated way:
61 eventNode = context.createJavaScriptNode(4096, 0, 2);
62    }
63    //Make our tick function the audio callback function:
64    eventNode.onaudioprocess = tick;
65    //Connect stream to volume control node:
66    eventNode.connect(gain_node);
67    //WORKAROUND FOR FIREFOX BUG:
68    initializeWatchDogForFirefoxBug();
69};
70
71function initializeWatchDogForFirefoxBug() {
72    //TODO: decide if we want to user agent sniff firefox here,
73    //since Google Chrome doesn't need this:
74    watchDogDateLast = (new Date()).getTime();
75    if (watchDogTimerEvent === null) {
76   watchDogTimerEvent = setInterval(function () {
77  var timeDiff = (new Date()).getTime() - watchDogDateLast;
78  if (timeDiff > 500) {
79 disconnect_old_event();
80 init_event();
81  }
82   }, 500);
83    }
84};
85
86function disconnect_old_event() {
87    //Disconnect from audio graph:
88    eventNode.disconnect();
89    //IIRC there was a firefox bug that did not GC this event when nulling the node itself:
90    eventNode.onaudioprocess = null;
91    //Null the glitched/unused node:
92    eventNode = null;
93};
94
95function set_mastervolume (
96  // even though it's 'attenuation' the value is negative, so...
97  attenuation_in_decibels
98) {
99  lazy_init();
100  if (!context) return;
101
102  // http://stackoverflow.com/questions/22604500/web-audio-api-working-with-decibels
103  // seemingly incorrect/broken. figures. welcome to Web Audio
104  // var gain_web_audio = 1.0 - Math.pow(10, 10 / attenuation_in_decibels);
105
106  // HACK: Max attenuation in JSMESS appears to be 32.
107  // Hit ' then left/right arrow to test.
108  // FIXME: This is linear instead of log10 scale.
109  var gain_web_audio = 1.0 + (+attenuation_in_decibels / +32);
110  if (gain_web_audio < +0)
111    gain_web_audio = +0;
112  else if (gain_web_audio > +1)
113    gain_web_audio = +1;
114
115  gain_node.gain.value = gain_web_audio;
116};
117
118function update_audio_stream (
119  pBuffer,           // pointer into emscripten heap. int16 samples
120  samples_this_frame // int. number of samples at pBuffer address.
121) {
122  lazy_init();
123  if (!context) return;
124
125  for (
126    var i = 0,
127   l = samples_this_frame | 0;
128    i < l;
129    i++
130  ) {
131    var offset =
132 // divide by sizeof(INT16) since pBuffer is offset
133 //  in bytes
134 ((pBuffer / 2) | 0) +
135 ((i * 2) | 0);
136
137    var left_sample = HEAP16[offset];
138    var right_sample = HEAP16[(offset + 1) | 0];
139
140    // normalize from signed int16 to signed float
141    var left_sample_float = left_sample / sampleScale;
142    var right_sample_float = right_sample / sampleScale;
143
144    inputBuffer[rear++] = left_sample_float;
145    inputBuffer[rear++] = right_sample_float;
146    if (rear == bufferSize) {
147 rear = 0;
148    }
149    if (start == rear) {
150 start += 2;
151 if (start == bufferSize) {
152   start = 0;
153 }
154    }
155  }
156};
157function tick (event) {
158  //Find all output channels:
159  for (var bufferCount = 0, buffers = []; bufferCount < 2; ++bufferCount) {
160    buffers[bufferCount] = event.outputBuffer.getChannelData(bufferCount);
161  }
162  //Copy samples from the input buffer to the Web Audio API:
163  for (var index = 0; index < 4096 && start != rear; ++index) {
164    buffers[0][index] = inputBuffer[start++];
165    buffers[1][index] = inputBuffer[start++];
166    if (start == bufferSize) {
167 start = 0;
168    }
169  }
170  //Pad with silence if we're underrunning:
171  while (index < 4096) {
172    buffers[0][index] = 0;
173    buffers[1][index++] = 0;
174  }
175  //Deep inside the bowels of vendors bugs,
176  //we're using watchdog for a firefox bug,
177  //where the user agent decides to stop firing events
178  //if the user agent lags out due to system load.
179  //Don't even ask....
180  watchDogDateLast = (new Date()).getTime();
181}
182
183function get_context() {
184  return context;
185};
186
187function sample_count() {
188    //TODO get someone to call this from the emulator,
189    //so the emulator can do proper audio buffering by
190    //knowing how many samples are left:
191    if (!context) {
192   //Use impossible value as an error code:
193   return -1;
194    }
195    var count = rear - start;
196    if (start > rear) {
197   count += bufferSize;
198    }
199    return count;
200}
201
202return {
203  set_mastervolume: set_mastervolume,
204  update_audio_stream: update_audio_stream,
205  get_context: get_context,
206  sample_count: sample_count
207};
208
209})();
210
211window.jsmame_set_mastervolume = jsmame_web_audio.set_mastervolume;
212window.jsmame_update_audio_stream = jsmame_web_audio.update_audio_stream;
213window.jsmame_sample_count = jsmame_web_audio.sample_count;


Previous 199869 Revisions Next


© 1997-2024 The MAME Team