RobLoach / pntr_app

Application wrapper for pntr.
https://robloach.github.io/pntr_app/
zlib License
5 stars 1 forks source link

pntr_load_sound_from_memory is not creating wav correctly on web #107

Closed konsumer closed 2 months ago

konsumer commented 2 months ago

I have a sfx function that generates sound like this:

uint32_t null0_new_sfx(SfxParams* params) {
  SfxSynth* synth = sfx_allocSynth(SFX_U8, 44100, 10);
  int sampleCount = sfx_generateWave(synth, params);

  wav_header.wav_size = sampleCount;
  wav_header.data_bytes = sampleCount;

  char* w = malloc(sampleCount + sizeof(wav_header));
  memcpy(w, &wav_header, sizeof(wav_header));
  memcpy((void*)((int64_t)w + sizeof(wav_header)), synth->samples.u8, sampleCount);

  pntr_sound* s = pntr_load_sound_from_memory(PNTR_APP_SOUND_TYPE_WAV, w, sampleCount + sizeof(wav_header));
  if (synth != NULL) {
    free(synth);
  }
  // free(w);
  return null0_add_sound(s);
}

This works on native, but is failing on web. It creates the blob-URL but the mime-type is wrong, and wav looks wrong to my eyes (the data part seems off)

Screenshot_2024-06-30_at_6 26 55_PM

This was working before, and still works ok on native, but I may have changed something in my host.

Here is my C code in game-wasm (the wasm that is hosted in web, that calls the other wasm):

typedef struct {
  // Random seed used to generate the wave
  u32 randSeed;

  // Wave type (square, sawtooth, sine, noise)
  i32 waveType;

  // Wave envelope parameters
  f32 attackTime;
  f32 sustainTime;
  f32 sustainPunch;
  f32 decayTime;

  // Frequency parameters
  f32 startFrequency;
  f32 minFrequency;
  f32 slide;
  f32 deltaSlide;
  f32 vibratoDepth;
  f32 vibratoSpeed;

  // Tone change parameters
  f32 changeAmount;
  f32 changeSpeed;

  // Square wave parameters
  f32 squareDuty;
  f32 dutySweep;

  // Repeat parameters
  f32 repeatSpeed;

  // Phaser parameters
  f32 phaserOffset;
  f32 phaserSweep;

  // Filter parameters
  f32 lpfCutoff;
  f32 lpfCutoffSweep;
  f32 lpfResonance;
  f32 hpfCutoff;
  f32 hpfCutoffSweep;
} SfxParams;

// Create a new sound-effect from some sfxr params
u32 new_sfx(SfxParams* params);

// Generate randomized preset sfxr params
void preset_sfx(SfxParams* params, SfxPresetType type);

And here is my js-host code to copy the struct out:

new_sfx (paramsPtr) {
  const paramsHostPtr = copyBytesFromCart(paramsPtr, 48)
  const ret = host._null0_new_sfx(paramsHostPtr)
  host._free(paramsHostPtr)
  return ret
},

preset_sfx (paramsPtr, type) {
  const paramsHostPtr = copyBytesFromCart(paramsPtr, 48)
  host._null0_new_sfx(paramsHostPtr, type)
  copyBytesToCart(paramsPtr, 48, paramsHostPtr)
  host._free(paramsHostPtr)
}

copyBytesFromCart and copyBytesToCart seem to work, otherwise. I will keep testing and see if I can narrow down the issue. Maybe a more isolated example would help.

Here is the output saved from web: test.wav.zip

RobLoach commented 2 months ago

Do you have your whole code available? Would love to check it out... When loading the WAV in a desktop audio playing, it's not loading correctly. Could there be somehting wrong with how it's setting up the file?

Does pntr_sound* s = pntr_load_sound_from_memory output something other than NULL?

Been wanting to add buffer support to playing audio, so that you wouldn't need to load it as a wav after creating it.

konsumer commented 2 months ago

Yeh, I can work on buffer-support too. This method of mine to generate a wav of sfx feels like a total-hack, anyway, and it's a bit slow (there is a noticeable delay, which is maybe fine if I preload some sfx, but not great on the fly.)

The code is here.

I feel like a simplified example would help (plain pntr_app compiloed to native and web) so I will make one, as this has a few layers to troubleshoot.

konsumer commented 2 months ago

Ok, so I added a few headers and some cmake-config to get sfx in example, here. Feel free to use the pntr_load_sfx function too, if you want. I generate a "powerup" sound and it works in raylib example. Press space to activate.

I build with

emcmake cmake -B build -DPNTR_APP_BUILD_EXAMPLE_RAYLIB=false -DPNTR_APP_BUILD_EXAMPLE_WEB=true
emmake make -C build

And it seems much stricter:

/src/example/sfx_gen.c:85:20: error: a function declaration without a prototype is deprecated in all versions of C [-Werror,-Wstrict-prototypes]
   85 | static float rndNP1()
      |                    ^
      |                     void
1 error generated.
make[2]: *** [example/CMakeFiles/pntr_app_example_web.dir/build.make:92: example/CMakeFiles/pntr_app_example_web.dir/sfx_gen.c.o] Error 1

I will come back to it later, when I have more time.

konsumer commented 2 months ago

I think it must be something in my web host-stuff. I made pntr_app_sfx, and it works in example with both emscritpen & native. I am going to close this.