OSDN Git Service

[*nix] Update installer.
[csp-qt/common_source_project-fm7.git] / source / tool / mz2500 / wav_apss.cpp
1 // wav.cpp : Defines the entry point for the console application.
2 //
3
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <tchar.h>
7
8 #ifndef uint8_t
9 typedef unsigned char uint8_t;
10 #endif
11 #ifndef uint16_t
12 typedef unsigned short uint16_t;
13 #endif
14 #ifndef uint32_t
15 typedef unsigned int uint32_t;
16 #endif
17
18 #ifndef int8_t
19 typedef signed char int8_t;
20 #endif
21 #ifndef int16_t
22 typedef signed short int16_t;
23 #endif
24 #ifndef int32_t
25 typedef signed int int32_t;
26 #endif
27
28 #pragma pack(1)
29 typedef struct {
30         char RIFF[4];
31         uint32_t file_len;
32         char WAVE[4];
33         char fmt[4];
34         uint32_t fmt_size;
35         uint16_t format_id;
36         uint16_t channels;
37         uint32_t sample_rate;
38         uint32_t data_speed;
39         uint16_t block_size;
40         uint16_t sample_bits;
41 } wav_header_t;
42 #pragma pack()
43
44 #pragma pack(1)
45 typedef struct {
46         char data[4];
47         uint32_t data_len;
48 } wav_data_t;
49 #pragma pack()
50
51 int _tmain(int argc, _TCHAR* argv[])
52 {
53         if(argc < 2) {
54                 printf("wav_apss (wav file) [threshold]\n\n");
55                 printf("Cleanup MZ-2500 tape file for APSS.\n");
56                 printf("The wave file should be pcm format, 16bit and 2ch.\n");
57                 return -1;
58         }
59         int threshold = 4096;
60         if(argc > 2) {
61                 threshold = _ttoi(argv[2]);
62         }
63         
64         FILE *fp = _tfopen(argv[1],_T("rb"));
65         
66         // check wav header
67         wav_header_t header;
68         wav_data_t data;
69         
70         fread(&header, sizeof(header), 1, fp);
71         fseek(fp, header.fmt_size - 0x10, SEEK_CUR);
72         fread(&data, sizeof(data), 1, fp);
73         long sample_top = ftell(fp);
74         
75         if(header.format_id != 1) {
76                 printf("The source wave file should be a pcm format.\n");
77                 fclose(fp);
78                 return -1;
79         }
80         if(header.channels != 2 || header.sample_bits != 16) {
81                 printf("The source wave file should be 16bit and 2ch.\n");
82                 fclose(fp);
83                 return -1;
84         }
85         int samples = data.data_len / 4;
86         
87         // load samples
88         int16_t* buffer_l = (int16_t *)malloc(samples * sizeof(int16_t));
89         int16_t* buffer_r = (int16_t *)malloc(samples * sizeof(int16_t));
90         
91         typedef union {
92                 int16_t s16;
93                 struct {
94                         uint8_t l, h;
95                 } b;
96         } sample_pair;
97         sample_pair sample;
98         
99         int count = 0, start, prev = 0;
100         
101         for(int i = 0; i < samples; i++) {
102                 sample.b.l = fgetc(fp);
103                 sample.b.h = fgetc(fp);
104                 buffer_l[i] = sample.s16;
105                 
106                 sample.b.l = fgetc(fp);
107                 sample.b.h = fgetc(fp);
108                 buffer_r[i] = sample.s16;
109                 
110                 if(abs(buffer_l[i]) > threshold) {
111                         if(count == 0) {
112                                 start = i;
113                         }
114                         count = 32 * header.sample_rate / 44100;
115                 }
116                 if(count > 0 && --count == 0) {
117                         int end = i;
118                         unsigned int width = end - start + 1;
119                         
120                         if(width > header.sample_rate * 250 / 1000) {
121                                 int count_p = 0, count_m = 0;
122                                 double volume = 0;
123                                 for(int j = start; j <= end; j++) {
124                                         if(buffer_l[j] > threshold) {
125                                                 count_p++;
126                                         } else if(buffer_l[j] < -threshold) {
127                                                 count_m++;
128                                         }
129                                         volume += buffer_l[j];
130                                 }
131                                 if((double)count_p / (double)width > 0.2 && (double)count_m / (double)width > 0.2) {
132                                         int16_t volume_ave = (int16_t)(volume / (double)width + 0.5);
133                                         int sec = start / header.sample_rate;
134                                         printf("Start = %d:%d\tWidth = %d (msec)\n", sec / 60, sec % 60, (int)(1000 * width / header.sample_rate));
135                                         for(int j = prev; j < start; j++) {
136                                                 buffer_l[j] = 0;
137                                         }
138                                         for(int j = start; j <= end; j++) {
139                                                 buffer_l[j] = buffer_l[j] > volume_ave ? 16384 : -16384;
140                                                 buffer_r[j] = 0;
141                                         }
142                                         prev = end + 1;
143                                 }
144                         }
145                 }
146         }
147         for(int j = prev; j < samples; j++) {
148                 buffer_l[j] = 0;
149         }
150         
151         // output wav file
152         FILE *fo = _tfopen(_T("output.wav"), _T("wb"));
153         fseek(fp, 0, SEEK_SET);
154         for(long i = 0; i < sample_top; i++) {
155                 fputc(fgetc(fp), fo);
156         }
157         for(int i = 0; i < samples; i++) {
158                 sample.s16 = buffer_l[i];
159                 fputc(sample.b.l, fo);
160                 fputc(sample.b.h, fo);
161                 
162                 sample.s16 = buffer_r[i];
163                 fputc(sample.b.l, fo);
164                 fputc(sample.b.h, fo);
165         }
166         fclose(fo);
167         
168         free(buffer_l);
169         free(buffer_r);
170         
171         fclose(fp);
172         
173         return 0;
174 }
175