You are not logged in.
Hello guys,
I've been looking for a solution for several days by now and have not gotten any smarter, I hope that someone of you is able to help me ![]()
What I'm currently working on is an application able to generate audio fingerprints (specifically acoustID fingerprints). To do so, I started with the sample
code that demonstrates the basic fingerprinting capability. You can find it here.
It is part of a library called chromaprint.
As you will see, a lot of this code uses deprecated functions. As a newbie to sound conversion, the sense of a lot of the calculations in the file is oblivious to me ![]()
Still, I want to renew the code to use functions that are up-to-date. Ideally I'd understand the code more thorough then, or so I thought.
I started modifiying the decode_audio_file function from fpcalc.c and got until here, where I am now stuck:
int decode_audio_file(ChromaprintContext *chromaprint_ctx, int16_t *buffer1, int16_t *buffer2, const char *file_name, int max_length, int *duration)
{
AVFormatContext *format_ctx = NULL;
AVCodecContext *codec_ctx = NULL;
AVAudioConvert *convert_ctx = NULL;
AVStream *stream = NULL;
AVCodec *codec = NULL;
AVPacket avpacket;
AVFrame *decoded_frame = NULL;
FILE *f;
int frameFinished = 0;
int stream_id, ok = 0;
int buffersize = AVCODEC_MAX_AUDIO_FRAME_SIZE + FF_INPUT_BUFFER_PADDING_SIZE;
uint8_t inbuf[buffersize];
/* initialize data packet that is read from the stream */
av_init_packet(&avpacket);
avpacket.data = inbuf;
avpacket.size = buffersize;
/* make space for frame that contains decoded data */
decoded_frame = avcodec_alloc_frame();
/* tell format_ctx about the input */
if (avformat_open_input(&format_ctx, file_name, NULL, NULL) < 0) {
fprintf(stderr,"ERROR: couldn't open the file");
goto done;
}
if (avformat_find_stream_info(format_ctx, 0) < 0) {
fprintf(stderr,"ERROR: couldn't find stream information in the file");
goto done;
}
for (int i = 0; i < format_ctx->nb_streams; ++i) {
codec_ctx = format_ctx->streams[i]->codec;
if (codec_ctx && codec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
stream = format_ctx->streams[i];
break;
}
}
if (!stream) {
fprintf(stderr,"ERROR: couldn't find any audio stream in the file\n");
goto done;
}
codec = avcodec_find_decoder(codec_ctx->codec_id);
/* chromaprint expects signed 16 bit samples */
codec_ctx->request_sample_fmt = AV_SAMPLE_FMT_S16;
if (codec_ctx->sample_fmt != AV_SAMPLE_FMT_S16) {
convert_ctx = av_audio_convert_alloc(AV_SAMPLE_FMT_S16, codec_ctx->channels,
codec_ctx->sample_fmt, codec_ctx->channels, NULL, 0);
if (!convert_ctx) {
fprintf(stderr, "ERROR: couldn't create sample format converter");
goto done;
}
}
if (!codec) {
fprintf(stderr,"ERROR: unknown codec");
goto done;
}
if (avcodec_open2(codec_ctx, codec, NULL) < 0) {
fprintf(stderr,"Could not open codec\n");
goto done;
}
chromaprint_start(chromaprint_ctx, codec_ctx->sample_rate, codec_ctx->channels);
*duration = stream->time_base.num * stream->duration / stream->time_base.den;
int len;
while (av_read_frame(format_ctx, &avpacket)>=0) {
if (avpacket.stream_index == stream->id) {
len = avcodec_decode_audio4(codec_ctx, decoded_frame, &frameFinished, &avpacket);
if(frameFinished) {
int data_size = av_samples_get_buffer_size(NULL, codec_ctx->channels,
decoded_frame->nb_samples,
codec_ctx->sample_fmt, 1);
if (convert_ctx) {
const void *ibuf[6] = { decoded_frame->data };
void *obuf[6] = { buffer2 };
int istride[6] = { av_get_bytes_per_sample(codec_ctx->sample_fmt) };
int ostride[6] = { 2 };
len = data_size / istride[0];
if (av_audio_convert(convert_ctx, obuf, ostride, ibuf, istride, 4) < 0) {
fprintf(stderr,"WARNING: unable to convert %d samples\n", len);
break;
}
if (!chromaprint_feed(chromaprint_ctx, buffer2, decoded_frame->nb_samples/2 )) {
fprintf(stderr,"ERROR: fingerprint calculation failed\n");
goto done;
}
} else if (!chromaprint_feed(chromaprint_ctx, decoded_frame->extended_data, decoded_frame->nb_samples)) {
fprintf(stderr,"ERROR: fingerprint calculation failed\n");
goto done;
}
}
}
}
ok = 1;
done:
avformat_close_input(&format_ctx);
avcodec_free_frame(&decoded_frame);
return ok;
}You can find the documentation for the used chromaprint functions here.
As I said, I am not really sure whether I have understood all of what is going on in the unmodified version of the function, so please bear with me ![]()
Any answers or suggestions for reading material will be gladly appreciated!
PS: goto marks will be removed once the code works ![]()
Last edited by n0stradamus (2013-03-29 23:10:36)
Offline