2013-05-20 1 views
3

겉으로보기에는 단순한 계산으로 2 일이 지나서 붙어 있습니다. 그러나 나는 그것을 얻지 못합니다.C++ 알고리즘 압축률 계산

압축 알고리즘으로 오디오 파일을 인코딩 중입니다.

전체 오디오 파일은 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); 
} 

압축 비율은 16

그래서 계산 46,320 바이트 * 16 을 = 60분의 960 것 같다하지만 그 741,120에 저를 가져옵니다 여기

파일을 인코딩하는 방법입니다 바이트. 그건 맞지 않아. 나는 그것이 1480320 바이트라고 예상했다.

계산에서 오류를 찾으려고하는데 관리하지 않습니다.

어디서 잘못 본 사람이 있습니까?

도움을 주셔서 감사합니다.

+0

실제 압축 비율은 16이 아닌 32로 나타납니다. –

+1

나는 당신에게 나쁜 소식을 전했다고 생각합니다. 각 척은 60 바이트로 압축되지 않습니다. 그 또는 각 청크는 960 바이트가 아닙니다. 글쎄요, 실제로 그것은 좋은 뉴스입니다. 왜냐하면 그것은 그것보다 덜/더 (각각) 때문입니다. – Dukeling

+0

다른 덩어리가 모두 균일하게 압축되기보다는 다른 크기로 압축 될 수 있습니까? 압축 알고리즘이 무엇인지 압니까? – Daniel

답변

1

내 의견을 확장하는 것이 좋습니다.

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

당신은 2 바이트 폭해야 960 개 short들, 읽고, 그래서 당신은 정말 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 
} 

당신은 쓸모 정지 플래그와 중첩 수준을 제거하고 구조가에 대한 관용적 인 "당신은 할 수 없습니다 때까지 읽습니다. " (this SO question을 참조하십시오.)

나는 코드가 hokey 인 것에 대해 언급 한 내용을 철회했으며, fread은 읽은 바이트가 아니라 읽은 바이트를 반환한다고 생각했습니다.