int Waveform::GetTrackSize(mpg123_handle *mh,int bits, int channels) { size_t buffer_size; unsigned char *buffer; size_t done; int trackSize=0; int fileSize=0; if(mpg123_length(mh) > 0) { return mpg123_length(mh); } buffer_size = mpg123_outblock(mh); buffer = (unsigned char*) malloc(buffer_size * sizeof(unsigned char)); mpg123_seek(mh,0,SEEK_SET); for (fileSize = 0 ; mpg123_read(mh, buffer, buffer_size, &done) == MPG123_OK ; ) { fileSize += done; } free(buffer); trackSize = fileSize/(bits*channels); return trackSize; }
//------------------------------------------------------------ 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; }
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; }
//------------------------------------------------------------ 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; }
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; }
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; }
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; }
//------------------------------------------------------------ bool ofOpenALSoundPlayer::mpg123Stream(string path,vector<short> & buffer,vector<float> & fftAuxBuffer){ if(!mp3streamf){ int err = MPG123_OK; mp3streamf = mpg123_new(NULL,&err); if(mpg123_open(mp3streamf,path.c_str())!=MPG123_OK){ mpg123_close(mp3streamf); mpg123_delete(mp3streamf); ofLogError("ofOpenALSoundPlayer") << "mpg123Stream(): couldn't read \"" << path << "\""; return false; } long int rate; mpg123_getformat(mp3streamf,&rate,&channels,(int*)&stream_encoding); if(stream_encoding!=MPG123_ENC_SIGNED_16){ ofLogError("ofOpenALSoundPlayer") << "mpg123Stream(): " << getMpg123EncodingString(stream_encoding) << " encoding for \"" << path << "\"" << " unsupported, expecting MPG123_ENC_SIGNED_16"; return false; } samplerate = rate; mp3_buffer_size = mpg123_outblock( mp3streamf ); mpg123_seek(mp3streamf,0,SEEK_END); off_t samples = mpg123_tell(mp3streamf); duration = float(samples/channels) / float(samplerate); mpg123_seek(mp3streamf,0,SEEK_SET); } int curr_buffer_size = mp3_buffer_size; if(speed>1) curr_buffer_size *= (int)round(speed); buffer.resize(curr_buffer_size); fftAuxBuffer.resize(buffer.size()); size_t done=0; if(mpg123_read(mp3streamf,(unsigned char*)&buffer[0],curr_buffer_size*2,&done)==MPG123_DONE){ setPosition(0); buffer.resize(done/2); fftAuxBuffer.resize(done/2); if(!bLoop) stopThread(); stream_end = true; } for(int i=0;i<(int)buffer.size();i++){ fftAuxBuffer[i] = float(buffer[i])/32565.f; } return true; }
Mp3Stream::Mp3Stream() { LOG4CXX_INFO(narratorMP3StreamLog, "Initializing mp3stream"); mError = 0; mEncoding = 0; mChannels = 0; mRate = 0; isOpen = false; openTmpFile = false; mTmpFile = ""; scaleNegative = powf(2, 16); scalePositive = scaleNegative - 1; mpg123_init(); mh = mpg123_new(NULL, &mError); mFrameSize = mpg123_outblock(mh); }
/** * @name Reset delle variabili Decoder * * Questa funzione inizializza le variabili necessarie in fase di riproduzione per il decoder */ void resetMp3(char * song) { if (buffer!=NULL) {freeMp3();} int err; int channels, encoding; long rate; /* Inizialize */ mpg123_init(); mh = mpg123_new(NULL, &err); buffer_size = mpg123_outblock(mh); buffer = (unsigned char*) malloc(buffer_size * sizeof(unsigned char)); /* open the file and get the decoding format */ mpg123_open(mh,song); mpg123_getformat(mh, &rate, &channels, &encoding); /* set the output format and open the output device */ int bits=(mpg123_encsize(encoding) * BITS); initAudioDev(bits,rate,channels); }
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"); } }
void Waveform::LoadTrackData(mpg123_handle *mh,char * data, int maxSize) { size_t buffer_size; unsigned char *buffer; size_t done; int bytesRead=0; buffer_size = mpg123_outblock(mh); buffer = (unsigned char*) malloc(buffer_size * sizeof(unsigned char)); mpg123_seek(mh,0,SEEK_SET); for (bytesRead = 0 ; mpg123_read(mh, buffer, buffer_size, &done) == MPG123_OK ; ) { if ((bytesRead + done) >= maxSize) { wxMessageBox("Error reading data from mp3, too much data read."); free(buffer); return; } memcpy(data+bytesRead,buffer,done); bytesRead+=done; } free(buffer); }
void open_sound(void) { int err; ao_initialize(); driver = ao_default_driver_id(); mpg123_init(); mh = mpg123_new(NULL, &err); buffer_size = mpg123_outblock(mh); buffer = malloc(buffer_size * sizeof(char)); GError *error = NULL; gchar *str; if ((str = g_key_file_get_string(keyfile, "preferences", "soundfile", &error))) { if (str[0]) { sound_file = str; init_dev(); } else g_free(str); } }
audioBuffer loadMp3File(const char* filename) { audioBuffer encBuffer; mpg123_handle *mh; unsigned char *buffer; size_t buffer_size; size_t done; int err; int channels, encoding; long rate; //inizialize mpg123 and its handler mpg123_init(); mh = mpg123_new(NULL, &err); buffer_size = mpg123_outblock(mh); buffer = (unsigned char*) malloc(buffer_size * sizeof(unsigned char)); mpg123_open(mh, filename); mpg123_getformat(mh, &rate, &channels, &encoding); int m_bits = mpg123_encsize(encoding); int m_rate = rate; int m_channels = channels; //loads decoded file in memory for (int totalBtyes = 0 ; mpg123_read(mh, buffer, buffer_size, &done) == MPG123_OK ; ) { totalBtyes += done; } encBuffer.bufPointer = buffer; //deallocates mpg123 memory mpg123_close(mh); mpg123_delete(mh); mpg123_exit(); return encBuffer; }
void UMP3Decoder::Init(const uint8*& Buffer, const uint8* BufferEnd) { int encoding; int channels; long samplerate; mpg123_init(); Handle = mpg123_new(NULL, &ErrorHandle); BlockBufferSize = mpg123_outblock(Handle); mpg123_open_feed(Handle); mpg123_feed(Handle, Buffer, BufferEnd - Buffer); mpg123_getformat(Handle, &samplerate, &channels, &encoding); uint32 bytesPerSample = mpg123_encsize(encoding); BitsPerSample = bytesPerSample * 8; Channels = channels; Samplerate = samplerate; UE_LOG(MP3ImporterLog, Display, TEXT("Initialized: Samplerate: %u, Channels: %u"), Samplerate, Channels); }
static SYS_SOUNDHANDLE SYS_LoadMP3File(char* filename) { mpg123_handle* mh = 0; int error = MPG123_OK; mh = mpg123_new(0, &error); if ((error != MPG123_OK) || (mh == 0)) { printf("error mpg123_new()\n"); return 0; } char newfilename[512]; sprintf(newfilename,"%s%s",g_DataPath,filename); error = mpg123_open(mh, newfilename); if (error != MPG123_OK) { printf("error mpg123_open()\n"); mpg123_delete(mh); return 0; } int channels, encoding; long rate; error = mpg123_getformat(mh, &rate, &channels, &encoding); if (error != MPG123_OK) { printf("error mpg123_getformat()\n"); mpg123_delete(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. mpg123_delete(mh); printf( "Bad encoding: 0x%x!\n", encoding); 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); // create streaming OpenAL buffers. SYS_Wave* wave = GetWaveFromFreePool(); wave->filename = filename; alGenBuffers(2, wave->mp3_buffers); CheckForErrors(); wave->bufferIndex = 0; wave->bufferSize = mpg123_outblock( mh ) * 64; wave->rate = rate; wave->channels = channels; wave->mh = mh; return (SYS_SOUNDHANDLE)wave; }
void VoxPlayer::aoplay(const std::string& path) { m_isplaying = true; ao_device* ad = NULL; mpg123_handle* mh = NULL; unsigned char* buf = NULL; size_t bufsz = 0; size_t done = 0; int driver = ao_default_driver_id(); ao_sample_format asf; int channels = 0; int encoding = 0; long rate = 0; if(!(mh = mpg123_new(NULL, NULL))) { ERROR("mpg123_new() failed"); goto error_success; } bufsz = mpg123_outblock(mh); buf = (unsigned char*)malloc(bufsz * sizeof(unsigned char)); if(mpg123_open(mh, path.c_str()) != MPG123_OK) { ERROR("mpg123_open() failed"); goto error_success; } mpg123_volume(mh, 1.4); if(mpg123_getformat(mh, &rate, &channels, &encoding) != MPG123_OK) { ERROR("mpg123_getformat() failed"); goto error_success; } asf.bits = mpg123_encsize(encoding) * 8; // BITS asf.rate = rate; asf.channels = channels; asf.byte_format = AO_FMT_NATIVE; asf.matrix = 0; if(!(ad = ao_open_live(driver, &asf, NULL))) { ERROR("ao_open_live() failed"); goto error_success; } while(!g_main.isExit() && !m_interrupt) { int ret = mpg123_read(mh, buf, bufsz, &done); DEBUG("ret=%d, done=%d", ret, done); if(ret == MPG123_OK || ret == MPG123_DONE || ret == MPG123_NEED_MORE) { if(!ao_play(ad, (char*)buf, done)) { ERROR("ao_play() failed"); break; } if(ret == MPG123_DONE) break; continue; } break; } DEBUG("play done"); error_success: if(buf) { free(buf); buf = NULL; } if(ad) { ao_close(ad); ad = NULL; } if(mh) { mpg123_close(mh); mpg123_delete(mh); mh = NULL; } m_isplaying = false; }
/** * TODO */ JNIEXPORT jlong JNICALL Java_de_mpg123_MPG123Decoder_open (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; // Create new mpg123 handle m_Mp3Decoder.m_mh = mpg123_new(NULL, &err); __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "mpg123_new: %p", m_Mp3Decoder.m_mh); if (err == MPG123_OK && m_Mp3Decoder.m_mh != NULL) { // Get the utf-8 string const char *file_path = env->GetStringUTFChars(path_to_file, JNI_FALSE); // Create new sound file and assign it to private Mp3Decoder field SoundFile *sound_file = new SoundFile(file_path); __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "Sound file path: %s", sound_file->file_path); err = mpg123_open(m_Mp3Decoder.m_mh, sound_file->file_path); // The jni string can now be released //env->ReleaseStringUTFChars(path_to_file, file_path); if (err == MPG123_OK) { err = mpg123_getformat(m_Mp3Decoder.m_mh, &rate, &channels, &encoding); if (err == MPG123_OK) { // Reset internal format table and only allow specific encodings mpg123_format_none(m_Mp3Decoder.m_mh); // TODO: remove this: Force 32 bit float encoding //mp3->encoding = MPG123_ENC_FLOAT_32; encoding = MPG123_ENC_SIGNED_16; // Set fixed format mpg123_format(m_Mp3Decoder.m_mh, rate, channels, encoding); // Store the maximum buffer size that is possible // The buffer will be needed in the reading/decoding step buffer_size = mpg123_outblock(m_Mp3Decoder.m_mh); // Store number of samples of one channel of current track num_samples = mpg123_length(m_Mp3Decoder.m_mh); // TODO: if sound file init fails, what to do? // Everything was properly loaded with mpg123. Initialize sound file sound_file->init(channels, rate, num_samples, encoding, buffer_size); //__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "return sound file pointer: %p", // sound_file); return (jlong) sound_file; } else { __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "Error: mpg123_getformat err: %i", err); __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "Trouble with mpg123: %s", mpg123_strerror(m_Mp3Decoder.m_mh)); } } else { __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "Error: mpg123_open err: %i", err); } delete sound_file; } __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "Error: no proper initialization of mpg123lib."); return 0; }
static float* readaudio_mp3(const char *filename,long *sr, const float nbsecs, unsigned int *buflen) { mpg123_handle *m; int ret; if (mpg123_init() != MPG123_OK || ((m = mpg123_new(NULL,&ret)) == NULL)|| \ mpg123_open(m, filename) != MPG123_OK) { fprintf(stderr,"unable to init mpg\n"); return NULL; } /*turn off logging */ mpg123_param(m, MPG123_ADD_FLAGS, MPG123_QUIET, 0); off_t totalsamples; mpg123_scan(m); totalsamples = mpg123_length(m); int meta = mpg123_meta_check(m); int channels, encoding; if (mpg123_getformat(m, sr, &channels, &encoding) != MPG123_OK) { fprintf(stderr,"unable to get format\n"); return NULL; } mpg123_format_none(m); mpg123_format(m, *sr, channels, encoding); size_t decbuflen = mpg123_outblock(m); unsigned char *decbuf = (unsigned char*)malloc(decbuflen); if (decbuf == NULL) { printf("mem alloc error\n"); return NULL; } unsigned int nbsamples = (nbsecs <= 0) ? totalsamples : nbsecs*(*sr); nbsamples = (nbsamples < totalsamples) ? nbsamples : totalsamples; size_t i, j, index = 0, done; float *buffer = (float*)malloc(nbsamples*sizeof(float)); *buflen = nbsamples; do { ret = mpg123_read(m, decbuf, decbuflen, &done); switch (encoding) { case MPG123_ENC_SIGNED_16 : for (i = 0; i < done/sizeof(short); i+=channels) { buffer[index] = 0.0f; for (j = 0; j < channels ; j++) { buffer[index] += (float)(((short*)decbuf)[i+j])/(float)SHRT_MAX; } buffer[index++] /= channels; if (index >= nbsamples) break; } break; case MPG123_ENC_SIGNED_8: for (i = 0; i < done/sizeof(char); i+=channels) { buffer[index] = 0.0f; for (j = 0; j < channels ; j++) { buffer[index] += (float)(((char*)decbuf)[i+j])/(float)SCHAR_MAX; } buffer[index++] /= channels; if (index >= nbsamples) break; } break; case MPG123_ENC_FLOAT_32: for (i = 0; i < done/sizeof(float); i+=channels) { buffer[index] = 0.0f; for (j = 0; j < channels; j++) { buffer[index] += ((float*)decbuf)[i+j]; } buffer[index++] /= channels; if (index >= nbsamples) break; } break; default: done = 0; } } while (ret == MPG123_OK && index < nbsamples); free(decbuf); mpg123_close(m); mpg123_delete(m); mpg123_exit(); return buffer; }
int plugin_run(struct playerHandles *ph, char *key, int *totaltime){ size_t size; size_t len; int mret=MPG123_NEED_MORE; int retval=DEC_RET_SUCCESS; struct outputdetail *details=ph->outdetail; unsigned char *out; int outsize; if(mp3Init(ph)<0)return DEC_RET_ERROR; details->totaltime=*totaltime>0?*totaltime:-1; details->percent=-1; ph->dechandle=&h; pthread_mutex_lock(&dechandle_lock); new_format(ph); outsize=mpg123_outblock(h.m); pthread_mutex_unlock(&dechandle_lock); h.tcarry=0; h.total=0; h.accuracy=1000; if(!(out=malloc(sizeof(unsigned char)*outsize))){ fprintf(stderr,"Malloc failed (out decoder buffer)."); plugin_exit(ph); return DEC_RET_ERROR; } do{ /* Read and write until everything is through. */ //if outbuff isn't big enough to hold all decoded data from inbuff, keep going if(mret != MPG123_NEED_MORE){ pthread_mutex_lock(&dechandle_lock); mret=mpg123_read(h.m,out,outsize,&len); pthread_mutex_unlock(&dechandle_lock); } else{ pthread_mutex_lock(&dechandle_lock); mret=mpg123_read(h.m,out,outsize,&len); pthread_mutex_unlock(&dechandle_lock); if(mret==MPG123_DONE || mret==MPG123_ERR){ // EOF (or read error) retval=DEC_RET_SUCCESS; break; } } if(mret==MPG123_NEW_FORMAT){ //fprintf(stderr,"Should have reformatted here."); pthread_mutex_lock(&dechandle_lock); new_format(ph); pthread_mutex_unlock(&dechandle_lock); } if(len==0)continue; size=len; pthread_mutex_lock(&dechandle_lock); details->curtime=h.total; details->percent=(details->curtime*100)/details->totaltime; h.tcarry+=size; if(h.tcarry>=h.samptime){ h.total+=h.tcarry/h.samptime; h.tcarry%=h.samptime; } pthread_mutex_unlock(&dechandle_lock); #if WITH_ALSA==1 if(writei_snd(ph,(char *)out,size/h.framesize)<0)break; #else if(writei_snd(ph,(char *)out,size)<0)break; #endif /* if(metacount++>2000){ printf("1\n"); metacount=0; pthread_mutex_lock(&dechandle_lock); metaret=mpg123_meta_check(h.m); if(metaret & MPG123_NEW_ICY){ mpg123_icy(h.m,&icymeta); printf("%s\n",icymeta); } pthread_mutex_unlock(&dechandle_lock); }*/ if(ph->pflag->exit!=DEC_RET_SUCCESS){ retval=ph->pflag->exit; break; } }while(mret != MPG123_ERR && mret!=MPG123_DONE); if(mret == MPG123_ERR){ fprintf(stderr, "decoder error: %s", mpg123_strerror(h.m)); if(mpg123_errcode(h.m)!=28) // Common error. quick fix retval=DEC_RET_ERROR; } writei_snd(ph,(char *)out,0); // drain sound buffer /* Done decoding, now just clean up and leave. */ plugin_exit(ph); free(out); *totaltime=details->curtime; return retval; }
int main(int argc, char *argv[]) { SNDFILE* sndfile = NULL; SF_INFO sfinfo; mpg123_handle *mh = NULL; unsigned char* buffer = NULL; size_t buffer_size = 0; size_t done = 0; int channels = 0, encoding = 0; long rate = 0; int err = MPG123_OK; off_t samples = 0; if (argc!=3) usage(); printf( "Input file: %s\n", argv[1]); printf( "Output file: %s\n", argv[2]); err = mpg123_init(); if( err != MPG123_OK || (mh = mpg123_new(NULL, &err)) == NULL /* Let mpg123 work with the file, that excludes MPG123_NEED_MORE messages. */ || mpg123_open(mh, argv[1]) != MPG123_OK /* Peek into track and get first output format. */ || 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 -1; } 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); fprintf(stderr, "Bad encoding: 0x%x!\n", encoding); return -2; } /* 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 could be almost any size here, mpg123_outblock() is just some recommendation. Important, especially for sndfile writing, is that the size is a multiple of sample size. */ buffer_size = mpg123_outblock( mh ); buffer = malloc( buffer_size ); bzero(&sfinfo, sizeof(sfinfo) ); sfinfo.samplerate = rate; sfinfo.channels = channels; sfinfo.format = SF_FORMAT_WAV|SF_FORMAT_PCM_16; printf("Creating 16bit WAV with %i channels and %liHz.\n", channels, rate); sndfile = sf_open(argv[2], SFM_WRITE, &sfinfo); if(sndfile == NULL){ fprintf(stderr, "Cannot open output file!\n"); cleanup(mh); return -2; } do { err = mpg123_read( mh, buffer, buffer_size, &done ); sf_write_short( sndfile, (short*)buffer, done/sizeof(short) ); samples += done/sizeof(short); /* We are not in feeder mode, so MPG123_OK, MPG123_ERR and MPG123_NEW_FORMAT are the only possibilities. We do not handle a new format, MPG123_DONE is the end... so abort on anything not MPG123_OK. */ } while (err==MPG123_OK); if(err != MPG123_DONE) fprintf( stderr, "Warning: Decoding ended prematurely because: %s\n", err == MPG123_ERR ? mpg123_strerror(mh) : mpg123_plain_strerror(err) ); sf_close( sndfile ); samples /= channels; printf("%li samples written.\n", (long)samples); cleanup(mh); return 0; }
void* player_thread(void* _mp3_info) { log_debug("player thread started"); mp3_t* mp3_info = (mp3_t* ) _mp3_info; long current_position_in_ms = 0; long previous_position_in_ms = -1; long guard_position_in_ms = -1; el_bool playing = el_false; pthread_t thread_id; int no_count = 0; post_event(mp3_info->client_notification, AUDIO_READY, current_position_in_ms); audio_event_t *event; event = audio_event_fifo_dequeue(mp3_info->player_control); while (event->state != INTERNAL_CMD_DESTROY) { if (event->state != INTERNAL_CMD_NONE) { log_debug4("event = %s, %ld, %s", audio_event_name(event->state), event->position_in_ms, mp3_info->file_or_url); } audio_state_t event_state = event->state; long event_position = event->position_in_ms; audio_event_destroy(event); switch (event_state) { case INTERNAL_CMD_LOAD_FILE: { playing = el_false; // Stop stream, if playing if (!mp3_info->is_file) { mp3_info->continue_streaming = el_false; psem_wait(mp3_info->stream_ready); } if (mp3_info->is_open) { mpg123_close(mp3_info->handle); aodev_close(mp3_info->ao_handle); } mpg123_open(mp3_info->handle, mp3_info->file_or_url); mpg123_getformat(mp3_info->handle, &mp3_info->rate, &mp3_info->channels, &mp3_info->encoding); mp3_info->buffer_size = mpg123_outblock(mp3_info->handle); mc_free(mp3_info->buffer); mp3_info->buffer = mc_malloc(mp3_info->buffer_size * sizeof(char) ); int bytes_per_sample = get_encsize(mp3_info->encoding); aodev_set_format(mp3_info->ao_handle, bytes_per_sample * 8, mp3_info->rate, mp3_info->channels); aodev_open(mp3_info->ao_handle); mp3_info->is_open = el_true; mp3_info->is_file = el_true; mp3_info->can_seek = el_true; current_position_in_ms = 0; guard_position_in_ms = -1; { off_t l = mpg123_length(mp3_info->handle); if (l == MPG123_ERR) { mp3_info->length = -1; } else { mp3_info->length = (l * 1000) / mp3_info->rate; } psem_post(mp3_info->length_set); } } break; case INTERNAL_CMD_LOAD_URL: { playing = el_false; log_debug2("loading url %s", mp3_info->file_or_url); // Wait for feeding streams to end if (!mp3_info->is_file) { mp3_info->continue_streaming = el_false; psem_wait(mp3_info->stream_ready); } mp3_info->is_file = el_false; log_debug("current stream ended"); if (mp3_info->is_open) { mpg123_close(mp3_info->handle); aodev_close(mp3_info->ao_handle); mp3_info->is_open = el_false; } log_debug("aodev closed"); mpg123_open_feed(mp3_info->handle); log_debug("feed opened"); pthread_create(&thread_id, NULL, stream_thread, mp3_info); log_debug("stream thread started"); mp3_info->is_open = el_true; mp3_info->can_seek = el_false; current_position_in_ms = 0; guard_position_in_ms = -1; mp3_info->length = 0; mp3_info->continue_streaming = el_true; psem_post(mp3_info->length_set); } break; case INTERNAL_CMD_SEEK: { off_t pos = mpg123_timeframe(mp3_info->handle, (event_position / 1000.0)); mpg123_seek_frame(mp3_info->handle, pos, SEEK_SET); } break; case INTERNAL_CMD_PLAY: { playing = el_true; } break; case INTERNAL_CMD_PAUSE: { playing = el_false; } break; case INTERNAL_CMD_GUARD: { guard_position_in_ms = event_position; } break; case INTERNAL_CMD_SET_VOLUME: { double volume = ((double) event_position) / 1000.0; mpg123_volume(mp3_info->handle, volume); } case INTERNAL_CMD_NONE: break; default: break; } //log_debug3("guard = %d, playing = %d", guard_position_in_ms, playing); if (guard_position_in_ms >= 0 && current_position_in_ms >= guard_position_in_ms) { guard_position_in_ms = -1; post_event(mp3_info->client_notification, AUDIO_GUARD_REACHED, current_position_in_ms); } else if (playing) { if (mp3_info->is_file) { size_t bytes; int res = mpg123_read(mp3_info->handle, mp3_info->buffer, mp3_info->buffer_size, &bytes); if (res == MPG123_OK) { aodev_play_buffer(mp3_info->ao_handle, mp3_info->buffer, bytes); off_t frame = mpg123_tellframe(mp3_info->handle); double time_per_frame = (mpg123_tpf(mp3_info->handle)*1000.0); //static int prt = 1; //if (prt) { printf("tpf=%.6lf\n",time_per_frame);prt=0; } current_position_in_ms = (long) (frame * time_per_frame); // 1 frame is about 26 milliseconds if (previous_position_in_ms == -1) previous_position_in_ms = current_position_in_ms; if ((current_position_in_ms - previous_position_in_ms) >= STATE_REPORT_THRESHOLD) { post_event(mp3_info->client_notification, AUDIO_PLAYING, current_position_in_ms); } previous_position_in_ms = current_position_in_ms; } else if (res == MPG123_DONE) { post_event(mp3_info->client_notification, AUDIO_EOS, current_position_in_ms); playing = el_false; } else { post_event(mp3_info->client_notification, AUDIO_STATE_ERROR, current_position_in_ms); playing = el_false; } } else { // Stream playing if (mp3_stream_fifo_peek(mp3_info->stream_fifo) != NULL) { el_bool go_on = el_true; while (go_on && mp3_stream_fifo_peek(mp3_info->stream_fifo) != NULL) { memblock_t* blk = mp3_stream_fifo_dequeue(mp3_info->stream_fifo); mpg123_feed(mp3_info->handle, (const unsigned char*) memblock_as_str(blk), memblock_size(blk)); memblock_destroy(blk); size_t done; int err; unsigned char *audio; off_t frame_offset; do { err = mpg123_decode_frame(mp3_info->handle, &frame_offset, &audio, &done); switch(err) { case MPG123_NEW_FORMAT: mpg123_getformat(mp3_info->handle, &mp3_info->rate, &mp3_info->channels, &mp3_info->encoding); if (aodev_is_open(mp3_info->ao_handle)) { aodev_close(mp3_info->ao_handle); } aodev_set_format(mp3_info->ao_handle, get_encsize(mp3_info->encoding) * 8, mp3_info->rate, mp3_info->channels); aodev_open(mp3_info->ao_handle); break; case MPG123_OK: //log_debug2("playing buffer %d", done); aodev_play_buffer(mp3_info->ao_handle, audio, done); off_t frame = mpg123_tellframe(mp3_info->handle); double time_per_frame = (mpg123_tpf(mp3_info->handle)*1000.0); current_position_in_ms = (long) (frame * time_per_frame); // 1 frame is about 26 milliseconds if (previous_position_in_ms == -1) previous_position_in_ms = current_position_in_ms; if ((current_position_in_ms - previous_position_in_ms) >= STATE_REPORT_THRESHOLD) { post_event(mp3_info->client_notification, AUDIO_PLAYING, current_position_in_ms); } previous_position_in_ms = current_position_in_ms; go_on = el_false; break; case MPG123_NEED_MORE: break; default: break; } } while (done > 0); } } else { // no streaming data, prevent race conditions // sleep for a small time (50 ms); no_count += 1; if (no_count > 10) { post_event(mp3_info->client_notification, AUDIO_BUFFERING, current_position_in_ms); } sleep_ms(50); } } } if (playing) { if (audio_event_fifo_peek(mp3_info->player_control) != NULL) { event = audio_event_fifo_dequeue(mp3_info->player_control); } else { event = (audio_event_t*) mc_malloc(sizeof(audio_event_t)); event->state = INTERNAL_CMD_NONE; event->position_in_ms = -1; } } else { //log_debug("waiting for next event"); event = audio_event_fifo_dequeue(mp3_info->player_control); } } // destroy event received log_debug("destroy event received"); // Kill playing streams if (mp3_info->streaming) { mp3_info->continue_streaming = el_false; psem_wait(mp3_info->stream_ready); } audio_event_destroy(event); // exit thread return NULL; }
int main(int argc, char *argv[]) { SNDFILE* sndfile = NULL; SF_INFO sfinfo; mpg123_handle *mh = NULL; unsigned char* buffer = NULL; size_t buffer_size = 0; size_t done = 0; int channels = 0, encoding = 0; long rate = 0; int err = MPG123_OK; off_t samples = 0; if (argc<3) usage(); printf( "Input file: %s\n", argv[1]); printf( "Output file: %s\n", argv[2]); err = mpg123_init(); if(err != MPG123_OK || (mh = mpg123_new(NULL, &err)) == NULL) { fprintf(stderr, "Basic setup goes wrong: %s", mpg123_plain_strerror(err)); cleanup(mh); return -1; } /* Simple hack to enable floating point output. */ if(argc >= 4 && !strcmp(argv[3], "f32")) mpg123_param(mh, MPG123_ADD_FLAGS, MPG123_FORCE_FLOAT, 0.); /* Let mpg123 work with the file, that excludes MPG123_NEED_MORE messages. */ if( mpg123_open(mh, argv[1]) != MPG123_OK /* Peek into track and get first output format. */ || mpg123_getformat(mh, &rate, &channels, &encoding) != MPG123_OK ) { fprintf( stderr, "Trouble with mpg123: %s\n", mpg123_strerror(mh) ); cleanup(mh); return -1; } 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); fprintf(stderr, "Bad encoding: 0x%x!\n", encoding); return -2; } /* Ensure that this output format will not change (it could, when we allow it). */ mpg123_format_none(mh); mpg123_format(mh, rate, channels, encoding); bzero(&sfinfo, sizeof(sfinfo) ); sfinfo.samplerate = rate; sfinfo.channels = channels; sfinfo.format = SF_FORMAT_WAV|(encoding == MPG123_ENC_SIGNED_16 ? SF_FORMAT_PCM_16 : SF_FORMAT_FLOAT); printf("Creating WAV with %i channels and %liHz.\n", channels, rate); sndfile = sf_open(argv[2], SFM_WRITE, &sfinfo); if(sndfile == NULL){ fprintf(stderr, "Cannot open output file!\n"); cleanup(mh); return -2; } /* Buffer could be almost any size here, mpg123_outblock() is just some recommendation. Important, especially for sndfile writing, is that the size is a multiple of sample size. */ buffer_size = argc >= 5 ? atol(argv[4]) : mpg123_outblock(mh); buffer = malloc( buffer_size ); do { sf_count_t more_samples; err = mpg123_read( mh, buffer, buffer_size, &done ); more_samples = encoding == MPG123_ENC_SIGNED_16 ? sf_write_short(sndfile, (short*)buffer, done/sizeof(short)) : sf_write_float(sndfile, (float*)buffer, done/sizeof(float)); if(more_samples < 0 || more_samples*mpg123_encsize(encoding) != done) { fprintf(stderr, "Warning: Written number of samples does not match the byte count we got from libmpg123: %li != %li\n", (long)(more_samples*mpg123_encsize(encoding)), (long)done); } samples += more_samples; /* We are not in feeder mode, so MPG123_OK, MPG123_ERR and MPG123_NEW_FORMAT are the only possibilities. We do not handle a new format, MPG123_DONE is the end... so abort on anything not MPG123_OK. */ } while (err==MPG123_OK); if(err != MPG123_DONE) fprintf( stderr, "Warning: Decoding ended prematurely because: %s\n", err == MPG123_ERR ? mpg123_strerror(mh) : mpg123_plain_strerror(err) ); sf_close( sndfile ); samples /= channels; printf("%li samples written.\n", (long)samples); cleanup(mh); return 0; }
static audio_result_t init(audio_worker_t* worker, const char* file_or_url, el_bool file) { static int mp3_initialized = 0; static int mp3_error = 0; if (!mp3_initialized) { mp3_initialized = 1; if (mpg123_init() != MPG123_OK) { mp3_error = 1; } else { atexit(mpg123_exit); } } if (mp3_error) { return AUDIO_CANNOT_INITIALIZE; } mp3_t* mp3=(mp3_t*) mc_malloc(sizeof(mp3_t)); worker->can_seek = can_seek; worker->play = play; worker->pause = mp3_pause; worker->seek = seek; worker->guard = guard; worker->destroy = destroy; worker->length_in_ms = length_in_ms; worker->load_file = load_file; worker->load_url = load_url; worker->set_volume = set_volume; worker->worker_data = (void*) mp3; int error; mp3->handle = mpg123_new(NULL, &error); mp3->buffer_size = mpg123_outblock(mp3->handle); mp3->buffer = mc_malloc(mp3->buffer_size * sizeof(char)); mpg123_volume(mp3->handle, 1.0); mp3->client_notification = worker->fifo; mp3->player_control = audio_event_fifo_new(); // http streams mp3->stream_fifo = mp3_stream_fifo_new(); mp3->continue_streaming = el_true; mp3->current_block = NULL; //sem_init(&mp3->stream_ready, 0, 0); mp3->stream_ready = psem_new(0); mp3->streaming = el_false; // etc. mp3->is_open = el_false; mp3->length = -1; //sem_init(&mp3->length_set, 0, 0); mp3->length_set = psem_new(0); mp3->ao_handle = aodev_new(); if (file) { mp3->can_seek = el_true; mp3->is_file = el_true; mp3->file_or_url = mc_strdup(file_or_url); post_event(mp3->player_control, INTERNAL_CMD_LOAD_FILE, -1); } else { // URL mp3->can_seek = el_false; mp3->is_file = el_true; // we check this later mp3->file_or_url = mc_strdup(file_or_url); post_event(mp3->player_control, INTERNAL_CMD_LOAD_URL, -1); } int thread_id = pthread_create(&mp3->player_thread, NULL, player_thread, mp3); // wait until fully loaded (length is set) psem_wait(mp3->length_set); log_debug("INIT OK"); return AUDIO_OK; }
int mpeg_open(char *path) { int rv = -1; int err = 0; int res = 0; int channels = 0; int encoding = 0; long rate = 0; if(handle != NULL) { goto mpeg_open_exit; } handle = calloc(1, sizeof(mpeg_handle_t)); if(handle == NULL) { goto mpeg_open_exit; } handle->mh = mpg123_new(NULL, &err); if(handle->mh == NULL) { goto mpeg_open_exit; } mpg123_param(handle->mh, MPG123_FLAGS, MPG123_QUIET, 0.0); handle->driver = ao_default_driver_id(); handle->bufsize = mpg123_outblock(handle->mh) / BUF_DIVISOR; handle->buf = (unsigned char*) malloc(handle->bufsize); if(handle->buf == NULL) { goto mpeg_open_exit; } res = mpg123_open(handle->mh, path); if(res != MPG123_OK) { goto mpeg_open_exit; } res = mpg123_getformat(handle->mh, &rate, &channels, &encoding); if(res != MPG123_OK) { goto mpeg_open_exit; } handle->format.bits = mpg123_encsize(encoding) * 8; handle->format.rate = rate; handle->format.channels = channels; handle->format.byte_format = AO_FMT_NATIVE; handle->format.matrix = 0; handle->device = ao_open_live(handle->driver, &(handle->format), NULL); if(handle->device == NULL) { goto mpeg_open_exit; } else { /* Return value to indicate success */ rv = 0; } mpeg_open_exit: if(rv == -1) { if(handle != NULL) { if(handle->buf != NULL) { free(handle->buf); handle->buf = NULL; } if(handle->device != NULL) { ao_close(handle->device); handle->device = NULL; } if(handle->mh != NULL) { mpg123_close(handle->mh); mpg123_delete(handle->mh); handle->mh = NULL; } free(handle); handle = NULL; } } return rv; }
float* readaudio_mp3(const char *filename,long *sr, unsigned int *buflen,\ const float nbsecs, AudioMetaData *mdata, int *error){ mpg123_handle *m; int ret = 0; mpg123_id3v1 *v1 = NULL; mpg123_id3v2 *v2 = NULL; if ((ret = mpg123_init()) != MPG123_OK || ((m = mpg123_new(NULL,&ret)) == NULL)|| \ (ret = mpg123_open(m, filename)) != MPG123_OK){ *error = (ret != 0) ? ret : PHERR_MP3NEW; return NULL; } /*turn off logging */ mpg123_param(m, MPG123_ADD_FLAGS, MPG123_QUIET, 0); off_t totalsamples; mpg123_scan(m); totalsamples = mpg123_length(m); if (totalsamples <= 0){ *error = PHERR_NOSAMPLES; return NULL; } int meta = mpg123_meta_check(m); if (mdata)init_mdata(mdata); if (mdata && (meta & MPG123_ID3) && mpg123_id3(m, &v1, &v2) == MPG123_OK){ if (v2){ get_v2_data(v2, mdata); } else if (v1){ get_v1_data(v1, mdata); } } int channels, encoding; if (mpg123_getformat(m, sr, &channels, &encoding) != MPG123_OK){ *error = PHERR_NOFORMAT; return NULL; } mpg123_format_none(m); mpg123_format(m, *sr, channels, encoding); if (channels <= 0 || encoding <= 0){ *error = PHERR_NOENCODING; return NULL; } size_t decbuflen = mpg123_outblock(m); if (decbuflen == 0){ /* take a guess */ decbuflen = 1<<16; } unsigned char *decbuf = (unsigned char*)malloc(decbuflen); if (decbuf == NULL){ *error = PHERR_MEMALLOC; return NULL; } unsigned int nbsamples = (nbsecs <= 0) ? totalsamples : nbsecs*(*sr); nbsamples = (nbsamples <= totalsamples) ? nbsamples : totalsamples; size_t i, j, index = 0, done; float *buffer = (float*)malloc(nbsamples*sizeof(float)); if (buffer == NULL){ *error = PHERR_MEMALLOC; return NULL; } *buflen = nbsamples; do { ret = mpg123_read(m, decbuf, decbuflen, &done); switch (encoding) { case MPG123_ENC_SIGNED_16 : for (i = 0; i < done/sizeof(short); i+=channels){ buffer[index] = 0.0f; for (j = 0; j < channels ; j++){ buffer[index] += (float)(((short*)decbuf)[i+j])/(float)SHRT_MAX; } buffer[index++] /= channels; if (index >= nbsamples) break; } break; case MPG123_ENC_SIGNED_8: for (i = 0; i < done/sizeof(char); i+=channels){ buffer[index] = 0.0f; for (j = 0; j < channels ; j++){ buffer[index] += (float)(((char*)decbuf)[i+j])/(float)SCHAR_MAX; } buffer[index++] /= channels; if (index >= nbsamples) break; } break; case MPG123_ENC_FLOAT_32: for (i = 0; i < done/sizeof(float); i+=channels){ buffer[index] = 0.0f; for (j = 0; j < channels; j++){ buffer[index] += ((float*)decbuf)[i+j]; } buffer[index++] /= channels; if (index >= nbsamples) break; } break; default: done = 0; } } while (ret == MPG123_OK && index < nbsamples); if (ret != MPG123_DONE && ret != MPG123_OK && index < nbsamples){ free(buffer); *error = ret; buffer=NULL; } free(decbuf); mpg123_close(m); mpg123_delete(m); mpg123_exit(); return buffer; }
JNIEXPORT jlong JNICALL Java_com_axelby_podax_player_MPG123_getOutputBlockSize (JNIEnv *env, jclass c, jlong handle) { MP3File *mp3 = (MP3File *)handle; return mpg123_outblock(mp3->handle); }
// Open Media file and return elapsed time in millseconds int Waveform::OpenfileMediaFile(const wxString &filename, wxString& error) { mpg123_handle *mh = NULL; int err; size_t buffer_size; int channels, encoding; long rate; err = mpg123_init(); if(err != MPG123_OK || (mh = mpg123_new(NULL, &err)) == NULL) { error = wxString::Format("Basic setup goes wrong: %s", mpg123_plain_strerror(err)); if (mh != NULL) { cleanup(mh); } return -1; } /* open the file and get the decoding format */ if( mpg123_open(mh, filename.c_str()) != MPG123_OK || mpg123_getformat(mh, &rate, &channels, &encoding) != MPG123_OK ) { error = wxString::Format("Trouble with mpg123: %s", mpg123_strerror(mh)); cleanup(mh); return -1; } if( encoding != MPG123_ENC_SIGNED_16 ) { error = "Encoding unsupported. Must be signed 16 bit."; cleanup(mh); return -2; } /* set the output format and open the output device */ m_bits = mpg123_encsize(encoding); m_rate = rate; m_channels = channels; /* Get Track Size */ mMediaTrackSize = GetTrackSize(mh,m_bits,m_channels); buffer_size = mpg123_outblock(mh); int size = (mMediaTrackSize+buffer_size)*m_bits*m_channels; char * trackData = (char*)malloc(size); LoadTrackData(mh,trackData, size); // Split data into left and right and normalize -1 to 1 m_left_data = (float*)malloc(sizeof(float)*mMediaTrackSize); if( m_channels == 2 ) { m_right_data = (float*)malloc(sizeof(float)*mMediaTrackSize); SplitTrackDataAndNormalize((signed short*)trackData,mMediaTrackSize,m_left_data,m_right_data); } else if( m_channels == 1 ) { NormalizeMonoTrackData((signed short*)trackData,mMediaTrackSize,m_left_data); } else { error = "More than 2 audio channels is not supported yet."; } views.clear(); float samplesPerLine = GetSamplesPerLineFromZoomLevel(mZoomLevel); WaveView wv(mZoomLevel,samplesPerLine,m_left_data,mMediaTrackSize); views.push_back(wv); mCurrentWaveView = 0; mpg123_close(mh); mpg123_delete(mh); mpg123_exit(); free(trackData); float seconds = (float)mMediaTrackSize * ((float)1/(float)rate); mAudioIsLoaded = true; return (int)(seconds * (float)1000); }