int check_sample(struct seeko *so, size_t i) { short buf[2]; /* at max one left and right sample */ size_t got = 0; if(mpg123_seek(m, so->position[i], SEEK_SET) != so->position[i]) { printf("Error seeking to %"OFF_P": %s\n", (off_p)so->position[i], mpg123_strerror(m)); return -1; } if( mpg123_read(m, (unsigned char*)buf, channels*sizeof(short), &got) != MPG123_OK || got/sizeof(short) != channels ) { printf("Error occured on reading sample %"SIZE_P"! (%s)\n", (size_p)i, mpg123_strerror(m)); return -1; } if(buf[0] == so->left[i] && (channels == 1 || buf[1] == so->right[i])) { printf("sample %"SIZE_P" PASS\n", (size_p)i); } else { if(channels == 1) printf("sample %"SIZE_P" FAIL (%i != %i)\n", (size_p)i, buf[0], so->left[i]); else printf("sample %"SIZE_P" FAIL (%i != %i || %i != %i)\n", (size_p)i, buf[0], so->left[i], buf[1], so->right[i]); return -1; } return 0; }
int test_whence(const char* path, int scan_before) { int err = MPG123_OK; mpg123_handle* mh = NULL; off_t length, pos; mh = mpg123_new(NULL, &err ); if(mh == NULL) return -1; err = mpg123_open(mh, path ); if(err != MPG123_OK) return -1; if(scan_before) mpg123_scan(mh); pos = mpg123_seek( mh, 0, SEEK_END); if(pos < 0){ error1("seek failed: %s", mpg123_strerror(mh)); return -1; } pos = mpg123_tell(mh); length = mpg123_length(mh); /* Later: Read samples and compare different whence values with identical seek positions. */ mpg123_close(mh); mpg123_delete(mh); fprintf(stdout, "length %"OFF_P" vs. pos %"OFF_P"\n", length, pos); return (pos == length) ? 0 : -1; }
/* External API... open and close. */ int dump_open(mpg123_handle *mh) { int ret; if(param.streamdump == NULL) return 0; if(!param.quiet) fprintf(stderr, "Note: Dumping stream to %s\n", param.streamdump); dump_fd = compat_open(param.streamdump, O_CREAT|O_TRUNC|O_RDWR); if(dump_fd < 0) { error1("Failed to open dump file: %s\n", strerror(errno)); return -1; } #ifdef WIN32 _setmode(dump_fd, _O_BINARY); #endif ret = mpg123_replace_reader(mh, dump_read, dump_seek); if(ret != MPG123_OK) { error1("Unable to replace reader for stream dump: %s\n", mpg123_strerror(mh)); dump_close(); return -1; } else return 0; }
VALUE rb_mpg123_new(VALUE klass, VALUE filename) { int err = MPG123_OK; mpg123_handle *mh; VALUE mpg123; long rate; int channels, encoding; Check_Type(filename, T_STRING); if ((mh = mpg123_new(NULL, &err)) == NULL) { rb_raise(rb_eStandardError, "%s", mpg123_plain_strerror(err)); } mpg123_param(mh, MPG123_ADD_FLAGS, MPG123_FORCE_FLOAT, 0.); if (mpg123_open(mh, (char*) RSTRING_PTR(filename)) != MPG123_OK || mpg123_getformat(mh, &rate, &channels, &encoding) != MPG123_OK) { rb_raise(rb_eStandardError, "%s", mpg123_strerror(mh)); } if (encoding != MPG123_ENC_FLOAT_32) { rb_raise(rb_eStandardError, "bad encoding"); } mpg123_format_none(mh); mpg123_format(mh, rate, channels, encoding); VALUE new_mpg123 = Data_Wrap_Struct(rb_cMpg123, 0, cleanup, mh); rb_iv_set(new_mpg123, "@file", filename); return new_mpg123; }
off_t term_control(mpg123_handle *fr, out123_handle *ao) { offset = 0; debug2("control for frame: %li, enable: %i", (long)mpg123_tellframe(fr), term_enable); if(!term_enable) return 0; if(paused) { /* pause_cycle counts the remaining frames _after_ this one, thus <0, not ==0 . */ if(--pause_cycle < 0) pause_recycle(fr); } do { off_t old_offset = offset; term_handle_input(fr, ao, stopped|seeking); if((offset < 0) && (-offset > framenum)) offset = - framenum; if(param.verbose && offset != old_offset) print_stat(fr,offset,ao); } while (!intflag && stopped); /* Make the seeking experience with buffer less annoying. No sound during seek, but at least it is possible to go backwards. */ if(offset) { if((offset = mpg123_seek_frame(fr, offset, SEEK_CUR)) >= 0) debug1("seeked to %li", (long)offset); else error1("seek failed: %s!", mpg123_strerror(fr)); /* Buffer resync already happened on un-stop? */ /* if(param.usebuffer) audio_drop(ao);*/ } return 0; }
MP3Decoder::MP3Decoder(const char* filename) { f = fopen(filename,"rb"); fseek(f,0,SEEK_END); size_t size = ftell(f); cbuf = (uchar*)malloc(size*24); size_t buffer_size = 0; size_t done = 0; rate = 0; channels = 0; encoding = 0; int err = MPG123_OK; err = mpg123_init(); if(err != MPG123_OK || (mh = mpg123_new(NULL, &err)) == NULL) { QMessageBox::critical(0,QString("MP3 decoding error!"),QString("Basic setup goes wrong: ")+QString(mpg123_plain_strerror(err))); cleanup(mh); return ; } /* Let mpg123 work with the file, that excludes MPG123_NEED_MORE messages. */ if( mpg123_open(mh, filename) != MPG123_OK /* Peek into track and get first output format. */ || mpg123_getformat(mh, &rate, &channels, &encoding) != MPG123_OK ) { QMessageBox::critical(0,QString("MP3 decoding error!"),QString("Error decoding mp3 file: ")+QString(mpg123_strerror(mh))); cleanup(mh); return ; } if(encoding != MPG123_ENC_SIGNED_16 && encoding != MPG123_ENC_FLOAT_32) { /* Signed 16 is the default output format anyways; it would actually by only different if we forced it. So this check is here just for this explanation. */ cleanup(mh); QMessageBox::critical(0,QString("MP3 decoding error!"),"Bad encoding: 0x"+QString::number(encoding,16)); return; } /* Ensure that this output format will not change (it could, when we allow it). */ mpg123_format_none(mh); mpg123_format(mh, rate, channels, encoding); buffer_size = mpg123_outblock(mh); cdone=0; buffer = (unsigned char*)malloc( buffer_size ); do { err = mpg123_read( mh, buffer, buffer_size, &done ); if(done<1)qDebug()<<"Error while reading mp3: "<<mpg123_errcode(mh); else memcpy(cbuf+cdone,buffer,done); cdone+=done; } while (err==MPG123_OK); cbuf[cdone-1]=0; if(err != MPG123_DONE){ fprintf( stderr, "Warning: Decoding ended prematurely because: %s\n", err == MPG123_ERR ? mpg123_strerror(mh) : mpg123_plain_strerror(err) ); QMessageBox::critical(0,QString("MP3 decoding error!"),QString("MP3 Decoding ended prematurely: %1").arg(err == MPG123_ERR ? mpg123_strerror(mh) : mpg123_plain_strerror(err) )); return; } }
//------------------------------------------------------------ bool ofxSoundFile::mpg123ReadFile(ofSoundBuffer & buffer){ size_t done=0; size_t block_size = mpg123_outblock( mp3File ); int err; if(buffer.size()==0){ buffer.resize(block_size); do{ err = mpg123_read(mp3File,(unsigned char*)&buffer[buffer.size()-block_size],block_size*4,&done); buffer.resize(buffer.size()+block_size); }while(err==MPG123_OK); buffer.resize(buffer.size()-(block_size-done/4)); if(err != MPG123_DONE){ ofLogError() << "Warning: Decoding ended prematurely because: " << (err == MPG123_ERR ? mpg123_strerror(mp3File) : mpg123_plain_strerror(err)); return false; } duration = float(buffer.size())/float(channels) / float(samplerate); }else{ err = mpg123_read(mp3File,(unsigned char*)&buffer[0],buffer.size()*sizeof(float),&done); if(err != MPG123_OK){ ofLogError() << "Warning: Error decoding mp3: " << (err == MPG123_ERR ? mpg123_strerror(mp3File) : mpg123_plain_strerror(err)); return false; } } return true; }
/***************************************************************************** * MPG123Open *****************************************************************************/ static int MPG123Open( decoder_t *p_dec ) { decoder_sys_t *p_sys = p_dec->p_sys; /* Create our mpg123 handle */ if( ( p_sys->p_handle = mpg123_new( NULL, NULL ) ) == NULL ) { msg_Err( p_dec, "mpg123 error: can't create handle" ); return VLC_EGENERIC; } /* Open a new bitstream */ if( mpg123_open_feed( p_sys->p_handle ) != MPG123_OK ) { msg_Err( p_dec, "mpg123 error: can't open feed" ); mpg123_delete( p_sys->p_handle ); return VLC_EGENERIC; } /* Disable resync stream after error */ mpg123_param( p_sys->p_handle, MPG123_ADD_FLAGS, MPG123_NO_RESYNC, 0 ); /* Setup output format */ mpg123_format_none( p_sys->p_handle ); int i_ret = MPG123_OK; if( p_dec->fmt_in.audio.i_rate != 0 ) { i_ret = mpg123_format( p_sys->p_handle, p_dec->fmt_in.audio.i_rate, MPG123_MONO | MPG123_STEREO, MPG123_ENC_FLOAT_32 ); } else { /* The rate from the input is unknown. Tell mpg123 to accept all rates * to avoid conversion on their side */ static const long mp3_rates[] = { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, }; for( size_t i = 0; i < sizeof(mp3_rates) / sizeof(*mp3_rates) && i_ret == MPG123_OK; ++i ) { i_ret = mpg123_format( p_sys->p_handle, mp3_rates[i], MPG123_MONO | MPG123_STEREO, MPG123_ENC_FLOAT_32 ); } } if( i_ret != MPG123_OK ) { msg_Err( p_dec, "mpg123 error: %s", mpg123_strerror( p_sys->p_handle ) ); mpg123_close( p_sys->p_handle ); mpg123_delete( p_sys->p_handle ); return VLC_EGENERIC; } p_sys->b_opened = true; return VLC_SUCCESS; }
/* return 1 on success, 0 on failure */ int play_frame(void) { unsigned char *audio; int mc; size_t bytes; debug("play_frame"); /* The first call will not decode anything but return MPG123_NEW_FORMAT! */ mc = mpg123_decode_frame(mh, &framenum, &audio, &bytes); /* Play what is there to play (starting with second decode_frame call!) */ if(bytes) { if(param.frame_number > -1) --frames_left; if(fresh && framenum >= param.start_frame) { fresh = FALSE; } /* Normal flushing of data, includes buffer decoding. */ if(flush_output(ao, audio, bytes) < (int)bytes && !intflag) { error("Deep trouble! Cannot flush to my output anymore!"); safe_exit(133); } if(param.checkrange) { long clip = mpg123_clip(mh); if(clip > 0) fprintf(stderr,"%ld samples clipped\n", clip); } } /* Special actions and errors. */ if(mc != MPG123_OK) { if(mc == MPG123_ERR || mc == MPG123_DONE) { if(mc == MPG123_ERR) error1("...in decoding next frame: %s", mpg123_strerror(mh)); return 0; } if(mc == MPG123_NO_SPACE) { error("I have not enough output space? I didn't plan for this."); return 0; } if(mc == MPG123_NEW_FORMAT) { long rate; int channels, format; mpg123_getformat(mh, &rate, &channels, &format); if(param.verbose > 2) fprintf(stderr, "\nNote: New output format %liHz %ich, format %i\n", rate, channels, format); if(!param.quiet) { fprintf(stderr, "\n"); if(param.verbose) print_header(mh); else print_header_compact(mh); } reset_audio(rate, channels, format); } } return 1; }
JNIEXPORT jlong JNICALL Java_de_mpg123_MPG123Decoder_checkFormat (JNIEnv *env, jobject self, jstring path_to_file) { // Error code int err = MPG123_OK; // Properties int channels; long rate; long num_samples; int encoding; size_t buffer_size; mpg123_handle* mh; // Create new mpg123 handle mh = mpg123_new(NULL, &err); __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "mpg123_new: %p", mh); if (err == MPG123_OK && mh != NULL) { // Get the utf-8 string const char *file_path = env->GetStringUTFChars(path_to_file, JNI_FALSE); __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "Sound file path: %s", file_path); err = mpg123_open(mh, file_path); if (err == MPG123_OK) { err = mpg123_getformat(mh, &rate, &channels, &encoding); if (err == MPG123_OK) { return MPG123_OK; } else { __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "Error: mpg123_getformat err: %i", err); __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "Trouble with mpg123: %s", mpg123_strerror(mh)); return MPG123_ERR; } } else { __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "Error: mpg123_open err: %i", err); return MPG123_ERR; } } __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "Error: no proper initialization of mpg123lib."); return MPG123_ERR; }
static int decode_packet(struct dec_audio *da) { struct ad_mpg123_context *con = da->priv; int ret; mp_audio_set_null_data(&da->decoded); struct demux_packet *pkt; if (demux_read_packet_async(da->header, &pkt) == 0) return AD_WAIT; if (!pkt) return AD_EOF; /* Next bytes from that presentation time. */ if (pkt->pts != MP_NOPTS_VALUE) { da->pts = pkt->pts; da->pts_offset = 0; } /* Have to use mpg123_feed() to avoid decoding here. */ ret = mpg123_feed(con->handle, pkt->buffer, pkt->len); talloc_free(pkt); if (ret != MPG123_OK) goto mpg123_fail; unsigned char *audio = NULL; size_t bytes = 0; ret = mpg123_decode_frame(con->handle, NULL, &audio, &bytes); if (ret == MPG123_NEED_MORE) return 0; if (ret != MPG123_OK && ret != MPG123_DONE && ret != MPG123_NEW_FORMAT) goto mpg123_fail; ret = set_format(da); if (ret != MPG123_OK) goto mpg123_fail; if (con->sample_size < 1) { MP_ERR(da, "no sample size\n"); return AD_ERR; } int got_samples = bytes / con->sample_size; da->decoded.planes[0] = audio; da->decoded.samples = got_samples; update_info(da); return 0; mpg123_fail: MP_ERR(da, "mpg123 decoding error: %s\n", mpg123_strerror(con->handle)); return AD_ERR; }
bool Mp3::openFromFile(const std::string& filename) { stop(); if (myBuffer) delete [] myBuffer; if(myHandle) mpg123_close(myHandle); mpg123_param(myHandle, MPG123_RESYNC_LIMIT, -1, 0); #ifndef DEBUG mpg123_param(myHandle, MPG123_ADD_FLAGS, 32 , 0); #endif if (mpg123_open(myHandle, filename.c_str()) != MPG123_OK) { std::cerr << mpg123_strerror(myHandle) << std::endl; return false; } //This should improve myDuration calculation, but generates frankenstein streams¿? //Warning: Real sample count 9505152 differs from given gapless sample count -1152. Frankenstein stream if(mpg123_scan(myHandle) != MPG123_OK) { std::cerr << "Failed when scanning " << std::endl; return false; } long rate = 0; int channels = 0, encoding = 0; if (mpg123_getformat(myHandle, &rate, &channels, &encoding) != MPG123_OK) { std::cerr << "Failed to get format information for 464480e9ee6eb73bc2b768d7e3d7865aa432fc34quot;" << filename << "464480e9ee6eb73bc2b768d7e3d7865aa432fc34quot;" << std::endl; return false; } myDuration = sf::Time(sf::milliseconds(1 + 1000*mpg123_length(myHandle)/rate)); myBufferSize = mpg123_outblock(myHandle); myBuffer = new unsigned char[myBufferSize]; if (!myBuffer) { std::cerr << "Failed to reserve memory for decoding one frame for 464480e9ee6eb73bc2b768d7e3d7865aa432fc34quot;" << filename << "464480e9ee6eb73bc2b768d7e3d7865aa432fc34quot;" << std::endl; return false; } sf::SoundStream::initialize(channels, rate); return true; }
static gboolean gst_mpg123_audio_dec_start (GstAudioDecoder * dec) { GstMpg123AudioDec *mpg123_decoder; int error; mpg123_decoder = GST_MPG123_AUDIO_DEC (dec); error = 0; mpg123_decoder->handle = mpg123_new (NULL, &error); mpg123_decoder->has_next_audioinfo = FALSE; mpg123_decoder->frame_offset = 0; /* Initially, the mpg123 handle comes with a set of default formats * supported. This clears this set. This is necessary, since only one * format shall be supported (see set_format for more). */ mpg123_format_none (mpg123_decoder->handle); /* Built-in mpg123 support for gapless decoding is disabled for now, * since it does not work well with seeking */ mpg123_param (mpg123_decoder->handle, MPG123_REMOVE_FLAGS, MPG123_GAPLESS, 0); /* Tells mpg123 to use a small read-ahead buffer for better MPEG sync; * essential for MP3 radio streams */ mpg123_param (mpg123_decoder->handle, MPG123_ADD_FLAGS, MPG123_SEEKBUFFER, 0); /* Sets the resync limit to the end of the stream (otherwise mpg123 may give * up on decoding prematurely, especially with mp3 web radios) */ mpg123_param (mpg123_decoder->handle, MPG123_RESYNC_LIMIT, -1, 0); #if MPG123_API_VERSION >= 36 /* The precise API version where MPG123_AUTO_RESAMPLE appeared is * somewhere between 29 and 36 */ /* Don't let mpg123 resample output */ mpg123_param (mpg123_decoder->handle, MPG123_REMOVE_FLAGS, MPG123_AUTO_RESAMPLE, 0); #endif /* Don't let mpg123 print messages to stdout/stderr */ mpg123_param (mpg123_decoder->handle, MPG123_ADD_FLAGS, MPG123_QUIET, 0); /* Open in feed mode (= encoded data is fed manually into the handle). */ error = mpg123_open_feed (mpg123_decoder->handle); if (G_UNLIKELY (error != MPG123_OK)) { GST_ELEMENT_ERROR (dec, LIBRARY, INIT, (NULL), ("%s", mpg123_strerror (mpg123_decoder->handle))); mpg123_close (mpg123_decoder->handle); mpg123_delete (mpg123_decoder->handle); mpg123_decoder->handle = NULL; return FALSE; } GST_INFO_OBJECT (dec, "mpg123 decoder started"); return TRUE; }
VALUE rb_mpg123_new(VALUE klass, VALUE filename, VALUE decideRate) { printf("Made it: 1\n"); int err = MPG123_OK; mpg123_handle *mh; printf("mh: "); printf("%d", mh); printf("\n"); VALUE mpg123; long rate; rate = decideRate; printf("rate: "); printf("%d", rate); printf("\n"); int channels, encoding; printf("Made it: 2\n"); printf("rate: "); printf("%d", rate); printf("\n"); Check_Type(filename, T_STRING); printf("Made it: 3\n"); printf("rate: "); printf("%d", rate); printf("\n"); if ((mh = mpg123_new(NULL, &err)) == NULL) { rb_raise(rb_eStandardError, "%s", mpg123_plain_strerror(err)); } printf("Made it: 4\n"); printf("rate: "); printf("%d", rate); printf("\n"); mpg123_param(mh, MPG123_ADD_FLAGS, MPG123_FORCE_FLOAT, 0.); printf("mpg123_open is: "); printf("%d", mpg123_open(mh, (char*) RSTRING_PTR(filename))); printf("\n"); printf("mh: "); printf("%d", mh); printf("\n"); printf("rate: "); printf("%d", rate); printf("\n"); printf("channels: "); printf("%d", channels); printf("\n"); printf("encoding: "); printf("%d", encoding); printf("\n"); printf("mpg123_getformat is: "); printf("%d", mpg123_getformat(mh, &rate, &channels, &encoding)); printf("\n"); printf("MPG123_OK is: "); printf("%d", MPG123_OK); printf("\n"); if (mpg123_open(mh, (char*) RSTRING_PTR(filename)) != MPG123_OK || mpg123_getformat(mh, &rate, &channels, &encoding) != MPG123_OK) { rb_raise(rb_eStandardError, "%s", mpg123_strerror(mh)); } printf("Made it: 5"); if (encoding != MPG123_ENC_FLOAT_32) { rb_raise(rb_eStandardError, "bad encoding"); } printf("Made it: 6"); mpg123_format_none(mh); mpg123_format(mh, rate, channels, encoding); printf("Made it: 7"); return Data_Wrap_Struct(rb_cMpg123, 0, cleanup, mh); }
static int decode_audio(struct dec_audio *da, struct mp_audio *buffer, int maxlen) { struct ad_mpg123_context *con = da->priv; void *buf = buffer->planes[0]; int ret; if (con->new_format) { ret = set_format(da); if (ret == MPG123_OK) { return 0; // let caller handle format change } else if (ret == MPG123_NEED_MORE) { con->need_data = true; } else { goto mpg123_fail; } } if (con->need_data) { if (feed_new_packet(da) < 0) return -1; } if (!mp_audio_config_equals(&da->decoded, buffer)) return 0; size_t got_now = 0; ret = mpg123_replace_buffer(con->handle, buf, maxlen * con->sample_size); if (ret != MPG123_OK) goto mpg123_fail; ret = mpg123_decode_frame(con->handle, NULL, NULL, &got_now); int got_samples = got_now / con->sample_size; buffer->samples += got_samples; da->pts_offset += got_samples; if (ret == MPG123_NEW_FORMAT) { con->new_format = true; } else if (ret == MPG123_NEED_MORE) { con->need_data = true; } else if (ret != MPG123_OK && ret != MPG123_DONE) { goto mpg123_fail; } update_info(da); return 0; mpg123_fail: MP_ERR(da, "mpg123 decoding error: %s\n", mpg123_strerror(con->handle)); return -1; }
static inline jlong wrapped_Java_com_badlogic_gdx_audio_io_Mpg123Decoder_openFile (JNIEnv* env, jobject object, jstring obj_filename, char* filename) { //@line:111 mpg123_handle *mh = NULL; int channels = 0, encoding = 0; long rate = 0; int err = MPG123_OK; err = mpg123_init(); if( err != MPG123_OK || (mh = mpg123_new(NULL, &err)) == NULL || mpg123_open(mh, filename) != MPG123_OK || mpg123_getformat(mh, &rate, &channels, &encoding) != MPG123_OK ) { fprintf( stderr, "Trouble with mpg123: %s\n", mh==NULL ? mpg123_plain_strerror(err) : mpg123_strerror(mh) ); cleanup(mh); return 0; } if(encoding != MPG123_ENC_SIGNED_16) { // Signed 16 is the default output format anyways; it would actually by only different if we forced it. // So this check is here just for this explanation. cleanup(mh); return 0; } // Ensure that this output format will not change (it could, when we allow it). mpg123_format_none(mh); mpg123_format(mh, rate, channels, encoding); size_t buffer_size = mpg123_outblock( mh ); unsigned char* buffer = (unsigned char*)malloc(buffer_size); size_t done = 0; int samples = 0; Mp3File* mp3 = new Mp3File(); mp3->handle = mh; mp3->channels = channels; mp3->rate = rate; mp3->buffer = buffer; mp3->buffer_size = buffer_size; int length = mpg123_length( mh ); if( length == MPG123_ERR ) mp3->length = 0; else mp3->length = length / rate; return (jlong)mp3; }
static inline int readBuffer(MP3File* mp3) { size_t done = 0; int err = mpg123_read(mp3->handle, mp3->buffer, mp3->buffer_size, &done); mp3->leftSamples = done / 2; mp3->offset = 0; if (err != MPG123_OK) __android_log_write(ANDROID_LOG_ERROR, "podax-jni", mpg123_strerror(mp3->handle)); return err != MPG123_OK ? 0 : done; }
static int open_track_fd (void) { /* Let reader handle invalid filept */ if(mpg123_open_fd(mh, filept) != MPG123_OK) { error2("Cannot open fd %i: %s", filept, mpg123_strerror(mh)); return 0; } debug("Track successfully opened."); fresh = TRUE; return 1; /*1 for success, 0 for failure */ }
void generic_sendalltag(mpg123_handle *mh) { mpg123_id3v1 *v1; mpg123_id3v2 *v2; generic_sendmsg("T {"); if(MPG123_OK != mpg123_id3(mh, &v1, &v2)) { error1("Cannot get ID3 data: %s", mpg123_strerror(mh)); v2 = NULL; v1 = NULL; } if(v1 != NULL) generic_sendv1(v1, "T"); if(v2 != NULL) { size_t i; for(i=0; i<v2->texts; ++i) { char id[5]; memcpy(id, v2->text[i].id, 4); id[4] = 0; generic_sendmsg("T ID3v2.%s:", id); generic_send_lines("T =%s", &v2->text[i].text); } for(i=0; i<v2->extras; ++i) { char id[5]; memcpy(id, v2->extra[i].id, 4); id[4] = 0; generic_sendmsg("T ID3v2.%s desc(%s):", id, v2->extra[i].description.fill ? v2->extra[i].description.p : "" ); generic_send_lines("T =%s", &v2->extra[i].text); } for(i=0; i<v2->comments; ++i) { char id[5]; char lang[4]; memcpy(id, v2->comment_list[i].id, 4); id[4] = 0; memcpy(lang, v2->comment_list[i].lang, 3); lang[3] = 0; generic_sendmsg("T ID3v2.%s lang(%s) desc(%s):", id, lang, v2->comment_list[i].description.fill ? v2->comment_list[i].description.p : ""); generic_send_lines("T =%s", &v2->comment_list[i].text); } } generic_sendmsg("T }"); }
int open_file() { if( mpg123_open(m, filename) == MPG123_OK && mpg123_getformat(m, NULL, &channels, NULL) == MPG123_OK ) { printf("Channels: %i\n", channels); return 0; } else { printf("Opening file failed: %s\n", mpg123_strerror(m)); return -1; } }
static int control(struct dec_audio *da, int cmd, void *arg) { struct ad_mpg123_context *con = da->priv; switch (cmd) { case ADCTRL_RESET: mpg123_close(con->handle); if (mpg123_open_feed(con->handle) != MPG123_OK) { MP_ERR(da, "mpg123 failed to reopen stream: %s\n", mpg123_strerror(con->handle)); return CONTROL_FALSE; } return CONTROL_TRUE; } return CONTROL_UNKNOWN; }
/* Now we really start accessing some data and determining file format. * Format now is allowed to change on-the-fly. Here is the only point * that has MPlayer react to errors. We have to pray that exceptional * erros in other places simply cannot occur. */ static int init(struct dec_audio *da, const char *decoder) { if (!preinit(da)) return 0; struct ad_mpg123_context *con = da->priv; int ret; ret = mpg123_open_feed(con->handle); if (ret != MPG123_OK) goto fail; for (int n = 0; ; n++) { if (feed_new_packet(da) < 0) { ret = MPG123_NEED_MORE; goto fail; } size_t got_now = 0; ret = mpg123_decode_frame(con->handle, NULL, NULL, &got_now); if (ret == MPG123_OK || ret == MPG123_NEW_FORMAT) { ret = set_format(da); if (ret == MPG123_OK) break; } if (ret != MPG123_NEED_MORE) goto fail; // max. 16 retries (randomly chosen number) if (n > 16) { ret = MPG123_NEED_MORE; goto fail; } } return 1; fail: if (ret == MPG123_NEED_MORE) { MP_ERR(da, "Could not find mp3 stream.\n"); } else { MP_ERR(da, "mpg123 init error: %s\n", mpg123_strerror(con->handle)); } uninit(da); return 0; }
off_t term_control(mpg123_handle *fr, audio_output_t *ao) { offset = 0; debug1("control for frame: %li", (long)mpg123_tellframe(fr)); if(!term_enable) return 0; if(paused) { /* pause_cycle counts the remaining frames _after_ this one, thus <0, not ==0 . */ if(--pause_cycle < 0) { pause_recycle(fr); if(param.usebuffer) { while(paused && xfermem_get_usedspace(buffermem)) { buffer_ignore_lowmem(); term_handle_input(fr, ao, TRUE); } /* Undo the cycling offset if we are done with cycling. */ if(!paused) pause_uncycle(); } } } do { term_handle_input(fr, ao, stopped|seeking); if((offset < 0) && (-offset > framenum)) offset = - framenum; if(param.verbose && offset != 0) print_stat(fr,offset,0); } while (stopped); /* Make the seeking experience with buffer less annoying. No sound during seek, but at least it is possible to go backwards. */ if(offset) { if((offset = mpg123_seek_frame(fr, offset, SEEK_CUR)) >= 0) debug1("seeked to %li", (long)offset); else error1("seek failed: %s!", mpg123_strerror(fr)); /* Buffer resync already happened on un-stop? */ /* if(param.usebuffer) buffer_resync();*/ } return 0; }
static gint64 xmms_mpg123_seek (xmms_xform_t *xform, gint64 samples, xmms_xform_seek_mode_t whence, xmms_error_t *err) { xmms_mpg123_data_t *data; gint64 ret; off_t byteoff, samploff; int mwhence = -1; data = xmms_xform_private_data_get (xform); g_return_val_if_fail (data, -1); if (whence == XMMS_XFORM_SEEK_SET) { mwhence = SEEK_SET; } else if (whence == XMMS_XFORM_SEEK_CUR) { mwhence = SEEK_CUR; } else if (whence == XMMS_XFORM_SEEK_END) { mwhence = SEEK_END; } /* Get needed input position and possibly reached sample offset * from mpg123. */ samploff = mpg123_feedseek (data->decoder, samples, mwhence, &byteoff); XMMS_DBG ("seeked to %li ... input stream seek following", (long) samploff); if (samploff < 0) { xmms_error_set (err, XMMS_ERROR_GENERIC, mpg123_strerror (data->decoder)); return -1; } /* Seek in input stream. */ ret = xmms_xform_seek (xform, byteoff, XMMS_XFORM_SEEK_SET, err); if (ret < 0) { return ret; } return samploff; }
int collect(struct seeko *so) { off_t pos_count = 0; off_t length; int err = MPG123_OK; size_t posi = 0; mpg123_scan(m); length = mpg123_length(m); printf("Estimated length: %"OFF_P"\n", (off_p)length); /* Compute the interesting positions */ fix_positions(so, length); /* Default format is always 16bit int, rate does not matter. Let's just get the channel count and not bother. */ while(err == MPG123_OK) { short buff[1024]; /* choosing a non-divider of mpeg frame size on purpose */ size_t got = 0; off_t buffsamples; err = mpg123_read(m, (unsigned char*)buff, 1024*sizeof(short), &got); buffsamples = got/(channels*sizeof(short)); while(so->position[posi] < pos_count+buffsamples) { size_t i = (so->position[posi]-pos_count)*channels; printf("got sample %"SIZE_P" (%"OFF_P")\n", (size_p)posi, (off_p)so->position[posi]); so->left[posi] = buff[i]; if(channels == 2) so->right[posi] = buff[i+1]; if(++posi >= samples) break; } if(posi >= samples) break; pos_count += buffsamples; } if(err != MPG123_DONE && err != MPG123_OK) { printf("An error occured (not done)?: %s\n", mpg123_strerror(m)); return -1; } return 0; }
static int print_index(mpg123_handle *mh) { int err; size_t c, fill; off_t *index; off_t step; err = mpg123_index(mh, &index, &step, &fill); if(err == MPG123_ERR) { fprintf(stderr, "Error accessing frame index: %s\n", mpg123_strerror(mh)); return err; } for(c=0; c < fill;++c) fprintf(stderr, "[%lu] %lu: %li (+%li)\n", (unsigned long) c, (unsigned long) (c*step), (long) index[c], (long) (c ? index[c]-index[c-1] : 0)); return MPG123_OK; }
inline void MP3Decoder::openFile(const char *filename) { mpg123_handle *mh = NULL; int channels = 0, encoding = 0; long rate = 0; int err = MPG123_OK; err = mpg123_init(); if( err != MPG123_OK || (mh = mpg123_new(NULL, &err)) == NULL || mpg123_open(mh, filename) != MPG123_OK || mpg123_getformat(mh, &rate, &channels, &encoding) != MPG123_OK ) { printf( "Trouble with mpg123: %s with file: %s\n", mh==NULL ? mpg123_plain_strerror(err) : mpg123_strerror(mh), filename); this->cleanup(mh); return; } // Ensure that this output format will not change (it could, when we allow it). mpg123_format_none(mh); mpg123_format(mh, rate, channels, encoding); size_t buffer_size = mpg123_length(mh) * channels;//mpg123_outblock( mh ); printf("buffer size: %ld\n", buffer_size); unsigned char* buffer = (unsigned char*)malloc(buffer_size); size_t done = 0; int samples = 0; mp3File = MP3File(); mp3File.handle = mh; mp3File.channels = channels; mp3File.rate = rate; mp3File.buffer = buffer; mp3File.buffer_size = buffer_size; int length = mpg123_length( mh ); if( length == MPG123_ERR ) mp3File.length = 0; else mp3File.length = length / rate; }
static void generic_sendinfoid3(mpg123_handle *mh) { mpg123_id3v1 *v1; mpg123_id3v2 *v2; if(MPG123_OK != mpg123_id3(mh, &v1, &v2)) { error1("Cannot get ID3 data: %s", mpg123_strerror(mh)); return; } if(v1 != NULL) { generic_sendv1(v1, "I"); } if(v2 != NULL) { generic_send_lines("I ID3v2.title:%s", v2->title); generic_send_lines("I ID3v2.artist:%s", v2->artist); generic_send_lines("I ID3v2.album:%s", v2->album); generic_send_lines("I ID3v2.year:%s", v2->year); generic_send_lines("I ID3v2.comment:%s", v2->comment); generic_send_lines("I ID3v2.genre:%s", v2->genre); } }
static int MP3_2_Pcm16( unsigned char* out_buf, unsigned char* in_buf, unsigned int size, unsigned int channels, unsigned int rate, long h_codec ) { #ifndef WITH_MPG123DECODER ERROR("MP3 decoding support not compiled in.\n"); return -1; #else int res; size_t decoded_size; mp3_coder_state* coder_state; if (!h_codec) { ERROR("mp3 decoder not initialized!\n"); return -1; } coder_state = (mp3_coder_state*)h_codec; res = mpg123_decode(coder_state->mpg123_h, in_buf, size, out_buf, AUDIO_BUFFER_SIZE, &decoded_size); if (res == MPG123_NEW_FORMAT) { WARN("intermediate mp3 file format change!\n"); } if (res == MPG123_ERR) { ERROR("decoding mp3: '%s'\n", mpg123_strerror(coder_state->mpg123_h)); return -1; } /* DBG("mp3: decoded %d\n", decoded_size); */ return decoded_size; #endif }
static gint xmms_mpg123_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len, xmms_error_t *err) { xmms_mpg123_data_t *data; int result = MPG123_OK; size_t read = 0; data = xmms_xform_private_data_get (xform); g_return_val_if_fail (data, -1); while (read == 0) { gint ret = 0; if (result == MPG123_NEED_MORE) { ret = xmms_xform_read (xform, data->buf, BUFSIZE, err); if (ret < 0) { return ret; } else if (ret == 0) { data->eof_found = TRUE; } } result = mpg123_decode (data->decoder, data->buf, (size_t) ret, buf, len, &read); if (result == MPG123_NEED_MORE && data->eof_found) { /* We need more data, but there's none available * so libmpg123 apparently missed an EOF */ result = MPG123_DONE; break; } else if (result != MPG123_OK && result != MPG123_NEED_MORE) { /* This is some uncommon result like EOF, handle outside * the loop */ break; } } if (result == MPG123_DONE) { /* This is just normal EOF reported from libmpg123 */ XMMS_DBG ("Got EOF while decoding stream"); return 0; } else if (result == MPG123_NEW_FORMAT) { /* FIXME: When we can handle format changes, modify this */ xmms_error_set (err, XMMS_ERROR_GENERIC, "The output format changed, XMMS2 can't handle that"); return -1; } else if (result == MPG123_ERR) { xmms_error_set (err, XMMS_ERROR_GENERIC, mpg123_strerror (data->decoder)); return -1; } return (gint) read; }