diff options
Diffstat (limited to 'src/hd24wavefix.cpp')
-rwxr-xr-x | src/hd24wavefix.cpp | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/src/hd24wavefix.cpp b/src/hd24wavefix.cpp new file mode 100755 index 0000000..c7ab2f0 --- /dev/null +++ b/src/hd24wavefix.cpp | |||
@@ -0,0 +1,207 @@ | |||
1 | #include "config.h" | ||
2 | #include <iostream> | ||
3 | #include <algorithm> | ||
4 | #include <cctype> | ||
5 | #include <string> | ||
6 | #include "hd24fs.h" | ||
7 | #include <sys/types.h> | ||
8 | #include <sys/stat.h> | ||
9 | #include <fcntl.h> | ||
10 | #ifndef WINDOWS | ||
11 | #include <unistd.h> | ||
12 | #endif | ||
13 | #include <stdio.h> | ||
14 | #include <stdlib.h> | ||
15 | #include <iostream> | ||
16 | #include "convertlib.h" | ||
17 | #define HEADERSIZE 44 | ||
18 | #define SAMPLES_IN_HALF_BUF 1024*1024 | ||
19 | #define SAMPLES_IN_FULL_BUF 2*SAMPLES_IN_HALF_BUF | ||
20 | #define BYTES_PER_SAM 3 | ||
21 | #define BYTES_IN_HALF_BUF BYTES_PER_SAM*SAMPLES_IN_HALF_BUF | ||
22 | #define BYTES_IN_FULL_BUF BYTES_PER_SAM*SAMPLES_IN_FULL_BUF | ||
23 | char audiobuf[BYTES_IN_FULL_BUF]; | ||
24 | char fixbuf[BYTES_IN_HALF_BUF]; | ||
25 | string inputfile; | ||
26 | string outputfile; | ||
27 | int simple=0; | ||
28 | FILE* infile; | ||
29 | FILE* outfile; | ||
30 | __uint64 writeoffset; | ||
31 | |||
32 | void clearaudiobuf() | ||
33 | { | ||
34 | int i; | ||
35 | for (i=0;i<BYTES_IN_FULL_BUF;i++) { | ||
36 | audiobuf[i]=0; | ||
37 | } | ||
38 | } | ||
39 | void shiftaudiobuf() | ||
40 | { | ||
41 | int i; | ||
42 | for (i=0;i<BYTES_IN_HALF_BUF;i++) { | ||
43 | audiobuf[i]=audiobuf[i+BYTES_IN_HALF_BUF]; | ||
44 | audiobuf[i+BYTES_IN_HALF_BUF]=0; | ||
45 | } | ||
46 | } | ||
47 | int getsam(int samnum) | ||
48 | { | ||
49 | int samval=audiobuf[samnum+BYTES_IN_HALF_BUF] | ||
50 | +(audiobuf[samnum+BYTES_IN_HALF_BUF]*256) | ||
51 | +(audiobuf[samnum+BYTES_IN_HALF_BUF]*256*256); | ||
52 | return samval; | ||
53 | } | ||
54 | int tosigned(int samval) { | ||
55 | if (samval>=(1<<23)) { | ||
56 | samval-=(1<<24); | ||
57 | } | ||
58 | return samval; | ||
59 | } | ||
60 | int topos(int samval) { | ||
61 | return samval+(1<<23); | ||
62 | } | ||
63 | bool fileexists (string* fname) { | ||
64 | struct stat fi; | ||
65 | if ((stat (fname->c_str(), &fi) != -1) && ((fi.st_mode & S_IFDIR) == 0)) { | ||
66 | return true; | ||
67 | } | ||
68 | return false; | ||
69 | } | ||
70 | void hd24seek(FSHANDLE devhd24,__uint64 seekpos) | ||
71 | { | ||
72 | #if defined(LINUX) || defined(DARWIN) | ||
73 | lseek(devhd24,seekpos,0); | ||
74 | // lseek64(devhd24,seekpos,0); | ||
75 | #endif | ||
76 | #ifdef WINDOWS | ||
77 | LARGE_INTEGER li; | ||
78 | li.HighPart=seekpos>>32; | ||
79 | li.LowPart=seekpos%((__uint64)1<<32); | ||
80 | SetFilePointerEx(devhd24,li,NULL,FILE_BEGIN); | ||
81 | #endif | ||
82 | return; | ||
83 | } | ||
84 | |||
85 | int parsecommandline(int argc, char ** argv) | ||
86 | { | ||
87 | int invalid=0; | ||
88 | inputfile=""; | ||
89 | outputfile=""; | ||
90 | for (int c=1;c<argc;c++) { | ||
91 | string arg=argv[c]; | ||
92 | if (arg.substr(0,strlen("--input="))=="--input=") { | ||
93 | inputfile=arg.substr(strlen("--input=")); | ||
94 | continue; | ||
95 | } | ||
96 | if (arg.substr(0,strlen("--output="))=="--output=") { | ||
97 | outputfile=arg.substr(strlen("--output=")); | ||
98 | continue; | ||
99 | } | ||
100 | if (arg.substr(0,strlen("--simple"))=="--simple") { | ||
101 | simple=1; | ||
102 | continue; | ||
103 | } | ||
104 | cout << "Invalid argument: " << arg << endl; | ||
105 | invalid=1; | ||
106 | } | ||
107 | return invalid; | ||
108 | } | ||
109 | void findmask(FILE* infile) | ||
110 | { | ||
111 | fseek(infile,HEADERSIZE,SEEK_SET); | ||
112 | return; | ||
113 | } | ||
114 | void copyheader(FILE* infile,FILE* outfile) | ||
115 | { | ||
116 | char buffer[HEADERSIZE]; | ||
117 | fseek(infile,0,SEEK_SET); | ||
118 | int readcount=fread((void*)&buffer[0],1,HEADERSIZE,infile); | ||
119 | if (readcount>0) { | ||
120 | int writecount=fwrite((const void*)&buffer[0],1,HEADERSIZE,outfile); | ||
121 | if (writecount==0) { | ||
122 | cout << "Cannot write output file" << endl; | ||
123 | } | ||
124 | } | ||
125 | return; | ||
126 | } | ||
127 | void copyaudio(FILE* infile,FILE* outfile) { | ||
128 | int readcount; | ||
129 | do { | ||
130 | shiftaudiobuf(); | ||
131 | readcount=fread((void*)&audiobuf[BYTES_IN_HALF_BUF],1,BYTES_IN_HALF_BUF,infile); | ||
132 | for (int i=0; i<SAMPLES_IN_HALF_BUF-1;i+=2) { | ||
133 | int q0=3; | ||
134 | int q1=0; | ||
135 | if (audiobuf[BYTES_IN_HALF_BUF+i*3+q0+2-6]==audiobuf[BYTES_IN_HALF_BUF+i*3+q1+2]) { | ||
136 | audiobuf[BYTES_IN_HALF_BUF+i*3+q0+2]=audiobuf[BYTES_IN_HALF_BUF+i*3+q1+2]; | ||
137 | } else { | ||
138 | audiobuf[BYTES_IN_HALF_BUF+i*3+q0+0]=audiobuf[BYTES_IN_HALF_BUF+i*3+q1+0]; | ||
139 | audiobuf[BYTES_IN_HALF_BUF+i*3+q0+1]=audiobuf[BYTES_IN_HALF_BUF+i*3+q1+1]; | ||
140 | audiobuf[BYTES_IN_HALF_BUF+i*3+q0+2]=audiobuf[BYTES_IN_HALF_BUF+i*3+q1+2]; | ||
141 | } | ||
142 | } | ||
143 | if (readcount>0) { | ||
144 | int writecount=fwrite( | ||
145 | (void*)&audiobuf[BYTES_IN_HALF_BUF],1,readcount,outfile); | ||
146 | if (writecount==0) { | ||
147 | cout << "Cannot write output file" << endl; | ||
148 | } | ||
149 | } | ||
150 | |||
151 | } | ||
152 | while (readcount>0); | ||
153 | return; | ||
154 | } | ||
155 | void simplecopyaudio(FILE* infile,FILE* outfile) | ||
156 | { | ||
157 | int readcount; | ||
158 | do { | ||
159 | readcount=fread((void*)&audiobuf[BYTES_IN_HALF_BUF],1,BYTES_IN_HALF_BUF,infile); | ||
160 | for (int i=0; i<SAMPLES_IN_HALF_BUF-1;i+=2) { | ||
161 | int q0=3; | ||
162 | int q1=0; | ||
163 | audiobuf[BYTES_IN_HALF_BUF+i*3+q0+0]=audiobuf[BYTES_IN_HALF_BUF+i*3+q1+0]; | ||
164 | audiobuf[BYTES_IN_HALF_BUF+i*3+q0+1]=audiobuf[BYTES_IN_HALF_BUF+i*3+q1+1]; | ||
165 | audiobuf[BYTES_IN_HALF_BUF+i*3+q0+2]=audiobuf[BYTES_IN_HALF_BUF+i*3+q1+2]; | ||
166 | } | ||
167 | if (readcount>0) { | ||
168 | int writecount=fwrite( | ||
169 | (void*)&audiobuf[BYTES_IN_HALF_BUF],1,readcount,outfile); | ||
170 | if (writecount==0) { | ||
171 | cout << "Cannot write output file" << endl; | ||
172 | } | ||
173 | } | ||
174 | |||
175 | } | ||
176 | while (readcount>0); | ||
177 | return; | ||
178 | } | ||
179 | void dothefix(FILE* infile, FILE* outfile) | ||
180 | { | ||
181 | copyheader(infile,outfile); | ||
182 | findmask(infile); | ||
183 | if (simple==1) { | ||
184 | simplecopyaudio(infile,outfile); | ||
185 | } else { | ||
186 | copyaudio(infile,outfile); | ||
187 | } | ||
188 | } | ||
189 | int main (int argc,char ** argv) | ||
190 | { | ||
191 | int invalid=parsecommandline(argc,argv); | ||
192 | if (invalid!=0) { | ||
193 | return invalid; | ||
194 | } | ||
195 | if ((inputfile=="")||(outputfile=="")) { | ||
196 | cout << "Usage: hd24wavefix [--simple] --input=<inputfile> --output=<outputfile>" << endl; | ||
197 | return 1; | ||
198 | } | ||
199 | clearaudiobuf(); | ||
200 | // Open files | ||
201 | infile=fopen(inputfile.c_str(),"rb"); | ||
202 | outfile=fopen(outputfile.c_str(),"wb"); | ||
203 | dothefix(infile,outfile); | ||
204 | fclose(outfile); | ||
205 | fclose(infile); | ||
206 | return 0; | ||
207 | } | ||