static int Open ( vlc_object_t *p_this ) { audio_output_t *p_aout = (audio_output_t *)p_this; struct aout_sys_t *p_sys = malloc(sizeof(aout_sys_t)); p_aout->sys = p_sys; OSStatus status = 0; // Setup the audio device. AudioStreamBasicDescription deviceFormat; deviceFormat.mSampleRate = 44100; deviceFormat.mFormatID = kAudioFormatLinearPCM; deviceFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger; // Signed integer, little endian deviceFormat.mBytesPerPacket = 4; deviceFormat.mFramesPerPacket = 1; deviceFormat.mBytesPerFrame = 4; deviceFormat.mChannelsPerFrame = 2; deviceFormat.mBitsPerChannel = 16; deviceFormat.mReserved = 0; // Create a new output AudioQueue for the device. status = AudioQueueNewOutput(&deviceFormat, // Format AudioQueueCallback, // Callback p_aout, // User data, passed to the callback CFRunLoopGetMain(), // RunLoop kCFRunLoopDefaultMode, // RunLoop mode 0, // Flags ; must be zero (per documentation)... &(p_sys->audioQueue)); // Output // This will be used for boosting the audio without the need of a mixer (floating-point conversion is expensive on ARM) // AudioQueueSetParameter(p_sys->audioQueue, kAudioQueueParam_Volume, 12.0); // Defaults to 1.0 msg_Dbg(p_aout, "New AudioQueue output created (status = %i)", status); // Allocate buffers for the AudioQueue, and pre-fill them. for (int i = 0; i < NUMBER_OF_BUFFERS; ++i) { AudioQueueBufferRef buffer = NULL; status = AudioQueueAllocateBuffer(p_sys->audioQueue, FRAME_SIZE * 4, &buffer); AudioQueueCallback(NULL, p_sys->audioQueue, buffer); } /* Volume is entirely done in software. */ aout_SoftVolumeInit( p_aout ); p_aout->format.i_format = VLC_CODEC_S16L; p_aout->format.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT; p_aout->format.i_rate = 44100; aout_PacketInit(p_aout, &p_sys->packet, FRAME_SIZE); p_aout->pf_play = aout_PacketPlay; p_aout->pf_pause = aout_PacketPause; p_aout->pf_flush = aout_PacketFlush; msg_Dbg(p_aout, "Starting AudioQueue (status = %i)", status); status = AudioQueueStart(p_sys->audioQueue, NULL); return VLC_SUCCESS; }
static int Open (vlc_object_t *obj) { audio_output_t *aout = (audio_output_t *)obj; aout_sys_t *sys = calloc( 1, sizeof( aout_sys_t ) ); if( unlikely( sys == NULL )) return VLC_ENOMEM; aout->sys = sys; aout->start = Start; aout->stop = Stop; aout_SoftVolumeInit( aout ); return VLC_SUCCESS; }
/***************************************************************************** * Open: open the audio device *****************************************************************************/ static int Open ( vlc_object_t *p_this ) { audio_output_t *p_aout = (audio_output_t *)p_this; aout_sys_t *p_sys; char *psz_mode; ULONG i_kai_mode; KAISPEC ks_wanted, ks_obtained; int i_nb_channels; int i_bytes_per_frame; vlc_value_t val, text; audio_format_t format = p_aout->format; /* Allocate structure */ p_aout->sys = calloc( 1, sizeof( aout_sys_t ) ); if( p_aout->sys == NULL ) return VLC_ENOMEM; p_sys = p_aout->sys; if( var_Get( p_aout, "audio-device", &val ) != VLC_ENOVAR ) { /* The user has selected an audio device. */ if ( val.i_int == AOUT_VAR_STEREO ) { format.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT; } else if ( val.i_int == AOUT_VAR_MONO ) { format.i_physical_channels = AOUT_CHAN_CENTER; } } psz_mode = var_InheritString( p_aout, "kai-audio-device" ); if( !psz_mode ) psz_mode = ( char * )ppsz_kai_audio_device[ 0 ]; // "auto" i_kai_mode = KAIM_AUTO; if( strcmp( psz_mode, "dart" ) == 0 ) i_kai_mode = KAIM_DART; else if( strcmp( psz_mode, "uniaud" ) == 0 ) i_kai_mode = KAIM_UNIAUD; msg_Dbg( p_aout, "selected mode = %s", psz_mode ); if( psz_mode != ppsz_kai_audio_device[ 0 ]) free( psz_mode ); i_nb_channels = aout_FormatNbChannels( &format ); if ( i_nb_channels > 2 ) { /* KAI doesn't support more than two channels. */ i_nb_channels = 2; format.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT; } /* Support s16l only */ format.i_format = VLC_CODEC_S16L; aout_FormatPrepare( &format ); i_bytes_per_frame = format.i_bytes_per_frame; /* Initialize library */ if( kaiInit( i_kai_mode )) { msg_Err( p_aout, "cannot initialize KAI"); goto exit_free_sys; } ks_wanted.usDeviceIndex = 0; ks_wanted.ulType = KAIT_PLAY; ks_wanted.ulBitsPerSample = BPS_16; ks_wanted.ulSamplingRate = format.i_rate; ks_wanted.ulDataFormat = MCI_WAVE_FORMAT_PCM; ks_wanted.ulChannels = i_nb_channels; ks_wanted.ulNumBuffers = 2; ks_wanted.ulBufferSize = FRAME_SIZE * i_bytes_per_frame; ks_wanted.fShareable = !var_InheritBool( p_aout, "kai-audio-exclusive-mode"); ks_wanted.pfnCallBack = KaiCallback; ks_wanted.pCallBackData = p_aout; msg_Dbg( p_aout, "requested ulBufferSize = %ld", ks_wanted.ulBufferSize ); /* Open the sound device. */ if( kaiOpen( &ks_wanted, &ks_obtained, &p_sys->hkai )) { msg_Err( p_aout, "cannot open KAI device"); goto exit_kai_done; } msg_Dbg( p_aout, "open in %s mode", ks_obtained.fShareable ? "shareable" : "exclusive" ); msg_Dbg( p_aout, "obtained i_nb_samples = %lu", ks_obtained.ulBufferSize / i_bytes_per_frame ); msg_Dbg( p_aout, "obtained i_bytes_per_frame = %d", format.i_bytes_per_frame ); p_aout->format = format; p_aout->pf_play = Play; p_aout->pf_pause = aout_PacketPause; p_aout->pf_flush = aout_PacketFlush; aout_PacketInit( p_aout, &p_sys->packet, ks_obtained.ulBufferSize / i_bytes_per_frame ); aout_SoftVolumeInit( p_aout ); if ( var_Type( p_aout, "audio-device" ) == 0 ) { /* First launch. */ var_Create( p_aout, "audio-device", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE ); text.psz_string = _("Audio Device"); var_Change( p_aout, "audio-device", VLC_VAR_SETTEXT, &text, NULL ); val.i_int = AOUT_VAR_STEREO; text.psz_string = _("Stereo"); var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val, &text ); val.i_int = AOUT_VAR_MONO; text.psz_string = _("Mono"); var_Change( p_aout, "audio-device", VLC_VAR_ADDCHOICE, &val, &text ); if ( i_nb_channels == 2 ) { val.i_int = AOUT_VAR_STEREO; } else { val.i_int = AOUT_VAR_MONO; } var_Change( p_aout, "audio-device", VLC_VAR_SETDEFAULT, &val, NULL ); var_AddCallback( p_aout, "audio-device", aout_ChannelsRestart, NULL ); } /* Prevent SIG_FPE */ _control87(MCW_EM, MCW_EM); return VLC_SUCCESS; exit_kai_done : kaiDone(); exit_free_sys : free( p_sys ); return VLC_EGENERIC; }