Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/audio/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Audio 在linux上用c语言中的libav转换音频格式_Audio_Mp3_Encode_Libav_Resampling - Fatal编程技术网

Audio 在linux上用c语言中的libav转换音频格式

Audio 在linux上用c语言中的libav转换音频格式,audio,mp3,encode,libav,resampling,Audio,Mp3,Encode,Libav,Resampling,我正在尝试编写一个应用程序,其中一部分将音频文件转换为不同的格式。但是输出是垃圾(好吧,这就是它在audacity中的样子) 在尝试了许多不同的东西之后,我最终得到了这样一个结果:一个原始音频文件,我试图将其转换成MP3文件。我知道原始音频还可以(通过audacity)。但是MP3又是垃圾 下面是我正在使用的代码(我从libav示例拼凑而成): /* *flac2m3.cpp * *创建日期:2014年8月20日 *作者:肯 */ #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括

我正在尝试编写一个应用程序,其中一部分将音频文件转换为不同的格式。但是输出是垃圾(好吧,这就是它在audacity中的样子)

在尝试了许多不同的东西之后,我最终得到了这样一个结果:一个原始音频文件,我试图将其转换成MP3文件。我知道原始音频还可以(通过audacity)。但是MP3又是垃圾

下面是我正在使用的代码(我从libav示例拼凑而成):

/*
*flac2m3.cpp
*
*创建日期:2014年8月20日
*作者:肯
*/
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#include//std::exception
#包括
#包括
#包括
#包括
#包括
#ifndef\uU STDC\u格式\u宏
#定义\u STDC\u格式\u宏
#包括
#恩迪夫
#ifndef INT64_C
#定义INT64_C(C)(C#LL)
#定义UINT64_C(C)(C#ULL)
#恩迪夫
外部“C”
{
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#ifdef CPP_W_LITERAL_后缀
#undef CPP_W_LITERAL_后缀
#包括
#定义CPP_W_LITERAL_后缀
#恩迪夫
#ifdef av_err2str
#undef av_err2str
#恩迪夫
#定义av_err2str(errnum)\
av生成错误字符串((字符*)((av生成错误最大字符串大小))\
AV\u错误\u最大\u字符串大小,errnum)
#ifdef av_ts2timestr
#未定义av_ts2timestr
#恩迪夫
#定义av_ts2timestr(ts,tb)\
av_ts_make_time_string((字符*)(_内置_alloca(av_ts_MAX_string_SIZE)),ts,tb)
}
typedef无符号字符字节;
#包括
#包括
静态AVFormatContext*encfmt_ctx=NULL;
静态AVcodeContext*音频加密ctx;
静态AVStream*audio_encstream=NULL;
静态整数音频帧计数=0,音频帧计数=0;
静态SwrContext*swr;
静态字节**输出;
静态常量字节**inpb;
#定义MP3\u示例\u FMT AV\u示例\u FMT\u S16P
#定义MP3_比特率256000
#定义MP3_采样率44100
#定义FLAC_样本\u FMT AV_样本\u FMT_S16
#定义FLAC_比特率256000
#定义FLAC_样本率44100
#定义样本到CB(stc,cs)(av获取每个样本的字节数(stc->编解码器->样本fmt)*stc->编解码器->频道*cs)
#从(stc,CB)CB定义样本/(每个样本(stc->codec->sample\u fmt)*stc->codec->channels)
#定义字节\u至\u读取2048
布尔编码_缓冲区(字节*buff,int-cbdec,布尔刷新)
{
int ret;
int-got_框架;
内线尺寸;
AVPacket epkt={0};
AVFrame*eframe=avcodec_alloc_frame();
av_初始_数据包(&epkt);
/*
*转换音频
*/
长整数c_样本=cbdec/(4);
//长整数延迟=swr\U get\U延迟(swr,(长整数)44100);
长整数延迟=0;
int c_outsamples=av_rescale_rnd(延迟+c_insamples,
(长整数)MP3_采样率,
(长整数)FLAC_采样率、AV_取整率);
ret=av样本分配(输出和线尺寸,2,
c_样本数,MP3_样本数_FMT,0);
av_资产0(ret>=0);
inpb[0]=buff;
ret=swr_转换(swr、outpb、c_外采样、inpb、c_内采样);
av_资产0(ret>=0);
/*
*编码
*/
音频帧计数+=(cbdec/4);
printf(“cbdec=%d,deccount=%d\n”,cbdec,音频\帧\ deccount);
eframe->nb_样本=cbdec/(4);
eframe->pts=(音频帧计数*(av重新缩放q(1,音频加密流->编解码器->时基,音频加密流->时基));
avcodec_fill_audio_frame(eframe,2,MP3_SAMPLE_FMT,outpb[0],cbdec,1);
epkt.stream\u index=音频流->索引;
eframe->nb\u samples=音频加密ctx->帧大小;
ret=avcodec\U encode\U audio 2(音频加密、ctx和epkt、eframe和got\U帧);
av_资产0(ret>=0);
如果(!得到了_帧)
{
//无AVU(输出B[0]);
返回false;
}
epkt.stream\u index=音频流->索引;
音频_帧_enccount++;
/*将压缩帧写入媒体文件*/
ret=av交织写入帧(encfmt、ctx和epkt);
无AVU(输出B[0]);
avcodec_free_帧(&eframe);
返回true;
}
int open_encodec_上下文(AVFormatContext*fmt_ctx,枚举AVMediaType类型)
{
int ret;
AVStream*st;
AVCodec*enc=NULL;
enc=avcodec\u find\u编码器(fmt\u ctx->oformat->audio\u codec);
av_资产0(enc!=NULL);
st=AVU格式新流(fmt ctx,enc);
/*查找流的编码器*/
st->codec->sample\u fmt=MP3\u sample\u fmt;
st->编解码器->比特率=MP3比特率;
st->codec->sample\u rate=MP3\u sample\u rate;
st->codec->channels=2;
ret=avcodec_open2(st->codec,enc,NULL);
av_资产0(ret>=0);
返回1;
}
int main(int argc,字符**argv)
{
常量字符*fn_out=argv[1];
int ret;
av_寄存器_all();
ret=avformat\u alloc\u output\u context2(&encfmt\u ctx,NULL,NULL,fn\u out);
av_资产0(ret>=0);
如果(打开编码上下文(encfmt\u ctx,AVMEDIA\u TYPE\u AUDIO)>=0)
{
音频_encstream=encfmt_ctx->streams[0];
音频加密ctx=音频加密流->编解码器;
av_转储_格式(encfmt_ctx,0,fn_out,1);
}
字节pbo[sizeof(BYTE*)*av_sample_fmt_是平面的(MP3_sample_fmt)?2:1];
outpb=(字节**)pbo;
outpb[0]=NULL;
字节pbi[sizeof(BYTE*)*2];
inpb=(常量字节**)pbi;
inpb[0]=NULL;
swr=swr_alloc();
av_资产0(swr);
/*设置选项*/
av_opt_set_int(swr,“通道内布局”,2,0);
av_opt_set_int(swr,“通道内计数”,2,0);
av_opt_set_int(swr,“进样率”,FLAC_采样率,0);
av选择集样本fmt(swr,“入样本fmt”,FLAC样本fmt,0);
av_opt_set_int(swr,“输出通道布局”,2,0);
av_opt_set_int(swr,“输出采样率”,MP3采样率,0);
av_opt_set_sample_fmt(swr,“out_sample_fmt”,MP3_sample_fmt,0);
ret=swr_初始值(swr);
av_资产0(ret>=0);
if(!(encfmt_ctx->oformat->flags&AVFMT_NOFILE))
{
ret=avio_打开(&encfmt_ctx->pb,fn_输出,avio_标志_写入);
如果(ret<0)
{
fprintf(stderr,“无法打开“%s”:%s\n”,fn\u out,
av_err2str(ret));
返回1;
}
}
ret=avformat\U write\U头(encfmt\U ctx,NU
/*
 * flac2mp3.cpp
 *
 *  Created on: Aug 20, 2014
 *      Author: ken
 */



#include <stddef.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <string.h>
#include <pthread.h>
#include <signal.h>
#include <exception>      // std::exception
#include <cerrno>
#include <assert.h>
#include <time.h>
#include <fcntl.h>
#include <linux/types.h>

#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#endif
#ifndef INT64_C
#define INT64_C(c) (c ## LL)
#define UINT64_C(c) (c ## ULL)
#endif

extern "C"
{
#include <libavutil/avassert.h>
#include <libavutil/channel_layout.h>
#include <libavutil/opt.h>
#include <libavutil/mathematics.h>
#include <libavutil/timestamp.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libswresample/swresample.h>

#ifdef CPP_W_LITERAL_SUFFIX
#undef CPP_W_LITERAL_SUFFIX
#include <libavutil/timestamp.h>
#define CPP_W_LITERAL_SUFFIX
#endif
#ifdef av_err2str
#undef  av_err2str
#endif
#define av_err2str(errnum) \
    av_make_error_string((char*)(__builtin_alloca(AV_ERROR_MAX_STRING_SIZE)),\
    AV_ERROR_MAX_STRING_SIZE, errnum)

#ifdef av_ts2timestr
#undef  av_ts2timestr
#endif
#define av_ts2timestr(ts, tb) \
        av_ts_make_time_string((char*)(__builtin_alloca(AV_TS_MAX_STRING_SIZE)), ts, tb)

}

typedef unsigned char   BYTE;
#include <algorithm>
#include <fcntl.h>

static AVFormatContext *encfmt_ctx = NULL;
static AVCodecContext *audio_enc_ctx;
static AVStream *audio_encstream = NULL;
static int audio_frame_deccount = 0, audio_frame_enccount = 0;
static SwrContext *swr;
static BYTE **outpb;
static const BYTE **inpb;

#define MP3_SAMPLE_FMT  AV_SAMPLE_FMT_S16P
#define MP3_BITRATE     256000
#define MP3_SAMPLE_RATE 44100

#define FLAC_SAMPLE_FMT AV_SAMPLE_FMT_S16
#define FLAC_BITRATE        256000
#define FLAC_SAMPLE_RATE    44100

#define SAMPLES_TO_CB(stc, cs)  (av_get_bytes_per_sample(stc->codec->sample_fmt) * stc->codec->channels * cs)
#define SAMPLES_FROM_CB(stc, cb) cb/(av_get_bytes_per_sample(stc->codec->sample_fmt) * stc->codec->channels)

#define BYTES_TO_READ   2048

bool encode_buffer(BYTE* buff, int cbdec, bool flush)
{
    int ret;
    int got_frame;
    int line_size;
    AVPacket    epkt = {0};
    AVFrame *eframe = avcodec_alloc_frame();

    av_init_packet(&epkt);
    /*
     * convert audio
     */
    long int c_insamples = cbdec/(4);
//  long int delay = swr_get_delay(swr,(long int) 44100);
    long int delay = 0;
    int c_outsamples = av_rescale_rnd(delay + c_insamples,
            (long int) MP3_SAMPLE_RATE,
            (long int) FLAC_SAMPLE_RATE, AV_ROUND_UP);
    ret = av_samples_alloc(outpb, &line_size, 2,
                    c_outsamples,MP3_SAMPLE_FMT, 0);
    av_assert0(ret >= 0);
    inpb[0] = buff;
    ret = swr_convert(swr, outpb, c_outsamples, inpb, c_insamples);
    av_assert0(ret >= 0);

    /*
     * encode
     */
    audio_frame_deccount +=(cbdec/4);
    printf("cbdec=%d, deccount=%d\n", cbdec, audio_frame_deccount);
    eframe->nb_samples = cbdec/(4);
    eframe->pts = (audio_frame_deccount * ( av_rescale_q(1, audio_encstream->codec->time_base, audio_encstream->time_base)));
    avcodec_fill_audio_frame(eframe, 2, MP3_SAMPLE_FMT, outpb[0], cbdec, 1);


    epkt.stream_index = audio_encstream->index;
    eframe->nb_samples = audio_enc_ctx->frame_size;

    ret = avcodec_encode_audio2(audio_enc_ctx, &epkt, eframe, &got_frame);
    av_assert0(ret >= 0);
    if (!got_frame)
    {
//      av_free(outpb[0]);
        return false;
    }
    epkt.stream_index = audio_encstream->index;
    audio_frame_enccount ++ ;
    /* Write the compressed frame to the media file. */
    ret = av_interleaved_write_frame(encfmt_ctx, &epkt);


    av_free(outpb[0]);
    avcodec_free_frame(&eframe);
    return true;

}


int open_encodec_context(AVFormatContext *fmt_ctx, enum AVMediaType type)
{
    int ret;
    AVStream *st;
    AVCodec *enc = NULL;
    enc = avcodec_find_encoder(fmt_ctx->oformat->audio_codec);
    av_assert0(enc != NULL);
    st = avformat_new_stream(fmt_ctx, enc);
    /* find encoder for the stream */
    st->codec->sample_fmt = MP3_SAMPLE_FMT;
    st->codec->bit_rate = MP3_BITRATE;
    st->codec->sample_rate = MP3_SAMPLE_RATE;
    st->codec->channels = 2;
    ret = avcodec_open2(st->codec, enc, NULL);
    av_assert0(ret >= 0);


    return 1;
}


int main(int argc, char **argv)
{

    const char *fn_out = argv[1];
    int ret;

    av_register_all();
    ret = avformat_alloc_output_context2(&encfmt_ctx, NULL, NULL, fn_out);
    av_assert0(ret >= 0);
    if (open_encodec_context(encfmt_ctx, AVMEDIA_TYPE_AUDIO) >= 0)
    {

        audio_encstream = encfmt_ctx->streams[0];
        audio_enc_ctx = audio_encstream->codec;
        av_dump_format(encfmt_ctx, 0, fn_out, 1);
    }

    BYTE pbo[sizeof(BYTE*) * av_sample_fmt_is_planar(MP3_SAMPLE_FMT) ? 2 : 1];
    outpb = (BYTE**) pbo;
    outpb[0] = NULL;
    BYTE pbi[sizeof(BYTE*) * 2];
    inpb = (const BYTE**) pbi;
    inpb[0] = NULL;
    swr = swr_alloc();
    av_assert0(swr);

    /* set options */
    av_opt_set_int(swr, "in_channel_layout", 2, 0);
    av_opt_set_int(swr, "in_channel_count", 2, 0);
    av_opt_set_int(swr, "in_sample_rate", FLAC_SAMPLE_RATE,0);
    av_opt_set_sample_fmt(swr, "in_sample_fmt", FLAC_SAMPLE_FMT, 0);
    av_opt_set_int(swr, "out_channel_layout",2, 0);
    av_opt_set_int(swr, "out_sample_rate", MP3_SAMPLE_RATE, 0);
    av_opt_set_sample_fmt(swr, "out_sample_fmt",MP3_SAMPLE_FMT, 0);
    ret = swr_init(swr);
    av_assert0(ret >= 0);

    if (!(encfmt_ctx->oformat->flags & AVFMT_NOFILE))
    {
        ret = avio_open(&encfmt_ctx->pb, fn_out, AVIO_FLAG_WRITE);
        if (ret < 0)
        {
            fprintf(stderr, "Could not open '%s': %s\n", fn_out,
                    av_err2str(ret));
            return 1;
        }
    }
    ret = avformat_write_header(encfmt_ctx, NULL);
    av_assert0(ret >= 0);

    int cbread = 0;
    int fd = open("/nas/temp/flac.raw", O_RDONLY);
    assert(fd > 0);
    int cb2read = BYTES_TO_READ;
    BYTE    b[cb2read];
    int c_reads = 0;
    while ((cbread = read(fd, b, cb2read)) > 0)
    {
        c_reads++;
        encode_buffer(b, cbread, false);
    }
    close(fd);
    ret = av_interleaved_write_frame(encfmt_ctx, NULL);
    av_assert0(ret >= 0);

    av_write_trailer(encfmt_ctx);
    avio_close(encfmt_ctx->pb);

    avcodec_close(audio_enc_ctx);
    avformat_free_context(encfmt_ctx);
    exit(1);
}