3

一見単純な計算で2日間立ち往生しています。しかし、私はそれを理解していません。

圧縮アルゴリズムを使用してオーディオ ファイルをエンコードしています。

オーディオ ファイル全体は、960 バイトの「チャンク」に分割されます。各チャンクは 60 バイトに圧縮されます。

私の非圧縮ファイルの長さは 1480320 バイトです。エンコードされたファイルの長さは 46320 バイトです。

何かが間違っているようです。エンコードされたオーディオのファイル サイズから理論上の非圧縮ファイル サイズを計算してみました。

ファイルのエンコード方法は次のとおりです。

short *m_in;
short *m_out;
unsigned char *m_data;
unsigned char *m_fbytes;
int m_max_frame_size;
int m_frame_size;
int m_sampling_rate;
int m_max_payload_bytes;
int m_bitrate_bps;
int m_iByteLen1FrameEncoded;
int m_iByteLen1FrameDecoded;


m_sampling_rate=48000;
m_max_frame_size = 960*6;
m_max_payload_bytes=1500;
m_bitrate_bps= 24000;
m_iByteLen1FrameEncoded=60;
m_iByteLen1FrameDecoded=960;

m_in = (short*)malloc(m_max_frame_size*sizeof(short));
m_out = (short*)malloc(m_max_frame_size*sizeof(short));
m_data = (unsigned char*)calloc(m_max_payload_bytes,sizeof(char));
m_fbytes = (unsigned char*)malloc(m_iByteLen1FrameDecoded*sizeof(short));

FILE *fin= fopen(uPathInput.c_str(), "rb");
FILE *fout=fopen(uPathOutput.c_str(), "wb");

int curr_read=0;
int stop=0;

    while (!stop)
    {
    int err;
    err = fread(m_fbytes, sizeof(short), 960, fin);
    curr_read = err;
    for(int i=0;i<curr_read;i++)
    {
        opus_int32 s;
        s=m_fbytes[2*i+1]<<8|m_fbytes[2*i];
        s=((s&0xFFFF)^0x8000)-0x8000;
        m_in[i]=s;
    }
    if (curr_read < 960)
    {
        for (int i=curr_read;i<960;i++)
        {
            m_in[i] = 0;
        }
        stop = 1;
    }
            //iLen will always return 60, so I guess the 960 bytes are compressed to 60 bytes, right?
    int iLen = opus_encode(m_enc, m_in, m_iByteLen1FrameDecoded, m_data, m_max_payload_bytes);
    if (fwrite(m_data, 1, iLen, fout) !=iLen) 
    {
        fprintf(stderr, "Error writing.\n");
    }     
}

    fclose(fin);
    fclose(fout);
 }

圧縮比は960/60=16のようです

だから私は 46320 バイト * 16 を計算しました。しかし、それは 741120 バイトになります。そして、それは合いません。1480320バイトになると予想していました。

計算でエラーを見つけようとしていますが、うまくいきません。

誰かが私がどこで間違ったのか見ていますか?

助けてくれてありがとう!

4

1 に答える 1

1

そうです、私のコメントを拡張します。問題はここにあります:

fread(m_fbytes, sizeof(short), 960, fin);

2 バイト幅の960short秒を読み取っているので、実際には1920バイトを読み取っています。圧縮されたサイズをバイト単位で返す場合、ロバートが観察したopus_encode()ように圧縮率になります。32

また、チャンクを処理するコードを簡素化します。

size_t ITEM_SIZE = sizeof(short);
int ITEM_COUNT = 960;

// fread should first return a short item count, then zero
size_t shorts_read = 0;
while (shorts_read = fread(m_fbytes, ITEM_SIZE, ITEM_COUNT, fin)) {
    size_t i = 0;
    for (; i<read; i++) {
        opus_int32 s;
        // etc.
    }
    for (; i < ITEM_COUNT; i++) {
        m_in[i] = 0;
    }
    // opus_encode() etc
}

役に立たない停止フラグとネストのレベルを取り除き、構造は「できないまで読む」の慣用句です。(この SO の質問を参照してください。)

freadコードがばかげていると述べたことを撤回します。読み取ったアイテムではなく、読み取ったバイトを返すと思いました。

于 2013-05-20T16:19:04.243 に答える