#import "SoundController.h" #import "Sound.h" #import "DBLog.h" @implementation SoundController //Note: use distributed objects for communication between Sound and SoundController....each should be in their own threads - (id)init { self = [super init]; if (self) { sound = [[Sound alloc] init]; } return self; } - (void)awakeFromNib { [timeField setFont:[NSFont systemFontOfSize:18]]; sendPort = [NSPort port]; if (sendPort) { [sendPort setDelegate:self]; NSArray *modes = [NSArray arrayWithObjects:NSDefaultRunLoopMode, NSEventTrackingRunLoopMode, NSModalPanelRunLoopMode, nil]; NSEnumerator *enumerator; NSString *mode; enumerator = [modes objectEnumerator]; while ((mode = [enumerator nextObject])) [[NSRunLoop currentRunLoop] addPort:sendPort forMode:mode]; [NSThread detachNewThreadSelector:@selector(launchThreadWithPort:) toTarget:sound withObject:sendPort]; } } - (IBAction)pauseResume:(id)sender { // DBLog(@"Pause/Resume Sent!"); [self sendPortMessage:kCogPauseResumeMessage]; } - (IBAction)pause:(id)sender { // DBLog(@"Pause Sent!"); [self sendPortMessage:kCogPauseMessage]; } - (IBAction)resume:(id)sender { // DBLog(@"Resume Sent!"); [self sendPortMessage:kCogResumeMessage]; } - (IBAction)stop:(id)sender { // DBLog(@"Stop Sent!"); waitingForPlay = NO; [self sendPortMessage:kCogStopMessage]; } //called by double-clicking on table - (void)playEntryAtIndex:(int)i { PlaylistEntry *pe = [[playlistController arrangedObjects] objectAtIndex:i]; [playlistController setCurrentEntry:pe addToHistory:YES]; [playlistController reset]; [self playEntry:pe]; } - (void)playEntry:(PlaylistEntry *)pe; { waitingForPlay = NO; // DBLog(@"PlayEntry: %@ Sent!", [pe filename]); [self sendPortMessage:kCogPlayFileMessage withString:[pe filename]]; } - (IBAction)next:(id)sender { waitingForPlay = NO; if ([playlistController nextEntry] == nil) return; [playlistController next]; [self playEntry:[playlistController currentEntry]]; } - (IBAction)prev:(id)sender { waitingForPlay = NO; if ([playlistController prevEntry] == nil) return; [playlistController prev]; [self playEntry:[playlistController currentEntry]]; } - (IBAction)seek:(id)sender { // DBLog(@"SEEKING?"); double time; time = [positionSlider doubleValue]; [self sendPortMessage:kCogSeekMessage withData:&time ofSize:(sizeof(double))]; int sec = (int)(time/1000.0); NSString *text; text = [NSString stringWithFormat:@"%i:%02i", sec/60, sec%60]; [timeField setStringValue:text]; } - (void)sendPortMessage:(int)msgid { NSPortMessage *portMessage = [[NSPortMessage alloc] initWithSendPort:distantPort receivePort:sendPort components:nil]; if (portMessage) { [portMessage setMsgid:msgid]; [portMessage sendBeforeDate:[NSDate date]]; [portMessage release]; } } - (void)sendPortMessage:(int)msgid withData:(void *)data ofSize:(int)size { NSPortMessage *portMessage; NSData *d = [[NSData alloc] initWithBytes:data length:size]; NSArray *a = [[NSArray alloc] initWithObjects:d,nil]; portMessage = [[NSPortMessage alloc] initWithSendPort:distantPort receivePort:sendPort components:a]; [a release]; [d release]; if (portMessage) { NSDate *date = [[NSDate alloc] init]; [portMessage setMsgid:msgid]; [portMessage sendBeforeDate:date]; [date release]; [portMessage release]; } } - (void)sendPortMessage:(int)msgid withString:(NSString *)s { NSData *dataString = [s dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:NO]; NSPortMessage *portMessage = [[NSPortMessage alloc] initWithSendPort:distantPort receivePort:sendPort components:[NSArray arrayWithObject:dataString]]; if (portMessage) { [portMessage setMsgid:msgid]; [portMessage sendBeforeDate:[NSDate date]]; [portMessage release]; } } - (void)handlePortMessage:(NSPortMessage *)portMessage { unsigned int message = [portMessage msgid]; // DBLog(@"SOUNDCONTROLLER RECEIVED MESSAGE"); if (message == kCogCheckinMessage) { // Get the worker threadÕs communications port. // DBLog(@"CHECKIN RECEIVED"); distantPort = [portMessage sendPort]; // Retain and save the worker port for later use. [distantPort retain]; } else if (message == kCogRequestNextFileMessage) { PlaylistEntry *pe; pe = [playlistController nextEntry]; if (pe == nil) { [self sendPortMessage:kCogEndOfPlaylistMessage]; } else { DBLog(@"REQUESTING"); waitingForPlay = YES; [self sendPortMessage:kCogChangeFileMessage withString:[pe filename]]; } } else if (message == kCogFileChangedMessage) { DBLog(@"FILE CHANGED"); if (waitingForPlay == YES) { waitingForPlay = NO; [playlistController next]; [timeField setStringValue:@"0:00"]; } } else if (message == kCogBitrateUpdateMessage) { NSArray* components = [portMessage components]; NSData *data = [components objectAtIndex:0]; int bitrate; bitrate = (*(int *)[data bytes]); // DBLog(@"Received length update: %f", max); // [bitrateField setIntValue:bitrate]; } else if (message == kCogLengthUpdateMessage) { NSArray* components = [portMessage components]; NSData *data = [components objectAtIndex:0]; double max; max = (*(double *)[data bytes]); // DBLog(@"Received length update: %f", max); [positionSlider setMaxValue:max]; [positionSlider setDoubleValue:0]; // DBLog(@"Length changed: %f", max); // [lengthField setDoubleValue:max/1000.0]; } else if (message = kCogPositionUpdateMessage) { NSArray* components = [portMessage components]; NSData *data = [components objectAtIndex:0]; double pos; pos = (*(double *)[data bytes]); if ([positionSlider tracking] == NO) { // DBLog(@"Received pos update: %f", pos); [positionSlider setDoubleValue:pos]; } int sec = (int)(pos/1000.0); NSString *text; text = [NSString stringWithFormat:@"%i:%02i", sec/60, sec%60]; [timeField setStringValue:text]; } } @end