📄 coreaudio.c
字号:
case 2: p_aout->output.output.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT; break; case 4: p_aout->output.output.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT; break; case 6: p_aout->output.output.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_LFE; break; case 8: p_aout->output.output.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_LFE | AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT; break; default: msg_Err( p_aout, "unknown channel count: [%ld]", p_sys->stream_format.mChannelsPerFrame ); FreeDevice( p_aout ); FreeHardwareInfo( p_aout ); vlc_mutex_destroy( &p_sys->lock ); free( (void *)p_sys ); return( VLC_EGENERIC ); } p_aout->output.i_nb_samples = p_sys->i_bufframe_size; aout_VolumeSoftInit( p_aout ); break; case 'IAC3': case kAudioFormat60958AC3: p_aout->output.output.i_format = VLC_FOURCC('s','p','d','i'); p_aout->output.output.i_bytes_per_frame = AOUT_SPDIF_SIZE; p_aout->output.output.i_frame_length = A52_FRAME_NB; p_aout->output.i_nb_samples = p_aout->output.output.i_frame_length; aout_VolumeNoneInit( p_aout ); break; default: msg_Err( p_aout, "unknown hardware format: [%4.4s]", (char *)&p_sys->stream_format.mFormatID ); FreeDevice( p_aout ); FreeHardwareInfo( p_aout ); vlc_mutex_destroy( &p_sys->lock ); free( (void *)p_sys ); return( VLC_EGENERIC ); } /* Add callback */ err = AudioDeviceAddIOProc( p_sys->devid, (AudioDeviceIOProc)IOCallback, (void *)p_aout ); if( err != noErr ) { msg_Err( p_aout, "AudioDeviceAddIOProc failed: [%4.4s]", (char *)&err ); FreeDevice( p_aout ); FreeHardwareInfo( p_aout ); vlc_mutex_destroy( &p_sys->lock ); free( (void *)p_sys ); return( VLC_EGENERIC ); } /* Start device */ err = AudioDeviceStart( p_sys->devid, (AudioDeviceIOProc)IOCallback ); if( err != noErr ) { msg_Err( p_aout, "AudioDeviceStart failed: [%4.4s]", (char *)&err ); err = AudioDeviceRemoveIOProc( p_sys->devid, (AudioDeviceIOProc)IOCallback ); if( err != noErr ) { msg_Err( p_aout, "AudioDeviceRemoveIOProc failed: [%4.4s]", (char *)&err ); } FreeDevice( p_aout ); FreeHardwareInfo( p_aout ); vlc_mutex_destroy( &p_sys->lock ); free( (void *)p_sys ); return( VLC_EGENERIC ); } err = AudioHardwareAddPropertyListener( kAudioHardwarePropertyDevices, HardwareListener, (void *)p_aout ); if( err != noErr ) { msg_Err( p_aout, "AudioHardwareAddPropertyListener failed: %4.4s", (char *)&err ); /* Stop device */ err = AudioDeviceStop( p_sys->devid, (AudioDeviceIOProc)IOCallback ); if( err != noErr ) { msg_Err( p_aout, "AudioDeviceStop failed: [%4.4s]", (char *)&err ); } /* Remove callback */ err = AudioDeviceRemoveIOProc( p_sys->devid, (AudioDeviceIOProc)IOCallback ); if( err != noErr ) { msg_Err( p_aout, "AudioDeviceRemoveIOProc failed: [%4.4s]", (char *)&err ); } FreeDevice( p_aout ); FreeHardwareInfo( p_aout ); vlc_mutex_destroy( &p_sys->lock ); free( (void *)p_sys ); return( VLC_EGENERIC ); } /* Let's pray for the following operation to be atomic... */ p_sys->clock_diff = - (mtime_t) AudioConvertHostTimeToNanos( AudioGetCurrentHostTime() ) / 1000; p_sys->clock_diff += mdate(); return( VLC_SUCCESS );}/***************************************************************************** * Close: close the CoreAudio HAL device *****************************************************************************/static void Close( vlc_object_t * p_this ){ OSStatus err; aout_instance_t * p_aout = (aout_instance_t *)p_this; struct aout_sys_t * p_sys = p_aout->output.p_sys; if( p_sys->b_dev_alive ) { /* Stop device */ err = AudioDeviceStop( p_sys->devid, (AudioDeviceIOProc)IOCallback ); if( err != noErr ) { msg_Err( p_aout, "AudioDeviceStop failed: [%4.4s]", (char *)&err ); } /* Remove callback */ err = AudioDeviceRemoveIOProc( p_sys->devid, (AudioDeviceIOProc)IOCallback ); if( err != noErr ) { msg_Err( p_aout, "AudioDeviceRemoveIOProc failed: [%4.4s]", (char *)&err ); } FreeDevice( p_aout ); } err = AudioHardwareRemovePropertyListener( kAudioHardwarePropertyDevices, HardwareListener ); if( err != noErr ) { msg_Err( p_aout, "AudioHardwareRemovePropertyListener failed: [%4.4s]", (char *)&err ); } FreeHardwareInfo( p_aout ); vlc_mutex_destroy( &p_sys->lock ); free( p_sys );}/***************************************************************************** * Play: nothing to do *****************************************************************************/static void Play( aout_instance_t * p_aout ){}/***************************************************************************** * IOCallback: callback for audio output *****************************************************************************/static OSStatus IOCallback( AudioDeviceID inDevice, const AudioTimeStamp * inNow, const void * inInputData, const AudioTimeStamp * inInputTime, AudioBufferList * outOutputData, const AudioTimeStamp * inOutputTime, void * threadGlobals ){ aout_buffer_t * p_buffer; AudioTimeStamp host_time; mtime_t current_date; aout_instance_t * p_aout = (aout_instance_t *)threadGlobals; struct aout_sys_t * p_sys = p_aout->output.p_sys; host_time.mFlags = kAudioTimeStampHostTimeValid; AudioDeviceTranslateTime( inDevice, inOutputTime, &host_time );#if 1 p_sys->clock_diff = - (mtime_t) AudioConvertHostTimeToNanos( AudioGetCurrentHostTime() ) / 1000; p_sys->clock_diff += mdate();#endif current_date = p_sys->clock_diff + AudioConvertHostTimeToNanos( host_time.mHostTime ) / 1000;#define B_SPDI (p_aout->output.output.i_format == VLC_FOURCC('s','p','d','i')) p_buffer = aout_OutputNextBuffer( p_aout, current_date, B_SPDI );#undef B_SPDI#define BUFFER outOutputData->mBuffers[ p_sys->i_stream_index ] if( p_buffer != NULL ) { /* move data into output data buffer */ p_aout->p_vlc->pf_memcpy( BUFFER.mData, p_buffer->p_buffer, p_buffer->i_nb_bytes ); aout_BufferFree( p_buffer ); } else { if( p_aout->output.output.i_format == VLC_FOURCC('f','l','3','2') ) { UInt32 i, i_size = p_sys->i_bufframe_size * p_sys->stream_format.mChannelsPerFrame; float * p = (float *)BUFFER.mData; for( i = 0; i < i_size; i++ ) { *p++ = 0.0; } } else { p_aout->p_vlc->pf_memset( BUFFER.mData, 0, BUFFER.mDataByteSize ); } }#undef BUFFER return( noErr ); }/***************************************************************************** * InitHardwareInfo *****************************************************************************/static int InitHardwareInfo( aout_instance_t * p_aout ){ OSStatus err; UInt32 i, i_param_size; AudioDeviceID devid_def; AudioDeviceID * p_devices; struct aout_sys_t * p_sys = p_aout->output.p_sys; vlc_mutex_lock( &p_sys->lock ); /* Get number of devices */ err = AudioHardwareGetPropertyInfo( kAudioHardwarePropertyDevices, &i_param_size, NULL ); if( err != noErr ) { msg_Err( p_aout, "could not get number of devices: [%4.4s]", (char *)&err ); vlc_mutex_unlock( &p_sys->lock ); return( VLC_EGENERIC ); } p_sys->i_devices = i_param_size / sizeof( AudioDeviceID ); if( p_sys->i_devices < 1 ) { msg_Err( p_aout, "no devices found" ); vlc_mutex_unlock( &p_sys->lock ); return( VLC_EGENERIC ); } msg_Dbg( p_aout, "system has [%ld] device(s)", p_sys->i_devices ); /* Allocate DeviceID array */ p_devices = (AudioDeviceID *)malloc( i_param_size ); if( p_devices == NULL ) { msg_Err( p_aout, "out of memory" ); vlc_mutex_unlock( &p_sys->lock ); return( VLC_ENOMEM ); } /* Populate DeviceID array */ err = AudioHardwareGetProperty( kAudioHardwarePropertyDevices, &i_param_size, (void *)p_devices ); if( err != noErr ) { msg_Err( p_aout, "could not get the device ID's: [%4.4s]", (char *)&err ); free( (void *)p_devices ); vlc_mutex_unlock( &p_sys->lock ); return( VLC_EGENERIC ); } i_param_size = sizeof( AudioDeviceID ); err = AudioHardwareGetProperty( kAudioHardwarePropertyDefaultOutputDevice, &i_param_size, (void *)&devid_def ); if( err != noErr ) { msg_Err( p_aout, "could not get default audio device: [%4.4s]", (char *)&err ); free( (void *)p_devices ); vlc_mutex_unlock( &p_sys->lock ); return( VLC_EGENERIC ); } p_sys->p_devices = (struct aout_dev_t *) malloc( sizeof( struct aout_dev_t ) * p_sys->i_devices ); if( p_sys->p_devices == NULL ) { msg_Err( p_aout, "out of memory" ); free( (void *)p_devices ); vlc_mutex_unlock( &p_sys->lock ); return( VLC_ENOMEM ); } p_sys->i_options = 0; p_sys->p_options = NULL; for( i = 0; i < p_sys->i_devices; i++ ) { p_sys->p_devices[i].devid = p_devices[i]; if( p_devices[i] == devid_def ) { p_sys->i_def_dev = i; } if( InitDeviceInfo( i, p_aout ) ) { UInt32 j; msg_Err( p_aout, "InitDeviceInfo(%ld) failed", i ); for( j = 0; j < i; j++ ) { FreeDeviceInfo( j, p_aout ); } free( (void *)p_sys->p_devices ); free( (void *)p_devices ); vlc_mutex_unlock( &p_sys->lock ); return( VLC_EGENERIC ); } } free( (void *)p_devices ); p_sys->b_hwinfo = VLC_TRUE; vlc_mutex_unlock( &p_sys->lock ); return( VLC_SUCCESS );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -