sinshu / meltysynth

A SoundFont MIDI synthesizer for .NET
Other
136 stars 16 forks source link

Thanks for making this!! #11

Open chipweinberger opened 2 years ago

chipweinberger commented 2 years ago

I made a Dart port of MeltySynth =) Just wanted to let you know of its existence!

https://github.com/chipweinberger/DartMeltySoundFont

I looked around for days for a good SoundFont implementation to port to Dart, and yours is incredibly clean and well written. Really impressive! I looked in depth to at least 4 different implementations!

Really happy I found your implementation, and for all your work making this high quality library!

sinshu commented 2 years ago

Excellent work!!! It's always nice to see the same software written in different languages!

BleuBleu commented 2 years ago

Sorry to use this as a strange way to get in touch with you, great little project, well done! :) I was curious, what is the source of the chorus algorithm you implemented? Id like to go back to the source and learn how it really works. Thanks!

EDIT : It looks like the original flanger from Alex Veltsistas, but with a precomputed delay table.

-Mat

sinshu commented 2 years ago

The chorus implementation is taken from the textbook "Sound programming in C - Signal processing for sound effects". Although the textbook is written in Japanese, the example code should be helpful. You can get the example code from the following web page.

http://floor13.sakura.ne.jp/book03/book03.html

"ex9_1.c" in "chapter09.zip" is the original chorus implementation. Here is the original code with English comments by me.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "wave.h"

int main(void)
{
  MONO_PCM pcm0, pcm1;
  int n, m;
  double d, depth, rate, t, tau, delta;

  mono_wave_read(&pcm0, "sample06.wav"); /* Read the mono sound data from the WAVE file */

  pcm1.fs = pcm0.fs; /* The sample rate */
  pcm1.bits = pcm0.bits; /* The bit depth */
  pcm1.length = pcm0.length; /* The length of the sound data */
  pcm1.s = calloc(pcm1.length, sizeof(double)); /* Memory allocation */

  d = pcm1.fs * 0.025; /* 25ms */
  depth = pcm1.fs * 0.01; /* 10ms */
  rate = 0.1; /* 0.1Hz */

  /* Chorus */
  for (n = 0; n < pcm1.length; n++)
  {
    pcm1.s[n] = pcm0.s[n];

    tau = d + depth * sin(2.0 * M_PI * rate * n / pcm1.fs);
    t = (double)n - tau;
    m = (int)t;
    delta = t - (double)m;
    if (m >= 0 && m + 1 < pcm1.length)
    {
      pcm1.s[n] += delta * pcm0.s[m + 1] + (1.0 - delta) * pcm0.s[m]; 
    }
  }

  mono_wave_write(&pcm1, "ex9_1.wav"); /* Output the mono sound data to the WAVE file */

  free(pcm0.s); /* Free memory */
  free(pcm1.s); /* Free memory */

  return 0;
}
BleuBleu commented 2 years ago

Thank you! That looks like such a good book. Too bad i cant read it, but i can read code.

-Mat

gregdivis commented 1 year ago

Just wanted to add my own thank you here. I've been wanting to add general midi synthesis to my x86/dos emulator for years, and it was trivially easy to plug MeltySynth in.

Fantastic work!

sinshu commented 1 year ago

Very nice 😄

maximilien-noal commented 1 year ago

Thank you so much for this library !

I was able to replace WinMM with a cross platform solution in this project here:

http://github.com/OpenRakis/Spice86

https://github.com/OpenRakis/Spice86/pull/318/files#diff-e2ea523633a3e17970892a5d688be542efc520860a73da8ea155191145ee85f2

Along with a small GM SoundFont with a suitable license (CC0), this works perfectly ! :)

sinshu commented 1 year ago

Glad to hear that 😊

markheath commented 1 year ago

A big thank you from me too. I always dreamed of adding something like this to NAudio but never had the time (there is a semi-complete SoundFont parser in there, but no sequencer or soundfont player). Really impressed with what you've made, and how easy it is to use.

sinshu commented 1 year ago

Thanks! I'm also grateful for your work on NAudio 😊

chipweinberger commented 1 year ago

https://markheath.net/post/naudio-midi-playback-soundfont-meltysynth

blog coverage =)