Added new files
parent
91957a3d72
commit
bb9f463b52
|
@ -11,6 +11,7 @@ The playlist index now starts at 1.
|
|||
Seekbar now updates the time field as you drag it, Simon Savary <savary (at) oricom.ca>
|
||||
French translation courtesy of Simon Savary <savary (at) oricom.ca>
|
||||
Window is now brought to the front when opening a playlist.
|
||||
Should work with 3rd party audio devices.
|
||||
|
||||
0.04
|
||||
----
|
||||
|
|
|
@ -197,6 +197,8 @@
|
|||
8E267D0C0837F7A6004ACBC5 /* UpdateController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = UpdateController.m; sourceTree = "<group>"; };
|
||||
8E2871080836934A0013CE39 /* VirtualRingBuffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = VirtualRingBuffer.h; sourceTree = "<group>"; };
|
||||
8E2871090836934A0013CE39 /* VirtualRingBuffer.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = VirtualRingBuffer.m; sourceTree = "<group>"; };
|
||||
8E2C5C2D08A67867008DA854 /* Controller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Controller.h; sourceTree = "<group>"; };
|
||||
8E2C5C2E08A67867008DA854 /* Controller.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Controller.m; sourceTree = "<group>"; };
|
||||
8E45227A0832898A00F8BA7C /* Sound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Sound.h; sourceTree = "<group>"; };
|
||||
8E45227B0832898A00F8BA7C /* Sound.m */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; path = Sound.m; sourceTree = "<group>"; };
|
||||
8E47218508318D7A001F89FA /* DNDArrayController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DNDArrayController.h; path = Playlist/DNDArrayController.h; sourceTree = "<group>"; };
|
||||
|
@ -215,6 +217,16 @@
|
|||
8E546D6908843E8500E356EE /* French */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = French; path = French.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
8E5A90B0084CBC2F00AE6D62 /* Changelog */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Changelog; sourceTree = "<group>"; };
|
||||
8E6F2A1808480D010011F126 /* wheel.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = wheel.icns; path = Icons/wheel.icns; sourceTree = "<group>"; };
|
||||
8E7D4F0B08A0709C00EBB15A /* OutputCoreAudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OutputCoreAudio.h; sourceTree = "<group>"; };
|
||||
8E7D4F0C08A0709C00EBB15A /* OutputCoreAudio.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OutputCoreAudio.m; sourceTree = "<group>"; };
|
||||
8E7D4F0F08A070AC00EBB15A /* OutputController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OutputController.h; sourceTree = "<group>"; };
|
||||
8E7D4F1008A070AC00EBB15A /* OutputController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OutputController.m; sourceTree = "<group>"; };
|
||||
8E7D4F1308A070BB00EBB15A /* InputController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InputController.h; sourceTree = "<group>"; };
|
||||
8E7D4F1408A070BB00EBB15A /* InputController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InputController.m; sourceTree = "<group>"; };
|
||||
8E7D4F1808A070D600EBB15A /* Converter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Converter.h; sourceTree = "<group>"; };
|
||||
8E7D4F1908A070D600EBB15A /* Converter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Converter.m; sourceTree = "<group>"; };
|
||||
8E7D4F5A08A0734300EBB15A /* Semaphore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Semaphore.h; sourceTree = "<group>"; };
|
||||
8E7D4F5B08A0734300EBB15A /* Semaphore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Semaphore.m; sourceTree = "<group>"; };
|
||||
8E7FA05508731B49005E8B5F /* TODO */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = TODO; sourceTree = "<group>"; };
|
||||
8E7FA05908731B6F005E8B5F /* COMPILE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = COMPILE; sourceTree = "<group>"; };
|
||||
8E81BC31083673ED0025A375 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /System/Library/Frameworks/AudioToolbox.framework; sourceTree = "<absolute>"; };
|
||||
|
@ -313,6 +325,7 @@
|
|||
080E96DDFE201D6D7F000001 /* Classes */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8E7D4F0A08A0708600EBB15A /* New */,
|
||||
8E267D030837F7A6004ACBC5 /* Feedback */,
|
||||
8E267D080837F7A6004ACBC5 /* Updates */,
|
||||
8E47215C08318D12001F89FA /* Playlist */,
|
||||
|
@ -472,6 +485,25 @@
|
|||
name = Custom;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
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 = "<group>";
|
||||
};
|
||||
8EAFD26D08465E4500107BA5 /* Icons */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
//
|
||||
// Controller.h
|
||||
// Cog
|
||||
//
|
||||
// Created by Zaphod Beeblebrox on 8/7/05.
|
||||
// Copyright 2005 __MyCompanyName__. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
|
||||
@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
|
|
@ -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
|
|
@ -0,0 +1,22 @@
|
|||
//
|
||||
// Converter.h
|
||||
// Cog
|
||||
//
|
||||
// Created by Zaphod Beeblebrox on 8/2/05.
|
||||
// Copyright 2005 __MyCompanyName__. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
|
||||
@interface Converter : NSObject {
|
||||
SoundController *soundController;
|
||||
}
|
||||
|
||||
- (void)setup;
|
||||
- (void)cleanUp;
|
||||
|
||||
- (void)process;
|
||||
- (int)convert:(void *)dest amount:(int)amount;
|
||||
|
||||
@end
|
|
@ -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
|
|
@ -9,7 +9,7 @@
|
|||
<key>29</key>
|
||||
<string>243 676 346 44 0 0 1024 746 </string>
|
||||
<key>463</key>
|
||||
<string>354 382 352 268 0 0 1024 746 </string>
|
||||
<string>336 385 352 268 0 0 1024 746 </string>
|
||||
<key>513</key>
|
||||
<string>475 157 109 106 0 0 1024 746 </string>
|
||||
</dict>
|
||||
|
@ -28,8 +28,8 @@
|
|||
<integer>3</integer>
|
||||
<key>IBOpenObjects</key>
|
||||
<array>
|
||||
<integer>21</integer>
|
||||
<integer>463</integer>
|
||||
<integer>21</integer>
|
||||
</array>
|
||||
<key>IBSystem Version</key>
|
||||
<string>8C46</string>
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,17 @@
|
|||
//
|
||||
// InputController.h
|
||||
// Cog
|
||||
//
|
||||
// Created by Zaphod Beeblebrox on 8/2/05.
|
||||
// Copyright 2005 __MyCompanyName__. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
|
||||
@interface InputController : NSObject {
|
||||
VirtualRingBuffer *buffer;
|
||||
AudioStreamBasicDescription format;
|
||||
}
|
||||
|
||||
@end
|
|
@ -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
|
|
@ -0,0 +1,17 @@
|
|||
//
|
||||
// OutputController.h
|
||||
// Cog
|
||||
//
|
||||
// Created by Zaphod Beeblebrox on 8/2/05.
|
||||
// Copyright 2005 __MyCompanyName__. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
|
||||
@interface OutputController : NSObject {
|
||||
VirtualRingBuffer *buffer;
|
||||
AudioStreamBasicDescription format;
|
||||
}
|
||||
|
||||
@end
|
|
@ -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
|
|
@ -0,0 +1,20 @@
|
|||
//
|
||||
// OutputCoreAudio.h
|
||||
// Cog
|
||||
//
|
||||
// Created by Zaphod Beeblebrox on 8/2/05.
|
||||
// Copyright 2005 __MyCompanyName__. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
|
||||
@interface OutputCoreAudio : NSObject {
|
||||
|
||||
}
|
||||
|
||||
- (void)setup;
|
||||
- (void)start;
|
||||
- (void)stop;
|
||||
|
||||
@end
|
|
@ -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
|
|
@ -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;
|
||||
|
|
2
README
2
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.
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
//
|
||||
// Semaphore.h
|
||||
// Cog
|
||||
//
|
||||
// Created by Zaphod Beeblebrox on 8/2/05.
|
||||
// Copyright 2005 __MyCompanyName__. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <mach/mach.h>
|
||||
|
||||
@interface Semaphore : NSObject {
|
||||
semaphore_t semaphore;
|
||||
}
|
||||
|
||||
-(id)init;
|
||||
-(void)signal;
|
||||
-(void)timedWait:(int)seconds;
|
||||
-(void)wait;
|
||||
|
||||
@end
|
|
@ -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
|
2
Sound.h
2
Sound.h
|
@ -102,7 +102,7 @@ enum
|
|||
- (void)resetBuffer;
|
||||
- (VirtualRingBuffer *)oppositeBuffer:(VirtualRingBuffer *)buf;
|
||||
|
||||
//private methodss
|
||||
//private methods
|
||||
- (BOOL)setupAudioOutput;
|
||||
- (BOOL)startAudioOutput;
|
||||
- (void)stopAudioOutput;
|
||||
|
|
9
Sound.m
9
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];
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue