libvgm: Add exception handling, and move buffer
Move the player buffer off the stack, as well as adding exception handlers to the init, playback, and shutdown code. Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
parent
0263367639
commit
5b51e664e2
2 changed files with 111 additions and 85 deletions
|
@ -19,6 +19,7 @@
|
||||||
DATA_LOADER* dLoad;
|
DATA_LOADER* dLoad;
|
||||||
PlayerA* mainPlr;
|
PlayerA* mainPlr;
|
||||||
id<CogSource> source;
|
id<CogSource> source;
|
||||||
|
UINT8* sampleBuffer;
|
||||||
double sampleRate;
|
double sampleRate;
|
||||||
long loopCount;
|
long loopCount;
|
||||||
double fadeTime;
|
double fadeTime;
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
|
|
||||||
@implementation libvgmDecoder
|
@implementation libvgmDecoder
|
||||||
|
|
||||||
|
enum { bufferSize = 1024 };
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
const int logLevel = DEVLOG_DEBUG;
|
const int logLevel = DEVLOG_DEBUG;
|
||||||
#else
|
#else
|
||||||
|
@ -99,6 +101,7 @@ const int masterVol = 0x10000; // Fixed point 16.16
|
||||||
fileData = NULL;
|
fileData = NULL;
|
||||||
dLoad = NULL;
|
dLoad = NULL;
|
||||||
mainPlr = NULL;
|
mainPlr = NULL;
|
||||||
|
sampleBuffer = NULL;
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -130,6 +133,7 @@ const int masterVol = 0x10000; // Fixed point 16.16
|
||||||
BOOL repeatOne = IsRepeatOneSet();
|
BOOL repeatOne = IsRepeatOneSet();
|
||||||
uint32_t maxLoops = repeatOne ? 0 : (uint32_t)loopCount;
|
uint32_t maxLoops = repeatOne ? 0 : (uint32_t)loopCount;
|
||||||
|
|
||||||
|
try {
|
||||||
mainPlr = new PlayerA;
|
mainPlr = new PlayerA;
|
||||||
mainPlr->RegisterPlayerEngine(new VGMPlayer);
|
mainPlr->RegisterPlayerEngine(new VGMPlayer);
|
||||||
mainPlr->RegisterPlayerEngine(new S98Player);
|
mainPlr->RegisterPlayerEngine(new S98Player);
|
||||||
|
@ -186,6 +190,14 @@ const int masterVol = 0x10000; // Fixed point 16.16
|
||||||
[self setTrackEnded:NO];
|
[self setTrackEnded:NO];
|
||||||
|
|
||||||
mainPlr->Start();
|
mainPlr->Start();
|
||||||
|
} catch(std::exception& e) {
|
||||||
|
ALog(@"Exception caught opening file: %s\n", e.what());
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
sampleBuffer = (UINT8*) malloc(bufferSize * numChannels * (numBitsPerSample / 8));
|
||||||
|
if(!sampleBuffer)
|
||||||
|
return NO;
|
||||||
|
|
||||||
[self willChangeValueForKey:@"properties"];
|
[self willChangeValueForKey:@"properties"];
|
||||||
[self didChangeValueForKey:@"properties"];
|
[self didChangeValueForKey:@"properties"];
|
||||||
|
@ -215,15 +227,18 @@ const int masterVol = 0x10000; // Fixed point 16.16
|
||||||
id audioChunkClass = NSClassFromString(@"AudioChunk");
|
id audioChunkClass = NSClassFromString(@"AudioChunk");
|
||||||
AudioChunk* chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
|
AudioChunk* chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
|
||||||
|
|
||||||
int frames = 1024;
|
int frames = bufferSize;
|
||||||
const size_t bytesPerFrame = [chunk format].mBytesPerFrame;
|
const int bytesPerFrame = [chunk format].mBytesPerFrame;
|
||||||
uint8_t buffer[frames * bytesPerFrame];
|
|
||||||
|
|
||||||
void* buf = (void*)buffer;
|
void* buf = (void*)sampleBuffer;
|
||||||
|
|
||||||
BOOL repeatOne = IsRepeatOneSet();
|
BOOL repeatOne = IsRepeatOneSet();
|
||||||
uint32_t maxLoops = repeatOne ? 0 : (uint32_t)loopCount;
|
uint32_t maxLoops = repeatOne ? 0 : (uint32_t)loopCount;
|
||||||
|
|
||||||
|
double streamTimestamp;
|
||||||
|
UInt32 framesDone = 0;
|
||||||
|
|
||||||
|
try {
|
||||||
PlayerBase* player = mainPlr->GetPlayer();
|
PlayerBase* player = mainPlr->GetPlayer();
|
||||||
mainPlr->SetLoopCount(maxLoops);
|
mainPlr->SetLoopCount(maxLoops);
|
||||||
if(player->GetPlayerType() == FCC_VGM) {
|
if(player->GetPlayerType() == FCC_VGM) {
|
||||||
|
@ -231,31 +246,33 @@ const int masterVol = 0x10000; // Fixed point 16.16
|
||||||
mainPlr->SetLoopCount(vgmplay->GetModifiedLoopCount(maxLoops));
|
mainPlr->SetLoopCount(vgmplay->GetModifiedLoopCount(maxLoops));
|
||||||
}
|
}
|
||||||
|
|
||||||
double streamTimestamp = mainPlr->GetCurTime(0);
|
streamTimestamp = mainPlr->GetCurTime(0);
|
||||||
|
|
||||||
UInt32 framesDone = 0;
|
|
||||||
|
|
||||||
while(framesDone < frames) {
|
while(framesDone < frames) {
|
||||||
UInt32 framesToDo = frames - framesDone;
|
UInt32 framesToDo = frames - framesDone;
|
||||||
if(framesToDo > smplAlloc)
|
if(framesToDo > smplAlloc)
|
||||||
framesToDo = smplAlloc;
|
framesToDo = smplAlloc;
|
||||||
|
|
||||||
int numSamples = framesToDo * numChannels * (numBitsPerSample / 8);
|
int numSamples = framesToDo * bytesPerFrame;
|
||||||
|
|
||||||
UINT32 numRendered = mainPlr->Render(numSamples, buf);
|
UINT32 numRendered = mainPlr->Render(numSamples, buf);
|
||||||
|
|
||||||
buf = (void*)(((uint8_t*)buf) + numRendered);
|
buf = (void*)(((uint8_t*)buf) + numRendered);
|
||||||
|
|
||||||
UINT32 framesRendered = numRendered / (numChannels * (numBitsPerSample / 8));
|
UINT32 framesRendered = numRendered / bytesPerFrame;
|
||||||
|
|
||||||
framesDone += framesRendered;
|
framesDone += framesRendered;
|
||||||
|
|
||||||
if(framesRendered < framesToDo)
|
if(framesRendered < framesToDo)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} catch(std::exception& e) {
|
||||||
|
ALog(@"Exception caught while playing track: %s\n", e.what());
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
[chunk setStreamTimestamp:streamTimestamp];
|
[chunk setStreamTimestamp:streamTimestamp];
|
||||||
[chunk assignSamples:buffer frameCount:framesDone];
|
[chunk assignSamples:sampleBuffer frameCount:framesDone];
|
||||||
|
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
|
@ -269,6 +286,11 @@ const int masterVol = 0x10000; // Fixed point 16.16
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)close {
|
- (void)close {
|
||||||
|
if(sampleBuffer) {
|
||||||
|
free(sampleBuffer);
|
||||||
|
sampleBuffer = NULL;
|
||||||
|
}
|
||||||
|
try {
|
||||||
if(mainPlr) {
|
if(mainPlr) {
|
||||||
mainPlr->Stop();
|
mainPlr->Stop();
|
||||||
mainPlr->UnloadFile();
|
mainPlr->UnloadFile();
|
||||||
|
@ -280,6 +302,9 @@ const int masterVol = 0x10000; // Fixed point 16.16
|
||||||
DataLoader_Deinit(dLoad);
|
DataLoader_Deinit(dLoad);
|
||||||
dLoad = NULL;
|
dLoad = NULL;
|
||||||
}
|
}
|
||||||
|
} catch(std::exception& e) {
|
||||||
|
ALog(@"Exception caught cleaning up player: %s\n", e.what());
|
||||||
|
}
|
||||||
if(fileData) {
|
if(fileData) {
|
||||||
free(fileData);
|
free(fileData);
|
||||||
fileData = NULL;
|
fileData = NULL;
|
||||||
|
|
Loading…
Reference in a new issue