Beispiel #1
0
/*****************************************************************************
 * MPG123Open
 *****************************************************************************/
static int MPG123Open( decoder_t *p_dec )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

    /* Create our mpg123 handle */
    if( ( p_sys->p_handle = mpg123_new( NULL, NULL ) ) == NULL )
    {
        msg_Err( p_dec, "mpg123 error: can't create handle" );
        return VLC_EGENERIC;
    }

    /* Open a new bitstream */
    if( mpg123_open_feed( p_sys->p_handle ) != MPG123_OK )
    {
        msg_Err( p_dec, "mpg123 error: can't open feed" );
        mpg123_delete( p_sys->p_handle );
        return VLC_EGENERIC;
    }

    /* Disable resync stream after error */
    mpg123_param( p_sys->p_handle, MPG123_ADD_FLAGS, MPG123_NO_RESYNC, 0 );

    /* Setup output format */
    mpg123_format_none( p_sys->p_handle );

    int i_ret = MPG123_OK;
    if( p_dec->fmt_in.audio.i_rate != 0 )
    {
        i_ret =  mpg123_format( p_sys->p_handle, p_dec->fmt_in.audio.i_rate,
                                MPG123_MONO | MPG123_STEREO,
                                MPG123_ENC_FLOAT_32 );
    }
    else
    {
        /* The rate from the input is unknown. Tell mpg123 to accept all rates
         * to avoid conversion on their side */
        static const long mp3_rates[] = {
            8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
        };
        for( size_t i = 0;
            i < sizeof(mp3_rates) / sizeof(*mp3_rates) && i_ret == MPG123_OK;
            ++i )
        {
            i_ret =  mpg123_format( p_sys->p_handle, mp3_rates[i],
                                    MPG123_MONO | MPG123_STEREO,
                                    MPG123_ENC_FLOAT_32 );
        }
    }
    if( i_ret != MPG123_OK )
    {
        msg_Err( p_dec, "mpg123 error: %s",
                 mpg123_strerror( p_sys->p_handle ) );
        mpg123_close( p_sys->p_handle );
        mpg123_delete( p_sys->p_handle );
        return VLC_EGENERIC;
    }

    p_sys->b_opened = true;
    return VLC_SUCCESS;
}
Beispiel #2
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);
}
Beispiel #3
0
VALUE rb_mpg123_new(VALUE klass, VALUE filename) {
  int err = MPG123_OK;
  mpg123_handle *mh;
  VALUE mpg123;
  long rate;
  int channels, encoding;

  Check_Type(filename, T_STRING);

  if ((mh = mpg123_new(NULL, &err)) == NULL) {
    rb_raise(rb_eStandardError, "%s", mpg123_plain_strerror(err));
  }

  mpg123_param(mh, MPG123_ADD_FLAGS, MPG123_FORCE_FLOAT, 0.);

  if (mpg123_open(mh, (char*) RSTRING_PTR(filename)) != MPG123_OK ||
      mpg123_getformat(mh, &rate, &channels, &encoding) != MPG123_OK) {
    rb_raise(rb_eStandardError, "%s", mpg123_strerror(mh));
  }

  if (encoding != MPG123_ENC_FLOAT_32) {
    rb_raise(rb_eStandardError, "bad encoding");
  }

  mpg123_format_none(mh);
  mpg123_format(mh, rate, channels, encoding);

  VALUE new_mpg123 = Data_Wrap_Struct(rb_cMpg123, 0, cleanup, mh);
  rb_iv_set(new_mpg123, "@file", filename);
  return new_mpg123;
}
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;
}
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;
    }

}
Beispiel #6
0
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;
    }
}
Beispiel #7
0
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;
}
Beispiel #8
0
int fm_player_open(fm_player_t *pl, fm_player_config_t *config)
{
    pl->config = *config;

    if (strcmp(config->driver, "pifm") == 0)
    {
        float f = atof(config->dev);
        if (f < 1)
            f = 102.4;
        printf("Player audio driver: pifm\n");
        printf("Player sample rate: %d Hz\n", config->rate);
        printf("Player FM fequency: %f Hz\n", f);
        config->channels = 1;
        fm_setup_fm();
        fm_setup_dma(f);
    }
    else
    {
        ao_sample_format ao_fmt;
        ao_fmt.rate = config->rate;
        ao_fmt.channels = config->channels;
        ao_fmt.bits = mpg123_encsize(config->encoding) * 8;
        ao_fmt.byte_format = AO_FMT_NATIVE;
        ao_fmt.matrix = 0;
        
        int driver = ao_driver_id(config->driver);
        if (driver == -1) {
            return -1;
        }
        
        ao_info *driver_info = ao_driver_info(driver);
        printf("Player audio driver: %s\n", driver_info->name);
        printf("Player sample rate: %d Hz\n", pl->config.rate);
        ao_option *options = NULL;
        if (config->dev[0] != '\0') {
            ao_append_option(&options, "dev", config->dev);
        }
        pl->dev = ao_open_live(driver, &ao_fmt, options);
        ao_free_options(options);
        if (pl->dev == NULL)
            return -1;
    }

    pl->mh = mpg123_new(NULL, NULL);
    mpg123_format_none(pl->mh);
    mpg123_format(pl->mh, config->rate, config->channels, config->encoding);

    pl->curl = curl_easy_init();
    curl_easy_setopt(pl->curl, CURLOPT_WRITEFUNCTION, download_callback);
    curl_easy_setopt(pl->curl, CURLOPT_WRITEDATA, pl);

    pl->tid_ack = 0;

    pthread_mutex_init(&pl->mutex_status, NULL);
    pthread_cond_init(&pl->cond_play, NULL);

    pl->status = FM_PLAYER_STOP;

    return 0;
}
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;.
}
Beispiel #10
0
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
	}
Beispiel #11
0
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;
}
Beispiel #12
0
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;
}
Beispiel #13
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;
	}
}
Beispiel #14
0
void mpgplayer::run()
{
    if(mpg123_init() != MPG123_OK)
        qDebug("Error initilizing mpg123");
    const char **test = mpg123_supported_decoders();
    int error;
    mpg123_handle *mh = mpg123_new(test[0],&error);
    if(!mpg123_feature(MPG123_FEATURE_DECODE_LAYER3))
    {
        qDebug("You do not seem to have mp3 decoding support");
        return;
    }
    mpg123_format_none(mh);
    if(mpg123_format(mh,samplerate,MPG123_STEREO,MPG123_ENC_SIGNED_16)!=MPG123_OK)
        qDebug("Error in initilizing format decoder");
    qDebug(test[0]);
    mpg123_open(mh,"/home/eli/Projects/groove-evan/Animal.mp3");
    net = TData;
    pa_simple *s;
    pa_sample_spec ss;
    ss.format = PA_SAMPLE_S16NE;
    ss.rate = samplerate;
    ss.channels = 2;
    s =pa_simple_new(NULL,"Groove",PA_STREAM_PLAYBACK ,NULL,"Music",&ss,NULL,NULL,NULL);

    unsigned char bytes[1024];
    size_t bsize = 1024;
    size_t done = 0;
    bool stop = false;
    playing=true;
    while(!stop)
    {
        switch(net)
        {
        case TWait: usleep(100); break;
        case TData:
            if(mpg123_read(mh,bytes,bsize,&done)==MPG123_DONE)
            {
                net=TFinish;
            }
            pa_simple_write(s,bytes,done,&error);
            break;
        case TAbort:
            stop = true;
            break;
        case TFinish:
            pa_simple_drain(s,&error);
            stop = true;
            break;
        default: break;
        }
    }
    qDebug("Finsihed playback");
    pa_simple_free(s);

    mpg123_exit();
}
Beispiel #15
0
bool Mpg123Decoder::SetFormat(int freq, AudioDecoder::Format fmt, int channels) {
	// mpg123 has a built-in pseudo-resampler, not needing SDL_ConvertAudio later
	// Remove all available conversion formats
	// Add just one format to force mpg123 pseudo-resampler work
	mpg123_format_none(handle.get());

	err = mpg123_format(handle.get(), (long)freq, (int)channels, (int)format_to_mpg123_format(fmt));
	if (err != MPG123_OK) {
		err = mpg123_format(handle.get(), (long)44100, (int)channels, (int)format_to_mpg123_format(fmt));
		if (err != MPG123_OK) {
			mpg123_format(handle.get(), (long)44100, (int)2, (int)MPG123_ENC_SIGNED_16);
		}

		return false;
	}

	return err == MPG123_OK;
}
Beispiel #16
0
void DecoderMPG123::setMPG123Format(int encoding)
{
    int sample_rates[] = { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 };

    /* Ensure that this output format will not change (it could, when we allow it). */
    mpg123_format_none(m_handle);
    for(unsigned int i = 0; i < sizeof(sample_rates)/sizeof(int); ++i)
        mpg123_format(m_handle, sample_rates[i], MPG123_MONO | MPG123_STEREO, encoding);
    m_mpg123_encoding = encoding;
}
Beispiel #17
0
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;
}
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);
}
Beispiel #19
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 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;
	
}
Beispiel #21
0
static bool is_mp3(FILE *fp, struct file_type **ft)
{
    mpg123_init();

    int err;
    mpg123_handle *mh = mpg123_new(NULL, &err);

    if (mh == NULL)
    {
        fprintf(stderr, "Could not create mpg123 handle: %s\n", mpg123_plain_strerror(err));
        return false;
    }

    long pos = ftell(fp);

    if (mpg123_open_fd(mh, fileno(fp)) != MPG123_OK)
    {
        fseek(fp, pos, SEEK_SET);
        return false;
    }

    mpg123_scan(mh);

    struct mpg123_frameinfo fi;
    mpg123_info(mh, &fi);

    if (mpg123_format(mh, fi.rate, MPG123_STEREO, MPG123_ENC_SIGNED_16) != MPG123_OK)
    {
        fseek(fp, pos, SEEK_SET);
        return false;
    }

    off_t length = mpg123_length(mh);

    struct mp3_format *fmt = calloc(sizeof(*fmt), 1);
    *ft = &fmt->ft;
    fmt->mh = mh;
    fmt->tpf = mpg123_tpf(mh);
    fmt->ft.channels = 2;
    fmt->ft.position = 0;
    fmt->ft.length = (length + (fi.rate / 2)) / fi.rate;
    fmt->ft.sample_rate = fi.rate;
    fmt->ft.sample_size = 2;
    fmt->ft.sample_type = ST_SIGNED_INTEGER_LE;
    fmt->ft.bitrate = (double)fi.abr_rate;

    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;
}
Beispiel #23
0
static uint8_t * ReadMP3(Sound_t * Sound, const uint8_t * InData, size_t FileSize){
    mpg123_handle *mh;
    if(mpg123_init() != MPG123_OK || (mh = mpg123_new(NULL, NULL)) == NULL){
        mpg123_exit();
        return NULL;
    }

    long rate;
    int channels, encoding;
    unsigned samples;
    size_t OutSize;
    uint8_t * OutData;

    if(mpg123_format_none(mh) != MPG123_OK ||
        mpg123_format(mh, 44100, MPG123_MONO | MPG123_STEREO, MPG123_ENC_SIGNED_16) != MPG123_OK ||
        mpg123_open_feed(mh) != MPG123_OK ||
        mpg123_feed(mh, InData, FileSize) != MPG123_OK ||
        mpg123_set_filesize(mh, FileSize) != MPG123_OK ||
        mpg123_getformat(mh, &rate, &channels, &encoding) != MPG123_OK ||
        (samples = mpg123_length(mh)) == 0 ||
        (OutData = (uint8_t*) malloc(OutSize = samples * channels * 2)) == NULL
    ){
        mpg123_close(mh);
        mpg123_delete(mh);
        mpg123_exit();
        return NULL;
    }

    size_t decoded;
    mpg123_read(mh, OutData, OutSize, &decoded);
    mpg123_close(mh);
    mpg123_delete(mh);
    mpg123_exit();

    if(decoded != OutSize){
        free(OutData);
        return NULL;
    }

    Sound->Channels = channels;
    Sound->SamplingRate = rate;
    Sound->BitDepth = 16;
    Sound->Duration = samples;
    Sound->Data = OutData;
    return OutData;
}
Beispiel #24
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;
}
Beispiel #25
0
inline void MP3Decoder::openFile(const char *filename) {
	mpg123_handle *mh = NULL;
	int  channels = 0, encoding = 0;
	long rate = 0;
	int  err  = MPG123_OK;
        
	err = mpg123_init();
	if( err != MPG123_OK || (mh = mpg123_new(NULL, &err)) == NULL
	|| mpg123_open(mh, filename) != MPG123_OK
	|| mpg123_getformat(mh, &rate, &channels, &encoding) != MPG123_OK ) {
		printf( "Trouble with mpg123: %s with file: %s\n",
		mh==NULL ? mpg123_plain_strerror(err) : mpg123_strerror(mh), filename);
		this->cleanup(mh);
		return;
	}
        
	// Ensure that this output format will not change (it could, when we allow it).
	mpg123_format_none(mh);
	mpg123_format(mh, rate, channels, encoding);
        
	size_t buffer_size = mpg123_length(mh) * channels;//mpg123_outblock( mh );
	printf("buffer size: %ld\n", buffer_size);
    unsigned char* buffer = (unsigned char*)malloc(buffer_size);
	size_t done = 0;
	int samples = 0;
        
	mp3File = MP3File();
	mp3File.handle = mh;
	mp3File.channels = channels;
	mp3File.rate = rate;
	mp3File.buffer = buffer;
	mp3File.buffer_size = buffer_size;
	int length = mpg123_length( mh );
	if( length == MPG123_ERR )
		mp3File.length = 0;
	else
		mp3File.length = length / rate;
}
/**
 * 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 gboolean
gst_mpg123_audio_dec_set_format (GstAudioDecoder * dec, GstCaps * input_caps)
{
/* Using the parsed information upstream, and the list of allowed caps
 * downstream, this code tries to find a suitable audio info. It is important
 * to keep in mind that the rate and number of channels should never deviate
 * from the one the bitstream has, otherwise mpg123 has to mix channels and/or
 * resample (and as its docs say, its internal resampler is very crude). The
 * sample format, however, can be chosen freely, because the MPEG specs do not
 * mandate any special format. Therefore, rate and number of channels are taken
 * from upstream (which parsed the MPEG frames, so the input_caps contain
 * exactly the rate and number of channels the bitstream actually has), while
 * the sample format is chosen by trying out all caps that are allowed by
 * downstream. This way, the output is adjusted to what the downstream prefers.
 *
 * Also, the new output audio info is not set immediately. Instead, it is
 * considered the "next audioinfo". The code waits for mpg123 to notice the new
 * format (= when mpg123_decode_frame() returns MPG123_AUDIO_DEC_NEW_FORMAT),
 * and then sets the next audioinfo. Otherwise, the next audioinfo is set too
 * soon, which may cause problems with mp3s containing several format headers.
 * One example would be an mp3 with the first 30 seconds using 44.1 kHz, then
 * the next 30 seconds using 32 kHz. Rare, but possible.
 *
 * STEPS:
 *
 * 1. get rate and channels from input_caps
 * 2. get allowed caps from src pad
 * 3. for each structure in allowed caps:
 * 3.1. take format
 * 3.2. if the combination of format with rate and channels is unsupported by
 *      mpg123, go to (3), or exit with error if there are no more structures
 *      to try
 * 3.3. create next audioinfo out of rate,channels,format, and exit
 */


  int rate, channels;
  GstMpg123AudioDec *mpg123_decoder;
  GstCaps *allowed_srccaps;
  guint structure_nr;
  gboolean match_found = FALSE;

  mpg123_decoder = GST_MPG123_AUDIO_DEC (dec);

  g_assert (mpg123_decoder->handle != NULL);

  mpg123_decoder->has_next_audioinfo = FALSE;

  /* Get rate and channels from input_caps */
  {
    GstStructure *structure;
    gboolean err = FALSE;

    /* Only the first structure is used (multiple
     * input caps structures don't make sense */
    structure = gst_caps_get_structure (input_caps, 0);

    if (!gst_structure_get_int (structure, "rate", &rate)) {
      err = TRUE;
      GST_ERROR_OBJECT (dec, "Input caps do not have a rate value");
    }
    if (!gst_structure_get_int (structure, "channels", &channels)) {
      err = TRUE;
      GST_ERROR_OBJECT (dec, "Input caps do not have a channel value");
    }

    if (err)
      return FALSE;
  }

  /* Get the caps that are allowed by downstream */
  {
    GstCaps *allowed_srccaps_unnorm =
        gst_pad_get_allowed_caps (GST_AUDIO_DECODER_SRC_PAD (dec));
    allowed_srccaps = gst_caps_normalize (allowed_srccaps_unnorm);
  }

  /* Go through all allowed caps, pick the first one that matches */
  for (structure_nr = 0; structure_nr < gst_caps_get_size (allowed_srccaps);
      ++structure_nr) {
    GstStructure *structure;
    gchar const *format_str;
    GstAudioFormat format;
    int encoding;

    structure = gst_caps_get_structure (allowed_srccaps, structure_nr);

    format_str = gst_structure_get_string (structure, "format");
    if (format_str == NULL) {
      GST_DEBUG_OBJECT (dec, "Could not get format from src caps");
      continue;
    }

    format = gst_audio_format_from_string (format_str);
    if (format == GST_AUDIO_FORMAT_UNKNOWN) {
      GST_DEBUG_OBJECT (dec, "Unknown format %s", format_str);
      continue;
    }

    switch (format) {
      case GST_AUDIO_FORMAT_S16:
        encoding = MPG123_ENC_SIGNED_16;
        break;
      case GST_AUDIO_FORMAT_S24:
        encoding = MPG123_ENC_SIGNED_24;
        break;
      case GST_AUDIO_FORMAT_S32:
        encoding = MPG123_ENC_SIGNED_32;
        break;
      case GST_AUDIO_FORMAT_U16:
        encoding = MPG123_ENC_UNSIGNED_16;
        break;
      case GST_AUDIO_FORMAT_U24:
        encoding = MPG123_ENC_UNSIGNED_24;
        break;
      case GST_AUDIO_FORMAT_U32:
        encoding = MPG123_ENC_UNSIGNED_32;
        break;
      case GST_AUDIO_FORMAT_F32:
        encoding = MPG123_ENC_FLOAT_32;
        break;
      default:
        GST_DEBUG_OBJECT (dec,
            "Format %s in srccaps is not supported", format_str);
        continue;
    }

    {
      int err;

      /* Cleanup old formats & set new one */
      mpg123_format_none (mpg123_decoder->handle);
      err = mpg123_format (mpg123_decoder->handle, rate, channels, encoding);
      if (err != MPG123_OK) {
        GST_DEBUG_OBJECT (dec,
            "mpg123 cannot use caps %" GST_PTR_FORMAT
            " because mpg123_format() failed: %s", structure,
            mpg123_strerror (mpg123_decoder->handle));
        continue;
      }
    }

    gst_audio_info_init (&(mpg123_decoder->next_audioinfo));
    gst_audio_info_set_format (&(mpg123_decoder->next_audioinfo), format, rate,
        channels, NULL);
    GST_LOG_OBJECT (dec, "The next audio format is: %s, %u Hz, %u channels",
        format_str, rate, channels);
    mpg123_decoder->has_next_audioinfo = TRUE;

    match_found = TRUE;

    break;
  }

  gst_caps_unref (allowed_srccaps);

  return match_found;
}
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;
}
Beispiel #29
0
int mp3decode_reg(struct xlplayer *xlplayer)
    {
    static pthread_once_t once_control = PTHREAD_ONCE_INIT;
    struct mp3decode_vars *self;
    struct chapter *chapter;
    int fd, rv;
    long rate;
    int channels, encoding;
    int src_error;

    pthread_once(&once_control, decoder_library_init);
    if (!decoder_library_ok)
        {
        fprintf(stderr, "mp3decode_reg: decoder library is not ok\n");
        goto rej;
        }


    if (!(self = xlplayer->dec_data = calloc(1, sizeof (struct mp3decode_vars))))
        {
        fprintf(stderr, "mp3decode_reg: malloc failure\n");
        goto rej;
        }


    if (!(self->mh = mpg123_new(NULL, NULL)))
        {
        fprintf(stderr, "mp3decode_reg: handle not okay");
        goto rej_;
        }

#ifdef MPG123_AUTO_RESAMPLE
    if (mpg123_param(self->mh, MPG123_REMOVE_FLAGS, MPG123_AUTO_RESAMPLE, 0.0) != MPG123_OK)
        {
        fprintf(stderr, "mpgdecode_reg: failed to turn off auto resampling\n");
        goto rej_;
        }
#endif

    if (mpg123_param(self->mh, MPG123_ADD_FLAGS, MPG123_FORCE_STEREO, 0.0) != MPG123_OK)
        {
        fprintf(stderr, "mpgdecode_reg: failed to set flags");
        goto rej_;
        }

    if (mpg123_format_none(self->mh) != MPG123_OK)
        {
        fprintf(stderr, "mp3decode_reg: failed to clear output formats");
        goto rej_;
        }

    /* all the permitted mp3 sample rates are enabled
     * forced stereo is in effect so no need to add mono formats
     */
    mpg123_format(self->mh, 48000, MPG123_STEREO, MPG123_ENC_FLOAT_32);
    mpg123_format(self->mh, 44100, MPG123_STEREO, MPG123_ENC_FLOAT_32);
    mpg123_format(self->mh, 32000, MPG123_STEREO, MPG123_ENC_FLOAT_32);
    mpg123_format(self->mh, 24000, MPG123_STEREO, MPG123_ENC_FLOAT_32);
    mpg123_format(self->mh, 22050, MPG123_STEREO, MPG123_ENC_FLOAT_32);
    mpg123_format(self->mh, 16000, MPG123_STEREO, MPG123_ENC_FLOAT_32);
    mpg123_format(self->mh, 12000, MPG123_STEREO, MPG123_ENC_FLOAT_32);
    mpg123_format(self->mh, 11025, MPG123_STEREO, MPG123_ENC_FLOAT_32);
    mpg123_format(self->mh, 8000, MPG123_STEREO, MPG123_ENC_FLOAT_32);

    if (!(self->fp = fopen(xlplayer->pathname, "r")))
        {
        fprintf(stderr, "mp3decode_reg: failed to open %s\n", xlplayer->pathname);
        goto rej_;
        }

    mp3_tag_read(&self->taginfo, self->fp);
    lseek(fd = fileno(self->fp), 0, SEEK_SET);

    if ((rv = mpg123_open_fd(self->mh, fd)) != MPG123_OK)
        {
        fprintf(stderr, "mp3decode_reg: mpg123_open_fd failed with return value %d\n", rv);
        goto rej__;
        }
        
    if (mpg123_getformat(self->mh, &rate, &channels, &encoding) != MPG123_OK || channels != 2)
        {
        fprintf(stderr, "mp3decode_reg: mpg123_getformat returned unexpected value\n");
        goto rej___;
        }
    
    if (rate != xlplayer->samplerate)
        {
        fprintf(stderr, "mp3decode_reg: configuring resampler\n");

        xlplayer->src_state = src_new(xlplayer->rsqual, channels, &src_error);
        if (src_error)
            {
            fprintf(stderr, "mp3decode_reg: src_new reports %s\n", src_strerror(src_error));
            goto rej___;
            }

        xlplayer->src_data.src_ratio = (double)xlplayer->samplerate / (double)rate;
        xlplayer->src_data.end_of_input = 0;
        
        size_t output_frames = (size_t)(xlplayer->src_data.src_ratio * 1.1 * 1152);
        xlplayer->src_data.output_frames = (long)output_frames;
        if (!(xlplayer->src_data.data_out = malloc(output_frames * 2 * sizeof (float))))
            {
            fprintf(stderr, "mp3decode_reg: malloc failure\n");
            goto rej____;
            }

        self->resample = TRUE;
        }

    xlplayer->dec_init = mp3decode_init;
    xlplayer->dec_play = mp3decode_play;
    xlplayer->dec_eject = mp3decode_eject;


    if ((chapter = mp3_tag_chapter_scan(&self->taginfo, xlplayer->play_progress_ms + 70)))
        {
        self->current_chapter = chapter;
        xlplayer_set_dynamic_metadata(xlplayer, dynamic_metadata_form[chapter->title.encoding], chapter->artist.text, chapter->title.text, chapter->album.text, 0);
        }

    if (xlplayer->seek_s)
        if (mpg123_seek(self->mh, (off_t)rate * xlplayer->seek_s, SEEK_SET) < 0)
            {
            fprintf(stderr, "mp3decode_init: seek failed\n");
            mp3decode_eject(xlplayer);
            xlplayer->playmode = PM_STOPPED;
            xlplayer->command = CMD_COMPLETE;
            }

    return ACCEPTED;

    rej____:
    xlplayer->src_state = src_delete(xlplayer->src_state);
    rej___:
    mpg123_delete(self->mh);
    rej__:
    mp3_tag_cleanup(&self->taginfo);
    fclose(self->fp);
    rej_:
    free(self);
    rej:
    return REJECTED;
    }
Beispiel #30
0
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;
}