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