WiiFlow_Lite/source/music/SoundDecoder.cpp

162 lines
3.1 KiB
C++
Raw Normal View History

2012-01-21 21:57:41 +01:00
/***************************************************************************
* Copyright (C) 2010
* by Dimok
*
* 3Band resampling thanks to libmad
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*
* for WiiXplorer 2010
***************************************************************************/
#include <gccore.h>
#include <string.h>
#include <unistd.h>
#include "SoundDecoder.hpp"
SoundDecoder::SoundDecoder()
{
file_fd = NULL;
Init();
2012-01-21 21:57:41 +01:00
}
SoundDecoder::SoundDecoder(const char * filepath)
{
file_fd = new CFile(filepath, "rb");
Init();
2012-01-21 21:57:41 +01:00
}
SoundDecoder::SoundDecoder(const u8 * buffer, int size)
{
file_fd = new CFile(buffer, size);
Init();
2012-01-21 21:57:41 +01:00
}
SoundDecoder::~SoundDecoder()
{
ExitRequested = true;
while(Decoding)
usleep(100);
2012-01-21 21:57:41 +01:00
if(file_fd)
delete file_fd;
file_fd = NULL;
2012-01-21 21:57:41 +01:00
}
void SoundDecoder::Init()
{
SoundType = SOUND_RAW;
SoundBlocks = 8;
SoundBlockSize = 8192;
CurPos = 0;
LoopStart = 0;
Loop = false;
EndOfFile = false;
Decoding = false;
ExitRequested = false;
SoundBuffer.SetBufferBlockSize(SoundBlockSize);
SoundBuffer.Resize(SoundBlocks);
2012-01-21 21:57:41 +01:00
}
int SoundDecoder::Rewind()
{
CurPos = 0;
EndOfFile = false;
file_fd->rewind();
2012-01-21 21:57:41 +01:00
return 0;
2012-01-21 21:57:41 +01:00
}
int SoundDecoder::Read(u8 * buffer, int buffer_size, int)
{
int ret = file_fd->read(buffer, buffer_size);
CurPos += ret;
2012-01-21 21:57:41 +01:00
return ret;
2012-01-21 21:57:41 +01:00
}
void SoundDecoder::Decode()
{
if(!file_fd || ExitRequested || EndOfFile)
return;
u16 newWhich = SoundBuffer.Which();
u16 i = 0;
for(i = 0; i < SoundBuffer.Size()-2; i++)
{
if(!SoundBuffer.IsBufferReady(newWhich))
break;
newWhich = (newWhich+1) % SoundBuffer.Size();
}
if(i == SoundBuffer.Size()-2)
return;
Decoding = true;
int done = 0;
u8 *write_buf = SoundBuffer.GetBuffer(newWhich);
if(!write_buf)
{
ExitRequested = true;
Decoding = false;
return;
}
while(done < SoundBlockSize)
{
int ret = Read(&write_buf[done], SoundBlockSize-done, Tell());
if(ret <= 0)
{
if(Loop)
{
Rewind();
continue;
}
else if(LoopStart)
{
Rewind();
CurPos = LoopStart;
continue;
}
else
{
EndOfFile = true;
break;
}
}
done += ret;
}
if(done > 0)
{
SoundBuffer.SetBufferSize(newWhich, done);
SoundBuffer.SetBufferReady(newWhich, true);
}
2012-01-21 21:57:41 +01:00
if(!SoundBuffer.IsBufferReady((newWhich+1) % SoundBuffer.Size()))
Decode();
2012-01-21 21:57:41 +01:00
Decoding = false;
2012-01-21 21:57:41 +01:00
}