Removed decoders folder.

CQTexperiment
vspader 2007-02-28 00:03:38 +00:00
parent 84e7b7df83
commit 656be855ce
20 changed files with 0 additions and 2381 deletions

View File

@ -1,41 +0,0 @@
/*
* $Id$
*
* Copyright (C) 2006 Stephen F. Booth <me@sbooth.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#import <Cocoa/Cocoa.h>
#include <AudioToolbox/ExtendedAudioFile.h>
#import "SoundFile.h"
#undef _USE_WRAPPER_
@interface CoreAudioFile : SoundFile
{
ExtAudioFileRef _in;
#ifdef _USE_WRAPPER_
int _inFd;
AudioFileID _audioID;
SInt64 _fileSize;
SInt64 _startOffset;
#endif
}
@end

View File

@ -1,324 +0,0 @@
/*
* $Id$
*
* Copyright (C) 2006 Stephen F. Booth <me@sbooth.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <unistd.h>
#import "CoreAudioFile.h"
@interface CoreAudioFile (Private)
- (BOOL) readInfoFromExtAudioFileRef;
@end
@implementation CoreAudioFile
#ifdef _USE_WRAPPER_
OSStatus readFunc(void * inRefCon, SInt64 inPosition, ByteCount requestCount, void *buffer, ByteCount* actualCount)
{
CoreAudioFile *caf = (CoreAudioFile *)inRefCon;
int fd = caf->_inFd;
// fseek(fd, inPosition, SEEK_SET);
// NSLog(@"Requesting %u", requestCount);
// NSLog(@"Currently at %lli", inPosition);
*actualCount = pread(fd, buffer, requestCount, inPosition+caf->_startOffset);
if (*actualCount <= 0)
{
return -1000; //Error?
}
return noErr;
}
SInt64 getSizeFunc(void *inRefCon)
{
CoreAudioFile *caf = (CoreAudioFile *)inRefCon;
int fd = caf->_inFd;
if (caf->_fileSize != 0)
{
return caf->_fileSize;
}
/* long curPos;
curPos = ftell(fd);
fseek(fd, 0, SEEK_END);
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;
}
OSStatus setSizeFunc(void * inRefCon, SInt64 inSize)
{
NSLog(@"setsize FUNC");
return -1000; //Not supported at the moment
}
OSStatus writeFunc(void * inRefCon, SInt64 inPosition, ByteCount requestCount, const void *buffer, ByteCount* actualCount)
{
NSLog(@"WRITE FUNC");
return -1000; //Not supported at the moment
}
#endif
- (BOOL) open:(const char *)filename
{
return [self readInfo:filename];
}
- (void) close
{
OSStatus err;
#ifdef _USE_WRAPPER_
if (_inFd)
close(_inFd);
AudioFileClose(_audioID);
#endif
err = ExtAudioFileDispose(_in);
if(noErr != err) {
NSLog(@"Error closing ExtAudioFile");
}
}
- (BOOL) readInfo:(const char *)filename
{
OSStatus err;
AudioFileTypeID type = 0;
NSString *ext;
#ifdef _USE_WRAPPER_
// Open the input file
_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, type, &_audioID);
if(noErr != err)
{
NSLog(@"Error opening with callbacks, falling back: %s", (char *)&err);
FSRef ref;
close(_inFd);
_inFd = 0;
err = FSPathMakeRef((const UInt8 *)filename, &ref, NULL);
if(noErr != err) {
return NO;
}
err = AudioFileOpen(&ref, fsRdPerm, type, &_audioID);
if(noErr != err) {
NSLog(@"Error opening AudioFile: %s", (char *)&err);
return NO;
}
}
err = ExtAudioFileWrapAudioFileID(_audioID, NO, &_in);
if(noErr != err) {
return NO;
}
#else
FSRef ref;
// Open the input file
err = FSPathMakeRef((const UInt8 *)filename, &ref, NULL);
if(noErr != err) {
return NO;
}
err = ExtAudioFileOpen(&ref, &_in);
if(noErr != err) {
NSLog(@"Error opening file: %s", &err);
return NO;
}
#endif
return [self readInfoFromExtAudioFileRef];
}
- (BOOL) readInfoFromExtAudioFileRef
{
OSStatus err;
UInt32 size;
SInt64 totalFrames;
AudioStreamBasicDescription asbd;
// Get input file information
size = sizeof(asbd);
err = ExtAudioFileGetProperty(_in, kExtAudioFileProperty_FileDataFormat, &size, &asbd);
if(err != noErr) {
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;
size = sizeof(totalBytes);
err = AudioFileGetProperty(_audioID, kAudioFilePropertyAudioDataByteCount, &size, &totalBytes);
if(err != noErr) {
[self close];
return NO;
}
NSLog(@"BITRATE: %lli %lli %lf", totalBytes, totalFrames, asbd.mSampleRate);
bitrate = round(((totalBytes*8.0)/((double)(totalFrames)/asbd.mSampleRate))/1000.0);
#else
//Is there a way to get bitrate with extAudioFile?
bitrate = 0;
#endif
// Set our properties
bitsPerSample = asbd.mBitsPerChannel;
channels = asbd.mChannelsPerFrame;
frequency = asbd.mSampleRate;
// mBitsPerChannel will only be set for lpcm formats
if(0 == bitsPerSample) {
bitsPerSample = 16;
}
totalSize = totalFrames * channels * (bitsPerSample / 8);
// Set output format
AudioStreamBasicDescription result;
bzero(&result, sizeof(AudioStreamBasicDescription));
result.mFormatID = kAudioFormatLinearPCM;
result.mFormatFlags = kAudioFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsBigEndian;
result.mSampleRate = frequency;
result.mChannelsPerFrame = channels;
result.mBitsPerChannel = bitsPerSample;
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);
return NO;
}
// Further properties
isBigEndian = YES;
isUnsigned = NO;
return YES;
}
- (int) fillBuffer:(void *)buf ofSize:(UInt32)size
{
OSStatus err;
AudioBufferList bufferList;
UInt32 frameCount;
// Set up the AudioBufferList
bufferList.mNumberBuffers = 1;
bufferList.mBuffers[0].mNumberChannels = channels;
bufferList.mBuffers[0].mData = buf;
bufferList.mBuffers[0].mDataByteSize = size;
// Read a chunk of PCM input (converted from whatever format)
frameCount = (size / (channels * (bitsPerSample / 8)));
err = ExtAudioFileRead(_in, &frameCount, &bufferList);
if(err != noErr) {
return 0;
}
return frameCount * (channels * (bitsPerSample / 8));
}
- (double) seekToTime:(double)milliseconds
{
OSStatus err;
err = ExtAudioFileSeek(_in, ((milliseconds / 1000.f) * frequency));
if(noErr != err) {
return -1.f;
}
return milliseconds;
}
@end

View File

@ -1,28 +0,0 @@
//
// FlacFile.h
// zyVorbis
//
// Created by Vincent Spader on 1/25/05.
// Copyright 2005 Vincent Spader All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "FLAC/all.h"
#import "SoundFile.h"
#define SAMPLES_PER_WRITE 512
#define FLAC__MAX_SUPPORTED_CHANNELS 2
#define SAMPLE_BUFFER_SIZE ((FLAC__MAX_BLOCK_SIZE + SAMPLES_PER_WRITE) * FLAC__MAX_SUPPORTED_CHANNELS * (24/8))
@interface FlacFile : SoundFile {
FLAC__FileDecoder *decoder;
char buffer[SAMPLE_BUFFER_SIZE];
int bufferAmount;
}
- (FLAC__FileDecoder *)decoder;
- (char *)buffer;
- (int)bufferAmount;
- (void)setBufferAmount:(int)amount;
@end

View File

@ -1,188 +0,0 @@
//
// FlacFile.m
// zyVorbis
//
// Created by Vincent Spader on 1/25/05.
// Copyright 2005 Vincent Spader All rights reserved.
//
#import "FlacFile.h"
@implementation FlacFile
FLAC__StreamDecoderWriteStatus WriteProc(const FLAC__FileDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const sampleBuffer[], void *client_data)
{
// DBLog(@"Write callback");
FlacFile *flacFile = (FlacFile *)client_data;
unsigned wide_samples = frame->header.blocksize;
unsigned channels = frame->header.channels;
UInt16 *buffer = (UInt16 *)[flacFile buffer];
int i, j, c;
for (i = j = 0; i < wide_samples; i++)
{
for (c = 0; c < channels; c++, j++)
{
// buffer[j] = CFSwapInt16LittleToHost(sampleBuffer[c][i]);
buffer[j] = sampleBuffer[c][i];
}
}
// memcpy([flacFile buffer], sampleBuffer, wide_samples*[flacFile bitsPerSample]/8);
[flacFile setBufferAmount:(wide_samples * channels*2)];
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
}
void MetadataProc(const FLAC__FileDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
{
FlacFile *flacFile = (FlacFile *)client_data;
flacFile->channels = metadata->data.stream_info.channels;
flacFile->frequency = metadata->data.stream_info.sample_rate;
flacFile->bitsPerSample = metadata->data.stream_info.bits_per_sample;
// DBLog(@"METADATAAAA LENGTH: %i %i %f", (int)(metadata->data.stream_info.total_samples),[flacFile frequency], (float)(metadata->data.stream_info.total_samples)/[flacFile frequency]);
flacFile->totalSize = metadata->data.stream_info.total_samples*metadata->data.stream_info.channels*metadata->data.stream_info.bits_per_sample/8;
}
void ErrorProc(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
{
DBLog(@"Error callback");
}
- (BOOL)open:(const char *)filename
{
FLAC__bool status;
decoder = FLAC__file_decoder_new();
if (decoder == NULL)
return NO;
status = FLAC__file_decoder_set_filename(decoder, filename);
if (status == false)
return NO;
status = FLAC__file_decoder_set_write_callback(decoder, WriteProc);
if (status == false)
return NO;
status = FLAC__file_decoder_set_metadata_callback(decoder, MetadataProc);
if (status == false)
return NO;
status = FLAC__file_decoder_set_error_callback(decoder, ErrorProc);
if (status == false)
return NO;
status = FLAC__file_decoder_set_client_data(decoder, self);
if (status == false)
return NO;
if (FLAC__file_decoder_init(decoder) != FLAC__FILE_DECODER_OK)
return NO;
FLAC__file_decoder_process_until_end_of_metadata(decoder);
isBigEndian = hostIsBigEndian();
return YES;
}
- (BOOL)readInfo:(const char *)filename
{
FLAC__StreamMetadata streamInfo;
FLAC__metadata_get_streaminfo(filename, &streamInfo);
channels = streamInfo.data.stream_info.channels;
frequency = streamInfo.data.stream_info.sample_rate;
bitsPerSample = streamInfo.data.stream_info.bits_per_sample;
totalSize = streamInfo.data.stream_info.total_samples*channels*(bitsPerSample/8);
bitrate = 0;
return YES;
}
- (int)fillBuffer:(void *)buf ofSize:(UInt32)size
{
int count;
int numread;
if (bufferAmount == 0)
{
int i;
if (FLAC__file_decoder_get_state (decoder) == FLAC__FILE_DECODER_END_OF_FILE)
{
return 0;
}
i = FLAC__file_decoder_process_single(decoder);// != FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE);
//return 0;
// [self writeSamplesToBuffer:buffer fromBuffer:sampleBuffer ofSize:(status*2)];
// write callback sets bufferAmount...frickin weird, also sets sampleBuffer
// bufferAmount = status*4;
}
count = bufferAmount;
if (bufferAmount > size)
{
count = size;
}
memcpy(buf, buffer, count);
bufferAmount -= count;
if (bufferAmount > 0)
memmove(buffer, &buffer[count], bufferAmount);
if (count < size)
numread = [self fillBuffer:(&((char *)buf)[count]) ofSize:(size - count)];
else
numread = 0;
return count + numread;
}
- (void)close
{
if (decoder)
{
FLAC__file_decoder_finish(decoder);
FLAC__file_decoder_delete(decoder);
}
decoder = NULL;
}
- (double)seekToTime:(double)milliseconds
{
FLAC__file_decoder_seek_absolute(decoder, frequency * ((double)milliseconds/1000.0));
return milliseconds;
}
//bs methods
- (char *)buffer
{
return buffer;
}
- (int)bufferAmount
{
return bufferAmount;
}
- (void)setBufferAmount:(int)amount
{
bufferAmount = amount;
}
- (FLAC__FileDecoder *)decoder
{
return decoder;
}
@end

View File

@ -1,19 +0,0 @@
//
// GameFile.h
// Cog
//
// Created by Vincent Spader on 5/29/06.
// Copyright 2006 Vincent Spader. 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

View File

@ -1,110 +0,0 @@
//
// GameFile.m
// Cog
//
// Created by Vincent Spader on 5/29/06.
// Copyright 2006 Vincent Spader. 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

@ -1,39 +0,0 @@
//
// MADFile.h
// Cog
//
// Created by Vincent Spader on 6/17/06.
// Copyright 2006 Vincent Spader. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "SoundFile.h"
#undef HAVE_CONFIG_H
#import "MAD/mad.h"
#define INPUT_BUFFER_SIZE 5*8192
@interface MADFile : SoundFile {
struct mad_stream _stream;
struct mad_frame _frame;
struct mad_synth _synth;
mad_timer_t _timer;
mad_timer_t _duration;
unsigned char _inputBuffer[INPUT_BUFFER_SIZE+MAD_BUFFER_GUARD];
unsigned char *_outputBuffer;
int _outputAvailable;
int _fileSize;
FILE *_inFd;
BOOL _seekSkip;
//For gapless playback of mp3s
BOOL _gapless;
long _currentFrame;
int _startPadding;
int _endPadding;
}
@end

View File

@ -1,570 +0,0 @@
//
// MADFile.m
// Cog
//
// Created by Vincent Spader on 6/17/06.
// Copyright 2006 Vincent Spader. All rights reserved.
//
#import "MADFile.h"
#undef HAVE_CONFIG_H
#import <ID3Tag/id3tag.h>
@implementation MADFile
/*XING FUN*/
#define XING_MAGIC (('X' << 24) | ('i' << 16) | ('n' << 8) | 'g')
#define INFO_MAGIC (('I' << 24) | ('n' << 16) | ('f' << 8) | 'o')
#define LAME_MAGIC (('L' << 24) | ('A' << 16) | ('M' << 8) | 'E')
struct xing
{
long flags; /* valid fields (see below) */
unsigned long frames; /* total number of frames */
unsigned long bytes; /* total number of bytes */
unsigned char toc[100]; /* 100-point seek table */
long scale; /* ?? */
};
struct lame
{
long flags;
};
enum
{
XING_FRAMES = 0x00000001L,
XING_BYTES = 0x00000002L,
XING_TOC = 0x00000004L,
XING_SCALE = 0x00000008L
};
int lame_parse(struct lame *lame, struct mad_bitptr *ptr, unsigned int bitlen)
{
unsigned long magic;
unsigned long garbage;
magic = mad_bit_read(ptr, 32); //4 bytes
if (magic != LAME_MAGIC)
return 0;
mad_bit_skip(ptr, 17*8); //17 bytes skipped
garbage = mad_bit_read(ptr, 24); //3 bytes
// _startPadding = (garbage >> 12) & 0x000FFF;
// _endPadding = garbage & 0x000FFF;
return 1;
}
int xing_parse(struct xing *xing, struct mad_bitptr *ptr, unsigned int bitlen)
{
xing->flags = 0;
unsigned long magic;
if (bitlen < 64)
return 0;
magic = mad_bit_read(ptr, 32);
if (magic != INFO_MAGIC && magic != XING_MAGIC)
return 0;
xing->flags = mad_bit_read(ptr, 32);
bitlen -= 64;
if (xing->flags & XING_FRAMES) {
if (bitlen < 32)
return 0;
xing->frames = mad_bit_read(ptr, 32);
bitlen -= 32;
}
if (xing->flags & XING_BYTES) {
if (bitlen < 32)
return 0;
xing->bytes = mad_bit_read(ptr, 32);
bitlen -= 32;
}
if (xing->flags & XING_TOC) {
int i;
if (bitlen < 800)
return 0;
for (i = 0; i < 100; ++i)
xing->toc[i] = mad_bit_read(ptr, 8);
bitlen -= 800;
}
if (xing->flags & XING_SCALE) {
if (bitlen < 32)
return 0;
xing->scale = mad_bit_read(ptr, 32);
bitlen -= 32;
}
return 1;
}
int parse_headers(struct xing *xing, struct lame *lame, struct mad_bitptr ptr, unsigned int bitlen)
{
xing->flags = 0;
lame->flags = 0;
if (xing_parse(xing, &ptr, bitlen))
{
lame_parse(lame, &ptr, bitlen);
return 1;
}
return 0;
}
- (BOOL)scanFileFast:(BOOL)fast useXing:(BOOL)use_xing
{
const int BUFFER_SIZE = 16*1024;
const int N_AVERAGE_FRAMES = 10;
struct mad_stream stream;
struct mad_header header;
struct mad_frame frame; /* to read xing data */
struct xing xing;
struct lame lame;
int remainder = 0;
int data_used = 0;
int len = 0;
int tagsize = 0;
int frames = 0;
unsigned char buffer[BUFFER_SIZE];
BOOL has_xing = NO;
BOOL vbr = NO;
mad_stream_init (&stream);
mad_header_init (&header);
mad_frame_init (&frame);
bitrate = 0;
_duration = mad_timer_zero;
frames = 0;
fseek(_inFd, 0, SEEK_END);
_fileSize = ftell(_inFd);
fseek(_inFd, 0, SEEK_SET);
BOOL done = NO;
while (!done)
{
remainder = stream.bufend - stream.next_frame;
memcpy (buffer, stream.this_frame, remainder);
len = fread(buffer + remainder, 1, BUFFER_SIZE - remainder, _inFd);
if (len <= 0)
break;
mad_stream_buffer (&stream, buffer, len + remainder);
while (1)
{
if (mad_header_decode (&header, &stream) == -1)
{
if (stream.error == MAD_ERROR_BUFLEN)
{
break;
}
if (!MAD_RECOVERABLE (stream.error))
{
break;
}
if (stream.error == MAD_ERROR_LOSTSYNC)
{
/* ignore LOSTSYNC due to ID3 tags */
tagsize = id3_tag_query (stream.this_frame,
stream.bufend -
stream.this_frame);
if (tagsize > 0)
{
mad_stream_skip (&stream, tagsize);
continue;
}
}
continue;
}
frames++;
mad_timer_add (&_duration, header.duration);
data_used += stream.next_frame - stream.this_frame;
if (frames == 1)
{
/* most of these *should* remain constant */
bitrate = header.bitrate;
frequency = header.samplerate;
channels = MAD_NCHANNELS(&header);
if (use_xing)
{
frame.header = header;
if (mad_frame_decode(&frame, &stream) == -1)
continue;
if (parse_headers(&xing, &lame, stream.anc_ptr, stream.anc_bitlen))
{
has_xing = YES;
vbr = YES;
frames = xing.frames;
mad_timer_multiply (&_duration, frames);
bitrate = 8.0 * xing.bytes / mad_timer_count(_duration, MAD_UNITS_SECONDS);
done = YES;
break;
}
}
}
else
{
/* perhaps we have a VBR file */
if (bitrate != header.bitrate)
vbr = YES;
if (vbr)
bitrate += header.bitrate;
}
if ((!vbr || (vbr && !has_xing)) && fast && frames >= N_AVERAGE_FRAMES)
{
float frame_size = ((double)data_used) / N_AVERAGE_FRAMES;
frames = (_fileSize - tagsize) / frame_size;
_duration.seconds /= N_AVERAGE_FRAMES;
_duration.fraction /= N_AVERAGE_FRAMES;
mad_timer_multiply (&_duration, frames);
done = YES;
break;
}
}
if (stream.error != MAD_ERROR_BUFLEN)
break;
}
if (vbr && !has_xing)
bitrate = bitrate / frames;
mad_frame_finish (&frame);
mad_header_finish (&header);
mad_stream_finish (&stream);
totalSize = (mad_timer_count(_duration, MAD_UNITS_MILLISECONDS)*(frequency/1000.0))*channels*(bitsPerSample/8);
bitrate /= 1000;
NSLog(@"BITRATE: %i %i", bitrate, vbr);
fseek(_inFd, 0, SEEK_SET);
return frames != 0;
}
- (BOOL)open:(const char *)filename
{
/* First the structures used by libmad must be initialized. */
mad_stream_init(&_stream);
mad_frame_init(&_frame);
mad_synth_init(&_synth);
mad_timer_reset(&_timer);
_inFd = fopen(filename, "r");
if (!_inFd)
return NO;
bitsPerSample = 16;
isBigEndian=YES;
isUnsigned=NO;
return [self scanFileFast:YES useXing:YES];
}
- (BOOL)readInfo:(const char *)filename
{
return [self open:filename];
}
/**
* Scale PCM data
*/
static inline signed int scale (mad_fixed_t sample)
{
BOOL hard_limit = YES;
// BOOL replaygain = NO;
/* replayGain by SamKR */
double scale = -1;
/* if (replaygain)
{
if (file_info->has_replaygain)
{
scale = file_info->replaygain_track_scale;
if (file_info->replaygain_album_scale != -1
&& (scale==-1 || ! xmmsmad_config.replaygain.track_mode))
{
scale = file_info->replaygain_album_scale;
}
}
if (scale == -1)
scale = xmmsmad_config.replaygain.default_scale;
}
*/
if (scale == -1)
scale = 1.0;
/* hard-limit (clipping-prevention) */
if (hard_limit)
{
/* convert to double before computation, to avoid mad_fixed_t wrapping */
double x = mad_f_todouble(sample) * scale;
static const double k = 0.5; // -6dBFS
if (x > k)
{
x = tanh((x - k) / (1-k)) * (1-k) + k;
}
else if(x < -k)
{
x = tanh((x + k) / (1-k)) * (1-k) - k;
}
sample = x * (MAD_F_ONE);
}
else
sample *= scale;
int n_bits_to_loose = MAD_F_FRACBITS + 1 - 16;
/* round */
/* add half of the bits_to_loose range to round */
sample += (1L << (n_bits_to_loose - 1));
/* clip */
/* make sure we are between -1 and 1 */
if (sample >= MAD_F_ONE)
{
sample = MAD_F_ONE - 1;
}
else if (sample < -MAD_F_ONE)
{
sample = -MAD_F_ONE;
}
/* quantize */
/*
* Turn our mad_fixed_t into an integer.
* Shift all but 16-bits of the fractional part
* off the right hand side and shift an extra place
* to get the sign bit.
*/
sample >>= n_bits_to_loose;
return sample;
}
- (void)writeOutput
{
unsigned int nsamples;
mad_fixed_t const *left_ch, *right_ch;
// if (_outputAvailable) {
// NSLog(@"Losing Output: %i", _outputAvailable);
// }
nsamples = _synth.pcm.length;
left_ch = _synth.pcm.samples[0];
right_ch = _synth.pcm.samples[1];
_outputAvailable = nsamples * channels * (bitsPerSample/8);
if (_outputBuffer)
free(_outputBuffer);
_outputBuffer = (unsigned char *) malloc (_outputAvailable * sizeof (char));
unsigned char *outputPtr = _outputBuffer;
int i;
for (i=0; i < nsamples; i++)
{
signed short sample;
/* output sample(s) in 16-bit signed little-endian PCM */
sample = scale(left_ch[i]);
*(outputPtr++) = sample>>8;
*(outputPtr++) = sample & 0xff;
if (channels == 2)
{
sample = scale(right_ch[i]);
*(outputPtr++) = sample>>8;
*(outputPtr++) = sample & 0xff;
}
}
}
- (int)fillBuffer:(void *)buf ofSize:(UInt32)size
{
int remainder;
int len;
BOOL eof = NO;
int amountToCopy = size;
int amountRemaining = size;
if (amountToCopy > _outputAvailable)
amountToCopy = _outputAvailable;
if (amountToCopy) {
memcpy(buf, _outputBuffer, amountToCopy);
memmove(_outputBuffer, _outputBuffer + amountToCopy, _outputAvailable - amountToCopy);
amountRemaining -= amountToCopy;
_outputAvailable -= amountToCopy;
}
while (amountRemaining > 0 && !eof) {
if (_stream.buffer == NULL || _stream.error == MAD_ERROR_BUFLEN)
{
if (!_seekSkip)
{
remainder = _stream.bufend - _stream.next_frame;
if (remainder)
memmove(_inputBuffer, _stream.this_frame, remainder);
}
else
{
remainder = 0;
}
len = fread(_inputBuffer+remainder, 1, INPUT_BUFFER_SIZE-remainder, _inFd);
if (len <= 0)
{
eof = YES;
break;
}
len += remainder;
if (len < MAD_BUFFER_GUARD) {
int i;
for (i = len; i < MAD_BUFFER_GUARD; i++)
_inputBuffer[i] = 0;
len = MAD_BUFFER_GUARD;
}
mad_stream_buffer(&_stream, _inputBuffer, len);
_stream.error = 0;
if (_seekSkip)
{
int skip = 2;
do
{
if (mad_frame_decode (&_frame, &_stream) == 0)
{
mad_timer_add (&_timer, _frame.header.duration);
if (--skip == 0)
mad_synth_frame (&_synth, &_frame);
}
else if (!MAD_RECOVERABLE (_stream.error))
break;
} while (skip);
_seekSkip = NO;
}
}
if (mad_frame_decode(&_frame, &_stream) == -1) {
if (!MAD_RECOVERABLE (_stream.error))
{
if(_stream.error==MAD_ERROR_BUFLEN) {
continue;
}
eof = YES;
}
if (_stream.error == MAD_ERROR_LOSTSYNC)
{
// ignore LOSTSYNC due to ID3 tags
int tagsize = id3_tag_query (_stream.this_frame,
_stream.bufend -
_stream.this_frame);
if (tagsize > 0)
{
mad_stream_skip (&_stream, tagsize);
}
}
continue;
}
mad_timer_add (&_timer, _frame.header.duration);
mad_synth_frame (&_synth, &_frame);
[self writeOutput];
amountToCopy = amountRemaining;
if (amountToCopy > _outputAvailable) {
amountToCopy = _outputAvailable;
}
if (amountRemaining < amountToCopy) {
amountToCopy = amountRemaining;
}
memcpy(((char *)buf)+(size-amountRemaining), _outputBuffer, amountToCopy);
memmove(_outputBuffer, _outputBuffer + amountToCopy, _outputAvailable - amountToCopy);
amountRemaining -= amountToCopy;
_outputAvailable -= amountToCopy;
}
return (size - amountRemaining);
}
- (void)close
{
fclose(_inFd);
mad_synth_finish(&_synth);
mad_frame_finish(&_frame);
mad_stream_finish(&_stream);
}
- (double)seekToTime:(double)milliseconds
{
int new_position;
int seconds = milliseconds/1000.0;
int total_seconds = mad_timer_count(_duration, MAD_UNITS_SECONDS);
if (seconds > total_seconds)
seconds = total_seconds;
mad_timer_set(&_timer, seconds, 0, 0);
new_position = ((double) seconds / (double) total_seconds) * _fileSize;
fseek(_inFd, new_position, SEEK_SET);
mad_stream_sync(&_stream);
_stream.error = MAD_ERROR_BUFLEN;
_stream.sync = 0;
_outputAvailable = 0;
mad_frame_mute(&_frame);
mad_synth_mute(&_synth);
_seekSkip = YES;
return seconds*1000.0;
}
@end

View File

@ -1,19 +0,0 @@
//
// MonkeysFile.h
// zyVorbis
//
// Created by Vincent Spader on 1/30/05.
// Copyright 2005 Vincent Spader All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import <MAC/All.h>
#import <MAC/MACLib.h>
#import "SoundFile.h"
@interface MonkeysFile : SoundFile {
IAPEDecompress * decompress;
}
@end

View File

@ -1,83 +0,0 @@
//
// MonkeysFile.m
// zyVorbis
//
// Created by Vincent Spader on 1/30/05.
// Copyright 2005 Vincent Spader All rights reserved.
//
#import "MonkeysFile.h"
#import "MAC/ApeInfo.h"
#import "MAC/CharacterHelper.h"
@implementation MonkeysFile
- (BOOL)open:(const char *)filename
{
int n;
str_utf16 *chars = NULL;
chars = GetUTF16FromUTF8((const unsigned char *)filename);
if(chars == NULL)
return NO;
decompress = CreateIAPEDecompress(chars, &n);
free(chars);
if (decompress == NULL)
{
DBLog(@"ERROR OPENING FILE");
return NO;
}
frequency = decompress->GetInfo(APE_INFO_SAMPLE_RATE);
bitsPerSample = decompress->GetInfo(APE_INFO_BITS_PER_SAMPLE);
channels = decompress->GetInfo(APE_INFO_CHANNELS);
totalSize = decompress->GetInfo(APE_INFO_TOTAL_BLOCKS)*bitsPerSample/8*channels;
return YES;
}
- (BOOL)readInfo:(const char *)filename
{
return [self open:filename];
}
- (int)fillBuffer:(void *)buf ofSize:(UInt32)size
{
int n;
int numread;
int blockAlign = decompress->GetInfo(APE_INFO_BLOCK_ALIGN);
n = decompress->GetData((char *)buf, size/blockAlign, &numread);
if (n != ERROR_SUCCESS)
{
DBLog(@"ERROR: %i", n);
return 0;
}
numread *= blockAlign;
// DBLog(@"READ DATA: %i", numread);
// DBLog(@"NUMREAD: %i", numread);
return numread;
}
- (void)close
{
// DBLog(@"CLOSE");
if (decompress)
delete decompress;
decompress = NULL;
}
- (double)seekToTime:(double)milliseconds
{
int r;
// DBLog(@"HELLO: %i", int(frequency*((double)milliseconds/1000.0)));
r = decompress->Seek(int(frequency*((double)milliseconds/1000.0)));
return milliseconds;
}
@end

View File

@ -1,30 +0,0 @@
//
// MusepackFile.h
// zyVorbis
//
// Created by Vincent Spader on 1/23/05.
// Copyright 2005 Vincent Spader All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import <MPCDec/mpcdec.h>
#import "SoundFile.h"
@interface MusepackFile : SoundFile {
FILE *inFd;
mpc_decoder decoder;
mpc_reader_file reader;
mpc_streaminfo info;
// int undecodedSize;
char buffer[MPC_FRAME_LENGTH*4];
int bufferAmount;
}
- (BOOL)writeSamplesToBuffer:(uint16_t *)sample_buffer fromBuffer:(const MPC_SAMPLE_FORMAT *)p_buffer ofSize:(unsigned)p_size;
//- (FILE *)inFd;
//- (int)undecodedSize;
@end

View File

@ -1,213 +0,0 @@
//
// MusepackFile.m
// zyVorbis
//
// Created by Vincent Spader on 1/23/05.
// Copyright 2005 Vincent Spader All rights reserved.
//
#import "MusepackFile.h"
@implementation MusepackFile
//callbacks
/*
mpc_int32_t ReadProc(void *data, void *ptr, mpc_int32_t size)
{
DBLog(@"Reading: %i", size);
MusepackFile *f = (MusepackFile *) data;
return fread(ptr, 1, size, [f inFd]);
}
BOOL SeekProc(void *data, mpc_int32_t offset)
{
MusepackFile *f = (MusepackFile *) data;
// DBLog(@"Seeking: %i %i", offset, f->reader.is_seekable);
return !fseek([f inFd], offset, SEEK_SET);
}
mpc_int32_t TellProc(void *data)
{
DBLog(@"Tell");
MusepackFile *f = (MusepackFile *) data;
return ftell([f inFd]);
}
mpc_int32_t GetSizeProc(void *data)
{
DBLog(@"Size");
MusepackFile *f = (MusepackFile *) data;
return [f undecodedSize];
}
BOOL CanSeekProc(void *data)
{
DBLog(@"Can seek");
MusepackFile *f = (MusepackFile *) data;
return YES;
}
*/
//real ish
- (BOOL)open:(const char *)filename
{
if ([self readInfo:filename] == NO)
return NO;
/* instantiate a decoder with our file reader */
mpc_decoder_setup(&decoder, &reader);
if (!mpc_decoder_initialize(&decoder, &info))
{
DBLog(@"Error initializing decoder.");
return NO;
}
// DBLog(@"Ok to go...");
isBigEndian = hostIsBigEndian();
return YES;
}
- (BOOL)readInfo:(const char *)filename
{
inFd = fopen(filename, "rb");
if (inFd == 0)
return NO;
mpc_reader_setup_file_reader(&reader , inFd);
mpc_streaminfo_init(&info);
if (mpc_streaminfo_read(&info, &reader) != ERROR_CODE_OK)
{
DBLog(@"Not a valid musepack file.");
return NO;
}
bitrate = (int)(info.average_bitrate/1000.0);
frequency = info.sample_freq;
bitsPerSample = 16;
channels = 2;
totalSize = mpc_streaminfo_get_length_samples(&info)*channels*bitsPerSample/8;
return YES;
}
- (BOOL)writeSamplesToBuffer:(uint16_t *)sample_buffer fromBuffer:(const MPC_SAMPLE_FORMAT *)p_buffer ofSize:(unsigned)p_size
{
unsigned n;
int m_bps = 16;
int clip_min = - 1 << (m_bps - 1),
clip_max = (1 << (m_bps - 1)) - 1,
float_scale = 1 << (m_bps - 1);
for (n = 0; n < p_size; n++)
{
int val;
#ifdef MPC_FIXED_POINT
val = shift_signed( p_buffer[n], m_bps - MPC_FIXED_POINT_SCALE_SHIFT );
#else
val = (int)( p_buffer[n] * float_scale );
#endif
if (val < clip_min)
val = clip_min;
else if (val > clip_max)
val = clip_max;
// sample_buffer[n] = CFSwapInt16LittleToHost(val);
sample_buffer[n] = val;
}
// DBLog(@"Samples written.");
// m_data_bytes_written += p_size * (m_bps >> 3);
return YES;
}
- (int)fillBuffer:(void *)buf ofSize:(UInt32)size
{
int numread = bufferAmount;
int count = 0;
MPC_SAMPLE_FORMAT sampleBuffer[MPC_DECODER_BUFFER_LENGTH];
// DBLog(@"Fill buffer: %i", size);
//Fill from buffer, going by bufferAmount
//if still needs more, decode and repeat
if (bufferAmount == 0)
{
/* returns the length of the samples*/
unsigned status = mpc_decoder_decode(&decoder, sampleBuffer, 0, 0);
if (status == (unsigned)( -1))
{
//decode error
DBLog(@"Decode error");
return 0;
}
else if (status == 0) //EOF
{
// DBLog(@"AHHHHHH EOF");
return 0;
}
else //status>0 /* status == MPC_FRAME_LENGTH */
{
[self writeSamplesToBuffer:((uint16_t*)buffer) fromBuffer:sampleBuffer ofSize:(status*2)];
}
bufferAmount = status*4;
}
count = bufferAmount;
if (bufferAmount > size)
{
count = size;
}
memcpy(buf, buffer, count);
bufferAmount -= count;
if (bufferAmount > 0)
memmove(buffer, &buffer[count], bufferAmount);
if (count < size)
numread = [self fillBuffer:(&((char *)buf)[count]) ofSize:(size - count)];
else
numread = 0;
return count + numread;
}
- (void)close
{
fclose(inFd);
}
- (double)seekToTime:(double)milliseconds
{
BOOL r;
// double n = milliseconds;
// DBLog(@"Milliseconds: %f", n);
// DBLog(@"SEEKING TO: %f", (double)milliseconds/1000.0);
r = mpc_decoder_seek_sample(&decoder, frequency*((double)milliseconds/1000.0));
// DBLog(@"SEEK RESULT: %i", r);
return milliseconds;
}
//accessors
/*
- (FILE *)inFd
{
return inFd;
}
- (int)undecodedSize
{
return undecodedSize;
}
*/
@end

View File

@ -1,24 +0,0 @@
//
// ShnFile.h
// Cog
//
// Created by Vincent Spader on 6/6/05.
// Copyright 2005 Vincent Spader All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import <Shorten/shn_reader.h>
#import "SoundFile.h"
@interface ShnFile : SoundFile {
//shn_file *handle;
shn_reader *decoder;
long bufferSize; //total size
void *buffer;
void *inputBuffer;//derek
long bufferAmount; //amount currently in
}
@end

View File

@ -1,158 +0,0 @@
//
// ShnFile.mm
// Cog
//
// Created by Vincent Spader on 6/6/05.
// Copyright 2005 Vincent Spader All rights reserved.
//
#import "ShnFile.h"
@implementation ShnFile
- (BOOL)open:(const char *)filename
{
if ([self readInfo:filename] == NO)
return NO;
return YES;
}
- (BOOL)readInfo:(const char *)filename
{
decoder = new shn_reader;
if (!decoder)
{
return NO;
}
decoder->open(filename, true);
bufferSize = decoder->shn_get_buffer_block_size(512);
buffer = malloc(bufferSize);
unsigned int length;
int chan;
float freq;
int bps;
decoder->file_info(NULL, &chan, &freq, NULL, &bps, NULL);
/*NSLog(@"chan: %d",chan);
NSLog(@"freq: %f",freq);
NSLog(@"bps: %d",bps);*/
channels = chan;
frequency = (int)freq;
bitsPerSample = bps;
/*NSLog(@"channels: %d",channels);
NSLog(@"frequency: %f",(double)frequency);
NSLog(@"bitsPerSample: %d",bitsPerSample);*/
length = decoder->shn_get_song_length();
//NSLog(@"length: %d",length);
totalSize = (((double)(length)*frequency)/1000.0) * channels * (bitsPerSample/8);
bitrate = (int)((double)totalSize/((double)length/1000.0));
/*NSLog(@"totalSize: %d",totalSize);
NSLog(@"bitrate: %d",bitrate);*/
decoder->go();
return YES;
}
- (int)fillBuffer:(void *)buf ofSize:(UInt32)size
{
//long numread = bufferAmount;
//long count = 0;
long numread, count;
bufferAmount = 0;
inputBuffer = malloc(bufferSize);
//Fill from buffer, going by bufferAmount
//if still needs more, decode and repeat
if (bufferAmount == 0)
{
//bufferAmount = shn_read(handle, buffer, bufferSize);
while((bufferAmount = decoder->read(inputBuffer, bufferSize)) == (unsigned)(-1))
{
bufferAmount = decoder->read(inputBuffer, bufferSize);
}
if (bufferAmount == 0)
return 0;
else if(bufferAmount == (unsigned)( -2))
{
//NSLog(@"closing file, eof");
return -2;
}
else
{
memcpy(buffer, inputBuffer, bufferAmount);
free(inputBuffer);
}
}
//NSLog(@"bufferAmount: %d",bufferAmount);
count = bufferAmount;
if (bufferAmount > size)
{
count = size;
}
memcpy(buf, buffer, count);
bufferAmount -= count;
if (bufferAmount > 0)
memmove(buffer, (&((char *)buffer)[count]), bufferAmount);
if (count < size)
numread = [self fillBuffer:(&((char *)buf)[count]) ofSize:(size - count)];
else
numread = 0;
return count + numread;
}
- (double)seekToTime:(double)milliseconds
{
unsigned int sec;
/*if (!shn_seekable(handle))
return -1.0;*/
sec = (int)(milliseconds/1000.0);
//shn_seek(handle, sec);
decoder->seek(sec);
return (sec * 1000.0);
}
- (void)close
{
if(decoder)
{
decoder->exit();
delete decoder;
decoder = NULL;
}
if (buffer)
{
free(buffer);
buffer = NULL;
}
/*if (shn_cleanup_decoder(handle))
shn_unload(handle);*/
}
@end

View File

@ -1,64 +0,0 @@
//
// SoundFile.h
// Cog
//
// Created by Vincent Spader on 1/15/05.
// Copyright 2005 Vincent Spader All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import <CoreAudio/AudioHardware.h>
#import <AudioToolbox/AudioToolbox.h>
#import <AudioUnit/AudioUnit.h>
#import "DBLog.h"
#ifdef __cplusplus
extern "C" {
#endif
BOOL hostIsBigEndian();
#ifdef __cplusplus
}
#endif
@interface SoundFile : NSObject {
UInt16 bitsPerSample;
UInt16 channels;
UInt32 frequency;
UInt32 bitrate;
BOOL isBigEndian;
BOOL isUnsigned;
unsigned long totalSize;
}
- (unsigned long)totalSize;
- (double)length;
- (int)bitrate;
+ (SoundFile *)soundFileFromFilename:(NSString *)filename; //PRIVATE
+ (SoundFile *)open:(NSString *)filename;
+ (SoundFile *)readInfo:(NSString *)filename;
- (BOOL)open:(const char *)filename;
- (void)getFormat:(AudioStreamBasicDescription *)sourceStreamFormat;
- (BOOL)readInfo:(const char *)filename; //for getting information
- (int)fillBuffer:(void *)buf ofSize:(UInt32)size;
//- (BOOL)seek:(unsigned long)position;
- (double)seekToTime:(double)milliseconds;
- (void)close;
- (void)reset; //START AGAIN
- (UInt16)channels;
- (UInt16)bitsPerSample;
- (UInt32)frequency;
-(BOOL)isBigEndian;
-(BOOL)isUnsigned;
@end

View File

@ -1,260 +0,0 @@
//
// SoundFile.m
// Cog
//
// Created by Vincent Spader on 1/15/05.
// Copyright 2005 Vincent Spader All rights reserved.
//
#import "SoundFile.h"
#import "FlacFile.h"
//#import "AACFile.h"
#import "MonkeysFile.h"
//#import "MPEGFile.h"
#import "MusepackFile.h"
#import "VorbisFile.h"
//#import "WaveFile.h"
#import "WavPackFile.h"
#import "ShnFile.h"
#import "CoreAudioFile.h"
//#import "GameFile.h"
#import "MadFile.h"
//Something is redefining BOOL
#undef BOOL
extern "C" {
BOOL hostIsBigEndian()
{
#ifdef __BIG_ENDIAN__
return YES;
#else
return NO;
#endif
}
extern NSArray * getCoreAudioExtensions();
};
@implementation SoundFile
/*- (void)seek:(unsigned long)position
{
unsigned long time;
unsigned long frame;
frame = position/channels/(bitsPerSample/8);
time = (unsigned long)(((double)frame/(frequency/1000.0)));
currentPosition = position;
time = [self seekToTime:time];
position = time * (frequency/1000.0)*chanels*(bitsPerSample/8)
}
*/
- (double)length
{
return (totalSize/channels/(bitsPerSample/8)/(frequency/1000.0));
}
- (int)bitrate
{
return bitrate;
}
//this should be done by the soundfile....not seek...
- (double)seekToTime:(double)milliseconds
{
return -1.0;
}
/*
@class FlacFile;
@class MonkeysFile;
@class MPEGFile;
@class MusepackFile;
@class VorbisFile;
@class WaveFile;
@class AACFile;
@class WavPackFile;
@class ShnFile;
*/
+ (SoundFile *)soundFileFromFilename:(NSString *)filename
{
SoundFile *soundFile;
NSString *extension;
DBLog(@"Filename: %@", filename);
extension = [filename pathExtension];
/*if (([[filename pathExtension] caseInsensitiveCompare:@"wav"] == NSOrderedSame) || ([[filename pathExtension] caseInsensitiveCompare:@"aiff"] == NSOrderedSame) || ([[filename pathExtension] caseInsensitiveCompare:@"aif"] == NSOrderedSame))
{
soundFile = [[WaveFile alloc] init];
}*/
if ([[filename pathExtension] caseInsensitiveCompare:@"ogg"] == NSOrderedSame)
{
soundFile = [[VorbisFile alloc] init];
}
else if ([[filename pathExtension] caseInsensitiveCompare:@"mpc"] == NSOrderedSame)
{
soundFile = [[MusepackFile alloc] init];
}
else if ([[filename pathExtension] caseInsensitiveCompare:@"flac"] == NSOrderedSame)
{
soundFile = [[FlacFile alloc] init];
}
else if ([[filename pathExtension] caseInsensitiveCompare:@"ape"] == NSOrderedSame)
{
soundFile = [[MonkeysFile alloc] init];
}
else if ([[filename pathExtension] caseInsensitiveCompare:@"mp3"] == NSOrderedSame)
{
soundFile = [[MADFile alloc] init];
}
/*else if ([[filename pathExtension] caseInsensitiveCompare:@"aac"] == NSOrderedSame)
{
soundFile = [[AACFile alloc] init];
}*/
else if ([[filename pathExtension] caseInsensitiveCompare:@"wv"] == NSOrderedSame)
{
soundFile = [[WavPackFile alloc] init];
}
else if ([[filename pathExtension] caseInsensitiveCompare:@"shn"] == NSOrderedSame)
{
soundFile = [[ShnFile alloc] init];
}
else
{
unsigned i;
NSArray *extensions = getCoreAudioExtensions();
soundFile = nil;
for(i = 0; i < [extensions count]; ++i) {
if([[extensions objectAtIndex:i] caseInsensitiveCompare:extension]) {
soundFile = [[CoreAudioFile alloc] init];
break;
}
}
}
return soundFile;
}
+ (SoundFile *)open:(NSString *)filename
{
SoundFile *soundFile;
BOOL b;
soundFile = [SoundFile soundFileFromFilename:filename];
b = [soundFile open:[filename UTF8String]];
if (b == YES)
return soundFile;
return nil;
}
+ (SoundFile *)readInfo:(NSString *)filename
{
BOOL b;
SoundFile *soundFile;
soundFile = [SoundFile soundFileFromFilename:filename];
b = [soundFile readInfo:[filename UTF8String]];
if (b == NO)
return nil;
[soundFile close];
return soundFile;
}
- (void)reset
{
[self seekToTime:0.0];
}
- (void)getFormat:(AudioStreamBasicDescription *)sourceStreamFormat
{
// NSLog(@"Getting format!");
sourceStreamFormat->mFormatID = kAudioFormatLinearPCM;
sourceStreamFormat->mFormatFlags = 0;
sourceStreamFormat->mSampleRate = frequency;
sourceStreamFormat->mBitsPerChannel = bitsPerSample;
sourceStreamFormat->mBytesPerFrame = (bitsPerSample/8)*channels;
sourceStreamFormat->mChannelsPerFrame = channels;
sourceStreamFormat->mFramesPerPacket = 1;
sourceStreamFormat->mBytesPerPacket = (bitsPerSample/8)*channels;
sourceStreamFormat->mReserved = 0;
if (isBigEndian == YES)
{
sourceStreamFormat->mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
sourceStreamFormat->mFormatFlags |= kLinearPCMFormatFlagIsAlignedHigh;
// sourceStreamFormat->mFormatFlags |= kLinearPCMFormatFlagIsNonMixable;
// NSLog(@"FUCKER IS BIG ENDIAN");
}
if (isUnsigned == NO)
sourceStreamFormat->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
}
- (void)close
{
}
- (int)fillBuffer:(void *)buf ofSize:(UInt32)size
{
return 0;
}
- (BOOL)open:(const char *)filename
{
// NSLog(@"WRONG OPEN!!!");
return NO;
}
- (BOOL)readInfo:(const char *)filename
{
return NO;
}
- (unsigned long)totalSize
{
return totalSize;
}
- (UInt16)channels
{
return channels;
}
- (UInt16)bitsPerSample
{
return bitsPerSample;
}
- (UInt32)frequency
{
return frequency;
}
-(BOOL)isBigEndian
{
return isBigEndian;
}
-(BOOL)isUnsigned
{
return isUnsigned;
}
@end

View File

@ -1,28 +0,0 @@
//
// VorbisFile.h
// zyVorbis
//
// Created by Vincent Spader on 1/22/05.
// Copyright 2005 Vincent Spader All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "SoundFile.h"
//config.h things
#define __MACOSX__
#define HAVE_CONFIG_H
#import <Vorbis/vorbisfile.h>
#import <Vorbis/codec.h>
#undef __MACOSX__
#undef HAVE_CONFIG_H
@interface VorbisFile : SoundFile {
FILE *inFd;
OggVorbis_File vorbisRef;
int currentSection;
}
- (BOOL)readInfo;
@end

View File

@ -1,79 +0,0 @@
//
// VorbisFile.m
// zyVorbis
//
// Created by Vincent Spader on 1/22/05.
// Copyright 2005 Vincent Spader All rights reserved.
//
#import "VorbisFile.h"
@implementation VorbisFile
- (BOOL)open:(const char *)filename
{
inFd = fopen(filename, "rb");
if (inFd == 0)
return NO;
if (ov_open(inFd, &vorbisRef, NULL, 0) != 0)
return NO;
return [self readInfo];
}
- (BOOL)readInfo
{
vorbis_info *vi;
vi = ov_info(&vorbisRef, -1);
bitrate = (int)(vi->bitrate_nominal/1000.0);
channels = vi->channels;
bitsPerSample = vi->channels * 8;
frequency = vi->rate;
totalSize = ov_pcm_total(&vorbisRef, -1) * channels * bitsPerSample/8;
// DBLog(@"Ok to go WITH OGG.");
return YES;
}
- (BOOL)readInfo:(const char *)filename
{
[self open:filename]; //automatically invokes readInfo
return YES;
}
- (int)fillBuffer:(void *)buf ofSize:(UInt32)size
{
int numread;
int total = 0;
numread = ov_read(&vorbisRef, &((char *)buf)[total], size - total, 0, bitsPerSample/8, 1, &currentSection);
while (total != size && numread > 0)
{
total += numread;
numread = ov_read(&vorbisRef, &((char *)buf)[total], size - total, 0, bitsPerSample/8, 1, &currentSection);
}
return total;
}
- (void)close
{
ov_clear(&vorbisRef);
}
- (double)seekToTime:(double)milliseconds
{
ov_time_seek(&vorbisRef, (double)milliseconds/1000.0);
return milliseconds;
}
@end

View File

@ -1,18 +0,0 @@
//
// WavPackFile.h
// Cog
//
// Created by Vincent Spader on 6/6/05.
// Copyright 2005 Vincent Spader All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "SoundFile.h"
#import "Wavpack/wputils.h"
@interface WavPackFile : SoundFile {
WavpackContext *wpc;
}
@end

View File

@ -1,86 +0,0 @@
//
// WavPackFile.m
// Cog
//
// Created by Vincent Spader on 6/6/05.
// Copyright 2005 Vincent Spader All rights reserved.
//
#import "WavPackFile.h"
@implementation WavPackFile
- (BOOL)open:(const char *)filename
{
int open_flags = 0;
char error[80];
wpc = WavpackOpenFileInput(filename, error, open_flags, 0);
if (!wpc)
return NO;
channels = WavpackGetNumChannels(wpc);
bitsPerSample = WavpackGetBitsPerSample(wpc);
// bitsPerSample = 32;
NSLog(@"BYTES PER SAMPLE: %i", WavpackGetBitsPerSample(wpc));
NSLog(@"BYTES PER SAMPLE: %i", WavpackGetBytesPerSample(wpc));
frequency = WavpackGetSampleRate(wpc);
int samples;
samples = WavpackGetNumSamples(wpc);
totalSize = samples * channels * (bitsPerSample/8);
bitrate = (int)(WavpackGetAverageBitrate(wpc, TRUE)/1000.0);
isBigEndian = hostIsBigEndian();
return YES;
}
- (BOOL)readInfo:(const char *)filename
{
[self open:filename]; //does the same damn thing
return YES;
}
- (int)fillBuffer:(void *)buf ofSize:(UInt32)size
{
int numsamples;
int n;
void *sampleBuf = malloc(size*2);
numsamples = size/(bitsPerSample/8)/channels;
// DBLog(@"NUM SAMPLES: %i %i", numsamples, size);
n = WavpackUnpackSamples(wpc, sampleBuf, numsamples);
int i;
for (i = 0; i < n*channels; i++)
{
((UInt16 *)buf)[i] = ((UInt32 *)sampleBuf)[i];
}
n *= (bitsPerSample/8)*channels;
free(sampleBuf);
return n;
}
- (double)seekToTime:(double)milliseconds
{
int sample;
sample = frequency*(milliseconds/1000.0);
WavpackSeekSample(wpc, sample);
return milliseconds;
}
- (void)close
{
WavpackCloseFile(wpc);
}
@end