Mp3 fixes

CQTexperiment
vspader 2006-05-29 22:02:59 +00:00
parent aea620374c
commit 8b5500053f
6 changed files with 215 additions and 27 deletions

View File

@ -149,6 +149,8 @@
8D1107320486CEB800E47090 /* Cog.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Cog.app; sourceTree = BUILT_PRODUCTS_DIR; };
8E4C7F060A0509FC003BE25F /* DragScrollView.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DragScrollView.h; sourceTree = "<group>"; };
8E4C7F070A0509FC003BE25F /* DragScrollView.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = DragScrollView.m; sourceTree = "<group>"; };
8E643DF20A2B585600844A28 /* GameFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GameFile.h; sourceTree = "<group>"; };
8E643DF30A2B585600844A28 /* GameFile.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = GameFile.mm; sourceTree = "<group>"; };
8E6A8E270A0D8A68002ABE9C /* CoreAudioFile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CoreAudioFile.h; sourceTree = "<group>"; };
8E6A8E280A0D8A68002ABE9C /* CoreAudioFile.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = CoreAudioFile.m; sourceTree = "<group>"; };
8E6A8E350A0D8AD8002ABE9C /* CoreAudioUtils.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CoreAudioUtils.h; sourceTree = "<group>"; };
@ -488,6 +490,8 @@
8E75755609F31D5A0080F1EE /* WaveFile.m */,
8E75755709F31D5A0080F1EE /* WavPackFile.h */,
8E75755809F31D5A0080F1EE /* WavPackFile.m */,
8E643DF20A2B585600844A28 /* GameFile.h */,
8E643DF30A2B585600844A28 /* GameFile.mm */,
);
path = SoundFile;
sourceTree = "<group>";
@ -755,6 +759,7 @@
"$(SRCROOT)/Libraries/Vorbis/build/Release",
"$(SRCROOT)/Libraries/WavPack/build/Release",
"$(SRCROOT)/Libraries/SndFile/build/Release",
"$(SRCROOT)/Libraries/GME/build/Release",
);
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
@ -792,6 +797,7 @@
"$(SRCROOT)/Libraries/Vorbis/build/Release",
"$(SRCROOT)/Libraries/WavPack/build/Release",
"$(SRCROOT)/Libraries/SndFile/build/Release",
"$(SRCROOT)/Libraries/GME/build/Release",
);
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_MODEL_TUNING = G5;

View File

@ -23,7 +23,6 @@
#include <AudioToolbox/ExtendedAudioFile.h>
#import "SoundFile.h"
#define _USE_WRAPPER_
@interface CoreAudioFile : SoundFile
@ -31,10 +30,11 @@
ExtAudioFileRef _in;
#ifdef _USE_WRAPPER_
FILE * _inFd;
int _inFd;
AudioFileID _audioID;
SInt64 _fileSize;
SInt64 _startOffset;
#endif
}

View File

@ -18,6 +18,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <unistd.h>
#import "CoreAudioFile.h"
@interface CoreAudioFile (Private)
@ -30,11 +32,13 @@
OSStatus readFunc(void * inRefCon, SInt64 inPosition, ByteCount requestCount, void *buffer, ByteCount* actualCount)
{
CoreAudioFile *caf = (CoreAudioFile *)inRefCon;
FILE *fd = caf->_inFd;
int fd = caf->_inFd;
fseek(fd, inPosition, SEEK_SET);
// fseek(fd, inPosition, SEEK_SET);
// NSLog(@"Requesting %u", requestCount);
// NSLog(@"Currently at %lli", inPosition);
*actualCount = fread(buffer, 1, requestCount, fd);
*actualCount = pread(fd, buffer, requestCount, inPosition+caf->_startOffset);
if (*actualCount <= 0)
{
@ -47,15 +51,14 @@ OSStatus readFunc(void * inRefCon, SInt64 inPosition, ByteCount requestCount, vo
SInt64 getSizeFunc(void *inRefCon)
{
CoreAudioFile *caf = (CoreAudioFile *)inRefCon;
FILE *fd = caf->_inFd;
int fd = caf->_inFd;
if (caf->_fileSize != 0)
{
return caf->_fileSize;
}
long curPos;
/* long curPos;
curPos = ftell(fd);
@ -64,7 +67,12 @@ SInt64 getSizeFunc(void *inRefCon)
caf->_fileSize = ftell(fd);
fseek(fd, curPos, SEEK_SET);
*/
caf->_fileSize = lseek(fd, 0, SEEK_END) - caf->_startOffset;
NSLog(@"SIZE at %lli", caf->_fileSize);
NSLog(@"ERROR: %i = %i %i %i", errno, EBADF, ESPIPE, EINVAL);
return caf->_fileSize;
}
@ -90,9 +98,10 @@ OSStatus writeFunc(void * inRefCon, SInt64 inPosition, ByteCount requestCount, c
- (void) close
{
OSStatus err;
#ifdef _USE_WRAPPER_
fclose(_inFd);
if (_inFd)
close(_inFd);
AudioFileClose(_audioID);
#endif
@ -105,31 +114,73 @@ OSStatus writeFunc(void * inRefCon, SInt64 inPosition, ByteCount requestCount, c
- (BOOL) readInfo:(const char *)filename
{
OSStatus err;
AudioFileTypeID type = 0;
NSString *ext;
#ifdef _USE_WRAPPER_
// Open the input file
_inFd = fopen(filename, "r");
if (!_inFd)
_inFd = open(filename, O_RDONLY, 0777);
if (_inFd < 0)
{
NSLog(@"Error operning file: %s", filename);
return NO;
}
_startOffset = 0;
ext = [[NSString stringWithCString:filename encoding:NSASCIIStringEncoding] pathExtension];
//Find first sync frame for MP3
if([ext caseInsensitiveCompare:@"mp3"] == NSOrderedSame) {
size_t bytesRead;
uint8_t buf[2];
type = kAudioFileMP3Type;
for(;;) {
bytesRead = read(_inFd, buf, 2);
if(2 != bytesRead) {
NSLog(@"Error finding mp3 sync frame");
close(_inFd);
return NO;
}
// found some kind of data
if(0x00 != buf[0] || 0x00 != buf[1]) {
_startOffset = lseek(_inFd, 0, SEEK_CUR) - 2;
NSLog(@"Found sync frame at: %llx", _startOffset);
break;
}
}
}
else if([ext caseInsensitiveCompare:@"aac"] == NSOrderedSame) {
type = kAudioFileAAC_ADTSType;
}
else if([ext caseInsensitiveCompare:@"m4a"] == NSOrderedSame) {
type = kAudioFileM4AType;
}
else if([ext caseInsensitiveCompare:@"mp4"] == NSOrderedSame) {
type = kAudioFileMPEG4Type;
}
//Using callbacks with fopen, ftell, fseek, fclose, because the default pread hangs when accessing the same file from multiple threads.
err = AudioFileOpenWithCallbacks(self, readFunc, writeFunc, getSizeFunc, setSizeFunc, 0, &_audioID);
err = AudioFileOpenWithCallbacks(self, readFunc, writeFunc, getSizeFunc, setSizeFunc, type, &_audioID);
if(noErr != err)
{
NSLog(@"Error opening with callbacks, falling back: %s", (char *)&err);
FSRef ref;
fclose(_inFd);
close(_inFd);
_inFd = 0;
err = FSPathMakeRef((const UInt8 *)filename, &ref, NULL);
if(noErr != err) {
return NO;
}
err = AudioFileOpen(&ref, fsRdPerm, 0, &_audioID);
err = AudioFileOpen(&ref, fsRdPerm, type, &_audioID);
if(noErr != err) {
NSLog(@"Error opening AudioFile: %i", (char *)&err);
NSLog(@"Error opening AudioFile: %s", (char *)&err);
return NO;
}
}
@ -141,7 +192,7 @@ OSStatus writeFunc(void * inRefCon, SInt64 inPosition, ByteCount requestCount, c
#else
FSRef ref;
// Open the input file
err = FSPathMakeRef((const UInt8 *)filename, &ref, NULL);
if(noErr != err) {
@ -150,6 +201,7 @@ OSStatus writeFunc(void * inRefCon, SInt64 inPosition, ByteCount requestCount, c
err = ExtAudioFileOpen(&ref, &_in);
if(noErr != err) {
NSLog(@"Error opening file: %s", &err);
return NO;
}
#endif
@ -162,7 +214,7 @@ OSStatus writeFunc(void * inRefCon, SInt64 inPosition, ByteCount requestCount, c
UInt32 size;
SInt64 totalFrames;
AudioStreamBasicDescription asbd;
// Get input file information
size = sizeof(asbd);
err = ExtAudioFileGetProperty(_in, kExtAudioFileProperty_FileDataFormat, &size, &asbd);
@ -170,14 +222,14 @@ OSStatus writeFunc(void * inRefCon, SInt64 inPosition, ByteCount requestCount, c
err = ExtAudioFileDispose(_in);
return NO;
}
size = sizeof(totalFrames);
err = ExtAudioFileGetProperty(_in, kExtAudioFileProperty_FileLengthFrames, &size, &totalFrames);
if(err != noErr) {
err = ExtAudioFileDispose(_in);
return NO;
}
#ifdef _USE_WRAPPER_
SInt64 totalBytes;
@ -205,7 +257,7 @@ OSStatus writeFunc(void * inRefCon, SInt64 inPosition, ByteCount requestCount, c
}
totalSize = totalFrames * channels * (bitsPerSample / 8);
// Set output format
AudioStreamBasicDescription result;
@ -221,7 +273,7 @@ OSStatus writeFunc(void * inRefCon, SInt64 inPosition, ByteCount requestCount, c
result.mBytesPerPacket = channels * (bitsPerSample / 8);
result.mFramesPerPacket = 1;
result.mBytesPerFrame = channels * (bitsPerSample / 8);
err = ExtAudioFileSetProperty(_in, kExtAudioFileProperty_ClientDataFormat, sizeof(result), &result);
if(noErr != err) {
err = ExtAudioFileDispose(_in);
@ -231,7 +283,7 @@ OSStatus writeFunc(void * inRefCon, SInt64 inPosition, ByteCount requestCount, c
// Further properties
isBigEndian = YES;
isUnsigned = NO;
return YES;
}
@ -260,7 +312,7 @@ OSStatus writeFunc(void * inRefCon, SInt64 inPosition, ByteCount requestCount, c
- (double) seekToTime:(double)milliseconds
{
OSStatus err;
err = ExtAudioFileSeek(_in, ((milliseconds / 1000.f) * frequency));
if(noErr != err) {
return -1.f;

View File

@ -0,0 +1,19 @@
//
// GameFile.h
// Cog
//
// Created by Zaphod Beeblebrox on 5/29/06.
// Copyright 2006 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "SoundFile.h"
#undef HAVE_CONFIG_H
#import "GME/Music_Emu.h"
@interface GameFile : SoundFile {
Music_Emu* emu;
}
@end

110
Sound/SoundFile/GameFile.mm Normal file
View File

@ -0,0 +1,110 @@
//
// GameFile.m
// Cog
//
// Created by Zaphod Beeblebrox on 5/29/06.
// Copyright 2006 __MyCompanyName__. All rights reserved.
//
#import "GameFile.h"
#include "GME/Nsf_Emu.h"
#include "GME/Gbs_Emu.h"
#include "GME/Spc_Emu.h"
#include "GME/Vgm_Emu.h"
#include "GME/Gym_Emu.h"
@implementation GameFile
- (BOOL)open:(const char *)filename
{
int i;
const char* p;
char ext[3];
p = strrchr( (char*) filename, '.' )+1;
NSLog(@"OPENING GAME FILE: %s", filename);
NSLog(@"Extension: %s", p);
if (!p || strlen(p) != 3)
return NO;
for (i = 0; i < 4; i++)
ext[i] = toupper(p[i]);
ext[3] = 0;
if (!ext)
emu = NULL;
else if ( !strcmp( ext, "NSF" ) )
emu = new Nsf_Emu;
else if ( !strcmp( ext, "GBS" ) )
emu = new Gbs_Emu;
else if ( !strcmp( ext, "SPC" ) )
emu = new Spc_Emu;
else if ( !strcmp( ext, "VGM" ) || !strcmp( ext, "VGZ" ) )
emu = new Vgm_Emu;
else if ( !strcmp( ext, "GYM" ) )
emu = new Gym_Emu;
else
emu = NULL;
NSLog(@"EMU IS: %i", emu);
if (!emu)
return NO;
emu->set_sample_rate(44100);
emu->load_file(filename);
emu->start_track( 0 );
frequency = 44100;
channels = 2;
bitsPerSample = 8 * sizeof(Music_Emu::sample_t);
totalSize = emu->track_count() * frequency*(bitsPerSample/8)*channels;
isBigEndian = YES;
NSLog(@"OPENED GAME FILE:");
return YES;
}
- (BOOL)readInfo:(const char *)filename
{
return [self open:filename];
}
- (int)fillBuffer:(void *)buf ofSize:(UInt32)size
{
int numSamples = size / ((bitsPerSample/8));
emu->play(numSamples, (short int *)buf);
return size; //No such thing as EOF
}
//Cheap hack until I figure out how to actually support multiple tracks in a single file.
- (double)seekToTime:(double)milliseconds
{
int track;
track = (int)(milliseconds/1000.0);
NSLog(@"Track: %i", track);
if (track > emu->track_count())
{
track = emu->track_count();
}
emu->start_track( track );
return -1.0;
}
- (void)close
{
if (emu)
delete emu;
}
@end

View File

@ -18,6 +18,7 @@
#import "WavPackFile.h"
#import "ShnFile.h"
#import "CoreAudioFile.h"
#import "GameFile.h"
extern "C" {
BOOL hostIsBigEndian()