Пример #1
0
Файл: kai.c Проект: cspowart/vlc
/*****************************************************************************
 * Close: close the audio device
 *****************************************************************************/
static void Stop ( audio_output_t *p_aout )
{
    aout_sys_t *p_sys = p_aout->sys;

    kaiClose( p_sys->hkai );
    kaiDone();

    aout_PacketDestroy( p_aout );
}
Пример #2
0
/*****************************************************************************
 * Close: close the audio device
 *****************************************************************************/
static void Close ( vlc_object_t *p_this )
{
    audio_output_t *p_aout = (audio_output_t *)p_this;
    struct aout_sys_t * p_sys = p_aout->sys;

    msg_Dbg(p_aout, "Stopping AudioQueue");
    AudioQueueStop(p_sys->audioQueue, false);
    msg_Dbg(p_aout, "Disposing of AudioQueue");
    AudioQueueDispose(p_sys->audioQueue, false);
    aout_PacketDestroy(p_aout);
    free (p_sys);
}
Пример #3
0
/*****************************************************************************
 * Close: close the audio device
 *****************************************************************************/
static void Close ( vlc_object_t *p_this )
{
    audio_output_t *p_aout = (audio_output_t *)p_this;
    aout_sys_t *p_sys = p_aout->sys;

    msg_Dbg( p_aout, "closing portaudio");

#ifdef PORTAUDIO_IS_SERIOUSLY_BROKEN

    /* Signal end of stream */
    vlc_mutex_lock( &pa_thread->lock_signal );
    pa_thread->b_signal = true;
    vlc_cond_signal( &pa_thread->signal );
    vlc_mutex_unlock( &pa_thread->lock_signal );

    /* Wait until thread is ready */
    vlc_mutex_lock( &pa_thread->lock_wait );
    while( !pa_thread->b_wait )
        vlc_cond_wait( &pa_thread->wait, &pa_thread->lock_wait );
    vlc_mutex_unlock( &pa_thread->lock_wait );
    pa_thread->b_wait = false;

#else

    int i_err = Pa_StopStream( p_sys->p_stream );
    if( i_err != paNoError )
    {
        msg_Err( p_aout, "Pa_StopStream: %d (%s)", i_err,
                 Pa_GetErrorText( i_err ) );
    }
    i_err = Pa_CloseStream( p_sys->p_stream );
    if( i_err != paNoError )
    {
        msg_Err( p_aout, "Pa_CloseStream: %d (%s)", i_err,
                 Pa_GetErrorText( i_err ) );
    }

    i_err = Pa_Terminate();
    if( i_err != paNoError )
    {
        msg_Err( p_aout, "Pa_Terminate: %d (%s)", i_err,
                 Pa_GetErrorText( i_err ) );
    }

#endif

    msg_Dbg( p_aout, "portaudio closed");
    aout_PacketDestroy( p_aout );
    free( p_sys );
}
Пример #4
0
Файл: oss.c Проект: CSRedRat/vlc
/*****************************************************************************
 * Close: close the DSP audio device
 *****************************************************************************/
static void Close( vlc_object_t * p_this )
{
    audio_output_t *p_aout = (audio_output_t *)p_this;
    struct aout_sys_t * p_sys = p_aout->sys;

    vlc_cancel( p_sys->thread );
    vlc_join( p_sys->thread, NULL );
    p_aout->b_die = false;
    var_DelCallback( p_aout, "audio-device", aout_ChannelsRestart, NULL );

    ioctl( p_sys->i_fd, SNDCTL_DSP_RESET, NULL );
    close( p_sys->i_fd );

    aout_PacketDestroy( p_aout );
    free( p_sys );
}
Пример #5
0
/*****************************************************************************
 * Close: close the JACK client
 *****************************************************************************/
static void Close( vlc_object_t *p_this )
{
    int i_error;
    audio_output_t *p_aout = (audio_output_t *)p_this;
    struct aout_sys_t *p_sys = p_aout->sys;

    i_error = jack_deactivate( p_sys->p_jack_client );
    if( i_error )
    {
        msg_Err( p_aout, "jack_deactivate failed (error %d)", i_error );
    }

    i_error = jack_client_close( p_sys->p_jack_client );
    if( i_error )
    {
        msg_Err( p_aout, "jack_client_close failed (error %d)", i_error );
    }
    free( p_sys->p_jack_ports );
    free( p_sys->p_jack_buffers );
    aout_PacketDestroy( p_aout );
    free( p_sys );
}
Пример #6
0
/*****************************************************************************
 * Open: create a JACK client
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    char psz_name[32];
    audio_output_t *p_aout = (audio_output_t *)p_this;
    struct aout_sys_t *p_sys = NULL;
    int status = VLC_SUCCESS;
    unsigned int i;
    int i_error;

    /* Allocate structure */
    p_sys = calloc( 1, sizeof( aout_sys_t ) );
    if( p_sys == NULL )
    {
        status = VLC_ENOMEM;
        goto error_out;
    }
    p_aout->sys = p_sys;
    p_sys->latency = 0;

    /* Connect to the JACK server */
    snprintf( psz_name, sizeof(psz_name), "vlc_%d", getpid());
    psz_name[sizeof(psz_name) - 1] = '\0';
    p_sys->p_jack_client = jack_client_open( psz_name,
                                             JackNullOption | JackNoStartServer,
                                             NULL );
    if( p_sys->p_jack_client == NULL )
    {
        msg_Err( p_aout, "failed to connect to JACK server" );
        status = VLC_EGENERIC;
        goto error_out;
    }

    /* Set the process callback */
    jack_set_process_callback( p_sys->p_jack_client, Process, p_aout );
    jack_set_graph_order_callback ( p_sys->p_jack_client, GraphChange, p_aout );

    p_aout->pf_play = aout_PacketPlay;
    p_aout->pf_pause = aout_PacketPause;
    p_aout->pf_flush = aout_PacketFlush;
    aout_PacketInit( p_aout, &p_sys->packet,
                     jack_get_buffer_size( p_sys->p_jack_client ) );
    aout_VolumeSoftInit( p_aout );

    /* JACK only supports fl32 format */
    p_aout->format.i_format = VLC_CODEC_FL32;
    // TODO add buffer size callback
    p_aout->format.i_rate = jack_get_sample_rate( p_sys->p_jack_client );

    p_sys->i_channels = aout_FormatNbChannels( &p_aout->format );

    p_sys->p_jack_ports = malloc( p_sys->i_channels *
                                  sizeof(jack_port_t *) );
    if( p_sys->p_jack_ports == NULL )
    {
        status = VLC_ENOMEM;
        goto error_out;
    }

    p_sys->p_jack_buffers = malloc( p_sys->i_channels *
                                    sizeof(jack_sample_t *) );
    if( p_sys->p_jack_buffers == NULL )
    {
        status = VLC_ENOMEM;
        goto error_out;
    }

    /* Create the output ports */
    for( i = 0; i < p_sys->i_channels; i++ )
    {
        snprintf( psz_name, sizeof(psz_name), "out_%d", i + 1);
        psz_name[sizeof(psz_name) - 1] = '\0';
        p_sys->p_jack_ports[i] = jack_port_register( p_sys->p_jack_client,
                psz_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 );

        if( p_sys->p_jack_ports[i] == NULL )
        {
            msg_Err( p_aout, "failed to register a JACK port" );
            status = VLC_EGENERIC;
            goto error_out;
        }
    }

    /* Tell the JACK server we are ready */
    i_error = jack_activate( p_sys->p_jack_client );
    if( i_error )
    {
        msg_Err( p_aout, "failed to activate JACK client (error %d)", i_error );
        status = VLC_EGENERIC;
        goto error_out;
    }

    /* Auto connect ports if we were asked to */
    if( var_InheritBool( p_aout, AUTO_CONNECT_OPTION ) )
    {
        unsigned int i_in_ports;
        char *psz_regex = var_InheritString( p_aout, CONNECT_REGEX_OPTION );
        const char **pp_in_ports = jack_get_ports( p_sys->p_jack_client,
                                                   psz_regex, NULL,
                                                   JackPortIsInput );
        free( psz_regex );
        /* Count the number of returned ports */
        i_in_ports = 0;
        while( pp_in_ports && pp_in_ports[i_in_ports] )
        {
            i_in_ports++;
        }

        /* Tie the output ports to JACK input ports */
        for( i = 0; i_in_ports > 0 && i < p_sys->i_channels; i++ )
        {
            const char* psz_in = pp_in_ports[i % i_in_ports];
            const char* psz_out = jack_port_name( p_sys->p_jack_ports[i] );

            i_error = jack_connect( p_sys->p_jack_client, psz_out, psz_in );
            if( i_error )
            {
                msg_Err( p_aout, "failed to connect port %s to port %s (error %d)",
                         psz_out, psz_in, i_error );
            }
            else
            {
                msg_Dbg( p_aout, "connecting port %s to port %s",
                         psz_out, psz_in );
            }
        }
        free( pp_in_ports );
    }

    msg_Dbg( p_aout, "JACK audio output initialized (%d channels, rate=%d)",
             p_sys->i_channels, p_aout->format.i_rate );

error_out:
    /* Clean up, if an error occurred */
    if( status != VLC_SUCCESS && p_sys != NULL)
    {
        if( p_sys->p_jack_client )
        {
            jack_deactivate( p_sys->p_jack_client );
            jack_client_close( p_sys->p_jack_client );
            aout_PacketDestroy( p_aout );
        }
        free( p_sys->p_jack_ports );
        free( p_sys->p_jack_buffers );
        free( p_sys );
    }
    return status;
}
Пример #7
0
Файл: oss.c Проект: CSRedRat/vlc
/*****************************************************************************
 * Open: open the audio device (the digital sound processor)
 *****************************************************************************
 * This function opens the DSP as a usual non-blocking write-only file, and
 * modifies the p_aout->p_sys->i_fd with the file's descriptor.
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    audio_output_t * p_aout = (audio_output_t *)p_this;
    struct aout_sys_t * p_sys;
    char * psz_device;
    vlc_value_t val;

    /* Allocate structure */
    p_aout->sys = p_sys = malloc( sizeof( aout_sys_t ) );
    if( p_sys == NULL )
        return VLC_ENOMEM;

    /* Get device name */
    if( (psz_device = var_InheritString( p_aout, "oss-audio-device" )) == NULL )
    {
        msg_Err( p_aout, "no audio device specified (maybe /dev/dsp?)" );
        free( p_sys );
        return VLC_EGENERIC;
    }

    /* Open the sound device in non-blocking mode, because ALSA's OSS
     * emulation and some broken OSS drivers would make a blocking call
     * wait forever until the device is available. Since this breaks the
     * OSS spec, we immediately put it back to blocking mode if the
     * operation was successful. */
    p_sys->i_fd = vlc_open( psz_device, O_WRONLY | O_NDELAY );
    if( p_sys->i_fd < 0 )
    {
        msg_Err( p_aout, "cannot open audio device (%s)", psz_device );
        free( psz_device );
        free( p_sys );
        return VLC_EGENERIC;
    }

    /* if the opening was ok, put the device back in blocking mode */
    fcntl( p_sys->i_fd, F_SETFL,
            fcntl( p_sys->i_fd, F_GETFL ) &~ FNDELAY );

    free( psz_device );

    p_aout->pf_play = aout_PacketPlay;
    p_aout->pf_pause = aout_PacketPause;
    p_aout->pf_flush = aout_PacketFlush;

    if ( var_Type( p_aout, "audio-device" ) == 0 )
        Probe( p_aout );
    var_AddCallback( p_aout, "audio-device", aout_ChannelsRestart, NULL );

    if ( var_Get( p_aout, "audio-device", &val ) < 0 )
        /* Probe() has failed. */
        goto error;

    if ( val.i_int == AOUT_VAR_SPDIF )
    {
        p_aout->format.i_format = VLC_CODEC_SPDIFL;
    }
    else if ( val.i_int == AOUT_VAR_5_1 )
    {
        p_aout->format.i_format = VLC_CODEC_S16N;
        p_aout->format.i_physical_channels
            = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
               | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
               | AOUT_CHAN_LFE;
    }
    else if ( val.i_int == AOUT_VAR_2F2R )
    {
        p_aout->format.i_format = VLC_CODEC_S16N;
        p_aout->format.i_physical_channels
            = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
               | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
    }
    else if ( val.i_int == AOUT_VAR_STEREO )
    {
        p_aout->format.i_format = VLC_CODEC_S16N;
        p_aout->format.i_physical_channels
            = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
    }
    else if ( val.i_int == AOUT_VAR_MONO )
    {
        p_aout->format.i_format = VLC_CODEC_S16N;
        p_aout->format.i_physical_channels = AOUT_CHAN_CENTER;
    }
    else
    {
        /* This should not happen ! */
        msg_Err( p_aout, "internal: can't find audio-device (%"PRId64")",
                 val.i_int );
        goto error;
    }

    var_TriggerCallback( p_aout, "intf-change" );

    /* Reset the DSP device */
    if( ioctl( p_sys->i_fd, SNDCTL_DSP_RESET, NULL ) < 0 )
    {
        msg_Err( p_aout, "cannot reset OSS audio device" );
        goto error;
    }

    /* Set the output format */
    if ( AOUT_FMT_SPDIF( &p_aout->format ) )
    {
        int i_format = AFMT_AC3;

        if( ioctl( p_sys->i_fd, SNDCTL_DSP_SETFMT, &i_format ) < 0
             || i_format != AFMT_AC3 )
        {
            msg_Err( p_aout, "cannot reset OSS audio device" );
            goto error;
        }

        p_aout->format.i_format = VLC_CODEC_SPDIFL;
        p_aout->format.i_bytes_per_frame = AOUT_SPDIF_SIZE;
        p_aout->format.i_frame_length = A52_FRAME_NB;

        aout_PacketInit( p_aout, &p_sys->packet, A52_FRAME_NB );
        aout_VolumeNoneInit( p_aout );
    }
    else
    {
        unsigned int i_format = AFMT_S16_NE;
        unsigned int i_frame_size, i_fragments;
        unsigned int i_rate;
        unsigned int i_nb_channels;
        audio_buf_info audio_buf;

        if( ioctl( p_sys->i_fd, SNDCTL_DSP_SETFMT, &i_format ) < 0 )
        {
            msg_Err( p_aout, "cannot set audio output format" );
            goto error;
        }

        switch ( i_format )
        {
        case AFMT_U8:
            p_aout->format.i_format = VLC_CODEC_U8;
            break;
        case AFMT_S8:
            p_aout->format.i_format = VLC_CODEC_S8;
            break;
        case AFMT_U16_LE:
            p_aout->format.i_format = VLC_CODEC_U16L;
            break;
        case AFMT_S16_LE:
            p_aout->format.i_format = VLC_CODEC_S16L;
            break;
        case AFMT_U16_BE:
            p_aout->format.i_format = VLC_CODEC_U16B;
            break;
        case AFMT_S16_BE:
            p_aout->format.i_format = VLC_CODEC_S16B;
            break;
        default:
            msg_Err( p_aout, "OSS fell back to an unknown format (%d)",
                     i_format );
            goto error;
        }

        i_nb_channels = aout_FormatNbChannels( &p_aout->format );

        /* Set the number of channels */
        if( ioctl( p_sys->i_fd, SNDCTL_DSP_CHANNELS, &i_nb_channels ) < 0 ||
            i_nb_channels != aout_FormatNbChannels( &p_aout->format ) )
        {
            msg_Err( p_aout, "cannot set number of audio channels (%s)",
                     aout_FormatPrintChannels( &p_aout->format) );
            goto error;
        }

        /* Set the output rate */
        i_rate = p_aout->format.i_rate;
        if( ioctl( p_sys->i_fd, SNDCTL_DSP_SPEED, &i_rate ) < 0 )
        {
            msg_Err( p_aout, "cannot set audio output rate (%i)",
                             p_aout->format.i_rate );
            goto error;
        }

        if( i_rate != p_aout->format.i_rate )
        {
            p_aout->format.i_rate = i_rate;
        }

        /* Set the fragment size */
        aout_FormatPrepare( &p_aout->format );

        /* i_fragment = xxxxyyyy where: xxxx        is fragtotal
         *                              1 << yyyy   is fragsize */
        i_frame_size = ((uint64_t)p_aout->format.i_bytes_per_frame * p_aout->format.i_rate * 65536) / (48000 * 2 * 2) / FRAME_COUNT;
        i_fragments = 4;
        while( i_fragments < 12 && (1U << i_fragments) < i_frame_size )
        {
            ++i_fragments;
        }
        i_fragments |= FRAME_COUNT << 16;
        if( ioctl( p_sys->i_fd, SNDCTL_DSP_SETFRAGMENT, &i_fragments ) < 0 )
        {
            msg_Warn( p_aout, "cannot set fragment size (%.8x)", i_fragments );
        }

        if( ioctl( p_sys->i_fd, SNDCTL_DSP_GETOSPACE, &audio_buf ) < 0 )
        {
            msg_Err( p_aout, "cannot get fragment size" );
            goto error;
        }

        /* Number of fragments actually allocated */
        p_aout->sys->i_fragstotal = audio_buf.fragstotal;

        /* Maximum duration the soundcard's buffer can hold */
        p_aout->sys->max_buffer_duration =
                (mtime_t)audio_buf.fragstotal * audio_buf.fragsize * 1000000
                / p_aout->format.i_bytes_per_frame
                / p_aout->format.i_rate
                * p_aout->format.i_frame_length;

        aout_PacketInit( p_aout, &p_sys->packet,
                         audio_buf.fragsize/p_aout->format.i_bytes_per_frame );
        aout_VolumeSoftInit( p_aout );
    }

    /* Create OSS thread and wait for its readiness. */
    if( vlc_clone( &p_sys->thread, OSSThread, p_aout,
                   VLC_THREAD_PRIORITY_OUTPUT ) )
    {
        msg_Err( p_aout, "cannot create OSS thread (%m)" );
        aout_PacketDestroy( p_aout );
        goto error;
    }

    return VLC_SUCCESS;

error:
    var_DelCallback( p_aout, "audio-device", aout_ChannelsRestart, NULL );
    close( p_sys->i_fd );
    free( p_sys );
    return VLC_EGENERIC;
}
Пример #8
0
static int PAOpenStream( audio_output_t *p_aout )
{
    aout_sys_t *p_sys = p_aout->sys;
    const PaHostErrorInfo* paLastHostErrorInfo = Pa_GetLastHostErrorInfo();
    PaStreamParameters paStreamParameters;
    vlc_value_t val;
    int i_channels, i_err;
    uint32_t i_channel_mask;

    if( var_Get( p_aout, "audio-device", &val ) < 0 )
    {
        return VLC_EGENERIC;
    }

    if( val.i_int == AOUT_VAR_5_1 )
    {
        p_aout->format.i_physical_channels
            = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
              | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
              | AOUT_CHAN_LFE;
    }
    else if( val.i_int == AOUT_VAR_3F2R )
    {
        p_aout->format.i_physical_channels
            = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
            | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
    }
    else if( val.i_int == AOUT_VAR_2F2R )
    {
        p_aout->format.i_physical_channels
            = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
            | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
    }
    else if( val.i_int == AOUT_VAR_MONO )
    {
        p_aout->format.i_physical_channels = AOUT_CHAN_CENTER;
    }
    else
    {
        p_aout->format.i_physical_channels
            = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
    }

    i_channels = aout_FormatNbChannels( &p_aout->format );
    msg_Dbg( p_aout, "nb_channels requested = %d", i_channels );
    i_channel_mask = p_aout->format.i_physical_channels;

    /* Calculate the frame size in bytes */
    p_sys->i_sample_size = 4 * i_channels;
    aout_FormatPrepare( &p_aout->format );
    aout_PacketInit( p_aout, &p_sys->packet, FRAME_SIZE );
    aout_VolumeSoftInit( p_aout );

    /* Check for channel reordering */
    p_aout->sys->i_channel_mask = i_channel_mask;
    p_aout->sys->i_bits_per_sample = 32; /* forced to paFloat32 */
    p_aout->sys->i_channels = i_channels;

    p_aout->sys->b_chan_reorder =
        aout_CheckChannelReorder( NULL, pi_channels_out,
                                  i_channel_mask, i_channels,
                                  p_aout->sys->pi_chan_table );

    if( p_aout->sys->b_chan_reorder )
    {
        msg_Dbg( p_aout, "channel reordering needed" );
    }

    paStreamParameters.device = p_sys->i_device_id;
    paStreamParameters.channelCount = i_channels;
    paStreamParameters.sampleFormat = paFloat32;
    paStreamParameters.suggestedLatency =
        p_sys->deviceInfo->defaultLowOutputLatency;
    paStreamParameters.hostApiSpecificStreamInfo = NULL;

    i_err = Pa_OpenStream( &p_sys->p_stream, NULL /* no input */,
                &paStreamParameters, (double)p_aout->format.i_rate,
                FRAME_SIZE, paClipOff, paCallback, p_sys );
    if( i_err != paNoError )
    {
        msg_Err( p_aout, "Pa_OpenStream returns %d : %s", i_err,
                 Pa_GetErrorText( i_err ) );
        if( i_err == paUnanticipatedHostError )
        {
            msg_Err( p_aout, "type %d code %ld : %s",
                     paLastHostErrorInfo->hostApiType,
                     paLastHostErrorInfo->errorCode,
                     paLastHostErrorInfo->errorText );
        }
        p_sys->p_stream = 0;
        aout_PacketDestroy( p_aout );
        return VLC_EGENERIC;
    }

    i_err = Pa_StartStream( p_sys->p_stream );
    if( i_err != paNoError )
    {
        msg_Err( p_aout, "Pa_StartStream() failed" );
        Pa_CloseStream( p_sys->p_stream );
        aout_PacketDestroy( p_aout );
        return VLC_EGENERIC;
    }

    return VLC_SUCCESS;
}