kwlMixBus* kwlMixBus_alloc() { kwlMixBus* newMixBus = (kwlMixBus*)KWL_MALLOC(sizeof(kwlMixBus), "kwlMixBus_alloc"); kwlMemset(newMixBus, 0, sizeof(kwlMixBus)); kwlMixBus_init(newMixBus); return newMixBus; }
void kwlMixBus_init(kwlMixBus* mixBus) { kwlMemset(mixBus, 0, sizeof(kwlMixBus)); mixBus->totalPitch.valueEngine = 0.0f; mixBus->totalPitch.valueMixer = 0.0f; mixBus->totalPitch.valueShared = 0.0f; mixBus->totalGainLeft.valueEngine = 0.0f; mixBus->totalGainLeft.valueMixer = 0.0f; mixBus->totalGainLeft.valueShared = 0.0f; mixBus->totalGainRight.valueEngine = 0.0f; mixBus->totalGainRight.valueMixer = 0.0f; mixBus->totalGainRight.valueShared = 0.0f; mixBus->userGainLeft = 1.0f; mixBus->userGainRight = 1.0f; mixBus->userPitch = 1.0f; mixBus->mixPresetGainLeft = 1.0f; mixBus->mixPresetGainRight = 1.0f; mixBus->mixPresetPitch = 1.0f; mixBus->isMaster = 0; mixBus->numSubBuses = 0; mixBus->subBuses = NULL; }
void kwlEventInstance_init(kwlEventInstance* event) { kwlMemset(event, 0, sizeof(kwlEventInstance)); event->definition_mixer = NULL; event->definition_engine = NULL; event->positionX = 0.0f; event->positionY = 0.0f; event->positionZ = 0.0f; event->velocityX = 0.0f; event->velocityY = 0.0f; event->velocityZ = 0.0f; event->directionX = 0.0f; event->directionY = 0.0f; event->directionZ = 0.0f; event->userGain = 1.0f; event->userPitch = 1.0f; event->balance = 0.0f; event->numBuffersPlayed = 0; event->currentAudioDataIndex = 0; event->pitchAccumulator = 0.0f; event->fadeGainIncrPerFrame = 0.0f; event->fadeGain = 1.0f; event->soundPitch = 1.0f; event->playbackState = KWL_STOPPED; }
kwlError kwlEventInstance_createFreeformEventFromFile(kwlEventInstance** event, const char* const audioFilePath, kwlEventType type, int streamFromDisk) { KWL_ASSERT(streamFromDisk == 0 && "stream flag not supported yet"); /*try to load the audio file data*/ kwlAudioData* audioData = (kwlAudioData*)KWL_MALLOC(sizeof(kwlAudioData), "freeform event audio data struct"); kwlMemset(audioData, 0, sizeof(kwlAudioData)); kwlError error = kwlLoadAudioFile(audioFilePath, audioData, KWL_CONVERT_TO_INT16_OR_FAIL); if (error != KWL_NO_ERROR) { KWL_FREE(audioData); return error; } if (type == KWL_POSITIONAL && audioData->numChannels != 1) { kwlAudioData_free(audioData); KWL_FREE(audioData); return KWL_POSITIONAL_EVENT_MUST_BE_MONO; } return kwlEventInstance_createFreeformEventFromAudioData(event, audioData, type, "freeform event"); }
kwlError kwlEventInstance_createFreeformEventFromBuffer(kwlEventInstance** event, kwlPCMBuffer* buffer, kwlEventType type) { if (buffer->numFrames < 1 || buffer->numChannels < 1 || buffer->numChannels > 2 || buffer->pcmData == NULL) { return KWL_INVALID_PARAMETER_VALUE; } kwlAudioData* audioData = (kwlAudioData*)KWL_MALLOC(sizeof(kwlAudioData), "freeform event audio data struct"); kwlMemset(audioData, 0, sizeof(kwlAudioData)); audioData->numChannels = buffer->numChannels; audioData->numFrames = buffer->numFrames; audioData->numBytes = buffer->numFrames * buffer->numChannels * 2;/*2 bytes per 16 bit sample*/ audioData->bytes = buffer->pcmData; audioData->encoding = KWL_ENCODING_SIGNED_16BIT_PCM; /*The id "freeform buffer event" is used later to indicate that the sample data should not be released. This should really be handled in a better way.*/ return kwlEventInstance_createFreeformEventFromAudioData(event, audioData, type, "freeform buffer event"); }
void kwlEventDefinition_init(kwlEventDefinition* eventDefinition) { kwlMemset(eventDefinition, 0, sizeof(kwlEventDefinition)); }
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; }