Trails of Cave Story: Synthesizing music

Описание к видео Trails of Cave Story: Synthesizing music

In this tool-assisted programming video I create a synthesizer from scratch. It plays authentic Cave Story (洞窟物語) music tracks and sound effects (ORG and PXT files).

Twitter:   / realbisqwit  
Patreon:   / bisqwit   (alternatives at https://iki.fi/bisqwit/donate.html)
Twitch:   / realbisqwit  
Homepage: https://iki.fi/bisqwit/

All resources concerning this video can be downloaded from https://bisqwit.iki.fi/jutut/kuvat/pr... , including the patch that does the waveform visualization.
Note there's a small bug in the showcased program regarding pitch calculation. It appears to work only when the sample rate is 48000. The formula for calculating "scale" for the lanczos filtering was also wrong; it used "phaseacc" when it should have used "phaseinc". The version on the web page has both bugs fixed.

The music system -- called Organya -- works like this. The song has 16 channels, eight of which are for melodic instruments and the other eight are for drums only.
Each channel is assigned one instrument, which is defined in the song header, and cannot be changed during the song.
Each channel can have a maximum of 1 voice playing simultaneously.
There is a global "wave table", which is hardcoded into the game; the wave table contains 100 short wave samples; the instruments refer to this wave table.
The actual song data is a per-channel list of events. Each event can begin a note, which plays for duration, or it can change the amplitude of the sample playing on the channel, or it can change the pan level, or do all of above.

In this program I play the music through ALSA sound system in Linux. For no reason at all, the audio data is going to be floating-point as opposed to the more commonly used sixteen-bit or eight-bit integer audio.

All the background music, in this video, is actually played through the program that I am writing in this very video. The background music played during programming is composed by Motoi Sakuraba, and originally published in Tales of Phantasia and Star Ocean SNES games. I converted those music tracks into Organya songs (covers).

The in-game songs I play are:
-- 3:56 Bush Lands (note: Grasstown is a mistranslation; note: played here without percussion)
-- 8:21 Jenka (note: it's a Finnish folk dance type, letkajenkka)
-- 8:59 Outside (the song that plays in the scene where you might choose to get the "bad ending")
-- 10:59 Gestation (the "default" exploration theme that plays in the beginning)
-- 12:36 Geothermal (this plays on the entrance of the first major boss, where the plot too begins branching significantly: it decides what happens to miss Curly Brace.)
-- 14:26 Pulse (demonstrating the detuned instruments; waveform is of "safety" though)
-- 14:55 Fanfare 1 (acquiring an item)

I do some tool-assisted voiceover in the video. I had fun doing that, not taking my cumbersome pronunciation too seriously. I hope you won't, either. All is fair in teaching memorably. Well, I cannot take it too seriously. English is very difficult to pronounce for me, very difficult sequences of consonants and sometimes hard to choose the right phonemes to begin with. In Finnish, my native language, having more than two consonants in a row is very rare, and even when there are two, the possible combinations are very few. I have been training my English pronounciation for years, but the entire language is a tongue-twister for someone with this background. I have found Hebrew and Japanese to be significantly easier.
Anyway, does anyone want to contribute closed-captions?

Quick illustrations of each modulation method (each generates 8-bit mono PCM audio):
No modulation example code:
(add relevant #includes)
int main() { float p=0;for(;;) { float a = sin(p); putc(128 + 100*a); p += 0.1; } }
Amplitude modulation is like this: The level of one signal is multiplied by the level of the second signal. Example code below:
int main() { float p=0,p2=0;for(;;) { float a = sin(p), b = sin(p2); putc(128 + 100*a*b); p += 0.1; p2 += 0.01;} }
Frequency modulation is like this: The frequency of one signal is changed by the level of the second signal. Example code below:
int main() { float p=0,p2=0;for(;;) { float a = sin(p), b = sin(p2); putc(128 + 100*a); p += 0.1 * (1+b/9); p2 += 0.1;} }

Комментарии

Информация по комментариям в разработке