Esempio n. 1
0
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;
}
Esempio n. 2
0
File: kai.c Progetto: cspowart/vlc
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;
}
Esempio n. 3
0
/*****************************************************************************
 * 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;
}