kwlError kwlWaveBank_loadAudioData(kwlWaveBank* waveBank, const char* path, int threaded, kwlWaveBankFinishedLoadingCallback callback) { if (threaded == 0) { /*perform blocking loading*/ kwlInputStream stream; kwlInputStream_initWithFile(&stream, path); return kwlWaveBank_loadAudioDataItems(waveBank, &stream); } else { /*do asynchronous loading*/ kwlInputStream_initWithFile(&waveBank->loadingThread.inputStream, path); waveBank->loadingThread.waveBank = waveBank; waveBank->loadingThread.callback = callback; kwlThreadCreate(&waveBank->loadingThread.thread, kwlWaveBank_loadingThreadEntryPoint, waveBank); return KWL_NO_ERROR; } }
kwlError kwlDecoder_init(kwlDecoder* decoder, kwlEventInstance* event) { kwlAudioData* audioData = event->definition_engine->streamAudioData; /*reset the decoder struct.*/ kwlMemset(decoder, 0, sizeof(kwlDecoder)); decoder->loop = event->definition_engine->loopIfStreaming; /* * Hook up audio data, that could either be from a file or from an already loaded buffer */ if (audioData->streamFromDisk != 0) { KWL_ASSERT(audioData->fileOffset >= 0); kwlError result = kwlInputStream_initWithFileRegion(&decoder->audioDataStream, audioData->waveBank->waveBankFilePath, audioData->fileOffset, audioData->numBytes); KWL_ASSERT(result == KWL_NO_ERROR); } else { kwlInputStream_initWithBuffer(&decoder->audioDataStream, audioData->bytes, 0, audioData->numBytes); } /* * do codec specific initialization. */ kwlError result = KWL_UNSUPPORTED_ENCODING; if (audioData->encoding == KWL_ENCODING_IMA_ADPCM) { result = kwlInitDecoderIMAADPCM(decoder); } else if (audioData->encoding == KWL_ENCODING_VORBIS) { result = kwlInitDecoderOggVorbis(decoder); } else if (kwlAudioData_isLinearPCM(audioData)) { result = kwlInitDecoderPCM(decoder); } #ifdef KWL_IPHONE else if (audioData->encoding == KWL_ENCODING_UNKNOWN) { /*try the iphone decoder*/ result = kwlInitDecoderIPhone(decoder); } #endif /*KWL_IPHONE*/ if (result != KWL_NO_ERROR) { decoder->deinit(decoder); return result; } KWL_ASSERT(decoder->numChannels > 0); decoder->currentDecodedBuffer = (short*)KWL_MALLOC(sizeof(short) * decoder->maxDecodedBufferSize, "decoder back buffer"); decoder->currentDecodedBufferFront = (short*)KWL_MALLOC(sizeof(short) * decoder->maxDecodedBufferSize, "decoder front buffer"); decoder->currentDecodedBufferSizeInBytes = 0; /* * Before starting the decoding thread, call the decode function * synchronously to get the first buffer of decoded samples. */ int decodingResult = decoder->decodeBuffer(decoder); kwlDecoder_swapBuffers(decoder); /*TODO: check the decoding result. the event could be done playing here.*/ event->currentPCMFrameIndex = 0; event->currentPCMBuffer = decoder->currentDecodedBufferFront; event->currentPCMBufferSize = decoder->currentDecodedBufferSizeInBytes / (2 * decoder->numChannels); event->currentNumChannels = decoder->numChannels; /*Create a semaphore with a unique name based on the addess of the decoder*/ sprintf(decoder->semaphoreName, "decoder%d", (int)decoder); decoder->semaphore = kwlSemaphoreOpen(decoder->semaphoreName); kwlSemaphorePost(decoder->semaphore); /*Fire up the decoding thread.*/ kwlThreadCreate(&decoder->decodingThread, kwlDecoder_decodingLoop, decoder); return result; }