/***************************************************************************** * Close: close our file *****************************************************************************/ static void Close( vlc_object_t * p_this ) { aout_instance_t * p_aout = (aout_instance_t *)p_this; msg_Dbg( p_aout, "closing audio file" ); if( p_aout->output.p_sys->b_add_wav_header ) { /* Update Wave Header */ p_aout->output.p_sys->waveh.Length = p_aout->output.p_sys->waveh.DataLength + sizeof(WAVEHEADER) - 4; /* Write Wave Header */ if( fseek( p_aout->output.p_sys->p_file, 0, SEEK_SET ) ) { msg_Err( p_aout, "seek error (%m)" ); } /* Header -> little endian format */ SetDWLE( &p_aout->output.p_sys->waveh.Length, p_aout->output.p_sys->waveh.Length ); SetDWLE( &p_aout->output.p_sys->waveh.DataLength, p_aout->output.p_sys->waveh.DataLength ); if( fwrite( &p_aout->output.p_sys->waveh, sizeof(WAVEHEADER), 1, p_aout->output.p_sys->p_file ) != 1 ) { msg_Err( p_aout, "write error (%m)" ); } } if( p_aout->output.p_sys->p_file != stdout ) fclose( p_aout->output.p_sys->p_file ); free( p_aout->output.p_sys ); }
static char *comment_init(size_t *length) { /*The 'vendor' field should be the actual encoding library used.*/ const char *vendor_string = opus_get_version_string(); int vendor_length = strlen(vendor_string); int user_comment_list_length = 0; int len = 8 + 4 + vendor_length + 4; char *p = malloc(len); if (p == NULL) return NULL; memcpy(p, "OpusTags", 8); SetDWLE(p + 8, vendor_length); memcpy(p + 12, vendor_string, vendor_length); SetDWLE(p + 12 + vendor_length, user_comment_list_length); *length = len; return p; }
static int comment_add(char **comments, size_t *length, const char *tag, const char *val) { char *p = *comments; int vendor_length = GetDWLE(p + 8); size_t user_comment_list_length = GetDWLE(p + 8 + 4 + vendor_length); size_t tag_len = (tag ? strlen(tag) : 0); size_t val_len = strlen(val); size_t len = (*length) + 4 + tag_len + val_len; p = realloc(p, len); if (p == NULL) return 1; SetDWLE(p + *length, tag_len + val_len); /* length of comment */ if (tag) memcpy(p + *length + 4, tag, tag_len); /* comment */ memcpy(p + *length + 4 + tag_len, val, val_len); /* comment */ SetDWLE(p + 8 + 4 + vendor_length, user_comment_list_length + 1); *comments = p; *length = len; return 0; }
/***************************************************************************** * 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; }
/***************************************************************************** * 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; }
static inline void put_le32(uint8_t **p, uint32_t d) { SetDWLE(*p, d); (*p) += 4; }