Adium

Changeset 23020

Show
Ignore:
Timestamp:
04/03/2008 09:48:57 AM (8 months ago)
Author:
evands
Message:

Merged [23017] and [23018]: Fixed repeating/stutterring event sounds on G5 machines. Fixes #8828

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/adium-1.2/Source/AdiumSound.h

    r21350 r23020  
    2626         
    2727        unsigned                        soundsAreMuted; 
     28 
     29        BOOL                            reconfigureAudioContextBeforeEachPlay; 
    2830} 
    2931 
  • branches/adium-1.2/Source/AdiumSound.m

    r22733 r23020  
    2121#import <AIUtilities/AISleepNotification.h> 
    2222#import <QTKit/QTKit.h> 
     23#import <CoreServices/CoreServices.h> 
    2324 
    2425#define SOUND_DEFAULT_PREFS                             @"SoundPrefs" 
     
    3132- (void)_uncacheLeastRecentlyUsedSound; 
    3233- (QTAudioContextRef)createAudioContextWithSystemOutputDevice; 
     34- (void)configureAudioContextForMovie:(QTMovie *)movie; 
    3335- (NSArray *)allSounds; 
    3436@end 
     
    6870                                                                                                   object:nil]; 
    6971                 
    70                 //Sign up for notification when the user changes the system output device in the Sound pane of System Preferences. 
    71                 OSStatus err = AudioHardwareAddPropertyListener(kAudioHardwarePropertyDefaultSystemOutputDevice, systemOutputDeviceDidChange, /*refcon*/ self); 
    72                 if (err != noErr) 
    73                         NSLog(@"%s: Couldn't sign up for system-output-device-changed notification, because AudioHardwareAddPropertyListener returned %i. Adium will not know when the default system audio device changes.", __PRETTY_FUNCTION__, err); 
     72                /* Sign up for notification when the user changes the system output device in the Sound pane of System Preferences. 
     73                 * 
     74                 * However, we avoid doing this on G5 machines. G5s spew a continuous stream of 
     75                 * kAudioHardwarePropertyDefaultSystemOutputDevice notifications without the device actually changing; 
     76                 * rather than stutter our audio and eat CPU continuously, we just won't try to update. 
     77                 */ 
     78                SInt32 gestaltReturnValue; 
     79                OSErr gestaltErr; 
     80                gestaltErr = Gestalt(gestaltNativeCPUfamily, &gestaltReturnValue); 
     81                if ((gestaltErr != noErr) || ((gestaltReturnValue != gestaltCPU970) && (gestaltReturnValue != gestaltCPU970FX))) { 
     82                        //We couldn't determine the CPU type, or we're not on a G5. 
     83                        OSStatus err = AudioHardwareAddPropertyListener(kAudioHardwarePropertyDefaultSystemOutputDevice, systemOutputDeviceDidChange, /*refcon*/ self); 
     84                        if (err != noErr) 
     85                                NSLog(@"%s: Couldn't sign up for system-output-device-changed notification, because AudioHardwareAddPropertyListener returned %i. Adium will not know when the default system audio device changes.", __PRETTY_FUNCTION__, err);                         
     86                } else { 
     87                        //We won't be updating automatically, so reconfigure before a sound is played again 
     88                        reconfigureAudioContextBeforeEachPlay = YES; 
     89                } 
    7490        } 
    7591 
     
    184200                        [movie setVolume:customVolume]; 
    185201 
    186                         //Create an audio context for the system output audio device. 
    187                         //We'd reuse one context for all the movies, but that doesn't work; movies can't share a context, apparently. (You get paramErr when you try to give the second movie a context already in use by the first.) 
    188                         QTAudioContextRef newAudioContext = [self createAudioContextWithSystemOutputDevice]; 
    189  
    190                         if (newAudioContext) { 
    191                                 OSStatus err = SetMovieAudioContext([movie quickTimeMovie], newAudioContext); 
    192                                 if (err != noErr) 
    193                                         NSLog(@"%s: Could not set audio context of movie %@ to %p: SetMovieAudioContext returned error %i. Sounds may be routed to the default audio device instead of the system alert audio device.", __PRETTY_FUNCTION__, movie, newAudioContext, err); 
    194                                  
    195                                 //We created it, so we must release it. 
    196                                 QTAudioContextRelease(newAudioContext); 
    197                         } else { 
    198                                 NSLog(@"cachedPlaySound: Could not set audio context because -[AdiumSound createAudioContextWithSystemOutputDevice] returned NULL"); 
    199                         }                        
     202                        [self configureAudioContextForMovie:movie]; 
    200203                } 
    201204 
     
    204207                [soundCacheArray removeObject:inPath]; 
    205208                [soundCacheArray insertObject:inPath atIndex:0]; 
     209                 
     210                if (reconfigureAudioContextBeforeEachPlay) { 
     211                        [movie stop]; 
     212                        [self configureAudioContextForMovie:movie]; 
     213                } 
    206214    } 
    207215 
     
    236244} 
    237245 
    238 - (QTAudioContextRef) createAudioContextWithSystemOutputDevice 
     246- (QTAudioContextRef)createAudioContextWithSystemOutputDevice 
    239247{ 
    240248        QTAudioContextRef newAudioContext = NULL; 
     
    271279} 
    272280 
     281- (void)configureAudioContextForMovie:(QTMovie *)movie 
     282{ 
     283        //QTMovie gets confused if we're playing when we do this, so pause momentarily. 
     284        float savedRate = [movie rate]; 
     285        [movie setRate:0.0]; 
     286         
     287        //Exchange the audio context for a new one with the new device. 
     288        QTAudioContextRef newAudioContext = [self createAudioContextWithSystemOutputDevice]; 
     289         
     290        if (newAudioContext) { 
     291                OSStatus err = SetMovieAudioContext([movie quickTimeMovie], newAudioContext); 
     292                if (err != noErr) { 
     293                        NSLog(@"%s: Could not set audio context of movie %@ to %p: SetMovieAudioContext returned error %i. Sounds may be routed to the default audio device instead of the system alert audio device.", __PRETTY_FUNCTION__, movie, newAudioContext, err); 
     294                } 
     295                 
     296                //We created it, so we must release it. 
     297                QTAudioContextRelease(newAudioContext); 
     298        } else { 
     299                NSLog(@"%s: Could not set audio context because -[AdiumSound createAudioContextWithSystemOutputDevice] returned NULL", __PRETTY_FUNCTION__); 
     300        } 
     301         
     302        //Resume playback, now on the new device. 
     303        [movie setRate:savedRate]; 
     304} 
     305 
    273306- (NSArray *)allSounds 
    274307{ 
     
    315348 
    316349        while ((movie = [soundsEnum nextObject])) { 
    317                 //QTMovie gets confused if we're playing when we do this, so pause momentarily. 
    318                 float savedRate = [movie rate]; 
    319                 [movie setRate:0.0]; 
    320  
    321                 //Exchange the audio context for a new one with the new device. 
    322                 QTAudioContextRef newAudioContext = [self createAudioContextWithSystemOutputDevice]; 
    323  
    324                 if (newAudioContext) { 
    325                         OSStatus err = SetMovieAudioContext([movie quickTimeMovie], newAudioContext); 
    326                         if (err != noErr) { 
    327                                 NSLog(@"%s: Could not set audio context of movie %@ to %p: SetMovieAudioContext returned error %i. Sounds may be routed to the default audio device instead of the system alert audio device.", __PRETTY_FUNCTION__, movie, newAudioContext, err); 
    328                         } 
    329  
    330                         //We created it, so we must release it. 
    331                         QTAudioContextRelease(newAudioContext); 
    332                 } else { 
    333                         NSLog(@"systemOutputDeviceDidChange: Could not set audio context because -[AdiumSound createAudioContextWithSystemOutputDevice] returned NULL"); 
    334                 } 
    335  
    336                 //Resume playback, now on the new device. 
    337                 [movie setRate:savedRate]; 
     350                [self configureAudioContextForMovie:movie]; 
    338351        } 
    339352}