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); }
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; } }
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); }
bool Mpg123Decoder::Open(FILE* file) { if (!init) { return false; } finished = false; err = mpg123_open_handle(handle.get(), file); if (err != MPG123_OK) { error_message = "mpg123: " + std::string(mpg123_plain_strerror(err)); return false; } return true; }
AudioStreamerMpg123::AudioStreamerMpg123(AudioSourceMpg123* source, int loops) : AudioStreamer(source, loops) { handle_ = NULL; int err = MPG123_OK; mpg123_handle* mh = mpg123_new(NULL, &err); if (mh == NULL || err != MPG123_OK) return; /* if (mpg123_open(mh, source->fileName()) != MPG123_OK) { mpg123_delete(mh); return; }*/ G_FILE* file = g_fopen(source->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); handle_ = mh; }
bool MPG123Decoder::open(FileReader &reader) { if(!inited) { if (!IsMPG123Present()) return false; if(mpg123_init() != MPG123_OK) return false; inited = true; } Reader = std::move(reader); { MPG123 = mpg123_new(NULL, NULL); if(mpg123_replace_reader_handle(MPG123, file_read, file_lseek, NULL) == MPG123_OK && mpg123_open_handle(MPG123, this) == 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 Done = false; return true; } } mpg123_close(MPG123); } mpg123_delete(MPG123); MPG123 = 0; } reader = std::move(Reader); // need to give it back. return false; }
bool Mp3Decoder::open( Downloader* downloader ) { _handle = mpg123_new(NULL, NULL); if(_handle == NULL) { printf("mpg123_new failed\n"); return false; } mpg123_replace_reader_handle(_handle, g_read, NULL, NULL); int res = mpg123_param(_handle, MPG123_FLAGS, MPG123_FUZZY | MPG123_SEEKBUFFER | MPG123_GAPLESS, 0); assert(res == MPG123_OK); res = mpg123_open_handle(_handle, downloader); if(res != MPG123_OK) { printf("mpg123_open_handle failed\n"); return false; } _downloader = downloader; return afterOpen(); }
bool DecoderMPG123::initialize() { if (input()->isSequential ()) //for streams only { TagExtractor extractor(input()); if(!extractor.id3v2tag().isEmpty()) addMetaData(extractor.id3v2tag()); } int err = mpg123_init(); if(err != MPG123_OK) { qWarning("DecoderMPG123: basic setup goes wrong: %s", mpg123_plain_strerror(err)); return false; } int channels = 0; if(!(m_handle = mpg123_new(0, &err))) { qWarning("DecoderMPG123: basic setup goes wrong: %s", mpg123_plain_strerror(err)); return false; } mpg123_param (m_handle, MPG123_ADD_FLAGS, MPG123_SEEKBUFFER | MPG123_FUZZY, 0); if((err = mpg123_replace_reader_handle(m_handle, mpg123_read_cb, mpg123_seek_cb, 0)) != MPG123_OK) { qWarning("DecoderMPG123: mpg123 error: %s", mpg123_plain_strerror(err)); cleanup(m_handle); m_handle = 0; return false; } setMPG123Format(MPG123_ENC_FLOAT_32); if((err = mpg123_open_handle(m_handle, this)) != MPG123_OK) { qWarning("DecoderMPG123: mpg123 error: %s", mpg123_plain_strerror(err)); cleanup(m_handle); m_handle = 0; return false; } if((err = mpg123_getformat(m_handle, &m_rate, &channels, &m_mpg123_encoding)) != MPG123_OK) { qWarning("DecoderMPG123: mpg123 error: %s", mpg123_plain_strerror(err)); cleanup(m_handle); m_handle = 0; return false; } //check format if(m_mpg123_encoding != MPG123_ENC_FLOAT_32) { cleanup(m_handle); qWarning("DecoderMPG123: bad encoding: 0x%x!\n", m_mpg123_encoding); m_handle = 0; return false; } if(!input()->isSequential()) { if((err = mpg123_scan(m_handle)) != MPG123_OK) qWarning("DecoderMPG123: mpg123 error: %s", mpg123_plain_strerror(err)); //duration m_totalTime = (qint64) mpg123_length(m_handle) * 1000 / m_rate; } else m_totalTime = 0; configure(m_rate, channels, Qmmp::PCM_FLOAT); return true; }
g_id gaudio_Mp3Open(const char *fileName, int *numChannels, int *sampleRate, int *bitsPerSample, int *numSamples, gaudio_Error *error) { int err = MPG123_OK; mpg123_handle *mh = mpg123_new(NULL, &err); if (mh == NULL || err != MPG123_OK) { if (error) *error = GAUDIO_INTERNAL_ERROR; return 0; } G_FILE *file = g_fopen(fileName, "rb"); if (file == NULL) { mpg123_delete(mh); if (error) *error = GAUDIO_CANNOT_OPEN_FILE; return 0; } mpg123_replace_reader_handle(mh, mpg123read, mpg123lseek, mpg123cleanup); if (mpg123_open_handle(mh, file) != MPG123_OK) { mpg123_delete(mh); if (error) *error = GAUDIO_UNRECOGNIZED_FORMAT; return 0; } int channels = 0, encoding = 0; long rate = 0; if (mpg123_getformat(mh, &rate, &channels, &encoding) != MPG123_OK) { mpg123_delete(mh); if (error) *error = GAUDIO_UNRECOGNIZED_FORMAT; return 0; } // although signed 16 is the default output format, we ensure that anyway. encoding = MPG123_ENC_SIGNED_16; mpg123_format_none(mh); mpg123_format(mh, rate, channels, encoding); mpg123_scan(mh); off_t sampleCount = mpg123_length(mh); if (numChannels) *numChannels = channels; if (sampleRate) *sampleRate = rate; if (bitsPerSample) *bitsPerSample = 16; if (numSamples) *numSamples = sampleCount; if (error) *error = GAUDIO_NO_ERROR; GGMp3Handle *handle = new GGMp3Handle(); handle->mh = mh; handle->sampleSize = channels * 2; return (g_id)handle; }
static snd_stream_t *S_MP3_CodecOpenStream (const char *filename) { snd_stream_t *stream; long rate = 0; int encoding = 0, channels = 0; mp3_priv_t *priv = NULL; stream = S_CodecUtilOpen(filename, &mp3_codec); if (!stream) return NULL; stream->priv = Z_Malloc(sizeof(mp3_priv_t)); priv = (mp3_priv_t *) stream->priv; priv->handle = mpg123_new(NULL, NULL); if (priv->handle == NULL) { Con_Printf("Unable to allocate mpg123 handle\n"); goto _fail; } priv->handle_newed = 1; if (mpg123_replace_reader_handle(priv->handle, mp3_read, mp3_seek, NULL) != MPG123_OK || mpg123_open_handle(priv->handle, &stream->fh) != MPG123_OK) { Con_Printf("Unable to open mpg123 handle\n"); goto _fail; } priv->handle_opened = 1; if (mpg123_getformat(priv->handle, &rate, &channels, &encoding) != MPG123_OK) { Con_Printf("Unable to retrieve mpg123 format for %s\n", filename); goto _fail; } switch (channels) { case MPG123_MONO: stream->info.channels = 1; break; case MPG123_STEREO: stream->info.channels = 2; break; default: Con_Printf("Unsupported number of channels %d in %s\n", channels, filename); goto _fail; } stream->info.rate = rate; switch (encoding) { case MPG123_ENC_UNSIGNED_8: stream->info.width = 1; break; case MPG123_ENC_SIGNED_8: /* unsupported: force mpg123 to convert */ stream->info.width = 1; encoding = MPG123_ENC_UNSIGNED_8; break; case MPG123_ENC_SIGNED_16: stream->info.width = 2; break; case MPG123_ENC_UNSIGNED_16: default: /* unsupported: force mpg123 to convert */ stream->info.width = 2; encoding = MPG123_ENC_SIGNED_16; break; } if (mpg123_format_support(priv->handle, rate, encoding) == 0) { Con_Printf("Unsupported format for %s\n", filename); goto _fail; } mpg123_format_none(priv->handle); mpg123_format(priv->handle, rate, channels, encoding); return stream; _fail: if (priv) { if (priv->handle_opened) mpg123_close(priv->handle); if (priv->handle_newed) mpg123_delete(priv->handle); Z_Free(stream->priv); } S_CodecUtilClose(&stream); return NULL; }