00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #define BYTE unsigned char
00033 #define WORD unsigned short
00034 #define DWORD unsigned long
00035
00036 #define WAVE_FORMAT_DVI_ADPCM 0x0011
00037
00038 #define BLOCK_SIZE (512/2)
00039 #define SAMPLE_RATE 8000
00040
00041 typedef struct __attribute__((__packed__))
00042 {
00043 BYTE chunk_id[4];
00044 DWORD chunk_size;
00045 BYTE riff_type[4];
00046 }s_wave_riff;
00047
00048 typedef struct __attribute__((__packed__))
00049 {
00050 BYTE chunk_id[4];
00051 DWORD chunk_size;
00052 WORD compression_code;
00053 WORD nb_channels;
00054 DWORD sample_rate;
00055 DWORD avg_bytes_per_sec;
00056 WORD block_align;
00057 WORD bits_per_sample;
00058 WORD extra_bytes;
00059 }s_wave_fmt;
00060
00061 typedef struct __attribute__((__packed__))
00062 {
00063 s_wave_fmt fmt;
00064 WORD samples_per_block;
00065 }s_wave_fmt_dvi;
00066
00067 typedef struct __attribute__((__packed__))
00068 {
00069 BYTE chunk_id[4];
00070 DWORD chunk_size;
00071 }s_wave_data;
00072
00073 typedef struct __attribute__((__packed__))
00074 {
00075 WORD isamp0;
00076 BYTE step_table_index;
00077 BYTE reserved;
00078 }s_wave_dvi_block_header;
00079
00080
00081
00082
00083
00084 int fget_struct(FILE *_file, void *_ptr, int size, char *_start_str)
00085 {
00086 int end;
00087 char *_str;
00088
00089 end = 0;
00090 while(!feof(_file) && !end)
00091 {
00092 _str = _start_str;
00093 while(*_str == fgetc(_file))
00094 {
00095 _str++;
00096 if (!*_str)
00097 {
00098 end = 1;
00099 break;
00100 }
00101 }
00102 }
00103
00104 if (!end)
00105 return 0;
00106
00107 fseek(_file, -strlen(_start_str), SEEK_CUR);
00108 fread(_ptr, 1, size, _file);
00109
00110 return 1;
00111 }
00112
00113 int main(int argc, char *_argv[])
00114 {
00115 FILE *_file, *_file_out;
00116 s_wave_riff header_riff;
00117 s_wave_fmt_dvi header_dvi;
00118 s_wave_data header_data;
00119 s_wave_dvi_block_header header_block;
00120 short step_index;
00121 short predicted_value;
00122 char *_buffer;
00123 int i, j, k, l, nb_bytes_per_block;
00124 int block_size;
00125 char c;
00126 int block_sent = 0;
00127 int end = 0;
00128 char _progress_bar[33];
00129 int file_size;
00130 int nb_blocks;
00131
00132
00133 if (argc != 3)
00134 {
00135 printf("Usage: ADPCM_IMA_DVI input_file output_file\n");
00136 return 0;
00137 }
00138
00139 printf("Opening input file %s for reading...", _argv[1]);
00140 fflush(stdout);
00141 _file = fopen(_argv[1], "rb");
00142 if (!_file)
00143 {
00144 printf("\t[ FAILED ]\n");
00145 return 0;
00146 }
00147 printf("\t[ OK ]\n");
00148
00149 printf("Opening output file %s for writing...", _argv[2]);
00150 fflush(stdout);
00151 _file_out = fopen(_argv[2], "wb");
00152 if (!_file_out)
00153 {
00154 printf("\t[ FAILED ]\n");
00155 return 0;
00156 }
00157 printf("\t[ OK ]\n");
00158
00159
00160 fseek(_file, 0, SEEK_END);
00161 file_size = ftell(_file);
00162 fseek(_file, 0, SEEK_SET);
00163
00164
00165 nb_blocks = file_size/(BLOCK_SIZE + 4);
00166
00167 file_size = nb_blocks*256;
00168
00169 file_size += (sizeof(header_riff) + sizeof(header_dvi) + sizeof(header_data));
00170
00171 printf("nb_blocks: %i\n", nb_blocks);
00172
00173 _buffer = malloc((header_dvi.fmt.block_align-sizeof(s_wave_dvi_block_header)));
00174
00175
00176 header_riff.chunk_id[0] = 'R';
00177 header_riff.chunk_id[1] = 'I';
00178 header_riff.chunk_id[2] = 'F';
00179 header_riff.chunk_id[3] = 'F';
00180 header_riff.chunk_size = file_size - 8;
00181 header_riff.riff_type[0] = 'W';
00182 header_riff.riff_type[1] = 'A';
00183 header_riff.riff_type[2] = 'V';
00184 header_riff.riff_type[3] = 'E';
00185
00186
00187 header_dvi.fmt.chunk_id[0] = 'f';
00188 header_dvi.fmt.chunk_id[1] = 'm';
00189 header_dvi.fmt.chunk_id[2] = 't';
00190 header_dvi.fmt.chunk_id[3] = ' ';
00191 header_dvi.fmt.chunk_size = 0x14;
00192 header_dvi.fmt.compression_code = WAVE_FORMAT_DVI_ADPCM;
00193 header_dvi.fmt.nb_channels = 1;
00194 header_dvi.fmt.sample_rate = SAMPLE_RATE;
00195 header_dvi.fmt.avg_bytes_per_sec = SAMPLE_RATE/2;
00196 header_dvi.fmt.block_align = 256;
00197 header_dvi.fmt.bits_per_sample = 4;
00198 header_dvi.fmt.extra_bytes = sizeof(header_dvi) - sizeof(header_dvi.fmt);
00199 header_dvi.samples_per_block = (header_dvi.fmt.block_align - (4*header_dvi.fmt.nb_channels))*8/(header_dvi.fmt.bits_per_sample*header_dvi.fmt.nb_channels)+1;
00200
00201
00202 header_data.chunk_id[0] = 'd';
00203 header_data.chunk_id[1] = 'a';
00204 header_data.chunk_id[2] = 't';
00205 header_data.chunk_id[3] = 'a';
00206 header_data.chunk_size = file_size - sizeof(header_riff) - sizeof(header_dvi) - sizeof(header_data);
00207
00208
00209 nb_bytes_per_block = (header_dvi.fmt.block_align/(4*header_dvi.fmt.nb_channels)-1);
00210 block_size = nb_bytes_per_block*4;
00211
00212
00213 fwrite(&header_riff, 1, sizeof(s_wave_riff), _file_out);
00214 fwrite(&header_dvi, 1, sizeof(s_wave_fmt_dvi), _file_out);
00215 fwrite(&header_data, 1, sizeof(s_wave_data), _file_out);
00216
00217 printf("File size: %i\n", sizeof(s_wave_riff) + sizeof(s_wave_fmt_dvi) + sizeof(s_wave_data) + (sizeof(s_wave_dvi_block_header) + header_dvi.fmt.block_align-sizeof(s_wave_dvi_block_header))*nb_blocks);
00218
00219 printf("Creation of the IMA/DVI ADPCM Wave file...");
00220 fflush(stdout);
00221
00222
00223 for(j=0; j<nb_blocks; j++)
00224 {
00225
00226 fread(&header_block.isamp0, 1, 2, _file);
00227
00228 fread(&header_block.step_table_index, 1, 2, _file);
00229 header_block.reserved = 0;
00230
00231 #ifdef __DEBUG
00232 printf("predicted_value: %i | step_index: %i\n", header_block.isamp0, header_block.step_table_index);
00233 #endif
00234
00235 fwrite(&header_block, 1, sizeof(s_wave_dvi_block_header), _file_out);
00236
00237
00238 fread(_buffer, 1, header_dvi.fmt.block_align-sizeof(s_wave_dvi_block_header), _file);
00239 fwrite(_buffer, 1, header_dvi.fmt.block_align-sizeof(s_wave_dvi_block_header), _file_out);
00240 }
00241
00242 printf("\t[ OK ]\n");
00243
00244 free(_buffer);
00245
00246 fclose(_file);
00247 fclose(_file_out);
00248
00249 return 1;
00250 }