void print_header_compact(mpg123_handle *mh) { struct mpg123_frameinfo i; mpg123_info(mh, &i); if(i.mode > 4 || i.mode < 0) i.mode = 4; if(i.version > 3 || i.version < 0) i.version = 3; if(i.layer > 3 || i.layer < 0) i.layer = 0; fprintf(stderr,"MPEG %s layer %s, ", versions[i.version], layers[i.layer]); switch(i.vbr) { case MPG123_CBR: if(i.bitrate) fprintf(stderr, "%d kbit/s", i.bitrate); else fprintf(stderr, "%d kbit/s (free format)", (int)((double)i.framesize*8*i.rate*0.001/samples_pre_frame[i.version][i.layer]+0.5)); break; case MPG123_VBR: fprintf(stderr, "VBR"); break; case MPG123_ABR: fprintf(stderr, "%d kbit/s ABR", i.abr_rate); break; default: fprintf(stderr, "???"); } fprintf(stderr,", %ld Hz %s\n", i.rate, smodes[i.mode]); }
void print_header(mpg123_handle *mh) { struct mpg123_frameinfo i; mpg123_info(mh, &i); if(i.mode > 4 || i.mode < 0) i.mode = 4; if(i.version > 3 || i.version < 0) i.version = 3; if(i.layer > 3 || i.layer < 0) i.layer = 0; fprintf(stderr,"MPEG %s, Layer: %s, Freq: %ld, mode: %s, modext: %d, BPF : %d\n", versions[i.version], layers[i.layer], i.rate, modes[i.mode],i.mode_ext,i.framesize); fprintf(stderr,"Channels: %d, copyright: %s, original: %s, CRC: %s, emphasis: %d.\n", i.mode == MPG123_M_MONO ? 1 : 2,i.flags & MPG123_COPYRIGHT ? "Yes" : "No", i.flags & MPG123_ORIGINAL ? "Yes" : "No", i.flags & MPG123_CRC ? "Yes" : "No", i.emphasis); fprintf(stderr,"Bitrate: "); switch(i.vbr) { case MPG123_CBR: fprintf(stderr, "%d kbit/s", i.bitrate); break; case MPG123_VBR: fprintf(stderr, "VBR"); break; case MPG123_ABR: fprintf(stderr, "%d kbit/s ABR", i.abr_rate); break; default: fprintf(stderr, "???"); } fprintf(stderr, " Extension value: %d\n", i.flags & MPG123_PRIVATE ? 1 : 0); }
void MP3Update2( long BUF_SIZE ) { double cSec; mpg123_position(musicfile,0,0,0,0,&cSec,0); if ( Type == 2 && !knownSize ) { currBytes += BUF_SIZE; pltime = currBytes / (rate*chn*2); } else pltime = cSec; SongPos = pltime; mpg123_info(musicfile,&frameinfo); getBR = QString::number( frameinfo.bitrate ) + "kbps"; if ( pltime != tmpPltime && Type == 2 && !knownSize ) { TMPint++; tmpPltime = pltime; } if ( Type == 2 && TMPint == 10 && !knownSize ) { TMPint = 0; if ( !titleThr.isRunning() ) titleThr.start(); } }
/* Update mean bitrate. This could be dropped if accurate time display * on audio file playback is not desired. */ static void update_info(struct dec_audio *da) { struct ad_mpg123_context *con = da->priv; struct mpg123_frameinfo finfo; if (mpg123_info(con->handle, &finfo) != MPG123_OK) return; /* finfo.bitrate is expressed in kilobits */ const int bitrate = finfo.bitrate * 1000; if (finfo.vbr != MPG123_CBR) { if (--con->delay < 1) { if (++con->mean_count > ((unsigned int) -1) / 2) con->mean_count = ((unsigned int) -1) / 4; /* Might not be numerically optimal, but works fine enough. */ con->mean_rate = ((con->mean_count - 1) * con->mean_rate + bitrate) / con->mean_count; da->bitrate = (int) (con->mean_rate + 0.5); con->delay = 10; } } else { da->bitrate = bitrate ? bitrate : compute_bitrate(&finfo); con->delay = 1; con->mean_rate = 0.; con->mean_count = 0; } }
qint64 DecoderMPG123::read(unsigned char *data, qint64 size) { size_t done = 0; int err = mpg123_read(m_handle, data, size, &done); if(err != MPG123_DONE && err != MPG123_OK) { qWarning("DecoderMPG123: decoder error: %s", mpg123_plain_strerror(err)); return -1; } mpg123_info(m_handle, &m_frame_info); return done; }
static bool is_mp3(FILE *fp, struct file_type **ft) { mpg123_init(); int err; mpg123_handle *mh = mpg123_new(NULL, &err); if (mh == NULL) { fprintf(stderr, "Could not create mpg123 handle: %s\n", mpg123_plain_strerror(err)); return false; } long pos = ftell(fp); if (mpg123_open_fd(mh, fileno(fp)) != MPG123_OK) { fseek(fp, pos, SEEK_SET); return false; } mpg123_scan(mh); struct mpg123_frameinfo fi; mpg123_info(mh, &fi); if (mpg123_format(mh, fi.rate, MPG123_STEREO, MPG123_ENC_SIGNED_16) != MPG123_OK) { fseek(fp, pos, SEEK_SET); return false; } off_t length = mpg123_length(mh); struct mp3_format *fmt = calloc(sizeof(*fmt), 1); *ft = &fmt->ft; fmt->mh = mh; fmt->tpf = mpg123_tpf(mh); fmt->ft.channels = 2; fmt->ft.position = 0; fmt->ft.length = (length + (fi.rate / 2)) / fi.rate; fmt->ft.sample_rate = fi.rate; fmt->ft.sample_size = 2; fmt->ft.sample_type = ST_SIGNED_INTEGER_LE; fmt->ft.bitrate = (double)fi.abr_rate; return true; }
static int UpdateAudioFormat( decoder_t *p_dec ) { int i_err; decoder_sys_t *p_sys = p_dec->p_sys; struct mpg123_frameinfo frame_info; /* Get details about the stream */ i_err = mpg123_info( p_sys->p_handle, &frame_info ); if( i_err != MPG123_OK ) { msg_Err( p_dec, "mpg123_info failed: %s", mpg123_plain_strerror( i_err ) ); return VLC_EGENERIC; } p_dec->fmt_out.i_bitrate = frame_info.bitrate * 1000; switch( frame_info.mode ) { case MPG123_M_DUAL: p_dec->fmt_out.audio.i_chan_mode = AOUT_CHANMODE_DUALMONO; /* fall through */ case MPG123_M_STEREO: case MPG123_M_JOINT: p_dec->fmt_out.audio.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT; break; case MPG123_M_MONO: p_dec->fmt_out.audio.i_physical_channels = AOUT_CHAN_CENTER; break; default: return VLC_EGENERIC; } aout_FormatPrepare( &p_dec->fmt_out.audio ); /* Date management */ if( p_dec->fmt_out.audio.i_rate != frame_info.rate ) { p_dec->fmt_out.audio.i_rate = frame_info.rate; date_Init( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 ); date_Set( &p_sys->end_date, 0 ); } return decoder_UpdateAudioFormat( p_dec ); }
void print_header_compact(mpg123_handle *mh) { struct mpg123_frameinfo i; mpg123_info(mh, &i); if(i.mode > 4 || i.mode < 0) i.mode = 4; if(i.version > 3 || i.version < 0) i.version = 3; if(i.layer > 3 || i.layer < 0) i.layer = 0; fprintf(stderr,"MPEG %s layer %s, ", versions[i.version], layers[i.layer]); switch(i.vbr) { case MPG123_CBR: fprintf(stderr, "%d kbit/s", i.bitrate); break; case MPG123_VBR: fprintf(stderr, "VBR"); break; case MPG123_ABR: fprintf(stderr, "%d kbit/s ABR", i.abr_rate); break; default: fprintf(stderr, "???"); } fprintf(stderr,", %ld Hz %s\n", i.rate, smodes[i.mode]); }
/* ----------- Global Functions ---------------------------------- */ int mpeg_isvalid(char *path) { int rv = 0; int fd = 0; struct mpg123_frameinfo finfo; fd = mpeg_open(path); if(fd != -1) { if(handle && (mpg123_info(handle->mh, &finfo) == MPG123_OK)) { rv = 1; } mpeg_close(fd); } return rv; }
void new_format(struct playerHandles *ph){ long ratel; int channels, enc,enc_bit=2; unsigned int rate; int guess=0; char tail[OUTPUT_TAIL_SIZE]; struct mpg123_frameinfo fi; mpg123_getformat(h.m, &ratel, &channels, &enc); if(enc&MPG123_ENC_8) enc=1; else if(enc&MPG123_ENC_16) enc=2; else if(enc&MPG123_ENC_24) enc=3; else if(enc&(MPG123_ENC_32|MPG123_ENC_FLOAT_32)) enc=4; else if(enc&MPG123_ENC_FLOAT_64) enc=8; else enc=0; rate=(unsigned int)ratel; mpg123_info(h.m,&fi); enc_bit=enc*8; snprintf(tail,OUTPUT_TAIL_SIZE,"New format: %dHz %dch %dbit %dkbps %s",(int)ratel, channels, enc_bit,fi.vbr==MPG123_ABR?fi.abr_rate:fi.bitrate,fi.vbr!=MPG123_CBR?"VBR":""); if(!rate) guess=ratel=rate=44100; if(!channels) guess=channels=2; if(!enc) guess=enc=16; if(guess) snprintf(tail,OUTPUT_TAIL_SIZE,"Guessing: %dHz %dch %dbit",(int)ratel, channels, enc_bit); addStatusTail(tail,ph->outdetail); snd_param_init(ph,&enc_bit,&channels,&rate); ph->dec_rate=ratel; ph->dec_enc=enc_bit; ph->dec_chan=channels; h.framesize=enc*channels; h.samptime=ratel*h.framesize; }
void print_remote_header(mpg123_handle *mh) { struct mpg123_frameinfo i; mpg123_info(mh, &i); if(i.mode >= 4 || i.mode < 0) i.mode = 4; if(i.version >= 3 || i.version < 0) i.version = 3; generic_sendmsg("S %s %d %ld %s %d %d %d %d %d %d %d %d %d", versions[i.version], i.layer, i.rate, modes[i.mode], i.mode_ext, i.framesize, i.mode == MPG123_M_MONO ? 1 : 2, i.flags & MPG123_COPYRIGHT ? 1 : 0, i.flags & MPG123_CRC ? 1 : 0, i.emphasis, i.bitrate, i.flags & MPG123_PRIVATE ? 1 : 0, i.vbr); }
VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; char filename[PATH_LIMIT]; off_t start_offset, meta_offset_offset, meta_offset, post_meta_offset; int32_t loop_start, loop_end; int loop_flag = 0; int channel_count; int codec_id; int aux_chunk_count; int32_t (*read_32bit)(off_t,STREAMFILE*) = NULL; int16_t (*read_16bit)(off_t,STREAMFILE*) = NULL; /* check extension, case insensitive */ streamFile->get_name(streamFile,filename,sizeof(filename)); if (strcasecmp("scd",filename_extension(filename))) goto fail; /* SEDB */ if (read_32bitBE(0,streamFile) != 0x53454442) goto fail; /* SSCF */ if (read_32bitBE(4,streamFile) != 0x53534346) goto fail; if (read_32bitBE(8,streamFile) == 2 || read_32bitBE(8,streamFile) == 3) { /* version 2 BE, as seen in FFXIII demo for PS3 */ /* version 3 BE, as seen in FFXIII for PS3 */ read_32bit = read_32bitBE; read_16bit = read_16bitBE; //size_offset = 0x14; meta_offset_offset = 0x40 + read_16bit(0xe,streamFile); } else if (read_32bitLE(8,streamFile) == 3 || read_32bitLE(8,streamFile) == 2) { /* version 2/3 LE, as seen in FFXIV for ?? */ read_32bit = read_32bitLE; read_16bit = read_16bitLE; //size_offset = 0x10; meta_offset_offset = 0x40 + read_16bit(0xe,streamFile); } else goto fail; /* never mind, FFXIII music_68tak.ps3.scd is 0x80 shorter */ #if 0 /* check file size with header value */ if (read_32bit(size_offset,streamFile) != get_streamfile_size(streamFile)) goto fail; #endif meta_offset = read_32bit(meta_offset_offset,streamFile); /* check that chunk size equals stream size (?) */ loop_start = read_32bit(meta_offset+0x10,streamFile); loop_end = read_32bit(meta_offset+0x14,streamFile); loop_flag = (loop_end > 0); channel_count = read_32bit(meta_offset+4,streamFile); codec_id = read_32bit(meta_offset+0xc,streamFile); post_meta_offset = meta_offset + 0x20; /* data at meta_offset is only 0x20 bytes, but there may be auxiliary chunks before anything else */ aux_chunk_count = read_32bit(meta_offset+0x1c,streamFile); for (; aux_chunk_count > 0; aux_chunk_count --) { /* skip aux chunks */ /*printf("skipping %08x\n", read_32bitBE(post_meta_offset, streamFile));*/ post_meta_offset += read_32bit(post_meta_offset+4,streamFile); } start_offset = post_meta_offset + read_32bit(meta_offset+0x18,streamFile); #ifdef VGM_USE_VORBIS if (codec_id == 0x6) { vgm_vorbis_info_t inf; uint32_t seek_table_size = read_32bit(post_meta_offset+0x10, streamFile); uint32_t vorb_header_size = read_32bit(post_meta_offset+0x14, streamFile); VGMSTREAM * result = NULL; memset(&inf, 0, sizeof(inf)); inf.loop_start = loop_start; inf.loop_end = loop_end; inf.loop_flag = loop_flag; inf.loop_end_found = loop_flag; inf.loop_length_found = 0; inf.layout_type = layout_ogg_vorbis; inf.meta_type = meta_SQEX_SCD; result = init_vgmstream_ogg_vorbis_callbacks(streamFile, filename, NULL, start_offset, &inf); if (result != NULL) { return result; } // try skipping seek table { if ((post_meta_offset-meta_offset) + seek_table_size + vorb_header_size != read_32bit(meta_offset+0x18, streamFile)) { return NULL; } start_offset = post_meta_offset + 0x20 + seek_table_size; result = init_vgmstream_ogg_vorbis_callbacks(streamFile, filename, NULL, start_offset, &inf); if (result != NULL) { return result; } } // failed with Ogg, try deobfuscating header { // skip chunks before xor_byte unsigned char xor_byte; xor_byte = read_8bit(post_meta_offset+2, streamFile); if (xor_byte == 0) { return NULL; } inf.scd_xor = xor_byte; inf.scd_xor_len = vorb_header_size; result = init_vgmstream_ogg_vorbis_callbacks(streamFile, filename, NULL, start_offset, &inf); return result; } } #endif /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; /* fill in the vital statistics */ vgmstream->channels = channel_count; vgmstream->sample_rate = read_32bit(meta_offset+8,streamFile); switch (codec_id) { case 0x1: /* PCM */ vgmstream->coding_type = coding_PCM16LE_int; vgmstream->layout_type = layout_none; vgmstream->num_samples = read_32bit(meta_offset+0,streamFile) / 2 / channel_count; if (loop_flag) { vgmstream->loop_start_sample = loop_start / 2 / channel_count; vgmstream->loop_end_sample = loop_end / 2 / channel_count; } break; #ifdef VGM_USE_MPEG case 0x7: /* MPEG */ { mpeg_codec_data *mpeg_data = NULL; struct mpg123_frameinfo mi; coding_t ct; if (vgmstream->sample_rate == 47999) vgmstream->sample_rate = 48000; if (vgmstream->sample_rate == 44099) vgmstream->sample_rate = 44100; mpeg_data = init_mpeg_codec_data(streamFile, start_offset, vgmstream->sample_rate, vgmstream->channels, &ct, NULL, NULL); if (!mpeg_data) goto fail; vgmstream->codec_data = mpeg_data; if (MPG123_OK != mpg123_info(mpeg_data->m, &mi)) goto fail; vgmstream->coding_type = ct; vgmstream->layout_type = layout_mpeg; if (mi.vbr != MPG123_CBR) goto fail; vgmstream->num_samples = mpeg_bytes_to_samples(read_32bit(meta_offset+0,streamFile), &mi); vgmstream->num_samples -= vgmstream->num_samples%576; if (loop_flag) { vgmstream->loop_start_sample = mpeg_bytes_to_samples(loop_start, &mi); vgmstream->loop_start_sample -= vgmstream->loop_start_sample%576; vgmstream->loop_end_sample = mpeg_bytes_to_samples(loop_end, &mi); vgmstream->loop_end_sample -= vgmstream->loop_end_sample%576; } vgmstream->interleave_block_size = 0; } break; #endif case 0xC: /* MS ADPCM */ vgmstream->coding_type = coding_MSADPCM; vgmstream->layout_type = layout_none; vgmstream->interleave_block_size = read_16bit(post_meta_offset+0xc,streamFile); vgmstream->num_samples = msadpcm_bytes_to_samples(read_32bit(meta_offset+0,streamFile), vgmstream->interleave_block_size, vgmstream->channels); if (loop_flag) { vgmstream->loop_start_sample = msadpcm_bytes_to_samples(loop_start, vgmstream->interleave_block_size, vgmstream->channels); vgmstream->loop_end_sample = msadpcm_bytes_to_samples(loop_end, vgmstream->interleave_block_size, vgmstream->channels); } break; case 0xA: /* GC/Wii DSP ADPCM */ { STREAMFILE * file; int i; const off_t interleave_size = 0x800; const off_t stride_size = interleave_size * channel_count; size_t total_size; scd_int_codec_data * data = NULL; vgmstream->coding_type = coding_NGC_DSP; vgmstream->layout_type = layout_scd_int; /* a normal DSP header... */ vgmstream->num_samples = read_32bitBE(start_offset+0,streamFile); total_size = (read_32bitBE(start_offset+4,streamFile)+1)/2; if (loop_flag) { vgmstream->loop_start_sample = loop_start; vgmstream->loop_end_sample = loop_end+1; } /* verify other channel headers */ for (i = 1; i < channel_count; i++) { if (read_32bitBE(start_offset+interleave_size*i+0,streamFile) != vgmstream->num_samples || (read_32bitBE(start_offset+4,streamFile)+1)/2 != total_size) { goto fail; } } /* the primary streamfile we'll be using */ file = streamFile->open(streamFile,filename,stride_size); if (!file) goto fail; vgmstream->ch[0].streamfile = file; data = malloc(sizeof(scd_int_codec_data)); data->substream_count = channel_count; data->substreams = calloc(channel_count, sizeof(VGMSTREAM *)); data->intfiles = calloc(channel_count, sizeof(STREAMFILE *)); vgmstream->codec_data = data; for (i=0;i<channel_count;i++) { STREAMFILE * intfile = open_scdint_with_STREAMFILE(file, "ARBITRARY.DSP", start_offset+interleave_size*i, interleave_size, stride_size, total_size); data->substreams[i] = init_vgmstream_ngc_dsp_std(intfile); data->intfiles[i] = intfile; if (!data->substreams[i]) goto fail; /* TODO: only handles mono substreams, though that's all we have with DSP */ /* save start things so we can restart for seeking/looping */ /* copy the channels */ memcpy(data->substreams[i]->start_ch,data->substreams[i]->ch,sizeof(VGMSTREAMCHANNEL)*1); /* copy the whole VGMSTREAM */ memcpy(data->substreams[i]->start_vgmstream,data->substreams[i],sizeof(VGMSTREAM)); } } break; #ifdef VGM_USE_FFMPEG case 0xB: /* XMA1/XMA2 */ { uint16_t codec_id = read_16bit(post_meta_offset, streamFile); if (codec_id == 0x165 || codec_id == 0x166) { ffmpeg_codec_data *ffmpeg_data = init_ffmpeg_faux_riff(streamFile, post_meta_offset, start_offset, streamFile->get_size(streamFile) - start_offset, read_32bit == read_32bitBE); if (!ffmpeg_data) goto fail; vgmstream->codec_data = ffmpeg_data; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; vgmstream->num_samples = ffmpeg_data->totalSamples; if (loop_flag) { vgmstream->loop_start_sample = loop_start; vgmstream->loop_end_sample = loop_end; } } else goto fail; } break; #endif default: goto fail; } vgmstream->meta_type = meta_SQEX_SCD; /* open the file for reading */ if (vgmstream->layout_type != layout_scd_int #ifdef VGM_USE_FFMPEG && vgmstream->coding_type != coding_FFmpeg #endif ) { int i; STREAMFILE * file; file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); if (!file) goto fail; for (i=0;i<channel_count;i++) { vgmstream->ch[i].streamfile = file; vgmstream->ch[i].channel_start_offset= vgmstream->ch[i].offset=start_offset; } } return vgmstream; /* clean up anything we may have opened */ fail: if (vgmstream) close_vgmstream(vgmstream); return NULL; }
/**************************************************************************** * DecodeBlock: the whole thing ****************************************************************************/ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) { int i_err; block_t *p_block = pp_block ? *pp_block : NULL; decoder_sys_t *p_sys = p_dec->p_sys; if( !pp_block || !p_block ) return NULL; if( p_block->i_buffer == 0 ) return NULL; if( !date_Get( &p_sys->end_date ) && p_block->i_pts <= VLC_TS_INVALID ) { /* We've just started the stream, wait for the first PTS. */ msg_Dbg( p_dec, "waiting for PTS" ); goto error; } if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED) ) { date_Set( &p_sys->end_date, 0 ); if( p_block->i_flags & BLOCK_FLAG_CORRUPTED ) goto error; } /* Feed mpg123 with raw data */ i_err = mpg123_feed( p_sys->p_handle, p_block->p_buffer, p_block->i_buffer ); if( i_err != MPG123_OK ) { msg_Err( p_dec, "mpg123_feed failed: %s", mpg123_plain_strerror( i_err ) ); goto error; } /* Get details about the stream */ i_err = mpg123_info( p_sys->p_handle, &p_sys->frame_info ); if( i_err == MPG123_NEED_MORE ) { /* Need moar data */ goto error; } else if( i_err != MPG123_OK ) { msg_Err( p_dec, "mpg123_info failed: %s", mpg123_plain_strerror( i_err ) ); goto error; } /* Configure the output */ p_block->i_nb_samples = mpg123_spf( p_sys->p_handle ); p_dec->fmt_out.i_bitrate = p_sys->frame_info.bitrate * 1000; switch( p_sys->frame_info.mode ) { case MPG123_M_STEREO: case MPG123_M_JOINT: p_dec->fmt_out.audio.i_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT; break; case MPG123_M_DUAL: p_dec->fmt_out.audio.i_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_DUALMONO; break; case MPG123_M_MONO: p_dec->fmt_out.audio.i_original_channels = AOUT_CHAN_CENTER; break; default: msg_Err( p_dec, "Unknown mode"); goto error; } p_dec->fmt_out.audio.i_physical_channels = p_dec->fmt_out.audio.i_original_channels & AOUT_CHAN_PHYSMASK; /* Date management */ if( p_dec->fmt_out.audio.i_rate != p_sys->frame_info.rate ) { p_dec->fmt_out.audio.i_rate = p_sys->frame_info.rate; date_Init( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 ); date_Set( &p_sys->end_date, 0 ); } if( p_block->i_pts > VLC_TS_INVALID && p_block->i_pts != date_Get( &p_sys->end_date ) ) { date_Set( &p_sys->end_date, p_block->i_pts ); } /* Request a new audio buffer */ block_t *p_out = decoder_NewAudioBuffer( p_dec, p_block->i_nb_samples ); if( unlikely( !p_out ) ) goto error; /* Configure the buffer */ p_out->i_nb_samples = p_block->i_nb_samples; p_out->i_dts = p_out->i_pts = date_Get( &p_sys->end_date ); p_out->i_length = date_Increment( &p_sys->end_date, p_block->i_nb_samples ) - p_out->i_pts; /* Make mpg123 write directly into the VLC output buffer */ i_err = mpg123_replace_buffer( p_sys->p_handle, p_out->p_buffer, p_out->i_buffer ); if( i_err != MPG123_OK ) { msg_Err( p_dec, "could not replace buffer: %s", mpg123_plain_strerror( i_err ) ); block_Release( p_out ); goto error; } *pp_block = NULL; /* avoid being fed the same packet again */ /* Do the actual decoding now */ i_err = mpg123_decode_frame( p_sys->p_handle, NULL, NULL, NULL ); if( i_err != MPG123_OK ) { if( i_err != MPG123_NEW_FORMAT ) msg_Err( p_dec, "mpg123_decode_frame error: %s", mpg123_plain_strerror( i_err ) ); block_Release( p_out ); goto error; } block_Release( p_block ); return p_out; error: block_Release( p_block ); return NULL; }
/* MSF header */ VGMSTREAM * init_vgmstream_ps3_msf(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; char filename[260]; off_t start_offset; int32_t loop_start, loop_end; int loop_flag = 0; int channel_count; int codec_id; size_t fileLength; /* check extension, case insensitive */ streamFile->get_name(streamFile,filename,sizeof(filename)); if (strcasecmp("msf",filename_extension(filename))) goto fail; if (read_8bit(0x0,streamFile) != 0x4D) goto fail; /* M */ if (read_8bit(0x1,streamFile) != 0x53) goto fail; /* S */ if (read_8bit(0x2,streamFile) != 0x46) goto fail; /* F */ fileLength = get_streamfile_size(streamFile); loop_flag = (read_32bitBE(0x18,streamFile) != 0xFFFFFFFF); if (loop_flag) { loop_start = read_32bitBE(0x18,streamFile); loop_end = read_32bitBE(0x0C,streamFile); } channel_count = read_32bitBE(0x8,streamFile); codec_id = read_32bitBE(0x4,streamFile); /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; /* fill in the vital statistics */ vgmstream->channels = channel_count; /* Sample rate hack for strange files that don't have a specified frequency */ if (read_32bitBE(0x10,streamFile)==0x00000000) vgmstream->sample_rate = 48000; else vgmstream->sample_rate = read_32bitBE(0x10,streamFile); start_offset = 0x40; switch (codec_id) { case 0x0: /* PCM (Big Endian) */ { vgmstream->coding_type = coding_PCM16BE; vgmstream->num_samples = read_32bitBE(0x0C,streamFile)/2/channel_count; if (loop_flag){ vgmstream->loop_start_sample = loop_start/2/channel_count; vgmstream->loop_end_sample = loop_end/2/channel_count; } if (channel_count == 1) { vgmstream->layout_type = layout_none; } else if (channel_count > 1) { vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = 2; } } break; case 0x3: /* PSx ADPCM */ { vgmstream->coding_type = coding_PSX; vgmstream->num_samples = read_32bitBE(0x0C,streamFile)*28/16/channel_count; if (vgmstream->num_samples == 0xFFFFFFFF) { vgmstream->num_samples = (fileLength - start_offset)*28/16/channel_count; } if (loop_flag) { vgmstream->loop_start_sample = loop_start*28/16/channel_count; vgmstream->loop_end_sample = loop_end*28/16/channel_count; } if (channel_count == 1) { vgmstream->layout_type = layout_none; } else if (channel_count > 1) { vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = 0x10; // read_32bitBE(0x14,streamFile); } } break; #ifdef VGM_USE_MPEG case 0x7: /* MPEG */ { mpeg_codec_data *mpeg_data = NULL; struct mpg123_frameinfo mi; coding_t ct; mpeg_data = init_mpeg_codec_data(streamFile, start_offset, vgmstream->sample_rate, vgmstream->channels, &ct, NULL, NULL); if (!mpeg_data) goto fail; vgmstream->codec_data = mpeg_data; if (MPG123_OK != mpg123_info(mpeg_data->m, &mi)) goto fail; vgmstream->coding_type = ct; vgmstream->layout_type = layout_mpeg; if (mi.vbr != MPG123_CBR) goto fail; vgmstream->num_samples = mpeg_bytes_to_samples(read_32bitBE(0xC,streamFile), &mi); vgmstream->num_samples -= vgmstream->num_samples%576; if (loop_flag) { vgmstream->loop_start_sample = mpeg_bytes_to_samples(loop_start, &mi); vgmstream->loop_start_sample -= vgmstream->loop_start_sample%576; vgmstream->loop_end_sample = mpeg_bytes_to_samples(loop_end, &mi); vgmstream->loop_end_sample -= vgmstream->loop_end_sample%576; } vgmstream->interleave_block_size = 0; } break; #endif default: goto fail; } vgmstream->meta_type = meta_PS3_MSF; /* open the file for reading */ { int i; STREAMFILE * file; file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); if (!file) goto fail; for (i=0;i<channel_count;i++) { vgmstream->ch[i].streamfile = file; vgmstream->ch[i].channel_start_offset= vgmstream->ch[i].offset=start_offset+vgmstream->interleave_block_size*i; } } return vgmstream; /* clean up anything we may have opened */ fail: if (vgmstream) close_vgmstream(vgmstream); return NULL; }
VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; int32_t channel_count; int32_t interleave; int32_t sample_rate; int32_t loop_start; int32_t loop_end; int32_t start_offset; int32_t header_size; int32_t coef[2]; int32_t dsp_interleave_type; char filename[260]; int coding; #ifdef VGM_USE_MPEG mpeg_codec_data *data = NULL; #endif /* check extension, case insensitive */ streamFile->get_name(streamFile,filename,sizeof(filename)); if (strcasecmp("genh",filename_extension(filename))) goto fail; /* check header magic */ if (read_32bitBE(0x0,streamFile) != 0x47454e48) goto fail; /* check channel count (needed for ADP/DTK check) */ channel_count = read_32bitLE(0x4,streamFile); if (channel_count < 1) goto fail; /* check format */ /* 0 = PSX ADPCM */ /* 1 = XBOX IMA ADPCM */ /* 2 = NGC ADP/DTK ADPCM */ /* 3 = 16bit big endian PCM */ /* 4 = 16bit little endian PCM */ /* 5 = 8bit PCM */ /* 6 = SDX2 */ /* 7 = DVI IMA */ /* 8 = MPEG-1 Layer III, possibly also the MPEG-2 and 2.5 extensions */ /* 9 = IMA */ /* 10 = AICA ADPCM */ /* 11 = MS ADPCM */ /* 12 = NGC DSP */ /* 13 = 8bit unsingned PCM */ /* 14 = PSX ADPCM (bad flagged) */ /* ... others to come */ switch (read_32bitLE(0x18,streamFile)) { case 0: coding = coding_PSX; break; case 1: coding = coding_XBOX; break; case 2: coding = coding_NGC_DTK; if (channel_count != 2) goto fail; break; case 3: coding = coding_PCM16BE; break; case 4: coding = coding_PCM16LE; break; case 5: coding = coding_PCM8; break; case 6: coding = coding_SDX2; break; case 7: coding = coding_DVI_IMA; break; #ifdef VGM_USE_MPEG case 8: /* we say MPEG-1 L3 here, but later find out exactly which */ coding = coding_MPEG1_L3; break; #endif case 9: coding = coding_IMA; break; case 10: coding = coding_AICA; break; case 11: coding = coding_MSADPCM; break; case 12: coding = coding_NGC_DSP; break; case 13: coding = coding_PCM8_U_int; break; case 14: coding = coding_PSX_badflags; break; default: goto fail; } start_offset = read_32bitLE(0x1C,streamFile); header_size = read_32bitLE(0x20,streamFile); /* HACK to support old genh */ if (header_size == 0) { start_offset = 0x800; header_size = 0x800; } /* check for audio data start past header end */ if (header_size > start_offset) goto fail; interleave = read_32bitLE(0x8,streamFile); sample_rate = read_32bitLE(0xc,streamFile); loop_start = read_32bitLE(0x10,streamFile); loop_end = read_32bitLE(0x14,streamFile); coef[0] = read_32bitLE(0x24,streamFile); coef[1] = read_32bitLE(0x28,streamFile); dsp_interleave_type = read_32bitLE(0x2C,streamFile); //if (coding == coding_XBOX && channel_count != 2) goto fail; /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,(loop_start!=-1)); if (!vgmstream) goto fail; /* fill in the vital information */ vgmstream->channels = channel_count; vgmstream->sample_rate = sample_rate; vgmstream->num_samples = loop_end; vgmstream->loop_start_sample = loop_start; vgmstream->loop_end_sample = loop_end; vgmstream->loop_flag = (loop_start != -1); switch (coding) { case coding_PCM8_U_int: vgmstream->layout_type=layout_none; break; case coding_PCM16LE: case coding_PCM16BE: case coding_PCM8: case coding_SDX2: case coding_PSX: case coding_PSX_badflags: case coding_DVI_IMA: case coding_IMA: case coding_AICA: vgmstream->interleave_block_size = interleave; if (channel_count > 1) { if (coding == coding_SDX2) { coding = coding_SDX2_int; vgmstream->coding_type = coding_SDX2_int; } if(vgmstream->interleave_block_size==0xffffffff) vgmstream->layout_type=layout_none; else { vgmstream->layout_type = layout_interleave; if(coding==coding_DVI_IMA) coding=coding_INT_DVI_IMA; if(coding==coding_IMA) coding=coding_INT_IMA; } } else { vgmstream->layout_type = layout_none; } break; case coding_MSADPCM: if (channel_count != 2) goto fail; vgmstream->interleave_block_size = interleave; vgmstream->layout_type = layout_none; break; case coding_XBOX: vgmstream->layout_type = layout_none; break; case coding_NGC_DTK: vgmstream->layout_type = layout_dtk_interleave; break; case coding_NGC_DSP: if (dsp_interleave_type == 0) { vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = interleave; } else if (dsp_interleave_type == 1) { vgmstream->layout_type = layout_interleave_byte; vgmstream->interleave_block_size = interleave; } else if (dsp_interleave_type == 2) { vgmstream->layout_type = layout_none; } break; #ifdef VGM_USE_MPEG case coding_MPEG1_L3: vgmstream->layout_type = layout_mpeg; break; #endif } vgmstream->coding_type = coding; vgmstream->meta_type = meta_GENH; /* open the file for reading by each channel */ { int i; int j; STREAMFILE * chstreamfile = NULL; for (i=0;i<channel_count;i++) { off_t chstart_offset = start_offset; switch (coding) { case coding_PSX: case coding_PSX_badflags: case coding_PCM16BE: case coding_PCM16LE: case coding_SDX2: case coding_SDX2_int: case coding_DVI_IMA: case coding_IMA: case coding_PCM8: case coding_PCM8_U_int: case coding_AICA: case coding_INT_DVI_IMA: case coding_INT_IMA: if (vgmstream->layout_type == layout_interleave) { if (interleave >= 512) { chstreamfile = streamFile->open(streamFile,filename,interleave); } else { if (!chstreamfile) chstreamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); } chstart_offset = start_offset+vgmstream->interleave_block_size*i; } else { chstreamfile = streamFile->open(streamFile,filename, STREAMFILE_DEFAULT_BUFFER_SIZE); } break; case coding_XBOX: case coding_MSADPCM: /* xbox's "interleave" is a lie, all channels start at same * offset */ chstreamfile = streamFile->open(streamFile,filename, STREAMFILE_DEFAULT_BUFFER_SIZE); break; case coding_NGC_DTK: if (!chstreamfile) chstreamfile = streamFile->open(streamFile,filename,32*0x400); break; case coding_NGC_DSP: if (!chstreamfile) chstreamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); for (j=0;j<16;j++) vgmstream->ch[i].adpcm_coef[j] = read_16bitBE(coef[i]+j*2,streamFile); chstart_offset =start_offset+vgmstream->interleave_block_size*i; break; #ifdef VGM_USE_MPEG case coding_MPEG1_L3: if (!chstreamfile) chstreamfile = streamFile->open(streamFile,filename,MPEG_BUFFER_SIZE); break; #endif } if (!chstreamfile) goto fail; vgmstream->ch[i].streamfile = chstreamfile; vgmstream->ch[i].channel_start_offset= vgmstream->ch[i].offset=chstart_offset; } } #ifdef VGM_USE_MPEG if (coding == coding_MPEG1_L3) { int rc; off_t read_offset; data = calloc(1,sizeof(mpeg_codec_data)); if (!data) goto mpeg_fail; data->m = mpg123_new(NULL,&rc); if (rc==MPG123_NOT_INITIALIZED) { if (mpg123_init()!=MPG123_OK) goto mpeg_fail; data->m = mpg123_new(NULL,&rc); if (rc!=MPG123_OK) goto mpeg_fail; } else if (rc!=MPG123_OK) { goto mpeg_fail; } mpg123_param(data->m,MPG123_REMOVE_FLAGS,MPG123_GAPLESS,0.0); if (mpg123_open_feed(data->m)!=MPG123_OK) { goto mpeg_fail; } /* check format */ read_offset=0; do { size_t bytes_done; if (read_streamfile(data->buffer, start_offset+read_offset, MPEG_BUFFER_SIZE,vgmstream->ch[0].streamfile) != MPEG_BUFFER_SIZE) goto mpeg_fail; read_offset+=1; rc = mpg123_decode(data->m,data->buffer,MPEG_BUFFER_SIZE, NULL,0,&bytes_done); if (rc != MPG123_OK && rc != MPG123_NEW_FORMAT && rc != MPG123_NEED_MORE) goto mpeg_fail; } while (rc != MPG123_NEW_FORMAT); { long rate; int channels,encoding; struct mpg123_frameinfo mi; rc = mpg123_getformat(data->m,&rate,&channels,&encoding); if (rc != MPG123_OK) goto mpeg_fail; if (rate != vgmstream->sample_rate || channels != vgmstream->channels || encoding != MPG123_ENC_SIGNED_16) goto mpeg_fail; mpg123_info(data->m,&mi); if (mi.rate != vgmstream->sample_rate) goto mpeg_fail; if (mi.version == MPG123_1_0 && mi.layer == 1) vgmstream->coding_type = coding_MPEG1_L1; else if (mi.version == MPG123_1_0 && mi.layer == 2) vgmstream->coding_type = coding_MPEG1_L2; else if (mi.version == MPG123_1_0 && mi.layer == 3) vgmstream->coding_type = coding_MPEG1_L3; else if (mi.version == MPG123_2_0 && mi.layer == 1) vgmstream->coding_type = coding_MPEG2_L1; else if (mi.version == MPG123_2_0 && mi.layer == 2) vgmstream->coding_type = coding_MPEG2_L2; else if (mi.version == MPG123_2_0 && mi.layer == 3) vgmstream->coding_type = coding_MPEG2_L3; else if (mi.version == MPG123_2_5 && mi.layer == 1) vgmstream->coding_type = coding_MPEG25_L1; else if (mi.version == MPG123_2_5 && mi.layer == 2) vgmstream->coding_type = coding_MPEG25_L2; else if (mi.version == MPG123_2_5 && mi.layer == 3) vgmstream->coding_type = coding_MPEG25_L3; else goto mpeg_fail; } /* reinit, to ignore the reading we've done so far */ mpg123_open_feed(data->m); vgmstream->codec_data = data; } #endif return vgmstream; /* clean up anything we may have opened */ #ifdef VGM_USE_MPEG mpeg_fail: if (data) { mpg123_delete(data->m); free(data); } #endif fail: if (vgmstream) close_vgmstream(vgmstream); return NULL; }
/* Open an MPEG stream and prepare for decode */ static int libmpg123_init(const char *fn) { int err; uint32 fd; /* Open the file */ #ifdef BS_SIZE mp3_fd = fd = fs_open(fn, O_RDONLY); #else fd = fs_open(fn, O_RDONLY); #endif if (fd < 0) { printf("Can't open input file %s\r\n", fn); printf("getwd() returns '%s'\r\n", fs_getwd()); return -1; } #ifndef BS_SIZE fs_close(fd); #endif if (fn != mp3_last_fn) { if (fn[0] != '/') { strcpy(mp3_last_fn, fs_getwd()); strcat(mp3_last_fn, "/"); strcat(mp3_last_fn, fn); } else { strcpy(mp3_last_fn, fn); } } /* Allocate buffers */ if (pcm_buffer == NULL) pcm_buffer = malloc(PCM_SIZE); pcm_ptr = pcm_buffer; pcm_count = pcm_discard = 0; #ifdef BS_SIZE if (bs_buffer == NULL) bs_buffer = malloc(BS_SIZE); bs_ptr = bs_buffer; bs_count = 0; /* Fill bitstream buffer */ if (bs_fill() < 0) { printf("Can't read file header\r\n"); goto errorout; } /* Are we looking at a RIFF file? (stupid Windows encoders) */ if (bs_ptr[0] == 'R' && bs_ptr[1] == 'I' && bs_ptr[2] == 'F' && bs_ptr[3] == 'F') { /* Found a RIFF header, scan through it until we find the data section */ printf("Skipping stupid RIFF header\r\n"); while (bs_ptr[0] != 'd' || bs_ptr[1] != 'a' || bs_ptr[2] != 't' || bs_ptr[3] != 'a') { bs_ptr++; if (bs_ptr >= (bs_buffer + BS_SIZE)) { printf("Indeterminately long RIFF header\r\n"); goto errorout; } } /* Skip 'data' and length */ bs_ptr += 8; bs_count -= (bs_ptr - bs_buffer); printf("Final index is %d\r\n", (bs_ptr - bs_buffer)); } if (((uint8)bs_ptr[0] != 0xff) && (!((uint8)bs_ptr[1] & 0xe0))) { printf("Definitely not an MPEG file\r\n"); goto errorout; } #endif mpg123_init(); mh = mpg123_new(NULL, &err); if(mh == NULL) { printf("Can't init mpg123: %s\n", mpg123_strerror(mh)); goto errorout; } /* Open the MP3 context in open_fd mode */ #ifdef BS_SIZE err = mpg123_open_fd(mh, mp3_fd); #else err = mpg123_open(mh, fn); #endif if(err != MPG123_OK) { printf("Can't open mpg123\n"); mpg123_exit(); goto errorout; } int enc; mpg123_getformat(mh, &rate, &channels, &enc); mpg123_info(mh, &decinfo); printf("Output Sampling rate = %ld\r\n", decinfo.rate); printf("Output Bitrate = %d\r\n", decinfo.bitrate); printf("Output Frame size = %d\r\n", decinfo.framesize); printf("mpg123 initialized successfully\r\n"); return 0; errorout: printf("Exiting on error\r\n"); #ifdef BS_SIZE if (bs_buffer) { free(bs_buffer); bs_buffer = NULL; } #endif if (pcm_buffer) { free(pcm_buffer); pcm_buffer = NULL; } #ifdef BS_SIZE fs_close(fd); mp3_fd = 0; #endif return -1; }
bool nuiAudioDecoder::ReadInfo() { if (!mpPrivate) { return false; } int err; int read; int toread = DECODER_INPUT_SIZE; unsigned char* pInput = new unsigned char[toread]; do { read = mrStream.ReadUInt8(pInput, toread); size_t done = 0; err = mpg123_decode(mpPrivate->mpHandle, pInput, read, NULL, 0, &done); // err = mpg123_feed(mpPrivate->mpHandle, pInput, read); } while (err != MPG123_NEW_FORMAT && read > 0); mpg123_frameinfo frameinfo; err = mpg123_info(mpPrivate->mpHandle, &frameinfo); if (err != MPG123_OK) { return false; } int channels; if (frameinfo.mode == MPG123_M_MONO) channels = 1; else channels = 2; double samplerate = 44100; int encoding = MPG123_ENC_SIGNED_16; int supportedChannelConfig = mpg123_format_support(mpPrivate->mpHandle, samplerate, encoding); if (supportedChannelConfig == 0) { return false; } int channelConfig; bool mono = (supportedChannelConfig & MPG123_MONO) && (channels == 1); bool stereo = (supportedChannelConfig & MPG123_STEREO) && (channels == 2); if (mono) channelConfig = MPG123_MONO; else if (stereo) channelConfig = MPG123_STEREO; else { return false; } mpg123_format_none(mpPrivate->mpHandle); err = mpg123_format(mpPrivate->mpHandle, samplerate, channelConfig, encoding); if (err != MPG123_OK) { return false; } off_t sampleframes = mpg123_length(mpPrivate->mpHandle); if (sampleframes <= 0) { int bitrate = frameinfo.bitrate; nglFileSize streamSize = mrStream.Available(); sampleframes = (streamSize / (bitrate * 1000.f / 8.f)) * samplerate; } int BitsPerSample; if (encoding == MPG123_ENC_FLOAT_32) BitsPerSample = 32; else if (encoding == MPG123_ENC_SIGNED_16) BitsPerSample = 16; else { return false; } mInfo.SetSampleFrames(sampleframes); mInfo.SetSampleRate(samplerate); mInfo.SetChannels(channels); mInfo.SetBitsPerSample(BitsPerSample); mInfo.SetFileFormat(eAudioCompressed); mInfo.SetStartFrame(0); mInfo.SetStopFrame(mInfo.GetSampleFrames()); return true; }
int Mp3Decoder::getInstantBitRate() { mpg123_info(_handle, &_frameinfo); return _frameinfo.bitrate * 1000; }