BasicC/Dźwięk
Do odtwarzania dźwięków używana jest własna biblioteka BasicSND, domyślnie załączana w BasicSDL, lub SDL_mixer. Obsługuje dowolną liczbę jednocześnie odtwarzanych kanałów 16-bitowego dźwięku stereo, domyślnie 16 dla BasicSND i 8 w SDL_mixer, + jeden kanał muzyczny. SDL_mixer wykorzystuje popularne biblioteki FLAC, MikMod MOD, Timidity MIDI, Ogg Vorbis i SMPEG MP3. BasicSND obsługuje formaty WAV, OGG, MOD i MIDI, posiada ponadto możliwość zmiany częstotliwości dźwięków, odtwarzania dźwięków MIDI, generator dźwięków syntezowanych i prosty sekwencer. Można też użyć BASSND - uproszczonej wersji BasicSND - pozbawionej obsługi muzyki i MIDI, jest za to mniejsza i troszkę szybsza, obsługuje WAV, OGG i MOD.
Częstotliwość odtwarzania domyślnie wynosi 22050 Hz, do tej częstotliwości konwertowane są dźwięki podczas ładowania do pamięci. Można ją zmienić modyfikując w pliku BasicSDL.h zapis #define SOUNDFREQUENCY 22050
lub dodając go do programu przed #include "BasicSDL.h"
. Przy odtwarzaniu sekwencji dźwięków zaleca się, by częstotliwość była wielokrotnością SNDSpec.samples.
Dźwięk a muzyka
Dźwięk jest w całości zapisany w pamięci w postaci nieskompresowanej. Na raz można odtworzyć tyle dźwięków - ile jest kanałów dźwiękowych. Muzyka jest zapamiętywana w określonym formacie lub odczytywana na bieżąco z pliku i podczas odtwarzania dekodowana "w locie" fragmentami. Jednocześnie obsługiwana jest tylko jedna muzyka.
BasicSND
edytujJest podstawowym mikserem dźwięków BasicC zapisanym w krótkim pliku BasicSND.h, który jest załączany w BasicSDL.h. Po drobnych zmianach może być też używany bezpośrednio w C + SDL. Domyślnie obsługuje 16 wirtualnych kanałów dźwiękowych, ilość tę można zmienić, podobnie jak częstotliwość, zmieniając wartość stałej SNDCHANNELS: #define SNDCHANNELS 16
w pliku BasicSND.h lub własnym programie.
"Kanał" jest strukturą typu struct SNDChan o polach:
Uint8 play; stan odtwarzania: wartość 0 oznacza brak odtwarzania na kanale, 1 - odtwarzanie, 2 - dźwięk MIDI, 3 - przerwa pomiędzy dźwiękami, gdy odtwarzana jest sekwencja dźwięków
SNDSample*spl; wskaźnik na dźwięk przypisany do kanału, 0 (NULL) gdy brak przypisania
Uint8*data; wskaźnik na dane dźwięku do odtwarzania na kanale, 0 dla MIDI
Uint32 dpos; aktualny nr bajtu danych odtwarzanego dźwięku, powinien być wielokrotnością 4, ponieważ pojedyńcza próbka składa się z 4 bajtów (po 2 bajty na kanał lewy i prawy)
Uint32 dlen; zawiera ilość bajtów danych dźwięku
Uint8 loop; ilość odtworzeń dźwięku, 0 - powtarzanie w nieskończoność
double(*waveform)(double); wskaźnik na funkcję generującą dźwięk, domyślnie sin
float freq; częstotliwość generowanego dźwięku lub mnożnik częstotliwości dla SNDSample lub nr nuty MIDI
float gainL; głośność kanału lewego, powinna mieścić się w przedziale 0-1
float gainR; głośność kanału prawego
Uint32 duration; "długość" dźwięku w bajtach, wielokrotność 4
Uint32 attack; "czas" narastania dźwięku w bajtach do osiągnięcia danej głośności
Uint32 release; "czas" zakończenia dźwięku, w którym głośność opada do 0
float*seq; wskaźnik na tablicę zawierającą sekwencję dźwięków (array[freq...,-duration...])
Uint16 spos; indeks tablicy seq wskazujący kolejny dźwięk
Uint16 slen; ilość elementów w tablicu seq
Struktury te są przechowywane w tablicy SNDChan.
Odtwarzane mogą być dźwięki próbkowane (np. typu .wav - odczytane z pliku), których dane wskazuje SNDChan[c].data (c - nr kanału), lub generowane przez funkcję wskazywaną przez SNDChan[c].waveform, jeśli data wskazuje na NULL. Prócz .wav obsługiwany jest format .MOD, poprzez bibliotekę micromod.h, oraz .OGG, poprzez BasicOGG.h, która jest okrojoną biblioteką STB_vorbis. Jeśli nie korzystamy z tych formatów można wyłączyć te biblioteki poprzez usunięcie lub skomentowanie w pliku BasicSND.h zapisów #include "BasicOGG.h"
i/lub #include "micromod.h"
. MOD może być ładowany również jako muzyka.
Dźwięki przechowywane są w strukturach typu SNDSample o polach: Uint8*data; - dane próbek dźwiękowych, Uint32 len; - długość tych danych w bajtach, float vol; - głośność 0-1. Przy deklaracji zmiennych tego typu powinno się zainicjować ich pola zerami, np. SNDSample nazwa_zmiennej={0};
W zmiennej strukturalnej SNDSpec typu SDL_AudioSpec zawarta jest specyfikacja próbek dźwiękowych:
SNDSpec.freq = SOUNDFREQUENCY; częstotliwość, domyślnie 22050
SNDSpec.format = AUDIO_S16SYS; format - 16 bitów ze znakiem (Sint16)
SNDSpec.channels = 2; ilość kanałów wyjściowych: 2 (stereo)
SNDSpec.samples = 500; ilość próbek przetwarzanych "na raz" przez funkcję SNDMixe. Wg dokumentacji SDL powinna być potęgą 2, ale by dokładnie odtwarzać sekwencje - powinna być dzielnikiem SOUNDFREQUENCY
SNDSpec.callback = SNDMixe; funkcja miksująca dźwięki, wywoływana automatycznie, okresowo
SNDSpec.userdata = NULL; wskaźnik na dane "użytkownika", aktualnie nieużywane.
Obsługiwana jest muzyka w formatach MOD oraz MID (pliki MI*, również pliki KAR - po zmianie końcówki na .MID). Do odtwarzania MIDI w systemach Windows wykorzystywana jest biblioteka windows.h + mmsystem.h (MCI) załączana w BasicSDL.h, w Linux fluidsynth.h załączana w BasicSND.h. libfluidsynth musi być zainstalowane wraz z libfluidsynth-dev i fontami dźwiękowymi sf2 w /usr/share/sounds/sf2/default-GM.sf2 (można to zmienic w pliku BasicSND.h w funkcji do_loadmusic). Jeśli nie wykorzystujemy funkcji danej biblioteki - najlepiej ją odłączyć.
Dane muzyki zawiera zmienna SNDMusic typu struct SNDMusic o polach:
Uint8 typ; wartość 0 - brak muzyki, 1 - MIDI MCI, 2. MIDI fluidsynth, 3 - wstrzymane odtwarzanie, 4 - MOD, 5 - MOD wtrzymane
void*data; wskaźnik na dane wczytane z pliku MOD, nie wykorzystywane w MIDI.
Do odtwarzania dźwięków MIDI wymagana jest biblioteka fluidsynth.h, która jest domyślnie załączana w BasicSND.h pod Linuksem.
Można korzystać bezpośrednio z funkcji danej biblioteki. W MCI wykorzystywana jest funkcja mciSendString, muzyka posiada alias m. W Fluidsynth wykorzystywane są zmienne fluid_player, fluid_synth, fluid_settings, fluid_audio.
System dźwiękowy jest inicjowany automatycznie komendą SDLOpen i zamykany przez SDLQuit. Jeśli nie chcemy otwierać innych elementów SDL - możemy inicjować komendą init_soundsystem();
, a zamknąć poprzez quit_soundsystem();
. Inicjacja, oprócz otwarcia urządzenia dźwiękowego SDL z odpowiednimi parametrami zapisanymi w SNDSpec, powoduje, dla wszystkich kanałów: wywołanie Wave(kanał,sin,0,0), ustawienie głośności na 1 i wyzerowanie pozostałych parametrów. Przed zamknięciem programu należy dodatkowo usunąć wszystkie używane zmienne typu SNDSample komendą DeleteSound.
Odtwarzanie wstrzymujemy komendą SDL_PauseAudio(1);
, przywrócenie odtwarzania: SDL_PauseAudio(0);
. Nie dotyczy to muzyki MIDI MCI odtwarzanej przez system Windows.
Komendy Basic:
ChannelPanning(channel,left,right)
edytujUstawia głośność (powinna mieścić się w zakresie 0-1) lewego (left) i prawego (right) kanału o nr channel. Nie działa dla MIDI.
DeleteMusic
edytujZatrzymuje muzykę i usuwa dane.
DeleteSound(S)
edytujUsuwa dane dźwięku S i ustawia wskaźnik danych na NULL. S jest zmienną typu SNDSample.
FluidOpen
edytujOtwiera syntezator fluid_synth i przypisuje do niego sterownik fluid_audio (domyślnie ALSA). Jest to wymagane do odtwarzania dźwięków MIDI. Domyślnie fluidsynth jest też automatycznie otwierany w Linuksie komendą LoadMusic wywoływaną dla pliku MIDI, wtedy korzysta ze sterownika SDL, otwierany jest też fluid_player. Fluidsynth nie może być jednocześnie otwarty dla odtwarzania dźwięków MIDI i muzyki MIDI, fluidsynth jest zamykany komendą FluidClose lub DeleteMusic (jeśli załadowana jest muzyka MIDI).
FluidClose
edytujZamyka fluidsynth. Wywołuje go też komenda DeleteMusic, jeśli muzyka korzysta z fluidsynth.
MidiChannelBallance(c,b)
edytujUstawia balans głośników dla kanału MIDI. Kanały numerowane są od 0 do 15, więc np. kanał 10 MIDI ma nr c=9. b przyjmuje wartości 0-127.
MidiChannelExpire(c)
edytujWygasza dźwięki MIDI (all notes off) na kanale c.
MidiChannelVol(c,v)
edytujUstawia głośność MIDI kanału c, v: 0-127
MidiSeq(c,m,l)
edytujUruchamia odtwarzanie sekwencji dźwięków MIDI na kanale c zapisaną w tablicy m (patrz komendy PlaySeq i Sound Seq) l-krotnie (dla 0 w nieskończoność). Wszystkie dźwięki akordów MIDI odtwarzane są na jednym kanale. Wywołuje procedurę do_midiseq(int c,float*seq,int spos,int slen,Uint8 loop);
MidiSound(c,k,d,l)
edytujOdtwarza dźwięk MIDI k (2-127, np. 60 dla C4) na kanale c (0-15) o długości d (w sekundach) l razy (lub w nieskończoność dla 0). Kanał 9 przypisany jest do perkusji.
MidiVoice(c,v)
edytujOkreśla instrument v MIDI dla kanału c. v jest numerem MIDI od 1 do 128, pomimo, że w fluidsynth numeracja instrumentów, podobnie jak kanałów, zaczyna się od 0. W przypadku perkusji podajemy kanał 9 i instrument 1.
HaltChannel(c)
edytujZatrzymuje odtwarzanie na kanale c i zwalnia pamięć danych dźwiękowych przypisanych do kanału c.
LoadMusic(FM)
edytujŁaduje plik muzyczny o nazwie FM i przypisuje go do zmiennej SNDMusic. Zmienna jest zadeklarowana w BasicSND. Dla MIDI MCI nazwa pliku nie może przekraczać 114 znaków.
LoadSound(S,FS)
edytujŁaduje dźwięk z pliku o nazwie FS i przypisuje do zmiennej S.
Zmienna jest typu SNDSample i musi być wcześniej zadeklarowana.
Wywołuje funkcję do_loadsound(FS,&S,1);
, którą można wywołać bezpośrednio pamiętając o umieszczeniu średnika na końcu oraz znaku & przed zmienną S. Ostatnim parametrem funkcji jest mnożnik częstotliwości - 1 oznacza zachowanie oryginalnej wysokości dźwięku, a np. 2 - dźwięk będzie odtwarzany z 2x większą wysokością.
Jeśli wskaźnik S.data był różny od NULL - pamięć danych S zostaje zwolniona (jeśli danych nie było - wystąpi błąd) przed załadowaniem nowych danych.
MusicVolume(volume)
edytujUstawia głośność muzyki na volume 0-1. Wpływa też na głośność dźwięków MIDI fluidsynth. Nie działa dla MIDI MCI w Windows.
MulSoundFreq(S,SS,mul)
edytujKonwertuje dźwięk SS typu SNDSample mnożąc jego częstotliwość (wysokość) przez mul, skonwertowany dźwięk przypisuje do S. Zmienna S jest typu SNDSample i musi być wcześniej zadeklarowana, a jej wskaźnik danych powinien wynosić NULL. Gdy w miejsce S podamy SS - do SS zostaną przydzielone nowe dane dźwiękowe, a stare zostaną zwolnione.
Komenda wywołuje funkcję SNDConvertFrequency(Uint8*sdata,Uint32 slen,SDL_AudioSpec Spec,Uint8**ddata,float mul)
, parametry oznaczają:
*sdata - wskaźnik na źródłowe dane dźwiękowe (do skonwertowania)
slen - długość danych sdata w bajtach
Spec - specyfikacja danych źródłowych
**ddata - wskaźnik na wskaźnik danych wyjściowych dźwięku, czyli jeśli np. *data jest zmienną wskaźnikową na dane - w wywołaniu funkcji wpisujemy &data.
mul - mnożnik częstotliwości danych źródłowych
Po wykonaniu tej funkcji zwrócona zostanie wartość typu Uint32 zawierająca długość skonwertowanych danych, a zmienna odpowiadająca parametrowi ddata będzie zawierała wskaźnik na skonwertowane dane do formatu określonego w SNDSpec, przy czym częstotliwość źródłowa będzie przemnożona przez mul.
UWAGA! Może się zdarzyć, np. jeśli przy deklaracji zmiennej nie zainicjujemy jej wartością NULL, że sdata i ddata będą wskazywały ten sam adres, co spowoduje zwolnienie wcześniejszych danych, a co nie musi być zgodne z oczekiwaniami programisty.
PauseChannel(channel)
edytujWstrzymuje odtwarzanie na kanale o nr channel do momentu wywołania ResumeChannel lub innej komendy rozpoczynającej odtwarzanie.
PauseMusic
edytujWstrzymuje odtwarzanie muzyki.
PlayMusic(loops)
edytujOdtwarza muzykę loops razy. Gdy loops=0 powtarza w nieskończoność. Dla MIDI MCI w Windows nie można odtwarzać w pętli, a po zakończeniu odtwarzania należy "przewinąć" na początek, jeśli chcemy odtworzyć ponownie. W starszych wersjach Fluidsynth w Linux po zakończeniu odtwarzania raczej nie można odtworzyć ponownie, należy znów załadować plik muzyczny komendą LoadMusic.
PlayingMusic
edytujZwraca 1 jeśli gra muzyka, 0 jeśli nie.
PlaySound(channel,S,pitch,loops)
edytujOdtwórz dźwięk S na kanale channel (gdy <0 odtwarza na pierwszym wolnym).
pitch jest mnożnikiem częstotliwości odtwarzania (1 - bez zmiany).
loops oznacza ile razy zostanie odtworzony dźwięk (maksymalnie 255 lub w nieskończoność, dla 0), po kropce dziesiętnej można podać jaka część dźwięku ma być odtwarzana, np.: 1 - cały dźwięk 1 raz, 2.5 - połowa dźwięku 2 razy.
Jeśli pitch=1 - SNDChan[channel].data=S.data, w przeciwnym razie wykonywana jest konwersja dźwięku S i tworzone są dane dźwięku ze zmienioną częstotliwością, na które wskazuje SNDChan[channel].data, może to powodować opóźnienie odtwarzania. Po zakończeniu odtwarzania, lub gdy ponownie wywołane zostanie PlaySound lub Sound dla tego kanału, pamięć tych danych jest zwalniana.
Za pomocą komendy Wave można ustawić czas narastania i opadania głośności dźwięku na danym kanale.
PlaySeq(c,s,mel,l)
edytujOdtwarza sekwencję dźwięków s typu SNDSample określoną w tablicy mel na kanale c l razy (lub w nieskończoność dla 0).
mel jest tablicą liczb rzeczywistych typu float, zawierającą wysokości i długości (w sekundach) dźwięków. Długość poprzedzamy znakiem -. Można odtwarzać akordy podając kolejno wysokości dźwięków i na końcu -długość akordu. Poszczególne dźwięki akordów odtwarzane są na kolejnych kanałach poczynając od c. Przyjęto, że oryginalna wysokość wynosi 256 Hz, co odpowiada dźwiękowi C w stroju A 432, więc jeśli wysokość w tablicy mel wynosi np. 384 Hz - dźwięk będzie konwertowany z mnożnikiem częstotliwości = 384/256, czyli wywołana zostanie komenda PlaySound z parametrem pitch=1.5. Jeśli częstotliwość = 0 - nastąpi pauza o podanej długości. Długość dźwięku może nie być dokładna, im większa wartość SNDSpec.freq MOD SNDSpec.samples - tym większa niedokładność.
ResumeChannel(channel)
edytujWznawia odtwarzanie na kanale channel.
SetMusicPosition(position)
edytuj"Przewija" muzykę do pozycji position, 0 - początek.
Sound(c,f,d,l)
edytujOdtwarza dźwięk syntezowany na kanale c z częstotliwością f o długości d (w sekundach) l razy (lub w nieskończoność dla 0). Parametry dźwięku określa się komendą Wave. Częstotliwość f jest tutaj rzeczywistą częstotliwością dźwięku, powinna być >1, 0 oznacza pauzę.
SNDChanFree(c)
edytujKomenda zwalnia pamięć danych dźwiękowych przypisanych do kanału c jeśli był na nim odtwarzany dźwięk o zmodyfikowanej częstotliwości. Nie zaleca się jej używania, bezpieczniejsze jest użycie komendy HaltChannel.
SoundSeq(c,m,l)
edytujOdpowiednik komendy PlaySeq dla dźwięków syntezowanych. c - kanał, m - tablica melodyczna, l - ilość odtworzeń.
Komendy PlaySeq i SoundSeq wywołują procedurę do_sequence(int c,void*snd,float*seq,int spos,int slen,Uint8 loop); obliczając długość tablicy za pomocą sizeof m/sizeof(float)
. Aby to działało, m musi być tablicą, nie samym wskaźnikiem. Parametry funkcji:
c - nr kanału
*snd - wskaźnik na strukturę typu SNDSample zawierającą próbki dźwiękowe lub 0 (NULL), jeśli dźwięk ma być generowany syntetycznie zdefiniowany komendą Wave.
seq - tablica melodyczna zawierająca liczby typu float oznaczające wysokości i -długość dźwięków, np.: mel[]={220,-1,262,300,-0.5} oznacza, że ma zostać odtworzony dźwięk 220 Hz przez 1 s, następnie 262 Hz i 300 Hz przez 0.5 s.
spos - indeks tablicy wskazujący na pierwszy dźwięk do odtworzenia, poczynając od 0
slen - długość tablicy
loop - ilość odtworzeń sekwencji lub 0 dla powtarzania w nieskończoność
Procedurę do_sequence można wywoływać bezpośrednio pamiętając o średniku na końcu i znaku & przed zmienną snd.
SoundVolume(S,volume)
edytujUstawia głośność dźwieku S na volume 0-1.
Wave(c,waveform,attack,release)
edytujUstawia parametry generatora dźwięku dla kanału c:
waveform - funkcja generująca wartości fali dźwiękowej, domyślnie sin. Może to być dowolna funkcja przyjmująca argument typu double i zwracająca wartość typu double z zakresu -1 do 1. Dla obliczenia częstotliwości dźwięku przyjmuje się, że jest to funkcja o okresie 2π - dla BASSNDm lub 6 - dla BasicSND. Oprócz sin zdefiniowane są funkcje generujące typowe fale: WavTooth - piłokształtna, WavTriang - trójkątna, WavSqr - prostokątna, WavNoise - szum, WavRound - okrągła.
attack - czas (s) narastania dźwięku do zadanej głośności
release - czas opadania dźwięku
Dwa ostatnie parametry działają również dla dźwięków typu SNDSample.
Głośność (maksymalny poziom fali) generowanego dźwięku wynosi 8192 i zapisana jest wewnątrz funkcji do_sound w pliku BasicSND.h lub SNDMixe w BASSND.h. Można zmienić tę wartość. Suma wartości dla wszystkich odtwarzanych na raz dźwięków nie powinna przekraczać 32000. Dźwięki generowane przez BASSND są czystsze niż w BasicSND, za to w BasicSND można wpływać na częstotliwość szumu generowanego przez WavNoise.
Przykład melodii granej losowymi dźwiękami generowanymi:
#define SOUNDFREQUENCY 20000
#include "BasicSDL.h"
double sinsqr(double a){return sin(a+WavSqr(a));}
double sintri(double a){return sin(a+WavTriang(a));}
double HZ(int w){
if(w<3)return(128+w*16);
else return(168+(w-3)*24);
}
MAIN
SDLOpen(0)
//FluidOpen
float bas[]={128,-0.125,64,-0.125,128,-0.125,256,-0.125};
float per[]={36,-.05,0,-.45,40,-.05,0,-.45,36,-.05,0,-.45,40,-.05,0,-.2,39,-.25};
Wave(0,sinsqr,0.1,1)
Wave(2,sintri,.5,.75)
ChannelPanning(2,.5,.5)
Wave(3,sintri,.5,.75)
ChannelPanning(3,.5,.5)
Wave(4,sintri,.5,.75)
ChannelPanning(4,.5,.5)
Wave(5,WavNoise,0,0.25)
ChannelPanning(5,.25,.25)
int t=0,f,a,b;
float r=1,rc=1;
Do
For(f,0,15)
if(f%4==0)ChannelPanning(0,.2,0.4)
else if(f%2==0)ChannelPanning(0,0.4,.2)
ChannelPanning(1,r,1-r)
if(Abs(r-rc)<.1)rc=Rnd;
r+=.1*(rc>r)-.1*(rc<r);
If(f==0)
if(t>3)SoundSeq(5,per,1)
// if(t>3)MidiSeq(9,per,1)
a=Random(3);if(a)a+=2;
bas[0]=bas[4]=HZ(a);bas[2]=bas[0]/2;bas[6]=bas[0]*2;
if(t>7)SoundSeq(0,bas,0)
Sound(2,HZ(a),2,1)
Sound(3,HZ(a+2),2,1)
Sound(4,HZ((a<1)? a+4:a-3),2,1)
EndIf
b=Random(7-a);//b+=(b==1)*6;
if(t>15)Sound(1,2*HZ(a+b),1,1)
Pause(125)
Next
t++;
Loop
SDLQuit
ENDMAIN
Odtwarzanie sekwencji MIDI:
#define SOUNDFREQUENCY 50000
#include "BasicSDL.h"
#define C 60
#define CI 61
#define D 62
#define DI 63
#define E 64
#define F 65
#define FI 66
#define G 67
#define GI 68
#define A 69
#define AI 70
#define H 71
MAIN
SDLOpen(0)
float m1[]={76,.125, 75,.125, 76,.125, 75,.125, 76,.125, 71,.125, 74,.125, 72,.125, A,.25, 0,.125, C,.125, E,.125, A,.125, H,.25, 0,.125, E,.125, GI,.125, H,.125, C+12,.25, 0,.125, E,.125, E+12,.125, DI+12,.125, E+12,.125, DI+12,.125, E+12,.125, H,.125, D+12,.125, C+12,.125, A,.25, 0,.125, C,.125, E,.125, A,.125, H,.25, 0,.125, E,.125, C+12,.125, H,.125, A,.5};
float b1[]={0,1, A-24,.125, E-12,.125, A-12,.125, 0,.375, E-24,.125, E-12,.125, GI-12,.125, 0,.375, A-24,.125, E-12,.125, A-12,.125, 0,.375, 0,.75,
A-24,.125, E-12,.125, A-12,.125, 0,.375, E-24,.125, E-12,.125, GI-12,.125, 0,.375, A-24,.125, E-12,.125, A-12,.125, 0,.125};
float m12[]={H,.125, C+12,.125, D+12,.125,};
float m2[]={E+12,.375, G,.125, F+12,.125, E+12,.125, D+12,.375, F,.125, E+12,.125, D+12,.125,
C+12,.375, E,.125, D+12,.125, C+12,.125, H,.25, 0,.125, E,.125, E+12,.125, 0,.25, E+12,.125, E+24,.125, 0,.25, DI+12,.125, E+12,.25, 0,.125, DI+12,.125, E+12,.125, DI+12,.125, E+12,.125, DI+12,.125, E+12,.125, H,.125, D+12,.125, C+12,.125, A,.25, 0,.125, C,.125, E,.125, A,.125,
H,.25, 0,.125, E,.125, GI,.125, H,.125, C+12,.25, 0,.125, E,.125, E+12,.125, DI+12,.125, E+12,.125, DI+12,.125, E+12,.125, H,.125, D+12,.125, C+12,.125,
A,.25, 0,.125, C,.125, E,.125, A,.125, H,.25, 0,.125, E,.125, C+12,.125, H,.125, A,.25, 0,.125, H,.125, C+12,.125, D+12,.125};
float b2[]={C-12,.125, G-12,.125, C,.125, 0,.375, G-24,.125, G-12,.125, H-12,.125, 0,.375,
A-24,.125, E-12,.125, A-12,.125, 0,.375, E-24,.125, E-12,.125, E,.125, 0,.25, E,.125, E+12,.125, 0,.25, DI+12,.125, E+12,.125, 0,.25, DI+12,.125, E+12,.125, 0,1.125,
A-24,.125, E-12,.125, A-12,.125, 0,.375, E-24,.125, E-12,.125, GI-12,.125, 0,.375, A-24,.125, E-12,.125, A-12,.125, 0,1.125,
A-24,.125, E-12,.125, A-12,.125, 0,.375, E-24,.125, E-12,.125, GI-12,.125, 0,.375, A-24,.125, E-12,.125, A-12,.125, 0,.375};
FluidOpen
MidiSeq(0,1,m1,.2)
MidiSeq(1,1,b1,2)
Pause(23750)
MidiSeq(0,6,m12,1)
Pause(750)
MidiSeq(0,12,m2,0)
MidiSeq(1,40,b2,0)
Do Loop
SDLQuit
ENDMAIN
SDL_mixer
edytujDokładniejszy opis znajduje się w dokumentacji SDL2_mixer, poniżej wymienione są jedynie komendy BasicC wykorzystujące SDL_mixer. Aby używać SDL_mixer należy w pliku BasicSDL.h odłączyć bibliotekę BasicSND.h i załączyć SDL_mixer.h.
Uwaga ! Niektóre komendy dla kanału, np. ChannelPanning, mogą nie działać jeśli na kanale odtwarzany jest dźwięk, należy go wcześniej wyłączyć komendą HaltChannel.
ChannelDistance(channel,distance)
edytujWłącza symulację odległości distance (0-255) dla kanału channel (tłumienie głośności).
ChannelPanning(channel,left,right)
edytujUstawia głośność (0-255) lewego i prawego kanału dla kanału o nr channel.
ChannelPosition(channel,angle,distance)
edytujWłącza symulację położenia głośnika dla kanału channel w odległości distance i kierunku angle (0 - na wprost, 90 - po prawej...). 0,0 wyłącza efekt.
LoadMusic(FM)
edytujŁaduje plik muzyczny o nazwie FM i przypisuje go do zmiennej MixMusic. Zmienna jest zadeklarowana w BasicSDL.
PlayMusic(loops)
edytujOdtwarza muzykę loops razy. Gdy loops=-1 powtarza w nieskończoność.
PlayingMusic
edytujZwraca 1 jeśli gra muzyka, 0 jeśli nie.
FadeInMusic(loops,ms)
edytujOdtwarza muzykę loops razy narastającą w pierwszym odtworzeniu przez ms milisekund.
FadeOutMusic(ms)
edytujRozpoczyna wyciszanie muzyki trwające ms milisekund.
MusicVolume(volume)
edytujUstawia głośność muzyki na volume. Maksymalnie 128, dla -1 podaje aktualna głośność.
PauseMusic
edytujWstrzymuje odtwarzanie muzyki.
PausedMusic
edytujZwraca 1 jeśli muzyka jest wstrzymana, 0 jeśli nie.
ResumeMusic
edytujKontynuuje odtwarzanie wstrzymanej muzyki.
SetMusicPosition(position)
edytuj"Przewija" muzykę do pozycji position, dla MOD jest to nr fragmentu, OGG - sekundy od początku, MP3 - sekundy od bieżącej pozycji
HaltMusic
edytujZatrzymuje odtwarzanie muzyki.
LoadSound(S,FS)
edytujŁaduje dźwięk z pliku o nazwie FS i przypisuje do zmiennej S. Zmienna jest typu Mix_Chunk* i musi być wcześniej zadeklarowana, np. Mix_Chunk* dzwiek=NULL;
MulSoundFreq(S,SS,mul)
edytujKonwertuje dźwięk SS mnożąc jego częstotliwość (wysokość) przez mul, skonwertowany dźwięk przypisuje do S. Zmienna S jest typu Mix_Chunk* i musi być wcześniej zadeklarowana.
PlaySound(S,channel,loops)
edytujOdtwórz dźwięk S na kanale channel (gdy -1 odtwarza na pierwszym wolnym) loops+1 razy lub w nieskończoność dla -1.
PlaySoundTimed(S,channel,loops,ticks)
edytujJak powyżej, ale tylko przez ticks milisekund lub do końca jeśli ticks=-1.
PlaySoundFadeIn(S,channel,loops,ms)
edytujJak PlaySound, ale głośność narasta przez ms milisekund.
PlaySoundFadeInTimed(S,channel,loops,ms,ticks)
edytujJak powyżej, ale gra tylko przez ticks milisekund.
SoundVolume(S,volume)
edytujUstawia głośność dźwięku S na volume (0-128).
DeleteSound(S)
edytujUsuwa dźwięk S i zwalnia pamięć.
ChannelVolume(channel,volume)
edytujUstawia głośność kanału channel (lub wszystkich, jeśli =-1) na volume.
PauseChannel(channel)
edytujWstrzymuje odtwarzanie na kanale channel.
PausedChannel(channel)
edytujZwraca 1 jeśli kanał channel jesst wstrzymany, 0 jeśli nie.
ResumeChannel(channel)
edytujWznawia odtwarzanie na kanale channel.
HaltChannel(channel)
edytujZatrzymuje odtwarzanie na kanale channel lub wszystkich kanałów dla -1.
ExpireChannel(channel,ticks)
edytujJak wyżej ale po ticks milisekundach.
FadeOutChannel(channel,ms)
edytujWycisza kanał chanel, lub wszystkie dla -1, przez ms milisekund.
PlayingChannel(channel)
edytujZwraca 1 jeśli gra kanał channel, 0 jeśli nie, ilość grających kanałów dla -1.
ReverseStereo(channel,flip)
edytujZamiana miejscami kanału lewego i prawego dla kanału channel. flip=0 - brak zamiany, flip>0 - zamiana