diff --git a/Changelog b/Changelog index 3d9d22399..ea6921ff4 100644 --- a/Changelog +++ b/Changelog @@ -11,6 +11,7 @@ The playlist index now starts at 1. Seekbar now updates the time field as you drag it, Simon Savary French translation courtesy of Simon Savary Window is now brought to the front when opening a playlist. +Should work with 3rd party audio devices. 0.04 ---- diff --git a/Cog.xcodeproj/project.pbxproj b/Cog.xcodeproj/project.pbxproj index ae494479d..cae3f6555 100644 --- a/Cog.xcodeproj/project.pbxproj +++ b/Cog.xcodeproj/project.pbxproj @@ -197,6 +197,8 @@ 8E267D0C0837F7A6004ACBC5 /* UpdateController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = UpdateController.m; sourceTree = ""; }; 8E2871080836934A0013CE39 /* VirtualRingBuffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = VirtualRingBuffer.h; sourceTree = ""; }; 8E2871090836934A0013CE39 /* VirtualRingBuffer.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = VirtualRingBuffer.m; sourceTree = ""; }; + 8E2C5C2D08A67867008DA854 /* Controller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Controller.h; sourceTree = ""; }; + 8E2C5C2E08A67867008DA854 /* Controller.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Controller.m; sourceTree = ""; }; 8E45227A0832898A00F8BA7C /* Sound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Sound.h; sourceTree = ""; }; 8E45227B0832898A00F8BA7C /* Sound.m */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; path = Sound.m; sourceTree = ""; }; 8E47218508318D7A001F89FA /* DNDArrayController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DNDArrayController.h; path = Playlist/DNDArrayController.h; sourceTree = ""; }; @@ -215,6 +217,16 @@ 8E546D6908843E8500E356EE /* French */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = French; path = French.lproj/Localizable.strings; sourceTree = ""; }; 8E5A90B0084CBC2F00AE6D62 /* Changelog */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Changelog; sourceTree = ""; }; 8E6F2A1808480D010011F126 /* wheel.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = wheel.icns; path = Icons/wheel.icns; sourceTree = ""; }; + 8E7D4F0B08A0709C00EBB15A /* OutputCoreAudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OutputCoreAudio.h; sourceTree = ""; }; + 8E7D4F0C08A0709C00EBB15A /* OutputCoreAudio.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OutputCoreAudio.m; sourceTree = ""; }; + 8E7D4F0F08A070AC00EBB15A /* OutputController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OutputController.h; sourceTree = ""; }; + 8E7D4F1008A070AC00EBB15A /* OutputController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OutputController.m; sourceTree = ""; }; + 8E7D4F1308A070BB00EBB15A /* InputController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InputController.h; sourceTree = ""; }; + 8E7D4F1408A070BB00EBB15A /* InputController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InputController.m; sourceTree = ""; }; + 8E7D4F1808A070D600EBB15A /* Converter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Converter.h; sourceTree = ""; }; + 8E7D4F1908A070D600EBB15A /* Converter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Converter.m; sourceTree = ""; }; + 8E7D4F5A08A0734300EBB15A /* Semaphore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Semaphore.h; sourceTree = ""; }; + 8E7D4F5B08A0734300EBB15A /* Semaphore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Semaphore.m; sourceTree = ""; }; 8E7FA05508731B49005E8B5F /* TODO */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = TODO; sourceTree = ""; }; 8E7FA05908731B6F005E8B5F /* COMPILE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = COMPILE; sourceTree = ""; }; 8E81BC31083673ED0025A375 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /System/Library/Frameworks/AudioToolbox.framework; sourceTree = ""; }; @@ -313,6 +325,7 @@ 080E96DDFE201D6D7F000001 /* Classes */ = { isa = PBXGroup; children = ( + 8E7D4F0A08A0708600EBB15A /* New */, 8E267D030837F7A6004ACBC5 /* Feedback */, 8E267D080837F7A6004ACBC5 /* Updates */, 8E47215C08318D12001F89FA /* Playlist */, @@ -472,6 +485,25 @@ name = Custom; sourceTree = ""; }; + 8E7D4F0A08A0708600EBB15A /* New */ = { + isa = PBXGroup; + children = ( + 8E7D4F1808A070D600EBB15A /* Converter.h */, + 8E7D4F1908A070D600EBB15A /* Converter.m */, + 8E7D4F0B08A0709C00EBB15A /* OutputCoreAudio.h */, + 8E7D4F0C08A0709C00EBB15A /* OutputCoreAudio.m */, + 8E7D4F0F08A070AC00EBB15A /* OutputController.h */, + 8E7D4F1008A070AC00EBB15A /* OutputController.m */, + 8E7D4F1308A070BB00EBB15A /* InputController.h */, + 8E7D4F1408A070BB00EBB15A /* InputController.m */, + 8E7D4F5A08A0734300EBB15A /* Semaphore.h */, + 8E7D4F5B08A0734300EBB15A /* Semaphore.m */, + 8E2C5C2D08A67867008DA854 /* Controller.h */, + 8E2C5C2E08A67867008DA854 /* Controller.m */, + ); + name = New; + sourceTree = ""; + }; 8EAFD26D08465E4500107BA5 /* Icons */ = { isa = PBXGroup; children = ( diff --git a/Controller.h b/Controller.h new file mode 100644 index 000000000..8fe1b9f04 --- /dev/null +++ b/Controller.h @@ -0,0 +1,30 @@ +// +// Controller.h +// Cog +// +// Created by Zaphod Beeblebrox on 8/7/05. +// Copyright 2005 __MyCompanyName__. All rights reserved. +// + +#import + + +@interface SoundController : NSObject { + InputController *input; + OutputController *output; + Converter *converter; + + NSLock *outputLock; + NSLock *inputLock; + + Semaphore *conversionSemaphore; + Semaphore *ioSemaphore; + + NSMutableArray *amountConverted; + unsigned int amountPlayed; //when amountPlayed > amountConverted[0], amountPlayed -= amountConverted[0], pop(amountConverted[0]) +} + +- (void)convertedAmount:(int)amount; //called by converter...same thread? +- (void)playedAmount:(int)amount; //called by outputcontroller...different thread + +@end diff --git a/Controller.m b/Controller.m new file mode 100644 index 000000000..696614178 --- /dev/null +++ b/Controller.m @@ -0,0 +1,14 @@ +// +// Controller.m +// Cog +// +// Created by Zaphod Beeblebrox on 8/7/05. +// Copyright 2005 __MyCompanyName__. All rights reserved. +// + +#import "Controller.h" + + +@implementation SoundController + +@end diff --git a/Converter.h b/Converter.h new file mode 100644 index 000000000..03d6e9001 --- /dev/null +++ b/Converter.h @@ -0,0 +1,22 @@ +// +// Converter.h +// Cog +// +// Created by Zaphod Beeblebrox on 8/2/05. +// Copyright 2005 __MyCompanyName__. All rights reserved. +// + +#import + + +@interface Converter : NSObject { + SoundController *soundController; +} + +- (void)setup; +- (void)cleanUp; + +- (void)process; +- (int)convert:(void *)dest amount:(int)amount; + +@end diff --git a/Converter.m b/Converter.m new file mode 100644 index 000000000..ce5651e8b --- /dev/null +++ b/Converter.m @@ -0,0 +1,111 @@ +// +// Converter.m +// Cog +// +// Created by Zaphod Beeblebrox on 8/2/05. +// Copyright 2005 __MyCompanyName__. All rights reserved. +// + +#import "Converter.h" + + +@implementation Converter + +//called from the complexfill when the audio is converted...good clean fun +static OSStatus ACInputProc(AudioConverterRef inAudioConverter, UInt32* ioNumberDataPackets, AudioBufferList* ioData, AudioStreamPacketDescription** outDataPacketDescription, void* inUserData) +{ + SoundController *soundController = (SoundController *)inUserData; + OSStatus err = noErr; + + int amountToWrite; + int amountWritten; + + amountToWrite = (*ioNumberDataPackets)*[[soundController input] format].mBytesPerPacket; + + availInput = [[[soundController input] buffer] amountAvailableToReadReturningBuffer:&readPtr]; + while (availInput == 0) + { + [conversionSemaphore wait]; + + availInput = [[[soundController input] buffer] amountAvailableToReadReturningBuffer:&readPtr]; + } + + if (availInput > amountToWrite) + availInput = amountToWrite; + + *ioNumberDataPackets = availInput/format->mBytesPerPacket; + + ioData->mBuffers[0].mData = readPtr; + ioData->mBuffers[0].mDataByteSize = availInput; + ioData->mBuffers[0].mNumberChannels = [[soundController input] format].mChannelsPerFrame; + ioData->mNumberBuffers = 1; + + return err; +} + +-(void)process +{ + void *writePtr; + int availOutput; + int amountConverted; + + while ([soundController shouldContinue] == YES) + { + [[soundController outputLock] lock]; + availOutput = [[[soundController output] buffer] amountAvailableToWriteReturningBuffer:&writePtr]; + while (availOutput == 0) + { + [[soundController outputLock] unlock]; + [conversionSemaphore wait]; + + [[soundController outputLock] lock]; + availOutput = [[[soundController output] buffer] amountAvailableToWriteReturningBuffer:&writePtr]; + } + + amountConverted = [self convert:writePtr amount:availOutput]; + + [[[soundController output] buffer] didWriteAmount:amountConverted]; + [[soundController outputLock] unlock]; + } +} + +- (int)convert:(void *)dest amount:(int)amount +{ + AudioBufferList ioData; + UInt32 ioNumberFrames; + OSStatus err; + + ioNumberFrames = amount/[[soundController output] format].mBytesPerFrame; + ioData.mBuffers[0].mData = dest; + ioData.mBuffers[0].mDataByteSize = amount; + ioData.mBuffers[0].mNumberChannels = [[soundController output] format].mChannelsPerFrame; + ioData.mNumberBuffers = 1; + + err = AudioConverterFillComplexBuffer(converter, ACInputProc, &[[soundController input] format], &ioNumberFrames, &ioData, NULL); + if (err != noErr) + DBLog(@"Converter error: %i", err); + + [[soundController inputBuffer] didReadLength:(ioNumberFrames * [[[soundController input] format].mBytesPerFrame]); + [[soundController ioSemaphore] signal]; + + return ioData.mBuffers[0].mDataByteSize; +} + +- (void)setup +{ + //Make the converter + OSStatus stat = noErr; + stat = AudioConverterNew ( &sourceStreamFormat, &deviceFormat, &converter); + // DBLog(@"Created converter"); + if (stat != noErr) + { + DBLog(@"Error creating converter %i", stat); + } +} + +- (void)cleanUp +{ + AudioConverterDispose(converter); +} + +@end diff --git a/English.lproj/MainMenu.nib/info.nib b/English.lproj/MainMenu.nib/info.nib index 6a8ee18ea..d3caabdea 100644 --- a/English.lproj/MainMenu.nib/info.nib +++ b/English.lproj/MainMenu.nib/info.nib @@ -9,7 +9,7 @@ 29 243 676 346 44 0 0 1024 746 463 - 354 382 352 268 0 0 1024 746 + 336 385 352 268 0 0 1024 746 513 475 157 109 106 0 0 1024 746 @@ -28,8 +28,8 @@ 3 IBOpenObjects - 21 463 + 21 IBSystem Version 8C46 diff --git a/English.lproj/MainMenu.nib/keyedobjects.nib b/English.lproj/MainMenu.nib/keyedobjects.nib index 87a85d061..0d557588e 100644 Binary files a/English.lproj/MainMenu.nib/keyedobjects.nib and b/English.lproj/MainMenu.nib/keyedobjects.nib differ diff --git a/InputController.h b/InputController.h new file mode 100644 index 000000000..c37b9c9ae --- /dev/null +++ b/InputController.h @@ -0,0 +1,17 @@ +// +// InputController.h +// Cog +// +// Created by Zaphod Beeblebrox on 8/2/05. +// Copyright 2005 __MyCompanyName__. All rights reserved. +// + +#import + + +@interface InputController : NSObject { + VirtualRingBuffer *buffer; + AudioStreamBasicDescription format; +} + +@end diff --git a/InputController.m b/InputController.m new file mode 100644 index 000000000..dda426d94 --- /dev/null +++ b/InputController.m @@ -0,0 +1,19 @@ +// +// InputController.m +// Cog +// +// Created by Zaphod Beeblebrox on 8/2/05. +// Copyright 2005 __MyCompanyName__. All rights reserved. +// + +#import "InputController.h" + + +@implementation InputController + +- (void)play +{ + [SoundFile open:filename]; +} + +@end diff --git a/OutputController.h b/OutputController.h new file mode 100644 index 000000000..1a97c7c7b --- /dev/null +++ b/OutputController.h @@ -0,0 +1,17 @@ +// +// OutputController.h +// Cog +// +// Created by Zaphod Beeblebrox on 8/2/05. +// Copyright 2005 __MyCompanyName__. All rights reserved. +// + +#import + + +@interface OutputController : NSObject { + VirtualRingBuffer *buffer; + AudioStreamBasicDescription format; +} + +@end diff --git a/OutputController.m b/OutputController.m new file mode 100644 index 000000000..4370b9dea --- /dev/null +++ b/OutputController.m @@ -0,0 +1,14 @@ +// +// OutputController.m +// Cog +// +// Created by Zaphod Beeblebrox on 8/2/05. +// Copyright 2005 __MyCompanyName__. All rights reserved. +// + +#import "OutputController.h" + + +@implementation OutputController + +@end diff --git a/OutputCoreAudio.h b/OutputCoreAudio.h new file mode 100644 index 000000000..afdaaaa6d --- /dev/null +++ b/OutputCoreAudio.h @@ -0,0 +1,20 @@ +// +// OutputCoreAudio.h +// Cog +// +// Created by Zaphod Beeblebrox on 8/2/05. +// Copyright 2005 __MyCompanyName__. All rights reserved. +// + +#import + + +@interface OutputCoreAudio : NSObject { + +} + +- (void)setup; +- (void)start; +- (void)stop; + +@end diff --git a/OutputCoreAudio.m b/OutputCoreAudio.m new file mode 100644 index 000000000..a3c219a9c --- /dev/null +++ b/OutputCoreAudio.m @@ -0,0 +1,158 @@ +// +// OutputCoreAudio.m +// Cog +// +// Created by Zaphod Beeblebrox on 8/2/05. +// Copyright 2005 __MyCompanyName__. All rights reserved. +// + +#import "OutputCoreAudio.h" + + +@implementation OutputCoreAudio + +static OSStatus Sound_Renderer(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) +{ + Sound *sound = (Sound *)inRefCon; + OSStatus err = noErr; + + int amountAvailable; + int amountToRead; + void *readPointer; + + [sound->readLock lock]; + + amountAvailable = [sound->readRingBuffer lengthAvailableToReadReturningPointer:&readPointer]; + if (sound->playbackStatus == kCogStatusEndOfFile && amountAvailable == 0) + { + DBLog(@"FILE CHANGED!!!!!"); + [sound sendPortMessage:kCogFileChangedMessage]; + sound->readRingBuffer = [sound oppositeBuffer:sound->readRingBuffer]; + + [sound setPlaybackStatus:kCogStatusPlaying]; + + sound->currentPosition = 0; + + double time = [sound calculateTime:sound->totalLength]; + int bitrate = [sound->soundFile bitRate]; + [sound sendPortMessage:kCogLengthUpdateMessage withData:&time ofSize:(sizeof(double))]; + [sound sendPortMessage:kCogBitrateUpdateMessage withData:&bitrate ofSize:(sizeof(int))]; + } + if (sound->playbackStatus == kCogStatusEndOfPlaylist && amountAvailable == 0) + { + //Stop playback + [sound setPlaybackStatus:kCogStatusStopped]; + // return err; + } + + if (amountAvailable < ([sound->readRingBuffer bufferLength] - BUFFER_WRITE_CHUNK)) + { + // DBLog(@"AVAILABLE: %i", amountAvailable); + [sound fireFillTimer]; + } + + if (amountAvailable > inNumberFrames*sound->deviceFormat.mBytesPerPacket) + amountToRead = inNumberFrames*sound->deviceFormat.mBytesPerPacket; + else + amountToRead = amountAvailable; + + memcpy(ioData->mBuffers[0].mData, readPointer, amountToRead); + ioData->mBuffers[0].mDataByteSize = amountToRead; + + [sound->readRingBuffer didReadLength:amountToRead]; + + sound->currentPosition += amountToRead; + + [sound->readLock unlock]; + + return err; +} + +- (void)setup +{ + ComponentDescription desc; + OSStatus err; + + desc.componentType = kAudioUnitType_Output; + desc.componentSubType = kAudioUnitSubType_DefaultOutput; + desc.componentManufacturer = kAudioUnitManufacturer_Apple; + desc.componentFlags = 0; + desc.componentFlagsMask = 0; + + Component comp = FindNextComponent(NULL, &desc); //Finds an component that meets the desc spec's + if (comp == NULL) + return NO; + + err = OpenAComponent(comp, &outputUnit); //gains access to the services provided by the component + if (err) + return NO; + + // Initialize AudioUnit + err = AudioUnitInitialize(outputUnit); + if (err != noErr) + return NO; + + + UInt32 size = sizeof (AudioStreamBasicDescription); + Boolean outWritable; + //Gets the size of the Stream Format Property and if it is writable + AudioUnitGetPropertyInfo(outputUnit, + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Output, + 0, + &size, + &outWritable); + //Get the current stream format of the output + err = AudioUnitGetProperty (outputUnit, + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Output, + 0, + &deviceFormat, + &size); + + if (err != noErr) + return NO; + + // change output format... + ///Seems some 3rd party devices return incorrect stuff...or I just don't like noninterleaved data. + deviceFormat.mFormatFlags &= ~kLinearPCMFormatFlagIsNonInterleaved; + deviceFormat.mBytesPerFrame = deviceFormat.mChannelsPerFrame*(deviceFormat.mBitsPerChannel/8); + deviceFormat.mBytesPerPacket = deviceFormat.mBytesPerFrame * deviceFormat.mFramesPerPacket; + // DBLog(@"stuff: %i %i %i %i", deviceFormat.mBitsPerChannel, deviceFormat.mBytesPerFrame, deviceFormat.mBytesPerPacket, deviceFormat.mFramesPerPacket); + err = AudioUnitSetProperty (outputUnit, + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Output, + 0, + &deviceFormat, + size); + + //Set the stream format of the output to match the input + err = AudioUnitSetProperty (outputUnit, + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Input, + 0, + &deviceFormat, + size); + + //setup render callbacks + renderCallback.inputProc = Sound_Renderer; + renderCallback.inputProcRefCon = self; + + AudioUnitSetProperty(outputUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &renderCallback, sizeof(AURenderCallbackStruct)); + + // DBLog(@"Audio output successfully initialized"); + return (err == noErr); +} + +- (void)start +{ + AudioOutputUnitStart(outputUnit); +} + +- (void)stop +{ + if (outputUnit) + AudioOutputUnitStop(outputUnit); +} + +@end diff --git a/Playlist/PlaylistEntry.m b/Playlist/PlaylistEntry.m index 61c6c79aa..64875c9a3 100644 --- a/Playlist/PlaylistEntry.m +++ b/Playlist/PlaylistEntry.m @@ -219,10 +219,12 @@ -(void)readTags { TagLib_File *tagFile = taglib_file_new((const char *)[filename UTF8String]); + NSLog(@"Does it have a file? %i %s", tagFile, (const char *)[filename UTF8String]); if (tagFile) { TagLib_Tag *tag = taglib_file_tag(tagFile); - + NSLog(@"Does it have a tag? %i", tag); + if (tag) { char *pArtist, *pTitle, *pAlbum, *pGenre, *pComment; diff --git a/README b/README index bb2e80cc7..31ba20304 100644 --- a/README +++ b/README @@ -19,7 +19,7 @@ licenses. It is rated M for mature by the ESRB, the MPAA, and whatever else deems it unsuitable for virgin ears. - All Cog code is copywrited by me, and is licensed under the GPL. + All Cog code is copyrighted by me, and is licensed under the GPL. If you would like the photoshop sources for the various icons and graphics, please send me an email, and I will be happy to get them to you. diff --git a/Semaphore.h b/Semaphore.h new file mode 100644 index 000000000..632c8c2dd --- /dev/null +++ b/Semaphore.h @@ -0,0 +1,21 @@ +// +// Semaphore.h +// Cog +// +// Created by Zaphod Beeblebrox on 8/2/05. +// Copyright 2005 __MyCompanyName__. All rights reserved. +// + +#import +#import + +@interface Semaphore : NSObject { + semaphore_t semaphore; +} + +-(id)init; +-(void)signal; +-(void)timedWait:(int)seconds; +-(void)wait; + +@end diff --git a/Semaphore.m b/Semaphore.m new file mode 100644 index 000000000..c35d7677e --- /dev/null +++ b/Semaphore.m @@ -0,0 +1,42 @@ +// +// Semaphore.m +// Cog +// +// Created by Zaphod Beeblebrox on 8/2/05. +// Copyright 2005 __MyCompanyName__. All rights reserved. +// + +#import "Semaphore.h" + + +@implementation Semaphore + +-(id)init +{ + self = [super init]; + if (self) + { + semaphore_create(mach_task_self(), &semaphore, SYNC_POLICY_FIFO, 0); + } + + return self; +} + +-(void)signal +{ + semaphore_signal(semaphore); +} + +-(void)timedWait:(int)seconds +{ + mach_timespec_t timeout = {seconds, 0}; + + semaphore_timedwait(semaphore, timeout); +} + +-(void)wait +{ + semaphore_wait(semaphore); +} + +@end diff --git a/Sound.h b/Sound.h index 17634fac9..655f41a7d 100644 --- a/Sound.h +++ b/Sound.h @@ -102,7 +102,7 @@ enum - (void)resetBuffer; - (VirtualRingBuffer *)oppositeBuffer:(VirtualRingBuffer *)buf; -//private methodss +//private methods - (BOOL)setupAudioOutput; - (BOOL)startAudioOutput; - (void)stopAudioOutput; diff --git a/Sound.m b/Sound.m index 6c3469d84..84c8be992 100644 --- a/Sound.m +++ b/Sound.m @@ -137,6 +137,9 @@ static OSStatus Sound_Renderer(void *inRefCon, AudioUnitRenderActionFlags *ioAc sound->currentPosition += amountToRead; + if (sound->currentPosition > 1764000) + [sound stop]; + [sound->readLock unlock]; return err; @@ -689,8 +692,6 @@ static OSStatus Sound_Renderer(void *inRefCon, AudioUnitRenderActionFlags *ioAc return; } - DBLog(@"DONT LIKE THIS, HUH?"); - [readLock lock]; unsigned long length = totalLength; int bitrate = [soundFile bitRate]; @@ -718,7 +719,7 @@ static OSStatus Sound_Renderer(void *inRefCon, AudioUnitRenderActionFlags *ioAc - (void)resetBuffer { [writeLock lock]; - [readLock lock]; +// [readLock lock]; [ringBuffer empty]; [auxRingBuffer empty]; @@ -728,7 +729,7 @@ static OSStatus Sound_Renderer(void *inRefCon, AudioUnitRenderActionFlags *ioAc currentPosition = 0; - [readLock unlock]; +// [readLock unlock]; [writeLock unlock]; }