You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I admire your project. I wanted to use your code to embed a small "play NSF chiptune" button on my blog. I have successfully compiled your fork of game_music_emu with emscripten, emcmake cmake ../ -DUSE_GME_AY=0 -DUSE_GME_GBS=0 -DUSE_GME_GYM=0 -DUSE_GME_HES=0 -DUSE_GME_KSS=0 -DUSE_GME_SAP=0 -DUSE_GME_SPC=0 -DUSE_GME_VGM=0 -DENABLE_UBSAN=OFF -DBUILD_SHARED_LIBS=OFF (After editing your CMakeList to include ym2413, and editing gme.cpp to comment out all emu types except NSF and NSFe)
and have written a few c and javascript helper functions.
I want to be able to pass true or false into my javascript helper function to render the song in stereo or mono. I have no issue playing back NSF music in stereo, but I cannot get it to switch to mono. The gme_set_effects function described in gme.h looks like it should play the song in mono if I pass NULL into it, but it has no effect.
Here is my c code:
#include<stdlib.h>#include<stdio.h>#include<gme.h>#include<emscripten/webaudio.h>#include<math.h>//for sin//uint8_t audioThreadStack[4096];gme_t*emu;
void*nsfdata;
longnsfdataSize=0;
inttrack;
EM_BOOLstereopref;
intlimitlogs=0;
intbuf_size;
short*buf;
voidhandle_error( constchar*str );
staticvoidplay_siren( longcount, short*out )
{
staticdoublea, a2;
while ( count-- )
*out++=0x2000*sin( a+=.1+.05*sin( a2+=.00005 ) );
}
EMSCRIPTEN_KEEPALIVEintsetupNSF(void*inputdata, longinputdataSize, intinputBufSize, inttracknum, EM_BOOLstereoInput)
{
printf("setupNSF\n");
nsfdata=inputdata;
nsfdataSize=inputdataSize;
track=tracknum;
stereopref=stereoInput;
buf_size=inputBufSize;
intsample_rate=44100;
/* Open music file in new emulator */handle_error( gme_open_data( nsfdata, nsfdataSize, &emu, sample_rate ) );
if (stereopref==EM_TRUE) {
printf("STEREOPREF IS TRUE\n");
structgme_effects_teffects;
effects.enabled=1;
effects.stereo=0.5;
effects.echo=0.0;
gme_set_effects( emu, &effects );
} else {
printf("STEREOPREF IS FALSE\n");
gme_set_effects( emu, NULL ); // this does not work//struct gme_effects_t effects;//effects.enabled = 0;//effects.stereo = 0.0;//gme_set_effects( emu, &effects ); //these also do not work
}
// I have tried putting open_data here, it made no difference.printf("nsfdataSize: %li \n", nsfdataSize);
/* Start track */handle_error( gme_start_track( emu, track ) );
buf=malloc(sizeof(*buf) *buf_size); // https://stackoverflow.com/questions/4240331/c-initializing-a-global-array-in-a-functionprintf("array buf entry number 3: %d\n", buf[3]);
printf("setupNSF done\n");
return0;
}
EMSCRIPTEN_KEEPALIVEshort*playNSF() { // run in script processor node's on audio process eventhandle_error( gme_play( emu, buf_size*2, buf ) );
//play_siren(buf_size, buf);// the c code cannot return an array to javascript, use runtime method getValue to access the buf array.returnbuf;
}
voidhandle_error( constchar*str )
{
if ( str )
{
printf( "Error: %s\n", str ); //getchar();//exit( EXIT_FAILURE );
}
}
Here is my Javascript:
document.getElementById("nsfplaybut").addEventListener("click",myclick,{once:true})functionmyclick(){nsfplay("Akumajou Densetsu (VRC6).nsfe",0,false);}constINT16_MAX=65535;asyncfunctionnsfplay(url,tracknum,stereopref){varresponse=awaitfetch(url)constaudioCtx=newAudioContext({latencyHint:"playback",sampleRate:44100});constbufferSize=Math.max(// Make sure script node bufferSize is at least baseLatencyMath.pow(2,Math.ceil(Math.log2((audioCtx.baseLatency||0.001)*audioCtx.sampleRate))),2048);console.log(bufferSize);varaudioNode=audioCtx.createScriptProcessor(bufferSize,2,2)audioNode.connect(audioCtx.destination)response=awaitresponse.arrayBuffer()vardata=newUint8Array(response)Module.ccall("setupNSF","number",["array","number","number","number","boolean"],[data,data.length,bufferSize,tracknum,stereopref])varplayNSF=Module.cwrap("playNSF","number",null)audioNode.onaudioprocess=function(e){letbufPtr=playNSF()letoutputData=[];for(letchannel=0;channel<e.outputBuffer.numberOfChannels;channel++){outputData[channel]=e.outputBuffer.getChannelData(channel);/*nested loop*/for(leti=0;i<bufferSize;i++){outputData[channel][i]=Module.getValue(bufPtr+i*2*2+/* frame offset * bytes per sample * num channels + */channel*2/* channel offset * bytes per sample */,'i16')/INT16_MAX/* convert int16 to float */}}}}
Thank you.
The text was updated successfully, but these errors were encountered:
Good question; before digging into your code, I'll just mention that I did a quick and dirty modification to game-music-emu to output the NES sound in stereo: 839b9c2
Simply put: the two 2A03 square channels are hard panned Left and Right.
That should be easy to undo, but if you want to make the stereo/mono switchable at runtime, you would have to do some further modifications.
You could always do a mixdown in Javascript to keep things simple. (Add both NSF channels to both output channels. Or create a mono Audio Node?)
I admire your project. I wanted to use your code to embed a small "play NSF chiptune" button on my blog. I have successfully compiled your fork of game_music_emu with emscripten,
emcmake cmake ../ -DUSE_GME_AY=0 -DUSE_GME_GBS=0 -DUSE_GME_GYM=0 -DUSE_GME_HES=0 -DUSE_GME_KSS=0 -DUSE_GME_SAP=0 -DUSE_GME_SPC=0 -DUSE_GME_VGM=0 -DENABLE_UBSAN=OFF -DBUILD_SHARED_LIBS=OFF
(After editing your CMakeList to include ym2413, and editing gme.cpp to comment out all emu types except NSF and NSFe)and have written a few c and javascript helper functions.
I want to be able to pass
true
orfalse
into my javascript helper function to render the song in stereo or mono. I have no issue playing back NSF music in stereo, but I cannot get it to switch to mono. Thegme_set_effects
function described in gme.h looks like it should play the song in mono if I passNULL
into it, but it has no effect.Here is my c code:
Here is my Javascript:
Thank you.
The text was updated successfully, but these errors were encountered: