Mpg123Input::Mpg123Input(const QString &fileName) { handle=new Handle; QByteArray fName=QFile::encodeName(fileName); bool ok=false; int result; handle->mpg123 = mpg123_new(NULL, &result); if (handle->mpg123 && MPG123_OK==mpg123_open(handle->mpg123, fName.constData()) && MPG123_OK==mpg123_getformat(handle->mpg123, &handle->rate, &handle->channels, &handle->encoding) && MPG123_OK==mpg123_format_none(handle->mpg123) && MPG123_OK==mpg123_format(handle->mpg123, handle->rate, handle->channels, MPG123_ENC_FLOAT_32)) { mpg123_close(handle->mpg123); if (MPG123_OK==mpg123_open(handle->mpg123, fName.constData()) && MPG123_OK==mpg123_getformat(handle->mpg123, &handle->rate, &handle->channels, &handle->encoding)) { ok=true; } } if (!ok) { if (handle->mpg123) { mpg123_close(handle->mpg123); mpg123_delete(handle->mpg123); handle->mpg123 = NULL; } delete handle; handle = 0; } }
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 cxBool cxMp3StreamOpen(cxAny stream) { cxMp3Stream this = stream; this->fd = open(cxStringBody(this->path), O_RDONLY, 0600);; if(this->fd <= 0){ CX_ERROR("open strean file %s failed",cxStringBody(this->path)); return false; } int error = 0; this->mh = mpg123_new(NULL, &error); if(this->mh == NULL){ CX_ERROR("mpg123 new failed"); return false; } if(mpg123_open_fd(this->mh, this->fd) != MPG123_OK){ CX_ERROR("open mpg file failed %s",cxStringBody(this->path)); return false; } allocator->free(this->buffer); this->bufsiz = mpg123_outblock(this->mh); this->buffer = allocator->malloc(this->bufsiz); mpg123_getformat(this->mh, &this->freq, &this->channels, &this->encoding); this->super.canRead = true; this->super.canSeek = true; this->super.isOpen = true; return true; }
void MusicPlayer::play(const char *filename) { #ifdef USE_OGG stb_vorbis_close(v); stb_vorbis_alloc t; t.alloc_buffer=this->buf; t.alloc_buffer_length_in_bytes=STB_BUFSIZE; // stb_vorbis has char* pointer even though it is not really writing to buffer v = stb_vorbis_open_filename((char *)filename, &error, &t); #endif #ifdef USE_MP3 mpg123_close(mh); error = mpg123_open(mh, filename); if (!error) { error = mpg123_getformat(mh, &rate, &channels, &encoding); rate = AUDIO_FREQUENCY; channels = 2; mpg123_format_none(mh); mpg123_format(mh, rate, channels, encoding); } #endif }
bool MPG123Decoder::seek(size_t ms_offset, bool ms, bool mayrestart) { int enc, channels; long srate; if (!mayrestart || ms_offset > 0) { if (mpg123_getformat(MPG123, &srate, &channels, &enc) == MPG123_OK) { size_t smp_offset = ms ? (size_t)((double)ms_offset / 1000. * srate) : ms_offset; if (mpg123_seek(MPG123, (off_t)smp_offset, SEEK_SET) >= 0) { Done = false; return true; } } return false; } else { // Restart the song instead of rewinding. A rewind seems to cause distortion when done repeatedly. // offset is intentionally ignored here. if (MPG123) { mpg123_close(MPG123); mpg123_delete(MPG123); MPG123 = 0; } Reader->Seek(0, SEEK_SET); return open(Reader); } }
void * in_mp3_open(char *file) { mpg123_handle *m; int channels, encoding, r; long rate; channels = encoding = 0; rate = 0; m = mpg123_new(NULL, &r); assert(m != NULL); /* verbosity */ mpg123_param(m, MPG123_VERBOSE, 1, 0); r = mpg123_open(m, file); if (r != MPG123_OK) return NULL; assert(m != NULL); assert(mpg123_getformat(m, &rate, &channels, &encoding) == MPG123_OK); mpg123_format_none(m); mpg123_format(m, rate, channels, encoding); return m; }
bool ofxSoundFile::mpg123Open(string path){ int err; mp3File = mpg123_new(NULL,&err); mpg123_param(mp3File, MPG123_ADD_FLAGS, MPG123_FORCE_FLOAT, 0.); if(mpg123_open(mp3File,path.c_str())!=MPG123_OK){ ofLogError() << "ofxSoundFile: couldnt read " + path; return false; } int encoding; long int rate; mpg123_getformat(mp3File,&rate,&channels,&encoding); if(encoding!=MPG123_ENC_SIGNED_16 && encoding != MPG123_ENC_FLOAT_32){ ofLogError() << "ofxSoundFile: unsupported encoding"; return false; } mpg123_format_none(mp3File); mpg123_format(mp3File, rate, channels, encoding); samplerate = rate; mpg123_seek(mp3File,0,SEEK_END); samples = mpg123_tell(mp3File); mpg123_seek(mp3File,0,SEEK_SET); bitDepth = 16; //TODO:get real bitdepth;. }
void input_mpg123::open(std::string path) { int err; int encoding; handle = mpg123_new(NULL, &err); if (handle == NULL) { throw input_error(mpg123_plain_strerror(err)); } if ((err = mpg123_open(handle, path.c_str())) != MPG123_OK) { throw input_error(mpg123_plain_strerror(err)); } if ((err = mpg123_getformat(handle, &_rate, &_channels, &encoding)) != MPG123_OK) { throw input_error(mpg123_plain_strerror(err)); } read_metadata(); /* force 16 bit format */ encoding = MPG123_ENC_SIGNED_16; mpg123_format_none(handle); mpg123_format(handle, _rate, _channels, encoding); double seconds_left; if ((err = mpg123_position(handle, 0, 0, NULL, NULL, NULL, &seconds_left)) != MPG123_OK) { throw input_error(mpg123_plain_strerror(err)); } this->_encoding = encoding; this->_length = seconds_left; }
JNIEXPORT void JNICALL Java_com_axelby_mp3decoders_MPG123_feed (JNIEnv *env, jclass c, jlong handle, jbyteArray in_buffer, jint in_size) { MP3File *mp3 = (MP3File*)handle; mpg123_handle *mh = mp3->handle; jboolean isCopy; jbyte* b = (*env)->GetByteArrayElements(env, in_buffer, &isCopy); int err = mpg123_feed(mh, b, in_size); if (err != MPG123_OK) __android_log_print(ANDROID_LOG_INFO, "podax-jni", "mpg123_feed error: %s", mpg123_plain_strerror(err)); (*env)->ReleaseByteArrayElements(env, in_buffer, b, JNI_ABORT); if (mp3->rate == 0) { off_t frame_offset; unsigned char* audio; size_t bytes_done; err = mpg123_decode_frame(mh, &frame_offset, &audio, &bytes_done); if (err == MPG123_NEW_FORMAT) { int encoding; err = mpg123_getformat(mh, &mp3->rate, &mp3->channels, &encoding); if (err != MPG123_NEED_MORE && err != MPG123_OK) { printerr("mpg123_getformat", err); return; } mp3->samples_per_frame = mpg123_spf(mh); mp3->secs_per_frame = mpg123_tpf(mh); } if (err != MPG123_OK && err != MPG123_NEED_MORE) __android_log_print(ANDROID_LOG_INFO, "podax-jni", "cannot get rate: %s", mpg123_plain_strerror(err)); } }
//------------------------------------------------------------ bool ofOpenALSoundPlayer::mpg123ReadFile(string path,vector<short> & buffer,vector<float> & fftAuxBuffer){ int err = MPG123_OK; mpg123_handle * f = mpg123_new(NULL,&err); if(mpg123_open(f,path.c_str())!=MPG123_OK){ ofLogError("ofOpenALSoundPlayer") << "mpg123ReadFile(): couldn't read \"" << path << "\""; return false; } mpg123_enc_enum encoding; long int rate; mpg123_getformat(f,&rate,&channels,(int*)&encoding); if(encoding!=MPG123_ENC_SIGNED_16){ ofLogError("ofOpenALSoundPlayer") << "mpg123ReadFile(): " << getMpg123EncodingString(encoding) << " encoding for \"" << path << "\"" << " unsupported, expecting MPG123_ENC_SIGNED_16"; return false; } samplerate = rate; size_t done=0; size_t buffer_size = mpg123_outblock( f ); buffer.resize(buffer_size/2); while(mpg123_read(f,(unsigned char*)&buffer[buffer.size()-buffer_size/2],buffer_size,&done)!=MPG123_DONE){ buffer.resize(buffer.size()+buffer_size/2); }; buffer.resize(buffer.size()-(buffer_size/2-done/2)); mpg123_close(f); mpg123_delete(f); fftAuxBuffer.resize(buffer.size()); for(int i=0;i<(int)buffer.size();i++){ fftAuxBuffer[i] = float(buffer[i])/32565.f; } duration = float(buffer.size()/channels) / float(samplerate); return true; }
bool MPG123Decoder::seek(size_t ms_offset, bool ms, bool mayrestart) { int enc, channels; long srate; if (!mayrestart || ms_offset > 0) { if (mpg123_getformat(MPG123, &srate, &channels, &enc) == MPG123_OK) { size_t smp_offset = ms ? (size_t)((double)ms_offset / 1000. * srate) : ms_offset; if (mpg123_seek(MPG123, (off_t)smp_offset, SEEK_SET) >= 0) { Done = false; return true; } } return false; } else { // Restart the song instead of rewinding. A rewind seems to cause distortion when done repeatedly. // offset is intentionally ignored here. if (MPG123) { mpg123_close(MPG123); mpg123_delete(MPG123); MPG123 = 0; } Reader.Seek(0, FileReader::SeekSet); // Do not call open with our own reader variable, that would be catastrophic. auto reader = std::move(Reader); return open(reader); } }
size_t play_stream(void *buffer, size_t size, size_t nmemb, void *userp) { int err; off_t frame_offset; unsigned char *audio; size_t done; ao_sample_format format; int channels, encoding; long rate; mpg123_feed(mh, (const unsigned char*) buffer, size * nmemb); do { err = mpg123_decode_frame(mh, &frame_offset, &audio, &done); switch(err) { case MPG123_NEW_FORMAT: mpg123_getformat(mh, &rate, &channels, &encoding); format.bits = mpg123_encsize(encoding) * BITS; format.rate = rate; format.channels = channels; format.byte_format = AO_FMT_NATIVE; format.matrix = 0; dev = ao_open_live(ao_default_driver_id(), &format, NULL); break; case MPG123_OK: ao_play(dev, audio, done); break; case MPG123_NEED_MORE: break; default: break; } } while(done > 0); return size * nmemb; }
SharedPtr<Decoder> Mpg123DecoderFactory::createDecoder(SharedPtr<std::istream> file) { if(!mIsInited) return SharedPtr<Decoder>(nullptr); mpg123_handle *mpg123 = mpg123_new(0, 0); if(mpg123) { if(mpg123_replace_reader_handle(mpg123, r_read, r_lseek, 0) == MPG123_OK && mpg123_open_handle(mpg123, file.get()) == MPG123_OK) { int enc, channels; long srate; if(mpg123_getformat(mpg123, &srate, &channels, &enc) == MPG123_OK) { if((channels == 1 || channels == 2) && srate > 0 && mpg123_format_none(mpg123) == MPG123_OK && mpg123_format(mpg123, srate, channels, MPG123_ENC_SIGNED_16) == MPG123_OK) { // All OK return SharedPtr<Decoder>(new Mpg123Decoder(file, mpg123, channels, srate)); } } mpg123_close(mpg123); } mpg123_delete(mpg123); } return SharedPtr<Decoder>(nullptr); }
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 ofOpenALSoundPlayer_TimelineAdditions::mpg123ReadFile(string path,vector<short> & buffer,vector<float> & fftAuxBuffer){ int err = MPG123_OK; mpg123_handle * f = mpg123_new(NULL,&err); if(mpg123_open(f,path.c_str())!=MPG123_OK){ ofLog(OF_LOG_ERROR,"ofOpenALSoundPlayer_TimelineAdditions: couldnt read " + path); return false; } int encoding; long int rate; mpg123_getformat(f,&rate,&channels,&encoding); if(encoding!=MPG123_ENC_SIGNED_16){ ofLog(OF_LOG_ERROR,"ofOpenALSoundPlayer_TimelineAdditions: unsupported encoding"); return false; } samplerate = rate; size_t done=0; size_t buffer_size = mpg123_outblock( f ); buffer.resize(buffer_size/2); while(mpg123_read(f,(unsigned char*)&buffer[buffer.size()-buffer_size/2],buffer_size,&done)!=MPG123_DONE){ buffer.resize(buffer.size()+buffer_size/2); }; buffer.resize(buffer.size()-(buffer_size/2-done/2)); mpg123_close(f); mpg123_delete(f); fftAuxBuffer.resize(buffer.size()); for(int i=0;i<(int)buffer.size();i++){ fftAuxBuffer[i] = float(buffer[i])/32565.f; } duration = float(buffer.size()/channels) / float(samplerate); return true; }
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; }
bool Mp3Decoder::afterOpen() { int encoding; long numberOfSamplesPerSecond; int res = mpg123_getformat(_handle, &numberOfSamplesPerSecond, &_numberOfChannels, &encoding); if(res != MPG123_OK) { printf("mpg123_getformat failed\n"); return false; } if(encoding != MPG123_ENC_SIGNED_16) { printf("encoding != MPG123_ENC_SIGNED_16\n"); return false; } /* Ensure that this output format will not change (it could, when we allow it). */ res = mpg123_format_none(_handle); assert(res == MPG123_OK); res = mpg123_format(_handle, numberOfSamplesPerSecond, _numberOfChannels, encoding); assert(res == MPG123_OK); _numberOfSamplesPerSecond = numberOfSamplesPerSecond; _numberOfBitsPerSample = 16; dprintf("\nsample rate: %d\n", _numberOfSamplesPerSecond); return true; }
/* Stop playback while seeking if buffer is involved. */ static void seekmode(mpg123_handle *mh, out123_handle *ao) { if(param.usebuffer && !stopped) { int channels = 0; int encoding = 0; int pcmframe; off_t back_samples = 0; stopped = TRUE; out123_pause(ao); mpg123_getformat(mh, NULL, &channels, &encoding); pcmframe = out123_encsize(encoding)*channels; if(pcmframe > 0) back_samples = out123_buffered(ao)/pcmframe; fprintf(stderr, "\nseeking back %"OFF_P" samples from %"OFF_P"\n" , (off_p)back_samples, (off_p)mpg123_tell(mh)); mpg123_seek(mh, -back_samples, SEEK_CUR); out123_drop(ao); fprintf(stderr, "\ndropped, now at %"OFF_P"\n" , (off_p)mpg123_tell(mh)); fprintf(stderr, "%s", MPG123_STOPPED_STRING); if(param.verbose) print_stat(mh, 0, ao); } }
int mp3file_determineStats(MP3File *mp3) { if (mp3 == NULL) return; int encoding; mpg123_handle* mh = mp3->handle; int err = mpg123_getformat(mh, &mp3->rate, &mp3->channels, &encoding); if (err == MPG123_NEED_MORE) return err; if (err != MPG123_OK) { printerr("mpg123_getformat", err); return err; } mpg123_format_none(mh); mpg123_format(mh, mp3->rate, mp3->channels, encoding); mp3->num_samples = mpg123_length(mh); mp3->samples_per_frame = mpg123_spf(mh); mp3->secs_per_frame = mpg123_tpf(mh); if (mp3->num_samples == MPG123_ERR || mp3->samples_per_frame < 0) mp3->num_frames = 0; else mp3->num_frames = mp3->num_samples / mp3->samples_per_frame; if (mp3->num_samples == MPG123_ERR || mp3->samples_per_frame < 0 || mp3->secs_per_frame < 0) mp3->duration = 0; else mp3->duration = mp3->num_samples / mp3->samples_per_frame * mp3->secs_per_frame; return err; }
/* 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; }
Mpg123Decoder::Mpg123Decoder(Data *data, const std::string &ext, int bufferSize) : Decoder(data, ext, bufferSize) , decoder_file(data) , handle(0) , channels(MPG123_STEREO) , duration(-2.0) { int ret = 0; if (!inited) { ret = mpg123_init(); if (ret != MPG123_OK) throw love::Exception("Could not initialize mpg123."); inited = (ret == MPG123_OK); } // Intialize the handle. handle = mpg123_new(nullptr, nullptr); if (handle == nullptr) throw love::Exception("Could not create decoder."); // Suppressing all mpg123 messages. mpg123_param(handle, MPG123_ADD_FLAGS, MPG123_QUIET, 0); try { ret = mpg123_replace_reader_handle(handle, &read_callback, &seek_callback, &cleanup_callback); if (ret != MPG123_OK) throw love::Exception("Could not set decoder callbacks."); ret = mpg123_open_handle(handle, &decoder_file); if (ret != MPG123_OK) throw love::Exception("Could not open decoder."); // mpg123_getformat should be able to tell us the properties of the stream's first frame. long rate = 0; ret = mpg123_getformat(handle, &rate, &channels, nullptr); if (ret == MPG123_ERR) throw love::Exception("Could not get stream information."); // I forgot what this was about. if (channels == 0) channels = 2; // Force signed 16-bit output. mpg123_param(handle, MPG123_FLAGS, (channels == 2 ? MPG123_FORCE_STEREO : MPG123_MONO_MIX), 0); mpg123_format_none(handle); mpg123_format(handle, rate, channels, MPG123_ENC_SIGNED_16); sampleRate = rate; } catch (love::Exception &) { mpg123_delete(handle); throw; } }
void mp3_init(char *mp3_file_0, char *mp3_file_1) { int err; int channels, encoding; long rate; mpg123_init(); mh_0 = mpg123_new(NULL, &err); mp3_buffer_size = mpg123_outblock(mh_0); mp3_buffer = malloc(mp3_buffer_size * sizeof(unsigned char)); mpg123_open(mh_0, mp3_file_0); mpg123_getformat(mh_0, &rate, &channels, &encoding); printf("0: %s: rate: %ld channels: %d encoding: %d\n", mp3_file_0, rate, channels, encoding); memset(&mp3_format, 0, sizeof(mp3_format)); mp3_format.bits = mpg123_encsize(encoding) * 8; mp3_format.channels = channels; mp3_format.rate = rate; // -- Open driver -- // mp3_device_0 = ao_open_live(ao_default_driver_id(), &mp3_format, NULL); // no options if (mp3_device_0 == NULL) { fprintf(stderr, "Error opening device 0 .\n"); } mh_1 = mpg123_new(NULL, &err); mpg123_open(mh_1, mp3_file_1); mpg123_getformat(mh_1, &rate, &channels, &encoding); printf("1: %s: rate: %ld channels: %d encoding: %d\n", mp3_file_1, rate, channels, encoding); memset(&mp3_format, 0, sizeof(mp3_format)); mp3_format.bits = mpg123_encsize(encoding) * 8; mp3_format.channels = channels; mp3_format.rate = rate; // -- Open driver -- // mp3_device_1 = ao_open_live(ao_default_driver_id(), &mp3_format, NULL); // no options if (mp3_device_1 == NULL) { fprintf(stderr, "Error opening device 1.\n"); } }
JNIEXPORT jlong JNICALL Java_com_axelby_podax_player_MPG123_openFile (JNIEnv *env, jclass c, jstring filename) { int err = MPG123_OK; mpg123_handle *mh = mpg123_new(NULL, &err); if (err == MPG123_OK && mh != NULL) { MP3File* mp3 = mp3file_init(mh); const char* fileString = (*env)->GetStringUTFChars(env, filename, NULL); err = mpg123_open(mh, fileString); (*env)->ReleaseStringUTFChars(env, filename, fileString); if (err == MPG123_OK) { int encoding; if (mpg123_getformat(mh, &mp3->rate, &mp3->channels, &encoding) == MPG123_OK) { if(encoding == MPG123_ENC_SIGNED_16) { // Signed 16 is the default output format anyway; // it would actually by only different if we forced it. // So this check is here just for this explanation. // Ensure that this output format will not change // (it could, when we allow it). mpg123_format_none(mh); mpg123_format(mh, mp3->rate, mp3->channels, encoding); mp3->buffer_size = mpg123_outblock(mh); mp3->buffer = (unsigned char*)malloc(mp3->buffer_size); mp3->num_samples = mpg123_length(mh); mp3->samples_per_frame = mpg123_spf(mh); mp3->secs_per_frame = mpg123_tpf(mh); if (mp3->num_samples == MPG123_ERR || mp3->samples_per_frame < 0) mp3->num_frames = 0; else mp3->num_frames = mp3->num_samples / mp3->samples_per_frame; if (mp3->num_samples == MPG123_ERR || mp3->samples_per_frame < 0 || mp3->secs_per_frame < 0) mp3->duration = 0; else mp3->duration = mp3->num_samples / mp3->samples_per_frame * mp3->secs_per_frame; return (jlong)mp3; } } } mp3file_delete(mp3); } else { __android_log_write(ANDROID_LOG_INFO, "podax-jni", mpg123_plain_strerror(err)); } return 0; }
/** Decodes given buffer of data to PCM */ jint Java_com_denisigo_netradioplayer_Decoder_decodeNative(JNIEnv* env, jobject thiz, jint handle, jbyteArray in_buffer, jint size, jbyteArray out_buffer, jint max_size){ jint ret; mpg123_handle* hnd = (mpg123_handle*) handle; jbyte* in_buf = (*env)->GetByteArrayElements(env, in_buffer, NULL); jbyte* out_buf = (*env)->GetByteArrayElements(env, out_buffer, NULL); size_t bytes_decoded; // Decode data ret = mpg123_decode(hnd, in_buf, size, out_buf, max_size, &bytes_decoded); LOG("Decoded %d bytes, ret: %d, max_size: %d", bytes_decoded, ret, max_size); // If status if OK, decoder decoded something if (ret == MPG123_OK){ ret = bytes_decoded; } // This means decoder faced new stream. For us this means that there was sufficient data decoded // to determine stream's params and we can notify Java Decoder about it else if (ret == MPG123_NEW_FORMAT){ long rate; int channels, encoding; // Get actual format params mpg123_getformat(hnd, &rate, &channels, &encoding); //LOG("mpg123_getformat: rate: %d channels: %d encoding: %d\n", rate, channels, encoding); // We support only 16 and 8 bits per sample if (encoding == MPG123_ENC_SIGNED_16) encoding = 16; else if (encoding == MPG123_ENC_SIGNED_8) encoding = 8; else encoding = -1; (*env)->CallVoidMethod(env, thiz, method_onNewFormatCallback, (jint)rate, (jint)channels, (jint)encoding); ret = 0; } // This means mpg123 decoder needs more data to provide decoded data else if (ret == MPG123_NEED_MORE){ ret = 0; } // Other cases usually means some errors else { // Ensure we will not return positive number which is normally indicating num of decoded bytes if (ret > 0) ret *= -1; } (*env)->ReleaseByteArrayElements(env, in_buffer, in_buf, 0); (*env)->ReleaseByteArrayElements(env, out_buffer, out_buf, 0); return ret; }
AudioSourceMpg123::AudioSourceMpg123(const char* filename) : AudioSource(filename) { rate_ = 0; channelCount_ = 0; sampleCount_ = 0; int err = MPG123_OK; mpg123_handle* mh = mpg123_new(NULL, &err); if (mh == NULL || err != MPG123_OK) return; /* if (mpg123_open(mh, filename) != MPG123_OK) { mpg123_delete(mh); return; } */ G_FILE* file = g_fopen(filename, "rb"); if (file == NULL) { mpg123_delete(mh); return; } mpg123_replace_reader_handle(mh, mpg123read, mpg123lseek, mpg123cleanup); if (mpg123_open_handle(mh, file) != MPG123_OK) { mpg123_delete(mh); return; } int channels = 0, encoding = 0; long rate = 0; if (mpg123_getformat(mh, &rate, &channels, &encoding) != MPG123_OK) { mpg123_delete(mh); return; } // Signed 16 is the default output format anyways (encoding == MPG123_ENC_SIGNED_16); // it would actually by only different if we forced it. // Ensure that this output format will not change (it could, when we allow it). mpg123_format_none(mh); mpg123_format(mh, rate, channels, encoding); rate_ = rate; channelCount_ = channels; mpg123_scan(mh); sampleCount_ = mpg123_length(mh); mpg123_close(mh); mpg123_delete(mh); }
void Mpg123Decoder::GetFormat(int& frequency, AudioDecoder::Format& format, int& channels) const { long freq; int ch; int fmt; mpg123_getformat(handle.get(), &freq, &ch, &fmt); frequency = (int)freq; channels = ch; format = mpg123_format_to_format(fmt); }
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 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; }
/* libmpg123 has a new format ready; query and store, return return value of mpg123_getformat() */ static int set_format(sh_audio_t *sh, struct ad_mpg123_context *con) { int ret; long rate; int channels; int encoding; ret = mpg123_getformat(con->handle, &rate, &channels, &encoding); if(ret == MPG123_OK) { sh->channels = channels; sh->samplerate = rate; /* Without external force, mpg123 will always choose signed encoding, * and non-16-bit only on builds that don't support it. * Be reminded that it doesn't matter to the MPEG file what encoding * is produced from it. */ switch (encoding) { case MPG123_ENC_SIGNED_8: sh->sample_format = AF_FORMAT_S8; sh->samplesize = 1; break; case MPG123_ENC_SIGNED_16: sh->sample_format = AF_FORMAT_S16_NE; sh->samplesize = 2; break; /* To stay compatible with the oldest libmpg123 headers, do not rely * on float and 32 bit encoding symbols being defined. * Those formats came later */ case 0x1180: /* MPG123_ENC_SIGNED_32 */ sh->sample_format = AF_FORMAT_S32_NE; sh->samplesize = 4; break; case 0x200: /* MPG123_ENC_FLOAT_32 */ sh->sample_format = AF_FORMAT_FLOAT_NE; sh->samplesize = 4; break; default: /* This means we got a funny custom build of libmpg123 that only supports an unknown format. */ mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Bad encoding from mpg123: %i.\n", encoding); return MPG123_ERR; } #ifdef AD_MPG123_FRAMEWISE /* Going to decode directly to MPlayer's memory. It is important * to have MPG123_AUTO_RESAMPLE disabled for the buffer size * being an all-time limit. */ sh->audio_out_minsize = 1152 * 2 * sh->samplesize; #endif con->new_format = 0; } return ret; }