📄 acwav.cpp
字号:
int transform[],
int buffer[])
{
// dyadic S+P inverse transform
for (int lv = 5; lv >= 0; lv--) {
int fd = ed >> lv, hd = fd >> 1;
memcpy(buffer, transform, fd * sizeof(int));
SpP_Synthesis(fd, buffer, buffer + hd, transform);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Separate_Channels(unsigned od,
unsigned ed,
short * data,
int left[],
int right[])
{
unsigned k; // separate interleaved left and right channels
for (k = 0; k < od; k++) {
left[k] = int(*data++);
right[k] = int(*data++);
}
for (k = od; k < ed; k++) {
left[k] = (7 * left[k-1]) >> 3;
right[k] = (7 * right[k-1]) >> 3;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Interleave_Channels(unsigned od,
int left[],
int right[],
short * data)
{
for (unsigned k = 0; k < od; k++) {
*data++ = short(left[k]);
*data++ = short(right[k]);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Encode_SpP(unsigned dim,
int transform[],
Arithmetic_Codec & encoder,
Adaptive_Data_Model data_model[])
{
float ctx = 0;
for (int k = dim - 1; k >= 0; k--) {
int nm = int(ctx); // context = weighted average of past values
unsigned bits, data;
Split_Integer(transform[k], bits, data);
encoder.encode(bits, data_model[nm]); // encode with context
if (bits) // write "raw" bits
if (bits == 1)
encoder.put_bit(data);
else
encoder.put_bits(data, bits);
ctx = 0.9F * ctx + 0.2F * bits; // update soft context
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Decode_SpP(unsigned dim,
Arithmetic_Codec & decoder,
Adaptive_Data_Model data_model[],
int transform[])
{
float ctx = 0;
for (int k = dim - 1; k >= 0; k--) {
int nm = int(ctx); // context = weighted average of past values
unsigned bits = decoder.decode(data_model[nm]); // decode with context
if (bits == 0)
transform[k] = 0;
else // read "raw" bits
if (bits == 1)
transform[k] = (decoder.get_bit() ? -1 : 1);
else
transform[k] = Restore_Integer(bits, decoder.get_bits(bits));
ctx = 0.9F * ctx + 0.2F * bits; // update soft context
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FILE * Open_Input_File(unsigned file_id,
char * file_name,
unsigned char header[44])
{
FILE * new_file = fopen(file_name, "rb");
if (new_file == 0) Error("cannot open input file");
if (fread(header, 1, 44, new_file) != 44) Error(R_MSG);
if (Recover_Number(header) != file_id)
Error("invalid input file");
for (unsigned n = 4; n < 44; n++)
if ((WAVE_HEADER[n] != 0x7F) && (WAVE_HEADER[n] != header[n]))
Error("unsupported audio file");
return new_file;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FILE * Open_Output_File(unsigned file_id,
char * file_name,
unsigned char header[44])
{
FILE * new_file = fopen(file_name, "rb");
if (new_file != 0) {
fclose(new_file);
printf("\n Overwrite file %s? (y = yes, otherwise quit) ", file_name);
char line[128];
gets(line);
if (line[0] != 'y') exit(0);
}
new_file = fopen(file_name, "wb");
if (new_file == 0) Error("cannot open output file");
Save_Number(file_id, header);
if (fwrite(header, 1, 44, new_file) != 44) Error(W_MSG);
return new_file;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Encode_WAV_File(char * data_file_name,
char * code_file_name)
{
// open files
unsigned char header[44];
FILE * data_file = Open_Input_File(WAV_ID, data_file_name, header);
unsigned file_samples = Audio_Samples(header);
if ((file_samples < 64) || (file_samples >= 0x10000000U))
Error("invalid WAV file");
FILE * code_file = Open_Output_File(ACW_ID, code_file_name, header);
// memory for audio data
int * data = new int[3*BufferSize];
int * left_channel = data + BufferSize;
int * right_channel = data + BufferSize * 2;
Arithmetic_Codec encoder(5 * BufferSize);
Adaptive_Data_Model * dm = new Adaptive_Data_Model[NumModels];
for (unsigned m = 0; m < NumModels; m++) dm[m].set_alphabet(24);
unsigned crc = 0;
do {
unsigned ns = (file_samples < BufferSize ? file_samples : BufferSize);
unsigned es = (ns + 63) & 0xFFFFFFC0U; // next multiple of 64
file_samples -= ns;
if (fread(data, 4, ns, data_file) != ns) Error(R_MSG); // read audio
crc ^= Buffer_CRC(4 * ns, (unsigned char *) data); // compute CRC
Separate_Channels(ns, es, (short*) data, left_channel, right_channel);
SpP_Analysis(es, left_channel, data); // compute transforms
SpP_Analysis(es, right_channel, data);
encoder.start_encoder(); // prepare to compress
Encode_SpP(es, left_channel, encoder, dm); // compress transforms
Encode_SpP(es, right_channel, encoder, dm);
encoder.write_to_file(code_file); // stop and write compressed data
} while (file_samples);
// save file CRC
Save_Number(crc, header);
if (fwrite(header, 1, 4, code_file) != 4) Error(W_MSG);
// done: close files
fflush(code_file);
unsigned data_bytes = ftell(data_file), code_bytes = ftell(code_file);
printf(" Compressed file size = %d bytes (%5.2f:1 compression)\n",
code_bytes, double(data_bytes) / double(code_bytes));
fclose(data_file);
fclose(code_file);
delete [] data;
delete [] dm;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Decode_WAV_File(char * code_file_name,
char * data_file_name)
{
// open files
unsigned char header[44];
FILE * code_file = Open_Input_File(ACW_ID, code_file_name, header);
FILE * data_file = Open_Output_File(WAV_ID, data_file_name, header);
unsigned file_samples = Audio_Samples(header);
// memory for audio data
int * data = new int[3*BufferSize];
int * left_channel = data + BufferSize;
int * right_channel = data + BufferSize * 2;
Arithmetic_Codec decoder(5 * BufferSize);
Adaptive_Data_Model * dm = new Adaptive_Data_Model[NumModels];
for (unsigned m = 0; m < NumModels; m++) dm[m].set_alphabet(24);
unsigned crc = 0;
do {
unsigned ns = (file_samples < BufferSize ? file_samples : BufferSize);
unsigned es = (ns + 63) & 0xFFFFFFC0U; // next multiple of 64
file_samples -= ns;
decoder.read_from_file(code_file); // read compressed data, start decoder
Decode_SpP(es, decoder, dm, left_channel); // decompress transforms
Decode_SpP(es, decoder, dm, right_channel);
decoder.stop_decoder(); // stop decoder
SpP_Synthesis(es, left_channel, data); // compute transforms
SpP_Synthesis(es, right_channel, data);
Interleave_Channels(ns, left_channel, right_channel, (short*) data);
crc ^= Buffer_CRC(4 * ns, (unsigned char *) data); // compute CRC
if (fwrite(data, 4, ns, data_file) != ns) Error(W_MSG); // read audio
} while (file_samples);
// check if file is correct
if (fread(header, 1, 4, code_file) != 4) Error(R_MSG);
if (crc != Recover_Number(header)) Error("incorrect file CRC");
// done: close files
fclose(data_file);
fclose(code_file);
delete [] data;
delete [] dm;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -