/**
Decodes given buffer of data to PCM
*/
jint Java_com_denisigo_netradioplayer_Decoder_decodeNative(JNIEnv* env, jobject thiz, jint handle,
                            jbyteArray in_buffer, jint size, jbyteArray out_buffer, jint max_size){
    jint ret;

    mpg123_handle* hnd = (mpg123_handle*) handle;
    jbyte* in_buf = (*env)->GetByteArrayElements(env, in_buffer, NULL);
    jbyte* out_buf = (*env)->GetByteArrayElements(env, out_buffer, NULL);

    size_t bytes_decoded;
    // Decode data
    ret = mpg123_decode(hnd, in_buf, size, out_buf, max_size, &bytes_decoded);
    LOG("Decoded %d bytes, ret: %d, max_size: %d", bytes_decoded, ret, max_size);

    // If status if OK, decoder decoded something
    if (ret == MPG123_OK){
        ret = bytes_decoded;
    }
    // This means decoder faced new stream. For us this means that there was sufficient data decoded
    // to determine stream's params and we can notify Java Decoder about it
    else if (ret == MPG123_NEW_FORMAT){
        long rate;
        int channels, encoding;
        // Get actual format params
        mpg123_getformat(hnd, &rate, &channels, &encoding);
        //LOG("mpg123_getformat: rate: %d channels: %d encoding: %d\n", rate, channels, encoding);

        // We support only 16 and 8 bits per sample
        if (encoding == MPG123_ENC_SIGNED_16)
            encoding = 16;
        else if (encoding == MPG123_ENC_SIGNED_8)
            encoding = 8;
        else
            encoding = -1;

        (*env)->CallVoidMethod(env, thiz, method_onNewFormatCallback, (jint)rate, (jint)channels,
                            (jint)encoding);

        ret = 0;
    }
    // This means mpg123 decoder needs more data to provide decoded data
    else if (ret == MPG123_NEED_MORE){
        ret = 0;
    }
    // Other cases usually means some errors
    else {
        // Ensure we will not return positive number which is normally indicating num of decoded bytes
        if (ret > 0)
            ret *= -1;
    }

    (*env)->ReleaseByteArrayElements(env, in_buffer, in_buf, 0);
    (*env)->ReleaseByteArrayElements(env, out_buffer, out_buf, 0);

    return ret;
}
Exemple #2
0
/* decode anything mpg123 can */
void decode_mpeg(VGMSTREAMCHANNEL *stream,
        mpeg_codec_data * data,
        sample * outbuf, int32_t samples_to_do, int channels) {
    int samples_done = 0;

    while (samples_done < samples_to_do) {
        size_t bytes_done;
        int rc;

        if (!data->buffer_full) {
            data->bytes_in_buffer = read_streamfile(data->buffer,
                    stream->offset,MPEG_BUFFER_SIZE,stream->streamfile);

            data->buffer_full = 1;
            data->buffer_used = 0;

            stream->offset += data->bytes_in_buffer;
        }

        if (!data->buffer_used) {
            rc = mpg123_decode(data->m,
                    data->buffer,data->bytes_in_buffer,
                    (unsigned char *)(outbuf+samples_done*channels),
                    (samples_to_do-samples_done)*sizeof(sample)*channels,
                    &bytes_done);
            data->buffer_used = 1;
        } else {
            rc = mpg123_decode(data->m,
                    NULL,0,
                    (unsigned char *)(outbuf+samples_done*channels),
                    (samples_to_do-samples_done)*sizeof(sample)*channels,
                    &bytes_done);
        }

        if (rc == MPG123_NEED_MORE) data->buffer_full = 0;

        samples_done += bytes_done/sizeof(sample)/channels;
    }
}
Exemple #3
0
QString InternetFormatSupport( const char* address )
{
	loadCURL();
	if ( !CURLloaded )
		return "";
	mpg123_handle *mus = mpg123_new(NULL, NULL);
	mpg123_open_feed( mus );
	URL_FILE *f = url_fopen( address );
	if ( !f )
	{
		unloadCURL();
		return "";
	}

	char *data;
	int _DATA_BUFF;
	if ( !getDataBuff( f, url_fread, _DATA_BUFF, &data ) )
	{
		url_fclose(f);
		unloadCURL();
		return "";
	}

	int bread = url_fread(data+10, 1, _DATA_BUFF-10, f);
	mpg123_decode( mus, (const unsigned char*)data, bread, 0,0,0 );
	bool loaded = getMusInfo( mus, 0,0,0,0,0, -1, "" );
	mpg123_close(mus);
	mpg123_delete(mus);
	delete[] data;
	url_fclose(f);
	unloadCURL();
	if ( loaded )
		return plugName;
	else
		return "";
}
Exemple #4
0
bool Reader::readSamples(int** dest, int destChannels, int destOffset,
        int64 startSampleInFile, int numSamples) {
 
    std::cout << "start sample in file: " << startSampleInFile << std::endl;

    unsigned char tmp_buf[numSamples];
    int r = AudioFormatReader::input->read(tmp_buf, numSamples);
    std::cout << "read " << r << " on " << numSamples << ", pos: " 
        << AudioFormatReader::input->getPosition()
        << ", remaining: " << AudioFormatReader::input->getNumBytesRemaining()
        << ", exhausted: " << AudioFormatReader::input->isExhausted()
        << std::endl;
    if (mpg123_seek(mh_, startSampleInFile, SEEK_SET) < 0) {
        std::cout << "couldn't seek -- returning" << std::endl;
        return false;
    }

    int64 bytesPerSample = this->bitsPerSample / 8;
    size_ = numSamples * numChannels * bytesPerSample;

    if (allocated_ < size_) {
        if (buffer_)
            free(buffer_);

        buffer_ = malloc(size_);
        allocated_ = size_;
    }

    size_t bytesCopied;
    Error e = mpg123_read(mh_, (uchar*) buffer_, size_, &bytesCopied);
    if (e != MPG123_DONE && e != MPG123_OK)
        return false;

    int64 sourceSize = bytesCopied / (bytesPerSample * numChannels);
    copier_(dest, destChannels, destOffset, buffer_, numChannels, sourceSize);
    return (bytesCopied == size_);

#if 0
    if (AudioFormatReader::input->getTotalLength()<0) { // infinite stream
        std::cout << " INFINITE STREAM" << std::endl;
        if (mpg123_seek(mh_, startSampleInFile, SEEK_SET) < 0) {
            std::cout << "couldn't seek in data!" << std::endl;
            return false;
        }

        InputStream *in = AudioFormatReader::input;

        int64 bytesPerSample = this->bitsPerSample / 8;
        size_ = numSamples * numChannels * bytesPerSample;
        unsigned char buf[numSamples], out[size_];

        size_t writtenBytes;
        size_t bytesCopied = 0;
        int ret;
        mpg123_param(mh_, MPG123_VERBOSE, 2, 0); 
        while(ret!=MPG123_ERR && ret!=MPG123_NEED_MORE) {
            std::cout << "looping..." << std::endl;
            int len = in->read(buf, numSamples);
            if(len<=0) {
                std::cout << "no more data to read!..." << std::endl;
                return false;
            }
            ret = mpg123_decode(mh_, buf, len, out, size_, &writtenBytes);
            bytesCopied+=writtenBytes;
            if(ret==MPG123_OK) {
                std::cout << "OK!" << std::endl;
                break;
            } else {
                std::cout << "returned: " << mpg123_strerror(mh_) << std::endl;
            }
        }

        for (int i=0;i<10;++i) {
            std::cout << "out " << i << " -> " << (int)out[i] << std::endl;
        }
        int64 sourceSize = bytesCopied / (bytesPerSample * numChannels);
        copier_(dest, destChannels, destOffset, out, numChannels, sourceSize);
        std::cout << "infinite bytesCopied: " << bytesCopied 
            << ", size_: " << size_
            << ", startSampleInFile: " << startSampleInFile
            << std::endl;
        return (bytesCopied == size_);

        /*
        unsigned char buf[numSamples];
        int len, num;
        unsigned char *audio;
        Error ret, state;
        size_t bytes;
        off_t inoffset;
        while((ret = mpg123_feedseek(mh_, numSamples, SEEK_SET, &inoffset)) == MPG123_NEED_MORE)
        {
            std::cout << "need more..." << std::endl;
            int len = AudioFormatReader::input->read(buf, numSamples);
            if(len <= 0)
                break;
            state = mpg123_feed(mh_, buf, len);
            if(state == MPG123_ERR)
            {
                std::cout << "Error: " << mpg123_strerror(mh_) << std::endl;
                return -1; 
            }
        }
        if(ret == MPG123_ERR)
        {
            std::cout << "Feedseek failed: " << mpg123_strerror(mh_) << std::endl;
            return false;
        } else {
            std::cout << "well, feedseek succeeded ???? " << inoffset << ", " << mpg123_strerror(mh_) << std::endl;
        }
        AudioFormatReader::input->setPosition(inoffset);

        len = AudioFormatReader::input->read(buf, numSamples);
        if(len <= 0) {
            std::cout << "no data read from stream" << std::endl;
            return false;
        }
        ret = mpg123_feed(mh_, buf, len);
        if(ret == MPG123_ERR)
        {
            std::cout << "feed failed: " << mpg123_strerror(mh_) << std::endl;
            return false;
        }
        */
    } else {
        if (mpg123_seek(mh_, startSampleInFile, SEEK_SET) < 0)
            return false;
    }

    int64 bytesPerSample = this->bitsPerSample / 8;
    size_ = numSamples * numChannels * bytesPerSample;

    if (allocated_ < size_) {
        if (buffer_)
            free(buffer_);

        buffer_ = malloc(size_);
        allocated_ = size_;
    }

    size_t bytesCopied;
    Error e = mpg123_read(mh_, (uchar*) buffer_, size_, &bytesCopied);
    if (e != MPG123_DONE && e != MPG123_OK) {
        std::cout << "can't read data: " << mpg123_strerror(mh_) << std::endl;
        return false;
    }

    int64 sourceSize = bytesCopied / (bytesPerSample * numChannels);
    copier_(dest, destChannels, destOffset, buffer_, numChannels, sourceSize);
    std::cout << "bytesCopied: " << bytesCopied 
        << ", size_: " << size_
        << ", startSampleInFile: " << startSampleInFile
        << std::endl;
    return (bytesCopied == size_);
#endif

}
Exemple #5
0
void play( const char *fileE, int )
{
	if ( Type != 0 && Type != 2 )
		return ERROR2( "Wtyczka obsługuje tylko odczyt plików i strumienia internetowego!" );

	if ( Type == 2 )
	{
		QString tmp = loadCURL();
		if ( !CURLloaded )
			return ERROR2( "Nie można załadować biblioteki: "+QMPInternetf+libExt+"\n"+tmp );
	}

	if ( fileE != curF )
		clrPos();

	clrSet();

	QString BLAD;
	if ( Type == 0 )
		BLAD = "Błąd odczytu pliku!";
	else if ( Type == 2 )
		BLAD = "Nie można otworzyć strumienia internetowego!";

	musicfile = mpg123_new(NULL, NULL);
	if ( Type == 0 )
	{
		fd = qmp_open( fileE, O_RDONLY|O_BINARY );
		mpg123_open_fd( musicfile, fd );
	}
	if ( Type == 2 )
	{
		title = "Czekaj, trwa otwieranie...";

		mpg123_open_feed( musicfile );

		f = url_fopen(fileE,0,1);
		if ( !f )
			return ERROR(BLAD);

		if ( !getDataBuff( f, url_fread, _DATA_BUFF, &data, &bolStop ) )
			return ERROR(BLAD);

		url_fread(data+10, 1, _DATA_BUFF-10, f);

		if ( getNetInfo( f, FILE_SIZE ) > 0.0 )
			knownSize = true;
		mpg123_decode( musicfile, (const unsigned char*)data, _DATA_BUFF, 0,0,0 );
	}

	if ( !musicfile )
		return ERROR(BLAD);

	curF = fileE;

	if ( !MP3Update() )
		return ERROR(BLAD);

	if ( Type == 2 && title.isEmpty() )
		title = fileE;

	if ( Type == 2 || ( Type == 0 && fileE[0] == '/' && fileE[1] == '/' ) )
		QOut->useQMPBuffer();
	QOut->Init( AudioInfo( rate, 16, chn ), true, 0, fileE, /*title*/Title );

	if ( *QOut->PlErr )
	{
		*QOut->PlErr = false;
		return ERROR("Błąd zwraca wtyczka wyjściowa!");
	}

	IsPlaying = true;
	size_t bDecoded = 0;
	audio_buffer = new char[BUF_SIZE];
	TMPint = 0;
	int musErr = 0;
	for(;;)
	{
		if ( bolStop )
			break;
		if ( !IsPaused )
		{
			if ( !*QOut->mustReset )
			{
				if ( doSeek )
				{
					mpg123_seek( musicfile, doSeek, SEEK_SET );
					QOut->control( QOUT_NEXT_READ );
					doSeek = 0;
				}

				musErr = mpg123_read( musicfile, (unsigned char*)audio_buffer, BUF_SIZE, &bDecoded );
				if ( musErr == MPG123_DONE )
					break;
				if ( musErr == MPG123_ERR && !searchParts )
					break;
				QOut->Play( audio_buffer, bDecoded, pltime, false );
				MP3Update2( bDecoded );
				if ( musErr == MPG123_NEED_MORE && Type != 0 )
				{
					int bread = url_fread( data, 1, _DATA_BUFF, f );
					if ( ( !bread && !wait4Data ) || ( !bread && url_feof(f) ) )
						break;
					else if ( !bread )
						MYsleep( 25 );
					mpg123_decode( musicfile, (const unsigned char*)data, bread, NULL, 0, NULL );
				}
			}
			else
				QOut->Play(0,0,pltime,true);
		}
		else
			QOut->Play(0,0,pltime,true);
	}
	STOP();
}
Exemple #6
0
static int MP3_open(FILE* fp, struct amci_file_desc_t* fmt_desc, int options, long h_codec)
{

#ifdef WITH_MPG123DECODER
  unsigned char mp_rd_buf[20]; 
  size_t sr, decoded_size;
  mp3_coder_state* coder_state;
  int res;
  DBG("mp3_open.\n");
#endif

   if(options == AMCI_RDONLY){
#ifndef WITH_MPG123DECODER
    ERROR("MP3 decoding support not compiled in.\n");
    return -1;
#else
     if (!h_codec) {
       ERROR("mp3 decoder not initialized!\n");
       return -1;
     }
     coder_state = (mp3_coder_state*)h_codec;
     
     DBG("Initializing mpg123 codec state.\n");
     res = mpg123_open_feed(coder_state->mpg123_h);
     if (MPG123_ERR == res) {
       ERROR("mpg123_open_feed returned mpg123 error '%s'\n", 
	     mpg123_strerror(coder_state->mpg123_h));
       return -1;
     }

     /* read until we know the format */
     while (res!= MPG123_NEW_FORMAT) {
       SAFE_READ(mp_rd_buf, 20, fp, sr);

       res = mpg123_decode(coder_state->mpg123_h, mp_rd_buf, 20, 
			   mp_rd_buf, 0, &decoded_size);
       if (res == MPG123_ERR) {
	 ERROR("trying to determine MP3 file format: '%s'\n", 
	       mpg123_strerror(coder_state->mpg123_h));
	 return -1;
       }
     }
          
     mpg123_getformat(coder_state->mpg123_h, 
		      &coder_state->rate, &coder_state->channels, &coder_state->enc);

     DBG("mpg123: New format: %li Hz, %i channels, encoding value %i\n", 
	 coder_state->rate, coder_state->channels, coder_state->enc);

     fmt_desc->subtype   = 1; // ?
     fmt_desc->rate      = coder_state->rate;
     fmt_desc->channels  = coder_state->channels;
     fmt_desc->data_size = -1;

     /* set buffering parameters */
     fmt_desc->buffer_size   = MP3_FRAMESAMPLES * 8;
     fmt_desc->buffer_thresh = MP3_FRAMESAMPLES;
     fmt_desc->buffer_full_thresh = MP3_FRAMESAMPLES * 3; 

     return 0;
#endif
   }  
   return 0;
}
Exemple #7
0
/* mono, mpg123 expects frames of 0x414 (160kbps, 22050Hz) but they
 * actually vary and are much shorter */
void decode_fake_mpeg2_l2(VGMSTREAMCHANNEL *stream,
        mpeg_codec_data * data,
        sample * outbuf, int32_t samples_to_do) {
    int samples_done = 0;

    while (samples_done < samples_to_do) {
        size_t bytes_done;
        int rc;

        if (!data->buffer_full) {
            /* fill buffer up to next frame ending (or file ending) */
            int bytes_into_header = 0;
            const uint8_t header[4] = {0xff,0xf5,0xe0,0xc0};
            off_t frame_offset = 0;

            /* assume that we are starting at a header, skip it and look for the
             * next one */
            read_streamfile(data->buffer, stream->offset+frame_offset, 4,
                    stream->streamfile);
            frame_offset += 4;

            do {
                uint8_t byte;
                byte =
                    read_8bit(stream->offset+frame_offset,stream->streamfile);
                data->buffer[frame_offset] = byte;
                frame_offset++;

                if (byte == header[bytes_into_header]) {
                    bytes_into_header++;
                } else {
                    /* This might have been the first byte of the header, so
                     * we need to check again.
                     * No need to get more complicated than this, though, since
                     * there are no repeated characters in the search string. */
                    if (bytes_into_header>0) {
                        frame_offset--;
                    }
                    bytes_into_header=0;
                }

                if (bytes_into_header==4) {
                    break;
                }
            } while (frame_offset < AHX_EXPECTED_FRAME_SIZE);

            if (bytes_into_header==4) frame_offset-=4;
            memset(data->buffer+frame_offset,0,
                    AHX_EXPECTED_FRAME_SIZE-frame_offset);

            data->buffer_full = 1;
            data->buffer_used = 0;

            stream->offset += frame_offset;
        }

        if (!data->buffer_used) {
            rc = mpg123_decode(data->m,
                    data->buffer,AHX_EXPECTED_FRAME_SIZE,
                    (unsigned char *)(outbuf+samples_done),
                    (samples_to_do-samples_done)*sizeof(sample),
                    &bytes_done);
            data->buffer_used = 1;
        } else {
            rc = mpg123_decode(data->m,
                    NULL,0,
                    (unsigned char *)(outbuf+samples_done),
                    (samples_to_do-samples_done)*sizeof(sample),
                    &bytes_done);
        }

        if (rc == MPG123_NEED_MORE) data->buffer_full = 0;

        samples_done += bytes_done/sizeof(sample);
    }
}
Exemple #8
0
/* This tries to extract a requested amount of decoded data.
 * Even when you request 0 bytes, it will feed enough input so that
 * the decoder _could_ have delivered something.
 * Returns byte count >= 0, -1 on error.
 *
 * Thoughts on exact pts keeping:
 * We have to assume that MPEG frames are cut in pieces by packet boundaries.
 * Also, it might be possible that the first packet does not contain enough
 * data to ensure initial stream sync... or re-sync on erroneous streams.
 * So we need something robust to relate the decoded byte count to the correct
 * time stamp. This is tricky, though. From the outside, you cannot tell if,
 * after having fed two packets until the first output arrives, one should
 * start counting from the first packet's pts or the second packet's.
 * So, let's just count from the last fed package's pts. If the packets are
 * exactly cut to MPEG frames, this will cause one frame mismatch in the
 * beginning (when mpg123 peeks ahead for the following header), but will
 * be corrected with the third frame already. One might add special code to
 * not increment the base pts past the first packet's after a resync before
 * the first decoded bytes arrived. */
static int decode_a_bit(sh_audio_t *sh, unsigned char *buf, int count)
{
    int ret = MPG123_OK;
    int got = 0;
    struct ad_mpg123_context *con = sh->context;

    /* There will be one MPG123_NEW_FORMAT message on first open.
     * This will be handled in init(). */
    do {
        size_t got_now = 0;

        /* Feed the decoder. This will only fire from the second round on. */
        if (ret == MPG123_NEED_MORE) {
            int incount;
            double pts;
            unsigned char *inbuf;
            /* Feed more input data. */
            incount = ds_get_packet_pts(sh->ds, &inbuf, &pts);
            if (incount <= 0)
                break;          /* Apparently that's it. EOF. */

            /* Next bytes from that presentation time. */
            if (pts != MP_NOPTS_VALUE) {
                sh->pts       = pts;
                sh->pts_bytes = 0;
            }

#ifdef AD_MPG123_FRAMEWISE
            /* Have to use mpg123_feed() to avoid decoding here. */
            ret = mpg123_feed(con->handle, inbuf, incount);
#else
            /* Do not use mpg123_feed(), added in later libmpg123 versions. */
            ret = mpg123_decode(con->handle, inbuf, incount, NULL, 0, NULL);
#endif
            if (ret == MPG123_ERR)
                break;
        }
        /* Theoretically, mpg123 could return MPG123_DONE, so be prepared.
         * Should not happen in our usage, but it is a valid return code. */
        else if (ret == MPG123_ERR || ret == MPG123_DONE)
            break;

        /* Try to decode a bit. This is the return value that counts
         * for the loop condition. */
#ifdef AD_MPG123_FRAMEWISE
        if (!buf) { /* fake call just for feeding to get format */
            ret = mpg123_getformat(con->handle, NULL, NULL, NULL);
        } else { /* This is the decoding. One frame at a time. */
            ret = mpg123_replace_buffer(con->handle, buf, count);
            if (ret == MPG123_OK)
                ret = mpg123_decode_frame(con->handle, NULL, NULL, &got_now);
        }
#else
        ret = mpg123_decode(con->handle, NULL, 0, buf + got, count - got,
                            &got_now);
#endif

        got += got_now;
        sh->pts_bytes += got_now;

#ifdef AD_MPG123_FRAMEWISE
    } while (ret == MPG123_NEED_MORE || (got == 0 && count != 0));
#else
    } while (ret == MPG123_NEED_MORE || got < count);
Exemple #9
0
VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
    
	VGMSTREAM * vgmstream = NULL;
    
	int32_t channel_count;
    int32_t interleave;
    int32_t sample_rate;
    int32_t loop_start;
    int32_t loop_end;
    int32_t start_offset;
    int32_t header_size;
	int32_t coef[2];
	int32_t dsp_interleave_type;
	
    char filename[260];
    int coding;
#ifdef VGM_USE_MPEG
    mpeg_codec_data *data = NULL;
#endif

    /* check extension, case insensitive */
    streamFile->get_name(streamFile,filename,sizeof(filename));
    if (strcasecmp("genh",filename_extension(filename))) goto fail;

    /* check header magic */
    if (read_32bitBE(0x0,streamFile) != 0x47454e48) goto fail;

    /* check channel count (needed for ADP/DTK check) */
    channel_count = read_32bitLE(0x4,streamFile);
    if (channel_count < 1) goto fail;

    /* check format */
    /* 0 = PSX ADPCM */
    /* 1 = XBOX IMA ADPCM */
    /* 2 = NGC ADP/DTK ADPCM */
    /* 3 = 16bit big endian PCM */
    /* 4 = 16bit little endian PCM */
    /* 5 = 8bit PCM */
    /* 6 = SDX2 */
    /* 7 = DVI IMA */
    /* 8 = MPEG-1 Layer III, possibly also the MPEG-2 and 2.5 extensions */
    /* 9 = IMA */
    /* 10 = AICA ADPCM */
    /* 11 = MS ADPCM */
    /* 12 = NGC DSP */
    /* 13 = 8bit unsingned PCM */
	/* 14 = PSX ADPCM (bad flagged) */
    /* ... others to come */
    switch (read_32bitLE(0x18,streamFile)) {
        case 0:
            coding = coding_PSX;
            break;
        case 1:
            coding = coding_XBOX;
            break;
        case 2:
            coding = coding_NGC_DTK;
            if (channel_count != 2) goto fail;
            break;
        case 3:
            coding = coding_PCM16BE;
            break;
        case 4:
            coding = coding_PCM16LE;
            break;
        case 5:
            coding = coding_PCM8;
            break;
        case 6:
            coding = coding_SDX2;
            break;
        case 7:
            coding = coding_DVI_IMA;
            break;
#ifdef VGM_USE_MPEG
        case 8:
            /* we say MPEG-1 L3 here, but later find out exactly which */
            coding = coding_MPEG1_L3;
            break;
#endif
        case 9:
            coding = coding_IMA;
            break;
        case 10:
            coding = coding_AICA;
            break;
        case 11:
            coding = coding_MSADPCM;
            break;
        case 12:
            coding = coding_NGC_DSP;
            break;
		case 13:
            coding = coding_PCM8_U_int;
            break;
		case 14:
            coding = coding_PSX_badflags;
            break;
        default:
            goto fail;
    }

    start_offset = read_32bitLE(0x1C,streamFile);
    header_size = read_32bitLE(0x20,streamFile);

    /* HACK to support old genh */
    if (header_size == 0) {
        start_offset = 0x800;
        header_size = 0x800;
    }

    /* check for audio data start past header end */
    if (header_size > start_offset) goto fail;

    interleave = read_32bitLE(0x8,streamFile);
    sample_rate = read_32bitLE(0xc,streamFile);
    loop_start = read_32bitLE(0x10,streamFile);
    loop_end = read_32bitLE(0x14,streamFile);
	
	coef[0] = read_32bitLE(0x24,streamFile);
	coef[1] = read_32bitLE(0x28,streamFile);
	dsp_interleave_type = read_32bitLE(0x2C,streamFile);

    //if (coding == coding_XBOX && channel_count != 2) goto fail;

    /* build the VGMSTREAM */
    vgmstream = allocate_vgmstream(channel_count,(loop_start!=-1));
    if (!vgmstream) goto fail;

    /* fill in the vital information */

    vgmstream->channels = channel_count;
    vgmstream->sample_rate = sample_rate;
    vgmstream->num_samples = loop_end;
    vgmstream->loop_start_sample = loop_start;
    vgmstream->loop_end_sample = loop_end;
    vgmstream->loop_flag = (loop_start != -1);

    switch (coding) {
        case coding_PCM8_U_int:
			vgmstream->layout_type=layout_none;
			break;
		case coding_PCM16LE:
        case coding_PCM16BE:
        case coding_PCM8:
        case coding_SDX2:
        case coding_PSX:
		case coding_PSX_badflags:
        case coding_DVI_IMA:
        case coding_IMA:
        case coding_AICA:
            vgmstream->interleave_block_size = interleave;
            if (channel_count > 1)
            {
                if (coding == coding_SDX2) {
                    coding = coding_SDX2_int;
                    vgmstream->coding_type = coding_SDX2_int;
                }
				if(vgmstream->interleave_block_size==0xffffffff)
					vgmstream->layout_type=layout_none;
				else {
					vgmstream->layout_type = layout_interleave;
					if(coding==coding_DVI_IMA)
						coding=coding_INT_DVI_IMA;
					if(coding==coding_IMA)
						coding=coding_INT_IMA;
				}
            } else {
                vgmstream->layout_type = layout_none;
            }
            break;
        case coding_MSADPCM:
            if (channel_count != 2) goto fail;
            vgmstream->interleave_block_size = interleave;
            vgmstream->layout_type = layout_none;
            break;
        case coding_XBOX:
            vgmstream->layout_type = layout_none;
            break;
        case coding_NGC_DTK:
            vgmstream->layout_type = layout_dtk_interleave;
            break;
        case coding_NGC_DSP:
        	if (dsp_interleave_type == 0) {
				vgmstream->layout_type = layout_interleave;
            	vgmstream->interleave_block_size = interleave;
			} else if (dsp_interleave_type == 1) {
        		vgmstream->layout_type = layout_interleave_byte;
            	vgmstream->interleave_block_size = interleave;
			} else if (dsp_interleave_type == 2) {
            	vgmstream->layout_type = layout_none;
			}
			break;
            
#ifdef VGM_USE_MPEG
        case coding_MPEG1_L3:
            vgmstream->layout_type = layout_mpeg;
            break;
#endif
    }
    
	vgmstream->coding_type = coding;
	vgmstream->meta_type = meta_GENH;
    
    /* open the file for reading by each channel */
    {
        int i;
		int j;

        STREAMFILE * chstreamfile = NULL;

        for (i=0;i<channel_count;i++) {
            off_t chstart_offset = start_offset;

            switch (coding) {
                case coding_PSX:
				case coding_PSX_badflags:
                case coding_PCM16BE:
                case coding_PCM16LE:
                case coding_SDX2:
                case coding_SDX2_int:
                case coding_DVI_IMA:
                case coding_IMA:
                case coding_PCM8:
                case coding_PCM8_U_int:
                case coding_AICA:
				case coding_INT_DVI_IMA:
				case coding_INT_IMA:
                    if (vgmstream->layout_type == layout_interleave) {
                        if (interleave >= 512) {
                            chstreamfile =
                                streamFile->open(streamFile,filename,interleave);
                        } else {
                            if (!chstreamfile)
                                chstreamfile =
                                    streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
                        }
                        chstart_offset =
                            start_offset+vgmstream->interleave_block_size*i;
                    } else {
                        chstreamfile =
                            streamFile->open(streamFile,filename,
                                    STREAMFILE_DEFAULT_BUFFER_SIZE);
                    }
                    break;
                case coding_XBOX:
                case coding_MSADPCM:
                    /* xbox's "interleave" is a lie, all channels start at same
                     * offset */
                    chstreamfile =
                        streamFile->open(streamFile,filename,
                                STREAMFILE_DEFAULT_BUFFER_SIZE);
                    break;
                case coding_NGC_DTK:
                    if (!chstreamfile) 
                        chstreamfile =
                            streamFile->open(streamFile,filename,32*0x400);
                    break;
                case coding_NGC_DSP:
                    if (!chstreamfile) 
                        chstreamfile =
                            streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);

					for (j=0;j<16;j++) 
            			vgmstream->ch[i].adpcm_coef[j] = read_16bitBE(coef[i]+j*2,streamFile);
							chstart_offset =start_offset+vgmstream->interleave_block_size*i;
					break;

#ifdef VGM_USE_MPEG
                case coding_MPEG1_L3:
                    if (!chstreamfile)
                        chstreamfile =
                            streamFile->open(streamFile,filename,MPEG_BUFFER_SIZE);
                    break;
#endif
            }

            if (!chstreamfile) goto fail;

            vgmstream->ch[i].streamfile = chstreamfile;

            vgmstream->ch[i].channel_start_offset=
                vgmstream->ch[i].offset=chstart_offset;
        }
    }

#ifdef VGM_USE_MPEG
    if (coding == coding_MPEG1_L3) {
        int rc;
        off_t read_offset;
        data = calloc(1,sizeof(mpeg_codec_data));
        if (!data) goto mpeg_fail;

        data->m = mpg123_new(NULL,&rc);
        if (rc==MPG123_NOT_INITIALIZED) {
            if (mpg123_init()!=MPG123_OK) goto mpeg_fail;
            data->m = mpg123_new(NULL,&rc);
            if (rc!=MPG123_OK) goto mpeg_fail;
        } else if (rc!=MPG123_OK) {
            goto mpeg_fail;
        }

        mpg123_param(data->m,MPG123_REMOVE_FLAGS,MPG123_GAPLESS,0.0);

        if (mpg123_open_feed(data->m)!=MPG123_OK) {
            goto mpeg_fail;
        }

        /* check format */
        read_offset=0;
        do {
            size_t bytes_done;
            if (read_streamfile(data->buffer, start_offset+read_offset,
                    MPEG_BUFFER_SIZE,vgmstream->ch[0].streamfile) !=
                    MPEG_BUFFER_SIZE) goto mpeg_fail;
            read_offset+=1;
            rc = mpg123_decode(data->m,data->buffer,MPEG_BUFFER_SIZE,
                    NULL,0,&bytes_done);
            if (rc != MPG123_OK && rc != MPG123_NEW_FORMAT &&
                    rc != MPG123_NEED_MORE) goto mpeg_fail;
        } while (rc != MPG123_NEW_FORMAT);

        {
            long rate;
            int channels,encoding;
            struct mpg123_frameinfo mi;
            rc = mpg123_getformat(data->m,&rate,&channels,&encoding);
            if (rc != MPG123_OK) goto mpeg_fail;
            if (rate != vgmstream->sample_rate ||
                    channels != vgmstream->channels ||
                    encoding != MPG123_ENC_SIGNED_16) goto mpeg_fail;
            mpg123_info(data->m,&mi);
            if (mi.rate != vgmstream->sample_rate) goto mpeg_fail;
            if (mi.version == MPG123_1_0 && mi.layer == 1)
                vgmstream->coding_type = coding_MPEG1_L1;
            else if (mi.version == MPG123_1_0 && mi.layer == 2)
                vgmstream->coding_type = coding_MPEG1_L2;
            else if (mi.version == MPG123_1_0 && mi.layer == 3)
                vgmstream->coding_type = coding_MPEG1_L3;
            else if (mi.version == MPG123_2_0 && mi.layer == 1)
                vgmstream->coding_type = coding_MPEG2_L1;
            else if (mi.version == MPG123_2_0 && mi.layer == 2)
                vgmstream->coding_type = coding_MPEG2_L2;
            else if (mi.version == MPG123_2_0 && mi.layer == 3)
                vgmstream->coding_type = coding_MPEG2_L3;
            else if (mi.version == MPG123_2_5 && mi.layer == 1)
                vgmstream->coding_type = coding_MPEG25_L1;
            else if (mi.version == MPG123_2_5 && mi.layer == 2)
                vgmstream->coding_type = coding_MPEG25_L2;
            else if (mi.version == MPG123_2_5 && mi.layer == 3)
                vgmstream->coding_type = coding_MPEG25_L3;
            else goto mpeg_fail;
        }

        /* reinit, to ignore the reading we've done so far */
        mpg123_open_feed(data->m);

        vgmstream->codec_data = data;
    }
#endif

    return vgmstream;

    /* clean up anything we may have opened */
#ifdef VGM_USE_MPEG
mpeg_fail:
    if (data) {
        mpg123_delete(data->m);
        free(data);
    }
#endif
fail:
    if (vgmstream) close_vgmstream(vgmstream);
    return NULL;
}
Exemple #10
0
bool nuiAudioDecoder::ReadInfo()
{
    if (!mpPrivate)
    {
        return false;
    }

    int err;

    int read;
    int toread = DECODER_INPUT_SIZE;
    unsigned char* pInput = new unsigned char[toread];
    do
    {
        read = mrStream.ReadUInt8(pInput, toread);

        size_t done = 0;
        err = mpg123_decode(mpPrivate->mpHandle, pInput, read, NULL, 0, &done);
//    err = mpg123_feed(mpPrivate->mpHandle, pInput, read);
    } while (err != MPG123_NEW_FORMAT && read > 0);

    mpg123_frameinfo frameinfo;
    err = mpg123_info(mpPrivate->mpHandle, &frameinfo);
    if (err != MPG123_OK)
    {
        return false;
    }

    int channels;
    if (frameinfo.mode == MPG123_M_MONO)
        channels = 1;
    else
        channels = 2;

    double samplerate = 44100;
    int encoding = MPG123_ENC_SIGNED_16;

    int supportedChannelConfig = mpg123_format_support(mpPrivate->mpHandle, samplerate, encoding);
    if (supportedChannelConfig == 0)
    {
        return false;
    }

    int channelConfig;
    bool mono = (supportedChannelConfig & MPG123_MONO) && (channels == 1);
    bool stereo = (supportedChannelConfig & MPG123_STEREO) && (channels == 2);
    if (mono)
        channelConfig = MPG123_MONO;
    else if (stereo)
        channelConfig = MPG123_STEREO;
    else
    {
        return false;
    }

    mpg123_format_none(mpPrivate->mpHandle);

    err = mpg123_format(mpPrivate->mpHandle, samplerate, channelConfig, encoding);
    if (err != MPG123_OK)
    {
        return false;
    }

    off_t sampleframes = mpg123_length(mpPrivate->mpHandle);
    if (sampleframes <= 0)
    {
        int bitrate = frameinfo.bitrate;
        nglFileSize streamSize = mrStream.Available();
        sampleframes = (streamSize / (bitrate * 1000.f  / 8.f)) * samplerate;
    }

    int BitsPerSample;
    if (encoding == MPG123_ENC_FLOAT_32)
        BitsPerSample = 32;
    else if (encoding == MPG123_ENC_SIGNED_16)
        BitsPerSample = 16;
    else
    {
        return false;
    }

    mInfo.SetSampleFrames(sampleframes);
    mInfo.SetSampleRate(samplerate);
    mInfo.SetChannels(channels);
    mInfo.SetBitsPerSample(BitsPerSample);
    mInfo.SetFileFormat(eAudioCompressed);
    mInfo.SetStartFrame(0);
    mInfo.SetStopFrame(mInfo.GetSampleFrames());

    return true;
}
Exemple #11
0
int mpa_decode_frm(struct audec_state *ads,
		   int fmt, void *sampv_void, size_t *sampc,
		    const uint8_t *buf, size_t len)
{
	int result, channels, encoding, i;
	long samplerate;
	size_t n;
	spx_uint32_t intermediate_len;
	spx_uint32_t out_len;
	int16_t *sampv = sampv_void;

#ifdef DEBUG
	debug("MPA dec start %d %ld\n",len, *sampc);
#endif

	if (!ads || !sampv || !sampc || !buf || len<=4)
		return EINVAL;

	if (*(uint32_t*)(void *)buf != 0) {
		warning("MPA dec header is not zero %08X, not supported yet\n",
			*(uint32_t*)(void *)buf);
		return EPROTO;
	}

	if (fmt != AUFMT_S16LE)
		return ENOTSUP;

	n = 0;
	result = mpg123_decode(ads->dec, buf+4, len-4,
				(unsigned char*)ads->intermediate_buffer,
				sizeof(ads->intermediate_buffer), &n);
				/* n counts bytes */
#ifdef DEBUG
	debug("MPA dec %d %d %d %d\n",result, len-4, n, ads->channels);
#endif

	if (result == MPG123_NEW_FORMAT) {
		mpg123_getformat(ads->dec, &samplerate, &channels, &encoding);
		info("MPA dec format change %d %d %04X\n",samplerate
			,channels,encoding);

		ads->channels = channels;
		ads->start = 0;
		if (ads->resampler)
			speex_resampler_destroy(ads->resampler);
		if (samplerate != MPA_IORATE) {
			ads->resampler = speex_resampler_init(channels,
				      (uint32_t)samplerate, MPA_IORATE,
				      3, &result);
			if (result!=RESAMPLER_ERR_SUCCESS
				|| ads->resampler==NULL) {
				warning("MPA dec upsampler failed %d\n",
					result);
				return EINVAL;
			}
		}
		else
			ads->resampler = NULL;
	}
	else if (result == MPG123_NEED_MORE)
		;			/* workaround: do nothing */
	else if (result != MPG123_OK) {
		warning("MPA dec feed error %d %s\n", result,
			mpg123_plain_strerror(result));
		return EPROTO;
	}

	if (ads->resampler)  {
		intermediate_len = (uint32_t)(n / 2 / ads->channels);
			/* intermediate_len counts samples per channel */
		out_len = (uint32_t)(*sampc / 2);

		result=speex_resampler_process_interleaved_int(
			ads->resampler, ads->intermediate_buffer,
			&intermediate_len, sampv, &out_len);
		if (result!=RESAMPLER_ERR_SUCCESS) {
			warning("MPA dec upsample error: %s %d %d\n",
				strerror(result), out_len, *sampc/2);
			return EPROTO;
		}
		if (ads->channels==1) {
			for (i=out_len-1;i>=0;i--)
				sampv[i+i+1]=sampv[i+i]=sampv[i];
			*sampc = out_len * 2;
		}
		else
			*sampc = out_len * ads->channels;
	}
	else {
		n /= 2;
		if (ads->channels!=1) {
			for (i=0;(unsigned)i<n;i++)
				sampv[i]=ads->intermediate_buffer[i];
			*sampc = n;
		}
		else {
			for (i=0;(unsigned)i<n;i++)
				sampv[i*2]=sampv[i*2+1]=
					ads->intermediate_buffer[i];
			*sampc = n * 2;
	}

#ifdef DEBUG
	debug("MPA dec done %d\n",*sampc);
#endif
	}

	return 0;
}
Exemple #12
0
/* This callback is called each time the sndstream driver needs
   some more data. It will tell us how much it needs in bytes. */
static void* mpg123_callback(snd_stream_hnd_t hnd, int size, int * actual) {
	//static	int frames = 0;
	size_t done = 0;
	int err = 0;

#ifdef BS_SIZE
	/* Check for file not started or file finished */
	if (mp3_fd == 0)
		return NULL;
#endif

	/* Dump the last PCM packet */
	pcm_empty(pcm_discard);

	/* Loop decoding until we have a full buffer */
	while (pcm_count < size) {
		
#ifdef BS_SIZE		
		/* Pull in some more data (and check for EOF) */
		
		if (bs_fill() < 0 || bs_count < decinfo.framesize) {
			printf("snd_mp3_server: Decode completed\r\n");
			goto errorout;
		}
		err = mpg123_decode(mh, bs_ptr, decinfo.framesize, pcm_ptr, size, &done); 
#else
		err = mpg123_read(mh, pcm_ptr, size, &done);
#endif

		switch(err) {
			case MPG123_DONE:
				printf("snd_mp3_server: Decode completed\r\n");
				goto errorout;
			case MPG123_NEED_MORE:
				printf("snd_mp3_server: MPG123_NEED_MORE\n");
				break;
			case MPG123_ERR:
				printf("snd_mp3_server: %s\n", (char*)mpg123_strerror(mh));
				goto errorout;
				break;
			default:
				break;
		}
		
#ifdef BS_SIZE
		bs_ptr += decinfo.framesize; bs_count -= decinfo.framesize;
#endif
		pcm_ptr += done; pcm_count += done;
		
		//frames++;
		//if (!(frames % 64)) {
			//printf("Decoded %d frames    \r", frames);
		//}
	}

	pcm_discard = *actual = size;

	/* Got it successfully */
	return pcm_buffer;

errorout:
#ifdef BS_SIZE
	fs_close(mp3_fd); mp3_fd = 0;
#endif
	return NULL;
}
Exemple #13
0
static gboolean
xmms_mpg123_init (xmms_xform_t *xform)
{
	xmms_mpg123_data_t *data;
	const long *rates;
	size_t num_rates;
	int encoding;
	off_t length;
	int i, result;

	g_return_val_if_fail (xform, FALSE);

	data = g_new0 (xmms_mpg123_data_t, 1);
	xmms_xform_private_data_set (xform, data);

	/* Get the total size of this stream and store it for later */
	if (xmms_xform_metadata_get_int (xform,
	                                 XMMS_MEDIALIB_ENTRY_PROPERTY_SIZE,
	                                 &result)) {
		data->filesize = result;
	}

	mpg123_rates (&rates, &num_rates);

	data->param = mpg123_new_pars (&result);
	g_return_val_if_fail (data->param, FALSE);

	/* Create a quiet (stderr) decoder with auto choosen optimization.
	 * Stuff set here should be tunable via plugin config properties!
	 * You can also change some things during playback...
	 */
	mpg123_par (data->param, MPG123_ADD_FLAGS, MPG123_QUIET, 0);
	mpg123_par (data->param, MPG123_ADD_FLAGS, MPG123_GAPLESS, 0);
	/* choose: MPG123_RVA_OFF, MPG123_RVA_MIX, MPG123_RVA_ALBUM
	 * xmms2 has its own ReplayGain plugin to handle the RVA field */
	mpg123_par (data->param, MPG123_RVA, MPG123_RVA_OFF, 0);

	/* You could choose a decoder from the list provided by
	 * mpg123_supported_decoders () and give that as second parameter.
	 */
	data->decoder = mpg123_parnew (data->param, NULL, &result);
	if (data->decoder == NULL) {
		xmms_log_error ("%s", mpg123_plain_strerror (result));
		goto bad;
	}

	/* Prepare for buffer input feeding. */
	result = mpg123_open_feed (data->decoder);
	if (result != MPG123_OK) {
		goto mpg123_bad;
	}

	/* Let's always decode to signed 16bit for a start.
	   Any mpg123-supported sample rate is accepted. */
	if (MPG123_OK != mpg123_format_none (data->decoder)) {
		goto mpg123_bad;
	}

	for (i = 0; i < num_rates; i++) {
		result = mpg123_format (data->decoder, rates[i],
		                        MPG123_MONO | MPG123_STEREO,
		                        MPG123_ENC_SIGNED_16);
		if (result != MPG123_OK) {
			goto mpg123_bad;
		}
	}

	/* Fetch ID3v1 data from the end of file if possible */
	result = xmms_id3v1_get_tags (xform);
	if (result < 0) {
		xmms_log_error ("Seeking error when reading ID3v1 tags");
		goto bad;
	} else if (data->filesize > result) {
		/* Reduce the size of tag data from the filesize */
		data->filesize -= result;
	}

	/* Read data from input until decoded data is available from decoder */
	do {
		/* Parse stream and get info. */
		gint ret;
		xmms_error_t err;

		ret = xmms_xform_read (xform, data->buf, BUFSIZE, &err);
		if (ret < 0) {
			xmms_log_error ("Error when trying to find beginning of stream");
			goto bad;
		} else if (ret == 0) {
			/* EOF reached before format was found, handled after loop */
			break;
		}

		/* With zero output size nothing is actually outputted */
		result = mpg123_decode (data->decoder, data->buf,
		                        (size_t) ret, NULL, 0, NULL);
	} while (result == MPG123_NEED_MORE); /* Keep feeding... */

	if (result != MPG123_NEW_FORMAT) {
		xmms_log_error ("Unable to find beginning of stream (%s)!",
		                result == MPG123_ERR ? mpg123_strerror (data->decoder)
		                : "unexpected EOF");
		goto bad;
	}

	result = mpg123_getformat (data->decoder, &data->samplerate,
	                           &data->channels, &encoding);
	if (result != MPG123_OK) {
		goto mpg123_bad;
	}

	/* Set the filesize so it can be used for duration estimation */
	if (data->filesize > 0) {
		mpg123_set_filesize (data->decoder, data->filesize);
	}

	/* Get duration in samples, convert to ms and save to xmms2 */
	length = mpg123_length (data->decoder);
	if (length > 0 &&
	    !xmms_xform_metadata_get_int (xform,
		                              XMMS_MEDIALIB_ENTRY_PROPERTY_DURATION,
		                              &i)) {
		length = (off_t) ((gfloat) length / data->samplerate * 1000);
		xmms_xform_metadata_set_int (xform,
		                             XMMS_MEDIALIB_ENTRY_PROPERTY_DURATION,
		                             (gint) length);
	}

	XMMS_DBG ("mpg123: got stream with %li Hz %i channels, encoding %i",
	          data->samplerate, data->channels, encoding);

	xmms_xform_outdata_type_add (xform,
	                             XMMS_STREAM_TYPE_MIMETYPE,
	                             "audio/pcm",
	                             XMMS_STREAM_TYPE_FMT_FORMAT,
	                             XMMS_SAMPLE_FORMAT_S16,
	                             XMMS_STREAM_TYPE_FMT_CHANNELS,
	                             data->channels,
	                             XMMS_STREAM_TYPE_FMT_SAMPLERATE,
	                             (gint) data->samplerate,
	                             XMMS_STREAM_TYPE_END);
	return TRUE;

mpg123_bad:
	xmms_log_error ("mpg123 error: %s", mpg123_strerror (data->decoder));

bad:
	mpg123_delete (data->decoder);
	mpg123_delete_pars (data->param);
	g_free (data);

	return FALSE;
}
Exemple #14
0
int _tmain(int argc, _TCHAR* argv[])
{
    mpg123_handle *m;
    int i;
    if (argc < 3)
    {
        fprintf(stderr, "\nI will give you the estimated and exact sample lengths of MPEG audio files.\n");
        fprintf(stderr, "\nUsage: %s <mpeg audio file list>\n\n", argv[0]);
        return -1;
    }
    mpg123_init();
    m = mpg123_new(NULL, NULL);
    mpg123_param(m, MPG123_RESYNC_LIMIT, -1, 0); /* New in library version 0.0.1 . */

    off_t a, b;
    if (MPG123_OK != mpg123_open_feed(m)) {
        fprintf(stderr, "open feed failed");
        return -1;
    }

    FILE* file = _tfopen(argv[1], TEXT("rb"));
    if (!file) {
        fprintf(stderr, "open file failed");
        return -1;
    }

    _stat64i32 st = { 0 };
    _tstat(argv[1], &st);
    if (st.st_size <= 0) {
        fprintf(stderr, "file size is zero");
        return -1;
    }
    char* pDataBuf = new char[st.st_size];
    memset(pDataBuf, 0, st.st_size);
    if (st.st_size != fread(pDataBuf, 1, st.st_size, file)) {
        fprintf(stderr, "read file error");
        return -1;
    }
    if (MPG123_OK != mpg123_feed(m, (const unsigned char*)pDataBuf, st.st_size)) {
        fprintf(stderr, "feed failed");
        return -1;
    }

    // channels;
    bool bSaved = false;
    size_t nDone = 0;
    int res = mpg123_decode(m, NULL, 0, NULL, 0, &nDone);
    if (res == MPG123_NEW_FORMAT) {
        long rate = 0;
        int channels = 0;
        int enc = 0;
        mpg123_getformat(m, &rate, &channels, &enc);

        if (MPG123_ENC_SIGNED_16 == enc) {
            int nSamples = mpg123_length(m);
            int nBufCount = nSamples * channels;
            int nBufSize = nBufCount * sizeof(short);
            short* pBuf = new short[nBufCount];

            res = mpg123_decode(m, NULL, 0, (unsigned char*)pBuf, nBufSize, &nDone);
            if (res == MPG123_OK) {
                KWavFile file;
                file.Init(pBuf, nDone, rate, "");
                file.Save(CT2A(argv[2]));
                bSaved = true;
            }
            if (pBuf) {
                delete[] pBuf;
                pBuf = NULL;
            }
        }
    }


    mpg123_tclose(m);
    mpg123_delete(m);
    mpg123_exit();
    return 0;
}
Exemple #15
0
size_t
in_mp3_decode(plugin_obj *obj, uint8_t *in, size_t insz, uint8_t *out, size_t *outsz)
{
        int		r;
        size_t		done;

	done = 0;
//	r = mpg123_decode((mpg123_handle *)obj->data, in, insz, out, outsz, &done);

	/* feed the decoder */
	r = mpg123_feed((mpg123_handle *)obj->data, in, insz);

	if (r != MPG123_DONE)
		abort(); 	/* LULZ TODO XXX WTF */

	/* read decoded data from internal buffer */
	r = mpg123_read((mpg123_handle *)obj->data, out, *outsz, &done);

	/* increase buffer space if we need more space */
	if (done > *outsz) {
		unsigned char	*tmp;
		int		newsz;

		newsz = done;
		tmp = malloc(newsz);
		memcpy(tmp, out, *outsz);

		r = mpg123_read((mpg123_handle *)obj->data, (tmp + *outsz), (newsz - *outsz), &done);
		assert(done == (newsz - *outsz));

		assert(out != NULL);
		free(out);
		out = tmp;

		*outsz = newsz;
	}

	if (r == MPG123_NEW_FORMAT) {
		long rate;
		int chan, enc;

		mpg123_getformat((mpg123_handle *)obj->data, &rate, &chan, &enc);

		obj->channels = chan; /* XXX */
		obj->rate = rate;

		/* TODO reinit output */
	}

#if 0
	while(ret != MPG123_ERR && ret != MPG123_NEED_MORE) {
		/* Get all decoded audio that is available now before feeding more input. */
		ret = mpg123_decode(m,NULL,0,out,OUTBUFF,&size);

	}
#endif

	if (r == MPG123_ERR)
		return 0;

        return done;
}
Exemple #16
0
int32 nuiAudioDecoder::ReadIN(void* pBuffer, int32 sampleframes, nuiSampleBitFormat format)
{
    if (!mInitialized)
        return 0;

    SetPosition(mPosition);

    int32 BitsPerSample  = mInfo.GetBitsPerSample();
    int32 channels       = mInfo.GetChannels();
    int32 frameSize      = channels * (mInfo.GetBitsPerSample() / 8.f);
    int32 outBytes       = sampleframes * frameSize;

    unsigned char* pTemp;
    bool allocated = false;

    if (BitsPerSample != 16 && BitsPerSample != 32)
    {
        NGL_ASSERT(0);
        return 0;
    }
    else if ( ((format == eSampleFloat32) && (BitsPerSample == 32)) || ((format == eSampleInt16) && (BitsPerSample == 16)) )
    {
        pTemp = (unsigned char*)pBuffer;
    }
    else
    {
        pTemp = new unsigned char[outBytes];
        allocated = true;
    }

    unsigned char* pIn = NULL;

    int32 bytesDone = 0;
    int err = MPG123_OK;
    int32 bytesRead = -1;
    while (outBytes && err != MPG123_DONE && bytesRead != 0)
    {
        size_t outBytesDone = 0;
        unsigned char* pOut = pTemp + bytesDone;
        err = mpg123_decode(mpPrivate->mpHandle, NULL, 0, pOut, outBytes, &outBytesDone);
        outBytes  -= outBytesDone;
        bytesDone += outBytesDone;

        if (err == MPG123_NEW_FORMAT)
        {
            long r;
            int c;
            int e;
            mpg123_getformat(mpPrivate->mpHandle, &r, &c, &e);
        }

        // feed decoder if needed
        bytesRead = -1;
        while (err == MPG123_NEED_MORE && bytesRead != 0)
        {
            int32 inBytes = DECODER_INPUT_SIZE;
            if (!pIn)
            {
                pIn = new unsigned char[inBytes];
            }
            bytesRead = mrStream.ReadUInt8(pIn, inBytes);
            err = mpg123_decode(mpPrivate->mpHandle, pIn, bytesRead, NULL, 0, &outBytesDone);
        }

        if (err != MPG123_OK && err != MPG123_DONE)
        {
            NGL_LOG("nuiAudioDecoder", NGL_LOG_INFO, "mpg123 error while decoding: %s", mpg123_strerror(mpPrivate->mpHandle));
        }
    }

    int32 frames = bytesDone / frameSize;

    if (format == eSampleFloat32 && BitsPerSample == 16)
    {
        // convert '16 bits int' samples in pTemp to '32 bits float' samples in pBuffer
        int16* pSrc = (int16*)pTemp;
        float* pCopy  = (float*)( ((int16*)pBuffer) + frames * channels );
        float* pFloat = (float*)pBuffer;

        // copy int16 data to the second half of the output buffer
        // => nuiAudioConvert_16bitsBufferToFloat converts in place
        // 'int16' samples atored in the second half of the buffer are converted in 'float' samples filling all the buffer (sizeof(float) == 2 * sizeof(int16))
        memcpy(pCopy, pSrc, frames * channels * sizeof(int16));

        nuiAudioConvert_16bitsBufferToFloat(pFloat, frames * channels); // convert in place (int16 to float)
    }
    else if (format == eSampleInt16 && BitsPerSample == 32)
    {
        // convert '32 bits float' samples in pTemp to '16 bits int' samples in pBuffer
        float* pFloat = (float*)pTemp;
        int16* pInt16 = (int16*)pBuffer;

        nuiAudioConvert_FloatBufferTo16bits(pFloat, pInt16, frames * channels);
    }

    if (allocated)
    {
        delete[] pTemp;
    }
    if (pIn)
    {
        delete[] pIn;
    }

    mPosition += frames;
    return frames;
}
Exemple #17
-1
bool FileFormatSupport( const char *fileE )
{
	FILE *f = qmp_fopen( fileE, "rb" );
	if ( !f )
		return 0;

	int _DATA_BUFF;
	if ( !getDataBuff( f, (size_t(*)(void *, size_t, size_t, void *))fread, _DATA_BUFF, NULL ) )
	{
		fclose(f);
		return false;
	}
	int TagSize = _DATA_BUFF - DATA_BUFF;

	bool loaded(0);
	mpg123_handle *mus = mpg123_new(NULL, NULL);
	mpg123_open_feed( mus );
	fseek(f,TagSize,0);
	char *data = new char[DATA_BUFF];
	int bread = fread( data, 1, DATA_BUFF, f );
	fclose(f);
	mpg123_decode( mus, (const unsigned char*)data, bread, 0,0,0 );
	delete[] data;
	loaded = getMusInfo( mus, 0,0,0,0,0, -1, "" );
	mpg123_close(mus);
	mpg123_delete(mus);
	return loaded;
}
Exemple #18
-1
static int MP3_2_Pcm16( unsigned char* out_buf, unsigned char* in_buf, unsigned int size,
			unsigned int channels, unsigned int rate, 
			long h_codec )
{

#ifndef WITH_MPG123DECODER
    ERROR("MP3 decoding support not compiled in.\n");
    return -1;
#else
    int res;
    size_t decoded_size;
    mp3_coder_state* coder_state;

    if (!h_codec) {
      ERROR("mp3 decoder not initialized!\n");
      return -1;
    }
        
    coder_state = (mp3_coder_state*)h_codec;
    res = mpg123_decode(coder_state->mpg123_h, in_buf, size, 
			out_buf, AUDIO_BUFFER_SIZE, &decoded_size);
    
    if (res == MPG123_NEW_FORMAT) {
      WARN("intermediate mp3 file format change!\n");
    }
    if (res == MPG123_ERR) {
      ERROR("decoding mp3: '%s'\n", 
	    mpg123_strerror(coder_state->mpg123_h));
      return -1;
    }
/*     DBG("mp3: decoded %d\n", decoded_size); */
    return decoded_size;
#endif
}
Exemple #19
-1
static gint
xmms_mpg123_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len,
                  xmms_error_t *err)
{
	xmms_mpg123_data_t *data;
	int result = MPG123_OK;
	size_t read = 0;

	data = xmms_xform_private_data_get (xform);
	g_return_val_if_fail (data, -1);

	while (read == 0) {
		gint ret = 0;

		if (result == MPG123_NEED_MORE) {
			ret = xmms_xform_read (xform, data->buf, BUFSIZE, err);
			if (ret < 0) {
				return ret;
			} else if (ret == 0) {
				data->eof_found = TRUE;
			}
		}

		result = mpg123_decode (data->decoder, data->buf, (size_t) ret,
		                        buf, len, &read);

		if (result == MPG123_NEED_MORE && data->eof_found) {
			/* We need more data, but there's none available
			 * so libmpg123 apparently missed an EOF */
			result = MPG123_DONE;
			break;
		} else if (result != MPG123_OK && result != MPG123_NEED_MORE) {
			/* This is some uncommon result like EOF, handle outside
			 * the loop */
			break;
		}
	}

	if (result == MPG123_DONE) {
		/* This is just normal EOF reported from libmpg123 */
		XMMS_DBG ("Got EOF while decoding stream");
		return 0;
	} else if (result == MPG123_NEW_FORMAT) {
		/* FIXME: When we can handle format changes, modify this */
		xmms_error_set (err,
		                XMMS_ERROR_GENERIC,
		                "The output format changed, XMMS2 can't handle that");
		return -1;
	} else if (result == MPG123_ERR) {
		xmms_error_set (err,
		                XMMS_ERROR_GENERIC,
		                mpg123_strerror (data->decoder));
		return -1;
	}

	return (gint) read;
}