Пример #1
0
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);
}
Пример #2
0
bool Mpg123Decoder::IsMp3(FILE* stream) {
	Mpg123Decoder decoder;
	// Prevent stream handle destruction
	mpg123_replace_reader_handle(decoder.handle.get(), custom_read, custom_seek, noop_close);
	// Prevent skipping of too many garbage, breaks heuristic
	mpg123_param(decoder.handle.get(), MPG123_RESYNC_LIMIT, 64, 0.0);
	if (!decoder.Open(stream)) {
		return false;
	}

	unsigned char buffer[1024];
	int err = 0;
	size_t done = 0;
	int err_count = 0;
	
	// Read beginning of assumed MP3 file and count errors as an heuristic to detect MP3
	for (int i = 0; i < 10; ++i) {
		err = mpg123_read(decoder.handle.get(), buffer, 1024, &done);
		if (err != MPG123_OK) {
			err_count += 1;
		}
		if (err_count >= 3) {
			break;
		}
	}

	return err_count < 3;
}
Пример #3
0
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;
	}
}
Пример #4
0
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);
}
Пример #5
0
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;
}
Пример #6
0
Mpg123Decoder::Mpg123Decoder() :
	handle(nullptr, mpg123_delete)
{
	music_type = "mp3";

	err = mpg123_init();
	if (err != MPG123_OK) {
		error_message = "mpg123: " + std::string(mpg123_plain_strerror(err));
		return;
	}

	handle.reset(mpg123_new(nullptr, &err));
	mpg123_replace_reader_handle(handle.get(), custom_read, custom_seek, custom_close);

	if (!handle) {
		error_message = "mpg123: " + std::string(mpg123_plain_strerror(err));
		return;
	}

	init = true;
}
Пример #7
0
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;
}
Пример #8
0
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();
}
Пример #9
0
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;
}
Пример #10
0
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;
}
Пример #11
0
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;
}