Modified AO decoder so it always asks for sampleRate/60. This is a limitation of the psf decoders.
parent
7cc09327e2
commit
717c3861b8
|
@ -10,7 +10,10 @@
|
||||||
#import "Plugin.h"
|
#import "Plugin.h"
|
||||||
|
|
||||||
@interface AODecoder : NSObject<CogDecoder,CogMetadataReader> {
|
@interface AODecoder : NSObject<CogDecoder,CogMetadataReader> {
|
||||||
uint8_t *buffer;
|
uint8_t *fileBuffer;
|
||||||
|
uint8_t *sampleBuffer;
|
||||||
|
int samplesInBuffer;
|
||||||
|
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
BOOL closed;
|
BOOL closed;
|
||||||
|
|
|
@ -17,6 +17,9 @@ static GlobalLock *globalLock;
|
||||||
|
|
||||||
@implementation AODecoder
|
@implementation AODecoder
|
||||||
|
|
||||||
|
// The AO SDK requires you ask for 1 frame at a time.
|
||||||
|
#define SAMPLES_PER_FRAME 44100/60
|
||||||
|
|
||||||
static struct
|
static struct
|
||||||
{
|
{
|
||||||
uint32_t sig;
|
uint32_t sig;
|
||||||
|
@ -162,6 +165,7 @@ int ao_get_lib(char *fn, uint8 **buf, uint64 *length)
|
||||||
return frames;
|
return frames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (BOOL)openUnderLock:(id<CogSource>)source
|
- (BOOL)openUnderLock:(id<CogSource>)source
|
||||||
{
|
{
|
||||||
if (![source seekable] || ![[source url] isFileURL]) {
|
if (![source seekable] || ![[source url] isFileURL]) {
|
||||||
|
@ -174,21 +178,21 @@ int ao_get_lib(char *fn, uint8 **buf, uint64 *length)
|
||||||
long size = [source tell];
|
long size = [source tell];
|
||||||
[source seek:0 whence:SEEK_SET];
|
[source seek:0 whence:SEEK_SET];
|
||||||
|
|
||||||
buffer = malloc(size);
|
fileBuffer = malloc(size);
|
||||||
if (!buffer) {
|
if (!fileBuffer) {
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
long amountRead = 0;
|
long amountRead = 0;
|
||||||
while (amountRead < size) {
|
while (amountRead < size) {
|
||||||
int read = [source read:buffer+amountRead amount:size - amountRead];
|
int read = [source read:fileBuffer+amountRead amount:size - amountRead];
|
||||||
amountRead += read;
|
amountRead += read;
|
||||||
}
|
}
|
||||||
|
|
||||||
[source close];
|
[source close];
|
||||||
|
|
||||||
type = 0;
|
type = 0;
|
||||||
int filesig = buffer[0]<<24 | buffer[1]<<16 | buffer[2]<<8 | buffer[3];
|
int filesig = fileBuffer[0]<<24 | fileBuffer[1]<<16 | fileBuffer[2]<<8 | fileBuffer[3];
|
||||||
while (types[type].sig != 0xffffffff)
|
while (types[type].sig != 0xffffffff)
|
||||||
{
|
{
|
||||||
if (filesig == types[type].sig)
|
if (filesig == types[type].sig)
|
||||||
|
@ -207,13 +211,13 @@ int ao_get_lib(char *fn, uint8 **buf, uint64 *length)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NSLog(@"ERROR: File is unknown, signature bytes are %02x %02x %02x %02x\n", buffer[0], buffer[1], buffer[2], buffer[3]);
|
NSLog(@"ERROR: File is unknown, signature bytes are %02x %02x %02x %02x\n", fileBuffer[0], fileBuffer[1], fileBuffer[2], fileBuffer[3]);
|
||||||
|
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ((*types[type].start)(buffer, size) != AO_SUCCESS)
|
if ((*types[type].start)(fileBuffer, size) != AO_SUCCESS)
|
||||||
{
|
{
|
||||||
NSLog(@"ERROR: Engine rejected file!\n");
|
NSLog(@"ERROR: Engine rejected file!\n");
|
||||||
|
|
||||||
|
@ -222,6 +226,9 @@ int ao_get_lib(char *fn, uint8 **buf, uint64 *length)
|
||||||
|
|
||||||
totalFrames = [self retrieveTotalFrames];
|
totalFrames = [self retrieveTotalFrames];
|
||||||
|
|
||||||
|
sampleBuffer = malloc(SAMPLES_PER_FRAME * 4); // 4 == bytes per sample * channels
|
||||||
|
samplesInBuffer = 0;
|
||||||
|
|
||||||
[self willChangeValueForKey:@"properties"];
|
[self willChangeValueForKey:@"properties"];
|
||||||
[self didChangeValueForKey:@"properties"];
|
[self didChangeValueForKey:@"properties"];
|
||||||
|
|
||||||
|
@ -247,16 +254,22 @@ int ao_get_lib(char *fn, uint8 **buf, uint64 *length)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int maxFrames = 1470; // The Dreamcast decoder starts smashing things if you try decoding more than this
|
|
||||||
|
|
||||||
int amountRead = 0;
|
int amountRead = 0;
|
||||||
while (amountRead < frames) {
|
while (amountRead < frames) {
|
||||||
int requestAmount = frames - amountRead;
|
if (samplesInBuffer == 0) {
|
||||||
if (requestAmount > maxFrames) {
|
// Fill them up!
|
||||||
requestAmount = maxFrames;
|
(*types[type].gen)((int16_t *)sampleBuffer, SAMPLES_PER_FRAME);
|
||||||
|
samplesInBuffer = SAMPLES_PER_FRAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*types[type].gen)((int16_t *)((uint32_t *)buf + amountRead), requestAmount);
|
int requestAmount = frames - amountRead;
|
||||||
|
if (requestAmount > samplesInBuffer) {
|
||||||
|
requestAmount = samplesInBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(((uint8_t *)buf) + amountRead*4, sampleBuffer, requestAmount*4);
|
||||||
|
memmove(sampleBuffer, sampleBuffer + (requestAmount*4), (samplesInBuffer - requestAmount)*4);
|
||||||
|
samplesInBuffer -= requestAmount;
|
||||||
|
|
||||||
amountRead += requestAmount;
|
amountRead += requestAmount;
|
||||||
}
|
}
|
||||||
|
@ -269,9 +282,12 @@ int ao_get_lib(char *fn, uint8 **buf, uint64 *length)
|
||||||
- (void)closeUnderLock
|
- (void)closeUnderLock
|
||||||
{
|
{
|
||||||
(*types[type ].stop)();
|
(*types[type ].stop)();
|
||||||
if (NULL != buffer) {
|
if (NULL != fileBuffer) {
|
||||||
free(buffer);
|
free(fileBuffer);
|
||||||
buffer = NULL;
|
fileBuffer = NULL;
|
||||||
|
|
||||||
|
free(sampleBuffer);
|
||||||
|
sampleBuffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
[currentSource release];
|
[currentSource release];
|
||||||
|
|
Loading…
Reference in New Issue