From bc8b98223b1900bb277f1c7097d91d50ab4d0f7a Mon Sep 17 00:00:00 2001 From: Liriosha <57261793+Liriosha@users.noreply.github.com> Date: Thu, 19 Mar 2026 03:31:12 -0400 Subject: [PATCH] clang-format --- .../Platform/Common/Audio/SoundEngine.cpp | 3198 ++++--- .../Platform/Common/Audio/SoundEngine.h | 6 +- .../Platform/Common/Audio/SoundNames.cpp | 12 +- .../Platform/Common/Audio/stb_vorbis.h | 7601 ++++++++--------- 4 files changed, 5383 insertions(+), 5434 deletions(-) diff --git a/Minecraft.Client/Platform/Common/Audio/SoundEngine.cpp b/Minecraft.Client/Platform/Common/Audio/SoundEngine.cpp index c7a3069d3..77ba30a09 100644 --- a/Minecraft.Client/Platform/Common/Audio/SoundEngine.cpp +++ b/Minecraft.Client/Platform/Common/Audio/SoundEngine.cpp @@ -117,46 +117,45 @@ char SoundEngine::m_szRedistName[] = {"redist"}; // Linux specific functions #ifdef __linux__ -std::wstring stws(const char* utf8) -{ +std::wstring stws(const char* utf8) { size_t len = std::mbstowcs(nullptr, utf8, 0); if (len == static_cast(-1)) return L""; std::wstring result(len, L'\0'); std::mbstowcs(&result[0], utf8, len); return result; } -SoundEngine::SoundEngine() { -} +SoundEngine::SoundEngine() {} std::vector m_activeSounds; void SoundEngine::init(Options* pOptions) { app.DebugPrintf("---SoundEngine::init\n"); random = new Random(); - memset(&m_engine, 0, sizeof(ma_engine)); + memset(&m_engine, 0, sizeof(ma_engine)); memset(&m_engineConfig, 0, sizeof(ma_engine_config)); m_musicStreamActive = false; - m_StreamState=eMusicStreamState_Idle; - m_iMusicDelay=0; - m_validListenerCount=0; + m_StreamState = eMusicStreamState_Idle; + m_iMusicDelay = 0; + m_validListenerCount = 0; - m_bHeardTrackA=nullptr; + m_bHeardTrackA = nullptr; - // Start the streaming music playing some music from the overworld - SetStreamingSounds(eStream_Overworld_Calm1,eStream_Overworld_piano3, - eStream_Nether1,eStream_Nether4, - eStream_end_dragon,eStream_end_end, - eStream_CD_1); + // Start the streaming music playing some music from the overworld + SetStreamingSounds(eStream_Overworld_Calm1, eStream_Overworld_piano3, + eStream_Nether1, eStream_Nether4, eStream_end_dragon, + eStream_end_end, eStream_CD_1); - m_musicID=getMusicID(LevelData::DIMENSION_OVERWORLD); + m_musicID = getMusicID(LevelData::DIMENSION_OVERWORLD); - m_StreamingAudioInfo.bIs3D=false; - m_StreamingAudioInfo.x=0; - m_StreamingAudioInfo.y=0; - m_StreamingAudioInfo.z=0; - m_StreamingAudioInfo.volume=1; - m_StreamingAudioInfo.pitch=1; + m_StreamingAudioInfo.bIs3D = false; + m_StreamingAudioInfo.x = 0; + m_StreamingAudioInfo.y = 0; + m_StreamingAudioInfo.z = 0; + m_StreamingAudioInfo.volume = 1; + m_StreamingAudioInfo.pitch = 1; - memset(CurrentSoundsPlaying, 0, sizeof(int) * (static_cast(eSoundType_MAX) + static_cast(eSFX_MAX))); - memset(m_ListenerA,0,sizeof(AUDIO_LISTENER)*XUSER_MAX_COUNT); + memset(CurrentSoundsPlaying, 0, + sizeof(int) * + (static_cast(eSoundType_MAX) + static_cast(eSFX_MAX))); + memset(m_ListenerA, 0, sizeof(AUDIO_LISTENER) * XUSER_MAX_COUNT); m_engineConfig = ma_engine_config_init(); m_engineConfig.listenerCount = MAX_LOCAL_PLAYERS; @@ -256,7 +255,8 @@ void SoundEngine::play(int iSound, float x, float y, float z, float volume, if (ma_sound_init_from_file(&m_engine, finalPath, MA_SOUND_FLAG_ASYNC, nullptr, nullptr, &s->sound) != MA_SUCCESS) { - app.DebugPrintf("Failed to load sound ID : %i from %S\n", iSound, wchSoundNames[iSound]); + app.DebugPrintf("Failed to load sound ID : %i from %S\n", iSound, + wchSoundNames[iSound]); delete s; return; } @@ -338,59 +338,60 @@ void SoundEngine::playUI(int iSound, float volume, float pitch) { m_activeSounds.push_back(s); } -int SoundEngine::getMusicID(int iDomain) -{ - int iRandomVal=0; - Minecraft *pMinecraft=Minecraft::GetInstance(); +int SoundEngine::getMusicID(int iDomain) { + int iRandomVal = 0; + Minecraft* pMinecraft = Minecraft::GetInstance(); - // Protection from errors - if(pMinecraft==nullptr || pMinecraft->skins==nullptr) - { - // any track from the overworld - return GetRandomishTrack(m_iStream_Overworld_Min,m_iStream_Overworld_Max); - } + // Protection from errors + if (pMinecraft == nullptr || pMinecraft->skins == nullptr) { + // any track from the overworld + return GetRandomishTrack(m_iStream_Overworld_Min, + m_iStream_Overworld_Max); + } - if(pMinecraft->skins->isUsingDefaultSkin()) - { - switch(iDomain) - { - case LevelData::DIMENSION_END: - // the end isn't random - it has different music depending on whether the dragon is alive or not, but we've not added the dead dragon music yet - return m_iStream_End_Min; - case LevelData::DIMENSION_NETHER: - return GetRandomishTrack(m_iStream_Nether_Min,m_iStream_Nether_Max); - //return m_iStream_Nether_Min + random->nextInt(m_iStream_Nether_Max-m_iStream_Nether_Min); - default: //overworld - //return m_iStream_Overworld_Min + random->nextInt(m_iStream_Overworld_Max-m_iStream_Overworld_Min); - return GetRandomishTrack(m_iStream_Overworld_Min,m_iStream_Overworld_Max); - } - } - else - { - // using a texture pack - may have multiple End music tracks - switch(iDomain) - { - case LevelData::DIMENSION_END: - return GetRandomishTrack(m_iStream_End_Min,m_iStream_End_Max); - case LevelData::DIMENSION_NETHER: - //return m_iStream_Nether_Min + random->nextInt(m_iStream_Nether_Max-m_iStream_Nether_Min); - return GetRandomishTrack(m_iStream_Nether_Min,m_iStream_Nether_Max); - default: //overworld - //return m_iStream_Overworld_Min + random->nextInt(m_iStream_Overworld_Max-m_iStream_Overworld_Min); - return GetRandomishTrack(m_iStream_Overworld_Min,m_iStream_Overworld_Max); - } - } + if (pMinecraft->skins->isUsingDefaultSkin()) { + switch (iDomain) { + case LevelData::DIMENSION_END: + // the end isn't random - it has different music depending on + // whether the dragon is alive or not, but we've not added the + // dead dragon music yet + return m_iStream_End_Min; + case LevelData::DIMENSION_NETHER: + return GetRandomishTrack(m_iStream_Nether_Min, + m_iStream_Nether_Max); + // return m_iStream_Nether_Min + + // random->nextInt(m_iStream_Nether_Max-m_iStream_Nether_Min); + default: // overworld + // return m_iStream_Overworld_Min + + // random->nextInt(m_iStream_Overworld_Max-m_iStream_Overworld_Min); + return GetRandomishTrack(m_iStream_Overworld_Min, + m_iStream_Overworld_Max); + } + } else { + // using a texture pack - may have multiple End music tracks + switch (iDomain) { + case LevelData::DIMENSION_END: + return GetRandomishTrack(m_iStream_End_Min, m_iStream_End_Max); + case LevelData::DIMENSION_NETHER: + // return m_iStream_Nether_Min + + // random->nextInt(m_iStream_Nether_Max-m_iStream_Nether_Min); + return GetRandomishTrack(m_iStream_Nether_Min, + m_iStream_Nether_Max); + default: // overworld + // return m_iStream_Overworld_Min + + // random->nextInt(m_iStream_Overworld_Max-m_iStream_Overworld_Min); + return GetRandomishTrack(m_iStream_Overworld_Min, + m_iStream_Overworld_Max); + } + } } -int SoundEngine::getMusicID(const std::wstring& name) -{ +int SoundEngine::getMusicID(const std::wstring& name) { int iCD = 0; - for (size_t i = 0; i < 12; i++) - { + for (size_t i = 0; i < 12; i++) { std::wstring fileNameW = stws(m_szStreamFileA[i + eStream_CD_1]); - if (name == fileNameW) - { + if (name == fileNameW) { iCD = static_cast(i); break; } @@ -400,98 +401,79 @@ int SoundEngine::getMusicID(const std::wstring& name) void SoundEngine::playStreaming(const wstring& name, float x, float y, float z, float volume, float pitch, bool bMusicDelay) { - m_StreamingAudioInfo.x=x; - m_StreamingAudioInfo.y=y; - m_StreamingAudioInfo.z=z; - m_StreamingAudioInfo.volume=volume; - m_StreamingAudioInfo.pitch=pitch; + m_StreamingAudioInfo.x = x; + m_StreamingAudioInfo.y = y; + m_StreamingAudioInfo.z = z; + m_StreamingAudioInfo.volume = volume; + m_StreamingAudioInfo.pitch = pitch; - if(m_StreamState==eMusicStreamState_Playing) - { - m_StreamState=eMusicStreamState_Stop; - } - else if(m_StreamState==eMusicStreamState_Opening) - { - m_StreamState=eMusicStreamState_OpeningCancel; - } + if (m_StreamState == eMusicStreamState_Playing) { + m_StreamState = eMusicStreamState_Stop; + } else if (m_StreamState == eMusicStreamState_Opening) { + m_StreamState = eMusicStreamState_OpeningCancel; + } app.DebugPrintf("playStreaming %S", name.c_str()); - if(name.empty()) - { - // music, or stop CD - m_StreamingAudioInfo.bIs3D=false; + if (name.empty()) { + // music, or stop CD + m_StreamingAudioInfo.bIs3D = false; - // we need a music id - // random delay of up to 3 minutes for music - m_iMusicDelay = random->nextInt(20 * 60 * 3);//random->nextInt(20 * 60 * 10) + 20 * 60 * 10; + // we need a music id + // random delay of up to 3 minutes for music + m_iMusicDelay = random->nextInt( + 20 * 60 * 3); // random->nextInt(20 * 60 * 10) + 20 * 60 * 10; #ifdef _DEBUG - m_iMusicDelay=0; + m_iMusicDelay = 0; #endif - Minecraft *pMinecraft=Minecraft::GetInstance(); + Minecraft* pMinecraft = Minecraft::GetInstance(); - bool playerInEnd=false; - bool playerInNether=false; - - for(unsigned int i=0;ilocalplayers[i]!=nullptr) - { - if(pMinecraft->localplayers[i]->dimension==LevelData::DIMENSION_END) - { - playerInEnd=true; - } - else if(pMinecraft->localplayers[i]->dimension==LevelData::DIMENSION_NETHER) - { - playerInNether=true; - } - } - } - if(playerInEnd) - { - m_musicID = getMusicID(LevelData::DIMENSION_END); - } - else if(playerInNether) - { - m_musicID = getMusicID(LevelData::DIMENSION_NETHER); - } - else - { - m_musicID = getMusicID(LevelData::DIMENSION_OVERWORLD); - } - } - else - { - // jukebox - m_StreamingAudioInfo.bIs3D=true; - m_musicID=getMusicID(name); - m_iMusicDelay=0; - } + bool playerInEnd = false; + bool playerInNether = false; + for (unsigned int i = 0; i < MAX_LOCAL_PLAYERS; i++) { + if (pMinecraft->localplayers[i] != nullptr) { + if (pMinecraft->localplayers[i]->dimension == + LevelData::DIMENSION_END) { + playerInEnd = true; + } else if (pMinecraft->localplayers[i]->dimension == + LevelData::DIMENSION_NETHER) { + playerInNether = true; + } + } + } + if (playerInEnd) { + m_musicID = getMusicID(LevelData::DIMENSION_END); + } else if (playerInNether) { + m_musicID = getMusicID(LevelData::DIMENSION_NETHER); + } else { + m_musicID = getMusicID(LevelData::DIMENSION_OVERWORLD); + } + } else { + // jukebox + m_StreamingAudioInfo.bIs3D = true; + m_musicID = getMusicID(name); + m_iMusicDelay = 0; + } } -int SoundEngine::OpenStreamThreadProc(void* lpParameter) -{ +int SoundEngine::OpenStreamThreadProc(void* lpParameter) { SoundEngine* soundEngine = (SoundEngine*)lpParameter; - const char* ext = strrchr(soundEngine->m_szStreamName, '.'); - - if (soundEngine->m_musicStreamActive) - { + const char* ext = strrchr(soundEngine->m_szStreamName, '.'); + + if (soundEngine->m_musicStreamActive) { ma_sound_stop(&soundEngine->m_musicStream); ma_sound_uninit(&soundEngine->m_musicStream); soundEngine->m_musicStreamActive = false; } ma_result result = ma_sound_init_from_file( - &soundEngine->m_engine, - soundEngine->m_szStreamName, - MA_SOUND_FLAG_STREAM, - nullptr, - nullptr, - &soundEngine->m_musicStream); + &soundEngine->m_engine, soundEngine->m_szStreamName, + MA_SOUND_FLAG_STREAM, nullptr, nullptr, &soundEngine->m_musicStream); - if (result != MA_SUCCESS) - { - app.DebugPrintf("SoundEngine::OpenStreamThreadProc - Failed to open stream: %s\n", soundEngine->m_szStreamName); + if (result != MA_SUCCESS) { + app.DebugPrintf( + "SoundEngine::OpenStreamThreadProc - Failed to open stream: %s\n", + soundEngine->m_szStreamName); return 0; } @@ -503,535 +485,491 @@ int SoundEngine::OpenStreamThreadProc(void* lpParameter) return 0; } +void SoundEngine::playMusicTick() { + static float fMusicVol = 0.0f; + fMusicVol = getMasterMusicVolume(); -void SoundEngine::playMusicTick() -{ - static float fMusicVol = 0.0f; - fMusicVol = getMasterMusicVolume(); + switch (m_StreamState) { + case eMusicStreamState_Idle: - switch(m_StreamState) - { - case eMusicStreamState_Idle: + // start a stream playing + if (m_iMusicDelay > 0) { + m_iMusicDelay--; + return; + } - // start a stream playing - if (m_iMusicDelay > 0) - { - m_iMusicDelay--; - return; - } + if (m_musicStreamActive) { + app.DebugPrintf( + "WARNING: m_musicStreamActive already true in Idle state, " + "resetting to Playing\n"); + m_StreamState = eMusicStreamState_Playing; + return; + } - if (m_musicStreamActive) - { - app.DebugPrintf("WARNING: m_musicStreamActive already true in Idle state, resetting to Playing\n"); - m_StreamState = eMusicStreamState_Playing; - return; - } + if (m_musicID != -1) { + // start playing it - if(m_musicID!=-1) - { - // start playing it + strcpy((char*)m_szStreamName, m_szMusicPath); + // are we using a mash-up pack? + // if(pMinecraft && !pMinecraft->skins->isUsingDefaultSkin() && + // pMinecraft->skins->getSelected()->hasAudio()) + if (Minecraft::GetInstance() + ->skins->getSelected() + ->hasAudio()) { + // It's a mash-up - need to use the DLC path for the music + TexturePack* pTexPack = + Minecraft::GetInstance()->skins->getSelected(); + DLCTexturePack* pDLCTexPack = (DLCTexturePack*)pTexPack; + DLCPack* pack = pDLCTexPack->getDLCInfoParentPack(); + DLCAudioFile* dlcAudioFile = (DLCAudioFile*)pack->getFile( + DLCManager::e_DLCType_Audio, 0); - strcpy((char *)m_szStreamName, m_szMusicPath); - // are we using a mash-up pack? - //if(pMinecraft && !pMinecraft->skins->isUsingDefaultSkin() && pMinecraft->skins->getSelected()->hasAudio()) - if(Minecraft::GetInstance()->skins->getSelected()->hasAudio()) - { - // It's a mash-up - need to use the DLC path for the music - TexturePack *pTexPack=Minecraft::GetInstance()->skins->getSelected(); - DLCTexturePack *pDLCTexPack=(DLCTexturePack *)pTexPack; - DLCPack *pack = pDLCTexPack->getDLCInfoParentPack(); - DLCAudioFile *dlcAudioFile = (DLCAudioFile *) pack->getFile(DLCManager::e_DLCType_Audio, 0); + app.DebugPrintf("Mashup pack \n"); - app.DebugPrintf("Mashup pack \n"); + // build the name - // build the name + // if the music ID is beyond the end of the texture pack + // music files, then it's a CD + if (m_musicID < m_iStream_CD_1) { + SetIsPlayingStreamingGameMusic(true); + SetIsPlayingStreamingCDMusic(false); + m_MusicType = eMusicType_Game; + m_StreamingAudioInfo.bIs3D = false; - // if the music ID is beyond the end of the texture pack music files, then it's a CD - if(m_musicIDGetSoundName(m_musicID); + wstring& wstrSoundName = + dlcAudioFile->GetSoundName(m_musicID); - char szName[255]; - wcstombs(szName, wstrSoundName.c_str(), 255); + char szName[255]; + wcstombs(szName, wstrSoundName.c_str(), 255); - string strFile = "TPACK:\\Data\\" + string(szName) + ".wav"; + string strFile = + "TPACK:\\Data\\" + string(szName) + ".wav"; - std::string mountedPath = StorageManager.GetMountedPath(strFile); - strcpy(m_szStreamName, mountedPath.c_str()); - } - else - { - SetIsPlayingStreamingGameMusic(false); - SetIsPlayingStreamingCDMusic(true); - m_MusicType=eMusicType_CD; - m_StreamingAudioInfo.bIs3D=true; + std::string mountedPath = + StorageManager.GetMountedPath(strFile); + strcpy(m_szStreamName, mountedPath.c_str()); + } else { + SetIsPlayingStreamingGameMusic(false); + SetIsPlayingStreamingCDMusic(true); + m_MusicType = eMusicType_CD; + m_StreamingAudioInfo.bIs3D = true; - // Need to adjust to index into the cds in the game's m_szStreamFileA - strcat((char *)m_szStreamName,"cds/"); - strcat((char *)m_szStreamName,m_szStreamFileA[m_musicID-m_iStream_CD_1+eStream_CD_1]); - strcat((char *)m_szStreamName,".wav"); - } - } - else - { - if(m_musicID(m_szStreamName), "rb"); - if (pFile) - { - fclose(pFile); - } - else - { - const char* extensions[] = { ".ogg", ".mp3", ".wav" }; - size_t extCount = sizeof(extensions) / sizeof(extensions[0]); - bool found = false; + FILE* pFile = nullptr; + pFile = fopen(reinterpret_cast(m_szStreamName), "rb"); + if (pFile) { + fclose(pFile); + } else { + const char* extensions[] = {".ogg", ".mp3", ".wav"}; + size_t extCount = + sizeof(extensions) / sizeof(extensions[0]); + bool found = false; - char* dotPos = strrchr(reinterpret_cast(m_szStreamName), '.'); - if (dotPos != nullptr && (dotPos - reinterpret_cast(m_szStreamName)) < 250) - { - for (size_t i = 0; i < extCount; i++) - { - strncpy(dotPos, extensions[i], 5 ); - app.DebugPrintf("Checking %s\n",m_szStreamName); - pFile = fopen(reinterpret_cast(m_szStreamName), "rb"); - if (pFile) - { - fclose(pFile); - found = true; - break; - } - } - } + char* dotPos = + strrchr(reinterpret_cast(m_szStreamName), '.'); + if (dotPos != nullptr && + (dotPos - reinterpret_cast(m_szStreamName)) < + 250) { + for (size_t i = 0; i < extCount; i++) { + strncpy(dotPos, extensions[i], 5); + app.DebugPrintf("Checking %s\n", m_szStreamName); + pFile = fopen( + reinterpret_cast(m_szStreamName), "rb"); + if (pFile) { + fclose(pFile); + found = true; + break; + } + } + } - if (!found) - { - if (dotPos != nullptr) - { - strncpy(dotPos, ".wav", 5); - } - app.DebugPrintf("WARNING: No audio file found for music ID %d (tried .ogg, .mp3, .wav)\n", m_musicID); - return; - } - } + if (!found) { + if (dotPos != nullptr) { + strncpy(dotPos, ".wav", 5); + } + app.DebugPrintf( + "WARNING: No audio file found for music ID %d " + "(tried .ogg, .mp3, .wav)\n", + m_musicID); + return; + } + } - app.DebugPrintf("Starting streaming - %s\n",m_szStreamName); - m_openStreamThread = new C4JThread(OpenStreamThreadProc, this, "OpenStreamThreadProc"); - m_openStreamThread->Run(); - m_StreamState = eMusicStreamState_Opening; - } - break; + app.DebugPrintf("Starting streaming - %s\n", m_szStreamName); + m_openStreamThread = new C4JThread(OpenStreamThreadProc, this, + "OpenStreamThreadProc"); + m_openStreamThread->Run(); + m_StreamState = eMusicStreamState_Opening; + } + break; - case eMusicStreamState_Opening: - if( !m_openStreamThread->isRunning() ) - { - delete m_openStreamThread; - m_openStreamThread = nullptr; + case eMusicStreamState_Opening: + if (!m_openStreamThread->isRunning()) { + delete m_openStreamThread; + m_openStreamThread = nullptr; - app.DebugPrintf("OpenStreamThreadProc finished. m_musicStreamActive=%d\n", m_musicStreamActive); + app.DebugPrintf( + "OpenStreamThreadProc finished. m_musicStreamActive=%d\n", + m_musicStreamActive); - if (!m_musicStreamActive) - { - const char* currentExt = strrchr(reinterpret_cast(m_szStreamName), '.'); - if (currentExt && _stricmp(currentExt, ".wav") == 0) - { - const bool isCD = (m_musicID >= m_iStream_CD_1); - const char* folder = isCD ? "cds/" : "music/"; - - int n = sprintf_s(reinterpret_cast(m_szStreamName), 512, "%s%s%s.wav", m_szMusicPath, folder, m_szStreamFileA[m_musicID]); - - if (n > 0) - { - FILE* pFile = fopen(reinterpret_cast(m_szStreamName), "rb"); - if (pFile) - { - fclose(pFile); - - m_openStreamThread = new C4JThread(OpenStreamThreadProc, this, "OpenStreamThreadProc"); - m_openStreamThread->Run(); - break; - } - } - } - - m_StreamState = eMusicStreamState_Idle; - break; - } - - if (m_StreamingAudioInfo.bIs3D) - { - ma_sound_set_spatialization_enabled(&m_musicStream, MA_TRUE); - ma_sound_set_position(&m_musicStream, m_StreamingAudioInfo.x, m_StreamingAudioInfo.y, m_StreamingAudioInfo.z); - } - else - { - ma_sound_set_spatialization_enabled(&m_musicStream, MA_FALSE); - } + if (!m_musicStreamActive) { + const char* currentExt = + strrchr(reinterpret_cast(m_szStreamName), '.'); + if (currentExt && _stricmp(currentExt, ".wav") == 0) { + const bool isCD = (m_musicID >= m_iStream_CD_1); + const char* folder = isCD ? "cds/" : "music/"; - ma_sound_set_pitch(&m_musicStream, m_StreamingAudioInfo.pitch); + int n = + sprintf_s(reinterpret_cast(m_szStreamName), + 512, "%s%s%s.wav", m_szMusicPath, folder, + m_szStreamFileA[m_musicID]); - float finalVolume = m_StreamingAudioInfo.volume * getMasterMusicVolume(); + if (n > 0) { + FILE* pFile = fopen( + reinterpret_cast(m_szStreamName), "rb"); + if (pFile) { + fclose(pFile); - ma_sound_set_volume(&m_musicStream, finalVolume); - ma_result startResult = ma_sound_start(&m_musicStream); - app.DebugPrintf("ma_sound_start result: %d\n", startResult); + m_openStreamThread = + new C4JThread(OpenStreamThreadProc, this, + "OpenStreamThreadProc"); + m_openStreamThread->Run(); + break; + } + } + } - m_StreamState=eMusicStreamState_Playing; - } - break; - case eMusicStreamState_OpeningCancel: - if( !m_openStreamThread->isRunning() ) - { - delete m_openStreamThread; - m_openStreamThread = nullptr; - m_StreamState = eMusicStreamState_Stop; - } - break; - case eMusicStreamState_Stop: - if (m_musicStreamActive) - { - ma_sound_stop(&m_musicStream); - ma_sound_uninit(&m_musicStream); - m_musicStreamActive = false; - } + m_StreamState = eMusicStreamState_Idle; + break; + } - SetIsPlayingStreamingCDMusic(false); - SetIsPlayingStreamingGameMusic(false); + if (m_StreamingAudioInfo.bIs3D) { + ma_sound_set_spatialization_enabled(&m_musicStream, + MA_TRUE); + ma_sound_set_position( + &m_musicStream, m_StreamingAudioInfo.x, + m_StreamingAudioInfo.y, m_StreamingAudioInfo.z); + } else { + ma_sound_set_spatialization_enabled(&m_musicStream, + MA_FALSE); + } - m_StreamState = eMusicStreamState_Idle; - break; - case eMusicStreamState_Stopping: - break; - case eMusicStreamState_Play: - break; - case eMusicStreamState_Playing: - { - static int frameCount = 0; - if (frameCount++ % 60 == 0) - { - if (m_musicStreamActive) - { - bool isPlaying = ma_sound_is_playing(&m_musicStream); - float vol = ma_sound_get_volume(&m_musicStream); - bool isAtEnd = ma_sound_at_end(&m_musicStream); - } - } - } - if(GetIsPlayingStreamingGameMusic()) - { - { - bool playerInEnd = false; - bool playerInNether=false; - Minecraft *pMinecraft = Minecraft::GetInstance(); - for(unsigned int i = 0; i < MAX_LOCAL_PLAYERS; ++i) - { - if(pMinecraft->localplayers[i]!=nullptr) - { - if(pMinecraft->localplayers[i]->dimension==LevelData::DIMENSION_END) - { - playerInEnd=true; - } - else if(pMinecraft->localplayers[i]->dimension==LevelData::DIMENSION_NETHER) - { - playerInNether=true; - } - } - } + ma_sound_set_pitch(&m_musicStream, m_StreamingAudioInfo.pitch); - if(playerInEnd && !GetIsPlayingEndMusic()) - { - m_StreamState=eMusicStreamState_Stop; + float finalVolume = + m_StreamingAudioInfo.volume * getMasterMusicVolume(); - // Set the end track - m_musicID = getMusicID(LevelData::DIMENSION_END); - SetIsPlayingEndMusic(true); - SetIsPlayingNetherMusic(false); - } - else if(!playerInEnd && GetIsPlayingEndMusic()) - { - if(playerInNether) - { - m_StreamState=eMusicStreamState_Stop; + ma_sound_set_volume(&m_musicStream, finalVolume); + ma_result startResult = ma_sound_start(&m_musicStream); + app.DebugPrintf("ma_sound_start result: %d\n", startResult); - // Set the end track - m_musicID = getMusicID(LevelData::DIMENSION_NETHER); - SetIsPlayingEndMusic(false); - SetIsPlayingNetherMusic(true); - } - else - { - m_StreamState=eMusicStreamState_Stop; + m_StreamState = eMusicStreamState_Playing; + } + break; + case eMusicStreamState_OpeningCancel: + if (!m_openStreamThread->isRunning()) { + delete m_openStreamThread; + m_openStreamThread = nullptr; + m_StreamState = eMusicStreamState_Stop; + } + break; + case eMusicStreamState_Stop: + if (m_musicStreamActive) { + ma_sound_stop(&m_musicStream); + ma_sound_uninit(&m_musicStream); + m_musicStreamActive = false; + } - // Set the end track - m_musicID = getMusicID(LevelData::DIMENSION_OVERWORLD); - SetIsPlayingEndMusic(false); - SetIsPlayingNetherMusic(false); - } - } - else if (playerInNether && !GetIsPlayingNetherMusic()) - { - m_StreamState=eMusicStreamState_Stop; - // set the Nether track - m_musicID = getMusicID(LevelData::DIMENSION_NETHER); - SetIsPlayingNetherMusic(true); - SetIsPlayingEndMusic(false); - } - else if(!playerInNether && GetIsPlayingNetherMusic()) - { - if(playerInEnd) - { - m_StreamState=eMusicStreamState_Stop; - // set the Nether track - m_musicID = getMusicID(LevelData::DIMENSION_END); - SetIsPlayingNetherMusic(false); - SetIsPlayingEndMusic(true); - } - else - { - m_StreamState=eMusicStreamState_Stop; - // set the Nether track - m_musicID = getMusicID(LevelData::DIMENSION_OVERWORLD); - SetIsPlayingNetherMusic(false); - SetIsPlayingEndMusic(false); - } - } + SetIsPlayingStreamingCDMusic(false); + SetIsPlayingStreamingGameMusic(false); - // volume change required? - if (m_musicStreamActive) - { - float finalVolume = m_StreamingAudioInfo.volume * fMusicVol; + m_StreamState = eMusicStreamState_Idle; + break; + case eMusicStreamState_Stopping: + break; + case eMusicStreamState_Play: + break; + case eMusicStreamState_Playing: { + static int frameCount = 0; + if (frameCount++ % 60 == 0) { + if (m_musicStreamActive) { + bool isPlaying = ma_sound_is_playing(&m_musicStream); + float vol = ma_sound_get_volume(&m_musicStream); + bool isAtEnd = ma_sound_at_end(&m_musicStream); + } + } + } + if (GetIsPlayingStreamingGameMusic()) { + { + bool playerInEnd = false; + bool playerInNether = false; + Minecraft* pMinecraft = Minecraft::GetInstance(); + for (unsigned int i = 0; i < MAX_LOCAL_PLAYERS; ++i) { + if (pMinecraft->localplayers[i] != nullptr) { + if (pMinecraft->localplayers[i]->dimension == + LevelData::DIMENSION_END) { + playerInEnd = true; + } else if (pMinecraft->localplayers[i]->dimension == + LevelData::DIMENSION_NETHER) { + playerInNether = true; + } + } + } - ma_sound_set_volume(&m_musicStream, finalVolume); - } - } - } - else - { - // Music disc playing - if it's a 3D stream, then set the position - we don't have any streaming audio in the world that moves, so this isn't - // required unless we have more than one listener, and are setting the listening position to the origin and setting a fake position - // for the sound down the z axis - if (m_StreamingAudioInfo.bIs3D && m_validListenerCount > 1) - { - int iClosestListener = 0; - float fClosestDist = 1e6f; + if (playerInEnd && !GetIsPlayingEndMusic()) { + m_StreamState = eMusicStreamState_Stop; - for (size_t i = 0; i < MAX_LOCAL_PLAYERS; i++) - { - if (m_ListenerA[i].bValid) - { - float dx = m_StreamingAudioInfo.x - m_ListenerA[i].vPosition.x; - float dy = m_StreamingAudioInfo.y - m_ListenerA[i].vPosition.y; - float dz = m_StreamingAudioInfo.z - m_ListenerA[i].vPosition.z; - float dist = sqrtf(dx*dx + dy*dy + dz*dz); + // Set the end track + m_musicID = getMusicID(LevelData::DIMENSION_END); + SetIsPlayingEndMusic(true); + SetIsPlayingNetherMusic(false); + } else if (!playerInEnd && GetIsPlayingEndMusic()) { + if (playerInNether) { + m_StreamState = eMusicStreamState_Stop; - if (dist < fClosestDist) - { - fClosestDist = dist; - iClosestListener = i; - } - } - } + // Set the end track + m_musicID = getMusicID(LevelData::DIMENSION_NETHER); + SetIsPlayingEndMusic(false); + SetIsPlayingNetherMusic(true); + } else { + m_StreamState = eMusicStreamState_Stop; - float relX = m_StreamingAudioInfo.x - m_ListenerA[iClosestListener].vPosition.x; - float relY = m_StreamingAudioInfo.y - m_ListenerA[iClosestListener].vPosition.y; - float relZ = m_StreamingAudioInfo.z - m_ListenerA[iClosestListener].vPosition.z; + // Set the end track + m_musicID = + getMusicID(LevelData::DIMENSION_OVERWORLD); + SetIsPlayingEndMusic(false); + SetIsPlayingNetherMusic(false); + } + } else if (playerInNether && !GetIsPlayingNetherMusic()) { + m_StreamState = eMusicStreamState_Stop; + // set the Nether track + m_musicID = getMusicID(LevelData::DIMENSION_NETHER); + SetIsPlayingNetherMusic(true); + SetIsPlayingEndMusic(false); + } else if (!playerInNether && GetIsPlayingNetherMusic()) { + if (playerInEnd) { + m_StreamState = eMusicStreamState_Stop; + // set the Nether track + m_musicID = getMusicID(LevelData::DIMENSION_END); + SetIsPlayingNetherMusic(false); + SetIsPlayingEndMusic(true); + } else { + m_StreamState = eMusicStreamState_Stop; + // set the Nether track + m_musicID = + getMusicID(LevelData::DIMENSION_OVERWORLD); + SetIsPlayingNetherMusic(false); + SetIsPlayingEndMusic(false); + } + } - if (m_musicStreamActive) - { - ma_sound_set_position(&m_musicStream, relX, relY, relZ); - } - } - } + // volume change required? + if (m_musicStreamActive) { + float finalVolume = + m_StreamingAudioInfo.volume * fMusicVol; - break; + ma_sound_set_volume(&m_musicStream, finalVolume); + } + } + } else { + // Music disc playing - if it's a 3D stream, then set the + // position - we don't have any streaming audio in the world + // that moves, so this isn't required unless we have more than + // one listener, and are setting the listening position to the + // origin and setting a fake position for the sound down the z + // axis + if (m_StreamingAudioInfo.bIs3D && m_validListenerCount > 1) { + int iClosestListener = 0; + float fClosestDist = 1e6f; - case eMusicStreamState_Completed: - { - // random delay of up to 3 minutes for music - m_iMusicDelay = random->nextInt(20 * 60 * 3);//random->nextInt(20 * 60 * 10) + 20 * 60 * 10; - // Check if we have a local player in The Nether or in The End, and play that music if they are - Minecraft *pMinecraft=Minecraft::GetInstance(); - bool playerInEnd=false; - bool playerInNether=false; + for (size_t i = 0; i < MAX_LOCAL_PLAYERS; i++) { + if (m_ListenerA[i].bValid) { + float dx = m_StreamingAudioInfo.x - + m_ListenerA[i].vPosition.x; + float dy = m_StreamingAudioInfo.y - + m_ListenerA[i].vPosition.y; + float dz = m_StreamingAudioInfo.z - + m_ListenerA[i].vPosition.z; + float dist = sqrtf(dx * dx + dy * dy + dz * dz); - for(unsigned int i=0;ilocalplayers[i]!=nullptr) - { - if(pMinecraft->localplayers[i]->dimension==LevelData::DIMENSION_END) - { - playerInEnd=true; - } - else if(pMinecraft->localplayers[i]->dimension==LevelData::DIMENSION_NETHER) - { - playerInNether=true; - } - } - } - if(playerInEnd) - { - m_musicID = getMusicID(LevelData::DIMENSION_END); - SetIsPlayingEndMusic(true); - SetIsPlayingNetherMusic(false); - } - else if(playerInNether) - { - m_musicID = getMusicID(LevelData::DIMENSION_NETHER); - SetIsPlayingNetherMusic(true); - SetIsPlayingEndMusic(false); - } - else - { - m_musicID = getMusicID(LevelData::DIMENSION_OVERWORLD); - SetIsPlayingNetherMusic(false); - SetIsPlayingEndMusic(false); - } + if (dist < fClosestDist) { + fClosestDist = dist; + iClosestListener = i; + } + } + } - m_StreamState=eMusicStreamState_Idle; - } - break; - } + float relX = m_StreamingAudioInfo.x - + m_ListenerA[iClosestListener].vPosition.x; + float relY = m_StreamingAudioInfo.y - + m_ListenerA[iClosestListener].vPosition.y; + float relZ = m_StreamingAudioInfo.z - + m_ListenerA[iClosestListener].vPosition.z; - // check the status of the stream - this is for when a track completes rather than is stopped by the user action + if (m_musicStreamActive) { + ma_sound_set_position(&m_musicStream, relX, relY, relZ); + } + } + } - if (m_musicStreamActive) - { - if (!ma_sound_is_playing(&m_musicStream) && ma_sound_at_end(&m_musicStream)) - { - ma_sound_uninit(&m_musicStream); - m_musicStreamActive = false; + break; - SetIsPlayingStreamingCDMusic(false); - SetIsPlayingStreamingGameMusic(false); + case eMusicStreamState_Completed: { + // random delay of up to 3 minutes for music + m_iMusicDelay = random->nextInt( + 20 * 60 * 3); // random->nextInt(20 * 60 * 10) + 20 * 60 * 10; + // Check if we have a local player in The Nether or in The End, and + // play that music if they are + Minecraft* pMinecraft = Minecraft::GetInstance(); + bool playerInEnd = false; + bool playerInNether = false; - m_StreamState = eMusicStreamState_Completed; - } - } + for (unsigned int i = 0; i < MAX_LOCAL_PLAYERS; i++) { + if (pMinecraft->localplayers[i] != nullptr) { + if (pMinecraft->localplayers[i]->dimension == + LevelData::DIMENSION_END) { + playerInEnd = true; + } else if (pMinecraft->localplayers[i]->dimension == + LevelData::DIMENSION_NETHER) { + playerInNether = true; + } + } + } + if (playerInEnd) { + m_musicID = getMusicID(LevelData::DIMENSION_END); + SetIsPlayingEndMusic(true); + SetIsPlayingNetherMusic(false); + } else if (playerInNether) { + m_musicID = getMusicID(LevelData::DIMENSION_NETHER); + SetIsPlayingNetherMusic(true); + SetIsPlayingEndMusic(false); + } else { + m_musicID = getMusicID(LevelData::DIMENSION_OVERWORLD); + SetIsPlayingNetherMusic(false); + SetIsPlayingEndMusic(false); + } + + m_StreamState = eMusicStreamState_Idle; + } break; + } + + // check the status of the stream - this is for when a track completes + // rather than is stopped by the user action + + if (m_musicStreamActive) { + if (!ma_sound_is_playing(&m_musicStream) && + ma_sound_at_end(&m_musicStream)) { + ma_sound_uninit(&m_musicStream); + m_musicStreamActive = false; + + SetIsPlayingStreamingCDMusic(false); + SetIsPlayingStreamingGameMusic(false); + + m_StreamState = eMusicStreamState_Completed; + } + } } - -void SoundEngine::updateMiniAudio() -{ - if (m_validListenerCount == 1) - { - for (size_t i = 0; i < MAX_LOCAL_PLAYERS; i++) - { - if (m_ListenerA[i].bValid) - { +void SoundEngine::updateMiniAudio() { + if (m_validListenerCount == 1) { + for (size_t i = 0; i < MAX_LOCAL_PLAYERS; i++) { + if (m_ListenerA[i].bValid) { ma_engine_listener_set_position( - &m_engine, - 0, - m_ListenerA[i].vPosition.x, - m_ListenerA[i].vPosition.y, - m_ListenerA[i].vPosition.z); + &m_engine, 0, m_ListenerA[i].vPosition.x, + m_ListenerA[i].vPosition.y, m_ListenerA[i].vPosition.z); - ma_engine_listener_set_direction( - &m_engine, - 0, - m_ListenerA[i].vOrientFront.x, - m_ListenerA[i].vOrientFront.y, - m_ListenerA[i].vOrientFront.z); + ma_engine_listener_set_direction(&m_engine, 0, + m_ListenerA[i].vOrientFront.x, + m_ListenerA[i].vOrientFront.y, + m_ListenerA[i].vOrientFront.z); - ma_engine_listener_set_world_up( - &m_engine, - 0, - 0.0f, 1.0f, 0.0f); + ma_engine_listener_set_world_up(&m_engine, 0, 0.0f, 1.0f, 0.0f); break; } } - } - else - { + } else { ma_engine_listener_set_position(&m_engine, 0, 0.0f, 0.0f, 0.0f); ma_engine_listener_set_direction(&m_engine, 0, 0.0f, 0.0f, 1.0f); ma_engine_listener_set_world_up(&m_engine, 0, 0.0f, 1.0f, 0.0f); } - for (auto it = m_activeSounds.begin(); it != m_activeSounds.end(); ) - { + for (auto it = m_activeSounds.begin(); it != m_activeSounds.end();) { MiniAudioSound* s = *it; - if (!ma_sound_is_playing(&s->sound)) - { + if (!ma_sound_is_playing(&s->sound)) { ma_sound_uninit(&s->sound); delete s; it = m_activeSounds.erase(it); continue; } - float finalVolume = s->info.volume * m_MasterEffectsVolume * SFX_VOLUME_MULTIPLIER; - if (finalVolume > SFX_MAX_GAIN) - finalVolume = SFX_MAX_GAIN; + float finalVolume = + s->info.volume * m_MasterEffectsVolume * SFX_VOLUME_MULTIPLIER; + if (finalVolume > SFX_MAX_GAIN) finalVolume = SFX_MAX_GAIN; ma_sound_set_volume(&s->sound, finalVolume); ma_sound_set_pitch(&s->sound, s->info.pitch); - if (s->info.bIs3D) - { - if (m_validListenerCount > 1) - { - float fClosest=10000.0f; - int iClosestListener=0; - float fClosestX=0.0f,fClosestY=0.0f,fClosestZ=0.0f,fDist; - for( size_t i = 0; i < MAX_LOCAL_PLAYERS; i++ ) - { - if( m_ListenerA[i].bValid ) - { - float x,y,z; + if (s->info.bIs3D) { + if (m_validListenerCount > 1) { + float fClosest = 10000.0f; + int iClosestListener = 0; + float fClosestX = 0.0f, fClosestY = 0.0f, fClosestZ = 0.0f, + fDist; + for (size_t i = 0; i < MAX_LOCAL_PLAYERS; i++) { + if (m_ListenerA[i].bValid) { + float x, y, z; - x=fabs(m_ListenerA[i].vPosition.x-s->info.x); - y=fabs(m_ListenerA[i].vPosition.y-s->info.y); - z=fabs(m_ListenerA[i].vPosition.z-s->info.z); - fDist=x+y+z; + x = fabs(m_ListenerA[i].vPosition.x - s->info.x); + y = fabs(m_ListenerA[i].vPosition.y - s->info.y); + z = fabs(m_ListenerA[i].vPosition.z - s->info.z); + fDist = x + y + z; - if(fDistsound, 0, 0, realDist); - } - else - { - ma_sound_set_position( - &s->sound, - s->info.x, - s->info.y, - s->info.z); + } else { + ma_sound_set_position(&s->sound, s->info.x, s->info.y, + s->info.z); } } @@ -1039,232 +977,236 @@ void SoundEngine::updateMiniAudio() } } -void SoundEngine::tick(shared_ptr *players, float a) -{ - // update the listener positions - int listenerCount = 0; - if( players ) - { - bool bListenerPostionSet = false; - for( size_t i = 0; i < MAX_LOCAL_PLAYERS; i++ ) - { - if( players[i] != nullptr ) - { - m_ListenerA[i].bValid=true; - F32 x,y,z; - x=players[i]->xo + (players[i]->x - players[i]->xo) * a; - y=players[i]->yo + (players[i]->y - players[i]->yo) * a; - z=players[i]->zo + (players[i]->z - players[i]->zo) * a; +void SoundEngine::tick(shared_ptr* players, float a) { + // update the listener positions + int listenerCount = 0; + if (players) { + bool bListenerPostionSet = false; + for (size_t i = 0; i < MAX_LOCAL_PLAYERS; i++) { + if (players[i] != nullptr) { + m_ListenerA[i].bValid = true; + F32 x, y, z; + x = players[i]->xo + (players[i]->x - players[i]->xo) * a; + y = players[i]->yo + (players[i]->y - players[i]->yo) * a; + z = players[i]->zo + (players[i]->z - players[i]->zo) * a; - float yRot = players[i]->yRotO + (players[i]->yRot - players[i]->yRotO) * a; - float yCos = (float)cos(yRot * Mth::RAD_TO_GRAD); - float ySin = (float)sin(yRot * Mth::RAD_TO_GRAD); + float yRot = players[i]->yRotO + + (players[i]->yRot - players[i]->yRotO) * a; + float yCos = (float)cos(yRot * Mth::RAD_TO_GRAD); + float ySin = (float)sin(yRot * Mth::RAD_TO_GRAD); - // store the listener positions for splitscreen - m_ListenerA[i].vPosition.x = x; - m_ListenerA[i].vPosition.y = y; - m_ListenerA[i].vPosition.z = z; + // store the listener positions for splitscreen + m_ListenerA[i].vPosition.x = x; + m_ListenerA[i].vPosition.y = y; + m_ListenerA[i].vPosition.z = z; - m_ListenerA[i].vOrientFront.x = -ySin; - m_ListenerA[i].vOrientFront.y = 0; - m_ListenerA[i].vOrientFront.z = yCos; + m_ListenerA[i].vOrientFront.x = -ySin; + m_ListenerA[i].vOrientFront.y = 0; + m_ListenerA[i].vOrientFront.z = yCos; - listenerCount++; - } - else - { - m_ListenerA[i].bValid=false; - } - } - } + listenerCount++; + } else { + m_ListenerA[i].bValid = false; + } + } + } - - // If there were no valid players set, make up a default listener - if( listenerCount == 0 ) - { - m_ListenerA[0].vPosition.x = 0; - m_ListenerA[0].vPosition.y = 0; - m_ListenerA[0].vPosition.z = 0; - m_ListenerA[0].vOrientFront.x = 0; - m_ListenerA[0].vOrientFront.y = 0; - m_ListenerA[0].vOrientFront.z = 1.0f; - listenerCount++; - } - m_validListenerCount = listenerCount; + // If there were no valid players set, make up a default listener + if (listenerCount == 0) { + m_ListenerA[0].vPosition.x = 0; + m_ListenerA[0].vPosition.y = 0; + m_ListenerA[0].vPosition.z = 0; + m_ListenerA[0].vOrientFront.x = 0; + m_ListenerA[0].vOrientFront.y = 0; + m_ListenerA[0].vOrientFront.z = 1.0f; + listenerCount++; + } + m_validListenerCount = listenerCount; updateMiniAudio(); } // Classic sound module #else -void SoundEngine::init(Options *pOptions) -{ - app.DebugPrintf("---SoundEngine::init\n"); +void SoundEngine::init(Options* pOptions) { + app.DebugPrintf("---SoundEngine::init\n"); #ifdef __DISABLE_MILES__ - return; + return; #endif #ifdef __ORBIS__ - C4JThread::PushAffinityAllCores(); -#endif -#if defined _DURANGO || defined __ORBIS__ || defined __PS3__ || defined __PSVITA__ - Register_RIB(BinkADec); + C4JThread::PushAffinityAllCores(); +#endif +#if defined _DURANGO || defined __ORBIS__ || defined __PS3__ || \ + defined __PSVITA__ + Register_RIB(BinkADec); #endif - char *redistpath; + char* redistpath; -#if (defined _WINDOWS64 || defined __PSVITA__)// || defined _DURANGO || defined __ORBIS__ ) - redistpath=AIL_set_redist_directory(m_szRedistName); +#if (defined _WINDOWS64 || \ + defined __PSVITA__) // || defined _DURANGO || defined __ORBIS__ ) + redistpath = AIL_set_redist_directory(m_szRedistName); #endif - app.DebugPrintf("---SoundEngine::init - AIL_startup\n"); - S32 ret = AIL_startup(); + app.DebugPrintf("---SoundEngine::init - AIL_startup\n"); + S32 ret = AIL_startup(); - int iNumberOfChannels=initAudioHardware(8); + int iNumberOfChannels = initAudioHardware(8); - // Create a driver to render our audio - 44khz, 16 bit, -#ifdef __PS3__ - // On the Sony PS3, the driver is always opened in 48 kHz, 32-bit floating point. The only meaningful configurations are MSS_MC_STEREO, MSS_MC_51_DISCRETE, and MSS_MC_71_DISCRETE. - m_hDriver = AIL_open_digital_driver( 48000, 16, iNumberOfChannels, AIL_OPEN_DIGITAL_USE_SPU0 ); + // Create a driver to render our audio - 44khz, 16 bit, +#ifdef __PS3__ + // On the Sony PS3, the driver is always opened in 48 kHz, 32-bit floating + //point. The only meaningful configurations are MSS_MC_STEREO, + //MSS_MC_51_DISCRETE, and MSS_MC_71_DISCRETE. + m_hDriver = AIL_open_digital_driver(48000, 16, iNumberOfChannels, + AIL_OPEN_DIGITAL_USE_SPU0); #elif defined __PSVITA__ - // maximum of 16 samples - AIL_set_preference(DIG_MIXER_CHANNELS, 16); + // maximum of 16 samples + AIL_set_preference(DIG_MIXER_CHANNELS, 16); - m_hDriver = AIL_open_digital_driver( 48000, 16, MSS_MC_STEREO, 0 ); + m_hDriver = AIL_open_digital_driver(48000, 16, MSS_MC_STEREO, 0); - // AP - For some reason the submit thread defaults to a priority of zero (invalid). Make sure it has the highest priority to avoid audio breakup. - SceUID threadID; - AIL_platform_property( m_hDriver, PSP2_SUBMIT_THREAD, &threadID, 0, 0); - S32 g_DefaultCPU = sceKernelGetThreadCpuAffinityMask(threadID); - S32 Old = sceKernelChangeThreadPriority(threadID, 64); + // AP - For some reason the submit thread defaults to a priority of zero + // (invalid). Make sure it has the highest priority to avoid audio breakup. + SceUID threadID; + AIL_platform_property(m_hDriver, PSP2_SUBMIT_THREAD, &threadID, 0, 0); + S32 g_DefaultCPU = sceKernelGetThreadCpuAffinityMask(threadID); + S32 Old = sceKernelChangeThreadPriority(threadID, 64); - // AP - register a callback when the mixer starts - AILMIXERCB temp = AIL_register_mix_callback(m_hDriver, MilesMixerCB); + // AP - register a callback when the mixer starts + AILMIXERCB temp = AIL_register_mix_callback(m_hDriver, MilesMixerCB); - InitializeCriticalSection(&SoundEngine_MixerMutex); + InitializeCriticalSection(&SoundEngine_MixerMutex); #elif defined(__ORBIS__) - m_hDriver = AIL_open_digital_driver( 48000, 16, 2, 0 ); - app.DebugPrintf("---SoundEngine::init - AIL_open_digital_driver\n"); + m_hDriver = AIL_open_digital_driver(48000, 16, 2, 0); + app.DebugPrintf("---SoundEngine::init - AIL_open_digital_driver\n"); #else - m_hDriver = AIL_open_digital_driver(44100, 16, MSS_MC_USE_SYSTEM_CONFIG, 0); + m_hDriver = AIL_open_digital_driver(44100, 16, MSS_MC_USE_SYSTEM_CONFIG, 0); #endif - if (m_hDriver == 0) - { - app.DebugPrintf("Couldn't open digital sound driver. (%s)\n", AIL_last_error()); - AIL_shutdown(); + if (m_hDriver == 0) { + app.DebugPrintf("Couldn't open digital sound driver. (%s)\n", + AIL_last_error()); + AIL_shutdown(); #ifdef __ORBIS__ - C4JThread::PopAffinity(); -#endif - return; - } - app.DebugPrintf("---SoundEngine::init - driver opened\n"); + C4JThread::PopAffinity(); +#endif + return; + } + app.DebugPrintf("---SoundEngine::init - driver opened\n"); #ifdef __PSVITA__ - // set high falloff power for maximum spatial effect in software mode - AIL_set_speaker_configuration( m_hDriver, 0, 0, 4.0F ); + // set high falloff power for maximum spatial effect in software mode + AIL_set_speaker_configuration(m_hDriver, 0, 0, 4.0F); #endif - AIL_set_event_error_callback(ErrorCallback); + AIL_set_event_error_callback(ErrorCallback); - AIL_set_3D_rolloff_factor(m_hDriver,1.0); + AIL_set_3D_rolloff_factor(m_hDriver, 1.0); - // Create an event system tied to that driver - let Miles choose memory defaults. - //if (AIL_startup_event_system(m_hDriver, 0, 0, 0) == 0) - // 4J-PB - Durango complains that the default memory (64k)isn't enough - // Error: MilesEvent: Out of event system memory (pool passed to event system startup exhausted). - // AP - increased command buffer from the default 5K to 20K for Vita + // Create an event system tied to that driver - let Miles choose memory + // defaults. + // if (AIL_startup_event_system(m_hDriver, 0, 0, 0) == 0) + // 4J-PB - Durango complains that the default memory (64k)isn't enough + // Error: MilesEvent: Out of event system memory (pool passed to event + // system startup exhausted). AP - increased command buffer from the default + // 5K to 20K for Vita - if (AIL_startup_event_system(m_hDriver, 1024*20, 0, 1024*128) == 0) - { - app.DebugPrintf("Couldn't init event system (%s).\n", AIL_last_error()); - AIL_close_digital_driver(m_hDriver); - AIL_shutdown(); + if (AIL_startup_event_system(m_hDriver, 1024 * 20, 0, 1024 * 128) == 0) { + app.DebugPrintf("Couldn't init event system (%s).\n", AIL_last_error()); + AIL_close_digital_driver(m_hDriver); + AIL_shutdown(); #ifdef __ORBIS__ - C4JThread::PopAffinity(); -#endif - app.DebugPrintf("---SoundEngine::init - AIL_startup_event_system failed\n"); - return; - } - char szBankName[255]; -#if defined __PS3__ - if(app.GetBootedFromDiscPatch()) - { - char szTempSoundFilename[255]; - sprintf(szTempSoundFilename,"%s%s",m_szSoundPath, "Minecraft.msscmp" ); + C4JThread::PopAffinity(); +#endif + app.DebugPrintf( + "---SoundEngine::init - AIL_startup_event_system failed\n"); + return; + } + char szBankName[255]; +#if defined __PS3__ + if (app.GetBootedFromDiscPatch()) { + char szTempSoundFilename[255]; + sprintf(szTempSoundFilename, "%s%s", m_szSoundPath, "Minecraft.msscmp"); + + app.DebugPrintf( + "SoundEngine::playMusicUpdate - (booted from disc patch) looking " + "for %s\n", + szTempSoundFilename); + sprintf(szBankName, "%s/%s", app.GetBDUsrDirPath(szTempSoundFilename), + m_szSoundPath); + app.DebugPrintf( + "SoundEngine::playMusicUpdate - (booted from disc patch) music " + "path - %s\n", + szBankName); + } else { + sprintf(szBankName, "%s/%s", getUsrDirPath(), m_szSoundPath); + } - app.DebugPrintf("SoundEngine::playMusicUpdate - (booted from disc patch) looking for %s\n",szTempSoundFilename); - sprintf(szBankName,"%s/%s",app.GetBDUsrDirPath(szTempSoundFilename), m_szSoundPath ); - app.DebugPrintf("SoundEngine::playMusicUpdate - (booted from disc patch) music path - %s\n",szBankName); - } - else - { - sprintf(szBankName,"%s/%s",getUsrDirPath(), m_szSoundPath ); - } - #elif defined __PSVITA__ - sprintf(szBankName,"%s/%s",getUsrDirPath(), m_szSoundPath ); + sprintf(szBankName, "%s/%s", getUsrDirPath(), m_szSoundPath); #elif defined __ORBIS__ - sprintf(szBankName,"%s/%s",getUsrDirPath(), m_szSoundPath ); + sprintf(szBankName, "%s/%s", getUsrDirPath(), m_szSoundPath); #else - strcpy((char *)szBankName,m_szSoundPath); + strcpy((char*)szBankName, m_szSoundPath); #endif - strcat((char *)szBankName,"Minecraft.msscmp"); + strcat((char*)szBankName, "Minecraft.msscmp"); - m_hBank=AIL_add_soundbank(szBankName, 0); + m_hBank = AIL_add_soundbank(szBankName, 0); - if(m_hBank == NULL) - { - char *Error=AIL_last_error(); - app.DebugPrintf("Couldn't open soundbank: %s (%s)\n", szBankName, Error); - AIL_close_digital_driver(m_hDriver); - AIL_shutdown(); + if (m_hBank == NULL) { + char* Error = AIL_last_error(); + app.DebugPrintf("Couldn't open soundbank: %s (%s)\n", szBankName, + Error); + AIL_close_digital_driver(m_hDriver); + AIL_shutdown(); #ifdef __ORBIS__ - C4JThread::PopAffinity(); -#endif - return; - } + C4JThread::PopAffinity(); +#endif + return; + } - //#ifdef _DEBUG - HMSSENUM token = MSS_FIRST; - char const* Events[1] = {0}; - S32 EventCount = 0; - while (AIL_enumerate_events(m_hBank, &token, 0, &Events[0])) - { - app.DebugPrintf(4,"%d - %s\n", EventCount, Events[0]); + // #ifdef _DEBUG + HMSSENUM token = MSS_FIRST; + char const* Events[1] = {0}; + S32 EventCount = 0; + while (AIL_enumerate_events(m_hBank, &token, 0, &Events[0])) { + app.DebugPrintf(4, "%d - %s\n", EventCount, Events[0]); - EventCount++; - } - //#endif + EventCount++; + } + // #endif - U64 u64Result; - u64Result=AIL_enqueue_event_by_name("Minecraft/CacheSounds"); + U64 u64Result; + u64Result = AIL_enqueue_event_by_name("Minecraft/CacheSounds"); - m_MasterMusicVolume=1.0f; - m_MasterEffectsVolume=1.0f; + m_MasterMusicVolume = 1.0f; + m_MasterEffectsVolume = 1.0f; - //AIL_set_variable_float(0,"UserEffectVol",1); + // AIL_set_variable_float(0,"UserEffectVol",1); - m_bSystemMusicPlaying = false; + m_bSystemMusicPlaying = false; - m_openStreamThread = NULL; + m_openStreamThread = NULL; #ifdef __ORBIS__ - C4JThread::PopAffinity(); + C4JThread::PopAffinity(); #endif #ifdef __PSVITA__ - // AP - By default the mixer won't start up and nothing will process. Kick off a blank sample to force the mixer to start up. - HSAMPLE Sample = AIL_allocate_sample_handle(m_hDriver); - AIL_init_sample(Sample, DIG_F_STEREO_16); - static U64 silence = 0; - AIL_set_sample_address(Sample, &silence, sizeof(U64)); - AIL_start_sample(Sample); + // AP - By default the mixer won't start up and nothing will process. Kick + // off a blank sample to force the mixer to start up. + HSAMPLE Sample = AIL_allocate_sample_handle(m_hDriver); + AIL_init_sample(Sample, DIG_F_STEREO_16); + static U64 silence = 0; + AIL_set_sample_address(Sample, &silence, sizeof(U64)); + AIL_start_sample(Sample); - // wait for 1 mix... - AIL_release_sample_handle(Sample); + // wait for 1 mix... + AIL_release_sample_handle(Sample); #endif } @@ -1274,217 +1216,241 @@ void SoundEngine::init(Options *pOptions) // //m_hAudio=hAudio; // } #endif -// AP - moved to a separate function so it can be called from the mixer callback on Vita -void SoundEngine::updateMiles() -{ -#ifdef __PSVITA__ - //CD - We must check for Background Music [BGM] at any point - //If it's playing disable our audio, otherwise enable - int NoBGMPlaying = sceAudioOutGetAdopt(SCE_AUDIO_OUT_PORT_TYPE_BGM); - updateSystemMusicPlaying( !NoBGMPlaying ); +// AP - moved to a separate function so it can be called from the mixer callback +// on Vita +void SoundEngine::updateMiles() { +#ifdef __PSVITA__ + // CD - We must check for Background Music [BGM] at any point + // If it's playing disable our audio, otherwise enable + int NoBGMPlaying = sceAudioOutGetAdopt(SCE_AUDIO_OUT_PORT_TYPE_BGM); + updateSystemMusicPlaying(!NoBGMPlaying); #elif defined __ORBIS__ - // is the system playing background music? - SceAudioOutPortState outPortState; - sceAudioOutGetPortState(m_hBGMAudio,&outPortState); - updateSystemMusicPlaying( outPortState.output==SCE_AUDIO_OUT_STATE_OUTPUT_UNKNOWN ); + // is the system playing background music? + SceAudioOutPortState outPortState; + sceAudioOutGetPortState(m_hBGMAudio, &outPortState); + updateSystemMusicPlaying(outPortState.output == + SCE_AUDIO_OUT_STATE_OUTPUT_UNKNOWN); #endif - if( m_validListenerCount == 1 ) - { - for( int i = 0; i < MAX_LOCAL_PLAYERS; i++ ) - { - // set the listener as the first player we find - if( m_ListenerA[i].bValid ) - { - AIL_set_listener_3D_position(m_hDriver,m_ListenerA[i].vPosition.x,m_ListenerA[i].vPosition.y,-m_ListenerA[i].vPosition.z); // Flipped sign of z as Miles is expecting left handed coord system - AIL_set_listener_3D_orientation(m_hDriver,-m_ListenerA[i].vOrientFront.x,m_ListenerA[i].vOrientFront.y,m_ListenerA[i].vOrientFront.z,0,1,0); // Flipped sign of z as Miles is expecting left handed coord system - break; - } - } - } - else - { - // 4J-PB - special case for splitscreen - // the shortest distance between any listener and a sound will be used to play a sound a set distance away down the z axis. - // The listener position will be set to 0,0,0, and the orientation will be facing down the z axis + if (m_validListenerCount == 1) { + for (int i = 0; i < MAX_LOCAL_PLAYERS; i++) { + // set the listener as the first player we find + if (m_ListenerA[i].bValid) { + AIL_set_listener_3D_position( + m_hDriver, m_ListenerA[i].vPosition.x, + m_ListenerA[i].vPosition.y, + -m_ListenerA[i] + .vPosition.z); // Flipped sign of z as Miles is + // expecting left handed coord system + AIL_set_listener_3D_orientation( + m_hDriver, -m_ListenerA[i].vOrientFront.x, + m_ListenerA[i].vOrientFront.y, + m_ListenerA[i].vOrientFront.z, 0, 1, + 0); // Flipped sign of z as Miles is expecting left handed + // coord system + break; + } + } + } else { + // 4J-PB - special case for splitscreen + // the shortest distance between any listener and a sound will be used + // to play a sound a set distance away down the z axis. The listener + // position will be set to 0,0,0, and the orientation will be facing + // down the z axis - AIL_set_listener_3D_position(m_hDriver,0,0,0); - AIL_set_listener_3D_orientation(m_hDriver,0,0,1,0,1,0); - } + AIL_set_listener_3D_position(m_hDriver, 0, 0, 0); + AIL_set_listener_3D_orientation(m_hDriver, 0, 0, 1, 0, 1, 0); + } - AIL_begin_event_queue_processing(); + AIL_begin_event_queue_processing(); - // Iterate over the sounds - S32 StartedCount = 0, CompletedCount = 0, TotalCount = 0; - HMSSENUM token = MSS_FIRST; - MILESEVENTSOUNDINFO SoundInfo; - int Playing = 0; - while (AIL_enumerate_sound_instances(0, &token, 0, 0, 0, &SoundInfo)) - { - AUDIO_INFO* game_data= (AUDIO_INFO*)( SoundInfo.UserBuffer ); + // Iterate over the sounds + S32 StartedCount = 0, CompletedCount = 0, TotalCount = 0; + HMSSENUM token = MSS_FIRST; + MILESEVENTSOUNDINFO SoundInfo; + int Playing = 0; + while (AIL_enumerate_sound_instances(0, &token, 0, 0, 0, &SoundInfo)) { + AUDIO_INFO* game_data = (AUDIO_INFO*)(SoundInfo.UserBuffer); - if( SoundInfo.Status == MILESEVENT_SOUND_STATUS_PLAYING ) - { - Playing += 1; - } + if (SoundInfo.Status == MILESEVENT_SOUND_STATUS_PLAYING) { + Playing += 1; + } - if ( SoundInfo.Status != MILESEVENT_SOUND_STATUS_COMPLETE ) - { - // apply the master volume - // watch for the 'special' volume levels - bool isThunder = false; - if( game_data->volume == 10000.0f ) - { - isThunder = true; - } - if(game_data->volume>1) - { - game_data->volume=1; - } - AIL_set_sample_volume_levels( SoundInfo.Sample, game_data->volume*m_MasterEffectsVolume, game_data->volume*m_MasterEffectsVolume); + if (SoundInfo.Status != MILESEVENT_SOUND_STATUS_COMPLETE) { + // apply the master volume + // watch for the 'special' volume levels + bool isThunder = false; + if (game_data->volume == 10000.0f) { + isThunder = true; + } + if (game_data->volume > 1) { + game_data->volume = 1; + } + AIL_set_sample_volume_levels( + SoundInfo.Sample, game_data->volume * m_MasterEffectsVolume, + game_data->volume * m_MasterEffectsVolume); - float distanceScaler = 16.0f; - switch(SoundInfo.Status) - { - case MILESEVENT_SOUND_STATUS_PENDING: - // 4J-PB - causes the falloff to be calculated on the PPU instead of the SPU, and seems to resolve our distorted sound issue - AIL_register_falloff_function_callback(SoundInfo.Sample,&custom_falloff_function); + float distanceScaler = 16.0f; + switch (SoundInfo.Status) { + case MILESEVENT_SOUND_STATUS_PENDING: + // 4J-PB - causes the falloff to be calculated on the PPU + // instead of the SPU, and seems to resolve our distorted + // sound issue + AIL_register_falloff_function_callback( + SoundInfo.Sample, &custom_falloff_function); - if(game_data->bIs3D) - { - AIL_set_sample_is_3D( SoundInfo.Sample, 1 ); + if (game_data->bIs3D) { + AIL_set_sample_is_3D(SoundInfo.Sample, 1); - int iSound = game_data->iSound - eSFX_MAX; - switch(iSound) - { - // Is this the Dragon? - case eSoundType_MOB_ENDERDRAGON_GROWL: - case eSoundType_MOB_ENDERDRAGON_MOVE: - case eSoundType_MOB_ENDERDRAGON_END: - case eSoundType_MOB_ENDERDRAGON_HIT: - distanceScaler=100.0f; - break; - case eSoundType_MOB_GHAST_MOAN: - case eSoundType_MOB_GHAST_SCREAM: - case eSoundType_MOB_GHAST_DEATH: - case eSoundType_MOB_GHAST_CHARGE: - case eSoundType_MOB_GHAST_FIREBALL: - distanceScaler=30.0f; - break; - } + int iSound = game_data->iSound - eSFX_MAX; + switch (iSound) { + // Is this the Dragon? + case eSoundType_MOB_ENDERDRAGON_GROWL: + case eSoundType_MOB_ENDERDRAGON_MOVE: + case eSoundType_MOB_ENDERDRAGON_END: + case eSoundType_MOB_ENDERDRAGON_HIT: + distanceScaler = 100.0f; + break; + case eSoundType_MOB_GHAST_MOAN: + case eSoundType_MOB_GHAST_SCREAM: + case eSoundType_MOB_GHAST_DEATH: + case eSoundType_MOB_GHAST_CHARGE: + case eSoundType_MOB_GHAST_FIREBALL: + distanceScaler = 30.0f; + break; + } - // Set a special distance scaler for thunder, which we respond to by having no attenutation - if( isThunder ) - { - distanceScaler = 10000.0f; - } - } - else - { - AIL_set_sample_is_3D( SoundInfo.Sample, 0 ); - } + // Set a special distance scaler for thunder, which we + // respond to by having no attenutation + if (isThunder) { + distanceScaler = 10000.0f; + } + } else { + AIL_set_sample_is_3D(SoundInfo.Sample, 0); + } - AIL_set_sample_3D_distances(SoundInfo.Sample,distanceScaler,1,0); - // set the pitch - if(!game_data->bUseSoundsPitchVal) - { - AIL_set_sample_playback_rate_factor(SoundInfo.Sample,game_data->pitch); - } + AIL_set_sample_3D_distances(SoundInfo.Sample, + distanceScaler, 1, 0); + // set the pitch + if (!game_data->bUseSoundsPitchVal) { + AIL_set_sample_playback_rate_factor(SoundInfo.Sample, + game_data->pitch); + } - if(game_data->bIs3D) - { - if(m_validListenerCount>1) - { - float fClosest=10000.0f; - int iClosestListener=0; - float fClosestX=0.0f,fClosestY=0.0f,fClosestZ=0.0f,fDist; - // need to calculate the distance from the sound to the nearest listener - use Manhattan Distance as the decision - for( int i = 0; i < MAX_LOCAL_PLAYERS; i++ ) - { - if( m_ListenerA[i].bValid ) - { - float x,y,z; + if (game_data->bIs3D) { + if (m_validListenerCount > 1) { + float fClosest = 10000.0f; + int iClosestListener = 0; + float fClosestX = 0.0f, fClosestY = 0.0f, + fClosestZ = 0.0f, fDist; + // need to calculate the distance from the sound to + // the nearest listener - use Manhattan Distance as + // the decision + for (int i = 0; i < MAX_LOCAL_PLAYERS; i++) { + if (m_ListenerA[i].bValid) { + float x, y, z; - x=fabs(m_ListenerA[i].vPosition.x-game_data->x); - y=fabs(m_ListenerA[i].vPosition.y-game_data->y); - z=fabs(m_ListenerA[i].vPosition.z-game_data->z); - fDist=x+y+z; + x = fabs(m_ListenerA[i].vPosition.x - + game_data->x); + y = fabs(m_ListenerA[i].vPosition.y - + game_data->y); + z = fabs(m_ListenerA[i].vPosition.z - + game_data->z); + fDist = x + y + z; - if(fDistx, game_data->y, -game_data->z ); // Flipped sign of z as Miles is expecting left handed coord system - } - } - break; + // app.DebugPrintf("Playing sound %d %f from nearest + // listener + // [%d]\n",SoundInfo.EventID,fDist,iClosestListener); + } else { + AIL_set_sample_3D_position( + SoundInfo.Sample, game_data->x, game_data->y, + -game_data->z); // Flipped sign of z as Miles + // is expecting left handed + // coord system + } + } + break; - default: - if(game_data->bIs3D) - { - if(m_validListenerCount>1) - { - float fClosest=10000.0f; - int iClosestListener=0; - float fClosestX=0.0f,fClosestY=0.0f,fClosestZ=0.0f,fDist; - // need to calculate the distance from the sound to the nearest listener - use Manhattan Distance as the decision - for( int i = 0; i < MAX_LOCAL_PLAYERS; i++ ) - { - if( m_ListenerA[i].bValid ) - { - float x,y,z; + default: + if (game_data->bIs3D) { + if (m_validListenerCount > 1) { + float fClosest = 10000.0f; + int iClosestListener = 0; + float fClosestX = 0.0f, fClosestY = 0.0f, + fClosestZ = 0.0f, fDist; + // need to calculate the distance from the sound to + // the nearest listener - use Manhattan Distance as + // the decision + for (int i = 0; i < MAX_LOCAL_PLAYERS; i++) { + if (m_ListenerA[i].bValid) { + float x, y, z; - x=fabs(m_ListenerA[i].vPosition.x-game_data->x); - y=fabs(m_ListenerA[i].vPosition.y-game_data->y); - z=fabs(m_ListenerA[i].vPosition.z-game_data->z); - fDist=x+y+z; + x = fabs(m_ListenerA[i].vPosition.x - + game_data->x); + y = fabs(m_ListenerA[i].vPosition.y - + game_data->y); + z = fabs(m_ListenerA[i].vPosition.z - + game_data->z); + fDist = x + y + z; - if(fDistx, game_data->y, -game_data->z ); // Flipped sign of z as Miles is expecting left handed coord system - } - } - break; - } - } - } - AIL_complete_event_queue_processing(); + // app.DebugPrintf("Playing sound %d %f from nearest + // listener + // [%d]\n",SoundInfo.EventID,fDist,iClosestListener); + } else { + AIL_set_sample_3D_position( + SoundInfo.Sample, game_data->x, game_data->y, + -game_data->z); // Flipped sign of z as Miles + // is expecting left handed + // coord system + } + } + break; + } + } + } + AIL_complete_event_queue_processing(); } -//#define DISTORTION_TEST +// #define DISTORTION_TEST #ifdef DISTORTION_TEST -static float fVal=0.0f; +static float fVal = 0.0f; #endif ///////////////////////////////////////////// // @@ -1496,120 +1462,111 @@ static float fVal=0.0f; static S32 running = AIL_ms_count(); #endif -void SoundEngine::tick(std::shared_ptr *players, float a) -{ +void SoundEngine::tick(std::shared_ptr* players, float a) { #ifdef __DISABLE_MILES__ - return; + return; #endif #ifdef __PSVITA__ - EnterCriticalSection(&SoundEngine_MixerMutex); + EnterCriticalSection(&SoundEngine_MixerMutex); #endif - // update the listener positions - int listenerCount = 0; + // update the listener positions + int listenerCount = 0; #ifdef DISTORTION_TEST - float fX,fY,fZ; + float fX, fY, fZ; #endif - if( players ) - { - bool bListenerPostionSet=false; - for( int i = 0; i < MAX_LOCAL_PLAYERS; i++ ) - { - if( players[i] != NULL ) - { - m_ListenerA[i].bValid=true; - F32 x,y,z; - x=players[i]->xo + (players[i]->x - players[i]->xo) * a; - y=players[i]->yo + (players[i]->y - players[i]->yo) * a; - z=players[i]->zo + (players[i]->z - players[i]->zo) * a; + if (players) { + bool bListenerPostionSet = false; + for (int i = 0; i < MAX_LOCAL_PLAYERS; i++) { + if (players[i] != NULL) { + m_ListenerA[i].bValid = true; + F32 x, y, z; + x = players[i]->xo + (players[i]->x - players[i]->xo) * a; + y = players[i]->yo + (players[i]->y - players[i]->yo) * a; + z = players[i]->zo + (players[i]->z - players[i]->zo) * a; - float yRot = players[i]->yRotO + (players[i]->yRot - players[i]->yRotO) * a; - float yCos = (float)cos(-yRot * Mth::RAD_TO_GRAD - PI); - float ySin = (float)sin(-yRot * Mth::RAD_TO_GRAD - PI); + float yRot = players[i]->yRotO + + (players[i]->yRot - players[i]->yRotO) * a; + float yCos = (float)cos(-yRot * Mth::RAD_TO_GRAD - PI); + float ySin = (float)sin(-yRot * Mth::RAD_TO_GRAD - PI); - // store the listener positions for splitscreen - m_ListenerA[i].vPosition.x = x; - m_ListenerA[i].vPosition.y = y; - m_ListenerA[i].vPosition.z = z; + // store the listener positions for splitscreen + m_ListenerA[i].vPosition.x = x; + m_ListenerA[i].vPosition.y = y; + m_ListenerA[i].vPosition.z = z; - m_ListenerA[i].vOrientFront.x = ySin; - m_ListenerA[i].vOrientFront.y = 0; - m_ListenerA[i].vOrientFront.z = yCos; + m_ListenerA[i].vOrientFront.x = ySin; + m_ListenerA[i].vOrientFront.y = 0; + m_ListenerA[i].vOrientFront.z = yCos; - listenerCount++; - } - else - { - m_ListenerA[i].bValid=false; - } - } - } + listenerCount++; + } else { + m_ListenerA[i].bValid = false; + } + } + } - - // If there were no valid players set, make up a default listener - if( listenerCount == 0 ) - { - m_ListenerA[0].vPosition.x = 0; - m_ListenerA[0].vPosition.y = 0; - m_ListenerA[0].vPosition.z = 0; - m_ListenerA[0].vOrientFront.x = 0; - m_ListenerA[0].vOrientFront.y = 0; - m_ListenerA[0].vOrientFront.z = 1.0f; - listenerCount++; - } - m_validListenerCount = listenerCount; + // If there were no valid players set, make up a default listener + if (listenerCount == 0) { + m_ListenerA[0].vPosition.x = 0; + m_ListenerA[0].vPosition.y = 0; + m_ListenerA[0].vPosition.z = 0; + m_ListenerA[0].vOrientFront.x = 0; + m_ListenerA[0].vOrientFront.y = 0; + m_ListenerA[0].vOrientFront.z = 1.0f; + listenerCount++; + } + m_validListenerCount = listenerCount; #ifdef __PSVITA__ - // AP - Show that a change has occurred so we know to update the values at the next Mixer callback - SoundEngine_Change = true; + // AP - Show that a change has occurred so we know to update the values at + // the next Mixer callback + SoundEngine_Change = true; - LeaveCriticalSection(&SoundEngine_MixerMutex); + LeaveCriticalSection(&SoundEngine_MixerMutex); #else - updateMiles(); + updateMiles(); #endif } -SoundEngine::SoundEngine() -{ - random = new Random(); - m_hStream=0; - m_StreamState=eMusicStreamState_Idle; - m_iMusicDelay=0; - m_validListenerCount=0; +SoundEngine::SoundEngine() { + random = new Random(); + m_hStream = 0; + m_StreamState = eMusicStreamState_Idle; + m_iMusicDelay = 0; + m_validListenerCount = 0; - m_bHeardTrackA=NULL; + m_bHeardTrackA = NULL; - // Start the streaming music playing some music from the overworld - SetStreamingSounds(eStream_Overworld_Calm1,eStream_Overworld_piano3, - eStream_Nether1,eStream_Nether4, - eStream_end_dragon,eStream_end_end, - eStream_CD_1); + // Start the streaming music playing some music from the overworld + SetStreamingSounds(eStream_Overworld_Calm1, eStream_Overworld_piano3, + eStream_Nether1, eStream_Nether4, eStream_end_dragon, + eStream_end_end, eStream_CD_1); - m_musicID=getMusicID(LevelData::DIMENSION_OVERWORLD); + m_musicID = getMusicID(LevelData::DIMENSION_OVERWORLD); - m_StreamingAudioInfo.bIs3D=false; - m_StreamingAudioInfo.x=0; - m_StreamingAudioInfo.y=0; - m_StreamingAudioInfo.z=0; - m_StreamingAudioInfo.volume=1; - m_StreamingAudioInfo.pitch=1; + m_StreamingAudioInfo.bIs3D = false; + m_StreamingAudioInfo.x = 0; + m_StreamingAudioInfo.y = 0; + m_StreamingAudioInfo.z = 0; + m_StreamingAudioInfo.volume = 1; + m_StreamingAudioInfo.pitch = 1; - memset(CurrentSoundsPlaying,0,sizeof(int)*(eSoundType_MAX+eSFX_MAX)); - memset(m_ListenerA,0,sizeof(AUDIO_LISTENER)*XUSER_MAX_COUNT); + memset(CurrentSoundsPlaying, 0, sizeof(int) * (eSoundType_MAX + eSFX_MAX)); + memset(m_ListenerA, 0, sizeof(AUDIO_LISTENER) * XUSER_MAX_COUNT); #ifdef __ORBIS__ - m_hBGMAudio=GetAudioBGMHandle(); + m_hBGMAudio = GetAudioBGMHandle(); #endif } void SoundEngine::destroy() {} #ifdef _DEBUG -void SoundEngine::GetSoundName(char *szSoundName,int iSound) -{ - strcpy((char *)szSoundName,"Minecraft/"); - std::wstring name = wchSoundNames[iSound]; - char *SoundName = (char *)ConvertSoundPathToName(name); - strcat((char *)szSoundName,SoundName); +void SoundEngine::GetSoundName(char* szSoundName, int iSound) { + strcpy((char*)szSoundName, "Minecraft/"); + std::wstring name = wchSoundNames[iSound]; + char* SoundName = (char*)ConvertSoundPathToName(name); + strcat((char*)szSoundName, SoundName); } #endif ///////////////////////////////////////////// @@ -1617,58 +1574,58 @@ void SoundEngine::GetSoundName(char *szSoundName,int iSound) // play // ///////////////////////////////////////////// -void SoundEngine::play(int iSound, float x, float y, float z, float volume, float pitch) -{ - U8 szSoundName[256]; +void SoundEngine::play(int iSound, float x, float y, float z, float volume, + float pitch) { + U8 szSoundName[256]; - if(iSound==-1) - { - app.DebugPrintf(6,"PlaySound with sound of -1 !!!!!!!!!!!!!!!\n"); - return; - } + if (iSound == -1) { + app.DebugPrintf(6, "PlaySound with sound of -1 !!!!!!!!!!!!!!!\n"); + return; + } - // AP removed old counting system. Now relying on Miles' Play Count Limit - /* // if we are already playing loads of this sounds ignore this one - if(CurrentSoundsPlaying[iSound+eSFX_MAX]>MAX_SAME_SOUNDS_PLAYING) - { - // std::wstring name = wchSoundNames[iSound]; - // char *SoundName = (char *)ConvertSoundPathToName(name); - // app.DebugPrintf("Too many %s sounds playing!\n",SoundName); - return; - }*/ + // AP removed old counting system. Now relying on Miles' Play Count Limit + /* // if we are already playing loads of this sounds ignore this one + if(CurrentSoundsPlaying[iSound+eSFX_MAX]>MAX_SAME_SOUNDS_PLAYING) + { + // std::wstring name = wchSoundNames[iSound]; + // char *SoundName = (char *)ConvertSoundPathToName(name); + // app.DebugPrintf("Too many %s sounds playing!\n",SoundName); + return; + }*/ - //if (iSound != eSoundType_MOB_IRONGOLEM_WALK) return; + // if (iSound != eSoundType_MOB_IRONGOLEM_WALK) return; - // build the name - strcpy((char *)szSoundName,"Minecraft/"); + // build the name + strcpy((char*)szSoundName, "Minecraft/"); #ifdef DISTORTION_TEST - std::wstring name = wchSoundNames[eSoundType_MOB_ENDERDRAGON_GROWL]; + std::wstring name = wchSoundNames[eSoundType_MOB_ENDERDRAGON_GROWL]; #else - std::wstring name = wchSoundNames[iSound]; + std::wstring name = wchSoundNames[iSound]; #endif - char *SoundName = (char *)ConvertSoundPathToName(name); - strcat((char *)szSoundName,SoundName); + char* SoundName = (char*)ConvertSoundPathToName(name); + strcat((char*)szSoundName, SoundName); -// app.DebugPrintf(6,"PlaySound - %d - %s - %s (%f %f %f, vol %f, pitch %f)\n",iSound, SoundName, szSoundName,x,y,z,volume,pitch); + // app.DebugPrintf(6,"PlaySound - %d - %s - %s (%f %f %f, vol %f, pitch + //%f)\n",iSound, SoundName, szSoundName,x,y,z,volume,pitch); - AUDIO_INFO AudioInfo; - AudioInfo.x=x; - AudioInfo.y=y; - AudioInfo.z=z; - AudioInfo.volume=volume; - AudioInfo.pitch=pitch; - AudioInfo.bIs3D=true; - AudioInfo.bUseSoundsPitchVal=false; - AudioInfo.iSound=iSound+eSFX_MAX; + AUDIO_INFO AudioInfo; + AudioInfo.x = x; + AudioInfo.y = y; + AudioInfo.z = z; + AudioInfo.volume = volume; + AudioInfo.pitch = pitch; + AudioInfo.bIs3D = true; + AudioInfo.bUseSoundsPitchVal = false; + AudioInfo.iSound = iSound + eSFX_MAX; #ifdef _DEBUG - strncpy(AudioInfo.chName,(char *)szSoundName,64); + strncpy(AudioInfo.chName, (char*)szSoundName, 64); #endif - S32 token = AIL_enqueue_event_start(); - AIL_enqueue_event_buffer(&token, &AudioInfo, sizeof(AUDIO_INFO), 0); - AIL_enqueue_event_end_named(token, (char *)szSoundName); + S32 token = AIL_enqueue_event_start(); + AIL_enqueue_event_buffer(&token, &AudioInfo, sizeof(AUDIO_INFO), 0); + AIL_enqueue_event_end_named(token, (char*)szSoundName); } ///////////////////////////////////////////// @@ -1676,658 +1633,653 @@ void SoundEngine::play(int iSound, float x, float y, float z, float volume, floa // playUI // ///////////////////////////////////////////// -void SoundEngine::playUI(int iSound, float volume, float pitch) -{ - U8 szSoundName[256]; - std::wstring name; - // we have some game sounds played as UI sounds... - // Not the best way to do this, but it seems to only be the portal sounds +void SoundEngine::playUI(int iSound, float volume, float pitch) { + U8 szSoundName[256]; + std::wstring name; + // we have some game sounds played as UI sounds... + // Not the best way to do this, but it seems to only be the portal sounds - if(iSound>=eSFX_MAX) - { - // AP removed old counting system. Now relying on Miles' Play Count Limit - /* // if we are already playing loads of this sounds ignore this one - if(CurrentSoundsPlaying[iSound+eSFX_MAX]>MAX_SAME_SOUNDS_PLAYING) return;*/ + if (iSound >= eSFX_MAX) { + // AP removed old counting system. Now relying on Miles' Play Count + // Limit + /* // if we are already playing loads of this sounds ignore + this one + if(CurrentSoundsPlaying[iSound+eSFX_MAX]>MAX_SAME_SOUNDS_PLAYING) + return;*/ - // build the name - strcpy((char *)szSoundName,"Minecraft/"); - name = wchSoundNames[iSound]; - } - else - { - // AP removed old counting system. Now relying on Miles' Play Count Limit - /* // if we are already playing loads of this sounds ignore this one - if(CurrentSoundsPlaying[iSound]>MAX_SAME_SOUNDS_PLAYING) return;*/ + // build the name + strcpy((char*)szSoundName, "Minecraft/"); + name = wchSoundNames[iSound]; + } else { + // AP removed old counting system. Now relying on Miles' Play Count + // Limit + /* // if we are already playing loads of this sounds ignore + this one if(CurrentSoundsPlaying[iSound]>MAX_SAME_SOUNDS_PLAYING) + return;*/ - // build the name - strcpy((char *)szSoundName,"Minecraft/UI/"); - name = wchUISoundNames[iSound]; - } + // build the name + strcpy((char*)szSoundName, "Minecraft/UI/"); + name = wchUISoundNames[iSound]; + } - char *SoundName = (char *)ConvertSoundPathToName(name); - strcat((char *)szSoundName,SoundName); -// app.DebugPrintf("UI: Playing %s, volume %f, pitch %f\n",SoundName,volume,pitch); + char* SoundName = (char*)ConvertSoundPathToName(name); + strcat((char*)szSoundName, SoundName); + // app.DebugPrintf("UI: Playing %s, volume %f, pitch + //%f\n",SoundName,volume,pitch); - //app.DebugPrintf("PlaySound - %d - %s\n",iSound, SoundName); + // app.DebugPrintf("PlaySound - %d - %s\n",iSound, SoundName); - AUDIO_INFO AudioInfo; - memset(&AudioInfo,0,sizeof(AUDIO_INFO)); - AudioInfo.volume=volume; // will be multiplied by the master volume - AudioInfo.pitch=pitch; - AudioInfo.bUseSoundsPitchVal=true; - if(iSound>=eSFX_MAX) - { - AudioInfo.iSound=iSound+eSFX_MAX; - } - else - { - AudioInfo.iSound=iSound; - } + AUDIO_INFO AudioInfo; + memset(&AudioInfo, 0, sizeof(AUDIO_INFO)); + AudioInfo.volume = volume; // will be multiplied by the master volume + AudioInfo.pitch = pitch; + AudioInfo.bUseSoundsPitchVal = true; + if (iSound >= eSFX_MAX) { + AudioInfo.iSound = iSound + eSFX_MAX; + } else { + AudioInfo.iSound = iSound; + } #ifdef _DEBUG - strncpy(AudioInfo.chName,(char *)szSoundName,64); + strncpy(AudioInfo.chName, (char*)szSoundName, 64); #endif - // 4J-PB - not going to stop UI events happening based on the number of currently playing sounds - S32 token = AIL_enqueue_event_start(); - AIL_enqueue_event_buffer(&token, &AudioInfo, sizeof(AUDIO_INFO), 0); - AIL_enqueue_event_end_named(token, (char *)szSoundName); + // 4J-PB - not going to stop UI events happening based on the number of + // currently playing sounds + S32 token = AIL_enqueue_event_start(); + AIL_enqueue_event_buffer(&token, &AudioInfo, sizeof(AUDIO_INFO), 0); + AIL_enqueue_event_end_named(token, (char*)szSoundName); } ///////////////////////////////////////////// // // playStreaming // ///////////////////////////////////////////// -void SoundEngine::playStreaming(const std::wstring& name, float x, float y , float z, float volume, float pitch, bool bMusicDelay) -{ - // This function doesn't actually play a streaming sound, just sets states and an id for the music tick to play it - // Level audio will be played when a play with an empty name comes in - // CD audio will be played when a named stream comes in +void SoundEngine::playStreaming(const std::wstring& name, float x, float y, + float z, float volume, float pitch, + bool bMusicDelay) { + // This function doesn't actually play a streaming sound, just sets states + // and an id for the music tick to play it Level audio will be played when a + // play with an empty name comes in CD audio will be played when a named + // stream comes in - m_StreamingAudioInfo.x=x; - m_StreamingAudioInfo.y=y; - m_StreamingAudioInfo.z=z; - m_StreamingAudioInfo.volume=volume; - m_StreamingAudioInfo.pitch=pitch; + m_StreamingAudioInfo.x = x; + m_StreamingAudioInfo.y = y; + m_StreamingAudioInfo.z = z; + m_StreamingAudioInfo.volume = volume; + m_StreamingAudioInfo.pitch = pitch; - if(m_StreamState==eMusicStreamState_Playing) - { - m_StreamState=eMusicStreamState_Stop; - } - else if(m_StreamState==eMusicStreamState_Opening) - { - m_StreamState=eMusicStreamState_OpeningCancel; - } + if (m_StreamState == eMusicStreamState_Playing) { + m_StreamState = eMusicStreamState_Stop; + } else if (m_StreamState == eMusicStreamState_Opening) { + m_StreamState = eMusicStreamState_OpeningCancel; + } - if(name.empty()) - { - // music, or stop CD - m_StreamingAudioInfo.bIs3D=false; + if (name.empty()) { + // music, or stop CD + m_StreamingAudioInfo.bIs3D = false; - // we need a music id - // random delay of up to 3 minutes for music - m_iMusicDelay = random->nextInt(20 * 60 * 3);//random->nextInt(20 * 60 * 10) + 20 * 60 * 10; + // we need a music id + // random delay of up to 3 minutes for music + m_iMusicDelay = random->nextInt( + 20 * 60 * 3); // random->nextInt(20 * 60 * 10) + 20 * 60 * 10; #ifdef _DEBUG - m_iMusicDelay=0; + m_iMusicDelay = 0; #endif - Minecraft *pMinecraft=Minecraft::GetInstance(); + Minecraft* pMinecraft = Minecraft::GetInstance(); - bool playerInEnd=false; - bool playerInNether=false; + bool playerInEnd = false; + bool playerInNether = false; - for(unsigned int i=0;ilocalplayers[i]!=NULL) - { - if(pMinecraft->localplayers[i]->dimension==LevelData::DIMENSION_END) - { - playerInEnd=true; - } - else if(pMinecraft->localplayers[i]->dimension==LevelData::DIMENSION_NETHER) - { - playerInNether=true; - } - } - } - if(playerInEnd) - { - m_musicID = getMusicID(LevelData::DIMENSION_END); - } - else if(playerInNether) - { - m_musicID = getMusicID(LevelData::DIMENSION_NETHER); - } - else - { - m_musicID = getMusicID(LevelData::DIMENSION_OVERWORLD); - } - } - else - { - // jukebox - m_StreamingAudioInfo.bIs3D=true; - m_musicID=getMusicID(name); - m_iMusicDelay=0; - } + for (unsigned int i = 0; i < MAX_LOCAL_PLAYERS; i++) { + if (pMinecraft->localplayers[i] != NULL) { + if (pMinecraft->localplayers[i]->dimension == + LevelData::DIMENSION_END) { + playerInEnd = true; + } else if (pMinecraft->localplayers[i]->dimension == + LevelData::DIMENSION_NETHER) { + playerInNether = true; + } + } + } + if (playerInEnd) { + m_musicID = getMusicID(LevelData::DIMENSION_END); + } else if (playerInNether) { + m_musicID = getMusicID(LevelData::DIMENSION_NETHER); + } else { + m_musicID = getMusicID(LevelData::DIMENSION_OVERWORLD); + } + } else { + // jukebox + m_StreamingAudioInfo.bIs3D = true; + m_musicID = getMusicID(name); + m_iMusicDelay = 0; + } } -int SoundEngine::OpenStreamThreadProc( void* lpParameter ) -{ +int SoundEngine::OpenStreamThreadProc(void* lpParameter) { #ifdef __DISABLE_MILES__ - return 0; + return 0; #endif - SoundEngine *soundEngine = (SoundEngine *)lpParameter; - soundEngine->m_hStream = AIL_open_stream(soundEngine->m_hDriver,soundEngine->m_szStreamName,0); - return 0; + SoundEngine* soundEngine = (SoundEngine*)lpParameter; + soundEngine->m_hStream = + AIL_open_stream(soundEngine->m_hDriver, soundEngine->m_szStreamName, 0); + return 0; } ///////////////////////////////////////////// // // playMusicTick // ///////////////////////////////////////////// -void SoundEngine::playMusicTick() -{ +void SoundEngine::playMusicTick() { // AP - vita will update the music during the mixer callback #ifndef __PSVITA__ - playMusicUpdate(); + playMusicUpdate(); #endif } -// AP - moved to a separate function so it can be called from the mixer callback on Vita -void SoundEngine::playMusicUpdate() -{ - //return; - static bool firstCall = true; - static float fMusicVol = 0.0f; - if( firstCall ) - { - fMusicVol = getMasterMusicVolume(); - firstCall = false; - } +// AP - moved to a separate function so it can be called from the mixer callback +// on Vita +void SoundEngine::playMusicUpdate() { + // return; + static bool firstCall = true; + static float fMusicVol = 0.0f; + if (firstCall) { + fMusicVol = getMasterMusicVolume(); + firstCall = false; + } - switch(m_StreamState) - { - case eMusicStreamState_Idle: + switch (m_StreamState) { + case eMusicStreamState_Idle: - // start a stream playing - if (m_iMusicDelay > 0) - { - m_iMusicDelay--; - return; - } + // start a stream playing + if (m_iMusicDelay > 0) { + m_iMusicDelay--; + return; + } - if(m_musicID!=-1) - { - // start playing it + if (m_musicID != -1) { + // start playing it - -#if ( defined __PS3__ || defined __PSVITA__ || defined __ORBIS__ ) +#if (defined __PS3__ || defined __PSVITA__ || defined __ORBIS__) #ifdef __PS3__ - // 4J-PB - Need to check if we are a patched BD build - if(app.GetBootedFromDiscPatch()) - { - sprintf(m_szStreamName,"%s/%s",app.GetBDUsrDirPath(m_szMusicPath), m_szMusicPath ); - app.DebugPrintf("SoundEngine::playMusicUpdate - (booted from disc patch) music path - %s",m_szStreamName); - } - else - { - sprintf(m_szStreamName,"%s/%s",getUsrDirPath(), m_szMusicPath ); - } + // 4J-PB - Need to check if we are a patched BD build + if (app.GetBootedFromDiscPatch()) { + sprintf(m_szStreamName, "%s/%s", + app.GetBDUsrDirPath(m_szMusicPath), m_szMusicPath); + app.DebugPrintf( + "SoundEngine::playMusicUpdate - (booted from disc " + "patch) music path - %s", + m_szStreamName); + } else { + sprintf(m_szStreamName, "%s/%s", getUsrDirPath(), + m_szMusicPath); + } #else - sprintf(m_szStreamName,"%s/%s",getUsrDirPath(), m_szMusicPath ); + sprintf(m_szStreamName, "%s/%s", getUsrDirPath(), + m_szMusicPath); #endif #else - strcpy((char *)m_szStreamName,m_szMusicPath); + strcpy((char*)m_szStreamName, m_szMusicPath); #endif - // are we using a mash-up pack? - //if(pMinecraft && !pMinecraft->skins->isUsingDefaultSkin() && pMinecraft->skins->getSelected()->hasAudio()) - if(Minecraft::GetInstance()->skins->getSelected()->hasAudio()) - { - // It's a mash-up - need to use the DLC path for the music - TexturePack *pTexPack=Minecraft::GetInstance()->skins->getSelected(); - DLCTexturePack *pDLCTexPack=(DLCTexturePack *)pTexPack; - DLCPack *pack = pDLCTexPack->getDLCInfoParentPack(); - DLCAudioFile *dlcAudioFile = (DLCAudioFile *) pack->getFile(DLCManager::e_DLCType_Audio, 0); + // are we using a mash-up pack? + // if(pMinecraft && !pMinecraft->skins->isUsingDefaultSkin() && + // pMinecraft->skins->getSelected()->hasAudio()) + if (Minecraft::GetInstance() + ->skins->getSelected() + ->hasAudio()) { + // It's a mash-up - need to use the DLC path for the music + TexturePack* pTexPack = + Minecraft::GetInstance()->skins->getSelected(); + DLCTexturePack* pDLCTexPack = (DLCTexturePack*)pTexPack; + DLCPack* pack = pDLCTexPack->getDLCInfoParentPack(); + DLCAudioFile* dlcAudioFile = (DLCAudioFile*)pack->getFile( + DLCManager::e_DLCType_Audio, 0); - app.DebugPrintf("Mashup pack \n"); + app.DebugPrintf("Mashup pack \n"); - // build the name + // build the name + + // if the music ID is beyond the end of the texture pack + // music files, then it's a CD + if (m_musicID < m_iStream_CD_1) { + SetIsPlayingStreamingGameMusic(true); + SetIsPlayingStreamingCDMusic(false); + m_MusicType = eMusicType_Game; + m_StreamingAudioInfo.bIs3D = false; - // if the music ID is beyond the end of the texture pack music files, then it's a CD - if(m_musicIDGetSoundName(m_musicID); - std::wstring wstrFile=L"TPACK:\\Data\\" + wstrSoundName +L".binka"; - std::wstring mountedPath = StorageManager.GetMountedPath(wstrFile); - wcstombs(m_szStreamName,mountedPath.c_str(),255); + std::wstring& wstrSoundName = + dlcAudioFile->GetSoundName(m_musicID); + std::wstring wstrFile = + L"TPACK:\\Data\\" + wstrSoundName + L".binka"; + std::wstring mountedPath = + StorageManager.GetMountedPath(wstrFile); + wcstombs(m_szStreamName, mountedPath.c_str(), 255); #else - std::wstring &wstrSoundName=dlcAudioFile->GetSoundName(m_musicID); - char szName[255]; - wcstombs(szName,wstrSoundName.c_str(),255); + std::wstring& wstrSoundName = + dlcAudioFile->GetSoundName(m_musicID); + char szName[255]; + wcstombs(szName, wstrSoundName.c_str(), 255); - std::string strFile="TPACK:\\Data\\" + string(szName) + ".binka"; - std::string mountedPath = StorageManager.GetMountedPath(strFile); - strcpy(m_szStreamName,mountedPath.c_str()); + std::string strFile = + "TPACK:\\Data\\" + string(szName) + ".binka"; + std::string mountedPath = + StorageManager.GetMountedPath(strFile); + strcpy(m_szStreamName, mountedPath.c_str()); #endif - } - else - { - SetIsPlayingStreamingGameMusic(false); - SetIsPlayingStreamingCDMusic(true); - m_MusicType=eMusicType_CD; - m_StreamingAudioInfo.bIs3D=true; + } else { + SetIsPlayingStreamingGameMusic(false); + SetIsPlayingStreamingCDMusic(true); + m_MusicType = eMusicType_CD; + m_StreamingAudioInfo.bIs3D = true; - // Need to adjust to index into the cds in the game's m_szStreamFileA - strcat((char *)m_szStreamName,"cds/"); - strcat((char *)m_szStreamName,m_szStreamFileA[m_musicID-m_iStream_CD_1+eStream_CD_1]); - strcat((char *)m_szStreamName,".binka"); - } - } - else - { - // 4J-PB - if this is a PS3 disc patch, we have to check if the music file is in the patch data + // Need to adjust to index into the cds in the game's + // m_szStreamFileA + strcat((char*)m_szStreamName, "cds/"); + strcat((char*)m_szStreamName, + m_szStreamFileA[m_musicID - m_iStream_CD_1 + + eStream_CD_1]); + strcat((char*)m_szStreamName, ".binka"); + } + } else { + // 4J-PB - if this is a PS3 disc patch, we have to check if + // the music file is in the patch data #ifdef __PS3__ - if(app.GetBootedFromDiscPatch() && (m_musicIDRun(); + m_StreamState = eMusicStreamState_Opening; + } + break; - // Don't actually open in this thread, as it can block for ~300ms. - m_openStreamThread = new C4JThread(OpenStreamThreadProc, this, "OpenStreamThreadProc"); - m_openStreamThread->Run(); - m_StreamState = eMusicStreamState_Opening; - } - break; + case eMusicStreamState_Opening: + // If the open stream thread is complete, then we are ready to + // proceed to actually playing + if (!m_openStreamThread->isRunning()) { + delete m_openStreamThread; + m_openStreamThread = NULL; - case eMusicStreamState_Opening: - // If the open stream thread is complete, then we are ready to proceed to actually playing - if( !m_openStreamThread->isRunning() ) - { - delete m_openStreamThread; - m_openStreamThread = NULL; + HSAMPLE hSample = AIL_stream_sample_handle(m_hStream); - HSAMPLE hSample = AIL_stream_sample_handle( m_hStream); + // 4J-PB - causes the falloff to be calculated on the PPU + // instead of the SPU, and seems to resolve our distorted sound + // issue + AIL_register_falloff_function_callback( + hSample, &custom_falloff_function); - // 4J-PB - causes the falloff to be calculated on the PPU instead of the SPU, and seems to resolve our distorted sound issue - AIL_register_falloff_function_callback(hSample,&custom_falloff_function); + if (m_StreamingAudioInfo.bIs3D) { + AIL_set_sample_3D_distances( + hSample, 64.0f, 1, + 0); // Larger distance scaler for music discs + if (m_validListenerCount > 1) { + float fClosest = 10000.0f; + int iClosestListener = 0; + float fClosestX = 0.0f, fClosestY = 0.0f, + fClosestZ = 0.0f, fDist; + // need to calculate the distance from the sound to the + // nearest listener - use Manhattan Distance as the + // decision + for (int i = 0; i < MAX_LOCAL_PLAYERS; i++) { + if (m_ListenerA[i].bValid) { + float x, y, z; - if(m_StreamingAudioInfo.bIs3D) - { - AIL_set_sample_3D_distances(hSample,64.0f,1,0); // Larger distance scaler for music discs - if(m_validListenerCount>1) - { - float fClosest=10000.0f; - int iClosestListener=0; - float fClosestX=0.0f,fClosestY=0.0f,fClosestZ=0.0f,fDist; - // need to calculate the distance from the sound to the nearest listener - use Manhattan Distance as the decision - for( int i = 0; i < MAX_LOCAL_PLAYERS; i++ ) - { - if( m_ListenerA[i].bValid ) - { - float x,y,z; + x = fabs(m_ListenerA[i].vPosition.x - + m_StreamingAudioInfo.x); + y = fabs(m_ListenerA[i].vPosition.y - + m_StreamingAudioInfo.y); + z = fabs(m_ListenerA[i].vPosition.z - + m_StreamingAudioInfo.z); + fDist = x + y + z; - x=fabs(m_ListenerA[i].vPosition.x-m_StreamingAudioInfo.x); - y=fabs(m_ListenerA[i].vPosition.y-m_StreamingAudioInfo.y); - z=fabs(m_ListenerA[i].vPosition.z-m_StreamingAudioInfo.z); - fDist=x+y+z; + if (fDist < fClosest) { + fClosest = fDist; + fClosestX = x; + fClosestY = y; + fClosestZ = z; + iClosestListener = i; + } + } + } - if(fDistisRunning()) { + delete m_openStreamThread; + m_openStreamThread = NULL; + m_StreamState = eMusicStreamState_Stop; + } + break; + case eMusicStreamState_Stop: + // should gradually take the volume down in steps + AIL_pause_stream(m_hStream, 1); + AIL_close_stream(m_hStream); + m_hStream = 0; + SetIsPlayingStreamingCDMusic(false); + SetIsPlayingStreamingGameMusic(false); + m_StreamState = eMusicStreamState_Idle; + break; + case eMusicStreamState_Stopping: + break; + case eMusicStreamState_Play: + break; + case eMusicStreamState_Playing: + if (GetIsPlayingStreamingGameMusic()) { + // if(m_MusicInfo.pCue!=NULL) + { + bool playerInEnd = false; + bool playerInNether = false; + Minecraft* pMinecraft = Minecraft::GetInstance(); + for (unsigned int i = 0; i < MAX_LOCAL_PLAYERS; ++i) { + if (pMinecraft->localplayers[i] != NULL) { + if (pMinecraft->localplayers[i]->dimension == + LevelData::DIMENSION_END) { + playerInEnd = true; + } else if (pMinecraft->localplayers[i]->dimension == + LevelData::DIMENSION_NETHER) { + playerInNether = true; + } + } + } - m_StreamState=eMusicStreamState_Playing; - } - break; - case eMusicStreamState_OpeningCancel: - if( !m_openStreamThread->isRunning() ) - { - delete m_openStreamThread; - m_openStreamThread = NULL; - m_StreamState = eMusicStreamState_Stop; - } - break; - case eMusicStreamState_Stop: - // should gradually take the volume down in steps - AIL_pause_stream(m_hStream,1); - AIL_close_stream(m_hStream); - m_hStream=0; - SetIsPlayingStreamingCDMusic(false); - SetIsPlayingStreamingGameMusic(false); - m_StreamState=eMusicStreamState_Idle; - break; - case eMusicStreamState_Stopping: - break; - case eMusicStreamState_Play: - break; - case eMusicStreamState_Playing: - if(GetIsPlayingStreamingGameMusic()) - { - //if(m_MusicInfo.pCue!=NULL) - { - bool playerInEnd = false; - bool playerInNether=false; - Minecraft *pMinecraft = Minecraft::GetInstance(); - for(unsigned int i = 0; i < MAX_LOCAL_PLAYERS; ++i) - { - if(pMinecraft->localplayers[i]!=NULL) - { - if(pMinecraft->localplayers[i]->dimension==LevelData::DIMENSION_END) - { - playerInEnd=true; - } - else if(pMinecraft->localplayers[i]->dimension==LevelData::DIMENSION_NETHER) - { - playerInNether=true; - } - } - } + if (playerInEnd && !GetIsPlayingEndMusic()) { + m_StreamState = eMusicStreamState_Stop; - if(playerInEnd && !GetIsPlayingEndMusic()) - { - m_StreamState=eMusicStreamState_Stop; + // Set the end track + m_musicID = getMusicID(LevelData::DIMENSION_END); + SetIsPlayingEndMusic(true); + SetIsPlayingNetherMusic(false); + } else if (!playerInEnd && GetIsPlayingEndMusic()) { + if (playerInNether) { + m_StreamState = eMusicStreamState_Stop; - // Set the end track - m_musicID = getMusicID(LevelData::DIMENSION_END); - SetIsPlayingEndMusic(true); - SetIsPlayingNetherMusic(false); - } - else if(!playerInEnd && GetIsPlayingEndMusic()) - { - if(playerInNether) - { - m_StreamState=eMusicStreamState_Stop; + // Set the end track + m_musicID = getMusicID(LevelData::DIMENSION_NETHER); + SetIsPlayingEndMusic(false); + SetIsPlayingNetherMusic(true); + } else { + m_StreamState = eMusicStreamState_Stop; - // Set the end track - m_musicID = getMusicID(LevelData::DIMENSION_NETHER); - SetIsPlayingEndMusic(false); - SetIsPlayingNetherMusic(true); - } - else - { - m_StreamState=eMusicStreamState_Stop; + // Set the end track + m_musicID = + getMusicID(LevelData::DIMENSION_OVERWORLD); + SetIsPlayingEndMusic(false); + SetIsPlayingNetherMusic(false); + } + } else if (playerInNether && !GetIsPlayingNetherMusic()) { + m_StreamState = eMusicStreamState_Stop; + // set the Nether track + m_musicID = getMusicID(LevelData::DIMENSION_NETHER); + SetIsPlayingNetherMusic(true); + SetIsPlayingEndMusic(false); + } else if (!playerInNether && GetIsPlayingNetherMusic()) { + if (playerInEnd) { + m_StreamState = eMusicStreamState_Stop; + // set the Nether track + m_musicID = getMusicID(LevelData::DIMENSION_END); + SetIsPlayingNetherMusic(false); + SetIsPlayingEndMusic(true); + } else { + m_StreamState = eMusicStreamState_Stop; + // set the Nether track + m_musicID = + getMusicID(LevelData::DIMENSION_OVERWORLD); + SetIsPlayingNetherMusic(false); + SetIsPlayingEndMusic(false); + } + } - // Set the end track - m_musicID = getMusicID(LevelData::DIMENSION_OVERWORLD); - SetIsPlayingEndMusic(false); - SetIsPlayingNetherMusic(false); - } - } - else if (playerInNether && !GetIsPlayingNetherMusic()) - { - m_StreamState=eMusicStreamState_Stop; - // set the Nether track - m_musicID = getMusicID(LevelData::DIMENSION_NETHER); - SetIsPlayingNetherMusic(true); - SetIsPlayingEndMusic(false); - } - else if(!playerInNether && GetIsPlayingNetherMusic()) - { - if(playerInEnd) - { - m_StreamState=eMusicStreamState_Stop; - // set the Nether track - m_musicID = getMusicID(LevelData::DIMENSION_END); - SetIsPlayingNetherMusic(false); - SetIsPlayingEndMusic(true); - } - else - { - m_StreamState=eMusicStreamState_Stop; - // set the Nether track - m_musicID = getMusicID(LevelData::DIMENSION_OVERWORLD); - SetIsPlayingNetherMusic(false); - SetIsPlayingEndMusic(false); - } - } + // volume change required? + if (fMusicVol != getMasterMusicVolume()) { + fMusicVol = getMasterMusicVolume(); + HSAMPLE hSample = AIL_stream_sample_handle(m_hStream); + // AIL_set_sample_3D_position( hSample, + // m_StreamingAudioInfo.x, m_StreamingAudioInfo.y, + // m_StreamingAudioInfo.z ); + AIL_set_sample_volume_levels(hSample, fMusicVol, + fMusicVol); + } + } + } else { + // Music disc playing - if it's a 3D stream, then set the + // position - we don't have any streaming audio in the world + // that moves, so this isn't required unless we have more than + // one listener, and are setting the listening position to the + // origin and setting a fake position for the sound down the z + // axis + if (m_StreamingAudioInfo.bIs3D) { + if (m_validListenerCount > 1) { + float fClosest = 10000.0f; + int iClosestListener = 0; + float fClosestX = 0.0f, fClosestY = 0.0f, + fClosestZ = 0.0f, fDist; - // volume change required? - if(fMusicVol!=getMasterMusicVolume()) - { - fMusicVol=getMasterMusicVolume(); - HSAMPLE hSample = AIL_stream_sample_handle( m_hStream); - //AIL_set_sample_3D_position( hSample, m_StreamingAudioInfo.x, m_StreamingAudioInfo.y, m_StreamingAudioInfo.z ); - AIL_set_sample_volume_levels( hSample, fMusicVol, fMusicVol); - } - } - } - else - { - // Music disc playing - if it's a 3D stream, then set the position - we don't have any streaming audio in the world that moves, so this isn't - // required unless we have more than one listener, and are setting the listening position to the origin and setting a fake position - // for the sound down the z axis - if(m_StreamingAudioInfo.bIs3D) - { - if(m_validListenerCount>1) - { - float fClosest=10000.0f; - int iClosestListener=0; - float fClosestX=0.0f,fClosestY=0.0f,fClosestZ=0.0f,fDist; + // need to calculate the distance from the sound to the + // nearest listener - use Manhattan Distance as the + // decision + for (int i = 0; i < MAX_LOCAL_PLAYERS; i++) { + if (m_ListenerA[i].bValid) { + float x, y, z; - // need to calculate the distance from the sound to the nearest listener - use Manhattan Distance as the decision - for( int i = 0; i < MAX_LOCAL_PLAYERS; i++ ) - { - if( m_ListenerA[i].bValid ) - { - float x,y,z; + x = fabs(m_ListenerA[i].vPosition.x - + m_StreamingAudioInfo.x); + y = fabs(m_ListenerA[i].vPosition.y - + m_StreamingAudioInfo.y); + z = fabs(m_ListenerA[i].vPosition.z - + m_StreamingAudioInfo.z); + fDist = x + y + z; - x=fabs(m_ListenerA[i].vPosition.x-m_StreamingAudioInfo.x); - y=fabs(m_ListenerA[i].vPosition.y-m_StreamingAudioInfo.y); - z=fabs(m_ListenerA[i].vPosition.z-m_StreamingAudioInfo.z); - fDist=x+y+z; + if (fDist < fClosest) { + fClosest = fDist; + fClosestX = x; + fClosestY = y; + fClosestZ = z; + iClosestListener = i; + } + } + } - if(fDistnextInt( + 20 * 60 * 3); // random->nextInt(20 * 60 * 10) + 20 * 60 * 10; + // Check if we have a local player in The Nether or in The End, and + // play that music if they are + Minecraft* pMinecraft = Minecraft::GetInstance(); + bool playerInEnd = false; + bool playerInNether = false; - case eMusicStreamState_Completed: - { - // random delay of up to 3 minutes for music - m_iMusicDelay = random->nextInt(20 * 60 * 3);//random->nextInt(20 * 60 * 10) + 20 * 60 * 10; - // Check if we have a local player in The Nether or in The End, and play that music if they are - Minecraft *pMinecraft=Minecraft::GetInstance(); - bool playerInEnd=false; - bool playerInNether=false; + for (unsigned int i = 0; i < MAX_LOCAL_PLAYERS; i++) { + if (pMinecraft->localplayers[i] != NULL) { + if (pMinecraft->localplayers[i]->dimension == + LevelData::DIMENSION_END) { + playerInEnd = true; + } else if (pMinecraft->localplayers[i]->dimension == + LevelData::DIMENSION_NETHER) { + playerInNether = true; + } + } + } + if (playerInEnd) { + m_musicID = getMusicID(LevelData::DIMENSION_END); + SetIsPlayingEndMusic(true); + SetIsPlayingNetherMusic(false); + } else if (playerInNether) { + m_musicID = getMusicID(LevelData::DIMENSION_NETHER); + SetIsPlayingNetherMusic(true); + SetIsPlayingEndMusic(false); + } else { + m_musicID = getMusicID(LevelData::DIMENSION_OVERWORLD); + SetIsPlayingNetherMusic(false); + SetIsPlayingEndMusic(false); + } - for(unsigned int i=0;ilocalplayers[i]!=NULL) - { - if(pMinecraft->localplayers[i]->dimension==LevelData::DIMENSION_END) - { - playerInEnd=true; - } - else if(pMinecraft->localplayers[i]->dimension==LevelData::DIMENSION_NETHER) - { - playerInNether=true; - } - } - } - if(playerInEnd) - { - m_musicID = getMusicID(LevelData::DIMENSION_END); - SetIsPlayingEndMusic(true); - SetIsPlayingNetherMusic(false); - } - else if(playerInNether) - { - m_musicID = getMusicID(LevelData::DIMENSION_NETHER); - SetIsPlayingNetherMusic(true); - SetIsPlayingEndMusic(false); - } - else - { - m_musicID = getMusicID(LevelData::DIMENSION_OVERWORLD); - SetIsPlayingNetherMusic(false); - SetIsPlayingEndMusic(false); - } + m_StreamState = eMusicStreamState_Idle; + } break; + } - m_StreamState=eMusicStreamState_Idle; - } - break; - } + // check the status of the stream - this is for when a track completes + // rather than is stopped by the user action - // check the status of the stream - this is for when a track completes rather than is stopped by the user action + if (m_hStream != 0) { + if (AIL_stream_status(m_hStream) == SMP_DONE) // SMP_DONE + { + AIL_close_stream(m_hStream); + m_hStream = 0; + SetIsPlayingStreamingCDMusic(false); + SetIsPlayingStreamingGameMusic(false); - if(m_hStream!=0) - { - if(AIL_stream_status(m_hStream)==SMP_DONE ) // SMP_DONE - { - AIL_close_stream(m_hStream); - m_hStream=0; - SetIsPlayingStreamingCDMusic(false); - SetIsPlayingStreamingGameMusic(false); - - m_StreamState=eMusicStreamState_Completed; - } - } + m_StreamState = eMusicStreamState_Completed; + } + } } -F32 AILCALLBACK custom_falloff_function (HSAMPLE S, - F32 distance, - F32 rolloff_factor, - F32 min_dist, - F32 max_dist) -{ - F32 result; +F32 AILCALLBACK custom_falloff_function(HSAMPLE S, F32 distance, + F32 rolloff_factor, F32 min_dist, + F32 max_dist) { + F32 result; - // This is now emulating the linear fall-off function that we used on the Xbox 360. The parameter which is passed as "max_dist" is the only one actually used, - // and is generally used as CurveDistanceScaler is used on XACT on the Xbox. A special value of 10000.0f is passed for thunder, which has no attenuation + // This is now emulating the linear fall-off function that we used on the + // Xbox 360. The parameter which is passed as "max_dist" is the only one + // actually used, and is generally used as CurveDistanceScaler is used on + // XACT on the Xbox. A special value of 10000.0f is passed for thunder, + // which has no attenuation - if( max_dist == 10000.0f ) - { - return 1.0f; - } + if (max_dist == 10000.0f) { + return 1.0f; + } - result = 1.0f - ( distance / max_dist ); - if( result < 0.0f ) result = 0.0f; - if( result > 1.0f ) result = 1.0f; + result = 1.0f - (distance / max_dist); + if (result < 0.0f) result = 0.0f; + if (result > 1.0f) result = 1.0f; - return result; + return result; } #endif - // Universal, these functions shouldn't need platform specific implementations void SoundEngine::updateMusicVolume(float fVal) { m_MasterMusicVolume = fVal; } void SoundEngine::updateSystemMusicPlaying(bool isPlaying) { diff --git a/Minecraft.Client/Platform/Common/Audio/SoundEngine.h b/Minecraft.Client/Platform/Common/Audio/SoundEngine.h index 29d8ea928..ceb474353 100644 --- a/Minecraft.Client/Platform/Common/Audio/SoundEngine.h +++ b/Minecraft.Client/Platform/Common/Audio/SoundEngine.h @@ -134,9 +134,9 @@ private: #else int initAudioHardware(int iMinSpeakers) { return iMinSpeakers; } #endif - #ifdef __linux__ - void updateMiniAudio(); - #endif +#ifdef __linux__ + void updateMiniAudio(); +#endif int GetRandomishTrack(int iStart, int iEnd); diff --git a/Minecraft.Client/Platform/Common/Audio/SoundNames.cpp b/Minecraft.Client/Platform/Common/Audio/SoundNames.cpp index fcb63905b..981eb9183 100644 --- a/Minecraft.Client/Platform/Common/Audio/SoundNames.cpp +++ b/Minecraft.Client/Platform/Common/Audio/SoundNames.cpp @@ -60,7 +60,7 @@ const WCHAR* ConsoleSoundEngine::wchSoundNames[eSoundType_MAX] = { // 4J-PB - correct the name of the event for hitting ocelots L"mob/cat/hit", // eSoundType_MOB_CAT_HITT // L"mob/irongolem/throw", // - //eSoundType_MOB_IRONGOLEM_THROW L"mob/irongolem/hit", + // eSoundType_MOB_IRONGOLEM_THROW L"mob/irongolem/hit", //// eSoundType_MOB_IRONGOLEM_HIT L"mob/irongolem/death", //// eSoundType_MOB_IRONGOLEM_DEATH L"mob/irongolem/walk", //// eSoundType_MOB_IRONGOLEM_WALK @@ -79,7 +79,7 @@ const WCHAR* ConsoleSoundEngine::wchSoundNames[eSoundType_MAX] = { L"random/orb", // eSoundType_RANDOM_ORB, L"random/break", // eSoundType_RANDOM_BREAK, L"block/chest/open", // eSoundType_RANDOM_CHEST_OPEN, - L"block/chest/close", // eSoundType_RANDOM_CHEST_CLOSE, + L"block/chest/close", // eSoundType_RANDOM_CHEST_CLOSE, L"random/door_open", // eSoundType_RANDOM_DOOR_OPEN, L"random/door_close", // eSoundType_RANDOM_DOOR_CLOSE, L"ambient/weather/rain", // eSoundType_AMBIENT_WEATHER_RAIN, @@ -87,17 +87,17 @@ const WCHAR* ConsoleSoundEngine::wchSoundNames[eSoundType_MAX] = { L"ambient/cave/cave", // eSoundType_CAVE_CAVE, DON'T USE FOR XBOX 360!!! #ifdef _XBOX L"ambient/cave/cave2", // eSoundType_CAVE_CAVE2 - removed the two sounds - //that were at 192k in the first ambient cave event + // that were at 192k in the first ambient cave event #endif L"portal/portal", // eSoundType_PORTAL_PORTAL, // 4J-PB - added a couple that were still using std::wstring L"portal/trigger", // eSoundType_PORTAL_TRIGGER L"portal/travel", // eSoundType_PORTAL_TRAVEL - L"fire/new_ignite", // eSoundType_FIRE_IGNITE, - L"fire/fire", // eSoundType_FIRE_FIRE, + L"fire/new_ignite", // eSoundType_FIRE_IGNITE, + L"fire/fire", // eSoundType_FIRE_FIRE, // Renamed to damage/hit as the other file doesn't exist - L"damage/hit", // eSoundType_DAMAGE_HURT, + L"damage/hit", // eSoundType_DAMAGE_HURT, L"damage/fallsmall", // eSoundType_DAMAGE_FALL_SMALL, L"damage/fallbig", // eSoundType_DAMAGE_FALL_BIG, L"note/harp", // eSoundType_NOTE_HARP, diff --git a/Minecraft.Client/Platform/Common/Audio/stb_vorbis.h b/Minecraft.Client/Platform/Common/Audio/stb_vorbis.h index 53f292d21..55e3c56c1 100644 --- a/Minecraft.Client/Platform/Common/Audio/stb_vorbis.h +++ b/Minecraft.Client/Platform/Common/Audio/stb_vorbis.h @@ -32,163 +32,172 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef __cplusplus extern "C" { #endif -typedef struct -{ - char *alloc_buffer; - int alloc_buffer_length_in_bytes; +typedef struct { + char* alloc_buffer; + int alloc_buffer_length_in_bytes; } stb_vorbis_alloc; typedef struct stb_vorbis stb_vorbis; -typedef struct -{ - unsigned int sample_rate; - int channels; +typedef struct { + unsigned int sample_rate; + int channels; - unsigned int setup_memory_required; - unsigned int setup_temp_memory_required; - unsigned int temp_memory_required; + unsigned int setup_memory_required; + unsigned int setup_temp_memory_required; + unsigned int temp_memory_required; - int max_frame_size; + int max_frame_size; } stb_vorbis_info; -typedef struct -{ - char *vendor; +typedef struct { + char* vendor; - int comment_list_length; - char **comment_list; + int comment_list_length; + char** comment_list; } stb_vorbis_comment; -extern stb_vorbis_info stb_vorbis_get_info(stb_vorbis *f); +extern stb_vorbis_info stb_vorbis_get_info(stb_vorbis* f); -extern stb_vorbis_comment stb_vorbis_get_comment(stb_vorbis *f); +extern stb_vorbis_comment stb_vorbis_get_comment(stb_vorbis* f); -extern int stb_vorbis_get_error(stb_vorbis *f); +extern int stb_vorbis_get_error(stb_vorbis* f); -extern void stb_vorbis_close(stb_vorbis *f); +extern void stb_vorbis_close(stb_vorbis* f); -extern int stb_vorbis_get_sample_offset(stb_vorbis *f); +extern int stb_vorbis_get_sample_offset(stb_vorbis* f); -extern unsigned int stb_vorbis_get_file_offset(stb_vorbis *f); +extern unsigned int stb_vorbis_get_file_offset(stb_vorbis* f); #ifndef STB_VORBIS_NO_PUSHDATA_API -extern stb_vorbis *stb_vorbis_open_pushdata( - const unsigned char * datablock, int datablock_length_in_bytes, - int *datablock_memory_consumed_in_bytes, - int *error, - const stb_vorbis_alloc *alloc_buffer); +extern stb_vorbis* stb_vorbis_open_pushdata( + const unsigned char* datablock, int datablock_length_in_bytes, + int* datablock_memory_consumed_in_bytes, int* error, + const stb_vorbis_alloc* alloc_buffer); -extern int stb_vorbis_decode_frame_pushdata( - stb_vorbis *f, - const unsigned char *datablock, int datablock_length_in_bytes, - int *channels, - float ***output, - int *samples - ); +extern int stb_vorbis_decode_frame_pushdata(stb_vorbis* f, + const unsigned char* datablock, + int datablock_length_in_bytes, + int* channels, float*** output, + int* samples); -extern void stb_vorbis_flush_pushdata(stb_vorbis *f); +extern void stb_vorbis_flush_pushdata(stb_vorbis* f); #endif #ifndef STB_VORBIS_NO_PULLDATA_API #if !defined(STB_VORBIS_NO_STDIO) && !defined(STB_VORBIS_NO_INTEGER_CONVERSION) -extern int stb_vorbis_decode_filename(const char *filename, int *channels, int *sample_rate, short **output); +extern int stb_vorbis_decode_filename(const char* filename, int* channels, + int* sample_rate, short** output); #endif #if !defined(STB_VORBIS_NO_INTEGER_CONVERSION) -extern int stb_vorbis_decode_memory(const unsigned char *mem, int len, int *channels, int *sample_rate, short **output); +extern int stb_vorbis_decode_memory(const unsigned char* mem, int len, + int* channels, int* sample_rate, + short** output); #endif -extern stb_vorbis * stb_vorbis_open_memory(const unsigned char *data, int len, - int *error, const stb_vorbis_alloc *alloc_buffer); +extern stb_vorbis* stb_vorbis_open_memory(const unsigned char* data, int len, + int* error, + const stb_vorbis_alloc* alloc_buffer); #ifndef STB_VORBIS_NO_STDIO -extern stb_vorbis * stb_vorbis_open_filename(const char *filename, - int *error, const stb_vorbis_alloc *alloc_buffer); +extern stb_vorbis* stb_vorbis_open_filename( + const char* filename, int* error, const stb_vorbis_alloc* alloc_buffer); -extern stb_vorbis * stb_vorbis_open_file(FILE *f, int close_handle_on_close, - int *error, const stb_vorbis_alloc *alloc_buffer); +extern stb_vorbis* stb_vorbis_open_file(FILE* f, int close_handle_on_close, + int* error, + const stb_vorbis_alloc* alloc_buffer); -extern stb_vorbis * stb_vorbis_open_file_section(FILE *f, int close_handle_on_close, - int *error, const stb_vorbis_alloc *alloc_buffer, unsigned int len); +extern stb_vorbis* stb_vorbis_open_file_section( + FILE* f, int close_handle_on_close, int* error, + const stb_vorbis_alloc* alloc_buffer, unsigned int len); #endif -extern int stb_vorbis_seek_frame(stb_vorbis *f, unsigned int sample_number); -extern int stb_vorbis_seek(stb_vorbis *f, unsigned int sample_number); +extern int stb_vorbis_seek_frame(stb_vorbis* f, unsigned int sample_number); +extern int stb_vorbis_seek(stb_vorbis* f, unsigned int sample_number); -extern int stb_vorbis_seek_start(stb_vorbis *f); +extern int stb_vorbis_seek_start(stb_vorbis* f); -extern unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f); -extern float stb_vorbis_stream_length_in_seconds(stb_vorbis *f); +extern unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis* f); +extern float stb_vorbis_stream_length_in_seconds(stb_vorbis* f); -extern int stb_vorbis_get_frame_float(stb_vorbis *f, int *channels, float ***output); +extern int stb_vorbis_get_frame_float(stb_vorbis* f, int* channels, + float*** output); #ifndef STB_VORBIS_NO_INTEGER_CONVERSION -extern int stb_vorbis_get_frame_short_interleaved(stb_vorbis *f, int num_c, short *buffer, int num_shorts); -extern int stb_vorbis_get_frame_short (stb_vorbis *f, int num_c, short **buffer, int num_samples); +extern int stb_vorbis_get_frame_short_interleaved(stb_vorbis* f, int num_c, + short* buffer, + int num_shorts); +extern int stb_vorbis_get_frame_short(stb_vorbis* f, int num_c, short** buffer, + int num_samples); #endif -extern int stb_vorbis_get_samples_float_interleaved(stb_vorbis *f, int channels, float *buffer, int num_floats); -extern int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, int num_samples); +extern int stb_vorbis_get_samples_float_interleaved(stb_vorbis* f, int channels, + float* buffer, + int num_floats); +extern int stb_vorbis_get_samples_float(stb_vorbis* f, int channels, + float** buffer, int num_samples); #ifndef STB_VORBIS_NO_INTEGER_CONVERSION -extern int stb_vorbis_get_samples_short_interleaved(stb_vorbis *f, int channels, short *buffer, int num_shorts); -extern int stb_vorbis_get_samples_short(stb_vorbis *f, int channels, short **buffer, int num_samples); +extern int stb_vorbis_get_samples_short_interleaved(stb_vorbis* f, int channels, + short* buffer, + int num_shorts); +extern int stb_vorbis_get_samples_short(stb_vorbis* f, int channels, + short** buffer, int num_samples); #endif #endif -enum STBVorbisError -{ - VORBIS__no_error, +enum STBVorbisError { + VORBIS__no_error, - VORBIS_need_more_data=1, + VORBIS_need_more_data = 1, - VORBIS_invalid_api_mixing, - VORBIS_outofmem, - VORBIS_feature_not_supported, - VORBIS_too_many_channels, - VORBIS_file_open_failure, - VORBIS_seek_without_length, + VORBIS_invalid_api_mixing, + VORBIS_outofmem, + VORBIS_feature_not_supported, + VORBIS_too_many_channels, + VORBIS_file_open_failure, + VORBIS_seek_without_length, - VORBIS_unexpected_eof=10, - VORBIS_seek_invalid, + VORBIS_unexpected_eof = 10, + VORBIS_seek_invalid, - VORBIS_invalid_setup=20, - VORBIS_invalid_stream, + VORBIS_invalid_setup = 20, + VORBIS_invalid_stream, - VORBIS_missing_capture_pattern=30, - VORBIS_invalid_stream_structure_version, - VORBIS_continued_packet_flag_invalid, - VORBIS_incorrect_stream_serial_number, - VORBIS_invalid_first_page, - VORBIS_bad_packet_type, - VORBIS_cant_find_last_page, - VORBIS_seek_failed, - VORBIS_ogg_skeleton_not_supported + VORBIS_missing_capture_pattern = 30, + VORBIS_invalid_stream_structure_version, + VORBIS_continued_packet_flag_invalid, + VORBIS_incorrect_stream_serial_number, + VORBIS_invalid_first_page, + VORBIS_bad_packet_type, + VORBIS_cant_find_last_page, + VORBIS_seek_failed, + VORBIS_ogg_skeleton_not_supported }; #ifdef __cplusplus } #endif -#endif +#endif #ifndef STB_VORBIS_HEADER_ONLY #ifndef STB_VORBIS_MAX_CHANNELS -#define STB_VORBIS_MAX_CHANNELS 16 +#define STB_VORBIS_MAX_CHANNELS 16 #endif #ifndef STB_VORBIS_PUSHDATA_CRC_COUNT -#define STB_VORBIS_PUSHDATA_CRC_COUNT 4 +#define STB_VORBIS_PUSHDATA_CRC_COUNT 4 #endif #ifndef STB_VORBIS_FAST_HUFFMAN_LENGTH -#define STB_VORBIS_FAST_HUFFMAN_LENGTH 10 +#define STB_VORBIS_FAST_HUFFMAN_LENGTH 10 #endif #ifndef STB_VORBIS_FAST_HUFFMAN_INT @@ -196,26 +205,27 @@ enum STBVorbisError #endif #ifdef STB_VORBIS_CODEBOOK_SHORTS -#error "STB_VORBIS_CODEBOOK_SHORTS is no longer supported as it produced incorrect results for some input formats" +#error \ + "STB_VORBIS_CODEBOOK_SHORTS is no longer supported as it produced incorrect results for some input formats" #endif #ifdef STB_VORBIS_NO_PULLDATA_API - #define STB_VORBIS_NO_INTEGER_CONVERSION - #define STB_VORBIS_NO_STDIO +#define STB_VORBIS_NO_INTEGER_CONVERSION +#define STB_VORBIS_NO_STDIO #endif #if defined(STB_VORBIS_NO_CRT) && !defined(STB_VORBIS_NO_STDIO) - #define STB_VORBIS_NO_STDIO 1 +#define STB_VORBIS_NO_STDIO 1 #endif #ifndef STB_VORBIS_NO_INTEGER_CONVERSION #ifndef STB_VORBIS_NO_FAST_SCALED_FLOAT - #ifndef STB_VORBIS_BIG_ENDIAN - #define STB_VORBIS_ENDIAN 0 - #else - #define STB_VORBIS_ENDIAN 1 - #endif +#ifndef STB_VORBIS_BIG_ENDIAN +#define STB_VORBIS_ENDIAN 0 +#else +#define STB_VORBIS_ENDIAN 1 +#endif #endif #endif @@ -225,41 +235,42 @@ enum STBVorbisError #endif #ifndef STB_VORBIS_NO_CRT - #include - #include - #include - #include +#include +#include +#include +#include - #if defined(_MSC_VER) || defined(__MINGW32__) - #include - #endif - #if defined(__linux__) || defined(__linux) || defined(__sun__) || defined(__EMSCRIPTEN__) || defined(__NEWLIB__) - #include - #endif -#else - #define NULL 0 - #define malloc(s) 0 - #define free(s) ((void) 0) - #define realloc(s) 0 -#endif +#if defined(_MSC_VER) || defined(__MINGW32__) +#include +#endif +#if defined(__linux__) || defined(__linux) || defined(__sun__) || \ + defined(__EMSCRIPTEN__) || defined(__NEWLIB__) +#include +#endif +#else +#define NULL 0 +#define malloc(s) 0 +#define free(s) ((void)0) +#define realloc(s) 0 +#endif #include #ifdef __MINGW32__ - - #ifdef __forceinline - #undef __forceinline - #endif - #define __forceinline - #ifndef alloca - #define alloca __builtin_alloca - #endif + +#ifdef __forceinline +#undef __forceinline +#endif +#define __forceinline +#ifndef alloca +#define alloca __builtin_alloca +#endif #elif !defined(_MSC_VER) - #if __GNUC__ - #define __forceinline inline - #else - #define __forceinline - #endif +#if __GNUC__ +#define __forceinline inline +#else +#define __forceinline +#endif #endif #if STB_VORBIS_MAX_CHANNELS > 256 @@ -272,20 +283,20 @@ enum STBVorbisError #if 0 #include -#define CHECK(f) _CrtIsValidHeapPointer(f->channel_buffers[1]) +#define CHECK(f) _CrtIsValidHeapPointer(f->channel_buffers[1]) #else -#define CHECK(f) ((void) 0) +#define CHECK(f) ((void)0) #endif -#define MAX_BLOCKSIZE_LOG 13 -#define MAX_BLOCKSIZE (1 << MAX_BLOCKSIZE_LOG) +#define MAX_BLOCKSIZE_LOG 13 +#define MAX_BLOCKSIZE (1 << MAX_BLOCKSIZE_LOG) -typedef unsigned char uint8; -typedef signed char int8; +typedef unsigned char uint8; +typedef signed char int8; typedef unsigned short uint16; -typedef signed short int16; -typedef unsigned int uint32; -typedef signed int int32; +typedef signed short int16; +typedef unsigned int uint32; +typedef signed int int32; #ifndef TRUE #define TRUE 1 @@ -295,435 +306,422 @@ typedef signed int int32; typedef float codetype; #ifdef _MSC_VER -#define STBV_NOTUSED(v) (void)(v) +#define STBV_NOTUSED(v) (void)(v) #else -#define STBV_NOTUSED(v) (void)sizeof(v) +#define STBV_NOTUSED(v) (void)sizeof(v) #endif -#define FAST_HUFFMAN_TABLE_SIZE (1 << STB_VORBIS_FAST_HUFFMAN_LENGTH) -#define FAST_HUFFMAN_TABLE_MASK (FAST_HUFFMAN_TABLE_SIZE - 1) +#define FAST_HUFFMAN_TABLE_SIZE (1 << STB_VORBIS_FAST_HUFFMAN_LENGTH) +#define FAST_HUFFMAN_TABLE_MASK (FAST_HUFFMAN_TABLE_SIZE - 1) -typedef struct -{ - int dimensions, entries; - uint8 *codeword_lengths; - float minimum_value; - float delta_value; - uint8 value_bits; - uint8 lookup_type; - uint8 sequence_p; - uint8 sparse; - uint32 lookup_values; - codetype *multiplicands; - uint32 *codewords; - #ifdef STB_VORBIS_FAST_HUFFMAN_SHORT - int16 fast_huffman[FAST_HUFFMAN_TABLE_SIZE]; - #else - int32 fast_huffman[FAST_HUFFMAN_TABLE_SIZE]; - #endif - uint32 *sorted_codewords; - int *sorted_values; - int sorted_entries; +typedef struct { + int dimensions, entries; + uint8* codeword_lengths; + float minimum_value; + float delta_value; + uint8 value_bits; + uint8 lookup_type; + uint8 sequence_p; + uint8 sparse; + uint32 lookup_values; + codetype* multiplicands; + uint32* codewords; +#ifdef STB_VORBIS_FAST_HUFFMAN_SHORT + int16 fast_huffman[FAST_HUFFMAN_TABLE_SIZE]; +#else + int32 fast_huffman[FAST_HUFFMAN_TABLE_SIZE]; +#endif + uint32* sorted_codewords; + int* sorted_values; + int sorted_entries; } Codebook; -typedef struct -{ - uint8 order; - uint16 rate; - uint16 bark_map_size; - uint8 amplitude_bits; - uint8 amplitude_offset; - uint8 number_of_books; - uint8 book_list[16]; +typedef struct { + uint8 order; + uint16 rate; + uint16 bark_map_size; + uint8 amplitude_bits; + uint8 amplitude_offset; + uint8 number_of_books; + uint8 book_list[16]; } Floor0; -typedef struct -{ - uint8 partitions; - uint8 partition_class_list[32]; - uint8 class_dimensions[16]; - uint8 class_subclasses[16]; - uint8 class_masterbooks[16]; - int16 subclass_books[16][8]; - uint16 Xlist[31*8+2]; - uint8 sorted_order[31*8+2]; - uint8 neighbors[31*8+2][2]; - uint8 floor1_multiplier; - uint8 rangebits; - int values; +typedef struct { + uint8 partitions; + uint8 partition_class_list[32]; + uint8 class_dimensions[16]; + uint8 class_subclasses[16]; + uint8 class_masterbooks[16]; + int16 subclass_books[16][8]; + uint16 Xlist[31 * 8 + 2]; + uint8 sorted_order[31 * 8 + 2]; + uint8 neighbors[31 * 8 + 2][2]; + uint8 floor1_multiplier; + uint8 rangebits; + int values; } Floor1; -typedef union -{ - Floor0 floor0; - Floor1 floor1; +typedef union { + Floor0 floor0; + Floor1 floor1; } Floor; -typedef struct -{ - uint32 begin, end; - uint32 part_size; - uint8 classifications; - uint8 classbook; - uint8 **classdata; - int16 (*residue_books)[8]; +typedef struct { + uint32 begin, end; + uint32 part_size; + uint8 classifications; + uint8 classbook; + uint8** classdata; + int16 (*residue_books)[8]; } Residue; -typedef struct -{ - uint8 magnitude; - uint8 angle; - uint8 mux; +typedef struct { + uint8 magnitude; + uint8 angle; + uint8 mux; } MappingChannel; -typedef struct -{ - uint16 coupling_steps; - MappingChannel *chan; - uint8 submaps; - uint8 submap_floor[15]; - uint8 submap_residue[15]; +typedef struct { + uint16 coupling_steps; + MappingChannel* chan; + uint8 submaps; + uint8 submap_floor[15]; + uint8 submap_residue[15]; } Mapping; -typedef struct -{ - uint8 blockflag; - uint8 mapping; - uint16 windowtype; - uint16 transformtype; +typedef struct { + uint8 blockflag; + uint8 mapping; + uint16 windowtype; + uint16 transformtype; } Mode; -typedef struct -{ - uint32 goal_crc; - int bytes_left; - uint32 crc_so_far; - int bytes_done; - uint32 sample_loc; +typedef struct { + uint32 goal_crc; + int bytes_left; + uint32 crc_so_far; + int bytes_done; + uint32 sample_loc; } CRCscan; -typedef struct -{ - uint32 page_start, page_end; - uint32 last_decoded_sample; +typedef struct { + uint32 page_start, page_end; + uint32 last_decoded_sample; } ProbedPage; -struct stb_vorbis -{ - - unsigned int sample_rate; - int channels; +struct stb_vorbis { + unsigned int sample_rate; + int channels; - unsigned int setup_memory_required; - unsigned int temp_memory_required; - unsigned int setup_temp_memory_required; + unsigned int setup_memory_required; + unsigned int temp_memory_required; + unsigned int setup_temp_memory_required; - char *vendor; - int comment_list_length; - char **comment_list; + char* vendor; + int comment_list_length; + char** comment_list; #ifndef STB_VORBIS_NO_STDIO - FILE *f; - uint32 f_start; - int close_on_free; + FILE* f; + uint32 f_start; + int close_on_free; #endif - uint8 *stream; - uint8 *stream_start; - uint8 *stream_end; + uint8* stream; + uint8* stream_start; + uint8* stream_end; - uint32 stream_len; + uint32 stream_len; - uint8 push_mode; + uint8 push_mode; - uint32 first_audio_page_offset; + uint32 first_audio_page_offset; - ProbedPage p_first, p_last; + ProbedPage p_first, p_last; - stb_vorbis_alloc alloc; - int setup_offset; - int temp_offset; + stb_vorbis_alloc alloc; + int setup_offset; + int temp_offset; - int eof; - enum STBVorbisError error; + int eof; + enum STBVorbisError error; - int blocksize[2]; - int blocksize_0, blocksize_1; - int codebook_count; - Codebook *codebooks; - int floor_count; - uint16 floor_types[64]; - Floor *floor_config; - int residue_count; - uint16 residue_types[64]; - Residue *residue_config; - int mapping_count; - Mapping *mapping; - int mode_count; - Mode mode_config[64]; + int blocksize[2]; + int blocksize_0, blocksize_1; + int codebook_count; + Codebook* codebooks; + int floor_count; + uint16 floor_types[64]; + Floor* floor_config; + int residue_count; + uint16 residue_types[64]; + Residue* residue_config; + int mapping_count; + Mapping* mapping; + int mode_count; + Mode mode_config[64]; - uint32 total_samples; + uint32 total_samples; - float *channel_buffers[STB_VORBIS_MAX_CHANNELS]; - float *outputs [STB_VORBIS_MAX_CHANNELS]; + float* channel_buffers[STB_VORBIS_MAX_CHANNELS]; + float* outputs[STB_VORBIS_MAX_CHANNELS]; - float *previous_window[STB_VORBIS_MAX_CHANNELS]; - int previous_length; + float* previous_window[STB_VORBIS_MAX_CHANNELS]; + int previous_length; - #ifndef STB_VORBIS_NO_DEFER_FLOOR - int16 *finalY[STB_VORBIS_MAX_CHANNELS]; - #else - float *floor_buffers[STB_VORBIS_MAX_CHANNELS]; - #endif +#ifndef STB_VORBIS_NO_DEFER_FLOOR + int16* finalY[STB_VORBIS_MAX_CHANNELS]; +#else + float* floor_buffers[STB_VORBIS_MAX_CHANNELS]; +#endif - uint32 current_loc; - int current_loc_valid; + uint32 current_loc; + int current_loc_valid; - float *A[2],*B[2],*C[2]; - float *window[2]; - uint16 *bit_reverse[2]; + float *A[2], *B[2], *C[2]; + float* window[2]; + uint16* bit_reverse[2]; - uint32 serial; - int last_page; - int segment_count; - uint8 segments[255]; - uint8 page_flag; - uint8 bytes_in_seg; - uint8 first_decode; - int next_seg; - int last_seg; - int last_seg_which; - uint32 acc; - int valid_bits; - int packet_bytes; - int end_seg_with_known_loc; - uint32 known_loc_for_packet; - int discard_samples_deferred; - uint32 samples_output; + uint32 serial; + int last_page; + int segment_count; + uint8 segments[255]; + uint8 page_flag; + uint8 bytes_in_seg; + uint8 first_decode; + int next_seg; + int last_seg; + int last_seg_which; + uint32 acc; + int valid_bits; + int packet_bytes; + int end_seg_with_known_loc; + uint32 known_loc_for_packet; + int discard_samples_deferred; + uint32 samples_output; - int page_crc_tests; + int page_crc_tests; #ifndef STB_VORBIS_NO_PUSHDATA_API - CRCscan scan[STB_VORBIS_PUSHDATA_CRC_COUNT]; + CRCscan scan[STB_VORBIS_PUSHDATA_CRC_COUNT]; #endif - int channel_buffer_start; - int channel_buffer_end; + int channel_buffer_start; + int channel_buffer_end; }; #if defined(STB_VORBIS_NO_PUSHDATA_API) - #define IS_PUSH_MODE(f) FALSE +#define IS_PUSH_MODE(f) FALSE #elif defined(STB_VORBIS_NO_PULLDATA_API) - #define IS_PUSH_MODE(f) TRUE +#define IS_PUSH_MODE(f) TRUE #else - #define IS_PUSH_MODE(f) ((f)->push_mode) +#define IS_PUSH_MODE(f) ((f)->push_mode) #endif typedef struct stb_vorbis vorb; -static int error(vorb *f, enum STBVorbisError e) -{ - f->error = e; - if (!f->eof && e != VORBIS_need_more_data) { - f->error=e; - } - return 0; +static int error(vorb* f, enum STBVorbisError e) { + f->error = e; + if (!f->eof && e != VORBIS_need_more_data) { + f->error = e; + } + return 0; } -#define array_size_required(count,size) (count*(sizeof(void *)+(size))) +#define array_size_required(count, size) (count * (sizeof(void*) + (size))) -#define temp_alloc(f,size) (f->alloc.alloc_buffer ? setup_temp_malloc(f,size) : alloca(size)) -#define temp_free(f,p) (void)0 -#define temp_alloc_save(f) ((f)->temp_offset) -#define temp_alloc_restore(f,p) ((f)->temp_offset = (p)) +#define temp_alloc(f, size) \ + (f->alloc.alloc_buffer ? setup_temp_malloc(f, size) : alloca(size)) +#define temp_free(f, p) (void)0 +#define temp_alloc_save(f) ((f)->temp_offset) +#define temp_alloc_restore(f, p) ((f)->temp_offset = (p)) -#define temp_block_array(f,count,size) make_block_array(temp_alloc(f,array_size_required(count,size)), count, size) +#define temp_block_array(f, count, size) \ + make_block_array(temp_alloc(f, array_size_required(count, size)), count, \ + size) -static void *make_block_array(void *mem, int count, int size) -{ - int i; - void ** p = (void **) mem; - char *q = (char *) (p + count); - for (i=0; i < count; ++i) { - p[i] = q; - q += size; - } - return p; +static void* make_block_array(void* mem, int count, int size) { + int i; + void** p = (void**)mem; + char* q = (char*)(p + count); + for (i = 0; i < count; ++i) { + p[i] = q; + q += size; + } + return p; } -static void *setup_malloc(vorb *f, int sz) -{ - sz = (sz+7) & ~7; - f->setup_memory_required += sz; - if (f->alloc.alloc_buffer) { - void *p = (char *) f->alloc.alloc_buffer + f->setup_offset; - if (f->setup_offset + sz > f->temp_offset) return NULL; - f->setup_offset += sz; - return p; - } - return sz ? malloc(sz) : NULL; +static void* setup_malloc(vorb* f, int sz) { + sz = (sz + 7) & ~7; + f->setup_memory_required += sz; + if (f->alloc.alloc_buffer) { + void* p = (char*)f->alloc.alloc_buffer + f->setup_offset; + if (f->setup_offset + sz > f->temp_offset) return NULL; + f->setup_offset += sz; + return p; + } + return sz ? malloc(sz) : NULL; } -static void setup_free(vorb *f, void *p) -{ - if (f->alloc.alloc_buffer) return; - free(p); +static void setup_free(vorb* f, void* p) { + if (f->alloc.alloc_buffer) return; + free(p); } -static void *setup_temp_malloc(vorb *f, int sz) -{ - sz = (sz+7) & ~7; - if (f->alloc.alloc_buffer) { - if (f->temp_offset - sz < f->setup_offset) return NULL; - f->temp_offset -= sz; - return (char *) f->alloc.alloc_buffer + f->temp_offset; - } - return malloc(sz); +static void* setup_temp_malloc(vorb* f, int sz) { + sz = (sz + 7) & ~7; + if (f->alloc.alloc_buffer) { + if (f->temp_offset - sz < f->setup_offset) return NULL; + f->temp_offset -= sz; + return (char*)f->alloc.alloc_buffer + f->temp_offset; + } + return malloc(sz); } -static void setup_temp_free(vorb *f, void *p, int sz) -{ - if (f->alloc.alloc_buffer) { - f->temp_offset += (sz+7)&~7; - return; - } - free(p); +static void setup_temp_free(vorb* f, void* p, int sz) { + if (f->alloc.alloc_buffer) { + f->temp_offset += (sz + 7) & ~7; + return; + } + free(p); } -#define CRC32_POLY 0x04c11db7 +#define CRC32_POLY 0x04c11db7 static uint32 crc_table[256]; -static void crc32_init(void) -{ - int i,j; - uint32 s; - for(i=0; i < 256; i++) { - for (s=(uint32) i << 24, j=0; j < 8; ++j) - s = (s << 1) ^ (s >= (1U<<31) ? CRC32_POLY : 0); - crc_table[i] = s; - } +static void crc32_init(void) { + int i, j; + uint32 s; + for (i = 0; i < 256; i++) { + for (s = (uint32)i << 24, j = 0; j < 8; ++j) + s = (s << 1) ^ (s >= (1U << 31) ? CRC32_POLY : 0); + crc_table[i] = s; + } } -static __forceinline uint32 crc32_update(uint32 crc, uint8 byte) -{ - return (crc << 8) ^ crc_table[byte ^ (crc >> 24)]; +static __forceinline uint32 crc32_update(uint32 crc, uint8 byte) { + return (crc << 8) ^ crc_table[byte ^ (crc >> 24)]; } -static unsigned int bit_reverse(unsigned int n) -{ - n = ((n & 0xAAAAAAAA) >> 1) | ((n & 0x55555555) << 1); - n = ((n & 0xCCCCCCCC) >> 2) | ((n & 0x33333333) << 2); - n = ((n & 0xF0F0F0F0) >> 4) | ((n & 0x0F0F0F0F) << 4); - n = ((n & 0xFF00FF00) >> 8) | ((n & 0x00FF00FF) << 8); - return (n >> 16) | (n << 16); +static unsigned int bit_reverse(unsigned int n) { + n = ((n & 0xAAAAAAAA) >> 1) | ((n & 0x55555555) << 1); + n = ((n & 0xCCCCCCCC) >> 2) | ((n & 0x33333333) << 2); + n = ((n & 0xF0F0F0F0) >> 4) | ((n & 0x0F0F0F0F) << 4); + n = ((n & 0xFF00FF00) >> 8) | ((n & 0x00FF00FF) << 8); + return (n >> 16) | (n << 16); } -static float square(float x) -{ - return x*x; -} +static float square(float x) { return x * x; } -static int ilog(int32 n) -{ - static signed char log2_4[16] = { 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4 }; +static int ilog(int32 n) { + static signed char log2_4[16] = {0, 1, 2, 2, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4}; - if (n < 0) return 0; + if (n < 0) return 0; - if (n < (1 << 14)) - if (n < (1 << 4)) return 0 + log2_4[n ]; - else if (n < (1 << 9)) return 5 + log2_4[n >> 5]; - else return 10 + log2_4[n >> 10]; - else if (n < (1 << 24)) - if (n < (1 << 19)) return 15 + log2_4[n >> 15]; - else return 20 + log2_4[n >> 20]; - else if (n < (1 << 29)) return 25 + log2_4[n >> 25]; - else return 30 + log2_4[n >> 30]; + if (n < (1 << 14)) + if (n < (1 << 4)) + return 0 + log2_4[n]; + else if (n < (1 << 9)) + return 5 + log2_4[n >> 5]; + else + return 10 + log2_4[n >> 10]; + else if (n < (1 << 24)) + if (n < (1 << 19)) + return 15 + log2_4[n >> 15]; + else + return 20 + log2_4[n >> 20]; + else if (n < (1 << 29)) + return 25 + log2_4[n >> 25]; + else + return 30 + log2_4[n >> 30]; } #ifndef M_PI - #define M_PI 3.14159265358979323846264f +#define M_PI 3.14159265358979323846264f #endif -#define NO_CODE 255 +#define NO_CODE 255 -static float float32_unpack(uint32 x) -{ - - uint32 mantissa = x & 0x1fffff; - uint32 sign = x & 0x80000000; - uint32 exp = (x & 0x7fe00000) >> 21; - double res = sign ? -(double)mantissa : (double)mantissa; - return (float) ldexp((float)res, (int)exp-788); +static float float32_unpack(uint32 x) { + uint32 mantissa = x & 0x1fffff; + uint32 sign = x & 0x80000000; + uint32 exp = (x & 0x7fe00000) >> 21; + double res = sign ? -(double)mantissa : (double)mantissa; + return (float)ldexp((float)res, (int)exp - 788); } -static void add_entry(Codebook *c, uint32 huff_code, int symbol, int count, int len, uint32 *values) -{ - if (!c->sparse) { - c->codewords [symbol] = huff_code; - } else { - c->codewords [count] = huff_code; - c->codeword_lengths[count] = len; - values [count] = symbol; - } +static void add_entry(Codebook* c, uint32 huff_code, int symbol, int count, + int len, uint32* values) { + if (!c->sparse) { + c->codewords[symbol] = huff_code; + } else { + c->codewords[count] = huff_code; + c->codeword_lengths[count] = len; + values[count] = symbol; + } } -static int compute_codewords(Codebook *c, uint8 *len, int n, uint32 *values) -{ - int i,k,m=0; - uint32 available[32]; +static int compute_codewords(Codebook* c, uint8* len, int n, uint32* values) { + int i, k, m = 0; + uint32 available[32]; - memset(available, 0, sizeof(available)); - - for (k=0; k < n; ++k) if (len[k] < NO_CODE) break; - if (k == n) { assert(c->sorted_entries == 0); return TRUE; } - assert(len[k] < 32); - - add_entry(c, 0, k, m++, len[k], values); - - for (i=1; i <= len[k]; ++i) - available[i] = 1U << (32-i); - - for (i=k+1; i < n; ++i) { - uint32 res; - int z = len[i], y; - if (z == NO_CODE) continue; - assert(z < 32); - - while (z > 0 && !available[z]) --z; - if (z == 0) { return FALSE; } - res = available[z]; - available[z] = 0; - add_entry(c, bit_reverse(res), i, m++, len[i], values); - - if (z != len[i]) { - for (y=len[i]; y > z; --y) { - assert(available[y] == 0); - available[y] = res + (1 << (32-y)); - } - } - } - return TRUE; + memset(available, 0, sizeof(available)); + + for (k = 0; k < n; ++k) + if (len[k] < NO_CODE) break; + if (k == n) { + assert(c->sorted_entries == 0); + return TRUE; + } + assert(len[k] < 32); + + add_entry(c, 0, k, m++, len[k], values); + + for (i = 1; i <= len[k]; ++i) available[i] = 1U << (32 - i); + + for (i = k + 1; i < n; ++i) { + uint32 res; + int z = len[i], y; + if (z == NO_CODE) continue; + assert(z < 32); + + while (z > 0 && !available[z]) --z; + if (z == 0) { + return FALSE; + } + res = available[z]; + available[z] = 0; + add_entry(c, bit_reverse(res), i, m++, len[i], values); + + if (z != len[i]) { + for (y = len[i]; y > z; --y) { + assert(available[y] == 0); + available[y] = res + (1 << (32 - y)); + } + } + } + return TRUE; } -static void compute_accelerated_huffman(Codebook *c) -{ - int i, len; - for (i=0; i < FAST_HUFFMAN_TABLE_SIZE; ++i) - c->fast_huffman[i] = -1; +static void compute_accelerated_huffman(Codebook* c) { + int i, len; + for (i = 0; i < FAST_HUFFMAN_TABLE_SIZE; ++i) c->fast_huffman[i] = -1; - len = c->sparse ? c->sorted_entries : c->entries; - #ifdef STB_VORBIS_FAST_HUFFMAN_SHORT - if (len > 32767) len = 32767; - #endif - for (i=0; i < len; ++i) { - if (c->codeword_lengths[i] <= STB_VORBIS_FAST_HUFFMAN_LENGTH) { - uint32 z = c->sparse ? bit_reverse(c->sorted_codewords[i]) : c->codewords[i]; - - while (z < FAST_HUFFMAN_TABLE_SIZE) { - c->fast_huffman[z] = i; - z += 1 << c->codeword_lengths[i]; - } - } - } + len = c->sparse ? c->sorted_entries : c->entries; +#ifdef STB_VORBIS_FAST_HUFFMAN_SHORT + if (len > 32767) len = 32767; +#endif + for (i = 0; i < len; ++i) { + if (c->codeword_lengths[i] <= STB_VORBIS_FAST_HUFFMAN_LENGTH) { + uint32 z = c->sparse ? bit_reverse(c->sorted_codewords[i]) + : c->codewords[i]; + + while (z < FAST_HUFFMAN_TABLE_SIZE) { + c->fast_huffman[z] = i; + z += 1 << c->codeword_lengths[i]; + } + } + } } #ifdef _MSC_VER @@ -732,1074 +730,1071 @@ static void compute_accelerated_huffman(Codebook *c) #define STBV_CDECL #endif -static int STBV_CDECL uint32_compare(const void *p, const void *q) -{ - uint32 x = * (uint32 *) p; - uint32 y = * (uint32 *) q; - return x < y ? -1 : x > y; +static int STBV_CDECL uint32_compare(const void* p, const void* q) { + uint32 x = *(uint32*)p; + uint32 y = *(uint32*)q; + return x < y ? -1 : x > y; } -static int include_in_sort(Codebook *c, uint8 len) -{ - if (c->sparse) { assert(len != NO_CODE); return TRUE; } - if (len == NO_CODE) return FALSE; - if (len > STB_VORBIS_FAST_HUFFMAN_LENGTH) return TRUE; - return FALSE; +static int include_in_sort(Codebook* c, uint8 len) { + if (c->sparse) { + assert(len != NO_CODE); + return TRUE; + } + if (len == NO_CODE) return FALSE; + if (len > STB_VORBIS_FAST_HUFFMAN_LENGTH) return TRUE; + return FALSE; } -static void compute_sorted_huffman(Codebook *c, uint8 *lengths, uint32 *values) -{ - int i, len; - - if (!c->sparse) { - int k = 0; - for (i=0; i < c->entries; ++i) - if (include_in_sort(c, lengths[i])) - c->sorted_codewords[k++] = bit_reverse(c->codewords[i]); - assert(k == c->sorted_entries); - } else { - for (i=0; i < c->sorted_entries; ++i) - c->sorted_codewords[i] = bit_reverse(c->codewords[i]); - } +static void compute_sorted_huffman(Codebook* c, uint8* lengths, + uint32* values) { + int i, len; - qsort(c->sorted_codewords, c->sorted_entries, sizeof(c->sorted_codewords[0]), uint32_compare); - c->sorted_codewords[c->sorted_entries] = 0xffffffff; + if (!c->sparse) { + int k = 0; + for (i = 0; i < c->entries; ++i) + if (include_in_sort(c, lengths[i])) + c->sorted_codewords[k++] = bit_reverse(c->codewords[i]); + assert(k == c->sorted_entries); + } else { + for (i = 0; i < c->sorted_entries; ++i) + c->sorted_codewords[i] = bit_reverse(c->codewords[i]); + } - len = c->sparse ? c->sorted_entries : c->entries; - - for (i=0; i < len; ++i) { - int huff_len = c->sparse ? lengths[values[i]] : lengths[i]; - if (include_in_sort(c,huff_len)) { - uint32 code = bit_reverse(c->codewords[i]); - int x=0, n=c->sorted_entries; - while (n > 1) { - - int m = x + (n >> 1); - if (c->sorted_codewords[m] <= code) { - x = m; - n -= (n>>1); - } else { - n >>= 1; + qsort(c->sorted_codewords, c->sorted_entries, + sizeof(c->sorted_codewords[0]), uint32_compare); + c->sorted_codewords[c->sorted_entries] = 0xffffffff; + + len = c->sparse ? c->sorted_entries : c->entries; + + for (i = 0; i < len; ++i) { + int huff_len = c->sparse ? lengths[values[i]] : lengths[i]; + if (include_in_sort(c, huff_len)) { + uint32 code = bit_reverse(c->codewords[i]); + int x = 0, n = c->sorted_entries; + while (n > 1) { + int m = x + (n >> 1); + if (c->sorted_codewords[m] <= code) { + x = m; + n -= (n >> 1); + } else { + n >>= 1; + } } - } - assert(c->sorted_codewords[x] == code); - if (c->sparse) { - c->sorted_values[x] = values[i]; - c->codeword_lengths[x] = huff_len; - } else { - c->sorted_values[x] = i; - } - } - } + assert(c->sorted_codewords[x] == code); + if (c->sparse) { + c->sorted_values[x] = values[i]; + c->codeword_lengths[x] = huff_len; + } else { + c->sorted_values[x] = i; + } + } + } } -static int vorbis_validate(uint8 *data) -{ - static uint8 vorbis[6] = { 'v', 'o', 'r', 'b', 'i', 's' }; - return memcmp(data, vorbis, 6) == 0; +static int vorbis_validate(uint8* data) { + static uint8 vorbis[6] = {'v', 'o', 'r', 'b', 'i', 's'}; + return memcmp(data, vorbis, 6) == 0; } -static int lookup1_values(int entries, int dim) -{ - int r = (int) floor(exp((float) log((float) entries) / dim)); - if ((int) floor(pow((float) r+1, dim)) <= entries) - ++r; - if (pow((float) r+1, dim) <= entries) - return -1; - if ((int) floor(pow((float) r, dim)) > entries) - return -1; - return r; +static int lookup1_values(int entries, int dim) { + int r = (int)floor(exp((float)log((float)entries) / dim)); + if ((int)floor(pow((float)r + 1, dim)) <= entries) ++r; + if (pow((float)r + 1, dim) <= entries) return -1; + if ((int)floor(pow((float)r, dim)) > entries) return -1; + return r; } -static void compute_twiddle_factors(int n, float *A, float *B, float *C) -{ - int n4 = n >> 2, n8 = n >> 3; - int k,k2; +static void compute_twiddle_factors(int n, float* A, float* B, float* C) { + int n4 = n >> 2, n8 = n >> 3; + int k, k2; - for (k=k2=0; k < n4; ++k,k2+=2) { - A[k2 ] = (float) cos(4*k*M_PI/n); - A[k2+1] = (float) -sin(4*k*M_PI/n); - B[k2 ] = (float) cos((k2+1)*M_PI/n/2) * 0.5f; - B[k2+1] = (float) sin((k2+1)*M_PI/n/2) * 0.5f; - } - for (k=k2=0; k < n8; ++k,k2+=2) { - C[k2 ] = (float) cos(2*(k2+1)*M_PI/n); - C[k2+1] = (float) -sin(2*(k2+1)*M_PI/n); - } + for (k = k2 = 0; k < n4; ++k, k2 += 2) { + A[k2] = (float)cos(4 * k * M_PI / n); + A[k2 + 1] = (float)-sin(4 * k * M_PI / n); + B[k2] = (float)cos((k2 + 1) * M_PI / n / 2) * 0.5f; + B[k2 + 1] = (float)sin((k2 + 1) * M_PI / n / 2) * 0.5f; + } + for (k = k2 = 0; k < n8; ++k, k2 += 2) { + C[k2] = (float)cos(2 * (k2 + 1) * M_PI / n); + C[k2 + 1] = (float)-sin(2 * (k2 + 1) * M_PI / n); + } } -static void compute_window(int n, float *window) -{ - int n2 = n >> 1, i; - for (i=0; i < n2; ++i) - window[i] = (float) sin(0.5 * M_PI * square((float) sin((i - 0 + 0.5) / n2 * 0.5 * M_PI))); +static void compute_window(int n, float* window) { + int n2 = n >> 1, i; + for (i = 0; i < n2; ++i) + window[i] = (float)sin( + 0.5 * M_PI * square((float)sin((i - 0 + 0.5) / n2 * 0.5 * M_PI))); } -static void compute_bitreverse(int n, uint16 *rev) -{ - int ld = ilog(n) - 1; - int i, n8 = n >> 3; - for (i=0; i < n8; ++i) - rev[i] = (bit_reverse(i) >> (32-ld+3)) << 2; +static void compute_bitreverse(int n, uint16* rev) { + int ld = ilog(n) - 1; + int i, n8 = n >> 3; + for (i = 0; i < n8; ++i) rev[i] = (bit_reverse(i) >> (32 - ld + 3)) << 2; } -static int init_blocksize(vorb *f, int b, int n) -{ - int n2 = n >> 1, n4 = n >> 2, n8 = n >> 3; - f->A[b] = (float *) setup_malloc(f, sizeof(float) * n2); - f->B[b] = (float *) setup_malloc(f, sizeof(float) * n2); - f->C[b] = (float *) setup_malloc(f, sizeof(float) * n4); - if (!f->A[b] || !f->B[b] || !f->C[b]) return error(f, VORBIS_outofmem); - compute_twiddle_factors(n, f->A[b], f->B[b], f->C[b]); - f->window[b] = (float *) setup_malloc(f, sizeof(float) * n2); - if (!f->window[b]) return error(f, VORBIS_outofmem); - compute_window(n, f->window[b]); - f->bit_reverse[b] = (uint16 *) setup_malloc(f, sizeof(uint16) * n8); - if (!f->bit_reverse[b]) return error(f, VORBIS_outofmem); - compute_bitreverse(n, f->bit_reverse[b]); - return TRUE; +static int init_blocksize(vorb* f, int b, int n) { + int n2 = n >> 1, n4 = n >> 2, n8 = n >> 3; + f->A[b] = (float*)setup_malloc(f, sizeof(float) * n2); + f->B[b] = (float*)setup_malloc(f, sizeof(float) * n2); + f->C[b] = (float*)setup_malloc(f, sizeof(float) * n4); + if (!f->A[b] || !f->B[b] || !f->C[b]) return error(f, VORBIS_outofmem); + compute_twiddle_factors(n, f->A[b], f->B[b], f->C[b]); + f->window[b] = (float*)setup_malloc(f, sizeof(float) * n2); + if (!f->window[b]) return error(f, VORBIS_outofmem); + compute_window(n, f->window[b]); + f->bit_reverse[b] = (uint16*)setup_malloc(f, sizeof(uint16) * n8); + if (!f->bit_reverse[b]) return error(f, VORBIS_outofmem); + compute_bitreverse(n, f->bit_reverse[b]); + return TRUE; } -static void neighbors(uint16 *x, int n, int *plow, int *phigh) -{ - int low = -1; - int high = 65536; - int i; - for (i=0; i < n; ++i) { - if (x[i] > low && x[i] < x[n]) { *plow = i; low = x[i]; } - if (x[i] < high && x[i] > x[n]) { *phigh = i; high = x[i]; } - } +static void neighbors(uint16* x, int n, int* plow, int* phigh) { + int low = -1; + int high = 65536; + int i; + for (i = 0; i < n; ++i) { + if (x[i] > low && x[i] < x[n]) { + *plow = i; + low = x[i]; + } + if (x[i] < high && x[i] > x[n]) { + *phigh = i; + high = x[i]; + } + } } -typedef struct -{ - uint16 x,id; +typedef struct { + uint16 x, id; } stbv__floor_ordering; -static int STBV_CDECL point_compare(const void *p, const void *q) -{ - stbv__floor_ordering *a = (stbv__floor_ordering *) p; - stbv__floor_ordering *b = (stbv__floor_ordering *) q; - return a->x < b->x ? -1 : a->x > b->x; +static int STBV_CDECL point_compare(const void* p, const void* q) { + stbv__floor_ordering* a = (stbv__floor_ordering*)p; + stbv__floor_ordering* b = (stbv__floor_ordering*)q; + return a->x < b->x ? -1 : a->x > b->x; } #if defined(STB_VORBIS_NO_STDIO) - #define USE_MEMORY(z) TRUE +#define USE_MEMORY(z) TRUE #else - #define USE_MEMORY(z) ((z)->stream) +#define USE_MEMORY(z) ((z)->stream) #endif -static uint8 get8(vorb *z) -{ - if (USE_MEMORY(z)) { - if (z->stream >= z->stream_end) { z->eof = TRUE; return 0; } - return *z->stream++; - } - - #ifndef STB_VORBIS_NO_STDIO - { - int c = fgetc(z->f); - if (c == EOF) { z->eof = TRUE; return 0; } - return c; - } - #endif -} - -static uint32 get32(vorb *f) -{ - uint32 x; - x = get8(f); - x += get8(f) << 8; - x += get8(f) << 16; - x += (uint32) get8(f) << 24; - return x; -} - -static int getn(vorb *z, uint8 *data, int n) -{ - if (USE_MEMORY(z)) { - if (z->stream+n > z->stream_end) { z->eof = 1; return 0; } - memcpy(data, z->stream, n); - z->stream += n; - return 1; - } - - #ifndef STB_VORBIS_NO_STDIO - if (fread(data, n, 1, z->f) == 1) - return 1; - else { - z->eof = 1; - return 0; - } - #endif -} - -static void skip(vorb *z, int n) -{ - if (USE_MEMORY(z)) { - z->stream += n; - if (z->stream >= z->stream_end) z->eof = 1; - return; - } - #ifndef STB_VORBIS_NO_STDIO - { - long x = ftell(z->f); - fseek(z->f, x+n, SEEK_SET); - } - #endif -} - -static int set_file_offset(stb_vorbis *f, unsigned int loc) -{ - #ifndef STB_VORBIS_NO_PUSHDATA_API - if (f->push_mode) return 0; - #endif - f->eof = 0; - if (USE_MEMORY(f)) { - if ((size_t)(f->stream_start + loc) >= (size_t)f->stream_end || - (size_t)(f->stream_start + loc) < (size_t)f->stream_start) { - f->stream = f->stream_end; - f->eof = 1; - return 0; - } else { - f->stream = f->stream_start + loc; - return 1; - } - } - #ifndef STB_VORBIS_NO_STDIO - if (loc + f->f_start < loc || loc >= 0x80000000) { - loc = 0x7fffffff; - f->eof = 1; - } else { - loc += f->f_start; - } - if (!fseek(f->f, loc, SEEK_SET)) - return 1; - f->eof = 1; - fseek(f->f, f->f_start, SEEK_END); - return 0; - #endif -} - -static uint8 ogg_page_header[4] = { 0x4f, 0x67, 0x67, 0x53 }; - -static int capture_pattern(vorb *f) -{ - if (0x4f != get8(f)) return FALSE; - if (0x67 != get8(f)) return FALSE; - if (0x67 != get8(f)) return FALSE; - if (0x53 != get8(f)) return FALSE; - return TRUE; -} - -#define PAGEFLAG_continued_packet 1 -#define PAGEFLAG_first_page 2 -#define PAGEFLAG_last_page 4 - -static int start_page_no_capturepattern(vorb *f) -{ - uint32 loc0,loc1,n; - if (f->first_decode && !IS_PUSH_MODE(f)) { - f->p_first.page_start = stb_vorbis_get_file_offset(f) - 4; - } - - if (0 != get8(f)) return error(f, VORBIS_invalid_stream_structure_version); - - f->page_flag = get8(f); - - loc0 = get32(f); - loc1 = get32(f); - - get32(f); - - n = get32(f); - f->last_page = n; - - get32(f); - - f->segment_count = get8(f); - if (!getn(f, f->segments, f->segment_count)) - return error(f, VORBIS_unexpected_eof); - - f->end_seg_with_known_loc = -2; - if (loc0 != ~0U || loc1 != ~0U) { - int i; - - for (i=f->segment_count-1; i >= 0; --i) - if (f->segments[i] < 255) - break; - - if (i >= 0) { - f->end_seg_with_known_loc = i; - f->known_loc_for_packet = loc0; - } - } - if (f->first_decode) { - int i,len; - len = 0; - for (i=0; i < f->segment_count; ++i) - len += f->segments[i]; - len += 27 + f->segment_count; - f->p_first.page_end = f->p_first.page_start + len; - f->p_first.last_decoded_sample = loc0; - } - f->next_seg = 0; - return TRUE; -} - -static int start_page(vorb *f) -{ - if (!capture_pattern(f)) return error(f, VORBIS_missing_capture_pattern); - return start_page_no_capturepattern(f); -} - -static int start_packet(vorb *f) -{ - while (f->next_seg == -1) { - if (!start_page(f)) return FALSE; - if (f->page_flag & PAGEFLAG_continued_packet) - return error(f, VORBIS_continued_packet_flag_invalid); - } - f->last_seg = FALSE; - f->valid_bits = 0; - f->packet_bytes = 0; - f->bytes_in_seg = 0; - - return TRUE; -} - -static int maybe_start_packet(vorb *f) -{ - if (f->next_seg == -1) { - int x = get8(f); - if (f->eof) return FALSE; - if (0x4f != x ) return error(f, VORBIS_missing_capture_pattern); - if (0x67 != get8(f)) return error(f, VORBIS_missing_capture_pattern); - if (0x67 != get8(f)) return error(f, VORBIS_missing_capture_pattern); - if (0x53 != get8(f)) return error(f, VORBIS_missing_capture_pattern); - if (!start_page_no_capturepattern(f)) return FALSE; - if (f->page_flag & PAGEFLAG_continued_packet) { - - f->last_seg = FALSE; - f->bytes_in_seg = 0; - return error(f, VORBIS_continued_packet_flag_invalid); - } - } - return start_packet(f); -} - -static int next_segment(vorb *f) -{ - int len; - if (f->last_seg) return 0; - if (f->next_seg == -1) { - f->last_seg_which = f->segment_count-1; - if (!start_page(f)) { f->last_seg = 1; return 0; } - if (!(f->page_flag & PAGEFLAG_continued_packet)) return error(f, VORBIS_continued_packet_flag_invalid); - } - len = f->segments[f->next_seg++]; - if (len < 255) { - f->last_seg = TRUE; - f->last_seg_which = f->next_seg-1; - } - if (f->next_seg >= f->segment_count) - f->next_seg = -1; - assert(f->bytes_in_seg == 0); - f->bytes_in_seg = len; - return len; -} - -#define EOP (-1) -#define INVALID_BITS (-1) - -static int get8_packet_raw(vorb *f) -{ - if (!f->bytes_in_seg) { - if (f->last_seg) return EOP; - else if (!next_segment(f)) return EOP; - } - assert(f->bytes_in_seg > 0); - --f->bytes_in_seg; - ++f->packet_bytes; - return get8(f); -} - -static int get8_packet(vorb *f) -{ - int x = get8_packet_raw(f); - f->valid_bits = 0; - return x; -} - -static int get32_packet(vorb *f) -{ - uint32 x; - x = get8_packet(f); - x += get8_packet(f) << 8; - x += get8_packet(f) << 16; - x += (uint32) get8_packet(f) << 24; - return x; -} - -static void flush_packet(vorb *f) -{ - while (get8_packet_raw(f) != EOP); -} - -static uint32 get_bits(vorb *f, int n) -{ - uint32 z; - - if (f->valid_bits < 0) return 0; - if (f->valid_bits < n) { - if (n > 24) { - - z = get_bits(f, 24); - z += get_bits(f, n-24) << 24; - return z; - } - if (f->valid_bits == 0) f->acc = 0; - while (f->valid_bits < n) { - int z = get8_packet_raw(f); - if (z == EOP) { - f->valid_bits = INVALID_BITS; +static uint8 get8(vorb* z) { + if (USE_MEMORY(z)) { + if (z->stream >= z->stream_end) { + z->eof = TRUE; return 0; - } - f->acc += z << f->valid_bits; - f->valid_bits += 8; - } - } + } + return *z->stream++; + } - assert(f->valid_bits >= n); - z = f->acc & ((1 << n)-1); - f->acc >>= n; - f->valid_bits -= n; - return z; +#ifndef STB_VORBIS_NO_STDIO + { + int c = fgetc(z->f); + if (c == EOF) { + z->eof = TRUE; + return 0; + } + return c; + } +#endif } -static __forceinline void prep_huffman(vorb *f) -{ - if (f->valid_bits <= 24) { - if (f->valid_bits == 0) f->acc = 0; - do { - int z; - if (f->last_seg && !f->bytes_in_seg) return; - z = get8_packet_raw(f); - if (z == EOP) return; - f->acc += (unsigned) z << f->valid_bits; - f->valid_bits += 8; - } while (f->valid_bits <= 24); - } +static uint32 get32(vorb* f) { + uint32 x; + x = get8(f); + x += get8(f) << 8; + x += get8(f) << 16; + x += (uint32)get8(f) << 24; + return x; } -enum -{ - VORBIS_packet_id = 1, - VORBIS_packet_comment = 3, - VORBIS_packet_setup = 5 +static int getn(vorb* z, uint8* data, int n) { + if (USE_MEMORY(z)) { + if (z->stream + n > z->stream_end) { + z->eof = 1; + return 0; + } + memcpy(data, z->stream, n); + z->stream += n; + return 1; + } + +#ifndef STB_VORBIS_NO_STDIO + if (fread(data, n, 1, z->f) == 1) + return 1; + else { + z->eof = 1; + return 0; + } +#endif +} + +static void skip(vorb* z, int n) { + if (USE_MEMORY(z)) { + z->stream += n; + if (z->stream >= z->stream_end) z->eof = 1; + return; + } +#ifndef STB_VORBIS_NO_STDIO + { + long x = ftell(z->f); + fseek(z->f, x + n, SEEK_SET); + } +#endif +} + +static int set_file_offset(stb_vorbis* f, unsigned int loc) { +#ifndef STB_VORBIS_NO_PUSHDATA_API + if (f->push_mode) return 0; +#endif + f->eof = 0; + if (USE_MEMORY(f)) { + if ((size_t)(f->stream_start + loc) >= (size_t)f->stream_end || + (size_t)(f->stream_start + loc) < (size_t)f->stream_start) { + f->stream = f->stream_end; + f->eof = 1; + return 0; + } else { + f->stream = f->stream_start + loc; + return 1; + } + } +#ifndef STB_VORBIS_NO_STDIO + if (loc + f->f_start < loc || loc >= 0x80000000) { + loc = 0x7fffffff; + f->eof = 1; + } else { + loc += f->f_start; + } + if (!fseek(f->f, loc, SEEK_SET)) return 1; + f->eof = 1; + fseek(f->f, f->f_start, SEEK_END); + return 0; +#endif +} + +static uint8 ogg_page_header[4] = {0x4f, 0x67, 0x67, 0x53}; + +static int capture_pattern(vorb* f) { + if (0x4f != get8(f)) return FALSE; + if (0x67 != get8(f)) return FALSE; + if (0x67 != get8(f)) return FALSE; + if (0x53 != get8(f)) return FALSE; + return TRUE; +} + +#define PAGEFLAG_continued_packet 1 +#define PAGEFLAG_first_page 2 +#define PAGEFLAG_last_page 4 + +static int start_page_no_capturepattern(vorb* f) { + uint32 loc0, loc1, n; + if (f->first_decode && !IS_PUSH_MODE(f)) { + f->p_first.page_start = stb_vorbis_get_file_offset(f) - 4; + } + + if (0 != get8(f)) return error(f, VORBIS_invalid_stream_structure_version); + + f->page_flag = get8(f); + + loc0 = get32(f); + loc1 = get32(f); + + get32(f); + + n = get32(f); + f->last_page = n; + + get32(f); + + f->segment_count = get8(f); + if (!getn(f, f->segments, f->segment_count)) + return error(f, VORBIS_unexpected_eof); + + f->end_seg_with_known_loc = -2; + if (loc0 != ~0U || loc1 != ~0U) { + int i; + + for (i = f->segment_count - 1; i >= 0; --i) + if (f->segments[i] < 255) break; + + if (i >= 0) { + f->end_seg_with_known_loc = i; + f->known_loc_for_packet = loc0; + } + } + if (f->first_decode) { + int i, len; + len = 0; + for (i = 0; i < f->segment_count; ++i) len += f->segments[i]; + len += 27 + f->segment_count; + f->p_first.page_end = f->p_first.page_start + len; + f->p_first.last_decoded_sample = loc0; + } + f->next_seg = 0; + return TRUE; +} + +static int start_page(vorb* f) { + if (!capture_pattern(f)) return error(f, VORBIS_missing_capture_pattern); + return start_page_no_capturepattern(f); +} + +static int start_packet(vorb* f) { + while (f->next_seg == -1) { + if (!start_page(f)) return FALSE; + if (f->page_flag & PAGEFLAG_continued_packet) + return error(f, VORBIS_continued_packet_flag_invalid); + } + f->last_seg = FALSE; + f->valid_bits = 0; + f->packet_bytes = 0; + f->bytes_in_seg = 0; + + return TRUE; +} + +static int maybe_start_packet(vorb* f) { + if (f->next_seg == -1) { + int x = get8(f); + if (f->eof) return FALSE; + if (0x4f != x) return error(f, VORBIS_missing_capture_pattern); + if (0x67 != get8(f)) return error(f, VORBIS_missing_capture_pattern); + if (0x67 != get8(f)) return error(f, VORBIS_missing_capture_pattern); + if (0x53 != get8(f)) return error(f, VORBIS_missing_capture_pattern); + if (!start_page_no_capturepattern(f)) return FALSE; + if (f->page_flag & PAGEFLAG_continued_packet) { + f->last_seg = FALSE; + f->bytes_in_seg = 0; + return error(f, VORBIS_continued_packet_flag_invalid); + } + } + return start_packet(f); +} + +static int next_segment(vorb* f) { + int len; + if (f->last_seg) return 0; + if (f->next_seg == -1) { + f->last_seg_which = f->segment_count - 1; + if (!start_page(f)) { + f->last_seg = 1; + return 0; + } + if (!(f->page_flag & PAGEFLAG_continued_packet)) + return error(f, VORBIS_continued_packet_flag_invalid); + } + len = f->segments[f->next_seg++]; + if (len < 255) { + f->last_seg = TRUE; + f->last_seg_which = f->next_seg - 1; + } + if (f->next_seg >= f->segment_count) f->next_seg = -1; + assert(f->bytes_in_seg == 0); + f->bytes_in_seg = len; + return len; +} + +#define EOP (-1) +#define INVALID_BITS (-1) + +static int get8_packet_raw(vorb* f) { + if (!f->bytes_in_seg) { + if (f->last_seg) + return EOP; + else if (!next_segment(f)) + return EOP; + } + assert(f->bytes_in_seg > 0); + --f->bytes_in_seg; + ++f->packet_bytes; + return get8(f); +} + +static int get8_packet(vorb* f) { + int x = get8_packet_raw(f); + f->valid_bits = 0; + return x; +} + +static int get32_packet(vorb* f) { + uint32 x; + x = get8_packet(f); + x += get8_packet(f) << 8; + x += get8_packet(f) << 16; + x += (uint32)get8_packet(f) << 24; + return x; +} + +static void flush_packet(vorb* f) { while (get8_packet_raw(f) != EOP); } + +static uint32 get_bits(vorb* f, int n) { + uint32 z; + + if (f->valid_bits < 0) return 0; + if (f->valid_bits < n) { + if (n > 24) { + z = get_bits(f, 24); + z += get_bits(f, n - 24) << 24; + return z; + } + if (f->valid_bits == 0) f->acc = 0; + while (f->valid_bits < n) { + int z = get8_packet_raw(f); + if (z == EOP) { + f->valid_bits = INVALID_BITS; + return 0; + } + f->acc += z << f->valid_bits; + f->valid_bits += 8; + } + } + + assert(f->valid_bits >= n); + z = f->acc & ((1 << n) - 1); + f->acc >>= n; + f->valid_bits -= n; + return z; +} + +static __forceinline void prep_huffman(vorb* f) { + if (f->valid_bits <= 24) { + if (f->valid_bits == 0) f->acc = 0; + do { + int z; + if (f->last_seg && !f->bytes_in_seg) return; + z = get8_packet_raw(f); + if (z == EOP) return; + f->acc += (unsigned)z << f->valid_bits; + f->valid_bits += 8; + } while (f->valid_bits <= 24); + } +} + +enum { + VORBIS_packet_id = 1, + VORBIS_packet_comment = 3, + VORBIS_packet_setup = 5 }; -static int codebook_decode_scalar_raw(vorb *f, Codebook *c) -{ - int i; - prep_huffman(f); +static int codebook_decode_scalar_raw(vorb* f, Codebook* c) { + int i; + prep_huffman(f); - if (c->codewords == NULL && c->sorted_codewords == NULL) - return -1; + if (c->codewords == NULL && c->sorted_codewords == NULL) return -1; - if (c->entries > 8 ? c->sorted_codewords!=NULL : !c->codewords) { - - uint32 code = bit_reverse(f->acc); - int x=0, n=c->sorted_entries, len; + if (c->entries > 8 ? c->sorted_codewords != NULL : !c->codewords) { + uint32 code = bit_reverse(f->acc); + int x = 0, n = c->sorted_entries, len; - while (n > 1) { - - int m = x + (n >> 1); - if (c->sorted_codewords[m] <= code) { - x = m; - n -= (n>>1); - } else { - n >>= 1; - } - } - - if (!c->sparse) x = c->sorted_values[x]; - - len = c->codeword_lengths[x]; - if (f->valid_bits >= len) { - f->acc >>= len; - f->valid_bits -= len; - return x; - } + while (n > 1) { + int m = x + (n >> 1); + if (c->sorted_codewords[m] <= code) { + x = m; + n -= (n >> 1); + } else { + n >>= 1; + } + } - f->valid_bits = 0; - return -1; - } + if (!c->sparse) x = c->sorted_values[x]; - assert(!c->sparse); - for (i=0; i < c->entries; ++i) { - if (c->codeword_lengths[i] == NO_CODE) continue; - if (c->codewords[i] == (f->acc & ((1 << c->codeword_lengths[i])-1))) { - if (f->valid_bits >= c->codeword_lengths[i]) { - f->acc >>= c->codeword_lengths[i]; - f->valid_bits -= c->codeword_lengths[i]; - return i; - } - f->valid_bits = 0; - return -1; - } - } + len = c->codeword_lengths[x]; + if (f->valid_bits >= len) { + f->acc >>= len; + f->valid_bits -= len; + return x; + } - error(f, VORBIS_invalid_stream); - f->valid_bits = 0; - return -1; + f->valid_bits = 0; + return -1; + } + + assert(!c->sparse); + for (i = 0; i < c->entries; ++i) { + if (c->codeword_lengths[i] == NO_CODE) continue; + if (c->codewords[i] == (f->acc & ((1 << c->codeword_lengths[i]) - 1))) { + if (f->valid_bits >= c->codeword_lengths[i]) { + f->acc >>= c->codeword_lengths[i]; + f->valid_bits -= c->codeword_lengths[i]; + return i; + } + f->valid_bits = 0; + return -1; + } + } + + error(f, VORBIS_invalid_stream); + f->valid_bits = 0; + return -1; } #ifndef STB_VORBIS_NO_INLINE_DECODE -#define DECODE_RAW(var, f,c) \ - if (f->valid_bits < STB_VORBIS_FAST_HUFFMAN_LENGTH) \ - prep_huffman(f); \ - var = f->acc & FAST_HUFFMAN_TABLE_MASK; \ - var = c->fast_huffman[var]; \ - if (var >= 0) { \ - int n = c->codeword_lengths[var]; \ - f->acc >>= n; \ - f->valid_bits -= n; \ - if (f->valid_bits < 0) { f->valid_bits = 0; var = -1; } \ - } else { \ - var = codebook_decode_scalar_raw(f,c); \ - } +#define DECODE_RAW(var, f, c) \ + if (f->valid_bits < STB_VORBIS_FAST_HUFFMAN_LENGTH) prep_huffman(f); \ + var = f->acc & FAST_HUFFMAN_TABLE_MASK; \ + var = c->fast_huffman[var]; \ + if (var >= 0) { \ + int n = c->codeword_lengths[var]; \ + f->acc >>= n; \ + f->valid_bits -= n; \ + if (f->valid_bits < 0) { \ + f->valid_bits = 0; \ + var = -1; \ + } \ + } else { \ + var = codebook_decode_scalar_raw(f, c); \ + } #else -static int codebook_decode_scalar(vorb *f, Codebook *c) -{ - int i; - if (f->valid_bits < STB_VORBIS_FAST_HUFFMAN_LENGTH) - prep_huffman(f); - - i = f->acc & FAST_HUFFMAN_TABLE_MASK; - i = c->fast_huffman[i]; - if (i >= 0) { - f->acc >>= c->codeword_lengths[i]; - f->valid_bits -= c->codeword_lengths[i]; - if (f->valid_bits < 0) { f->valid_bits = 0; return -1; } - return i; - } - return codebook_decode_scalar_raw(f,c); +static int codebook_decode_scalar(vorb* f, Codebook* c) { + int i; + if (f->valid_bits < STB_VORBIS_FAST_HUFFMAN_LENGTH) prep_huffman(f); + + i = f->acc & FAST_HUFFMAN_TABLE_MASK; + i = c->fast_huffman[i]; + if (i >= 0) { + f->acc >>= c->codeword_lengths[i]; + f->valid_bits -= c->codeword_lengths[i]; + if (f->valid_bits < 0) { + f->valid_bits = 0; + return -1; + } + return i; + } + return codebook_decode_scalar_raw(f, c); } -#define DECODE_RAW(var,f,c) var = codebook_decode_scalar(f,c); +#define DECODE_RAW(var, f, c) var = codebook_decode_scalar(f, c); #endif -#define DECODE(var,f,c) \ - DECODE_RAW(var,f,c) \ - if (c->sparse) var = c->sorted_values[var]; +#define DECODE(var, f, c) \ + DECODE_RAW(var, f, c) \ + if (c->sparse) var = c->sorted_values[var]; #ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK - #define DECODE_VQ(var,f,c) DECODE_RAW(var,f,c) +#define DECODE_VQ(var, f, c) DECODE_RAW(var, f, c) #else - #define DECODE_VQ(var,f,c) DECODE(var,f,c) +#define DECODE_VQ(var, f, c) DECODE(var, f, c) #endif -#define CODEBOOK_ELEMENT(c,off) (c->multiplicands[off]) -#define CODEBOOK_ELEMENT_FAST(c,off) (c->multiplicands[off]) -#define CODEBOOK_ELEMENT_BASE(c) (0) +#define CODEBOOK_ELEMENT(c, off) (c->multiplicands[off]) +#define CODEBOOK_ELEMENT_FAST(c, off) (c->multiplicands[off]) +#define CODEBOOK_ELEMENT_BASE(c) (0) -static int codebook_decode_start(vorb *f, Codebook *c) -{ - int z = -1; +static int codebook_decode_start(vorb* f, Codebook* c) { + int z = -1; - if (c->lookup_type == 0) - error(f, VORBIS_invalid_stream); - else { - DECODE_VQ(z,f,c); - if (c->sparse) assert(z < c->sorted_entries); - if (z < 0) { - if (!f->bytes_in_seg) - if (f->last_seg) - return z; - error(f, VORBIS_invalid_stream); - } - } - return z; + if (c->lookup_type == 0) + error(f, VORBIS_invalid_stream); + else { + DECODE_VQ(z, f, c); + if (c->sparse) assert(z < c->sorted_entries); + if (z < 0) { + if (!f->bytes_in_seg) + if (f->last_seg) return z; + error(f, VORBIS_invalid_stream); + } + } + return z; } -static int codebook_decode(vorb *f, Codebook *c, float *output, int len) -{ - int i,z = codebook_decode_start(f,c); - if (z < 0) return FALSE; - if (len > c->dimensions) len = c->dimensions; +static int codebook_decode(vorb* f, Codebook* c, float* output, int len) { + int i, z = codebook_decode_start(f, c); + if (z < 0) return FALSE; + if (len > c->dimensions) len = c->dimensions; #ifdef STB_VORBIS_DIVIDES_IN_CODEBOOK - if (c->lookup_type == 1) { - float last = CODEBOOK_ELEMENT_BASE(c); - int div = 1; - for (i=0; i < len; ++i) { - int off = (z / div) % c->lookup_values; - float val = CODEBOOK_ELEMENT_FAST(c,off) + last; - output[i] += val; - if (c->sequence_p) last = val + c->minimum_value; - div *= c->lookup_values; - } - return TRUE; - } -#endif - - z *= c->dimensions; - if (c->sequence_p) { - float last = CODEBOOK_ELEMENT_BASE(c); - for (i=0; i < len; ++i) { - float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last; - output[i] += val; - last = val + c->minimum_value; - } - } else { - float last = CODEBOOK_ELEMENT_BASE(c); - for (i=0; i < len; ++i) { - output[i] += CODEBOOK_ELEMENT_FAST(c,z+i) + last; - } - } - - return TRUE; -} - -static int codebook_decode_step(vorb *f, Codebook *c, float *output, int len, int step) -{ - int i,z = codebook_decode_start(f,c); - float last = CODEBOOK_ELEMENT_BASE(c); - if (z < 0) return FALSE; - if (len > c->dimensions) len = c->dimensions; - -#ifdef STB_VORBIS_DIVIDES_IN_CODEBOOK - if (c->lookup_type == 1) { - int div = 1; - for (i=0; i < len; ++i) { - int off = (z / div) % c->lookup_values; - float val = CODEBOOK_ELEMENT_FAST(c,off) + last; - output[i*step] += val; - if (c->sequence_p) last = val; - div *= c->lookup_values; - } - return TRUE; - } -#endif - - z *= c->dimensions; - for (i=0; i < len; ++i) { - float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last; - output[i*step] += val; - if (c->sequence_p) last = val; - } - - return TRUE; -} - -static int codebook_decode_deinterleave_repeat(vorb *f, Codebook *c, float **outputs, int ch, int *c_inter_p, int *p_inter_p, int len, int total_decode) -{ - int c_inter = *c_inter_p; - int p_inter = *p_inter_p; - int i,z, effective = c->dimensions; - - if (c->lookup_type == 0) return error(f, VORBIS_invalid_stream); - - while (total_decode > 0) { - float last = CODEBOOK_ELEMENT_BASE(c); - DECODE_VQ(z,f,c); - #ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK - assert(!c->sparse || z < c->sorted_entries); - #endif - if (z < 0) { - if (!f->bytes_in_seg) - if (f->last_seg) return FALSE; - return error(f, VORBIS_invalid_stream); - } - - if (c_inter + p_inter*ch + effective > len * ch) { - effective = len*ch - (p_inter*ch - c_inter); - } - - #ifdef STB_VORBIS_DIVIDES_IN_CODEBOOK - if (c->lookup_type == 1) { - int div = 1; - for (i=0; i < effective; ++i) { + if (c->lookup_type == 1) { + float last = CODEBOOK_ELEMENT_BASE(c); + int div = 1; + for (i = 0; i < len; ++i) { int off = (z / div) % c->lookup_values; - float val = CODEBOOK_ELEMENT_FAST(c,off) + last; - if (outputs[c_inter]) - outputs[c_inter][p_inter] += val; - if (++c_inter == ch) { c_inter = 0; ++p_inter; } + float val = CODEBOOK_ELEMENT_FAST(c, off) + last; + output[i] += val; + if (c->sequence_p) last = val + c->minimum_value; + div *= c->lookup_values; + } + return TRUE; + } +#endif + + z *= c->dimensions; + if (c->sequence_p) { + float last = CODEBOOK_ELEMENT_BASE(c); + for (i = 0; i < len; ++i) { + float val = CODEBOOK_ELEMENT_FAST(c, z + i) + last; + output[i] += val; + last = val + c->minimum_value; + } + } else { + float last = CODEBOOK_ELEMENT_BASE(c); + for (i = 0; i < len; ++i) { + output[i] += CODEBOOK_ELEMENT_FAST(c, z + i) + last; + } + } + + return TRUE; +} + +static int codebook_decode_step(vorb* f, Codebook* c, float* output, int len, + int step) { + int i, z = codebook_decode_start(f, c); + float last = CODEBOOK_ELEMENT_BASE(c); + if (z < 0) return FALSE; + if (len > c->dimensions) len = c->dimensions; + +#ifdef STB_VORBIS_DIVIDES_IN_CODEBOOK + if (c->lookup_type == 1) { + int div = 1; + for (i = 0; i < len; ++i) { + int off = (z / div) % c->lookup_values; + float val = CODEBOOK_ELEMENT_FAST(c, off) + last; + output[i * step] += val; if (c->sequence_p) last = val; div *= c->lookup_values; - } - } else - #endif - { - z *= c->dimensions; - if (c->sequence_p) { - for (i=0; i < effective; ++i) { - float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last; - if (outputs[c_inter]) - outputs[c_inter][p_inter] += val; - if (++c_inter == ch) { c_inter = 0; ++p_inter; } - last = val; - } - } else { - for (i=0; i < effective; ++i) { - float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last; - if (outputs[c_inter]) - outputs[c_inter][p_inter] += val; - if (++c_inter == ch) { c_inter = 0; ++p_inter; } - } - } - } + } + return TRUE; + } +#endif - total_decode -= effective; - } - *c_inter_p = c_inter; - *p_inter_p = p_inter; - return TRUE; + z *= c->dimensions; + for (i = 0; i < len; ++i) { + float val = CODEBOOK_ELEMENT_FAST(c, z + i) + last; + output[i * step] += val; + if (c->sequence_p) last = val; + } + + return TRUE; } -static int predict_point(int x, int x0, int x1, int y0, int y1) -{ - int dy = y1 - y0; - int adx = x1 - x0; - - int err = abs(dy) * (x - x0); - int off = err / adx; - return dy < 0 ? y0 - off : y0 + off; +static int codebook_decode_deinterleave_repeat(vorb* f, Codebook* c, + float** outputs, int ch, + int* c_inter_p, int* p_inter_p, + int len, int total_decode) { + int c_inter = *c_inter_p; + int p_inter = *p_inter_p; + int i, z, effective = c->dimensions; + + if (c->lookup_type == 0) return error(f, VORBIS_invalid_stream); + + while (total_decode > 0) { + float last = CODEBOOK_ELEMENT_BASE(c); + DECODE_VQ(z, f, c); +#ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK + assert(!c->sparse || z < c->sorted_entries); +#endif + if (z < 0) { + if (!f->bytes_in_seg) + if (f->last_seg) return FALSE; + return error(f, VORBIS_invalid_stream); + } + + if (c_inter + p_inter * ch + effective > len * ch) { + effective = len * ch - (p_inter * ch - c_inter); + } + +#ifdef STB_VORBIS_DIVIDES_IN_CODEBOOK + if (c->lookup_type == 1) { + int div = 1; + for (i = 0; i < effective; ++i) { + int off = (z / div) % c->lookup_values; + float val = CODEBOOK_ELEMENT_FAST(c, off) + last; + if (outputs[c_inter]) outputs[c_inter][p_inter] += val; + if (++c_inter == ch) { + c_inter = 0; + ++p_inter; + } + if (c->sequence_p) last = val; + div *= c->lookup_values; + } + } else +#endif + { + z *= c->dimensions; + if (c->sequence_p) { + for (i = 0; i < effective; ++i) { + float val = CODEBOOK_ELEMENT_FAST(c, z + i) + last; + if (outputs[c_inter]) outputs[c_inter][p_inter] += val; + if (++c_inter == ch) { + c_inter = 0; + ++p_inter; + } + last = val; + } + } else { + for (i = 0; i < effective; ++i) { + float val = CODEBOOK_ELEMENT_FAST(c, z + i) + last; + if (outputs[c_inter]) outputs[c_inter][p_inter] += val; + if (++c_inter == ch) { + c_inter = 0; + ++p_inter; + } + } + } + } + + total_decode -= effective; + } + *c_inter_p = c_inter; + *p_inter_p = p_inter; + return TRUE; } -static float inverse_db_table[256] = -{ - 1.0649863e-07f, 1.1341951e-07f, 1.2079015e-07f, 1.2863978e-07f, - 1.3699951e-07f, 1.4590251e-07f, 1.5538408e-07f, 1.6548181e-07f, - 1.7623575e-07f, 1.8768855e-07f, 1.9988561e-07f, 2.1287530e-07f, - 2.2670913e-07f, 2.4144197e-07f, 2.5713223e-07f, 2.7384213e-07f, - 2.9163793e-07f, 3.1059021e-07f, 3.3077411e-07f, 3.5226968e-07f, - 3.7516214e-07f, 3.9954229e-07f, 4.2550680e-07f, 4.5315863e-07f, - 4.8260743e-07f, 5.1396998e-07f, 5.4737065e-07f, 5.8294187e-07f, - 6.2082472e-07f, 6.6116941e-07f, 7.0413592e-07f, 7.4989464e-07f, - 7.9862701e-07f, 8.5052630e-07f, 9.0579828e-07f, 9.6466216e-07f, - 1.0273513e-06f, 1.0941144e-06f, 1.1652161e-06f, 1.2409384e-06f, - 1.3215816e-06f, 1.4074654e-06f, 1.4989305e-06f, 1.5963394e-06f, - 1.7000785e-06f, 1.8105592e-06f, 1.9282195e-06f, 2.0535261e-06f, - 2.1869758e-06f, 2.3290978e-06f, 2.4804557e-06f, 2.6416497e-06f, - 2.8133190e-06f, 2.9961443e-06f, 3.1908506e-06f, 3.3982101e-06f, - 3.6190449e-06f, 3.8542308e-06f, 4.1047004e-06f, 4.3714470e-06f, - 4.6555282e-06f, 4.9580707e-06f, 5.2802740e-06f, 5.6234160e-06f, - 5.9888572e-06f, 6.3780469e-06f, 6.7925283e-06f, 7.2339451e-06f, - 7.7040476e-06f, 8.2047000e-06f, 8.7378876e-06f, 9.3057248e-06f, - 9.9104632e-06f, 1.0554501e-05f, 1.1240392e-05f, 1.1970856e-05f, - 1.2748789e-05f, 1.3577278e-05f, 1.4459606e-05f, 1.5399272e-05f, - 1.6400004e-05f, 1.7465768e-05f, 1.8600792e-05f, 1.9809576e-05f, - 2.1096914e-05f, 2.2467911e-05f, 2.3928002e-05f, 2.5482978e-05f, - 2.7139006e-05f, 2.8902651e-05f, 3.0780908e-05f, 3.2781225e-05f, - 3.4911534e-05f, 3.7180282e-05f, 3.9596466e-05f, 4.2169667e-05f, - 4.4910090e-05f, 4.7828601e-05f, 5.0936773e-05f, 5.4246931e-05f, - 5.7772202e-05f, 6.1526565e-05f, 6.5524908e-05f, 6.9783085e-05f, - 7.4317983e-05f, 7.9147585e-05f, 8.4291040e-05f, 8.9768747e-05f, - 9.5602426e-05f, 0.00010181521f, 0.00010843174f, 0.00011547824f, - 0.00012298267f, 0.00013097477f, 0.00013948625f, 0.00014855085f, - 0.00015820453f, 0.00016848555f, 0.00017943469f, 0.00019109536f, - 0.00020351382f, 0.00021673929f, 0.00023082423f, 0.00024582449f, - 0.00026179955f, 0.00027881276f, 0.00029693158f, 0.00031622787f, - 0.00033677814f, 0.00035866388f, 0.00038197188f, 0.00040679456f, - 0.00043323036f, 0.00046138411f, 0.00049136745f, 0.00052329927f, - 0.00055730621f, 0.00059352311f, 0.00063209358f, 0.00067317058f, - 0.00071691700f, 0.00076350630f, 0.00081312324f, 0.00086596457f, - 0.00092223983f, 0.00098217216f, 0.0010459992f, 0.0011139742f, - 0.0011863665f, 0.0012634633f, 0.0013455702f, 0.0014330129f, - 0.0015261382f, 0.0016253153f, 0.0017309374f, 0.0018434235f, - 0.0019632195f, 0.0020908006f, 0.0022266726f, 0.0023713743f, - 0.0025254795f, 0.0026895994f, 0.0028643847f, 0.0030505286f, - 0.0032487691f, 0.0034598925f, 0.0036847358f, 0.0039241906f, - 0.0041792066f, 0.0044507950f, 0.0047400328f, 0.0050480668f, - 0.0053761186f, 0.0057254891f, 0.0060975636f, 0.0064938176f, - 0.0069158225f, 0.0073652516f, 0.0078438871f, 0.0083536271f, - 0.0088964928f, 0.009474637f, 0.010090352f, 0.010746080f, - 0.011444421f, 0.012188144f, 0.012980198f, 0.013823725f, - 0.014722068f, 0.015678791f, 0.016697687f, 0.017782797f, - 0.018938423f, 0.020169149f, 0.021479854f, 0.022875735f, - 0.024362330f, 0.025945531f, 0.027631618f, 0.029427276f, - 0.031339626f, 0.033376252f, 0.035545228f, 0.037855157f, - 0.040315199f, 0.042935108f, 0.045725273f, 0.048696758f, - 0.051861348f, 0.055231591f, 0.058820850f, 0.062643361f, - 0.066714279f, 0.071049749f, 0.075666962f, 0.080584227f, - 0.085821044f, 0.091398179f, 0.097337747f, 0.10366330f, - 0.11039993f, 0.11757434f, 0.12521498f, 0.13335215f, - 0.14201813f, 0.15124727f, 0.16107617f, 0.17154380f, - 0.18269168f, 0.19456402f, 0.20720788f, 0.22067342f, - 0.23501402f, 0.25028656f, 0.26655159f, 0.28387361f, - 0.30232132f, 0.32196786f, 0.34289114f, 0.36517414f, - 0.38890521f, 0.41417847f, 0.44109412f, 0.46975890f, - 0.50028648f, 0.53279791f, 0.56742212f, 0.60429640f, - 0.64356699f, 0.68538959f, 0.72993007f, 0.77736504f, - 0.82788260f, 0.88168307f, 0.9389798f, 1.0f -}; +static int predict_point(int x, int x0, int x1, int y0, int y1) { + int dy = y1 - y0; + int adx = x1 - x0; + + int err = abs(dy) * (x - x0); + int off = err / adx; + return dy < 0 ? y0 - off : y0 + off; +} + +static float inverse_db_table[256] = { + 1.0649863e-07f, 1.1341951e-07f, 1.2079015e-07f, 1.2863978e-07f, + 1.3699951e-07f, 1.4590251e-07f, 1.5538408e-07f, 1.6548181e-07f, + 1.7623575e-07f, 1.8768855e-07f, 1.9988561e-07f, 2.1287530e-07f, + 2.2670913e-07f, 2.4144197e-07f, 2.5713223e-07f, 2.7384213e-07f, + 2.9163793e-07f, 3.1059021e-07f, 3.3077411e-07f, 3.5226968e-07f, + 3.7516214e-07f, 3.9954229e-07f, 4.2550680e-07f, 4.5315863e-07f, + 4.8260743e-07f, 5.1396998e-07f, 5.4737065e-07f, 5.8294187e-07f, + 6.2082472e-07f, 6.6116941e-07f, 7.0413592e-07f, 7.4989464e-07f, + 7.9862701e-07f, 8.5052630e-07f, 9.0579828e-07f, 9.6466216e-07f, + 1.0273513e-06f, 1.0941144e-06f, 1.1652161e-06f, 1.2409384e-06f, + 1.3215816e-06f, 1.4074654e-06f, 1.4989305e-06f, 1.5963394e-06f, + 1.7000785e-06f, 1.8105592e-06f, 1.9282195e-06f, 2.0535261e-06f, + 2.1869758e-06f, 2.3290978e-06f, 2.4804557e-06f, 2.6416497e-06f, + 2.8133190e-06f, 2.9961443e-06f, 3.1908506e-06f, 3.3982101e-06f, + 3.6190449e-06f, 3.8542308e-06f, 4.1047004e-06f, 4.3714470e-06f, + 4.6555282e-06f, 4.9580707e-06f, 5.2802740e-06f, 5.6234160e-06f, + 5.9888572e-06f, 6.3780469e-06f, 6.7925283e-06f, 7.2339451e-06f, + 7.7040476e-06f, 8.2047000e-06f, 8.7378876e-06f, 9.3057248e-06f, + 9.9104632e-06f, 1.0554501e-05f, 1.1240392e-05f, 1.1970856e-05f, + 1.2748789e-05f, 1.3577278e-05f, 1.4459606e-05f, 1.5399272e-05f, + 1.6400004e-05f, 1.7465768e-05f, 1.8600792e-05f, 1.9809576e-05f, + 2.1096914e-05f, 2.2467911e-05f, 2.3928002e-05f, 2.5482978e-05f, + 2.7139006e-05f, 2.8902651e-05f, 3.0780908e-05f, 3.2781225e-05f, + 3.4911534e-05f, 3.7180282e-05f, 3.9596466e-05f, 4.2169667e-05f, + 4.4910090e-05f, 4.7828601e-05f, 5.0936773e-05f, 5.4246931e-05f, + 5.7772202e-05f, 6.1526565e-05f, 6.5524908e-05f, 6.9783085e-05f, + 7.4317983e-05f, 7.9147585e-05f, 8.4291040e-05f, 8.9768747e-05f, + 9.5602426e-05f, 0.00010181521f, 0.00010843174f, 0.00011547824f, + 0.00012298267f, 0.00013097477f, 0.00013948625f, 0.00014855085f, + 0.00015820453f, 0.00016848555f, 0.00017943469f, 0.00019109536f, + 0.00020351382f, 0.00021673929f, 0.00023082423f, 0.00024582449f, + 0.00026179955f, 0.00027881276f, 0.00029693158f, 0.00031622787f, + 0.00033677814f, 0.00035866388f, 0.00038197188f, 0.00040679456f, + 0.00043323036f, 0.00046138411f, 0.00049136745f, 0.00052329927f, + 0.00055730621f, 0.00059352311f, 0.00063209358f, 0.00067317058f, + 0.00071691700f, 0.00076350630f, 0.00081312324f, 0.00086596457f, + 0.00092223983f, 0.00098217216f, 0.0010459992f, 0.0011139742f, + 0.0011863665f, 0.0012634633f, 0.0013455702f, 0.0014330129f, + 0.0015261382f, 0.0016253153f, 0.0017309374f, 0.0018434235f, + 0.0019632195f, 0.0020908006f, 0.0022266726f, 0.0023713743f, + 0.0025254795f, 0.0026895994f, 0.0028643847f, 0.0030505286f, + 0.0032487691f, 0.0034598925f, 0.0036847358f, 0.0039241906f, + 0.0041792066f, 0.0044507950f, 0.0047400328f, 0.0050480668f, + 0.0053761186f, 0.0057254891f, 0.0060975636f, 0.0064938176f, + 0.0069158225f, 0.0073652516f, 0.0078438871f, 0.0083536271f, + 0.0088964928f, 0.009474637f, 0.010090352f, 0.010746080f, + 0.011444421f, 0.012188144f, 0.012980198f, 0.013823725f, + 0.014722068f, 0.015678791f, 0.016697687f, 0.017782797f, + 0.018938423f, 0.020169149f, 0.021479854f, 0.022875735f, + 0.024362330f, 0.025945531f, 0.027631618f, 0.029427276f, + 0.031339626f, 0.033376252f, 0.035545228f, 0.037855157f, + 0.040315199f, 0.042935108f, 0.045725273f, 0.048696758f, + 0.051861348f, 0.055231591f, 0.058820850f, 0.062643361f, + 0.066714279f, 0.071049749f, 0.075666962f, 0.080584227f, + 0.085821044f, 0.091398179f, 0.097337747f, 0.10366330f, + 0.11039993f, 0.11757434f, 0.12521498f, 0.13335215f, + 0.14201813f, 0.15124727f, 0.16107617f, 0.17154380f, + 0.18269168f, 0.19456402f, 0.20720788f, 0.22067342f, + 0.23501402f, 0.25028656f, 0.26655159f, 0.28387361f, + 0.30232132f, 0.32196786f, 0.34289114f, 0.36517414f, + 0.38890521f, 0.41417847f, 0.44109412f, 0.46975890f, + 0.50028648f, 0.53279791f, 0.56742212f, 0.60429640f, + 0.64356699f, 0.68538959f, 0.72993007f, 0.77736504f, + 0.82788260f, 0.88168307f, 0.9389798f, 1.0f}; #ifndef STB_VORBIS_NO_DEFER_FLOOR -#define LINE_OP(a,b) a *= b +#define LINE_OP(a, b) a *= b #else -#define LINE_OP(a,b) a = b +#define LINE_OP(a, b) a = b #endif #ifdef STB_VORBIS_DIVIDE_TABLE -#define DIVTAB_NUMER 32 -#define DIVTAB_DENOM 64 -int8 integer_divide_table[DIVTAB_NUMER][DIVTAB_DENOM]; +#define DIVTAB_NUMER 32 +#define DIVTAB_DENOM 64 +int8 integer_divide_table[DIVTAB_NUMER][DIVTAB_DENOM]; #endif -static __forceinline void draw_line(float *output, int x0, int y0, int x1, int y1, int n) -{ - int dy = y1 - y0; - int adx = x1 - x0; - int ady = abs(dy); - int base; - int x=x0,y=y0; - int err = 0; - int sy; +static __forceinline void draw_line(float* output, int x0, int y0, int x1, + int y1, int n) { + int dy = y1 - y0; + int adx = x1 - x0; + int ady = abs(dy); + int base; + int x = x0, y = y0; + int err = 0; + int sy; #ifdef STB_VORBIS_DIVIDE_TABLE - if (adx < DIVTAB_DENOM && ady < DIVTAB_NUMER) { - if (dy < 0) { - base = -integer_divide_table[ady][adx]; - sy = base-1; - } else { - base = integer_divide_table[ady][adx]; - sy = base+1; - } - } else { - base = dy / adx; - if (dy < 0) - sy = base - 1; - else - sy = base+1; - } + if (adx < DIVTAB_DENOM && ady < DIVTAB_NUMER) { + if (dy < 0) { + base = -integer_divide_table[ady][adx]; + sy = base - 1; + } else { + base = integer_divide_table[ady][adx]; + sy = base + 1; + } + } else { + base = dy / adx; + if (dy < 0) + sy = base - 1; + else + sy = base + 1; + } #else - base = dy / adx; - if (dy < 0) - sy = base - 1; - else - sy = base+1; + base = dy / adx; + if (dy < 0) + sy = base - 1; + else + sy = base + 1; #endif - ady -= abs(base) * adx; - if (x1 > n) x1 = n; - if (x < x1) { - LINE_OP(output[x], inverse_db_table[y&255]); - for (++x; x < x1; ++x) { - err += ady; - if (err >= adx) { - err -= adx; - y += sy; - } else - y += base; - LINE_OP(output[x], inverse_db_table[y&255]); - } - } + ady -= abs(base) * adx; + if (x1 > n) x1 = n; + if (x < x1) { + LINE_OP(output[x], inverse_db_table[y & 255]); + for (++x; x < x1; ++x) { + err += ady; + if (err >= adx) { + err -= adx; + y += sy; + } else + y += base; + LINE_OP(output[x], inverse_db_table[y & 255]); + } + } } -static int residue_decode(vorb *f, Codebook *book, float *target, int offset, int n, int rtype) -{ - int k; - if (rtype == 0) { - int step = n / book->dimensions; - for (k=0; k < step; ++k) - if (!codebook_decode_step(f, book, target+offset+k, n-offset-k, step)) - return FALSE; - } else { - for (k=0; k < n; ) { - if (!codebook_decode(f, book, target+offset, n-k)) - return FALSE; - k += book->dimensions; - offset += book->dimensions; - } - } - return TRUE; +static int residue_decode(vorb* f, Codebook* book, float* target, int offset, + int n, int rtype) { + int k; + if (rtype == 0) { + int step = n / book->dimensions; + for (k = 0; k < step; ++k) + if (!codebook_decode_step(f, book, target + offset + k, + n - offset - k, step)) + return FALSE; + } else { + for (k = 0; k < n;) { + if (!codebook_decode(f, book, target + offset, n - k)) return FALSE; + k += book->dimensions; + offset += book->dimensions; + } + } + return TRUE; } -static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int rn, uint8 *do_not_decode) -{ - int i,j,pass; - Residue *r = f->residue_config + rn; - int rtype = f->residue_types[rn]; - int c = r->classbook; - int classwords = f->codebooks[c].dimensions; - unsigned int actual_size = rtype == 2 ? n*2 : n; - unsigned int limit_r_begin = (r->begin < actual_size ? r->begin : actual_size); - unsigned int limit_r_end = (r->end < actual_size ? r->end : actual_size); - int n_read = limit_r_end - limit_r_begin; - int part_read = n_read / r->part_size; - int temp_alloc_point = temp_alloc_save(f); - #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE - uint8 ***part_classdata = (uint8 ***) temp_block_array(f,f->channels, part_read * sizeof(**part_classdata)); - #else - int **classifications = (int **) temp_block_array(f,f->channels, part_read * sizeof(**classifications)); - #endif +static void decode_residue(vorb* f, float* residue_buffers[], int ch, int n, + int rn, uint8* do_not_decode) { + int i, j, pass; + Residue* r = f->residue_config + rn; + int rtype = f->residue_types[rn]; + int c = r->classbook; + int classwords = f->codebooks[c].dimensions; + unsigned int actual_size = rtype == 2 ? n * 2 : n; + unsigned int limit_r_begin = + (r->begin < actual_size ? r->begin : actual_size); + unsigned int limit_r_end = (r->end < actual_size ? r->end : actual_size); + int n_read = limit_r_end - limit_r_begin; + int part_read = n_read / r->part_size; + int temp_alloc_point = temp_alloc_save(f); +#ifndef STB_VORBIS_DIVIDES_IN_RESIDUE + uint8*** part_classdata = (uint8***)temp_block_array( + f, f->channels, part_read * sizeof(**part_classdata)); +#else + int** classifications = (int**)temp_block_array( + f, f->channels, part_read * sizeof(**classifications)); +#endif - CHECK(f); + CHECK(f); - for (i=0; i < ch; ++i) - if (!do_not_decode[i]) - memset(residue_buffers[i], 0, sizeof(float) * n); + for (i = 0; i < ch; ++i) + if (!do_not_decode[i]) memset(residue_buffers[i], 0, sizeof(float) * n); - if (rtype == 2 && ch != 1) { - for (j=0; j < ch; ++j) - if (!do_not_decode[j]) - break; - if (j == ch) - goto done; + if (rtype == 2 && ch != 1) { + for (j = 0; j < ch; ++j) + if (!do_not_decode[j]) break; + if (j == ch) goto done; - for (pass=0; pass < 8; ++pass) { - int pcount = 0, class_set = 0; - if (ch == 2) { - while (pcount < part_read) { - int z = r->begin + pcount*r->part_size; - int c_inter = (z & 1), p_inter = z>>1; - if (pass == 0) { - Codebook *c = f->codebooks+r->classbook; - int q; - DECODE(q,f,c); - if (q == EOP) goto done; - #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE - part_classdata[0][class_set] = r->classdata[q]; - #else - for (i=classwords-1; i >= 0; --i) { - classifications[0][i+pcount] = q % r->classifications; - q /= r->classifications; - } - #endif - } - for (i=0; i < classwords && pcount < part_read; ++i, ++pcount) { - int z = r->begin + pcount*r->part_size; - #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE - int c = part_classdata[0][class_set][i]; - #else - int c = classifications[0][pcount]; - #endif - int b = r->residue_books[c][pass]; - if (b >= 0) { - Codebook *book = f->codebooks + b; - #ifdef STB_VORBIS_DIVIDES_IN_CODEBOOK - if (!codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r->part_size)) - goto done; - #else - - if (!codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r->part_size)) - goto done; - #endif - } else { - z += r->part_size; - c_inter = z & 1; - p_inter = z >> 1; - } - } - #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE - ++class_set; - #endif + for (pass = 0; pass < 8; ++pass) { + int pcount = 0, class_set = 0; + if (ch == 2) { + while (pcount < part_read) { + int z = r->begin + pcount * r->part_size; + int c_inter = (z & 1), p_inter = z >> 1; + if (pass == 0) { + Codebook* c = f->codebooks + r->classbook; + int q; + DECODE(q, f, c); + if (q == EOP) goto done; +#ifndef STB_VORBIS_DIVIDES_IN_RESIDUE + part_classdata[0][class_set] = r->classdata[q]; +#else + for (i = classwords - 1; i >= 0; --i) { + classifications[0][i + pcount] = + q % r->classifications; + q /= r->classifications; + } +#endif + } + for (i = 0; i < classwords && pcount < part_read; + ++i, ++pcount) { + int z = r->begin + pcount * r->part_size; +#ifndef STB_VORBIS_DIVIDES_IN_RESIDUE + int c = part_classdata[0][class_set][i]; +#else + int c = classifications[0][pcount]; +#endif + int b = r->residue_books[c][pass]; + if (b >= 0) { + Codebook* book = f->codebooks + b; +#ifdef STB_VORBIS_DIVIDES_IN_CODEBOOK + if (!codebook_decode_deinterleave_repeat( + f, book, residue_buffers, ch, &c_inter, + &p_inter, n, r->part_size)) + goto done; +#else + + if (!codebook_decode_deinterleave_repeat( + f, book, residue_buffers, ch, &c_inter, + &p_inter, n, r->part_size)) + goto done; +#endif + } else { + z += r->part_size; + c_inter = z & 1; + p_inter = z >> 1; + } + } +#ifndef STB_VORBIS_DIVIDES_IN_RESIDUE + ++class_set; +#endif + } + } else if (ch > 2) { + while (pcount < part_read) { + int z = r->begin + pcount * r->part_size; + int c_inter = z % ch, p_inter = z / ch; + if (pass == 0) { + Codebook* c = f->codebooks + r->classbook; + int q; + DECODE(q, f, c); + if (q == EOP) goto done; +#ifndef STB_VORBIS_DIVIDES_IN_RESIDUE + part_classdata[0][class_set] = r->classdata[q]; +#else + for (i = classwords - 1; i >= 0; --i) { + classifications[0][i + pcount] = + q % r->classifications; + q /= r->classifications; + } +#endif + } + for (i = 0; i < classwords && pcount < part_read; + ++i, ++pcount) { + int z = r->begin + pcount * r->part_size; +#ifndef STB_VORBIS_DIVIDES_IN_RESIDUE + int c = part_classdata[0][class_set][i]; +#else + int c = classifications[0][pcount]; +#endif + int b = r->residue_books[c][pass]; + if (b >= 0) { + Codebook* book = f->codebooks + b; + if (!codebook_decode_deinterleave_repeat( + f, book, residue_buffers, ch, &c_inter, + &p_inter, n, r->part_size)) + goto done; + } else { + z += r->part_size; + c_inter = z % ch; + p_inter = z / ch; + } + } +#ifndef STB_VORBIS_DIVIDES_IN_RESIDUE + ++class_set; +#endif + } } - } else if (ch > 2) { - while (pcount < part_read) { - int z = r->begin + pcount*r->part_size; - int c_inter = z % ch, p_inter = z/ch; - if (pass == 0) { - Codebook *c = f->codebooks+r->classbook; - int q; - DECODE(q,f,c); - if (q == EOP) goto done; - #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE - part_classdata[0][class_set] = r->classdata[q]; - #else - for (i=classwords-1; i >= 0; --i) { - classifications[0][i+pcount] = q % r->classifications; - q /= r->classifications; - } - #endif - } - for (i=0; i < classwords && pcount < part_read; ++i, ++pcount) { - int z = r->begin + pcount*r->part_size; - #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE - int c = part_classdata[0][class_set][i]; - #else - int c = classifications[0][pcount]; - #endif - int b = r->residue_books[c][pass]; - if (b >= 0) { - Codebook *book = f->codebooks + b; - if (!codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r->part_size)) - goto done; - } else { - z += r->part_size; - c_inter = z % ch; - p_inter = z / ch; - } - } - #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE - ++class_set; - #endif - } - } - } - goto done; - } - CHECK(f); + } + goto done; + } + CHECK(f); - for (pass=0; pass < 8; ++pass) { - int pcount = 0, class_set=0; - while (pcount < part_read) { - if (pass == 0) { - for (j=0; j < ch; ++j) { - if (!do_not_decode[j]) { - Codebook *c = f->codebooks+r->classbook; - int temp; - DECODE(temp,f,c); - if (temp == EOP) goto done; - #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE - part_classdata[j][class_set] = r->classdata[temp]; - #else - for (i=classwords-1; i >= 0; --i) { - classifications[j][i+pcount] = temp % r->classifications; - temp /= r->classifications; - } - #endif - } + for (pass = 0; pass < 8; ++pass) { + int pcount = 0, class_set = 0; + while (pcount < part_read) { + if (pass == 0) { + for (j = 0; j < ch; ++j) { + if (!do_not_decode[j]) { + Codebook* c = f->codebooks + r->classbook; + int temp; + DECODE(temp, f, c); + if (temp == EOP) goto done; +#ifndef STB_VORBIS_DIVIDES_IN_RESIDUE + part_classdata[j][class_set] = r->classdata[temp]; +#else + for (i = classwords - 1; i >= 0; --i) { + classifications[j][i + pcount] = + temp % r->classifications; + temp /= r->classifications; + } +#endif + } + } } - } - for (i=0; i < classwords && pcount < part_read; ++i, ++pcount) { - for (j=0; j < ch; ++j) { - if (!do_not_decode[j]) { - #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE - int c = part_classdata[j][class_set][i]; - #else - int c = classifications[j][pcount]; - #endif - int b = r->residue_books[c][pass]; - if (b >= 0) { - float *target = residue_buffers[j]; - int offset = r->begin + pcount * r->part_size; - int n = r->part_size; - Codebook *book = f->codebooks + b; - if (!residue_decode(f, book, target, offset, n, rtype)) - goto done; - } - } + for (i = 0; i < classwords && pcount < part_read; ++i, ++pcount) { + for (j = 0; j < ch; ++j) { + if (!do_not_decode[j]) { +#ifndef STB_VORBIS_DIVIDES_IN_RESIDUE + int c = part_classdata[j][class_set][i]; +#else + int c = classifications[j][pcount]; +#endif + int b = r->residue_books[c][pass]; + if (b >= 0) { + float* target = residue_buffers[j]; + int offset = r->begin + pcount * r->part_size; + int n = r->part_size; + Codebook* book = f->codebooks + b; + if (!residue_decode(f, book, target, offset, n, + rtype)) + goto done; + } + } + } } - } - #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE - ++class_set; - #endif - } - } - done: - CHECK(f); - #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE - temp_free(f,part_classdata); - #else - temp_free(f,classifications); - #endif - temp_alloc_restore(f,temp_alloc_point); +#ifndef STB_VORBIS_DIVIDES_IN_RESIDUE + ++class_set; +#endif + } + } +done: + CHECK(f); +#ifndef STB_VORBIS_DIVIDES_IN_RESIDUE + temp_free(f, part_classdata); +#else + temp_free(f, classifications); +#endif + temp_alloc_restore(f, temp_alloc_point); } #if 0 @@ -1821,54 +1816,49 @@ void inverse_mdct_slow(float *buffer, int n) } #elif 0 -void inverse_mdct_slow(float *buffer, int n, vorb *f, int blocktype) -{ - float mcos[16384]; - int i,j; - int n2 = n >> 1, nmask = (n << 2) -1; - float *x = (float *) malloc(sizeof(*x) * n2); - memcpy(x, buffer, sizeof(*x) * n2); - for (i=0; i < 4*n; ++i) - mcos[i] = (float) cos(M_PI / 2 * i / n); +void inverse_mdct_slow(float* buffer, int n, vorb* f, int blocktype) { + float mcos[16384]; + int i, j; + int n2 = n >> 1, nmask = (n << 2) - 1; + float* x = (float*)malloc(sizeof(*x) * n2); + memcpy(x, buffer, sizeof(*x) * n2); + for (i = 0; i < 4 * n; ++i) mcos[i] = (float)cos(M_PI / 2 * i / n); - for (i=0; i < n; ++i) { - float acc = 0; - for (j=0; j < n2; ++j) - acc += x[j] * mcos[(2 * i + 1 + n2)*(2*j+1) & nmask]; - buffer[i] = acc; - } - free(x); + for (i = 0; i < n; ++i) { + float acc = 0; + for (j = 0; j < n2; ++j) + acc += x[j] * mcos[(2 * i + 1 + n2) * (2 * j + 1) & nmask]; + buffer[i] = acc; + } + free(x); } #elif 0 -void dct_iv_slow(float *buffer, int n) -{ - float mcos[16384]; - float x[2048]; - int i,j; - int n2 = n >> 1, nmask = (n << 3) - 1; - memcpy(x, buffer, sizeof(*x) * n); - for (i=0; i < 8*n; ++i) - mcos[i] = (float) cos(M_PI / 4 * i / n); - for (i=0; i < n; ++i) { - float acc = 0; - for (j=0; j < n; ++j) - acc += x[j] * mcos[((2 * i + 1)*(2*j+1)) & nmask]; - buffer[i] = acc; - } +void dct_iv_slow(float* buffer, int n) { + float mcos[16384]; + float x[2048]; + int i, j; + int n2 = n >> 1, nmask = (n << 3) - 1; + memcpy(x, buffer, sizeof(*x) * n); + for (i = 0; i < 8 * n; ++i) mcos[i] = (float)cos(M_PI / 4 * i / n); + for (i = 0; i < n; ++i) { + float acc = 0; + for (j = 0; j < n; ++j) + acc += x[j] * mcos[((2 * i + 1) * (2 * j + 1)) & nmask]; + buffer[i] = acc; + } } -void inverse_mdct_slow(float *buffer, int n, vorb *f, int blocktype) -{ - int i, n4 = n >> 2, n2 = n >> 1, n3_4 = n - n4; - float temp[4096]; +void inverse_mdct_slow(float* buffer, int n, vorb* f, int blocktype) { + int i, n4 = n >> 2, n2 = n >> 1, n3_4 = n - n4; + float temp[4096]; - memcpy(temp, buffer, n2 * sizeof(float)); - dct_iv_slow(temp, n2); + memcpy(temp, buffer, n2 * sizeof(float)); + dct_iv_slow(temp, n2); - for (i=0; i < n4 ; ++i) buffer[i] = temp[i+n4]; - for ( ; i < n3_4; ++i) buffer[i] = -temp[n3_4 - i - 1]; - for ( ; i < n ; ++i) buffer[i] = -temp[i - n3_4]; + for (i = 0; i < n4; ++i) buffer[i] = temp[i + n4]; + for (; i < n3_4; ++i) buffer[i] = -temp[n3_4 - i - 1]; + for (; i < n; ++i) buffer[i] = -temp[i - n3_4]; } #endif @@ -1878,492 +1868,493 @@ void inverse_mdct_slow(float *buffer, int n, vorb *f, int blocktype) #if LIBVORBIS_MDCT -typedef struct -{ - int n; - int log2n; +typedef struct { + int n; + int log2n; - float *trig; - int *bitrev; + float* trig; + int* bitrev; - float scale; + float scale; } mdct_lookup; -extern void mdct_init(mdct_lookup *lookup, int n); -extern void mdct_clear(mdct_lookup *l); -extern void mdct_backward(mdct_lookup *init, float *in, float *out); +extern void mdct_init(mdct_lookup* lookup, int n); +extern void mdct_clear(mdct_lookup* l); +extern void mdct_backward(mdct_lookup* init, float* in, float* out); -mdct_lookup M1,M2; +mdct_lookup M1, M2; -void inverse_mdct(float *buffer, int n, vorb *f, int blocktype) -{ - mdct_lookup *M; - if (M1.n == n) M = &M1; - else if (M2.n == n) M = &M2; - else if (M1.n == 0) { mdct_init(&M1, n); M = &M1; } - else { - if (M2.n) __asm int 3; - mdct_init(&M2, n); - M = &M2; - } +void inverse_mdct(float* buffer, int n, vorb* f, int blocktype) { + mdct_lookup* M; + if (M1.n == n) + M = &M1; + else if (M2.n == n) + M = &M2; + else if (M1.n == 0) { + mdct_init(&M1, n); + M = &M1; + } else { + if (M2.n) __asm int 3; + mdct_init(&M2, n); + M = &M2; + } - mdct_backward(M, buffer, buffer); + mdct_backward(M, buffer, buffer); } #endif -static void imdct_step3_iter0_loop(int n, float *e, int i_off, int k_off, float *A) -{ - float *ee0 = e + i_off; - float *ee2 = ee0 + k_off; - int i; +static void imdct_step3_iter0_loop(int n, float* e, int i_off, int k_off, + float* A) { + float* ee0 = e + i_off; + float* ee2 = ee0 + k_off; + int i; - assert((n & 3) == 0); - for (i=(n>>2); i > 0; --i) { - float k00_20, k01_21; - k00_20 = ee0[ 0] - ee2[ 0]; - k01_21 = ee0[-1] - ee2[-1]; - ee0[ 0] += ee2[ 0]; - ee0[-1] += ee2[-1]; - ee2[ 0] = k00_20 * A[0] - k01_21 * A[1]; - ee2[-1] = k01_21 * A[0] + k00_20 * A[1]; - A += 8; + assert((n & 3) == 0); + for (i = (n >> 2); i > 0; --i) { + float k00_20, k01_21; + k00_20 = ee0[0] - ee2[0]; + k01_21 = ee0[-1] - ee2[-1]; + ee0[0] += ee2[0]; + ee0[-1] += ee2[-1]; + ee2[0] = k00_20 * A[0] - k01_21 * A[1]; + ee2[-1] = k01_21 * A[0] + k00_20 * A[1]; + A += 8; - k00_20 = ee0[-2] - ee2[-2]; - k01_21 = ee0[-3] - ee2[-3]; - ee0[-2] += ee2[-2]; - ee0[-3] += ee2[-3]; - ee2[-2] = k00_20 * A[0] - k01_21 * A[1]; - ee2[-3] = k01_21 * A[0] + k00_20 * A[1]; - A += 8; + k00_20 = ee0[-2] - ee2[-2]; + k01_21 = ee0[-3] - ee2[-3]; + ee0[-2] += ee2[-2]; + ee0[-3] += ee2[-3]; + ee2[-2] = k00_20 * A[0] - k01_21 * A[1]; + ee2[-3] = k01_21 * A[0] + k00_20 * A[1]; + A += 8; - k00_20 = ee0[-4] - ee2[-4]; - k01_21 = ee0[-5] - ee2[-5]; - ee0[-4] += ee2[-4]; - ee0[-5] += ee2[-5]; - ee2[-4] = k00_20 * A[0] - k01_21 * A[1]; - ee2[-5] = k01_21 * A[0] + k00_20 * A[1]; - A += 8; + k00_20 = ee0[-4] - ee2[-4]; + k01_21 = ee0[-5] - ee2[-5]; + ee0[-4] += ee2[-4]; + ee0[-5] += ee2[-5]; + ee2[-4] = k00_20 * A[0] - k01_21 * A[1]; + ee2[-5] = k01_21 * A[0] + k00_20 * A[1]; + A += 8; - k00_20 = ee0[-6] - ee2[-6]; - k01_21 = ee0[-7] - ee2[-7]; - ee0[-6] += ee2[-6]; - ee0[-7] += ee2[-7]; - ee2[-6] = k00_20 * A[0] - k01_21 * A[1]; - ee2[-7] = k01_21 * A[0] + k00_20 * A[1]; - A += 8; - ee0 -= 8; - ee2 -= 8; - } + k00_20 = ee0[-6] - ee2[-6]; + k01_21 = ee0[-7] - ee2[-7]; + ee0[-6] += ee2[-6]; + ee0[-7] += ee2[-7]; + ee2[-6] = k00_20 * A[0] - k01_21 * A[1]; + ee2[-7] = k01_21 * A[0] + k00_20 * A[1]; + A += 8; + ee0 -= 8; + ee2 -= 8; + } } -static void imdct_step3_inner_r_loop(int lim, float *e, int d0, int k_off, float *A, int k1) -{ - int i; - float k00_20, k01_21; +static void imdct_step3_inner_r_loop(int lim, float* e, int d0, int k_off, + float* A, int k1) { + int i; + float k00_20, k01_21; - float *e0 = e + d0; - float *e2 = e0 + k_off; + float* e0 = e + d0; + float* e2 = e0 + k_off; - for (i=lim >> 2; i > 0; --i) { - k00_20 = e0[-0] - e2[-0]; - k01_21 = e0[-1] - e2[-1]; - e0[-0] += e2[-0]; - e0[-1] += e2[-1]; - e2[-0] = (k00_20)*A[0] - (k01_21) * A[1]; - e2[-1] = (k01_21)*A[0] + (k00_20) * A[1]; + for (i = lim >> 2; i > 0; --i) { + k00_20 = e0[-0] - e2[-0]; + k01_21 = e0[-1] - e2[-1]; + e0[-0] += e2[-0]; + e0[-1] += e2[-1]; + e2[-0] = (k00_20)*A[0] - (k01_21)*A[1]; + e2[-1] = (k01_21)*A[0] + (k00_20)*A[1]; - A += k1; + A += k1; - k00_20 = e0[-2] - e2[-2]; - k01_21 = e0[-3] - e2[-3]; - e0[-2] += e2[-2]; - e0[-3] += e2[-3]; - e2[-2] = (k00_20)*A[0] - (k01_21) * A[1]; - e2[-3] = (k01_21)*A[0] + (k00_20) * A[1]; + k00_20 = e0[-2] - e2[-2]; + k01_21 = e0[-3] - e2[-3]; + e0[-2] += e2[-2]; + e0[-3] += e2[-3]; + e2[-2] = (k00_20)*A[0] - (k01_21)*A[1]; + e2[-3] = (k01_21)*A[0] + (k00_20)*A[1]; - A += k1; + A += k1; - k00_20 = e0[-4] - e2[-4]; - k01_21 = e0[-5] - e2[-5]; - e0[-4] += e2[-4]; - e0[-5] += e2[-5]; - e2[-4] = (k00_20)*A[0] - (k01_21) * A[1]; - e2[-5] = (k01_21)*A[0] + (k00_20) * A[1]; + k00_20 = e0[-4] - e2[-4]; + k01_21 = e0[-5] - e2[-5]; + e0[-4] += e2[-4]; + e0[-5] += e2[-5]; + e2[-4] = (k00_20)*A[0] - (k01_21)*A[1]; + e2[-5] = (k01_21)*A[0] + (k00_20)*A[1]; - A += k1; + A += k1; - k00_20 = e0[-6] - e2[-6]; - k01_21 = e0[-7] - e2[-7]; - e0[-6] += e2[-6]; - e0[-7] += e2[-7]; - e2[-6] = (k00_20)*A[0] - (k01_21) * A[1]; - e2[-7] = (k01_21)*A[0] + (k00_20) * A[1]; + k00_20 = e0[-6] - e2[-6]; + k01_21 = e0[-7] - e2[-7]; + e0[-6] += e2[-6]; + e0[-7] += e2[-7]; + e2[-6] = (k00_20)*A[0] - (k01_21)*A[1]; + e2[-7] = (k01_21)*A[0] + (k00_20)*A[1]; - e0 -= 8; - e2 -= 8; + e0 -= 8; + e2 -= 8; - A += k1; - } + A += k1; + } } -static void imdct_step3_inner_s_loop(int n, float *e, int i_off, int k_off, float *A, int a_off, int k0) -{ - int i; - float A0 = A[0]; - float A1 = A[0+1]; - float A2 = A[0+a_off]; - float A3 = A[0+a_off+1]; - float A4 = A[0+a_off*2+0]; - float A5 = A[0+a_off*2+1]; - float A6 = A[0+a_off*3+0]; - float A7 = A[0+a_off*3+1]; +static void imdct_step3_inner_s_loop(int n, float* e, int i_off, int k_off, + float* A, int a_off, int k0) { + int i; + float A0 = A[0]; + float A1 = A[0 + 1]; + float A2 = A[0 + a_off]; + float A3 = A[0 + a_off + 1]; + float A4 = A[0 + a_off * 2 + 0]; + float A5 = A[0 + a_off * 2 + 1]; + float A6 = A[0 + a_off * 3 + 0]; + float A7 = A[0 + a_off * 3 + 1]; - float k00,k11; + float k00, k11; - float *ee0 = e +i_off; - float *ee2 = ee0+k_off; + float* ee0 = e + i_off; + float* ee2 = ee0 + k_off; - for (i=n; i > 0; --i) { - k00 = ee0[ 0] - ee2[ 0]; - k11 = ee0[-1] - ee2[-1]; - ee0[ 0] = ee0[ 0] + ee2[ 0]; - ee0[-1] = ee0[-1] + ee2[-1]; - ee2[ 0] = (k00) * A0 - (k11) * A1; - ee2[-1] = (k11) * A0 + (k00) * A1; + for (i = n; i > 0; --i) { + k00 = ee0[0] - ee2[0]; + k11 = ee0[-1] - ee2[-1]; + ee0[0] = ee0[0] + ee2[0]; + ee0[-1] = ee0[-1] + ee2[-1]; + ee2[0] = (k00)*A0 - (k11)*A1; + ee2[-1] = (k11)*A0 + (k00)*A1; - k00 = ee0[-2] - ee2[-2]; - k11 = ee0[-3] - ee2[-3]; - ee0[-2] = ee0[-2] + ee2[-2]; - ee0[-3] = ee0[-3] + ee2[-3]; - ee2[-2] = (k00) * A2 - (k11) * A3; - ee2[-3] = (k11) * A2 + (k00) * A3; + k00 = ee0[-2] - ee2[-2]; + k11 = ee0[-3] - ee2[-3]; + ee0[-2] = ee0[-2] + ee2[-2]; + ee0[-3] = ee0[-3] + ee2[-3]; + ee2[-2] = (k00)*A2 - (k11)*A3; + ee2[-3] = (k11)*A2 + (k00)*A3; - k00 = ee0[-4] - ee2[-4]; - k11 = ee0[-5] - ee2[-5]; - ee0[-4] = ee0[-4] + ee2[-4]; - ee0[-5] = ee0[-5] + ee2[-5]; - ee2[-4] = (k00) * A4 - (k11) * A5; - ee2[-5] = (k11) * A4 + (k00) * A5; + k00 = ee0[-4] - ee2[-4]; + k11 = ee0[-5] - ee2[-5]; + ee0[-4] = ee0[-4] + ee2[-4]; + ee0[-5] = ee0[-5] + ee2[-5]; + ee2[-4] = (k00)*A4 - (k11)*A5; + ee2[-5] = (k11)*A4 + (k00)*A5; - k00 = ee0[-6] - ee2[-6]; - k11 = ee0[-7] - ee2[-7]; - ee0[-6] = ee0[-6] + ee2[-6]; - ee0[-7] = ee0[-7] + ee2[-7]; - ee2[-6] = (k00) * A6 - (k11) * A7; - ee2[-7] = (k11) * A6 + (k00) * A7; + k00 = ee0[-6] - ee2[-6]; + k11 = ee0[-7] - ee2[-7]; + ee0[-6] = ee0[-6] + ee2[-6]; + ee0[-7] = ee0[-7] + ee2[-7]; + ee2[-6] = (k00)*A6 - (k11)*A7; + ee2[-7] = (k11)*A6 + (k00)*A7; - ee0 -= k0; - ee2 -= k0; - } + ee0 -= k0; + ee2 -= k0; + } } -static __forceinline void iter_54(float *z) -{ - float k00,k11,k22,k33; - float y0,y1,y2,y3; +static __forceinline void iter_54(float* z) { + float k00, k11, k22, k33; + float y0, y1, y2, y3; - k00 = z[ 0] - z[-4]; - y0 = z[ 0] + z[-4]; - y2 = z[-2] + z[-6]; - k22 = z[-2] - z[-6]; + k00 = z[0] - z[-4]; + y0 = z[0] + z[-4]; + y2 = z[-2] + z[-6]; + k22 = z[-2] - z[-6]; - z[-0] = y0 + y2; - z[-2] = y0 - y2; + z[-0] = y0 + y2; + z[-2] = y0 - y2; - k33 = z[-3] - z[-7]; + k33 = z[-3] - z[-7]; - z[-4] = k00 + k33; - z[-6] = k00 - k33; + z[-4] = k00 + k33; + z[-6] = k00 - k33; - k11 = z[-1] - z[-5]; - y1 = z[-1] + z[-5]; - y3 = z[-3] + z[-7]; + k11 = z[-1] - z[-5]; + y1 = z[-1] + z[-5]; + y3 = z[-3] + z[-7]; - z[-1] = y1 + y3; - z[-3] = y1 - y3; - z[-5] = k11 - k22; - z[-7] = k11 + k22; + z[-1] = y1 + y3; + z[-3] = y1 - y3; + z[-5] = k11 - k22; + z[-7] = k11 + k22; } -static void imdct_step3_inner_s_loop_ld654(int n, float *e, int i_off, float *A, int base_n) -{ - int a_off = base_n >> 3; - float A2 = A[0+a_off]; - float *z = e + i_off; - float *base = z - 16 * n; +static void imdct_step3_inner_s_loop_ld654(int n, float* e, int i_off, float* A, + int base_n) { + int a_off = base_n >> 3; + float A2 = A[0 + a_off]; + float* z = e + i_off; + float* base = z - 16 * n; - while (z > base) { - float k00,k11; - float l00,l11; + while (z > base) { + float k00, k11; + float l00, l11; - k00 = z[-0] - z[ -8]; - k11 = z[-1] - z[ -9]; - l00 = z[-2] - z[-10]; - l11 = z[-3] - z[-11]; - z[ -0] = z[-0] + z[ -8]; - z[ -1] = z[-1] + z[ -9]; - z[ -2] = z[-2] + z[-10]; - z[ -3] = z[-3] + z[-11]; - z[ -8] = k00; - z[ -9] = k11; - z[-10] = (l00+l11) * A2; - z[-11] = (l11-l00) * A2; + k00 = z[-0] - z[-8]; + k11 = z[-1] - z[-9]; + l00 = z[-2] - z[-10]; + l11 = z[-3] - z[-11]; + z[-0] = z[-0] + z[-8]; + z[-1] = z[-1] + z[-9]; + z[-2] = z[-2] + z[-10]; + z[-3] = z[-3] + z[-11]; + z[-8] = k00; + z[-9] = k11; + z[-10] = (l00 + l11) * A2; + z[-11] = (l11 - l00) * A2; - k00 = z[ -4] - z[-12]; - k11 = z[ -5] - z[-13]; - l00 = z[ -6] - z[-14]; - l11 = z[ -7] - z[-15]; - z[ -4] = z[ -4] + z[-12]; - z[ -5] = z[ -5] + z[-13]; - z[ -6] = z[ -6] + z[-14]; - z[ -7] = z[ -7] + z[-15]; - z[-12] = k11; - z[-13] = -k00; - z[-14] = (l11-l00) * A2; - z[-15] = (l00+l11) * -A2; + k00 = z[-4] - z[-12]; + k11 = z[-5] - z[-13]; + l00 = z[-6] - z[-14]; + l11 = z[-7] - z[-15]; + z[-4] = z[-4] + z[-12]; + z[-5] = z[-5] + z[-13]; + z[-6] = z[-6] + z[-14]; + z[-7] = z[-7] + z[-15]; + z[-12] = k11; + z[-13] = -k00; + z[-14] = (l11 - l00) * A2; + z[-15] = (l00 + l11) * -A2; - iter_54(z); - iter_54(z-8); - z -= 16; - } + iter_54(z); + iter_54(z - 8); + z -= 16; + } } -static void inverse_mdct(float *buffer, int n, vorb *f, int blocktype) -{ - int n2 = n >> 1, n4 = n >> 2, n8 = n >> 3, l; - int ld; - - int save_point = temp_alloc_save(f); - float *buf2 = (float *) temp_alloc(f, n2 * sizeof(*buf2)); - float *u=NULL,*v=NULL; - - float *A = f->A[blocktype]; +static void inverse_mdct(float* buffer, int n, vorb* f, int blocktype) { + int n2 = n >> 1, n4 = n >> 2, n8 = n >> 3, l; + int ld; - { - float *d,*e, *AA, *e_stop; - d = &buf2[n2-2]; - AA = A; - e = &buffer[0]; - e_stop = &buffer[n2]; - while (e != e_stop) { - d[1] = (e[0] * AA[0] - e[2]*AA[1]); - d[0] = (e[0] * AA[1] + e[2]*AA[0]); - d -= 2; - AA += 2; - e += 4; - } + int save_point = temp_alloc_save(f); + float* buf2 = (float*)temp_alloc(f, n2 * sizeof(*buf2)); + float *u = NULL, *v = NULL; - e = &buffer[n2-3]; - while (d >= buf2) { - d[1] = (-e[2] * AA[0] - -e[0]*AA[1]); - d[0] = (-e[2] * AA[1] + -e[0]*AA[0]); - d -= 2; - AA += 2; - e -= 4; - } - } + float* A = f->A[blocktype]; - u = buffer; - v = buf2; + { + float *d, *e, *AA, *e_stop; + d = &buf2[n2 - 2]; + AA = A; + e = &buffer[0]; + e_stop = &buffer[n2]; + while (e != e_stop) { + d[1] = (e[0] * AA[0] - e[2] * AA[1]); + d[0] = (e[0] * AA[1] + e[2] * AA[0]); + d -= 2; + AA += 2; + e += 4; + } - { - float *AA = &A[n2-8]; - float *d0,*d1, *e0, *e1; + e = &buffer[n2 - 3]; + while (d >= buf2) { + d[1] = (-e[2] * AA[0] - -e[0] * AA[1]); + d[0] = (-e[2] * AA[1] + -e[0] * AA[0]); + d -= 2; + AA += 2; + e -= 4; + } + } - e0 = &v[n4]; - e1 = &v[0]; + u = buffer; + v = buf2; - d0 = &u[n4]; - d1 = &u[0]; + { + float* AA = &A[n2 - 8]; + float *d0, *d1, *e0, *e1; - while (AA >= A) { - float v40_20, v41_21; + e0 = &v[n4]; + e1 = &v[0]; - v41_21 = e0[1] - e1[1]; - v40_20 = e0[0] - e1[0]; - d0[1] = e0[1] + e1[1]; - d0[0] = e0[0] + e1[0]; - d1[1] = v41_21*AA[4] - v40_20*AA[5]; - d1[0] = v40_20*AA[4] + v41_21*AA[5]; + d0 = &u[n4]; + d1 = &u[0]; - v41_21 = e0[3] - e1[3]; - v40_20 = e0[2] - e1[2]; - d0[3] = e0[3] + e1[3]; - d0[2] = e0[2] + e1[2]; - d1[3] = v41_21*AA[0] - v40_20*AA[1]; - d1[2] = v40_20*AA[0] + v41_21*AA[1]; + while (AA >= A) { + float v40_20, v41_21; - AA -= 8; + v41_21 = e0[1] - e1[1]; + v40_20 = e0[0] - e1[0]; + d0[1] = e0[1] + e1[1]; + d0[0] = e0[0] + e1[0]; + d1[1] = v41_21 * AA[4] - v40_20 * AA[5]; + d1[0] = v40_20 * AA[4] + v41_21 * AA[5]; - d0 += 4; - d1 += 4; - e0 += 4; - e1 += 4; - } - } + v41_21 = e0[3] - e1[3]; + v40_20 = e0[2] - e1[2]; + d0[3] = e0[3] + e1[3]; + d0[2] = e0[2] + e1[2]; + d1[3] = v41_21 * AA[0] - v40_20 * AA[1]; + d1[2] = v40_20 * AA[0] + v41_21 * AA[1]; - ld = ilog(n) - 1; + AA -= 8; - imdct_step3_iter0_loop(n >> 4, u, n2-1-n4*0, -(n >> 3), A); - imdct_step3_iter0_loop(n >> 4, u, n2-1-n4*1, -(n >> 3), A); + d0 += 4; + d1 += 4; + e0 += 4; + e1 += 4; + } + } - imdct_step3_inner_r_loop(n >> 5, u, n2-1 - n8*0, -(n >> 4), A, 16); - imdct_step3_inner_r_loop(n >> 5, u, n2-1 - n8*1, -(n >> 4), A, 16); - imdct_step3_inner_r_loop(n >> 5, u, n2-1 - n8*2, -(n >> 4), A, 16); - imdct_step3_inner_r_loop(n >> 5, u, n2-1 - n8*3, -(n >> 4), A, 16); + ld = ilog(n) - 1; - l=2; - for (; l < (ld-3)>>1; ++l) { - int k0 = n >> (l+2), k0_2 = k0>>1; - int lim = 1 << (l+1); - int i; - for (i=0; i < lim; ++i) - imdct_step3_inner_r_loop(n >> (l+4), u, n2-1 - k0*i, -k0_2, A, 1 << (l+3)); - } + imdct_step3_iter0_loop(n >> 4, u, n2 - 1 - n4 * 0, -(n >> 3), A); + imdct_step3_iter0_loop(n >> 4, u, n2 - 1 - n4 * 1, -(n >> 3), A); - for (; l < ld-6; ++l) { - int k0 = n >> (l+2), k1 = 1 << (l+3), k0_2 = k0>>1; - int rlim = n >> (l+6), r; - int lim = 1 << (l+1); - int i_off; - float *A0 = A; - i_off = n2-1; - for (r=rlim; r > 0; --r) { - imdct_step3_inner_s_loop(lim, u, i_off, -k0_2, A0, k1, k0); - A0 += k1*4; - i_off -= 8; - } - } + imdct_step3_inner_r_loop(n >> 5, u, n2 - 1 - n8 * 0, -(n >> 4), A, 16); + imdct_step3_inner_r_loop(n >> 5, u, n2 - 1 - n8 * 1, -(n >> 4), A, 16); + imdct_step3_inner_r_loop(n >> 5, u, n2 - 1 - n8 * 2, -(n >> 4), A, 16); + imdct_step3_inner_r_loop(n >> 5, u, n2 - 1 - n8 * 3, -(n >> 4), A, 16); - imdct_step3_inner_s_loop_ld654(n >> 5, u, n2-1, A, n); + l = 2; + for (; l < (ld - 3) >> 1; ++l) { + int k0 = n >> (l + 2), k0_2 = k0 >> 1; + int lim = 1 << (l + 1); + int i; + for (i = 0; i < lim; ++i) + imdct_step3_inner_r_loop(n >> (l + 4), u, n2 - 1 - k0 * i, -k0_2, A, + 1 << (l + 3)); + } - { - uint16 *bitrev = f->bit_reverse[blocktype]; - - float *d0 = &v[n4-4]; - float *d1 = &v[n2-4]; - while (d0 >= v) { - int k4; + for (; l < ld - 6; ++l) { + int k0 = n >> (l + 2), k1 = 1 << (l + 3), k0_2 = k0 >> 1; + int rlim = n >> (l + 6), r; + int lim = 1 << (l + 1); + int i_off; + float* A0 = A; + i_off = n2 - 1; + for (r = rlim; r > 0; --r) { + imdct_step3_inner_s_loop(lim, u, i_off, -k0_2, A0, k1, k0); + A0 += k1 * 4; + i_off -= 8; + } + } - k4 = bitrev[0]; - d1[3] = u[k4+0]; - d1[2] = u[k4+1]; - d0[3] = u[k4+2]; - d0[2] = u[k4+3]; + imdct_step3_inner_s_loop_ld654(n >> 5, u, n2 - 1, A, n); - k4 = bitrev[1]; - d1[1] = u[k4+0]; - d1[0] = u[k4+1]; - d0[1] = u[k4+2]; - d0[0] = u[k4+3]; + { + uint16* bitrev = f->bit_reverse[blocktype]; - d0 -= 4; - d1 -= 4; - bitrev += 2; - } - } - - assert(v == buf2); + float* d0 = &v[n4 - 4]; + float* d1 = &v[n2 - 4]; + while (d0 >= v) { + int k4; - { - float *C = f->C[blocktype]; - float *d, *e; + k4 = bitrev[0]; + d1[3] = u[k4 + 0]; + d1[2] = u[k4 + 1]; + d0[3] = u[k4 + 2]; + d0[2] = u[k4 + 3]; - d = v; - e = v + n2 - 4; + k4 = bitrev[1]; + d1[1] = u[k4 + 0]; + d1[0] = u[k4 + 1]; + d0[1] = u[k4 + 2]; + d0[0] = u[k4 + 3]; - while (d < e) { - float a02,a11,b0,b1,b2,b3; + d0 -= 4; + d1 -= 4; + bitrev += 2; + } + } - a02 = d[0] - e[2]; - a11 = d[1] + e[3]; + assert(v == buf2); - b0 = C[1]*a02 + C[0]*a11; - b1 = C[1]*a11 - C[0]*a02; + { + float* C = f->C[blocktype]; + float *d, *e; - b2 = d[0] + e[ 2]; - b3 = d[1] - e[ 3]; + d = v; + e = v + n2 - 4; - d[0] = b2 + b0; - d[1] = b3 + b1; - e[2] = b2 - b0; - e[3] = b1 - b3; + while (d < e) { + float a02, a11, b0, b1, b2, b3; - a02 = d[2] - e[0]; - a11 = d[3] + e[1]; + a02 = d[0] - e[2]; + a11 = d[1] + e[3]; - b0 = C[3]*a02 + C[2]*a11; - b1 = C[3]*a11 - C[2]*a02; + b0 = C[1] * a02 + C[0] * a11; + b1 = C[1] * a11 - C[0] * a02; - b2 = d[2] + e[ 0]; - b3 = d[3] - e[ 1]; + b2 = d[0] + e[2]; + b3 = d[1] - e[3]; - d[2] = b2 + b0; - d[3] = b3 + b1; - e[0] = b2 - b0; - e[1] = b1 - b3; + d[0] = b2 + b0; + d[1] = b3 + b1; + e[2] = b2 - b0; + e[3] = b1 - b3; - C += 4; - d += 4; - e -= 4; - } - } + a02 = d[2] - e[0]; + a11 = d[3] + e[1]; - { - float *d0,*d1,*d2,*d3; + b0 = C[3] * a02 + C[2] * a11; + b1 = C[3] * a11 - C[2] * a02; - float *B = f->B[blocktype] + n2 - 8; - float *e = buf2 + n2 - 8; - d0 = &buffer[0]; - d1 = &buffer[n2-4]; - d2 = &buffer[n2]; - d3 = &buffer[n-4]; - while (e >= v) { - float p0,p1,p2,p3; + b2 = d[2] + e[0]; + b3 = d[3] - e[1]; - p3 = e[6]*B[7] - e[7]*B[6]; - p2 = -e[6]*B[6] - e[7]*B[7]; + d[2] = b2 + b0; + d[3] = b3 + b1; + e[0] = b2 - b0; + e[1] = b1 - b3; - d0[0] = p3; - d1[3] = - p3; - d2[0] = p2; - d3[3] = p2; + C += 4; + d += 4; + e -= 4; + } + } - p1 = e[4]*B[5] - e[5]*B[4]; - p0 = -e[4]*B[4] - e[5]*B[5]; + { + float *d0, *d1, *d2, *d3; - d0[1] = p1; - d1[2] = - p1; - d2[1] = p0; - d3[2] = p0; + float* B = f->B[blocktype] + n2 - 8; + float* e = buf2 + n2 - 8; + d0 = &buffer[0]; + d1 = &buffer[n2 - 4]; + d2 = &buffer[n2]; + d3 = &buffer[n - 4]; + while (e >= v) { + float p0, p1, p2, p3; - p3 = e[2]*B[3] - e[3]*B[2]; - p2 = -e[2]*B[2] - e[3]*B[3]; + p3 = e[6] * B[7] - e[7] * B[6]; + p2 = -e[6] * B[6] - e[7] * B[7]; - d0[2] = p3; - d1[1] = - p3; - d2[2] = p2; - d3[1] = p2; + d0[0] = p3; + d1[3] = -p3; + d2[0] = p2; + d3[3] = p2; - p1 = e[0]*B[1] - e[1]*B[0]; - p0 = -e[0]*B[0] - e[1]*B[1]; + p1 = e[4] * B[5] - e[5] * B[4]; + p0 = -e[4] * B[4] - e[5] * B[5]; - d0[3] = p1; - d1[0] = - p1; - d2[3] = p0; - d3[0] = p0; + d0[1] = p1; + d1[2] = -p1; + d2[1] = p0; + d3[2] = p0; - B -= 8; - e -= 8; - d0 += 4; - d2 += 4; - d1 -= 4; - d3 -= 4; - } - } + p3 = e[2] * B[3] - e[3] * B[2]; + p2 = -e[2] * B[2] - e[3] * B[3]; - temp_free(f,buf2); - temp_alloc_restore(f,save_point); + d0[2] = p3; + d1[1] = -p3; + d2[2] = p2; + d3[1] = p2; + + p1 = e[0] * B[1] - e[1] * B[0]; + p0 = -e[0] * B[0] - e[1] * B[1]; + + d0[3] = p1; + d1[0] = -p1; + d2[3] = p0; + d3[0] = p0; + + B -= 8; + e -= 8; + d0 += 4; + d2 += 4; + d1 -= 4; + d3 -= 4; + } + } + + temp_free(f, buf2); + temp_alloc_restore(f, save_point); } #if 0 @@ -2474,12 +2465,11 @@ void inverse_mdct_naive(float *buffer, int n) } #endif -static float *get_window(vorb *f, int len) -{ - len <<= 1; - if (len == f->blocksize_0) return f->window[0]; - if (len == f->blocksize_1) return f->window[1]; - return NULL; +static float* get_window(vorb* f, int len) { + len <<= 1; + if (len == f->blocksize_0) return f->window[0]; + if (len == f->blocksize_1) return f->window[1]; + return NULL; } #ifndef STB_VORBIS_NO_DEFER_FLOOR @@ -2487,2217 +2477,2224 @@ typedef int16 YTYPE; #else typedef int YTYPE; #endif -static int do_floor(vorb *f, Mapping *map, int i, int n, float *target, YTYPE *finalY, uint8 *step2_flag) -{ - int n2 = n >> 1; - int s = map->chan[i].mux, floor; - floor = map->submap_floor[s]; - if (f->floor_types[floor] == 0) { - return error(f, VORBIS_invalid_stream); - } else { - Floor1 *g = &f->floor_config[floor].floor1; - int j,q; - int lx = 0, ly = finalY[0] * g->floor1_multiplier; - for (q=1; q < g->values; ++q) { - j = g->sorted_order[q]; - #ifndef STB_VORBIS_NO_DEFER_FLOOR - STBV_NOTUSED(step2_flag); - if (finalY[j] >= 0) - #else - if (step2_flag[j]) - #endif - { - int hy = finalY[j] * g->floor1_multiplier; - int hx = g->Xlist[j]; - if (lx != hx) - draw_line(target, lx,ly, hx,hy, n2); +static int do_floor(vorb* f, Mapping* map, int i, int n, float* target, + YTYPE* finalY, uint8* step2_flag) { + int n2 = n >> 1; + int s = map->chan[i].mux, floor; + floor = map->submap_floor[s]; + if (f->floor_types[floor] == 0) { + return error(f, VORBIS_invalid_stream); + } else { + Floor1* g = &f->floor_config[floor].floor1; + int j, q; + int lx = 0, ly = finalY[0] * g->floor1_multiplier; + for (q = 1; q < g->values; ++q) { + j = g->sorted_order[q]; +#ifndef STB_VORBIS_NO_DEFER_FLOOR + STBV_NOTUSED(step2_flag); + if (finalY[j] >= 0) +#else + if (step2_flag[j]) +#endif + { + int hy = finalY[j] * g->floor1_multiplier; + int hx = g->Xlist[j]; + if (lx != hx) draw_line(target, lx, ly, hx, hy, n2); + CHECK(f); + lx = hx, ly = hy; + } + } + if (lx < n2) { + for (j = lx; j < n2; ++j) LINE_OP(target[j], inverse_db_table[ly]); CHECK(f); - lx = hx, ly = hy; - } - } - if (lx < n2) { - - for (j=lx; j < n2; ++j) - LINE_OP(target[j], inverse_db_table[ly]); - CHECK(f); - } - } - return TRUE; + } + } + return TRUE; } -static int vorbis_decode_initial(vorb *f, int *p_left_start, int *p_left_end, int *p_right_start, int *p_right_end, int *mode) -{ - Mode *m; - int i, n, prev, next, window_center; - f->channel_buffer_start = f->channel_buffer_end = 0; +static int vorbis_decode_initial(vorb* f, int* p_left_start, int* p_left_end, + int* p_right_start, int* p_right_end, + int* mode) { + Mode* m; + int i, n, prev, next, window_center; + f->channel_buffer_start = f->channel_buffer_end = 0; - retry: - if (f->eof) return FALSE; - if (!maybe_start_packet(f)) - return FALSE; - - if (get_bits(f,1) != 0) { - if (IS_PUSH_MODE(f)) - return error(f,VORBIS_bad_packet_type); - while (EOP != get8_packet(f)); - goto retry; - } +retry: + if (f->eof) return FALSE; + if (!maybe_start_packet(f)) return FALSE; - if (f->alloc.alloc_buffer) - assert(f->alloc.alloc_buffer_length_in_bytes == f->temp_offset); + if (get_bits(f, 1) != 0) { + if (IS_PUSH_MODE(f)) return error(f, VORBIS_bad_packet_type); + while (EOP != get8_packet(f)); + goto retry; + } - i = get_bits(f, ilog(f->mode_count-1)); - if (i == EOP) return FALSE; - if (i >= f->mode_count) return FALSE; - *mode = i; - m = f->mode_config + i; - if (m->blockflag) { - n = f->blocksize_1; - prev = get_bits(f,1); - next = get_bits(f,1); - } else { - prev = next = 0; - n = f->blocksize_0; - } + if (f->alloc.alloc_buffer) + assert(f->alloc.alloc_buffer_length_in_bytes == f->temp_offset); - window_center = n >> 1; - if (m->blockflag && !prev) { - *p_left_start = (n - f->blocksize_0) >> 2; - *p_left_end = (n + f->blocksize_0) >> 2; - } else { - *p_left_start = 0; - *p_left_end = window_center; - } - if (m->blockflag && !next) { - *p_right_start = (n*3 - f->blocksize_0) >> 2; - *p_right_end = (n*3 + f->blocksize_0) >> 2; - } else { - *p_right_start = window_center; - *p_right_end = n; - } + i = get_bits(f, ilog(f->mode_count - 1)); + if (i == EOP) return FALSE; + if (i >= f->mode_count) return FALSE; + *mode = i; + m = f->mode_config + i; + if (m->blockflag) { + n = f->blocksize_1; + prev = get_bits(f, 1); + next = get_bits(f, 1); + } else { + prev = next = 0; + n = f->blocksize_0; + } - return TRUE; + window_center = n >> 1; + if (m->blockflag && !prev) { + *p_left_start = (n - f->blocksize_0) >> 2; + *p_left_end = (n + f->blocksize_0) >> 2; + } else { + *p_left_start = 0; + *p_left_end = window_center; + } + if (m->blockflag && !next) { + *p_right_start = (n * 3 - f->blocksize_0) >> 2; + *p_right_end = (n * 3 + f->blocksize_0) >> 2; + } else { + *p_right_start = window_center; + *p_right_end = n; + } + + return TRUE; } -static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start, int left_end, int right_start, int right_end, int *p_left) -{ - Mapping *map; - int i,j,k,n,n2; - int zero_channel[256]; - int really_zero_channel[256]; +static int vorbis_decode_packet_rest(vorb* f, int* len, Mode* m, int left_start, + int left_end, int right_start, + int right_end, int* p_left) { + Mapping* map; + int i, j, k, n, n2; + int zero_channel[256]; + int really_zero_channel[256]; - STBV_NOTUSED(left_end); - n = f->blocksize[m->blockflag]; - map = &f->mapping[m->mapping]; + STBV_NOTUSED(left_end); + n = f->blocksize[m->blockflag]; + map = &f->mapping[m->mapping]; - n2 = n >> 1; + n2 = n >> 1; - CHECK(f); + CHECK(f); - for (i=0; i < f->channels; ++i) { - int s = map->chan[i].mux, floor; - zero_channel[i] = FALSE; - floor = map->submap_floor[s]; - if (f->floor_types[floor] == 0) { - return error(f, VORBIS_invalid_stream); - } else { - Floor1 *g = &f->floor_config[floor].floor1; - if (get_bits(f, 1)) { - short *finalY; - uint8 step2_flag[256]; - static int range_list[4] = { 256, 128, 86, 64 }; - int range = range_list[g->floor1_multiplier-1]; - int offset = 2; - finalY = f->finalY[i]; - finalY[0] = get_bits(f, ilog(range)-1); - finalY[1] = get_bits(f, ilog(range)-1); - for (j=0; j < g->partitions; ++j) { - int pclass = g->partition_class_list[j]; - int cdim = g->class_dimensions[pclass]; - int cbits = g->class_subclasses[pclass]; - int csub = (1 << cbits)-1; - int cval = 0; - if (cbits) { - Codebook *c = f->codebooks + g->class_masterbooks[pclass]; - DECODE(cval,f,c); - } - for (k=0; k < cdim; ++k) { - int book = g->subclass_books[pclass][cval & csub]; - cval = cval >> cbits; - if (book >= 0) { - int temp; - Codebook *c = f->codebooks + book; - DECODE(temp,f,c); - finalY[offset++] = temp; - } else - finalY[offset++] = 0; - } - } - if (f->valid_bits == INVALID_BITS) goto error; - step2_flag[0] = step2_flag[1] = 1; - for (j=2; j < g->values; ++j) { - int low, high, pred, highroom, lowroom, room, val; - low = g->neighbors[j][0]; - high = g->neighbors[j][1]; - - pred = predict_point(g->Xlist[j], g->Xlist[low], g->Xlist[high], finalY[low], finalY[high]); - val = finalY[j]; - highroom = range - pred; - lowroom = pred; - if (highroom < lowroom) - room = highroom * 2; - else - room = lowroom * 2; - if (val) { - step2_flag[low] = step2_flag[high] = 1; - step2_flag[j] = 1; - if (val >= room) - if (highroom > lowroom) - finalY[j] = val - lowroom + pred; - else - finalY[j] = pred - val + highroom - 1; - else - if (val & 1) - finalY[j] = pred - ((val+1)>>1); - else - finalY[j] = pred + (val>>1); - } else { - step2_flag[j] = 0; - finalY[j] = pred; - } - } + for (i = 0; i < f->channels; ++i) { + int s = map->chan[i].mux, floor; + zero_channel[i] = FALSE; + floor = map->submap_floor[s]; + if (f->floor_types[floor] == 0) { + return error(f, VORBIS_invalid_stream); + } else { + Floor1* g = &f->floor_config[floor].floor1; + if (get_bits(f, 1)) { + short* finalY; + uint8 step2_flag[256]; + static int range_list[4] = {256, 128, 86, 64}; + int range = range_list[g->floor1_multiplier - 1]; + int offset = 2; + finalY = f->finalY[i]; + finalY[0] = get_bits(f, ilog(range) - 1); + finalY[1] = get_bits(f, ilog(range) - 1); + for (j = 0; j < g->partitions; ++j) { + int pclass = g->partition_class_list[j]; + int cdim = g->class_dimensions[pclass]; + int cbits = g->class_subclasses[pclass]; + int csub = (1 << cbits) - 1; + int cval = 0; + if (cbits) { + Codebook* c = + f->codebooks + g->class_masterbooks[pclass]; + DECODE(cval, f, c); + } + for (k = 0; k < cdim; ++k) { + int book = g->subclass_books[pclass][cval & csub]; + cval = cval >> cbits; + if (book >= 0) { + int temp; + Codebook* c = f->codebooks + book; + DECODE(temp, f, c); + finalY[offset++] = temp; + } else + finalY[offset++] = 0; + } + } + if (f->valid_bits == INVALID_BITS) goto error; + step2_flag[0] = step2_flag[1] = 1; + for (j = 2; j < g->values; ++j) { + int low, high, pred, highroom, lowroom, room, val; + low = g->neighbors[j][0]; + high = g->neighbors[j][1]; + + pred = predict_point(g->Xlist[j], g->Xlist[low], + g->Xlist[high], finalY[low], + finalY[high]); + val = finalY[j]; + highroom = range - pred; + lowroom = pred; + if (highroom < lowroom) + room = highroom * 2; + else + room = lowroom * 2; + if (val) { + step2_flag[low] = step2_flag[high] = 1; + step2_flag[j] = 1; + if (val >= room) + if (highroom > lowroom) + finalY[j] = val - lowroom + pred; + else + finalY[j] = pred - val + highroom - 1; + else if (val & 1) + finalY[j] = pred - ((val + 1) >> 1); + else + finalY[j] = pred + (val >> 1); + } else { + step2_flag[j] = 0; + finalY[j] = pred; + } + } #ifdef STB_VORBIS_NO_DEFER_FLOOR - do_floor(f, map, i, n, f->floor_buffers[i], finalY, step2_flag); + do_floor(f, map, i, n, f->floor_buffers[i], finalY, step2_flag); #else - - for (j=0; j < g->values; ++j) { - if (!step2_flag[j]) - finalY[j] = -1; - } + + for (j = 0; j < g->values; ++j) { + if (!step2_flag[j]) finalY[j] = -1; + } #endif - } else { - error: - zero_channel[i] = TRUE; - } - - } - } - CHECK(f); - - if (f->alloc.alloc_buffer) - assert(f->alloc.alloc_buffer_length_in_bytes == f->temp_offset); - - memcpy(really_zero_channel, zero_channel, sizeof(really_zero_channel[0]) * f->channels); - for (i=0; i < map->coupling_steps; ++i) - if (!zero_channel[map->chan[i].magnitude] || !zero_channel[map->chan[i].angle]) { - zero_channel[map->chan[i].magnitude] = zero_channel[map->chan[i].angle] = FALSE; - } - - CHECK(f); - - for (i=0; i < map->submaps; ++i) { - float *residue_buffers[STB_VORBIS_MAX_CHANNELS]; - int r; - uint8 do_not_decode[256]; - int ch = 0; - for (j=0; j < f->channels; ++j) { - if (map->chan[j].mux == i) { - if (zero_channel[j]) { - do_not_decode[ch] = TRUE; - residue_buffers[ch] = NULL; } else { - do_not_decode[ch] = FALSE; - residue_buffers[ch] = f->channel_buffers[j]; + error: + zero_channel[i] = TRUE; } - ++ch; - } - } - r = map->submap_residue[i]; - decode_residue(f, residue_buffers, ch, n2, r, do_not_decode); - } + } + } + CHECK(f); - if (f->alloc.alloc_buffer) - assert(f->alloc.alloc_buffer_length_in_bytes == f->temp_offset); - CHECK(f); + if (f->alloc.alloc_buffer) + assert(f->alloc.alloc_buffer_length_in_bytes == f->temp_offset); - for (i = map->coupling_steps-1; i >= 0; --i) { - int n2 = n >> 1; - float *m = f->channel_buffers[map->chan[i].magnitude]; - float *a = f->channel_buffers[map->chan[i].angle ]; - for (j=0; j < n2; ++j) { - float a2,m2; - if (m[j] > 0) - if (a[j] > 0) - m2 = m[j], a2 = m[j] - a[j]; + memcpy(really_zero_channel, zero_channel, + sizeof(really_zero_channel[0]) * f->channels); + for (i = 0; i < map->coupling_steps; ++i) + if (!zero_channel[map->chan[i].magnitude] || + !zero_channel[map->chan[i].angle]) { + zero_channel[map->chan[i].magnitude] = + zero_channel[map->chan[i].angle] = FALSE; + } + + CHECK(f); + + for (i = 0; i < map->submaps; ++i) { + float* residue_buffers[STB_VORBIS_MAX_CHANNELS]; + int r; + uint8 do_not_decode[256]; + int ch = 0; + for (j = 0; j < f->channels; ++j) { + if (map->chan[j].mux == i) { + if (zero_channel[j]) { + do_not_decode[ch] = TRUE; + residue_buffers[ch] = NULL; + } else { + do_not_decode[ch] = FALSE; + residue_buffers[ch] = f->channel_buffers[j]; + } + ++ch; + } + } + r = map->submap_residue[i]; + decode_residue(f, residue_buffers, ch, n2, r, do_not_decode); + } + + if (f->alloc.alloc_buffer) + assert(f->alloc.alloc_buffer_length_in_bytes == f->temp_offset); + CHECK(f); + + for (i = map->coupling_steps - 1; i >= 0; --i) { + int n2 = n >> 1; + float* m = f->channel_buffers[map->chan[i].magnitude]; + float* a = f->channel_buffers[map->chan[i].angle]; + for (j = 0; j < n2; ++j) { + float a2, m2; + if (m[j] > 0) + if (a[j] > 0) + m2 = m[j], a2 = m[j] - a[j]; + else + a2 = m[j], m2 = m[j] + a[j]; + else if (a[j] > 0) + m2 = m[j], a2 = m[j] + a[j]; else - a2 = m[j], m2 = m[j] + a[j]; - else - if (a[j] > 0) - m2 = m[j], a2 = m[j] + a[j]; - else - a2 = m[j], m2 = m[j] - a[j]; - m[j] = m2; - a[j] = a2; - } - } - CHECK(f); + a2 = m[j], m2 = m[j] - a[j]; + m[j] = m2; + a[j] = a2; + } + } + CHECK(f); #ifndef STB_VORBIS_NO_DEFER_FLOOR - for (i=0; i < f->channels; ++i) { - if (really_zero_channel[i]) { - memset(f->channel_buffers[i], 0, sizeof(*f->channel_buffers[i]) * n2); - } else { - do_floor(f, map, i, n, f->channel_buffers[i], f->finalY[i], NULL); - } - } + for (i = 0; i < f->channels; ++i) { + if (really_zero_channel[i]) { + memset(f->channel_buffers[i], 0, + sizeof(*f->channel_buffers[i]) * n2); + } else { + do_floor(f, map, i, n, f->channel_buffers[i], f->finalY[i], NULL); + } + } #else - for (i=0; i < f->channels; ++i) { - if (really_zero_channel[i]) { - memset(f->channel_buffers[i], 0, sizeof(*f->channel_buffers[i]) * n2); - } else { - for (j=0; j < n2; ++j) - f->channel_buffers[i][j] *= f->floor_buffers[i][j]; - } - } + for (i = 0; i < f->channels; ++i) { + if (really_zero_channel[i]) { + memset(f->channel_buffers[i], 0, + sizeof(*f->channel_buffers[i]) * n2); + } else { + for (j = 0; j < n2; ++j) + f->channel_buffers[i][j] *= f->floor_buffers[i][j]; + } + } #endif - CHECK(f); - for (i=0; i < f->channels; ++i) - inverse_mdct(f->channel_buffers[i], n, f, m->blockflag); - CHECK(f); + CHECK(f); + for (i = 0; i < f->channels; ++i) + inverse_mdct(f->channel_buffers[i], n, f, m->blockflag); + CHECK(f); - flush_packet(f); + flush_packet(f); - if (f->first_decode) { - - f->current_loc = 0u - n2; - - f->discard_samples_deferred = n - right_end; - f->current_loc_valid = TRUE; - f->first_decode = FALSE; - } else if (f->discard_samples_deferred) { - if (f->discard_samples_deferred >= right_start - left_start) { - f->discard_samples_deferred -= (right_start - left_start); - left_start = right_start; - *p_left = left_start; - } else { - left_start += f->discard_samples_deferred; - *p_left = left_start; - f->discard_samples_deferred = 0; - } - } else if (f->previous_length == 0 && f->current_loc_valid) { - - } + if (f->first_decode) { + f->current_loc = 0u - n2; - if (f->last_seg_which == f->end_seg_with_known_loc) { - - if (f->current_loc_valid && (f->page_flag & PAGEFLAG_last_page)) { - uint32 current_end = f->known_loc_for_packet; - - if (current_end < f->current_loc + (right_end-left_start)) { - if (current_end < f->current_loc) { - - *len = 0; - } else { - *len = current_end - f->current_loc; + f->discard_samples_deferred = n - right_end; + f->current_loc_valid = TRUE; + f->first_decode = FALSE; + } else if (f->discard_samples_deferred) { + if (f->discard_samples_deferred >= right_start - left_start) { + f->discard_samples_deferred -= (right_start - left_start); + left_start = right_start; + *p_left = left_start; + } else { + left_start += f->discard_samples_deferred; + *p_left = left_start; + f->discard_samples_deferred = 0; + } + } else if (f->previous_length == 0 && f->current_loc_valid) { + } + + if (f->last_seg_which == f->end_seg_with_known_loc) { + if (f->current_loc_valid && (f->page_flag & PAGEFLAG_last_page)) { + uint32 current_end = f->known_loc_for_packet; + + if (current_end < f->current_loc + (right_end - left_start)) { + if (current_end < f->current_loc) { + *len = 0; + } else { + *len = current_end - f->current_loc; + } + *len += left_start; + if (*len > right_end) *len = right_end; + f->current_loc += *len; + return TRUE; } - *len += left_start; - if (*len > right_end) *len = right_end; - f->current_loc += *len; - return TRUE; - } - } - - f->current_loc = f->known_loc_for_packet - (n2-left_start); - f->current_loc_valid = TRUE; - } - if (f->current_loc_valid) - f->current_loc += (right_start - left_start); + } - if (f->alloc.alloc_buffer) - assert(f->alloc.alloc_buffer_length_in_bytes == f->temp_offset); - *len = right_end; - CHECK(f); + f->current_loc = f->known_loc_for_packet - (n2 - left_start); + f->current_loc_valid = TRUE; + } + if (f->current_loc_valid) f->current_loc += (right_start - left_start); - return TRUE; + if (f->alloc.alloc_buffer) + assert(f->alloc.alloc_buffer_length_in_bytes == f->temp_offset); + *len = right_end; + CHECK(f); + + return TRUE; } -static int vorbis_decode_packet(vorb *f, int *len, int *p_left, int *p_right) -{ - int mode, left_end, right_end; - if (!vorbis_decode_initial(f, p_left, &left_end, p_right, &right_end, &mode)) return 0; - return vorbis_decode_packet_rest(f, len, f->mode_config + mode, *p_left, left_end, *p_right, right_end, p_left); +static int vorbis_decode_packet(vorb* f, int* len, int* p_left, int* p_right) { + int mode, left_end, right_end; + if (!vorbis_decode_initial(f, p_left, &left_end, p_right, &right_end, + &mode)) + return 0; + return vorbis_decode_packet_rest(f, len, f->mode_config + mode, *p_left, + left_end, *p_right, right_end, p_left); } -static int vorbis_finish_frame(stb_vorbis *f, int len, int left, int right) -{ - int prev,i,j; - - if (f->previous_length) { - int i,j, n = f->previous_length; - float *w = get_window(f, n); - if (w == NULL) return 0; - for (i=0; i < f->channels; ++i) { - for (j=0; j < n; ++j) - f->channel_buffers[i][left+j] = - f->channel_buffers[i][left+j]*w[ j] + - f->previous_window[i][ j]*w[n-1-j]; - } - } +static int vorbis_finish_frame(stb_vorbis* f, int len, int left, int right) { + int prev, i, j; - prev = f->previous_length; + if (f->previous_length) { + int i, j, n = f->previous_length; + float* w = get_window(f, n); + if (w == NULL) return 0; + for (i = 0; i < f->channels; ++i) { + for (j = 0; j < n; ++j) + f->channel_buffers[i][left + j] = + f->channel_buffers[i][left + j] * w[j] + + f->previous_window[i][j] * w[n - 1 - j]; + } + } - f->previous_length = len - right; + prev = f->previous_length; - for (i=0; i < f->channels; ++i) - for (j=0; right+j < len; ++j) - f->previous_window[i][j] = f->channel_buffers[i][right+j]; + f->previous_length = len - right; - if (!prev) - - return 0; + for (i = 0; i < f->channels; ++i) + for (j = 0; right + j < len; ++j) + f->previous_window[i][j] = f->channel_buffers[i][right + j]; - if (len < right) right = len; + if (!prev) return 0; - f->samples_output += right-left; + if (len < right) right = len; - return right - left; + f->samples_output += right - left; + + return right - left; } -static int vorbis_pump_first_frame(stb_vorbis *f) -{ - int len, right, left, res; - res = vorbis_decode_packet(f, &len, &left, &right); - if (res) - vorbis_finish_frame(f, len, left, right); - return res; +static int vorbis_pump_first_frame(stb_vorbis* f) { + int len, right, left, res; + res = vorbis_decode_packet(f, &len, &left, &right); + if (res) vorbis_finish_frame(f, len, left, right); + return res; } #ifndef STB_VORBIS_NO_PUSHDATA_API -static int is_whole_packet_present(stb_vorbis *f) -{ - - int s = f->next_seg, first = TRUE; - uint8 *p = f->stream; +static int is_whole_packet_present(stb_vorbis* f) { + int s = f->next_seg, first = TRUE; + uint8* p = f->stream; - if (s != -1) { - for (; s < f->segment_count; ++s) { - p += f->segments[s]; - if (f->segments[s] < 255) - break; - } - - if (s == f->segment_count) - s = -1; - if (p > f->stream_end) return error(f, VORBIS_need_more_data); - first = FALSE; - } - for (; s == -1;) { - uint8 *q; - int n; + if (s != -1) { + for (; s < f->segment_count; ++s) { + p += f->segments[s]; + if (f->segments[s] < 255) break; + } - if (p + 26 >= f->stream_end) return error(f, VORBIS_need_more_data); - - if (memcmp(p, ogg_page_header, 4)) return error(f, VORBIS_invalid_stream); - if (p[4] != 0) return error(f, VORBIS_invalid_stream); - if (first) { - if (f->previous_length) - if ((p[5] & PAGEFLAG_continued_packet)) return error(f, VORBIS_invalid_stream); - - } else { - if (!(p[5] & PAGEFLAG_continued_packet)) return error(f, VORBIS_invalid_stream); - } - n = p[26]; - q = p+27; - p = q + n; - - if (p > f->stream_end) return error(f, VORBIS_need_more_data); - for (s=0; s < n; ++s) { - p += q[s]; - if (q[s] < 255) - break; - } - if (s == n) - s = -1; - if (p > f->stream_end) return error(f, VORBIS_need_more_data); - first = FALSE; - } - return TRUE; + if (s == f->segment_count) s = -1; + if (p > f->stream_end) return error(f, VORBIS_need_more_data); + first = FALSE; + } + for (; s == -1;) { + uint8* q; + int n; + + if (p + 26 >= f->stream_end) return error(f, VORBIS_need_more_data); + + if (memcmp(p, ogg_page_header, 4)) + return error(f, VORBIS_invalid_stream); + if (p[4] != 0) return error(f, VORBIS_invalid_stream); + if (first) { + if (f->previous_length) + if ((p[5] & PAGEFLAG_continued_packet)) + return error(f, VORBIS_invalid_stream); + + } else { + if (!(p[5] & PAGEFLAG_continued_packet)) + return error(f, VORBIS_invalid_stream); + } + n = p[26]; + q = p + 27; + p = q + n; + + if (p > f->stream_end) return error(f, VORBIS_need_more_data); + for (s = 0; s < n; ++s) { + p += q[s]; + if (q[s] < 255) break; + } + if (s == n) s = -1; + if (p > f->stream_end) return error(f, VORBIS_need_more_data); + first = FALSE; + } + return TRUE; } -#endif +#endif -static int start_decoder(vorb *f) -{ - uint8 header[6], x,y; - int len,i,j,k, max_submaps = 0; - int longest_floorlist=0; +static int start_decoder(vorb* f) { + uint8 header[6], x, y; + int len, i, j, k, max_submaps = 0; + int longest_floorlist = 0; - f->first_decode = TRUE; + f->first_decode = TRUE; - if (!start_page(f)) return FALSE; - - if (!(f->page_flag & PAGEFLAG_first_page)) return error(f, VORBIS_invalid_first_page); - if (f->page_flag & PAGEFLAG_last_page) return error(f, VORBIS_invalid_first_page); - if (f->page_flag & PAGEFLAG_continued_packet) return error(f, VORBIS_invalid_first_page); - - if (f->segment_count != 1) return error(f, VORBIS_invalid_first_page); - if (f->segments[0] != 30) { - - if (f->segments[0] == 64 && - getn(f, header, 6) && - header[0] == 'f' && - header[1] == 'i' && - header[2] == 's' && - header[3] == 'h' && - header[4] == 'e' && - header[5] == 'a' && - get8(f) == 'd' && - get8(f) == '\0') return error(f, VORBIS_ogg_skeleton_not_supported); - else - return error(f, VORBIS_invalid_first_page); - } + if (!start_page(f)) return FALSE; - if (get8(f) != VORBIS_packet_id) return error(f, VORBIS_invalid_first_page); - if (!getn(f, header, 6)) return error(f, VORBIS_unexpected_eof); - if (!vorbis_validate(header)) return error(f, VORBIS_invalid_first_page); - - if (get32(f) != 0) return error(f, VORBIS_invalid_first_page); - f->channels = get8(f); if (!f->channels) return error(f, VORBIS_invalid_first_page); - if (f->channels > STB_VORBIS_MAX_CHANNELS) return error(f, VORBIS_too_many_channels); - f->sample_rate = get32(f); if (!f->sample_rate) return error(f, VORBIS_invalid_first_page); - get32(f); - get32(f); - get32(f); - x = get8(f); - { - int log0,log1; - log0 = x & 15; - log1 = x >> 4; - f->blocksize_0 = 1 << log0; - f->blocksize_1 = 1 << log1; - if (log0 < 6 || log0 > 13) return error(f, VORBIS_invalid_setup); - if (log1 < 6 || log1 > 13) return error(f, VORBIS_invalid_setup); - if (log0 > log1) return error(f, VORBIS_invalid_setup); - } + if (!(f->page_flag & PAGEFLAG_first_page)) + return error(f, VORBIS_invalid_first_page); + if (f->page_flag & PAGEFLAG_last_page) + return error(f, VORBIS_invalid_first_page); + if (f->page_flag & PAGEFLAG_continued_packet) + return error(f, VORBIS_invalid_first_page); - x = get8(f); - if (!(x & 1)) return error(f, VORBIS_invalid_first_page); + if (f->segment_count != 1) return error(f, VORBIS_invalid_first_page); + if (f->segments[0] != 30) { + if (f->segments[0] == 64 && getn(f, header, 6) && header[0] == 'f' && + header[1] == 'i' && header[2] == 's' && header[3] == 'h' && + header[4] == 'e' && header[5] == 'a' && get8(f) == 'd' && + get8(f) == '\0') + return error(f, VORBIS_ogg_skeleton_not_supported); + else + return error(f, VORBIS_invalid_first_page); + } - if (!start_page(f)) return FALSE; + if (get8(f) != VORBIS_packet_id) return error(f, VORBIS_invalid_first_page); + if (!getn(f, header, 6)) return error(f, VORBIS_unexpected_eof); + if (!vorbis_validate(header)) return error(f, VORBIS_invalid_first_page); - if (!start_packet(f)) return FALSE; + if (get32(f) != 0) return error(f, VORBIS_invalid_first_page); + f->channels = get8(f); + if (!f->channels) return error(f, VORBIS_invalid_first_page); + if (f->channels > STB_VORBIS_MAX_CHANNELS) + return error(f, VORBIS_too_many_channels); + f->sample_rate = get32(f); + if (!f->sample_rate) return error(f, VORBIS_invalid_first_page); + get32(f); + get32(f); + get32(f); + x = get8(f); + { + int log0, log1; + log0 = x & 15; + log1 = x >> 4; + f->blocksize_0 = 1 << log0; + f->blocksize_1 = 1 << log1; + if (log0 < 6 || log0 > 13) return error(f, VORBIS_invalid_setup); + if (log1 < 6 || log1 > 13) return error(f, VORBIS_invalid_setup); + if (log0 > log1) return error(f, VORBIS_invalid_setup); + } - if (!next_segment(f)) return FALSE; + x = get8(f); + if (!(x & 1)) return error(f, VORBIS_invalid_first_page); - if (get8_packet(f) != VORBIS_packet_comment) return error(f, VORBIS_invalid_setup); - for (i=0; i < 6; ++i) header[i] = get8_packet(f); - if (!vorbis_validate(header)) return error(f, VORBIS_invalid_setup); - - len = get32_packet(f); - f->vendor = (char*)setup_malloc(f, sizeof(char) * (len+1)); - if (f->vendor == NULL) return error(f, VORBIS_outofmem); - for(i=0; i < len; ++i) { - f->vendor[i] = get8_packet(f); - } - f->vendor[len] = (char)'\0'; - - f->comment_list_length = get32_packet(f); - f->comment_list = NULL; - if (f->comment_list_length > 0) - { - f->comment_list = (char**) setup_malloc(f, sizeof(char*) * (f->comment_list_length)); - if (f->comment_list == NULL) return error(f, VORBIS_outofmem); - } + if (!start_page(f)) return FALSE; - for(i=0; i < f->comment_list_length; ++i) { - len = get32_packet(f); - f->comment_list[i] = (char*)setup_malloc(f, sizeof(char) * (len+1)); - if (f->comment_list[i] == NULL) return error(f, VORBIS_outofmem); + if (!start_packet(f)) return FALSE; - for(j=0; j < len; ++j) { - f->comment_list[i][j] = get8_packet(f); - } - f->comment_list[i][len] = (char)'\0'; - } + if (!next_segment(f)) return FALSE; - x = get8_packet(f); - if (!(x & 1)) return error(f, VORBIS_invalid_setup); + if (get8_packet(f) != VORBIS_packet_comment) + return error(f, VORBIS_invalid_setup); + for (i = 0; i < 6; ++i) header[i] = get8_packet(f); + if (!vorbis_validate(header)) return error(f, VORBIS_invalid_setup); - skip(f, f->bytes_in_seg); - f->bytes_in_seg = 0; + len = get32_packet(f); + f->vendor = (char*)setup_malloc(f, sizeof(char) * (len + 1)); + if (f->vendor == NULL) return error(f, VORBIS_outofmem); + for (i = 0; i < len; ++i) { + f->vendor[i] = get8_packet(f); + } + f->vendor[len] = (char)'\0'; - do { - len = next_segment(f); - skip(f, len); - f->bytes_in_seg = 0; - } while (len); + f->comment_list_length = get32_packet(f); + f->comment_list = NULL; + if (f->comment_list_length > 0) { + f->comment_list = + (char**)setup_malloc(f, sizeof(char*) * (f->comment_list_length)); + if (f->comment_list == NULL) return error(f, VORBIS_outofmem); + } - if (!start_packet(f)) return FALSE; + for (i = 0; i < f->comment_list_length; ++i) { + len = get32_packet(f); + f->comment_list[i] = (char*)setup_malloc(f, sizeof(char) * (len + 1)); + if (f->comment_list[i] == NULL) return error(f, VORBIS_outofmem); - #ifndef STB_VORBIS_NO_PUSHDATA_API - if (IS_PUSH_MODE(f)) { - if (!is_whole_packet_present(f)) { - - if (f->error == VORBIS_invalid_stream) - f->error = VORBIS_invalid_setup; - return FALSE; - } - } - #endif + for (j = 0; j < len; ++j) { + f->comment_list[i][j] = get8_packet(f); + } + f->comment_list[i][len] = (char)'\0'; + } - crc32_init(); + x = get8_packet(f); + if (!(x & 1)) return error(f, VORBIS_invalid_setup); - if (get8_packet(f) != VORBIS_packet_setup) return error(f, VORBIS_invalid_setup); - for (i=0; i < 6; ++i) header[i] = get8_packet(f); - if (!vorbis_validate(header)) return error(f, VORBIS_invalid_setup); + skip(f, f->bytes_in_seg); + f->bytes_in_seg = 0; - f->codebook_count = get_bits(f,8) + 1; - f->codebooks = (Codebook *) setup_malloc(f, sizeof(*f->codebooks) * f->codebook_count); - if (f->codebooks == NULL) return error(f, VORBIS_outofmem); - memset(f->codebooks, 0, sizeof(*f->codebooks) * f->codebook_count); - for (i=0; i < f->codebook_count; ++i) { - uint32 *values; - int ordered, sorted_count; - int total=0; - uint8 *lengths; - Codebook *c = f->codebooks+i; - CHECK(f); - x = get_bits(f, 8); if (x != 0x42) return error(f, VORBIS_invalid_setup); - x = get_bits(f, 8); if (x != 0x43) return error(f, VORBIS_invalid_setup); - x = get_bits(f, 8); if (x != 0x56) return error(f, VORBIS_invalid_setup); - x = get_bits(f, 8); - c->dimensions = (get_bits(f, 8)<<8) + x; - x = get_bits(f, 8); - y = get_bits(f, 8); - c->entries = (get_bits(f, 8)<<16) + (y<<8) + x; - ordered = get_bits(f,1); - c->sparse = ordered ? 0 : get_bits(f,1); + do { + len = next_segment(f); + skip(f, len); + f->bytes_in_seg = 0; + } while (len); - if (c->dimensions == 0 && c->entries != 0) return error(f, VORBIS_invalid_setup); + if (!start_packet(f)) return FALSE; - if (c->sparse) - lengths = (uint8 *) setup_temp_malloc(f, c->entries); - else - lengths = c->codeword_lengths = (uint8 *) setup_malloc(f, c->entries); +#ifndef STB_VORBIS_NO_PUSHDATA_API + if (IS_PUSH_MODE(f)) { + if (!is_whole_packet_present(f)) { + if (f->error == VORBIS_invalid_stream) + f->error = VORBIS_invalid_setup; + return FALSE; + } + } +#endif - if (!lengths) return error(f, VORBIS_outofmem); + crc32_init(); - if (ordered) { - int current_entry = 0; - int current_length = get_bits(f,5) + 1; - while (current_entry < c->entries) { - int limit = c->entries - current_entry; - int n = get_bits(f, ilog(limit)); - if (current_length >= 32) return error(f, VORBIS_invalid_setup); - if (current_entry + n > (int) c->entries) { return error(f, VORBIS_invalid_setup); } - memset(lengths + current_entry, current_length, n); - current_entry += n; - ++current_length; - } - } else { - for (j=0; j < c->entries; ++j) { - int present = c->sparse ? get_bits(f,1) : 1; - if (present) { - lengths[j] = get_bits(f, 5) + 1; - ++total; - if (lengths[j] == 32) - return error(f, VORBIS_invalid_setup); - } else { - lengths[j] = NO_CODE; + if (get8_packet(f) != VORBIS_packet_setup) + return error(f, VORBIS_invalid_setup); + for (i = 0; i < 6; ++i) header[i] = get8_packet(f); + if (!vorbis_validate(header)) return error(f, VORBIS_invalid_setup); + + f->codebook_count = get_bits(f, 8) + 1; + f->codebooks = + (Codebook*)setup_malloc(f, sizeof(*f->codebooks) * f->codebook_count); + if (f->codebooks == NULL) return error(f, VORBIS_outofmem); + memset(f->codebooks, 0, sizeof(*f->codebooks) * f->codebook_count); + for (i = 0; i < f->codebook_count; ++i) { + uint32* values; + int ordered, sorted_count; + int total = 0; + uint8* lengths; + Codebook* c = f->codebooks + i; + CHECK(f); + x = get_bits(f, 8); + if (x != 0x42) return error(f, VORBIS_invalid_setup); + x = get_bits(f, 8); + if (x != 0x43) return error(f, VORBIS_invalid_setup); + x = get_bits(f, 8); + if (x != 0x56) return error(f, VORBIS_invalid_setup); + x = get_bits(f, 8); + c->dimensions = (get_bits(f, 8) << 8) + x; + x = get_bits(f, 8); + y = get_bits(f, 8); + c->entries = (get_bits(f, 8) << 16) + (y << 8) + x; + ordered = get_bits(f, 1); + c->sparse = ordered ? 0 : get_bits(f, 1); + + if (c->dimensions == 0 && c->entries != 0) + return error(f, VORBIS_invalid_setup); + + if (c->sparse) + lengths = (uint8*)setup_temp_malloc(f, c->entries); + else + lengths = c->codeword_lengths = (uint8*)setup_malloc(f, c->entries); + + if (!lengths) return error(f, VORBIS_outofmem); + + if (ordered) { + int current_entry = 0; + int current_length = get_bits(f, 5) + 1; + while (current_entry < c->entries) { + int limit = c->entries - current_entry; + int n = get_bits(f, ilog(limit)); + if (current_length >= 32) return error(f, VORBIS_invalid_setup); + if (current_entry + n > (int)c->entries) { + return error(f, VORBIS_invalid_setup); + } + memset(lengths + current_entry, current_length, n); + current_entry += n; + ++current_length; } - } - } + } else { + for (j = 0; j < c->entries; ++j) { + int present = c->sparse ? get_bits(f, 1) : 1; + if (present) { + lengths[j] = get_bits(f, 5) + 1; + ++total; + if (lengths[j] == 32) return error(f, VORBIS_invalid_setup); + } else { + lengths[j] = NO_CODE; + } + } + } - if (c->sparse && total >= c->entries >> 2) { - - if (c->entries > (int) f->setup_temp_memory_required) - f->setup_temp_memory_required = c->entries; + if (c->sparse && total >= c->entries >> 2) { + if (c->entries > (int)f->setup_temp_memory_required) + f->setup_temp_memory_required = c->entries; - c->codeword_lengths = (uint8 *) setup_malloc(f, c->entries); - if (c->codeword_lengths == NULL) return error(f, VORBIS_outofmem); - memcpy(c->codeword_lengths, lengths, c->entries); - setup_temp_free(f, lengths, c->entries); - lengths = c->codeword_lengths; - c->sparse = 0; - } + c->codeword_lengths = (uint8*)setup_malloc(f, c->entries); + if (c->codeword_lengths == NULL) return error(f, VORBIS_outofmem); + memcpy(c->codeword_lengths, lengths, c->entries); + setup_temp_free(f, lengths, c->entries); + lengths = c->codeword_lengths; + c->sparse = 0; + } - if (c->sparse) { - sorted_count = total; - } else { - sorted_count = 0; - #ifndef STB_VORBIS_NO_HUFFMAN_BINARY_SEARCH - for (j=0; j < c->entries; ++j) - if (lengths[j] > STB_VORBIS_FAST_HUFFMAN_LENGTH && lengths[j] != NO_CODE) - ++sorted_count; - #endif - } + if (c->sparse) { + sorted_count = total; + } else { + sorted_count = 0; +#ifndef STB_VORBIS_NO_HUFFMAN_BINARY_SEARCH + for (j = 0; j < c->entries; ++j) + if (lengths[j] > STB_VORBIS_FAST_HUFFMAN_LENGTH && + lengths[j] != NO_CODE) + ++sorted_count; +#endif + } - c->sorted_entries = sorted_count; - values = NULL; + c->sorted_entries = sorted_count; + values = NULL; - CHECK(f); - if (!c->sparse) { - c->codewords = (uint32 *) setup_malloc(f, sizeof(c->codewords[0]) * c->entries); - if (!c->codewords) return error(f, VORBIS_outofmem); - } else { - unsigned int size; - if (c->sorted_entries) { - c->codeword_lengths = (uint8 *) setup_malloc(f, c->sorted_entries); - if (!c->codeword_lengths) return error(f, VORBIS_outofmem); - c->codewords = (uint32 *) setup_temp_malloc(f, sizeof(*c->codewords) * c->sorted_entries); - if (!c->codewords) return error(f, VORBIS_outofmem); - values = (uint32 *) setup_temp_malloc(f, sizeof(*values) * c->sorted_entries); - if (!values) return error(f, VORBIS_outofmem); - } - size = c->entries + (sizeof(*c->codewords) + sizeof(*values)) * c->sorted_entries; - if (size > f->setup_temp_memory_required) - f->setup_temp_memory_required = size; - } + CHECK(f); + if (!c->sparse) { + c->codewords = + (uint32*)setup_malloc(f, sizeof(c->codewords[0]) * c->entries); + if (!c->codewords) return error(f, VORBIS_outofmem); + } else { + unsigned int size; + if (c->sorted_entries) { + c->codeword_lengths = + (uint8*)setup_malloc(f, c->sorted_entries); + if (!c->codeword_lengths) return error(f, VORBIS_outofmem); + c->codewords = (uint32*)setup_temp_malloc( + f, sizeof(*c->codewords) * c->sorted_entries); + if (!c->codewords) return error(f, VORBIS_outofmem); + values = (uint32*)setup_temp_malloc( + f, sizeof(*values) * c->sorted_entries); + if (!values) return error(f, VORBIS_outofmem); + } + size = c->entries + (sizeof(*c->codewords) + sizeof(*values)) * + c->sorted_entries; + if (size > f->setup_temp_memory_required) + f->setup_temp_memory_required = size; + } - if (!compute_codewords(c, lengths, c->entries, values)) { - if (c->sparse) setup_temp_free(f, values, 0); - return error(f, VORBIS_invalid_setup); - } + if (!compute_codewords(c, lengths, c->entries, values)) { + if (c->sparse) setup_temp_free(f, values, 0); + return error(f, VORBIS_invalid_setup); + } - if (c->sorted_entries) { - - c->sorted_codewords = (uint32 *) setup_malloc(f, sizeof(*c->sorted_codewords) * (c->sorted_entries+1)); - if (c->sorted_codewords == NULL) return error(f, VORBIS_outofmem); - - c->sorted_values = ( int *) setup_malloc(f, sizeof(*c->sorted_values ) * (c->sorted_entries+1)); - if (c->sorted_values == NULL) return error(f, VORBIS_outofmem); - ++c->sorted_values; - c->sorted_values[-1] = -1; - compute_sorted_huffman(c, lengths, values); - } + if (c->sorted_entries) { + c->sorted_codewords = (uint32*)setup_malloc( + f, sizeof(*c->sorted_codewords) * (c->sorted_entries + 1)); + if (c->sorted_codewords == NULL) return error(f, VORBIS_outofmem); - if (c->sparse) { - setup_temp_free(f, values, sizeof(*values)*c->sorted_entries); - setup_temp_free(f, c->codewords, sizeof(*c->codewords)*c->sorted_entries); - setup_temp_free(f, lengths, c->entries); - c->codewords = NULL; - } + c->sorted_values = (int*)setup_malloc( + f, sizeof(*c->sorted_values) * (c->sorted_entries + 1)); + if (c->sorted_values == NULL) return error(f, VORBIS_outofmem); + ++c->sorted_values; + c->sorted_values[-1] = -1; + compute_sorted_huffman(c, lengths, values); + } - compute_accelerated_huffman(c); + if (c->sparse) { + setup_temp_free(f, values, sizeof(*values) * c->sorted_entries); + setup_temp_free(f, c->codewords, + sizeof(*c->codewords) * c->sorted_entries); + setup_temp_free(f, lengths, c->entries); + c->codewords = NULL; + } - CHECK(f); - c->lookup_type = get_bits(f, 4); - if (c->lookup_type > 2) return error(f, VORBIS_invalid_setup); - if (c->lookup_type > 0) { - uint16 *mults; - c->minimum_value = float32_unpack(get_bits(f, 32)); - c->delta_value = float32_unpack(get_bits(f, 32)); - c->value_bits = get_bits(f, 4)+1; - c->sequence_p = get_bits(f,1); - if (c->lookup_type == 1) { - int values = lookup1_values(c->entries, c->dimensions); - if (values < 0) return error(f, VORBIS_invalid_setup); - c->lookup_values = (uint32) values; - } else { - c->lookup_values = c->entries * c->dimensions; - } - if (c->lookup_values == 0) return error(f, VORBIS_invalid_setup); - mults = (uint16 *) setup_temp_malloc(f, sizeof(mults[0]) * c->lookup_values); - if (mults == NULL) return error(f, VORBIS_outofmem); - for (j=0; j < (int) c->lookup_values; ++j) { - int q = get_bits(f, c->value_bits); - if (q == EOP) { setup_temp_free(f,mults,sizeof(mults[0])*c->lookup_values); return error(f, VORBIS_invalid_setup); } - mults[j] = q; - } + compute_accelerated_huffman(c); + + CHECK(f); + c->lookup_type = get_bits(f, 4); + if (c->lookup_type > 2) return error(f, VORBIS_invalid_setup); + if (c->lookup_type > 0) { + uint16* mults; + c->minimum_value = float32_unpack(get_bits(f, 32)); + c->delta_value = float32_unpack(get_bits(f, 32)); + c->value_bits = get_bits(f, 4) + 1; + c->sequence_p = get_bits(f, 1); + if (c->lookup_type == 1) { + int values = lookup1_values(c->entries, c->dimensions); + if (values < 0) return error(f, VORBIS_invalid_setup); + c->lookup_values = (uint32)values; + } else { + c->lookup_values = c->entries * c->dimensions; + } + if (c->lookup_values == 0) return error(f, VORBIS_invalid_setup); + mults = (uint16*)setup_temp_malloc( + f, sizeof(mults[0]) * c->lookup_values); + if (mults == NULL) return error(f, VORBIS_outofmem); + for (j = 0; j < (int)c->lookup_values; ++j) { + int q = get_bits(f, c->value_bits); + if (q == EOP) { + setup_temp_free(f, mults, + sizeof(mults[0]) * c->lookup_values); + return error(f, VORBIS_invalid_setup); + } + mults[j] = q; + } #ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK - if (c->lookup_type == 1) { - int len, sparse = c->sparse; - float last=0; - - if (sparse) { - if (c->sorted_entries == 0) goto skip; - c->multiplicands = (codetype *) setup_malloc(f, sizeof(c->multiplicands[0]) * c->sorted_entries * c->dimensions); + if (c->lookup_type == 1) { + int len, sparse = c->sparse; + float last = 0; + + if (sparse) { + if (c->sorted_entries == 0) goto skip; + c->multiplicands = (codetype*)setup_malloc( + f, sizeof(c->multiplicands[0]) * c->sorted_entries * + c->dimensions); + } else + c->multiplicands = (codetype*)setup_malloc( + f, sizeof(c->multiplicands[0]) * c->entries * + c->dimensions); + if (c->multiplicands == NULL) { + setup_temp_free(f, mults, + sizeof(mults[0]) * c->lookup_values); + return error(f, VORBIS_outofmem); + } + len = sparse ? c->sorted_entries : c->entries; + for (j = 0; j < len; ++j) { + unsigned int z = sparse ? c->sorted_values[j] : j; + unsigned int div = 1; + for (k = 0; k < c->dimensions; ++k) { + int off = (z / div) % c->lookup_values; + float val = mults[off] * c->delta_value + + c->minimum_value + last; + c->multiplicands[j * c->dimensions + k] = val; + if (c->sequence_p) last = val; + if (k + 1 < c->dimensions) { + if (div > + UINT_MAX / (unsigned int)c->lookup_values) { + setup_temp_free( + f, mults, + sizeof(mults[0]) * c->lookup_values); + return error(f, VORBIS_invalid_setup); + } + div *= c->lookup_values; + } + } + } + c->lookup_type = 2; } else - c->multiplicands = (codetype *) setup_malloc(f, sizeof(c->multiplicands[0]) * c->entries * c->dimensions); - if (c->multiplicands == NULL) { setup_temp_free(f,mults,sizeof(mults[0])*c->lookup_values); return error(f, VORBIS_outofmem); } - len = sparse ? c->sorted_entries : c->entries; - for (j=0; j < len; ++j) { - unsigned int z = sparse ? c->sorted_values[j] : j; - unsigned int div=1; - for (k=0; k < c->dimensions; ++k) { - int off = (z / div) % c->lookup_values; - float val = mults[off]*c->delta_value + c->minimum_value + last; - c->multiplicands[j*c->dimensions + k] = val; - if (c->sequence_p) - last = val; - if (k+1 < c->dimensions) { - if (div > UINT_MAX / (unsigned int) c->lookup_values) { - setup_temp_free(f, mults,sizeof(mults[0])*c->lookup_values); - return error(f, VORBIS_invalid_setup); - } - div *= c->lookup_values; - } - } - } - c->lookup_type = 2; - } - else #endif - { - float last=0; - CHECK(f); - c->multiplicands = (codetype *) setup_malloc(f, sizeof(c->multiplicands[0]) * c->lookup_values); - if (c->multiplicands == NULL) { setup_temp_free(f, mults,sizeof(mults[0])*c->lookup_values); return error(f, VORBIS_outofmem); } - for (j=0; j < (int) c->lookup_values; ++j) { - float val = mults[j] * c->delta_value + c->minimum_value + last; - c->multiplicands[j] = val; - if (c->sequence_p) - last = val; + { + float last = 0; + CHECK(f); + c->multiplicands = (codetype*)setup_malloc( + f, sizeof(c->multiplicands[0]) * c->lookup_values); + if (c->multiplicands == NULL) { + setup_temp_free(f, mults, + sizeof(mults[0]) * c->lookup_values); + return error(f, VORBIS_outofmem); + } + for (j = 0; j < (int)c->lookup_values; ++j) { + float val = + mults[j] * c->delta_value + c->minimum_value + last; + c->multiplicands[j] = val; + if (c->sequence_p) last = val; + } } - } #ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK skip:; #endif - setup_temp_free(f, mults, sizeof(mults[0])*c->lookup_values); + setup_temp_free(f, mults, sizeof(mults[0]) * c->lookup_values); - CHECK(f); - } - CHECK(f); - } + CHECK(f); + } + CHECK(f); + } - x = get_bits(f, 6) + 1; - for (i=0; i < x; ++i) { - uint32 z = get_bits(f, 16); - if (z != 0) return error(f, VORBIS_invalid_setup); - } + x = get_bits(f, 6) + 1; + for (i = 0; i < x; ++i) { + uint32 z = get_bits(f, 16); + if (z != 0) return error(f, VORBIS_invalid_setup); + } - f->floor_count = get_bits(f, 6)+1; - f->floor_config = (Floor *) setup_malloc(f, f->floor_count * sizeof(*f->floor_config)); - if (f->floor_config == NULL) return error(f, VORBIS_outofmem); - for (i=0; i < f->floor_count; ++i) { - f->floor_types[i] = get_bits(f, 16); - if (f->floor_types[i] > 1) return error(f, VORBIS_invalid_setup); - if (f->floor_types[i] == 0) { - Floor0 *g = &f->floor_config[i].floor0; - g->order = get_bits(f,8); - g->rate = get_bits(f,16); - g->bark_map_size = get_bits(f,16); - g->amplitude_bits = get_bits(f,6); - g->amplitude_offset = get_bits(f,8); - g->number_of_books = get_bits(f,4) + 1; - for (j=0; j < g->number_of_books; ++j) - g->book_list[j] = get_bits(f,8); - return error(f, VORBIS_feature_not_supported); - } else { - stbv__floor_ordering p[31*8+2]; - Floor1 *g = &f->floor_config[i].floor1; - int max_class = -1; - g->partitions = get_bits(f, 5); - for (j=0; j < g->partitions; ++j) { - g->partition_class_list[j] = get_bits(f, 4); - if (g->partition_class_list[j] > max_class) - max_class = g->partition_class_list[j]; - } - for (j=0; j <= max_class; ++j) { - g->class_dimensions[j] = get_bits(f, 3)+1; - g->class_subclasses[j] = get_bits(f, 2); - if (g->class_subclasses[j]) { - g->class_masterbooks[j] = get_bits(f, 8); - if (g->class_masterbooks[j] >= f->codebook_count) return error(f, VORBIS_invalid_setup); + f->floor_count = get_bits(f, 6) + 1; + f->floor_config = + (Floor*)setup_malloc(f, f->floor_count * sizeof(*f->floor_config)); + if (f->floor_config == NULL) return error(f, VORBIS_outofmem); + for (i = 0; i < f->floor_count; ++i) { + f->floor_types[i] = get_bits(f, 16); + if (f->floor_types[i] > 1) return error(f, VORBIS_invalid_setup); + if (f->floor_types[i] == 0) { + Floor0* g = &f->floor_config[i].floor0; + g->order = get_bits(f, 8); + g->rate = get_bits(f, 16); + g->bark_map_size = get_bits(f, 16); + g->amplitude_bits = get_bits(f, 6); + g->amplitude_offset = get_bits(f, 8); + g->number_of_books = get_bits(f, 4) + 1; + for (j = 0; j < g->number_of_books; ++j) + g->book_list[j] = get_bits(f, 8); + return error(f, VORBIS_feature_not_supported); + } else { + stbv__floor_ordering p[31 * 8 + 2]; + Floor1* g = &f->floor_config[i].floor1; + int max_class = -1; + g->partitions = get_bits(f, 5); + for (j = 0; j < g->partitions; ++j) { + g->partition_class_list[j] = get_bits(f, 4); + if (g->partition_class_list[j] > max_class) + max_class = g->partition_class_list[j]; } - for (k=0; k < 1 << g->class_subclasses[j]; ++k) { - g->subclass_books[j][k] = (int16)get_bits(f,8)-1; - if (g->subclass_books[j][k] >= f->codebook_count) return error(f, VORBIS_invalid_setup); + for (j = 0; j <= max_class; ++j) { + g->class_dimensions[j] = get_bits(f, 3) + 1; + g->class_subclasses[j] = get_bits(f, 2); + if (g->class_subclasses[j]) { + g->class_masterbooks[j] = get_bits(f, 8); + if (g->class_masterbooks[j] >= f->codebook_count) + return error(f, VORBIS_invalid_setup); + } + for (k = 0; k < 1 << g->class_subclasses[j]; ++k) { + g->subclass_books[j][k] = (int16)get_bits(f, 8) - 1; + if (g->subclass_books[j][k] >= f->codebook_count) + return error(f, VORBIS_invalid_setup); + } } - } - g->floor1_multiplier = get_bits(f,2)+1; - g->rangebits = get_bits(f,4); - g->Xlist[0] = 0; - g->Xlist[1] = 1 << g->rangebits; - g->values = 2; - for (j=0; j < g->partitions; ++j) { - int c = g->partition_class_list[j]; - for (k=0; k < g->class_dimensions[c]; ++k) { - g->Xlist[g->values] = get_bits(f, g->rangebits); - ++g->values; + g->floor1_multiplier = get_bits(f, 2) + 1; + g->rangebits = get_bits(f, 4); + g->Xlist[0] = 0; + g->Xlist[1] = 1 << g->rangebits; + g->values = 2; + for (j = 0; j < g->partitions; ++j) { + int c = g->partition_class_list[j]; + for (k = 0; k < g->class_dimensions[c]; ++k) { + g->Xlist[g->values] = get_bits(f, g->rangebits); + ++g->values; + } } - } - - for (j=0; j < g->values; ++j) { - p[j].x = g->Xlist[j]; - p[j].id = j; - } - qsort(p, g->values, sizeof(p[0]), point_compare); - for (j=0; j < g->values-1; ++j) - if (p[j].x == p[j+1].x) - return error(f, VORBIS_invalid_setup); - for (j=0; j < g->values; ++j) - g->sorted_order[j] = (uint8) p[j].id; - - for (j=2; j < g->values; ++j) { - int low = 0,hi = 0; - neighbors(g->Xlist, j, &low,&hi); - g->neighbors[j][0] = low; - g->neighbors[j][1] = hi; - } - if (g->values > longest_floorlist) - longest_floorlist = g->values; - } - } - - f->residue_count = get_bits(f, 6)+1; - f->residue_config = (Residue *) setup_malloc(f, f->residue_count * sizeof(f->residue_config[0])); - if (f->residue_config == NULL) return error(f, VORBIS_outofmem); - memset(f->residue_config, 0, f->residue_count * sizeof(f->residue_config[0])); - for (i=0; i < f->residue_count; ++i) { - uint8 residue_cascade[64]; - Residue *r = f->residue_config+i; - f->residue_types[i] = get_bits(f, 16); - if (f->residue_types[i] > 2) return error(f, VORBIS_invalid_setup); - r->begin = get_bits(f, 24); - r->end = get_bits(f, 24); - if (r->end < r->begin) return error(f, VORBIS_invalid_setup); - r->part_size = get_bits(f,24)+1; - r->classifications = get_bits(f,6)+1; - r->classbook = get_bits(f,8); - if (r->classbook >= f->codebook_count) return error(f, VORBIS_invalid_setup); - for (j=0; j < r->classifications; ++j) { - uint8 high_bits=0; - uint8 low_bits=get_bits(f,3); - if (get_bits(f,1)) - high_bits = get_bits(f,5); - residue_cascade[j] = high_bits*8 + low_bits; - } - r->residue_books = (short (*)[8]) setup_malloc(f, sizeof(r->residue_books[0]) * r->classifications); - if (r->residue_books == NULL) return error(f, VORBIS_outofmem); - for (j=0; j < r->classifications; ++j) { - for (k=0; k < 8; ++k) { - if (residue_cascade[j] & (1 << k)) { - r->residue_books[j][k] = get_bits(f, 8); - if (r->residue_books[j][k] >= f->codebook_count) return error(f, VORBIS_invalid_setup); - } else { - r->residue_books[j][k] = -1; + for (j = 0; j < g->values; ++j) { + p[j].x = g->Xlist[j]; + p[j].id = j; } - } - } - - r->classdata = (uint8 **) setup_malloc(f, sizeof(*r->classdata) * f->codebooks[r->classbook].entries); - if (!r->classdata) return error(f, VORBIS_outofmem); - memset(r->classdata, 0, sizeof(*r->classdata) * f->codebooks[r->classbook].entries); - for (j=0; j < f->codebooks[r->classbook].entries; ++j) { - int classwords = f->codebooks[r->classbook].dimensions; - int temp = j; - r->classdata[j] = (uint8 *) setup_malloc(f, sizeof(r->classdata[j][0]) * classwords); - if (r->classdata[j] == NULL) return error(f, VORBIS_outofmem); - for (k=classwords-1; k >= 0; --k) { - r->classdata[j][k] = temp % r->classifications; - temp /= r->classifications; - } - } - } + qsort(p, g->values, sizeof(p[0]), point_compare); + for (j = 0; j < g->values - 1; ++j) + if (p[j].x == p[j + 1].x) return error(f, VORBIS_invalid_setup); + for (j = 0; j < g->values; ++j) g->sorted_order[j] = (uint8)p[j].id; - f->mapping_count = get_bits(f,6)+1; - f->mapping = (Mapping *) setup_malloc(f, f->mapping_count * sizeof(*f->mapping)); - if (f->mapping == NULL) return error(f, VORBIS_outofmem); - memset(f->mapping, 0, f->mapping_count * sizeof(*f->mapping)); - for (i=0; i < f->mapping_count; ++i) { - Mapping *m = f->mapping + i; - int mapping_type = get_bits(f,16); - if (mapping_type != 0) return error(f, VORBIS_invalid_setup); - m->chan = (MappingChannel *) setup_malloc(f, f->channels * sizeof(*m->chan)); - if (m->chan == NULL) return error(f, VORBIS_outofmem); - if (get_bits(f,1)) - m->submaps = get_bits(f,4)+1; - else - m->submaps = 1; - if (m->submaps > max_submaps) - max_submaps = m->submaps; - if (get_bits(f,1)) { - m->coupling_steps = get_bits(f,8)+1; - if (m->coupling_steps > f->channels) return error(f, VORBIS_invalid_setup); - for (k=0; k < m->coupling_steps; ++k) { - m->chan[k].magnitude = get_bits(f, ilog(f->channels-1)); - m->chan[k].angle = get_bits(f, ilog(f->channels-1)); - if (m->chan[k].magnitude >= f->channels) return error(f, VORBIS_invalid_setup); - if (m->chan[k].angle >= f->channels) return error(f, VORBIS_invalid_setup); - if (m->chan[k].magnitude == m->chan[k].angle) return error(f, VORBIS_invalid_setup); - } - } else - m->coupling_steps = 0; + for (j = 2; j < g->values; ++j) { + int low = 0, hi = 0; + neighbors(g->Xlist, j, &low, &hi); + g->neighbors[j][0] = low; + g->neighbors[j][1] = hi; + } - if (get_bits(f,2)) return error(f, VORBIS_invalid_setup); - if (m->submaps > 1) { - for (j=0; j < f->channels; ++j) { - m->chan[j].mux = get_bits(f, 4); - if (m->chan[j].mux >= m->submaps) return error(f, VORBIS_invalid_setup); - } - } else - - for (j=0; j < f->channels; ++j) - m->chan[j].mux = 0; + if (g->values > longest_floorlist) longest_floorlist = g->values; + } + } - for (j=0; j < m->submaps; ++j) { - get_bits(f,8); - m->submap_floor[j] = get_bits(f,8); - m->submap_residue[j] = get_bits(f,8); - if (m->submap_floor[j] >= f->floor_count) return error(f, VORBIS_invalid_setup); - if (m->submap_residue[j] >= f->residue_count) return error(f, VORBIS_invalid_setup); - } - } + f->residue_count = get_bits(f, 6) + 1; + f->residue_config = (Residue*)setup_malloc( + f, f->residue_count * sizeof(f->residue_config[0])); + if (f->residue_config == NULL) return error(f, VORBIS_outofmem); + memset(f->residue_config, 0, + f->residue_count * sizeof(f->residue_config[0])); + for (i = 0; i < f->residue_count; ++i) { + uint8 residue_cascade[64]; + Residue* r = f->residue_config + i; + f->residue_types[i] = get_bits(f, 16); + if (f->residue_types[i] > 2) return error(f, VORBIS_invalid_setup); + r->begin = get_bits(f, 24); + r->end = get_bits(f, 24); + if (r->end < r->begin) return error(f, VORBIS_invalid_setup); + r->part_size = get_bits(f, 24) + 1; + r->classifications = get_bits(f, 6) + 1; + r->classbook = get_bits(f, 8); + if (r->classbook >= f->codebook_count) + return error(f, VORBIS_invalid_setup); + for (j = 0; j < r->classifications; ++j) { + uint8 high_bits = 0; + uint8 low_bits = get_bits(f, 3); + if (get_bits(f, 1)) high_bits = get_bits(f, 5); + residue_cascade[j] = high_bits * 8 + low_bits; + } + r->residue_books = (short (*)[8])setup_malloc( + f, sizeof(r->residue_books[0]) * r->classifications); + if (r->residue_books == NULL) return error(f, VORBIS_outofmem); + for (j = 0; j < r->classifications; ++j) { + for (k = 0; k < 8; ++k) { + if (residue_cascade[j] & (1 << k)) { + r->residue_books[j][k] = get_bits(f, 8); + if (r->residue_books[j][k] >= f->codebook_count) + return error(f, VORBIS_invalid_setup); + } else { + r->residue_books[j][k] = -1; + } + } + } - f->mode_count = get_bits(f, 6)+1; - for (i=0; i < f->mode_count; ++i) { - Mode *m = f->mode_config+i; - m->blockflag = get_bits(f,1); - m->windowtype = get_bits(f,16); - m->transformtype = get_bits(f,16); - m->mapping = get_bits(f,8); - if (m->windowtype != 0) return error(f, VORBIS_invalid_setup); - if (m->transformtype != 0) return error(f, VORBIS_invalid_setup); - if (m->mapping >= f->mapping_count) return error(f, VORBIS_invalid_setup); - } + r->classdata = (uint8**)setup_malloc( + f, sizeof(*r->classdata) * f->codebooks[r->classbook].entries); + if (!r->classdata) return error(f, VORBIS_outofmem); + memset(r->classdata, 0, + sizeof(*r->classdata) * f->codebooks[r->classbook].entries); + for (j = 0; j < f->codebooks[r->classbook].entries; ++j) { + int classwords = f->codebooks[r->classbook].dimensions; + int temp = j; + r->classdata[j] = (uint8*)setup_malloc( + f, sizeof(r->classdata[j][0]) * classwords); + if (r->classdata[j] == NULL) return error(f, VORBIS_outofmem); + for (k = classwords - 1; k >= 0; --k) { + r->classdata[j][k] = temp % r->classifications; + temp /= r->classifications; + } + } + } - flush_packet(f); + f->mapping_count = get_bits(f, 6) + 1; + f->mapping = + (Mapping*)setup_malloc(f, f->mapping_count * sizeof(*f->mapping)); + if (f->mapping == NULL) return error(f, VORBIS_outofmem); + memset(f->mapping, 0, f->mapping_count * sizeof(*f->mapping)); + for (i = 0; i < f->mapping_count; ++i) { + Mapping* m = f->mapping + i; + int mapping_type = get_bits(f, 16); + if (mapping_type != 0) return error(f, VORBIS_invalid_setup); + m->chan = + (MappingChannel*)setup_malloc(f, f->channels * sizeof(*m->chan)); + if (m->chan == NULL) return error(f, VORBIS_outofmem); + if (get_bits(f, 1)) + m->submaps = get_bits(f, 4) + 1; + else + m->submaps = 1; + if (m->submaps > max_submaps) max_submaps = m->submaps; + if (get_bits(f, 1)) { + m->coupling_steps = get_bits(f, 8) + 1; + if (m->coupling_steps > f->channels) + return error(f, VORBIS_invalid_setup); + for (k = 0; k < m->coupling_steps; ++k) { + m->chan[k].magnitude = get_bits(f, ilog(f->channels - 1)); + m->chan[k].angle = get_bits(f, ilog(f->channels - 1)); + if (m->chan[k].magnitude >= f->channels) + return error(f, VORBIS_invalid_setup); + if (m->chan[k].angle >= f->channels) + return error(f, VORBIS_invalid_setup); + if (m->chan[k].magnitude == m->chan[k].angle) + return error(f, VORBIS_invalid_setup); + } + } else + m->coupling_steps = 0; - f->previous_length = 0; + if (get_bits(f, 2)) return error(f, VORBIS_invalid_setup); + if (m->submaps > 1) { + for (j = 0; j < f->channels; ++j) { + m->chan[j].mux = get_bits(f, 4); + if (m->chan[j].mux >= m->submaps) + return error(f, VORBIS_invalid_setup); + } + } else - for (i=0; i < f->channels; ++i) { - f->channel_buffers[i] = (float *) setup_malloc(f, sizeof(float) * f->blocksize_1); - f->previous_window[i] = (float *) setup_malloc(f, sizeof(float) * f->blocksize_1/2); - f->finalY[i] = (int16 *) setup_malloc(f, sizeof(int16) * longest_floorlist); - if (f->channel_buffers[i] == NULL || f->previous_window[i] == NULL || f->finalY[i] == NULL) return error(f, VORBIS_outofmem); - memset(f->channel_buffers[i], 0, sizeof(float) * f->blocksize_1); - #ifdef STB_VORBIS_NO_DEFER_FLOOR - f->floor_buffers[i] = (float *) setup_malloc(f, sizeof(float) * f->blocksize_1/2); - if (f->floor_buffers[i] == NULL) return error(f, VORBIS_outofmem); - #endif - } + for (j = 0; j < f->channels; ++j) m->chan[j].mux = 0; - if (!init_blocksize(f, 0, f->blocksize_0)) return FALSE; - if (!init_blocksize(f, 1, f->blocksize_1)) return FALSE; - f->blocksize[0] = f->blocksize_0; - f->blocksize[1] = f->blocksize_1; + for (j = 0; j < m->submaps; ++j) { + get_bits(f, 8); + m->submap_floor[j] = get_bits(f, 8); + m->submap_residue[j] = get_bits(f, 8); + if (m->submap_floor[j] >= f->floor_count) + return error(f, VORBIS_invalid_setup); + if (m->submap_residue[j] >= f->residue_count) + return error(f, VORBIS_invalid_setup); + } + } + + f->mode_count = get_bits(f, 6) + 1; + for (i = 0; i < f->mode_count; ++i) { + Mode* m = f->mode_config + i; + m->blockflag = get_bits(f, 1); + m->windowtype = get_bits(f, 16); + m->transformtype = get_bits(f, 16); + m->mapping = get_bits(f, 8); + if (m->windowtype != 0) return error(f, VORBIS_invalid_setup); + if (m->transformtype != 0) return error(f, VORBIS_invalid_setup); + if (m->mapping >= f->mapping_count) + return error(f, VORBIS_invalid_setup); + } + + flush_packet(f); + + f->previous_length = 0; + + for (i = 0; i < f->channels; ++i) { + f->channel_buffers[i] = + (float*)setup_malloc(f, sizeof(float) * f->blocksize_1); + f->previous_window[i] = + (float*)setup_malloc(f, sizeof(float) * f->blocksize_1 / 2); + f->finalY[i] = + (int16*)setup_malloc(f, sizeof(int16) * longest_floorlist); + if (f->channel_buffers[i] == NULL || f->previous_window[i] == NULL || + f->finalY[i] == NULL) + return error(f, VORBIS_outofmem); + memset(f->channel_buffers[i], 0, sizeof(float) * f->blocksize_1); +#ifdef STB_VORBIS_NO_DEFER_FLOOR + f->floor_buffers[i] = + (float*)setup_malloc(f, sizeof(float) * f->blocksize_1 / 2); + if (f->floor_buffers[i] == NULL) return error(f, VORBIS_outofmem); +#endif + } + + if (!init_blocksize(f, 0, f->blocksize_0)) return FALSE; + if (!init_blocksize(f, 1, f->blocksize_1)) return FALSE; + f->blocksize[0] = f->blocksize_0; + f->blocksize[1] = f->blocksize_1; #ifdef STB_VORBIS_DIVIDE_TABLE - if (integer_divide_table[1][1]==0) - for (i=0; i < DIVTAB_NUMER; ++i) - for (j=1; j < DIVTAB_DENOM; ++j) - integer_divide_table[i][j] = i / j; + if (integer_divide_table[1][1] == 0) + for (i = 0; i < DIVTAB_NUMER; ++i) + for (j = 1; j < DIVTAB_DENOM; ++j) + integer_divide_table[i][j] = i / j; #endif - { - uint32 imdct_mem = (f->blocksize_1 * sizeof(float) >> 1); - uint32 classify_mem; - int i,max_part_read=0; - for (i=0; i < f->residue_count; ++i) { - Residue *r = f->residue_config + i; - unsigned int actual_size = f->blocksize_1 / 2; - unsigned int limit_r_begin = r->begin < actual_size ? r->begin : actual_size; - unsigned int limit_r_end = r->end < actual_size ? r->end : actual_size; - int n_read = limit_r_end - limit_r_begin; - int part_read = n_read / r->part_size; - if (part_read > max_part_read) - max_part_read = part_read; - } - #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE - classify_mem = f->channels * (sizeof(void*) + max_part_read * sizeof(uint8 *)); - #else - classify_mem = f->channels * (sizeof(void*) + max_part_read * sizeof(int *)); - #endif + { + uint32 imdct_mem = (f->blocksize_1 * sizeof(float) >> 1); + uint32 classify_mem; + int i, max_part_read = 0; + for (i = 0; i < f->residue_count; ++i) { + Residue* r = f->residue_config + i; + unsigned int actual_size = f->blocksize_1 / 2; + unsigned int limit_r_begin = + r->begin < actual_size ? r->begin : actual_size; + unsigned int limit_r_end = + r->end < actual_size ? r->end : actual_size; + int n_read = limit_r_end - limit_r_begin; + int part_read = n_read / r->part_size; + if (part_read > max_part_read) max_part_read = part_read; + } +#ifndef STB_VORBIS_DIVIDES_IN_RESIDUE + classify_mem = + f->channels * (sizeof(void*) + max_part_read * sizeof(uint8*)); +#else + classify_mem = + f->channels * (sizeof(void*) + max_part_read * sizeof(int*)); +#endif - f->temp_memory_required = classify_mem; - if (imdct_mem > f->temp_memory_required) - f->temp_memory_required = imdct_mem; - } + f->temp_memory_required = classify_mem; + if (imdct_mem > f->temp_memory_required) + f->temp_memory_required = imdct_mem; + } - if (f->alloc.alloc_buffer) { - assert(f->temp_offset == f->alloc.alloc_buffer_length_in_bytes); - - if (f->setup_offset + sizeof(*f) + f->temp_memory_required > (unsigned) f->temp_offset) - return error(f, VORBIS_outofmem); - } + if (f->alloc.alloc_buffer) { + assert(f->temp_offset == f->alloc.alloc_buffer_length_in_bytes); - if (f->next_seg == -1) { - f->first_audio_page_offset = stb_vorbis_get_file_offset(f); - } else { - f->first_audio_page_offset = 0; - } + if (f->setup_offset + sizeof(*f) + f->temp_memory_required > + (unsigned)f->temp_offset) + return error(f, VORBIS_outofmem); + } - return TRUE; + if (f->next_seg == -1) { + f->first_audio_page_offset = stb_vorbis_get_file_offset(f); + } else { + f->first_audio_page_offset = 0; + } + + return TRUE; } -static void vorbis_deinit(stb_vorbis *p) -{ - int i,j; +static void vorbis_deinit(stb_vorbis* p) { + int i, j; - setup_free(p, p->vendor); - for (i=0; i < p->comment_list_length; ++i) { - setup_free(p, p->comment_list[i]); - } - setup_free(p, p->comment_list); + setup_free(p, p->vendor); + for (i = 0; i < p->comment_list_length; ++i) { + setup_free(p, p->comment_list[i]); + } + setup_free(p, p->comment_list); - if (p->residue_config) { - for (i=0; i < p->residue_count; ++i) { - Residue *r = p->residue_config+i; - if (r->classdata) { - for (j=0; j < p->codebooks[r->classbook].entries; ++j) - setup_free(p, r->classdata[j]); - setup_free(p, r->classdata); - } - setup_free(p, r->residue_books); - } - } + if (p->residue_config) { + for (i = 0; i < p->residue_count; ++i) { + Residue* r = p->residue_config + i; + if (r->classdata) { + for (j = 0; j < p->codebooks[r->classbook].entries; ++j) + setup_free(p, r->classdata[j]); + setup_free(p, r->classdata); + } + setup_free(p, r->residue_books); + } + } - if (p->codebooks) { - CHECK(p); - for (i=0; i < p->codebook_count; ++i) { - Codebook *c = p->codebooks + i; - setup_free(p, c->codeword_lengths); - setup_free(p, c->multiplicands); - setup_free(p, c->codewords); - setup_free(p, c->sorted_codewords); - - setup_free(p, c->sorted_values ? c->sorted_values-1 : NULL); - } - setup_free(p, p->codebooks); - } - setup_free(p, p->floor_config); - setup_free(p, p->residue_config); - if (p->mapping) { - for (i=0; i < p->mapping_count; ++i) - setup_free(p, p->mapping[i].chan); - setup_free(p, p->mapping); - } - CHECK(p); - for (i=0; i < p->channels && i < STB_VORBIS_MAX_CHANNELS; ++i) { - setup_free(p, p->channel_buffers[i]); - setup_free(p, p->previous_window[i]); - #ifdef STB_VORBIS_NO_DEFER_FLOOR - setup_free(p, p->floor_buffers[i]); - #endif - setup_free(p, p->finalY[i]); - } - for (i=0; i < 2; ++i) { - setup_free(p, p->A[i]); - setup_free(p, p->B[i]); - setup_free(p, p->C[i]); - setup_free(p, p->window[i]); - setup_free(p, p->bit_reverse[i]); - } - #ifndef STB_VORBIS_NO_STDIO - if (p->close_on_free) fclose(p->f); - #endif + if (p->codebooks) { + CHECK(p); + for (i = 0; i < p->codebook_count; ++i) { + Codebook* c = p->codebooks + i; + setup_free(p, c->codeword_lengths); + setup_free(p, c->multiplicands); + setup_free(p, c->codewords); + setup_free(p, c->sorted_codewords); + + setup_free(p, c->sorted_values ? c->sorted_values - 1 : NULL); + } + setup_free(p, p->codebooks); + } + setup_free(p, p->floor_config); + setup_free(p, p->residue_config); + if (p->mapping) { + for (i = 0; i < p->mapping_count; ++i) + setup_free(p, p->mapping[i].chan); + setup_free(p, p->mapping); + } + CHECK(p); + for (i = 0; i < p->channels && i < STB_VORBIS_MAX_CHANNELS; ++i) { + setup_free(p, p->channel_buffers[i]); + setup_free(p, p->previous_window[i]); +#ifdef STB_VORBIS_NO_DEFER_FLOOR + setup_free(p, p->floor_buffers[i]); +#endif + setup_free(p, p->finalY[i]); + } + for (i = 0; i < 2; ++i) { + setup_free(p, p->A[i]); + setup_free(p, p->B[i]); + setup_free(p, p->C[i]); + setup_free(p, p->window[i]); + setup_free(p, p->bit_reverse[i]); + } +#ifndef STB_VORBIS_NO_STDIO + if (p->close_on_free) fclose(p->f); +#endif } -void stb_vorbis_close(stb_vorbis *p) -{ - if (p == NULL) return; - vorbis_deinit(p); - setup_free(p,p); +void stb_vorbis_close(stb_vorbis* p) { + if (p == NULL) return; + vorbis_deinit(p); + setup_free(p, p); } -static void vorbis_init(stb_vorbis *p, const stb_vorbis_alloc *z) -{ - memset(p, 0, sizeof(*p)); - if (z) { - p->alloc = *z; - p->alloc.alloc_buffer_length_in_bytes &= ~7; - p->temp_offset = p->alloc.alloc_buffer_length_in_bytes; - } - p->eof = 0; - p->error = VORBIS__no_error; - p->stream = NULL; - p->codebooks = NULL; - p->page_crc_tests = -1; - #ifndef STB_VORBIS_NO_STDIO - p->close_on_free = FALSE; - p->f = NULL; - #endif +static void vorbis_init(stb_vorbis* p, const stb_vorbis_alloc* z) { + memset(p, 0, sizeof(*p)); + if (z) { + p->alloc = *z; + p->alloc.alloc_buffer_length_in_bytes &= ~7; + p->temp_offset = p->alloc.alloc_buffer_length_in_bytes; + } + p->eof = 0; + p->error = VORBIS__no_error; + p->stream = NULL; + p->codebooks = NULL; + p->page_crc_tests = -1; +#ifndef STB_VORBIS_NO_STDIO + p->close_on_free = FALSE; + p->f = NULL; +#endif } -int stb_vorbis_get_sample_offset(stb_vorbis *f) -{ - if (f->current_loc_valid) - return f->current_loc; - else - return -1; +int stb_vorbis_get_sample_offset(stb_vorbis* f) { + if (f->current_loc_valid) + return f->current_loc; + else + return -1; } -stb_vorbis_info stb_vorbis_get_info(stb_vorbis *f) -{ - stb_vorbis_info d; - d.channels = f->channels; - d.sample_rate = f->sample_rate; - d.setup_memory_required = f->setup_memory_required; - d.setup_temp_memory_required = f->setup_temp_memory_required; - d.temp_memory_required = f->temp_memory_required; - d.max_frame_size = f->blocksize_1 >> 1; - return d; +stb_vorbis_info stb_vorbis_get_info(stb_vorbis* f) { + stb_vorbis_info d; + d.channels = f->channels; + d.sample_rate = f->sample_rate; + d.setup_memory_required = f->setup_memory_required; + d.setup_temp_memory_required = f->setup_temp_memory_required; + d.temp_memory_required = f->temp_memory_required; + d.max_frame_size = f->blocksize_1 >> 1; + return d; } -stb_vorbis_comment stb_vorbis_get_comment(stb_vorbis *f) -{ - stb_vorbis_comment d; - d.vendor = f->vendor; - d.comment_list_length = f->comment_list_length; - d.comment_list = f->comment_list; - return d; +stb_vorbis_comment stb_vorbis_get_comment(stb_vorbis* f) { + stb_vorbis_comment d; + d.vendor = f->vendor; + d.comment_list_length = f->comment_list_length; + d.comment_list = f->comment_list; + return d; } -int stb_vorbis_get_error(stb_vorbis *f) -{ - int e = f->error; - f->error = VORBIS__no_error; - return e; +int stb_vorbis_get_error(stb_vorbis* f) { + int e = f->error; + f->error = VORBIS__no_error; + return e; } -static stb_vorbis * vorbis_alloc(stb_vorbis *f) -{ - stb_vorbis *p = (stb_vorbis *) setup_malloc(f, sizeof(*p)); - return p; +static stb_vorbis* vorbis_alloc(stb_vorbis* f) { + stb_vorbis* p = (stb_vorbis*)setup_malloc(f, sizeof(*p)); + return p; } #ifndef STB_VORBIS_NO_PUSHDATA_API -void stb_vorbis_flush_pushdata(stb_vorbis *f) -{ - f->previous_length = 0; - f->page_crc_tests = 0; - f->discard_samples_deferred = 0; - f->current_loc_valid = FALSE; - f->first_decode = FALSE; - f->samples_output = 0; - f->channel_buffer_start = 0; - f->channel_buffer_end = 0; +void stb_vorbis_flush_pushdata(stb_vorbis* f) { + f->previous_length = 0; + f->page_crc_tests = 0; + f->discard_samples_deferred = 0; + f->current_loc_valid = FALSE; + f->first_decode = FALSE; + f->samples_output = 0; + f->channel_buffer_start = 0; + f->channel_buffer_end = 0; } -static int vorbis_search_for_page_pushdata(vorb *f, uint8 *data, int data_len) -{ - int i,n; - for (i=0; i < f->page_crc_tests; ++i) - f->scan[i].bytes_done = 0; +static int vorbis_search_for_page_pushdata(vorb* f, uint8* data, int data_len) { + int i, n; + for (i = 0; i < f->page_crc_tests; ++i) f->scan[i].bytes_done = 0; - if (f->page_crc_tests < STB_VORBIS_PUSHDATA_CRC_COUNT) { - if (data_len < 4) return 0; - data_len -= 3; - - for (i=0; i < data_len; ++i) { - if (data[i] == 0x4f) { - if (0==memcmp(data+i, ogg_page_header, 4)) { - int j,len; - uint32 crc; - - if (i+26 >= data_len || i+27+data[i+26] >= data_len) { - - data_len = i; - break; - } - - len = 27 + data[i+26]; - for (j=0; j < data[i+26]; ++j) - len += data[i+27+j]; - - crc = 0; - for (j=0; j < 22; ++j) - crc = crc32_update(crc, data[i+j]); - - for ( ; j < 26; ++j) - crc = crc32_update(crc, 0); - - n = f->page_crc_tests++; - f->scan[n].bytes_left = len-j; - f->scan[n].crc_so_far = crc; - f->scan[n].goal_crc = data[i+22] + (data[i+23] << 8) + (data[i+24]<<16) + (data[i+25]<<24); - - if (data[i+27+data[i+26]-1] == 255) - f->scan[n].sample_loc = ~0; - else - f->scan[n].sample_loc = data[i+6] + (data[i+7] << 8) + (data[i+ 8]<<16) + (data[i+ 9]<<24); - f->scan[n].bytes_done = i+j; - if (f->page_crc_tests == STB_VORBIS_PUSHDATA_CRC_COUNT) - break; - + if (f->page_crc_tests < STB_VORBIS_PUSHDATA_CRC_COUNT) { + if (data_len < 4) return 0; + data_len -= 3; + + for (i = 0; i < data_len; ++i) { + if (data[i] == 0x4f) { + if (0 == memcmp(data + i, ogg_page_header, 4)) { + int j, len; + uint32 crc; + + if (i + 26 >= data_len || + i + 27 + data[i + 26] >= data_len) { + data_len = i; + break; + } + + len = 27 + data[i + 26]; + for (j = 0; j < data[i + 26]; ++j) len += data[i + 27 + j]; + + crc = 0; + for (j = 0; j < 22; ++j) + crc = crc32_update(crc, data[i + j]); + + for (; j < 26; ++j) crc = crc32_update(crc, 0); + + n = f->page_crc_tests++; + f->scan[n].bytes_left = len - j; + f->scan[n].crc_so_far = crc; + f->scan[n].goal_crc = data[i + 22] + (data[i + 23] << 8) + + (data[i + 24] << 16) + + (data[i + 25] << 24); + + if (data[i + 27 + data[i + 26] - 1] == 255) + f->scan[n].sample_loc = ~0; + else + f->scan[n].sample_loc = + data[i + 6] + (data[i + 7] << 8) + + (data[i + 8] << 16) + (data[i + 9] << 24); + f->scan[n].bytes_done = i + j; + if (f->page_crc_tests == STB_VORBIS_PUSHDATA_CRC_COUNT) + break; + } } - } - } - } + } + } - for (i=0; i < f->page_crc_tests;) { - uint32 crc; - int j; - int n = f->scan[i].bytes_done; - int m = f->scan[i].bytes_left; - if (m > data_len - n) m = data_len - n; - - crc = f->scan[i].crc_so_far; - for (j=0; j < m; ++j) - crc = crc32_update(crc, data[n+j]); - f->scan[i].bytes_left -= m; - f->scan[i].crc_so_far = crc; - if (f->scan[i].bytes_left == 0) { - - if (f->scan[i].crc_so_far == f->scan[i].goal_crc) { - - data_len = n+m; - f->page_crc_tests = -1; - f->previous_length = 0; - f->next_seg = -1; - f->current_loc = f->scan[i].sample_loc; - - f->current_loc_valid = f->current_loc != ~0U; - return data_len; - } - - f->scan[i] = f->scan[--f->page_crc_tests]; - } else { - ++i; - } - } + for (i = 0; i < f->page_crc_tests;) { + uint32 crc; + int j; + int n = f->scan[i].bytes_done; + int m = f->scan[i].bytes_left; + if (m > data_len - n) m = data_len - n; - return data_len; + crc = f->scan[i].crc_so_far; + for (j = 0; j < m; ++j) crc = crc32_update(crc, data[n + j]); + f->scan[i].bytes_left -= m; + f->scan[i].crc_so_far = crc; + if (f->scan[i].bytes_left == 0) { + if (f->scan[i].crc_so_far == f->scan[i].goal_crc) { + data_len = n + m; + f->page_crc_tests = -1; + f->previous_length = 0; + f->next_seg = -1; + f->current_loc = f->scan[i].sample_loc; + + f->current_loc_valid = f->current_loc != ~0U; + return data_len; + } + + f->scan[i] = f->scan[--f->page_crc_tests]; + } else { + ++i; + } + } + + return data_len; } -int stb_vorbis_decode_frame_pushdata( - stb_vorbis *f, - const uint8 *data, int data_len, - int *channels, - float ***output, - int *samples - ) -{ - int i; - int len,right,left; +int stb_vorbis_decode_frame_pushdata(stb_vorbis* f, const uint8* data, + int data_len, int* channels, + float*** output, int* samples) { + int i; + int len, right, left; - if (!IS_PUSH_MODE(f)) return error(f, VORBIS_invalid_api_mixing); + if (!IS_PUSH_MODE(f)) return error(f, VORBIS_invalid_api_mixing); - if (f->page_crc_tests >= 0) { - *samples = 0; - return vorbis_search_for_page_pushdata(f, (uint8 *) data, data_len); - } + if (f->page_crc_tests >= 0) { + *samples = 0; + return vorbis_search_for_page_pushdata(f, (uint8*)data, data_len); + } - f->stream = (uint8 *) data; - f->stream_end = (uint8 *) data + data_len; - f->error = VORBIS__no_error; + f->stream = (uint8*)data; + f->stream_end = (uint8*)data + data_len; + f->error = VORBIS__no_error; - if (!is_whole_packet_present(f)) { - *samples = 0; - return 0; - } + if (!is_whole_packet_present(f)) { + *samples = 0; + return 0; + } - if (!vorbis_decode_packet(f, &len, &left, &right)) { - - enum STBVorbisError error = f->error; - if (error == VORBIS_bad_packet_type) { - - f->error = VORBIS__no_error; - while (get8_packet(f) != EOP) - if (f->eof) break; - *samples = 0; - return (int) (f->stream - data); - } - if (error == VORBIS_continued_packet_flag_invalid) { - if (f->previous_length == 0) { - + if (!vorbis_decode_packet(f, &len, &left, &right)) { + enum STBVorbisError error = f->error; + if (error == VORBIS_bad_packet_type) { f->error = VORBIS__no_error; while (get8_packet(f) != EOP) - if (f->eof) break; + if (f->eof) break; *samples = 0; - return (int) (f->stream - data); - } - } - - stb_vorbis_flush_pushdata(f); - - f->error = error; - *samples = 0; - return 1; - } + return (int)(f->stream - data); + } + if (error == VORBIS_continued_packet_flag_invalid) { + if (f->previous_length == 0) { + f->error = VORBIS__no_error; + while (get8_packet(f) != EOP) + if (f->eof) break; + *samples = 0; + return (int)(f->stream - data); + } + } - len = vorbis_finish_frame(f, len, left, right); - for (i=0; i < f->channels; ++i) - f->outputs[i] = f->channel_buffers[i] + left; + stb_vorbis_flush_pushdata(f); - if (channels) *channels = f->channels; - *samples = len; - *output = f->outputs; - return (int) (f->stream - data); + f->error = error; + *samples = 0; + return 1; + } + + len = vorbis_finish_frame(f, len, left, right); + for (i = 0; i < f->channels; ++i) + f->outputs[i] = f->channel_buffers[i] + left; + + if (channels) *channels = f->channels; + *samples = len; + *output = f->outputs; + return (int)(f->stream - data); } -stb_vorbis *stb_vorbis_open_pushdata( - const unsigned char *data, int data_len, - int *data_used, - int *error, const stb_vorbis_alloc *alloc) -{ - stb_vorbis *f, p; - vorbis_init(&p, alloc); - p.stream = (uint8 *) data; - p.stream_end = (uint8 *) data + data_len; - p.push_mode = TRUE; - if (!start_decoder(&p)) { - if (p.eof) - *error = VORBIS_need_more_data; - else - *error = p.error; - vorbis_deinit(&p); - return NULL; - } - f = vorbis_alloc(&p); - if (f) { - *f = p; - *data_used = (int) (f->stream - data); - *error = 0; - return f; - } else { - vorbis_deinit(&p); - return NULL; - } +stb_vorbis* stb_vorbis_open_pushdata(const unsigned char* data, int data_len, + int* data_used, int* error, + const stb_vorbis_alloc* alloc) { + stb_vorbis *f, p; + vorbis_init(&p, alloc); + p.stream = (uint8*)data; + p.stream_end = (uint8*)data + data_len; + p.push_mode = TRUE; + if (!start_decoder(&p)) { + if (p.eof) + *error = VORBIS_need_more_data; + else + *error = p.error; + vorbis_deinit(&p); + return NULL; + } + f = vorbis_alloc(&p); + if (f) { + *f = p; + *data_used = (int)(f->stream - data); + *error = 0; + return f; + } else { + vorbis_deinit(&p); + return NULL; + } } -#endif +#endif -unsigned int stb_vorbis_get_file_offset(stb_vorbis *f) -{ - #ifndef STB_VORBIS_NO_PUSHDATA_API - if (f->push_mode) return 0; - #endif - if (USE_MEMORY(f)) return (unsigned int) (f->stream - f->stream_start); - #ifndef STB_VORBIS_NO_STDIO - return (unsigned int) (ftell(f->f) - f->f_start); - #endif +unsigned int stb_vorbis_get_file_offset(stb_vorbis* f) { +#ifndef STB_VORBIS_NO_PUSHDATA_API + if (f->push_mode) return 0; +#endif + if (USE_MEMORY(f)) return (unsigned int)(f->stream - f->stream_start); +#ifndef STB_VORBIS_NO_STDIO + return (unsigned int)(ftell(f->f) - f->f_start); +#endif } #ifndef STB_VORBIS_NO_PULLDATA_API -static uint32 vorbis_find_page(stb_vorbis *f, uint32 *end, uint32 *last) -{ - for(;;) { - int n; - if (f->eof) return 0; - n = get8(f); - if (n == 0x4f) { - unsigned int retry_loc = stb_vorbis_get_file_offset(f); - int i; - - if (retry_loc - 25 > f->stream_len) - return 0; - - for (i=1; i < 4; ++i) - if (get8(f) != ogg_page_header[i]) - break; - if (f->eof) return 0; - if (i == 4) { - uint8 header[27]; - uint32 i, crc, goal, len; - for (i=0; i < 4; ++i) - header[i] = ogg_page_header[i]; - for (; i < 27; ++i) - header[i] = get8(f); +static uint32 vorbis_find_page(stb_vorbis* f, uint32* end, uint32* last) { + for (;;) { + int n; + if (f->eof) return 0; + n = get8(f); + if (n == 0x4f) { + unsigned int retry_loc = stb_vorbis_get_file_offset(f); + int i; + + if (retry_loc - 25 > f->stream_len) return 0; + + for (i = 1; i < 4; ++i) + if (get8(f) != ogg_page_header[i]) break; if (f->eof) return 0; - if (header[4] != 0) goto invalid; - goal = header[22] + (header[23] << 8) + (header[24]<<16) + ((uint32)header[25]<<24); - for (i=22; i < 26; ++i) - header[i] = 0; - crc = 0; - for (i=0; i < 27; ++i) - crc = crc32_update(crc, header[i]); - len = 0; - for (i=0; i < header[26]; ++i) { - int s = get8(f); - crc = crc32_update(crc, s); - len += s; + if (i == 4) { + uint8 header[27]; + uint32 i, crc, goal, len; + for (i = 0; i < 4; ++i) header[i] = ogg_page_header[i]; + for (; i < 27; ++i) header[i] = get8(f); + if (f->eof) return 0; + if (header[4] != 0) goto invalid; + goal = header[22] + (header[23] << 8) + (header[24] << 16) + + ((uint32)header[25] << 24); + for (i = 22; i < 26; ++i) header[i] = 0; + crc = 0; + for (i = 0; i < 27; ++i) crc = crc32_update(crc, header[i]); + len = 0; + for (i = 0; i < header[26]; ++i) { + int s = get8(f); + crc = crc32_update(crc, s); + len += s; + } + if (len && f->eof) return 0; + for (i = 0; i < len; ++i) crc = crc32_update(crc, get8(f)); + + if (crc == goal) { + if (end) *end = stb_vorbis_get_file_offset(f); + if (last) { + if (header[5] & 0x04) + *last = 1; + else + *last = 0; + } + set_file_offset(f, retry_loc - 1); + return 1; + } } - if (len && f->eof) return 0; - for (i=0; i < len; ++i) - crc = crc32_update(crc, get8(f)); - - if (crc == goal) { - - if (end) - *end = stb_vorbis_get_file_offset(f); - if (last) { - if (header[5] & 0x04) - *last = 1; - else - *last = 0; - } - set_file_offset(f, retry_loc-1); - return 1; - } - } invalid: - - set_file_offset(f, retry_loc); - } - } + + set_file_offset(f, retry_loc); + } + } } -#define SAMPLE_unknown 0xffffffff +#define SAMPLE_unknown 0xffffffff -static int get_seek_page_info(stb_vorbis *f, ProbedPage *z) -{ - uint8 header[27], lacing[255]; - int i,len; +static int get_seek_page_info(stb_vorbis* f, ProbedPage* z) { + uint8 header[27], lacing[255]; + int i, len; - z->page_start = stb_vorbis_get_file_offset(f); + z->page_start = stb_vorbis_get_file_offset(f); - getn(f, header, 27); - if (header[0] != 'O' || header[1] != 'g' || header[2] != 'g' || header[3] != 'S') - return 0; - getn(f, lacing, header[26]); + getn(f, header, 27); + if (header[0] != 'O' || header[1] != 'g' || header[2] != 'g' || + header[3] != 'S') + return 0; + getn(f, lacing, header[26]); - len = 0; - for (i=0; i < header[26]; ++i) - len += lacing[i]; + len = 0; + for (i = 0; i < header[26]; ++i) len += lacing[i]; - z->page_end = z->page_start + 27 + header[26] + len; + z->page_end = z->page_start + 27 + header[26] + len; - z->last_decoded_sample = header[6] + (header[7] << 8) + (header[8] << 16) + (header[9] << 24); + z->last_decoded_sample = + header[6] + (header[7] << 8) + (header[8] << 16) + (header[9] << 24); - set_file_offset(f, z->page_start); - return 1; + set_file_offset(f, z->page_start); + return 1; } -static int go_to_page_before(stb_vorbis *f, unsigned int limit_offset) -{ - unsigned int previous_safe, end; +static int go_to_page_before(stb_vorbis* f, unsigned int limit_offset) { + unsigned int previous_safe, end; - if (limit_offset >= 65536 && limit_offset-65536 >= f->first_audio_page_offset) - previous_safe = limit_offset - 65536; - else - previous_safe = f->first_audio_page_offset; + if (limit_offset >= 65536 && + limit_offset - 65536 >= f->first_audio_page_offset) + previous_safe = limit_offset - 65536; + else + previous_safe = f->first_audio_page_offset; - set_file_offset(f, previous_safe); + set_file_offset(f, previous_safe); - while (vorbis_find_page(f, &end, NULL)) { - if (end >= limit_offset && stb_vorbis_get_file_offset(f) < limit_offset) - return 1; - set_file_offset(f, end); - } + while (vorbis_find_page(f, &end, NULL)) { + if (end >= limit_offset && stb_vorbis_get_file_offset(f) < limit_offset) + return 1; + set_file_offset(f, end); + } - return 0; + return 0; } -static int seek_to_sample_coarse(stb_vorbis *f, uint32 sample_number) -{ - ProbedPage left, right, mid; - int i, start_seg_with_known_loc, end_pos, page_start; - uint32 delta, stream_length, padding, last_sample_limit; - double offset = 0.0, bytes_per_sample = 0.0; - int probe = 0; +static int seek_to_sample_coarse(stb_vorbis* f, uint32 sample_number) { + ProbedPage left, right, mid; + int i, start_seg_with_known_loc, end_pos, page_start; + uint32 delta, stream_length, padding, last_sample_limit; + double offset = 0.0, bytes_per_sample = 0.0; + int probe = 0; - stream_length = stb_vorbis_stream_length_in_samples(f); - if (stream_length == 0) return error(f, VORBIS_seek_without_length); - if (sample_number > stream_length) return error(f, VORBIS_seek_invalid); + stream_length = stb_vorbis_stream_length_in_samples(f); + if (stream_length == 0) return error(f, VORBIS_seek_without_length); + if (sample_number > stream_length) return error(f, VORBIS_seek_invalid); - padding = ((f->blocksize_1 - f->blocksize_0) >> 2); - if (sample_number < padding) - last_sample_limit = 0; - else - last_sample_limit = sample_number - padding; + padding = ((f->blocksize_1 - f->blocksize_0) >> 2); + if (sample_number < padding) + last_sample_limit = 0; + else + last_sample_limit = sample_number - padding; - left = f->p_first; - while (left.last_decoded_sample == ~0U) { - - set_file_offset(f, left.page_end); - if (!get_seek_page_info(f, &left)) goto error; - } + left = f->p_first; + while (left.last_decoded_sample == ~0U) { + set_file_offset(f, left.page_end); + if (!get_seek_page_info(f, &left)) goto error; + } - right = f->p_last; - assert(right.last_decoded_sample != ~0U); + right = f->p_last; + assert(right.last_decoded_sample != ~0U); - if (last_sample_limit <= left.last_decoded_sample) { - if (stb_vorbis_seek_start(f)) { - if (f->current_loc > sample_number) - return error(f, VORBIS_seek_failed); - return 1; - } - return 0; - } + if (last_sample_limit <= left.last_decoded_sample) { + if (stb_vorbis_seek_start(f)) { + if (f->current_loc > sample_number) + return error(f, VORBIS_seek_failed); + return 1; + } + return 0; + } - while (left.page_end != right.page_start) { - assert(left.page_end < right.page_start); - - delta = right.page_start - left.page_end; - if (delta <= 65536) { - - set_file_offset(f, left.page_end); - } else { - if (probe < 2) { - if (probe == 0) { - - double data_bytes = right.page_end - left.page_start; - bytes_per_sample = data_bytes / right.last_decoded_sample; - offset = left.page_start + bytes_per_sample * (last_sample_limit - left.last_decoded_sample); + while (left.page_end != right.page_start) { + assert(left.page_end < right.page_start); + + delta = right.page_start - left.page_end; + if (delta <= 65536) { + set_file_offset(f, left.page_end); + } else { + if (probe < 2) { + if (probe == 0) { + double data_bytes = right.page_end - left.page_start; + bytes_per_sample = data_bytes / right.last_decoded_sample; + offset = left.page_start + + bytes_per_sample * + (last_sample_limit - left.last_decoded_sample); + } else { + double error = + ((double)last_sample_limit - mid.last_decoded_sample) * + bytes_per_sample; + if (error >= 0 && error < 8000) error = 8000; + if (error < 0 && error > -8000) error = -8000; + offset += error * 2; + } + + if (offset < left.page_end) offset = left.page_end; + if (offset > right.page_start - 65536) + offset = right.page_start - 65536; + + set_file_offset(f, (unsigned int)offset); } else { - - double error = ((double) last_sample_limit - mid.last_decoded_sample) * bytes_per_sample; - if (error >= 0 && error < 8000) error = 8000; - if (error < 0 && error > -8000) error = -8000; - offset += error * 2; + set_file_offset(f, left.page_end + (delta / 2) - 32768); } - if (offset < left.page_end) - offset = left.page_end; - if (offset > right.page_start - 65536) - offset = right.page_start - 65536; + if (!vorbis_find_page(f, NULL, NULL)) goto error; + } - set_file_offset(f, (unsigned int) offset); - } else { - set_file_offset(f, left.page_end + (delta / 2) - 32768); - } + for (;;) { + if (!get_seek_page_info(f, &mid)) goto error; + if (mid.last_decoded_sample != ~0U) break; + set_file_offset(f, mid.page_end); + assert(mid.page_start < right.page_start); + } + if (mid.page_start == right.page_start) { + if (probe >= 2 || delta <= 65536) break; + } else { + if (last_sample_limit < mid.last_decoded_sample) + right = mid; + else + left = mid; + } - if (!vorbis_find_page(f, NULL, NULL)) goto error; - } + ++probe; + } + page_start = left.page_start; + set_file_offset(f, page_start); + if (!start_page(f)) return error(f, VORBIS_seek_failed); + end_pos = f->end_seg_with_known_loc; + assert(end_pos >= 0); - for (;;) { - if (!get_seek_page_info(f, &mid)) goto error; - if (mid.last_decoded_sample != ~0U) break; - set_file_offset(f, mid.page_end); - assert(mid.page_start < right.page_start); - } - if (mid.page_start == right.page_start) { - if (probe >= 2 || delta <= 65536) - break; - } else { - if (last_sample_limit < mid.last_decoded_sample) - right = mid; - else - left = mid; - } + for (;;) { + for (i = end_pos; i > 0; --i) + if (f->segments[i - 1] != 255) break; - ++probe; - } - page_start = left.page_start; - set_file_offset(f, page_start); - if (!start_page(f)) return error(f, VORBIS_seek_failed); - end_pos = f->end_seg_with_known_loc; - assert(end_pos >= 0); + start_seg_with_known_loc = i; - for (;;) { - for (i = end_pos; i > 0; --i) - if (f->segments[i-1] != 255) + if (start_seg_with_known_loc > 0 || + !(f->page_flag & PAGEFLAG_continued_packet)) break; - start_seg_with_known_loc = i; + if (!go_to_page_before(f, page_start)) goto error; - if (start_seg_with_known_loc > 0 || !(f->page_flag & PAGEFLAG_continued_packet)) - break; + page_start = stb_vorbis_get_file_offset(f); + if (!start_page(f)) goto error; + end_pos = f->segment_count - 1; + } + f->current_loc_valid = FALSE; + f->last_seg = FALSE; + f->valid_bits = 0; + f->packet_bytes = 0; + f->bytes_in_seg = 0; + f->previous_length = 0; + f->next_seg = start_seg_with_known_loc; - if (!go_to_page_before(f, page_start)) - goto error; - - page_start = stb_vorbis_get_file_offset(f); - if (!start_page(f)) goto error; - end_pos = f->segment_count - 1; - } - f->current_loc_valid = FALSE; - f->last_seg = FALSE; - f->valid_bits = 0; - f->packet_bytes = 0; - f->bytes_in_seg = 0; - f->previous_length = 0; - f->next_seg = start_seg_with_known_loc; - - for (i = 0; i < start_seg_with_known_loc; i++) - skip(f, f->segments[i]); - if (!vorbis_pump_first_frame(f)) - return 0; - if (f->current_loc > sample_number) - return error(f, VORBIS_seek_failed); - return 1; + for (i = 0; i < start_seg_with_known_loc; i++) skip(f, f->segments[i]); + if (!vorbis_pump_first_frame(f)) return 0; + if (f->current_loc > sample_number) return error(f, VORBIS_seek_failed); + return 1; error: - stb_vorbis_seek_start(f); - return error(f, VORBIS_seek_failed); + stb_vorbis_seek_start(f); + return error(f, VORBIS_seek_failed); } -static int peek_decode_initial(vorb *f, int *p_left_start, int *p_left_end, int *p_right_start, int *p_right_end, int *mode) -{ - int bits_read, bytes_read; +static int peek_decode_initial(vorb* f, int* p_left_start, int* p_left_end, + int* p_right_start, int* p_right_end, + int* mode) { + int bits_read, bytes_read; - if (!vorbis_decode_initial(f, p_left_start, p_left_end, p_right_start, p_right_end, mode)) - return 0; - bits_read = 1 + ilog(f->mode_count-1); - if (f->mode_config[*mode].blockflag) - bits_read += 2; - bytes_read = (bits_read + 7) / 8; + if (!vorbis_decode_initial(f, p_left_start, p_left_end, p_right_start, + p_right_end, mode)) + return 0; + bits_read = 1 + ilog(f->mode_count - 1); + if (f->mode_config[*mode].blockflag) bits_read += 2; + bytes_read = (bits_read + 7) / 8; - f->bytes_in_seg += bytes_read; - f->packet_bytes -= bytes_read; - skip(f, -bytes_read); - if (f->next_seg == -1) - f->next_seg = f->segment_count - 1; - else - f->next_seg--; - f->valid_bits = 0; + f->bytes_in_seg += bytes_read; + f->packet_bytes -= bytes_read; + skip(f, -bytes_read); + if (f->next_seg == -1) + f->next_seg = f->segment_count - 1; + else + f->next_seg--; + f->valid_bits = 0; - return 1; + return 1; } -int stb_vorbis_seek_frame(stb_vorbis *f, unsigned int sample_number) -{ - uint32 max_frame_samples; +int stb_vorbis_seek_frame(stb_vorbis* f, unsigned int sample_number) { + uint32 max_frame_samples; - if (IS_PUSH_MODE(f)) return error(f, VORBIS_invalid_api_mixing); + if (IS_PUSH_MODE(f)) return error(f, VORBIS_invalid_api_mixing); - if (!seek_to_sample_coarse(f, sample_number)) - return 0; + if (!seek_to_sample_coarse(f, sample_number)) return 0; - assert(f->current_loc_valid); - assert(f->current_loc <= sample_number); - max_frame_samples = (f->blocksize_1*3 - f->blocksize_0) >> 2; - while (f->current_loc < sample_number) { - int left_start, left_end, right_start, right_end, mode, frame_samples; - if (!peek_decode_initial(f, &left_start, &left_end, &right_start, &right_end, &mode)) - return error(f, VORBIS_seek_failed); - frame_samples = right_start - left_start; - if (f->current_loc + frame_samples > sample_number) { - return 1; - } else if (f->current_loc + frame_samples + max_frame_samples > sample_number) { - vorbis_pump_first_frame(f); - } else { - f->current_loc += frame_samples; - f->previous_length = 0; - maybe_start_packet(f); - flush_packet(f); - } - } - if (f->current_loc != sample_number) return error(f, VORBIS_seek_failed); - return 1; + assert(f->current_loc_valid); + assert(f->current_loc <= sample_number); + max_frame_samples = (f->blocksize_1 * 3 - f->blocksize_0) >> 2; + while (f->current_loc < sample_number) { + int left_start, left_end, right_start, right_end, mode, frame_samples; + if (!peek_decode_initial(f, &left_start, &left_end, &right_start, + &right_end, &mode)) + return error(f, VORBIS_seek_failed); + frame_samples = right_start - left_start; + if (f->current_loc + frame_samples > sample_number) { + return 1; + } else if (f->current_loc + frame_samples + max_frame_samples > + sample_number) { + vorbis_pump_first_frame(f); + } else { + f->current_loc += frame_samples; + f->previous_length = 0; + maybe_start_packet(f); + flush_packet(f); + } + } + if (f->current_loc != sample_number) return error(f, VORBIS_seek_failed); + return 1; } -int stb_vorbis_seek(stb_vorbis *f, unsigned int sample_number) -{ - if (!stb_vorbis_seek_frame(f, sample_number)) - return 0; +int stb_vorbis_seek(stb_vorbis* f, unsigned int sample_number) { + if (!stb_vorbis_seek_frame(f, sample_number)) return 0; - if (sample_number != f->current_loc) { - int n; - uint32 frame_start = f->current_loc; - stb_vorbis_get_frame_float(f, &n, NULL); - assert(sample_number > frame_start); - assert(f->channel_buffer_start + (int) (sample_number-frame_start) <= f->channel_buffer_end); - f->channel_buffer_start += (sample_number - frame_start); - } + if (sample_number != f->current_loc) { + int n; + uint32 frame_start = f->current_loc; + stb_vorbis_get_frame_float(f, &n, NULL); + assert(sample_number > frame_start); + assert(f->channel_buffer_start + (int)(sample_number - frame_start) <= + f->channel_buffer_end); + f->channel_buffer_start += (sample_number - frame_start); + } - return 1; + return 1; } -int stb_vorbis_seek_start(stb_vorbis *f) -{ - if (IS_PUSH_MODE(f)) { return error(f, VORBIS_invalid_api_mixing); } - set_file_offset(f, f->first_audio_page_offset); - f->previous_length = 0; - f->first_decode = TRUE; - f->next_seg = -1; - return vorbis_pump_first_frame(f); +int stb_vorbis_seek_start(stb_vorbis* f) { + if (IS_PUSH_MODE(f)) { + return error(f, VORBIS_invalid_api_mixing); + } + set_file_offset(f, f->first_audio_page_offset); + f->previous_length = 0; + f->first_decode = TRUE; + f->next_seg = -1; + return vorbis_pump_first_frame(f); } -unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f) -{ - unsigned int restore_offset, previous_safe; - unsigned int end, last_page_loc; +unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis* f) { + unsigned int restore_offset, previous_safe; + unsigned int end, last_page_loc; - if (IS_PUSH_MODE(f)) return error(f, VORBIS_invalid_api_mixing); - if (!f->total_samples) { - unsigned int last; - uint32 lo,hi; - char header[6]; - restore_offset = stb_vorbis_get_file_offset(f); + if (IS_PUSH_MODE(f)) return error(f, VORBIS_invalid_api_mixing); + if (!f->total_samples) { + unsigned int last; + uint32 lo, hi; + char header[6]; + restore_offset = stb_vorbis_get_file_offset(f); - if (f->stream_len >= 65536 && f->stream_len-65536 >= f->first_audio_page_offset) - previous_safe = f->stream_len - 65536; - else - previous_safe = f->first_audio_page_offset; + if (f->stream_len >= 65536 && + f->stream_len - 65536 >= f->first_audio_page_offset) + previous_safe = f->stream_len - 65536; + else + previous_safe = f->first_audio_page_offset; - set_file_offset(f, previous_safe); + set_file_offset(f, previous_safe); - if (!vorbis_find_page(f, &end, &last)) { - f->error = VORBIS_cant_find_last_page; - f->total_samples = 0xffffffff; - goto done; - } - last_page_loc = stb_vorbis_get_file_offset(f); - while (!last) { - set_file_offset(f, end); - if (!vorbis_find_page(f, &end, &last)) { - break; - } - last_page_loc = stb_vorbis_get_file_offset(f); - } + if (!vorbis_find_page(f, &end, &last)) { + f->error = VORBIS_cant_find_last_page; + f->total_samples = 0xffffffff; + goto done; + } + last_page_loc = stb_vorbis_get_file_offset(f); + while (!last) { + set_file_offset(f, end); + if (!vorbis_find_page(f, &end, &last)) { + break; + } + last_page_loc = stb_vorbis_get_file_offset(f); + } - set_file_offset(f, last_page_loc); - getn(f, (unsigned char *)header, 6); - lo = get32(f); - hi = get32(f); - if (lo == 0xffffffff && hi == 0xffffffff) { - f->error = VORBIS_cant_find_last_page; - f->total_samples = SAMPLE_unknown; - goto done; - } - if (hi) - lo = 0xfffffffe; - f->total_samples = lo; + set_file_offset(f, last_page_loc); + getn(f, (unsigned char*)header, 6); + lo = get32(f); + hi = get32(f); + if (lo == 0xffffffff && hi == 0xffffffff) { + f->error = VORBIS_cant_find_last_page; + f->total_samples = SAMPLE_unknown; + goto done; + } + if (hi) lo = 0xfffffffe; + f->total_samples = lo; - f->p_last.page_start = last_page_loc; - f->p_last.page_end = end; - f->p_last.last_decoded_sample = lo; + f->p_last.page_start = last_page_loc; + f->p_last.page_end = end; + f->p_last.last_decoded_sample = lo; - done: - set_file_offset(f, restore_offset); - } - return f->total_samples == SAMPLE_unknown ? 0 : f->total_samples; + done: + set_file_offset(f, restore_offset); + } + return f->total_samples == SAMPLE_unknown ? 0 : f->total_samples; } -float stb_vorbis_stream_length_in_seconds(stb_vorbis *f) -{ - return stb_vorbis_stream_length_in_samples(f) / (float) f->sample_rate; +float stb_vorbis_stream_length_in_seconds(stb_vorbis* f) { + return stb_vorbis_stream_length_in_samples(f) / (float)f->sample_rate; } -int stb_vorbis_get_frame_float(stb_vorbis *f, int *channels, float ***output) -{ - int len, right,left,i; - if (IS_PUSH_MODE(f)) return error(f, VORBIS_invalid_api_mixing); +int stb_vorbis_get_frame_float(stb_vorbis* f, int* channels, float*** output) { + int len, right, left, i; + if (IS_PUSH_MODE(f)) return error(f, VORBIS_invalid_api_mixing); - if (!vorbis_decode_packet(f, &len, &left, &right)) { - f->channel_buffer_start = f->channel_buffer_end = 0; - return 0; - } + if (!vorbis_decode_packet(f, &len, &left, &right)) { + f->channel_buffer_start = f->channel_buffer_end = 0; + return 0; + } - len = vorbis_finish_frame(f, len, left, right); - for (i=0; i < f->channels; ++i) - f->outputs[i] = f->channel_buffers[i] + left; + len = vorbis_finish_frame(f, len, left, right); + for (i = 0; i < f->channels; ++i) + f->outputs[i] = f->channel_buffers[i] + left; - f->channel_buffer_start = left; - f->channel_buffer_end = left+len; + f->channel_buffer_start = left; + f->channel_buffer_end = left + len; - if (channels) *channels = f->channels; - if (output) *output = f->outputs; - return len; + if (channels) *channels = f->channels; + if (output) *output = f->outputs; + return len; } #ifndef STB_VORBIS_NO_STDIO -stb_vorbis * stb_vorbis_open_file_section(FILE *file, int close_on_free, int *error, const stb_vorbis_alloc *alloc, unsigned int length) -{ - stb_vorbis *f, p; - vorbis_init(&p, alloc); - p.f = file; - p.f_start = (uint32) ftell(file); - p.stream_len = length; - p.close_on_free = close_on_free; - if (start_decoder(&p)) { - f = vorbis_alloc(&p); - if (f) { - *f = p; - vorbis_pump_first_frame(f); - return f; - } - } - if (error) *error = p.error; - vorbis_deinit(&p); - return NULL; +stb_vorbis* stb_vorbis_open_file_section(FILE* file, int close_on_free, + int* error, + const stb_vorbis_alloc* alloc, + unsigned int length) { + stb_vorbis *f, p; + vorbis_init(&p, alloc); + p.f = file; + p.f_start = (uint32)ftell(file); + p.stream_len = length; + p.close_on_free = close_on_free; + if (start_decoder(&p)) { + f = vorbis_alloc(&p); + if (f) { + *f = p; + vorbis_pump_first_frame(f); + return f; + } + } + if (error) *error = p.error; + vorbis_deinit(&p); + return NULL; } -stb_vorbis * stb_vorbis_open_file(FILE *file, int close_on_free, int *error, const stb_vorbis_alloc *alloc) -{ - unsigned int len, start; - start = (unsigned int) ftell(file); - fseek(file, 0, SEEK_END); - len = (unsigned int) (ftell(file) - start); - fseek(file, start, SEEK_SET); - return stb_vorbis_open_file_section(file, close_on_free, error, alloc, len); +stb_vorbis* stb_vorbis_open_file(FILE* file, int close_on_free, int* error, + const stb_vorbis_alloc* alloc) { + unsigned int len, start; + start = (unsigned int)ftell(file); + fseek(file, 0, SEEK_END); + len = (unsigned int)(ftell(file) - start); + fseek(file, start, SEEK_SET); + return stb_vorbis_open_file_section(file, close_on_free, error, alloc, len); } -stb_vorbis * stb_vorbis_open_filename(const char *filename, int *error, const stb_vorbis_alloc *alloc) -{ - FILE *f; +stb_vorbis* stb_vorbis_open_filename(const char* filename, int* error, + const stb_vorbis_alloc* alloc) { + FILE* f; #if defined(_WIN32) && defined(__STDC_WANT_SECURE_LIB__) - if (0 != fopen_s(&f, filename, "rb")) - f = NULL; + if (0 != fopen_s(&f, filename, "rb")) f = NULL; #else - f = fopen(filename, "rb"); + f = fopen(filename, "rb"); #endif - if (f) - return stb_vorbis_open_file(f, TRUE, error, alloc); - if (error) *error = VORBIS_file_open_failure; - return NULL; + if (f) return stb_vorbis_open_file(f, TRUE, error, alloc); + if (error) *error = VORBIS_file_open_failure; + return NULL; } -#endif +#endif -stb_vorbis * stb_vorbis_open_memory(const unsigned char *data, int len, int *error, const stb_vorbis_alloc *alloc) -{ - stb_vorbis *f, p; - if (!data) { - if (error) *error = VORBIS_unexpected_eof; - return NULL; - } - vorbis_init(&p, alloc); - p.stream = (uint8 *) data; - p.stream_end = (uint8 *) data + len; - p.stream_start = (uint8 *) p.stream; - p.stream_len = len; - p.push_mode = FALSE; - if (start_decoder(&p)) { - f = vorbis_alloc(&p); - if (f) { - *f = p; - vorbis_pump_first_frame(f); - if (error) *error = VORBIS__no_error; - return f; - } - } - if (error) *error = p.error; - vorbis_deinit(&p); - return NULL; +stb_vorbis* stb_vorbis_open_memory(const unsigned char* data, int len, + int* error, const stb_vorbis_alloc* alloc) { + stb_vorbis *f, p; + if (!data) { + if (error) *error = VORBIS_unexpected_eof; + return NULL; + } + vorbis_init(&p, alloc); + p.stream = (uint8*)data; + p.stream_end = (uint8*)data + len; + p.stream_start = (uint8*)p.stream; + p.stream_len = len; + p.push_mode = FALSE; + if (start_decoder(&p)) { + f = vorbis_alloc(&p); + if (f) { + *f = p; + vorbis_pump_first_frame(f); + if (error) *error = VORBIS__no_error; + return f; + } + } + if (error) *error = p.error; + vorbis_deinit(&p); + return NULL; } #ifndef STB_VORBIS_NO_INTEGER_CONVERSION -#define PLAYBACK_MONO 1 -#define PLAYBACK_LEFT 2 -#define PLAYBACK_RIGHT 4 +#define PLAYBACK_MONO 1 +#define PLAYBACK_LEFT 2 +#define PLAYBACK_RIGHT 4 -#define L (PLAYBACK_LEFT | PLAYBACK_MONO) -#define C (PLAYBACK_LEFT | PLAYBACK_RIGHT | PLAYBACK_MONO) -#define R (PLAYBACK_RIGHT | PLAYBACK_MONO) +#define L (PLAYBACK_LEFT | PLAYBACK_MONO) +#define C (PLAYBACK_LEFT | PLAYBACK_RIGHT | PLAYBACK_MONO) +#define R (PLAYBACK_RIGHT | PLAYBACK_MONO) -static int8 channel_position[7][6] = -{ - { 0 }, - { C }, - { L, R }, - { L, C, R }, - { L, R, L, R }, - { L, C, R, L, R }, - { L, C, R, L, R, C }, +static int8 channel_position[7][6] = { + {0}, + {C}, + {L, R}, + {L, C, R}, + {L, R, L, R}, + {L, C, R, L, R}, + {L, C, R, L, R, C}, }; #ifndef STB_VORBIS_NO_FAST_SCALED_FLOAT - typedef union { - float f; - int i; - } float_conv; - typedef char stb_vorbis_float_size_test[sizeof(float)==4 && sizeof(int) == 4]; - #define FASTDEF(x) float_conv x - - #define MAGIC(SHIFT) (1.5f * (1 << (23-SHIFT)) + 0.5f/(1 << SHIFT)) - #define ADDEND(SHIFT) (((150-SHIFT) << 23) + (1 << 22)) - #define FAST_SCALED_FLOAT_TO_INT(temp,x,s) (temp.f = (x) + MAGIC(s), temp.i - ADDEND(s)) - #define check_endianness() +typedef union { + float f; + int i; +} float_conv; +typedef char stb_vorbis_float_size_test[sizeof(float) == 4 && sizeof(int) == 4]; +#define FASTDEF(x) float_conv x + +#define MAGIC(SHIFT) (1.5f * (1 << (23 - SHIFT)) + 0.5f / (1 << SHIFT)) +#define ADDEND(SHIFT) (((150 - SHIFT) << 23) + (1 << 22)) +#define FAST_SCALED_FLOAT_TO_INT(temp, x, s) \ + (temp.f = (x) + MAGIC(s), temp.i - ADDEND(s)) +#define check_endianness() #else - #define FAST_SCALED_FLOAT_TO_INT(temp,x,s) ((int) ((x) * (1 << (s)))) - #define check_endianness() - #define FASTDEF(x) +#define FAST_SCALED_FLOAT_TO_INT(temp, x, s) ((int)((x) * (1 << (s)))) +#define check_endianness() +#define FASTDEF(x) #endif -static void copy_samples(short *dest, float *src, int len) -{ - int i; - check_endianness(); - for (i=0; i < len; ++i) { - FASTDEF(temp); - int v = FAST_SCALED_FLOAT_TO_INT(temp, src[i],15); - if ((unsigned int) (v + 32768) > 65535) - v = v < 0 ? -32768 : 32767; - dest[i] = v; - } +static void copy_samples(short* dest, float* src, int len) { + int i; + check_endianness(); + for (i = 0; i < len; ++i) { + FASTDEF(temp); + int v = FAST_SCALED_FLOAT_TO_INT(temp, src[i], 15); + if ((unsigned int)(v + 32768) > 65535) v = v < 0 ? -32768 : 32767; + dest[i] = v; + } } -static void compute_samples(int mask, short *output, int num_c, float **data, int d_offset, int len) -{ - #define STB_BUFFER_SIZE 32 - float buffer[STB_BUFFER_SIZE]; - int i,j,o,n = STB_BUFFER_SIZE; - check_endianness(); - for (o = 0; o < len; o += STB_BUFFER_SIZE) { - memset(buffer, 0, sizeof(buffer)); - if (o + n > len) n = len - o; - for (j=0; j < num_c; ++j) { - if (channel_position[num_c][j] & mask) { - for (i=0; i < n; ++i) - buffer[i] += data[j][d_offset+o+i]; - } - } - for (i=0; i < n; ++i) { - FASTDEF(temp); - int v = FAST_SCALED_FLOAT_TO_INT(temp,buffer[i],15); - if ((unsigned int) (v + 32768) > 65535) - v = v < 0 ? -32768 : 32767; - output[o+i] = v; - } - } - #undef STB_BUFFER_SIZE -} - -static void compute_stereo_samples(short *output, int num_c, float **data, int d_offset, int len) -{ - #define STB_BUFFER_SIZE 32 - float buffer[STB_BUFFER_SIZE]; - int i,j,o,n = STB_BUFFER_SIZE >> 1; - - check_endianness(); - for (o = 0; o < len; o += STB_BUFFER_SIZE >> 1) { - - int o2 = o << 1; - memset(buffer, 0, sizeof(buffer)); - if (o + n > len) n = len - o; - for (j=0; j < num_c; ++j) { - int m = channel_position[num_c][j] & (PLAYBACK_LEFT | PLAYBACK_RIGHT); - if (m == (PLAYBACK_LEFT | PLAYBACK_RIGHT)) { - for (i=0; i < n; ++i) { - buffer[i*2+0] += data[j][d_offset+o+i]; - buffer[i*2+1] += data[j][d_offset+o+i]; +static void compute_samples(int mask, short* output, int num_c, float** data, + int d_offset, int len) { +#define STB_BUFFER_SIZE 32 + float buffer[STB_BUFFER_SIZE]; + int i, j, o, n = STB_BUFFER_SIZE; + check_endianness(); + for (o = 0; o < len; o += STB_BUFFER_SIZE) { + memset(buffer, 0, sizeof(buffer)); + if (o + n > len) n = len - o; + for (j = 0; j < num_c; ++j) { + if (channel_position[num_c][j] & mask) { + for (i = 0; i < n; ++i) buffer[i] += data[j][d_offset + o + i]; } - } else if (m == PLAYBACK_LEFT) { - for (i=0; i < n; ++i) { - buffer[i*2+0] += data[j][d_offset+o+i]; - } - } else if (m == PLAYBACK_RIGHT) { - for (i=0; i < n; ++i) { - buffer[i*2+1] += data[j][d_offset+o+i]; - } - } - } - for (i=0; i < (n<<1); ++i) { - FASTDEF(temp); - int v = FAST_SCALED_FLOAT_TO_INT(temp,buffer[i],15); - if ((unsigned int) (v + 32768) > 65535) - v = v < 0 ? -32768 : 32767; - output[o2+i] = v; - } - } - #undef STB_BUFFER_SIZE -} - -static void convert_samples_short(int buf_c, short **buffer, int b_offset, int data_c, float **data, int d_offset, int samples) -{ - int i; - if (buf_c != data_c && buf_c <= 2 && data_c <= 6) { - static int channel_selector[3][2] = { {0}, {PLAYBACK_MONO}, {PLAYBACK_LEFT, PLAYBACK_RIGHT} }; - for (i=0; i < buf_c; ++i) - compute_samples(channel_selector[buf_c][i], buffer[i]+b_offset, data_c, data, d_offset, samples); - } else { - int limit = buf_c < data_c ? buf_c : data_c; - for (i=0; i < limit; ++i) - copy_samples(buffer[i]+b_offset, data[i]+d_offset, samples); - for ( ; i < buf_c; ++i) - memset(buffer[i]+b_offset, 0, sizeof(short) * samples); - } -} - -int stb_vorbis_get_frame_short(stb_vorbis *f, int num_c, short **buffer, int num_samples) -{ - float **output = NULL; - int len = stb_vorbis_get_frame_float(f, NULL, &output); - if (len > num_samples) len = num_samples; - if (len) - convert_samples_short(num_c, buffer, 0, f->channels, output, 0, len); - return len; -} - -static void convert_channels_short_interleaved(int buf_c, short *buffer, int data_c, float **data, int d_offset, int len) -{ - int i; - check_endianness(); - if (buf_c != data_c && buf_c <= 2 && data_c <= 6) { - assert(buf_c == 2); - for (i=0; i < buf_c; ++i) - compute_stereo_samples(buffer, data_c, data, d_offset, len); - } else { - int limit = buf_c < data_c ? buf_c : data_c; - int j; - for (j=0; j < len; ++j) { - for (i=0; i < limit; ++i) { + } + for (i = 0; i < n; ++i) { FASTDEF(temp); - float f = data[i][d_offset+j]; - int v = FAST_SCALED_FLOAT_TO_INT(temp, f,15); - if ((unsigned int) (v + 32768) > 65535) - v = v < 0 ? -32768 : 32767; - *buffer++ = v; - } - for ( ; i < buf_c; ++i) - *buffer++ = 0; - } - } + int v = FAST_SCALED_FLOAT_TO_INT(temp, buffer[i], 15); + if ((unsigned int)(v + 32768) > 65535) v = v < 0 ? -32768 : 32767; + output[o + i] = v; + } + } +#undef STB_BUFFER_SIZE } -int stb_vorbis_get_frame_short_interleaved(stb_vorbis *f, int num_c, short *buffer, int num_shorts) -{ - float **output; - int len; - if (num_c == 1) return stb_vorbis_get_frame_short(f,num_c,&buffer, num_shorts); - len = stb_vorbis_get_frame_float(f, NULL, &output); - if (len) { - if (len*num_c > num_shorts) len = num_shorts / num_c; - convert_channels_short_interleaved(num_c, buffer, f->channels, output, 0, len); - } - return len; +static void compute_stereo_samples(short* output, int num_c, float** data, + int d_offset, int len) { +#define STB_BUFFER_SIZE 32 + float buffer[STB_BUFFER_SIZE]; + int i, j, o, n = STB_BUFFER_SIZE >> 1; + + check_endianness(); + for (o = 0; o < len; o += STB_BUFFER_SIZE >> 1) { + int o2 = o << 1; + memset(buffer, 0, sizeof(buffer)); + if (o + n > len) n = len - o; + for (j = 0; j < num_c; ++j) { + int m = + channel_position[num_c][j] & (PLAYBACK_LEFT | PLAYBACK_RIGHT); + if (m == (PLAYBACK_LEFT | PLAYBACK_RIGHT)) { + for (i = 0; i < n; ++i) { + buffer[i * 2 + 0] += data[j][d_offset + o + i]; + buffer[i * 2 + 1] += data[j][d_offset + o + i]; + } + } else if (m == PLAYBACK_LEFT) { + for (i = 0; i < n; ++i) { + buffer[i * 2 + 0] += data[j][d_offset + o + i]; + } + } else if (m == PLAYBACK_RIGHT) { + for (i = 0; i < n; ++i) { + buffer[i * 2 + 1] += data[j][d_offset + o + i]; + } + } + } + for (i = 0; i < (n << 1); ++i) { + FASTDEF(temp); + int v = FAST_SCALED_FLOAT_TO_INT(temp, buffer[i], 15); + if ((unsigned int)(v + 32768) > 65535) v = v < 0 ? -32768 : 32767; + output[o2 + i] = v; + } + } +#undef STB_BUFFER_SIZE } -int stb_vorbis_get_samples_short_interleaved(stb_vorbis *f, int channels, short *buffer, int num_shorts) -{ - float **outputs; - int len = num_shorts / channels; - int n=0; - while (n < len) { - int k = f->channel_buffer_end - f->channel_buffer_start; - if (n+k >= len) k = len - n; - if (k) - convert_channels_short_interleaved(channels, buffer, f->channels, f->channel_buffers, f->channel_buffer_start, k); - buffer += k*channels; - n += k; - f->channel_buffer_start += k; - if (n == len) break; - if (!stb_vorbis_get_frame_float(f, NULL, &outputs)) break; - } - return n; +static void convert_samples_short(int buf_c, short** buffer, int b_offset, + int data_c, float** data, int d_offset, + int samples) { + int i; + if (buf_c != data_c && buf_c <= 2 && data_c <= 6) { + static int channel_selector[3][2] = { + {0}, {PLAYBACK_MONO}, {PLAYBACK_LEFT, PLAYBACK_RIGHT}}; + for (i = 0; i < buf_c; ++i) + compute_samples(channel_selector[buf_c][i], buffer[i] + b_offset, + data_c, data, d_offset, samples); + } else { + int limit = buf_c < data_c ? buf_c : data_c; + for (i = 0; i < limit; ++i) + copy_samples(buffer[i] + b_offset, data[i] + d_offset, samples); + for (; i < buf_c; ++i) + memset(buffer[i] + b_offset, 0, sizeof(short) * samples); + } } -int stb_vorbis_get_samples_short(stb_vorbis *f, int channels, short **buffer, int len) -{ - float **outputs; - int n=0; - while (n < len) { - int k = f->channel_buffer_end - f->channel_buffer_start; - if (n+k >= len) k = len - n; - if (k) - convert_samples_short(channels, buffer, n, f->channels, f->channel_buffers, f->channel_buffer_start, k); - n += k; - f->channel_buffer_start += k; - if (n == len) break; - if (!stb_vorbis_get_frame_float(f, NULL, &outputs)) break; - } - return n; +int stb_vorbis_get_frame_short(stb_vorbis* f, int num_c, short** buffer, + int num_samples) { + float** output = NULL; + int len = stb_vorbis_get_frame_float(f, NULL, &output); + if (len > num_samples) len = num_samples; + if (len) + convert_samples_short(num_c, buffer, 0, f->channels, output, 0, len); + return len; +} + +static void convert_channels_short_interleaved(int buf_c, short* buffer, + int data_c, float** data, + int d_offset, int len) { + int i; + check_endianness(); + if (buf_c != data_c && buf_c <= 2 && data_c <= 6) { + assert(buf_c == 2); + for (i = 0; i < buf_c; ++i) + compute_stereo_samples(buffer, data_c, data, d_offset, len); + } else { + int limit = buf_c < data_c ? buf_c : data_c; + int j; + for (j = 0; j < len; ++j) { + for (i = 0; i < limit; ++i) { + FASTDEF(temp); + float f = data[i][d_offset + j]; + int v = FAST_SCALED_FLOAT_TO_INT(temp, f, 15); + if ((unsigned int)(v + 32768) > 65535) + v = v < 0 ? -32768 : 32767; + *buffer++ = v; + } + for (; i < buf_c; ++i) *buffer++ = 0; + } + } +} + +int stb_vorbis_get_frame_short_interleaved(stb_vorbis* f, int num_c, + short* buffer, int num_shorts) { + float** output; + int len; + if (num_c == 1) + return stb_vorbis_get_frame_short(f, num_c, &buffer, num_shorts); + len = stb_vorbis_get_frame_float(f, NULL, &output); + if (len) { + if (len * num_c > num_shorts) len = num_shorts / num_c; + convert_channels_short_interleaved(num_c, buffer, f->channels, output, + 0, len); + } + return len; +} + +int stb_vorbis_get_samples_short_interleaved(stb_vorbis* f, int channels, + short* buffer, int num_shorts) { + float** outputs; + int len = num_shorts / channels; + int n = 0; + while (n < len) { + int k = f->channel_buffer_end - f->channel_buffer_start; + if (n + k >= len) k = len - n; + if (k) + convert_channels_short_interleaved(channels, buffer, f->channels, + f->channel_buffers, + f->channel_buffer_start, k); + buffer += k * channels; + n += k; + f->channel_buffer_start += k; + if (n == len) break; + if (!stb_vorbis_get_frame_float(f, NULL, &outputs)) break; + } + return n; +} + +int stb_vorbis_get_samples_short(stb_vorbis* f, int channels, short** buffer, + int len) { + float** outputs; + int n = 0; + while (n < len) { + int k = f->channel_buffer_end - f->channel_buffer_start; + if (n + k >= len) k = len - n; + if (k) + convert_samples_short(channels, buffer, n, f->channels, + f->channel_buffers, f->channel_buffer_start, + k); + n += k; + f->channel_buffer_start += k; + if (n == len) break; + if (!stb_vorbis_get_frame_float(f, NULL, &outputs)) break; + } + return n; } #ifndef STB_VORBIS_NO_STDIO -int stb_vorbis_decode_filename(const char *filename, int *channels, int *sample_rate, short **output) -{ - int data_len, offset, total, limit, error; - short *data; - stb_vorbis *v = stb_vorbis_open_filename(filename, &error, NULL); - if (v == NULL) return -1; - limit = v->channels * 4096; - *channels = v->channels; - if (sample_rate) - *sample_rate = v->sample_rate; - offset = data_len = 0; - total = limit; - data = (short *) malloc(total * sizeof(*data)); - if (data == NULL) { - stb_vorbis_close(v); - return -2; - } - for (;;) { - int n = stb_vorbis_get_frame_short_interleaved(v, v->channels, data+offset, total-offset); - if (n == 0) break; - data_len += n; - offset += n * v->channels; - if (offset + limit > total) { - short *data2; - total *= 2; - data2 = (short *) realloc(data, total * sizeof(*data)); - if (data2 == NULL) { - free(data); - stb_vorbis_close(v); - return -2; - } - data = data2; - } - } - *output = data; - stb_vorbis_close(v); - return data_len; +int stb_vorbis_decode_filename(const char* filename, int* channels, + int* sample_rate, short** output) { + int data_len, offset, total, limit, error; + short* data; + stb_vorbis* v = stb_vorbis_open_filename(filename, &error, NULL); + if (v == NULL) return -1; + limit = v->channels * 4096; + *channels = v->channels; + if (sample_rate) *sample_rate = v->sample_rate; + offset = data_len = 0; + total = limit; + data = (short*)malloc(total * sizeof(*data)); + if (data == NULL) { + stb_vorbis_close(v); + return -2; + } + for (;;) { + int n = stb_vorbis_get_frame_short_interleaved( + v, v->channels, data + offset, total - offset); + if (n == 0) break; + data_len += n; + offset += n * v->channels; + if (offset + limit > total) { + short* data2; + total *= 2; + data2 = (short*)realloc(data, total * sizeof(*data)); + if (data2 == NULL) { + free(data); + stb_vorbis_close(v); + return -2; + } + data = data2; + } + } + *output = data; + stb_vorbis_close(v); + return data_len; } -#endif - -int stb_vorbis_decode_memory(const uint8 *mem, int len, int *channels, int *sample_rate, short **output) -{ - int data_len, offset, total, limit, error; - short *data; - stb_vorbis *v = stb_vorbis_open_memory(mem, len, &error, NULL); - if (v == NULL) return -1; - limit = v->channels * 4096; - *channels = v->channels; - if (sample_rate) - *sample_rate = v->sample_rate; - offset = data_len = 0; - total = limit; - data = (short *) malloc(total * sizeof(*data)); - if (data == NULL) { - stb_vorbis_close(v); - return -2; - } - for (;;) { - int n = stb_vorbis_get_frame_short_interleaved(v, v->channels, data+offset, total-offset); - if (n == 0) break; - data_len += n; - offset += n * v->channels; - if (offset + limit > total) { - short *data2; - total *= 2; - data2 = (short *) realloc(data, total * sizeof(*data)); - if (data2 == NULL) { - free(data); - stb_vorbis_close(v); - return -2; - } - data = data2; - } - } - *output = data; - stb_vorbis_close(v); - return data_len; -} -#endif - -int stb_vorbis_get_samples_float_interleaved(stb_vorbis *f, int channels, float *buffer, int num_floats) -{ - float **outputs; - int len = num_floats / channels; - int n=0; - int z = f->channels; - if (z > channels) z = channels; - while (n < len) { - int i,j; - int k = f->channel_buffer_end - f->channel_buffer_start; - if (n+k >= len) k = len - n; - for (j=0; j < k; ++j) { - for (i=0; i < z; ++i) - *buffer++ = f->channel_buffers[i][f->channel_buffer_start+j]; - for ( ; i < channels; ++i) - *buffer++ = 0; - } - n += k; - f->channel_buffer_start += k; - if (n == len) - break; - if (!stb_vorbis_get_frame_float(f, NULL, &outputs)) - break; - } - return n; -} - -int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, int num_samples) -{ - float **outputs; - int n=0; - int z = f->channels; - if (z > channels) z = channels; - while (n < num_samples) { - int i; - int k = f->channel_buffer_end - f->channel_buffer_start; - if (n+k >= num_samples) k = num_samples - n; - if (k) { - for (i=0; i < z; ++i) - memcpy(buffer[i]+n, f->channel_buffers[i]+f->channel_buffer_start, sizeof(float)*k); - for ( ; i < channels; ++i) - memset(buffer[i]+n, 0, sizeof(float) * k); - } - n += k; - f->channel_buffer_start += k; - if (n == num_samples) - break; - if (!stb_vorbis_get_frame_float(f, NULL, &outputs)) - break; - } - return n; -} -#endif +#endif + +int stb_vorbis_decode_memory(const uint8* mem, int len, int* channels, + int* sample_rate, short** output) { + int data_len, offset, total, limit, error; + short* data; + stb_vorbis* v = stb_vorbis_open_memory(mem, len, &error, NULL); + if (v == NULL) return -1; + limit = v->channels * 4096; + *channels = v->channels; + if (sample_rate) *sample_rate = v->sample_rate; + offset = data_len = 0; + total = limit; + data = (short*)malloc(total * sizeof(*data)); + if (data == NULL) { + stb_vorbis_close(v); + return -2; + } + for (;;) { + int n = stb_vorbis_get_frame_short_interleaved( + v, v->channels, data + offset, total - offset); + if (n == 0) break; + data_len += n; + offset += n * v->channels; + if (offset + limit > total) { + short* data2; + total *= 2; + data2 = (short*)realloc(data, total * sizeof(*data)); + if (data2 == NULL) { + free(data); + stb_vorbis_close(v); + return -2; + } + data = data2; + } + } + *output = data; + stb_vorbis_close(v); + return data_len; +} +#endif + +int stb_vorbis_get_samples_float_interleaved(stb_vorbis* f, int channels, + float* buffer, int num_floats) { + float** outputs; + int len = num_floats / channels; + int n = 0; + int z = f->channels; + if (z > channels) z = channels; + while (n < len) { + int i, j; + int k = f->channel_buffer_end - f->channel_buffer_start; + if (n + k >= len) k = len - n; + for (j = 0; j < k; ++j) { + for (i = 0; i < z; ++i) + *buffer++ = f->channel_buffers[i][f->channel_buffer_start + j]; + for (; i < channels; ++i) *buffer++ = 0; + } + n += k; + f->channel_buffer_start += k; + if (n == len) break; + if (!stb_vorbis_get_frame_float(f, NULL, &outputs)) break; + } + return n; +} + +int stb_vorbis_get_samples_float(stb_vorbis* f, int channels, float** buffer, + int num_samples) { + float** outputs; + int n = 0; + int z = f->channels; + if (z > channels) z = channels; + while (n < num_samples) { + int i; + int k = f->channel_buffer_end - f->channel_buffer_start; + if (n + k >= num_samples) k = num_samples - n; + if (k) { + for (i = 0; i < z; ++i) + memcpy(buffer[i] + n, + f->channel_buffers[i] + f->channel_buffer_start, + sizeof(float) * k); + for (; i < channels; ++i) + memset(buffer[i] + n, 0, sizeof(float) * k); + } + n += k; + f->channel_buffer_start += k; + if (n == num_samples) break; + if (!stb_vorbis_get_frame_float(f, NULL, &outputs)) break; + } + return n; +} +#endif #endif