示例#1
0
文件: tospdif.c 项目: IAPark/vlc
static void set_16( filter_t *p_filter, void *p_buf, uint16_t i_val )
{
    if( p_filter->fmt_out.audio.i_format == VLC_CODEC_SPDIFB )
        SetWBE( p_buf, i_val );
    else
        SetWLE( p_buf, i_val );
}
示例#2
0
/*****************************************************************************
 * DoWork: convert a buffer
 *****************************************************************************/
static block_t *DoWork( filter_t * p_filter, block_t *p_in_buf )
{
    /* AC3 is natively big endian. Most SPDIF devices have the native
     * endianness of the computer system.
     * On Mac OS X however, little endian devices are also common.
     */
    static const uint8_t p_sync_le[6] = { 0x72, 0xF8, 0x1F, 0x4E, 0x01, 0x00 };
    static const uint8_t p_sync_be[6] = { 0xF8, 0x72, 0x4E, 0x1F, 0x00, 0x01 };
    uint16_t i_frame_size = p_in_buf->i_buffer / 2;
    uint8_t * p_in = p_in_buf->p_buffer;

    block_t *p_out_buf = filter_NewAudioBuffer( p_filter, AOUT_SPDIF_SIZE );
    if( !p_out_buf )
        goto out;
    uint8_t * p_out = p_out_buf->p_buffer;

    /* Copy the S/PDIF headers. */
    if( p_filter->fmt_out.audio.i_format == VLC_CODEC_SPDIFB )
    {
        vlc_memcpy( p_out, p_sync_be, 6 );
        p_out[4] = p_in[5] & 0x7; /* bsmod */
        SetWBE( p_out + 6, i_frame_size << 4 );
        vlc_memcpy( &p_out[8], p_in, i_frame_size * 2 );
    }
    else
    {
        vlc_memcpy( p_out, p_sync_le, 6 );
        p_out[5] = p_in[5] & 0x7; /* bsmod */
        SetWLE( p_out + 6, i_frame_size << 4 );
        swab( p_in, &p_out[8], i_frame_size * 2 );
    }
    vlc_memset( p_out + 8 + i_frame_size * 2, 0,
                AOUT_SPDIF_SIZE - i_frame_size * 2 - 8 );

    p_out_buf->i_dts = p_in_buf->i_dts;
    p_out_buf->i_pts = p_in_buf->i_pts;
    p_out_buf->i_nb_samples = p_in_buf->i_nb_samples;
    p_out_buf->i_buffer = AOUT_SPDIF_SIZE;
out:
    block_Release( p_in_buf );
    return p_out_buf;
}
/*****************************************************************************
 * Open: open cdda
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    access_t     *p_access = (access_t*)p_this;
    access_sys_t *p_sys;
    vcddev_t     *vcddev;
    char         *psz_name;

    if( !p_access->psz_filepath || !*p_access->psz_filepath )
    {
        /* Only when selected */
        if( !p_access->psz_access || !*p_access->psz_access )
            return VLC_EGENERIC;

        psz_name = var_InheritString( p_this, "cd-audio" );
        if( !psz_name )
            return VLC_EGENERIC;
    }
    else psz_name = ToLocaleDup( p_access->psz_filepath );

#if defined( _WIN32 ) || defined( __OS2__ )
    if( psz_name[0] && psz_name[1] == ':' &&
        psz_name[2] == '\\' && psz_name[3] == '\0' ) psz_name[2] = '\0';
#endif

    /* Open CDDA */
    if( (vcddev = ioctl_Open( VLC_OBJECT(p_access), psz_name ) ) == NULL )
    {
        msg_Warn( p_access, "could not open %s", psz_name );
        free( psz_name );
        return VLC_EGENERIC;
    }
    free( psz_name );

    /* Set up p_access */
    STANDARD_BLOCK_ACCESS_INIT
    p_sys->vcddev = vcddev;

    /* Do we play a single track ? */
    p_sys->i_track = var_InheritInteger( p_access, "cdda-track" ) - 1;

    if( p_sys->i_track < 0 )
    {
        /* We only do separate items if the whole disc is requested */
        input_thread_t *p_input = access_GetParentInput( p_access );

        int i_ret = -1;
        if( p_input )
        {
            input_item_t *p_current = input_GetItem( p_input );
            if( p_current )
                i_ret = GetTracks( p_access, p_current );

            vlc_object_release( p_input );
        }
        if( i_ret < 0 )
            goto error;
    }
    else
    {
        /* Build a WAV header for the output data */
        memset( &p_sys->waveheader, 0, sizeof(WAVEHEADER) );
        SetWLE( &p_sys->waveheader.Format, 1 ); /*WAVE_FORMAT_PCM*/
        SetWLE( &p_sys->waveheader.BitsPerSample, 16);
        p_sys->waveheader.MainChunkID = VLC_FOURCC('R', 'I', 'F', 'F');
        p_sys->waveheader.Length = 0;               /* we just don't know */
        p_sys->waveheader.ChunkTypeID = VLC_FOURCC('W', 'A', 'V', 'E');
        p_sys->waveheader.SubChunkID = VLC_FOURCC('f', 'm', 't', ' ');
        SetDWLE( &p_sys->waveheader.SubChunkLength, 16);
        SetWLE( &p_sys->waveheader.Modus, 2);
        SetDWLE( &p_sys->waveheader.SampleFreq, 44100);
        SetWLE( &p_sys->waveheader.BytesPerSample,
                    2 /*Modus*/ * 16 /*BitsPerSample*/ / 8 );
        SetDWLE( &p_sys->waveheader.BytesPerSec,
                    2*16/8 /*BytesPerSample*/ * 44100 /*SampleFreq*/ );
        p_sys->waveheader.DataChunkID = VLC_FOURCC('d', 'a', 't', 'a');
        p_sys->waveheader.DataLength = 0;           /* we just don't know */

        p_sys->i_first_sector = var_InheritInteger( p_access,
                                                    "cdda-first-sector" );
        p_sys->i_last_sector  = var_InheritInteger( p_access,
                                                    "cdda-last-sector" );
        /* Tracknumber in MRL */
        if( p_sys->i_first_sector < 0 || p_sys->i_last_sector < 0 )
        {
            const int i_titles = ioctl_GetTracksMap( VLC_OBJECT(p_access),
                                                     p_sys->vcddev, &p_sys->p_sectors );
            if( p_sys->i_track >= i_titles )
            {
                msg_Err( p_access, "invalid track number" );
                goto error;
            }
            p_sys->i_first_sector = p_sys->p_sectors[p_sys->i_track];
            p_sys->i_last_sector = p_sys->p_sectors[p_sys->i_track+1];
        }

        p_sys->i_sector = p_sys->i_first_sector;
        p_access->info.i_size = (p_sys->i_last_sector - p_sys->i_first_sector)
                                     * (int64_t)CDDA_DATA_SIZE;
    }

    return VLC_SUCCESS;

error:
    free( p_sys->p_sectors );
    ioctl_Close( VLC_OBJECT(p_access), p_sys->vcddev );
    free( p_sys );
    return VLC_EGENERIC;
}
示例#4
0
文件: file.c 项目: shanewfx/vlc-arib
/*****************************************************************************
 * Open: open a dummy audio device
 *****************************************************************************/
static int Open( vlc_object_t * p_this )
{
    aout_instance_t * p_aout = (aout_instance_t *)p_this;
    char * psz_name, * psz_format;
    const char * const * ppsz_compare = format_list;
    int i_channels, i = 0;

    psz_name = var_CreateGetString( p_this, "audiofile-file" );
    if( !psz_name || !*psz_name )
    {
        msg_Err( p_aout, "you need to specify an output file name" );
        free( psz_name );
        return VLC_EGENERIC;
    }

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

    if( !strcmp( psz_name, "-" ) )
        p_aout->output.p_sys->p_file = stdout;
    else
        p_aout->output.p_sys->p_file = utf8_fopen( psz_name, "wb" );

    free( psz_name );
    if ( p_aout->output.p_sys->p_file == NULL )
    {
        free( p_aout->output.p_sys );
        return VLC_EGENERIC;
    }

    p_aout->output.pf_play = Play;

    /* Audio format */
    psz_format = var_CreateGetString( p_this, "audiofile-format" );

    while ( *ppsz_compare != NULL )
    {
        if ( !strncmp( *ppsz_compare, psz_format, strlen(*ppsz_compare) ) )
        {
            break;
        }
        ppsz_compare++; i++;
    }

    if ( *ppsz_compare == NULL )
    {
        msg_Err( p_aout, "cannot understand the format string (%s)",
                 psz_format );
        if( p_aout->output.p_sys->p_file != stdout )
            fclose( p_aout->output.p_sys->p_file );
        free( p_aout->output.p_sys );
        free( psz_format );
        return VLC_EGENERIC;
    }
    free( psz_format );

    p_aout->output.output.i_format = format_int[i];
    if ( AOUT_FMT_NON_LINEAR( &p_aout->output.output ) )
    {
        p_aout->output.i_nb_samples = A52_FRAME_NB;
        p_aout->output.output.i_bytes_per_frame = AOUT_SPDIF_SIZE;
        p_aout->output.output.i_frame_length = A52_FRAME_NB;
        aout_VolumeNoneInit( p_aout );
    }
    else
    {
        p_aout->output.i_nb_samples = FRAME_SIZE;
        aout_VolumeSoftInit( p_aout );
    }

    /* Channels number */
    i_channels = var_CreateGetInteger( p_this, "audiofile-channels" );

    if( i_channels > 0 && i_channels <= CHANNELS_MAX )
    {
        p_aout->output.output.i_physical_channels =
            pi_channels_maps[i_channels];
    }

    /* WAV header */
    p_aout->output.p_sys->b_add_wav_header = var_CreateGetBool( p_this,
                                                        "audiofile-wav" );

    if( p_aout->output.p_sys->b_add_wav_header )
    {
        /* Write wave header */
        WAVEHEADER *wh = &p_aout->output.p_sys->waveh;

        memset( wh, 0, sizeof(wh) );

        switch( p_aout->output.output.i_format )
        {
        case VLC_CODEC_FL32:
            wh->Format     = WAVE_FORMAT_IEEE_FLOAT;
            wh->BitsPerSample = sizeof(float) * 8;
            break;
        case VLC_CODEC_U8:
            wh->Format     = WAVE_FORMAT_PCM;
            wh->BitsPerSample = 8;
            break;
        case VLC_CODEC_S16L:
        default:
            wh->Format     = WAVE_FORMAT_PCM;
            wh->BitsPerSample = 16;
            break;
        }

        wh->MainChunkID = VLC_FOURCC('R', 'I', 'F', 'F');
        wh->Length = 0;                    /* temp, to be filled in as we go */
        wh->ChunkTypeID = VLC_FOURCC('W', 'A', 'V', 'E');
        wh->SubChunkID = VLC_FOURCC('f', 'm', 't', ' ');
        wh->SubChunkLength = 16;

        wh->Modus = aout_FormatNbChannels( &p_aout->output.output );
        wh->SampleFreq = p_aout->output.output.i_rate;
        wh->BytesPerSample = wh->Modus * ( wh->BitsPerSample / 8 );
        wh->BytesPerSec = wh->BytesPerSample * wh->SampleFreq;

        wh->DataChunkID = VLC_FOURCC('d', 'a', 't', 'a');
        wh->DataLength = 0;                /* temp, to be filled in as we go */

        /* Header -> little endian format */
        SetWLE( &wh->Format, wh->Format );
        SetWLE( &wh->BitsPerSample, wh->BitsPerSample );
        SetDWLE( &wh->SubChunkLength, wh->SubChunkLength );
        SetWLE( &wh->Modus, wh->Modus );
        SetDWLE( &wh->SampleFreq, wh->SampleFreq );
        SetWLE( &wh->BytesPerSample, wh->BytesPerSample );
        SetDWLE( &wh->BytesPerSec, wh->BytesPerSec );

        if( fwrite( wh, sizeof(WAVEHEADER), 1,
                    p_aout->output.p_sys->p_file ) != 1 )
        {
            msg_Err( p_aout, "write error (%m)" );
        }
    }

    return 0;
}
示例#5
0
文件: dtstospdif.c 项目: Mettbrot/vlc
/*****************************************************************************
 * DoWork: convert a buffer
 *****************************************************************************/
static block_t *DoWork( filter_t * p_filter, block_t * p_in_buf )
{
    uint32_t i_ac5_spdif_type = 0;
    uint16_t i_fz = p_in_buf->i_nb_samples * 4;
    uint16_t i_frame, i_length = p_in_buf->i_buffer;
    static const uint8_t p_sync_le[6] = { 0x72, 0xF8, 0x1F, 0x4E, 0x00, 0x00 };
    static const uint8_t p_sync_be[6] = { 0xF8, 0x72, 0x4E, 0x1F, 0x00, 0x00 };

    if( p_in_buf->i_buffer != p_filter->p_sys->i_frame_size )
    {
        /* Frame size changed, reset everything */
        msg_Warn( p_filter, "Frame size changed from %zu to %zu, "
                          "resetting everything.",
                  p_filter->p_sys->i_frame_size, p_in_buf->i_buffer );

        p_filter->p_sys->i_frame_size = p_in_buf->i_buffer;
        p_filter->p_sys->p_buf = xrealloc( p_filter->p_sys->p_buf,
                                                  p_in_buf->i_buffer * 3 );
        p_filter->p_sys->i_frames = 0;
    }

    /* Backup frame */
    /* TODO: keeping the blocks in a list would save one memcpy */
    memcpy( p_filter->p_sys->p_buf + p_in_buf->i_buffer *
                  p_filter->p_sys->i_frames,
                p_in_buf->p_buffer, p_in_buf->i_buffer );

    p_filter->p_sys->i_frames++;

    if( p_filter->p_sys->i_frames < 3 )
    {
        if( p_filter->p_sys->i_frames == 1 )
            /* We'll need the starting date */
            p_filter->p_sys->start_date = p_in_buf->i_pts;

        /* Not enough data */
        block_Release( p_in_buf );
        return NULL;
    }

    p_filter->p_sys->i_frames = 0;
    block_t *p_out_buf = filter_NewAudioBuffer( p_filter,
                                                12 * p_in_buf->i_nb_samples );
    if( !p_out_buf )
        goto out;

    for( i_frame = 0; i_frame < 3; i_frame++ )
    {
        uint16_t i_length_padded = i_length;
        uint8_t * p_out = p_out_buf->p_buffer + (i_frame * i_fz);
        uint8_t * p_in = p_filter->p_sys->p_buf + (i_frame * i_length);

        switch( p_in_buf->i_nb_samples )
        {
            case  512: i_ac5_spdif_type = 0x0B; break;
            case 1024: i_ac5_spdif_type = 0x0C; break;
            case 2048: i_ac5_spdif_type = 0x0D; break;
        }

        /* Copy the S/PDIF headers. */
        if( p_filter->fmt_out.audio.i_format == VLC_CODEC_SPDIFB )
        {
            memcpy( p_out, p_sync_be, 6 );
            p_out[5] = i_ac5_spdif_type;
            SetWBE( p_out + 6, i_length << 3 );
        }
        else
        {
            memcpy( p_out, p_sync_le, 6 );
            p_out[4] = i_ac5_spdif_type;
            SetWLE( p_out + 6, i_length << 3 );
        }

        if( ( (p_in[0] == 0x1F || p_in[0] == 0x7F) && p_filter->fmt_out.audio.i_format == VLC_CODEC_SPDIFL ) ||
            ( (p_in[0] == 0xFF || p_in[0] == 0xFE) && p_filter->fmt_out.audio.i_format == VLC_CODEC_SPDIFB ) )
        {
            /* We are dealing with a big endian bitstream and a little endian output
             * or a little endian bitstream and a big endian output.
             * Byteswap the stream */
            swab( p_in, p_out + 8, i_length );

            /* If i_length is odd, we have to adjust swapping a bit.. */
            if( i_length & 1 )
            {
                p_out[8+i_length-1] = 0;
                p_out[8+i_length] = p_in[i_length-1];
                i_length_padded++;
            }
        }
        else
        {
            memcpy( p_out + 8, p_in, i_length );
        }

        if( i_fz > i_length + 8 )
        {
            memset( p_out + 8 + i_length_padded, 0,
                        i_fz - i_length_padded - 8 );
        }
    }

    p_out_buf->i_pts = p_filter->p_sys->start_date;
    p_out_buf->i_nb_samples = p_in_buf->i_nb_samples * 3;
    p_out_buf->i_buffer = p_out_buf->i_nb_samples * 4;
out:
    block_Release( p_in_buf );
    return p_out_buf;
}