/* Wrapper for receive-side integer-to-float array resampling */ int rx_resmpl_int_flt(float *smpls_out, short *smpls_in, int num_smpls) { int num_resmpld, num_chunks; signalVector *convert_vec, *resamp_vec, *trunc_vec; if (!rx_lpf || !rx_vec || !rx_hist) init_resampler(&rx_lpf, &rx_vec, &rx_hist, false); /* Convert and add samples to the receive buffer */ convert_vec = short_to_sigvec(smpls_in, num_smpls); rx_vec = concat(rx_vec, convert_vec); num_chunks = rx_vec->size() / OUTCHUNK; if (num_chunks < 1) return 0; /* Resample */ resamp_vec = resmpl_sigvec(rx_hist, &rx_vec, rx_lpf, INRATE, OUTRATE, OUTCHUNK); /* Truncate */ trunc_vec = segment(resamp_vec, INHISTORY, resamp_vec->size() - INHISTORY); /* Convert */ num_resmpld = sigvec_to_float(trunc_vec, smpls_out); return num_resmpld; }
/* Wrapper for transmit-side float-to-int array resampling */ int tx_resmpl_flt_int(short *smpls_out, float *smpls_in, int num_smpls) { int num_resmpl, num_chunks; signalVector *convert_vec, *resamp_vec; if (!tx_lpf || !tx_vec || !tx_hist) init_resampler(&tx_lpf, &tx_vec, &tx_hist, true); /* Convert and add samples to the transmit buffer */ convert_vec = float_to_sigvec(smpls_in, num_smpls); tx_vec = concat(tx_vec, convert_vec); num_chunks = tx_vec->size() / INCHUNK; if (num_chunks < 1) return 0; /* Resample and convert to an integer array */ resamp_vec = resmpl_sigvec(tx_hist, &tx_vec, tx_lpf, OUTRATE, INRATE, INCHUNK); num_resmpl = sigvec_to_short(resamp_vec, smpls_out); return num_resmpl; }
/** Convert an audio file to an AAC file in an MP4 container. */ int compress(int argc, char **argv) { AVFormatContext *input_format_context = NULL, *output_format_context = NULL; AVCodecContext *input_codec_context = NULL, *output_codec_context = NULL; SwrContext *resample_context = NULL; AVAudioFifo *fifo = NULL; int ret = AVERROR_EXIT; if (argc < 3) { fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]); exit(1); } const char *input_filename = argv[1]; const char *output_filename = argv[2]; /** Register all codecs and formats so that they can be used. */ av_register_all(); /** Open the input file for reading. */ if (open_input_file(input_filename, &input_format_context, &input_codec_context)) goto cleanup; /** Open the output file for writing. */ if (open_output_file(output_filename, input_codec_context, &output_format_context, &output_codec_context)) goto cleanup; /** Initialize the resampler to be able to convert audio sample formats. */ if (init_resampler(input_codec_context, output_codec_context, &resample_context)) goto cleanup; /** Initialize the FIFO buffer to store audio samples to be encoded. */ if (init_fifo(&fifo, output_codec_context)) goto cleanup; /** Write the header of the output file container. */ if (write_output_file_header(output_format_context)) goto cleanup; /** * Loop as long as we have input samples to read or output samples * to write; abort as soon as we have neither. */ while (1) { /** Use the encoder's desired frame size for processing. */ const int output_frame_size = output_codec_context->frame_size; int finished = 0; /** * Make sure that there is one frame worth of samples in the FIFO * buffer so that the encoder can do its work. * Since the decoder's and the encoder's frame size may differ, we * need to FIFO buffer to store as many frames worth of input samples * that they make up at least one frame worth of output samples. */ while (av_audio_fifo_size(fifo) < output_frame_size) { /** * Decode one frame worth of audio samples, convert it to the * output sample format and put it into the FIFO buffer. */ if (read_decode_convert_and_store(fifo, input_format_context, input_codec_context, output_codec_context, resample_context, &finished)) goto cleanup; /** * If we are at the end of the input file, we continue * encoding the remaining audio samples to the output file. */ if (finished) break; } /** * If we have enough samples for the encoder, we encode them. * At the end of the file, we pass the remaining samples to * the encoder. */ while (av_audio_fifo_size(fifo) >= output_frame_size || (finished && av_audio_fifo_size(fifo) > 0)) /** * Take one frame worth of audio samples from the FIFO buffer, * encode it and write it to the output file. */ if (load_encode_and_write(fifo, output_format_context, output_codec_context)) goto cleanup; /** * If we are at the end of the input file and have encoded * all remaining samples, we can exit this loop and finish. */ if (finished) { int data_written; /** Flush the encoder as it may have delayed frames. */ do { if (encode_audio_frame(NULL, output_format_context, output_codec_context, &data_written)) goto cleanup; } while (data_written); break; } } /** Write the trailer of the output file container. */ if (write_output_file_trailer(output_format_context)) goto cleanup; ret = 0; cleanup: if (fifo) av_audio_fifo_free(fifo); swr_free(&resample_context); if (output_codec_context) avcodec_close(output_codec_context); if (output_format_context) { avio_closep(&output_format_context->pb); avformat_free_context(output_format_context); } if (input_codec_context) avcodec_close(input_codec_context); if (input_format_context) avformat_close_input(&input_format_context); return ret; }
/** * * @param orig * @param dest * @return */ int Transcode::transcode(string orig, string dest, TID3Tags *tags) { AVFormatContext *input_format_context = NULL, *output_format_context = NULL; AVCodecContext *input_codec_context = NULL, *output_codec_context = NULL; SwrContext *resample_context = NULL; AVAudioFifo *fifo = NULL; int ret = AVERROR_EXIT; this->pts = 0; if (orig.empty() || dest.empty()) { fprintf(stderr, "Files to process not especified\n"); return ret; } /* Register all codecs and formats so that they can be used. */ av_register_all(); /* Open the input file for reading. */ if (open_input_file(orig.c_str(), &input_format_context, &input_codec_context)) goto cleanup; /* Open the output file for writing. */ if (open_output_file(dest.c_str(), input_codec_context, &output_format_context, &output_codec_context)) goto cleanup; /**Copy the metadata if exist*/ copy_metadata(input_format_context, output_format_context, tags); /* Initialize the resampler to be able to convert audio sample formats. */ if (init_resampler(input_codec_context, output_codec_context, &resample_context)) goto cleanup; /* Initialize the FIFO buffer to store audio samples to be encoded. */ if (init_fifo(&fifo, output_codec_context)) goto cleanup; /* Write the header of the output file container. */ if (write_output_file_header(output_format_context)) goto cleanup; /* Loop as long as we have input samples to read or output samples * to write; abort as soon as we have neither. */ while (1) { /* Use the encoder's desired frame size for processing. */ const int output_frame_size = output_codec_context->frame_size; int finished = 0; /* Make sure that there is one frame worth of samples in the FIFO * buffer so that the encoder can do its work. * Since the decoder's and the encoder's frame size may differ, we * need to FIFO buffer to store as many frames worth of input samples * that they make up at least one frame worth of output samples. */ while (av_audio_fifo_size(fifo) < output_frame_size) { /* Decode one frame worth of audio samples, convert it to the * output sample format and put it into the FIFO buffer. */ if (read_decode_convert_and_store(fifo, input_format_context, input_codec_context, output_codec_context, resample_context, &finished)) goto cleanup; /* If we are at the end of the input file, we continue * encoding the remaining audio samples to the output file. */ if (finished) break; } /* If we have enough samples for the encoder, we encode them. * At the end of the file, we pass the remaining samples to * the encoder. */ while (av_audio_fifo_size(fifo) >= output_frame_size || (finished && av_audio_fifo_size(fifo) > 0)) /* Take one frame worth of audio samples from the FIFO buffer, * encode it and write it to the output file. */ if (load_encode_and_write(fifo, output_format_context, output_codec_context)) goto cleanup; /* If we are at the end of the input file and have encoded * all remaining samples, we can exit this loop and finish. */ if (finished) { int data_written; /* Flush the encoder as it may have delayed frames. */ do { if (encode_audio_frame(NULL, output_format_context, output_codec_context, &data_written)) goto cleanup; } while (data_written); break; } } /* Write the trailer of the output file container. */ if (write_output_file_trailer(output_format_context)) goto cleanup; ret = 0; cleanup: if (fifo) av_audio_fifo_free(fifo); swr_free(&resample_context); if (output_codec_context) avcodec_free_context(&output_codec_context); if (output_format_context) { avio_closep(&output_format_context->pb); avformat_free_context(output_format_context); } if (input_codec_context) avcodec_free_context(&input_codec_context); if (input_format_context) avformat_close_input(&input_format_context); return ret; }
int AudioDecoder::initDecoder(AVCodecContext* context, AVCodec* dec_codec) { ELOG_DEBUG("initDecoder started"); codec_ = dec_codec; input_codec_context = context; // ok? ok if (avcodec_open2(input_codec_context, codec_, NULL) < 0) { ELOG_DEBUG("AudioDecoder initDecoder Error open2 audio decoder"); return 0; } ELOG_DEBUG("input sample_fmts[0] is %s", av_get_sample_fmt_name(codec_->sample_fmts[0])); ELOG_DEBUG("input sample_fmt is %s", av_get_sample_fmt_name(input_codec_context->sample_fmt)); ELOG_DEBUG("input frame size is %d, bitrate=%d", input_codec_context->frame_size, input_codec_context->bit_rate); // Init output encoder as well. AVCodec *output_codec = NULL; int error; if (!(output_codec = avcodec_find_encoder(OUTPUT_CODEC_ID))) { ELOG_DEBUG( "Could not find the encoder."); return 0; } output_codec_context = avcodec_alloc_context3(output_codec); if (!output_codec_context) { ELOG_DEBUG( "Could not allocate an encoding context"); return 0; } /** * Set the basic encoder parameters. * The input file's sample rate is used to avoid a sample rate conversion. */ output_codec_context->channels = OUTPUT_CHANNELS; output_codec_context->channel_layout = av_get_default_channel_layout(OUTPUT_CHANNELS); output_codec_context->sample_rate = input_codec_context->sample_rate; output_codec_context->sample_fmt = output_codec->sample_fmts[0]; //u8 output_codec_context->bit_rate = 510000; /** Allow the use of the experimental feature */ output_codec_context->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; /** Open the encoder for the audio stream to use it later. */ if ((error = avcodec_open2(output_codec_context, output_codec, NULL)) < 0) { ELOG_DEBUG("Could not open output codec %s", get_error_text(error)); return 0; } ELOG_DEBUG("output sample_fmts[0] is %s", av_get_sample_fmt_name(output_codec->sample_fmts[0])); ELOG_DEBUG("output sample_fmt is %s", av_get_sample_fmt_name(output_codec_context->sample_fmt)); ELOG_DEBUG("output frame size is %d", output_codec_context->frame_size); output_codec_context->frame_size = 960; //20ms. actually no need, as it already is /** Initialize the resampler to be able to convert audio sample formats. */ if (init_resampler(input_codec_context, output_codec_context)) { ELOG_DEBUG(" init resampleer failed !!"); return 0; } init_fifo(&fifo); ELOG_DEBUG("initDecoder end"); return 1; }