Blame simple/x11/lib/snd.c

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