|
Ivan Mahonin |
7d8000 |
#ifdef WITHSOUND
|
|
Ivan Mahonin |
7d8000 |
|
|
Ivan Mahonin |
7d8000 |
#include "snd.h"
|
|
Ivan Mahonin |
7d8000 |
|
|
Ivan Mahonin |
7d8000 |
|
|
Ivan Mahonin |
7d8000 |
ALCdevice *adev;
|
|
Ivan Mahonin |
7d8000 |
ALCcontext *actx;
|
|
Ivan Mahonin |
7d8000 |
|
|
Ivan Mahonin |
7d8000 |
|
|
Ivan Mahonin |
7d8000 |
void sndInit() {
|
|
Ivan Mahonin |
7d8000 |
if (adev) return;
|
|
Ivan Mahonin |
7d8000 |
adev = alcOpenDevice(NULL);
|
|
Ivan Mahonin |
7d8000 |
if (!adev) LOGWRN("sndInit: cannot open device");
|
|
Ivan Mahonin |
7d8000 |
actx = alcCreateContext(adev, NULL);
|
|
Ivan Mahonin |
7d8000 |
if (!actx) LOGWRN("sndInit: cannot create context");
|
|
Ivan Mahonin |
7d8000 |
alcMakeContextCurrent(actx);
|
|
Ivan Mahonin |
7d8000 |
}
|
|
Ivan Mahonin |
7d8000 |
|
|
Ivan Mahonin |
7d8000 |
|
|
Ivan Mahonin |
7d8000 |
void sndDeinit() {
|
|
Ivan Mahonin |
7d8000 |
alcMakeContextCurrent(NULL);
|
|
Ivan Mahonin |
7d8000 |
if (actx) alcDestroyContext(actx);
|
|
Ivan Mahonin |
7d8000 |
if (adev) alcCloseDevice(adev);
|
|
Ivan Mahonin |
7d8000 |
actx = NULL;
|
|
Ivan Mahonin |
7d8000 |
adev = NULL;
|
|
Ivan Mahonin |
7d8000 |
}
|
|
Ivan Mahonin |
7d8000 |
|
|
Ivan Mahonin |
7d8000 |
|
|
Ivan Mahonin |
7d8000 |
void sndFree(Sound *snd) {
|
|
Ivan Mahonin |
7d8000 |
if (!snd) return;
|
|
Ivan Mahonin |
7d8000 |
if (snd->src) alDeleteSources(1, &snd->src);
|
|
Ivan Mahonin |
7d8000 |
if (snd->buf) alDeleteBuffers(1, &snd->buf);
|
|
Ivan Mahonin |
7d8000 |
*snd = (Sound){};
|
|
Ivan Mahonin |
7d8000 |
}
|
|
Ivan Mahonin |
7d8000 |
|
|
Ivan Mahonin |
7d8000 |
|
|
Ivan Mahonin |
7d8000 |
Sound sndGen(int rate, int freq, int samples) {
|
|
Ivan Mahonin |
7d8000 |
Sound snd = {};
|
|
Ivan Mahonin |
7d8000 |
if (rate <= 0 || freq <= 0 || samples <= 0)
|
|
Ivan Mahonin |
7d8000 |
return snd;
|
|
Ivan Mahonin |
7d8000 |
|
|
Ivan Mahonin |
7d8000 |
short *buf = malloc(samples*sizeof(*buf));
|
|
Ivan Mahonin |
7d8000 |
if (!buf)
|
|
Ivan Mahonin |
7d8000 |
return LOGERR("sndGen: cannot alocate memory for samples (%d)", samples), (Sound){};
|
|
Ivan Mahonin |
7d8000 |
for(int i = 0; i < samples; ++i)
|
|
Ivan Mahonin |
7d8000 |
buf[i] = (int)(32760*sin(2*3.14159*i*freq/rate));
|
|
Ivan Mahonin |
7d8000 |
|
|
Ivan Mahonin |
7d8000 |
alGenBuffers(1, &snd.buf);
|
|
Ivan Mahonin |
7d8000 |
alBufferData(snd.buf, AL_FORMAT_MONO16, buf, sizeof(*buf)*samples, rate);
|
|
Ivan Mahonin |
7d8000 |
free(buf);
|
|
Ivan Mahonin |
7d8000 |
|
|
Ivan Mahonin |
7d8000 |
alGenSources(1, &snd.src);
|
|
Ivan Mahonin |
7d8000 |
alSourcei(snd.src, AL_BUFFER, snd.buf);
|
|
Ivan Mahonin |
7d8000 |
return snd;
|
|
Ivan Mahonin |
7d8000 |
}
|
|
Ivan Mahonin |
7d8000 |
|
|
Ivan Mahonin |
7d8000 |
|
|
Ivan Mahonin |
7d8000 |
Sound sndLoadRaw(const char *filename, int rate) {
|
|
Ivan Mahonin |
7d8000 |
LOGDBG("sndLoadRaw: open: %s", filename);
|
|
Ivan Mahonin |
7d8000 |
FILE *f = fopen(filename, "rb");
|
|
Ivan Mahonin |
7d8000 |
if (!f)
|
|
Ivan Mahonin |
7d8000 |
return LOGERR("sndLoadRaw: cannot open file for read: %s", filename), (Sound){};
|
|
Ivan Mahonin |
7d8000 |
|
|
Ivan Mahonin |
7d8000 |
fseek(f, 0, SEEK_END);
|
|
Ivan Mahonin |
7d8000 |
int samples = ftell(f)/sizeof(short);
|
|
Ivan Mahonin |
7d8000 |
fseek(f, 0, SEEK_SET);
|
|
Ivan Mahonin |
7d8000 |
if (samples <= 0)
|
|
Ivan Mahonin |
7d8000 |
return LOGERR("sndLoadRaw: file is empty: %s", filename), (Sound){};
|
|
Ivan Mahonin |
7d8000 |
|
|
Ivan Mahonin |
7d8000 |
unsigned short *buf = (unsigned short*)malloc(sizeof(*buf)*samples);
|
|
Ivan Mahonin |
7d8000 |
if (!buf)
|
|
Ivan Mahonin |
7d8000 |
return LOGERR("sndGen: cannot alocate memory for samples (%d): %s", samples, filename), fclose(f), (Sound){};
|
|
Ivan Mahonin |
7d8000 |
|
|
Ivan Mahonin |
7d8000 |
for(int i = 0; i < samples; ++i) {
|
|
Ivan Mahonin |
7d8000 |
unsigned int a = fgetc(f), b = fgetc(f);
|
|
Ivan Mahonin |
7d8000 |
buf[i] = a | (b << 8);
|
|
Ivan Mahonin |
7d8000 |
}
|
|
Ivan Mahonin |
7d8000 |
fclose(f);
|
|
Ivan Mahonin |
7d8000 |
|
|
Ivan Mahonin |
7d8000 |
Sound snd = {};
|
|
Ivan Mahonin |
7d8000 |
|
|
Ivan Mahonin |
7d8000 |
alGenBuffers(1, &snd.buf);
|
|
Ivan Mahonin |
7d8000 |
alBufferData(snd.buf, AL_FORMAT_MONO16, buf, sizeof(*buf)*samples, rate);
|
|
Ivan Mahonin |
7d8000 |
free(buf);
|
|
Ivan Mahonin |
7d8000 |
|
|
Ivan Mahonin |
7d8000 |
alGenSources(1, &snd.src);
|
|
Ivan Mahonin |
7d8000 |
alSourcei(snd.src, AL_BUFFER, snd.buf);
|
|
Ivan Mahonin |
7d8000 |
return snd;
|
|
Ivan Mahonin |
7d8000 |
}
|
|
Ivan Mahonin |
7d8000 |
|
|
Ivan Mahonin |
7d8000 |
|
|
Ivan Mahonin |
7d8000 |
void sndPlay(Sound snd) {
|
|
Ivan Mahonin |
7d8000 |
LOGDBG("sndPlay: %d", snd.src);
|
|
Ivan Mahonin |
7d8000 |
alSourcePlay(snd.src);
|
|
Ivan Mahonin |
7d8000 |
}
|
|
Ivan Mahonin |
7d8000 |
|
|
Ivan Mahonin |
7d8000 |
#endif
|