packages feed

proteaaudio-0.10.0: cbits/proteaaudio_binding.cpp

#include <cstring>
#include <cstdlib>
#include "proteaaudio_binding.h"

// check if either PROTEAAUDIO_SDL or PROTEAAUDIO_RT is set
#if defined PROTEAAUDIO_SDL && defined PROTEAAUDIO_RT
#error "both PROTEAAUDIO_SDL and PROTEAAUDIO_RT is defined"
#endif

#if !defined PROTEAAUDIO_SDL && !defined PROTEAAUDIO_RT
#error "neither PROTEAAUDIO_SDL and PROTEAAUDIO_RT is defined"
#endif

// import backend api
#ifdef PROTEAAUDIO_RT
#include "proAudioRt.h"
#endif

#ifdef PROTEAAUDIO_SDL
#include "proAudioSdl.h"
#endif

using namespace std;

typedef struct {
  unsigned char * data;
  size_t size;
  size_t pos;
} MEM_FILE;

static size_t mem_fread ( void * ptr, size_t size, size_t count, FILE * stream_ ) {
  MEM_FILE * stream = (MEM_FILE*)stream_;
  if (!ptr || !stream) return 0;
  size_t remain = stream->size - stream->pos;
  if (remain <= 0) return 0;
  size_t cnt = size*count;
  size_t bytes = (cnt>remain)?remain:cnt;
  memcpy(ptr,&stream->data[stream->pos],bytes);
  stream->pos = stream->pos + bytes;
  return cnt;
}

static AudioSample* loadWavFromMemory(unsigned char * ptr, size_t len) {
  MEM_FILE* fp = new MEM_FILE();
  if (!fp) return 0;
  fp->data = ptr;
  fp->size = len;
  fp->pos = 0;
  AudioSample * pSample = AudioSample::readWav((FILE*)fp, mem_fread);
  delete fp;
  return pSample;
}

#define MINIMP3_IMPLEMENTATION
#include "minimp3_ex.h"

static AudioSample* loadMp3FromMemory(unsigned char * file_data_ptr, size_t file_data_len) {
  mp3dec_t mp3d;
  mp3dec_file_info_t info;
  memset(&info, 0, sizeof(info));

  if (mp3dec_load_buf(&mp3d, file_data_ptr, file_data_len, &info, 0, 0)) return 0;

  // convert to AudioSample:
  unsigned int size = info.samples*sizeof(short); // channels included, byte size = samples*sizeof(mp3d_sample_t)
  unsigned char * data = new unsigned char[size];
  if(!data) return 0;
  memcpy(data, info.buffer, size);
  free(info.buffer);
  return new AudioSample(data, size, info.channels, info.hz, 16);
}

extern "C" {
extern int stb_vorbis_decode_memory(unsigned char *mem, int len, int *channels, int* sample_rate, short **output);
};

static AudioSample* loadOggFromMemory(unsigned char * file_data_ptr, size_t file_data_len) {
  int channels, sampleRate;
  short *decoded;
  int len = stb_vorbis_decode_memory(file_data_ptr, file_data_len, &channels, &sampleRate, &decoded);
  if(len<0) return 0;
  // convert to AudioSample:
  unsigned int size = len*channels*sizeof(short);
  unsigned char * data = new unsigned char[size];
  if(!data) return 0;
  memcpy(data,decoded, size);
  free(decoded);
  return new AudioSample(data, size, channels, sampleRate, 16);
}



// generic
int initAudio(int nTracks, int frequency, int chunkSize) {
    if (nTracks < 1 || nTracks > (1<<UH_PAYLOAD_BIT_WIDTH) )
        return 0;
#ifdef PROTEAAUDIO_SDL
    DeviceAudio* pAudio = DeviceAudioSdl::create(nTracks, frequency, chunkSize);
#endif
#ifdef PROTEAAUDIO_RT
    DeviceAudio* pAudio = DeviceAudioRt::create(nTracks, frequency, chunkSize);
#endif
    return pAudio != 0;
}

void finishAudio() {
    DeviceAudio::destroy();
}

int loaderAvailable(char* suffix) {
    DeviceAudio & audio = DeviceAudio::singleton();
    if((&audio) == 0) return 0;
    return audio.loaderAvailable(suffix);
}

void volume(float left, float right) {
    DeviceAudio & audio = DeviceAudio::singleton();
    if((&audio) == 0) return;
    audio.volume(left,right);
}

sample_t sampleFromFile(char* filename, float volume) {
    DeviceAudio & audio = DeviceAudio::singleton();
    if((&audio) == 0) return 0;
    return audio.sampleFromFile(filename, volume);
}

sample_t _sampleFromMemoryPcm(char *pcm_data, int size, int channels, int sampleRate, int bitsPerSample, float volume) {
    DeviceAudio & audio = DeviceAudio::singleton();
    if((&audio) == 0) return 0;
    unsigned char * data = new unsigned char[size];
    if(!data) return 0;
    memcpy(data, pcm_data, size);
    AudioSample * pSample = new AudioSample(data, size, channels, sampleRate, bitsPerSample);
    if(!pSample) return 0;
    sample_t ret = audio.sampleFromMemory(*pSample, volume);
    delete pSample;
    return ret;
}
sample_t _sampleFromMemoryWav(char *data, int size, float volume) {
    DeviceAudio & audio = DeviceAudio::singleton();
    if((&audio) == 0) return 0;
    AudioSample* pSample = loadWavFromMemory((unsigned char*)data, size);
    if(!pSample) return 0;
    sample_t ret = audio.sampleFromMemory(*pSample, volume);
    delete pSample;
    return ret;
}

sample_t _sampleFromMemoryOgg(char *data, int size, float volume) {
    DeviceAudio & audio = DeviceAudio::singleton();
    if((&audio) == 0) return 0;
    AudioSample* pSample = loadOggFromMemory((unsigned char*)data, size);
    if(!pSample) return 0;
    sample_t ret = audio.sampleFromMemory(*pSample, volume);
    delete pSample;
    return ret;
}

sample_t _sampleFromMemoryMp3(char *data, int size, float volume) {
    DeviceAudio & audio = DeviceAudio::singleton();
    if((&audio) == 0) return 0;
    AudioSample* pSample = loadMp3FromMemory((unsigned char*)data, size);
    if(!pSample) return 0;
    sample_t ret = audio.sampleFromMemory(*pSample, volume);
    delete pSample;
    return ret;
}

int soundActiveAll() {
    DeviceAudio & audio = DeviceAudio::singleton();
    if((&audio) == 0) return 0;
    return (int)audio.soundActive();
}

void soundStopAll() {
    DeviceAudio & audio = DeviceAudio::singleton();
    if((&audio) == 0) return;
    audio.soundStop();
}

int sampleDestroy(uint64_t sample) {
    DeviceAudio & audio = DeviceAudio::singleton();
    if((&audio) == 0) return false;
    return audio.sampleDestroy(sample);
}

// sound
sound_t soundLoop(sample_t sample, float volumeL, float volumeR, float disparity, float pitch) {
    DeviceAudio & audio = DeviceAudio::singleton();
    if((&audio) == 0) return 0;
    return audio.soundLoop(sample, volumeL, volumeR, disparity, pitch);
}

sound_t soundPlay(sample_t sample, float volumeL, float volumeR, float disparity, float pitch) {
    DeviceAudio & audio = DeviceAudio::singleton();
    if((&audio) == 0) return 0;
    return audio.soundPlay(sample, volumeL, volumeR, disparity, pitch);
}

sound_t soundLoopOn(unsigned int track, sample_t sample, float volumeL, float volumeR, float disparity, float pitch) {
    DeviceAudio & audio = DeviceAudio::singleton();
    if((&audio) == 0) return 0;
    return audio.soundLoopOn(track, sample, volumeL, volumeR, disparity, pitch);    
}

sound_t soundPlayOn(unsigned int track, sample_t sample, float volumeL, float volumeR, float disparity, float pitch) {
    DeviceAudio & audio = DeviceAudio::singleton();
    if((&audio) == 0) return 0;
    return audio.soundPlayOn(track, sample, volumeL, volumeR, disparity, pitch);    
}

int soundUpdate(sound_t sound, int pause, float volumeL, float volumeR, float disparity, float pitch) {
    DeviceAudio & audio = DeviceAudio::singleton();
    if((&audio) == 0) return 0;
    return audio.soundUpdate(sound, pause, volumeL, volumeR, disparity, pitch);
}

int soundStop(sound_t sound) {
    DeviceAudio & audio = DeviceAudio::singleton();
    if((&audio) == 0) return 0;
    return audio.soundStop(sound);
}

int soundActive(sound_t sound) {
    DeviceAudio & audio = DeviceAudio::singleton();
    if((&audio) == 0) return 0;
    return audio.soundActive(sound);
}