size_t gauX_sample_source_ogg_callback_read(void *ptr, size_t size, size_t nmemb, void *datasource) { gau_OggDataSourceCallbackData* stream = (gau_OggDataSourceCallbackData*)datasource; ga_DataSource* ds = stream->dataSrc; size_t ret = (size_t)ga_data_source_read(ds, ptr, size, nmemb); return ret; }
void gauX_data_source_advance(ga_DataSource* in_dataSrc, gc_int32 in_delta) { if(ga_data_source_flags(in_dataSrc) & GA_FLAG_SEEKABLE) ga_data_source_seek(in_dataSrc, in_delta, GA_SEEK_ORIGIN_CUR); else { char buffer[256]; while(in_delta > 0) { gc_int32 advance = in_delta > 256 ? 256 : in_delta; gc_int32 bytesAdvanced = ga_data_source_read(in_dataSrc, &buffer[0], 1, advance); in_delta -= bytesAdvanced; } } }
gc_int32 gauX_sample_source_wav_read(void* in_context, void* in_dst, gc_int32 in_numSamples, tOnSeekFunc in_onSeekFunc, void* in_seekContext) { gau_SampleSourceWavContext* ctx = &((gau_SampleSourceWav*)in_context)->context; gc_int32 numRead = 0; gc_int32 totalSamples = ctx->wavHeader.dataSize / ctx->sampleSize; gc_mutex_lock(ctx->posMutex); if(ctx->pos + in_numSamples > totalSamples) in_numSamples = totalSamples - ctx->pos; if(in_numSamples > 0) { numRead = ga_data_source_read(ctx->dataSrc, in_dst, ctx->sampleSize, in_numSamples); ctx->pos += numRead; } gc_mutex_unlock(ctx->posMutex); return numRead; }
ga_Memory* ga_memory_create_data_source(ga_DataSource* in_dataSource) { ga_Memory* ret = 0; gc_int32 BUFFER_BYTES = 4096; char* data = 0; gc_int32 totalBytes = 0; gc_int32 numBytesRead = 0; do { data = gcX_ops->reallocFunc(data, totalBytes + BUFFER_BYTES); numBytesRead = ga_data_source_read(in_dataSource, data + totalBytes, 1, BUFFER_BYTES); if(numBytesRead < BUFFER_BYTES) data = gcX_ops->reallocFunc(data, totalBytes + numBytesRead); totalBytes += numBytesRead; } while(numBytesRead > 0); ret = gaX_memory_create(data, totalBytes, 0); if(!ret) gcX_ops->freeFunc(data); return ret; }
gc_result gauX_sample_source_wav_load_header(ga_DataSource* in_dataSrc, ga_WavData* out_wavData) { /* TODO: Make this work with non-blocking reads? Need to get this data... */ ga_WavData* wavData = out_wavData; gc_int32 seekable = ga_data_source_flags(in_dataSrc) & GA_FLAG_SEEKABLE ? 1 : 0; gc_int32 dataOffset = 0; char id[5]; id[4] = 0; if(!in_dataSrc) return GC_ERROR_GENERIC; ga_data_source_read(in_dataSrc, &id[0], sizeof(char), 4); /* 'RIFF' */ dataOffset += 4; if(!strcmp(id, "RIFF")) { ga_data_source_read(in_dataSrc, &wavData->fileSize, sizeof(gc_int32), 1); ga_data_source_read(in_dataSrc, &id[0], sizeof(char), 4); /* 'WAVE' */ dataOffset += 8; if(!strcmp(id, "WAVE")) { gc_int32 dataFound = 0; gc_int32 hdrFound = 0; do { gc_int32 chunkSize = 0; ga_data_source_read(in_dataSrc, &id[0], sizeof(char), 4); ga_data_source_read(in_dataSrc, &chunkSize, sizeof(gc_int32), 1); dataOffset += 8; if(!hdrFound && !strcmp(id, "fmt ")) /* 'fmt ' */ { wavData->fmtSize = chunkSize; ga_data_source_read(in_dataSrc, &wavData->fmtTag, sizeof(gc_int16), 1); ga_data_source_read(in_dataSrc, &wavData->channels, sizeof(gc_int16), 1); ga_data_source_read(in_dataSrc, &wavData->sampleRate, sizeof(gc_int32), 1); ga_data_source_read(in_dataSrc, &wavData->bytesPerSec, sizeof(gc_int32), 1); ga_data_source_read(in_dataSrc, &wavData->blockAlign, sizeof(gc_int16), 1); ga_data_source_read(in_dataSrc, &wavData->bitsPerSample, sizeof(gc_int16), 1); gauX_data_source_advance(in_dataSrc, chunkSize - 16); hdrFound = 1; } else if(!dataFound && !strcmp(id, "data")) /* 'data' */ { wavData->dataSize = chunkSize; wavData->dataOffset = dataOffset; dataFound = 1; } else { gauX_data_source_advance(in_dataSrc, chunkSize); } dataOffset += chunkSize; } while(!(hdrFound && dataFound)); /* TODO: Need End-Of-Data support in Data Sources */ if(hdrFound && dataFound) return GC_SUCCESS; } } return GC_ERROR_GENERIC; }