6 #include "audioconvert.hpp"
8 #define BLOCKSAMPLES 1024
10 #define OUTSAMPLESIZE 4
13 #define RIFF_MAGIC 0x46464952
14 #define WAVE_MAGIC 0x45564157
15 #define FMT_MAGIC 0x20746d66
16 #define DATA_MAGIC 0x61746164
18 static short do_filter(std::vector
<double>* old_input
, std::vector
<double>* old_output
,
19 std::vector
<double>& numerator
, std::vector
<double>& denumerator
, size_t* lag
, size_t delay
,
20 unsigned index
, double amplification
, double preamp
, short sample
, uint64_t& clipcount
)
24 double in
= (double)sample
* preamp
;
25 size_t nsize
= numerator
.size();
26 size_t dsize
= denumerator
.size();
30 memmove(&old_input
[index
][1], &old_input
[index
][0], (nsize
- 1) * sizeof(double));
31 old_input
[index
][0] = in
;
33 size_t old_lag
= lag
[index
];
37 return 0; //No sample yet.
40 for(size_t j
= 0; j
< nsize
; j
++)
41 out
+= numerator
[j
] * old_input
[index
][j
];
42 for(size_t j
= 1; j
< dsize
; j
++)
43 out
-= denumerator
[j
] * old_output
[index
][j
];
45 //Save output. The last sample needs to wind up into index 1. Also scale by denum[0].
46 out
/= denumerator
[0];
47 old_output
[index
][0] = out
;
49 memmove(&old_output
[index
][1], &old_output
[index
][0], (dsize
- 1) * sizeof(double));
51 //Finally amplify and cast back.
56 } else if(out
> 32767) {
64 static void write_little32(unsigned char* to
, uint32_t value
)
66 to
[0] = (value
) & 0xFF;
67 to
[1] = (value
>> 8) & 0xFF;
68 to
[2] = (value
>> 16) & 0xFF;
69 to
[3] = (value
>> 24) & 0xFF;
72 static void write_little16(unsigned char* to
, uint16_t value
)
74 to
[0] = (value
) & 0xFF;
75 to
[1] = (value
>> 8) & 0xFF;
78 void write_wav_header(struct converter_parameters
* params
, FILE* out
, uint64_t samples
)
80 unsigned char header
[44];
83 if(samples
== OUTPUT_MAX_UNLIMITED
) {
89 if((size2
>> 2) != samples
|| size1
< 36 || size1
> 0x7FFFFFFF) {
90 fprintf(stderr
, "Error: Too many samples for wav file.\n");
95 write_little32(header
+ 0, RIFF_MAGIC
); //The main RIFF header.
96 write_little32(header
+ 4, size1
); //File size.
97 write_little32(header
+ 8, WAVE_MAGIC
); //This is wave data.
98 write_little32(header
+ 12, FMT_MAGIC
); //Format data.
99 write_little32(header
+ 16, 16); //16 bytes of format for PCM.
100 write_little16(header
+ 20, 1); //PCM data.
101 write_little16(header
+ 22, 2); //Stereo
102 write_little32(header
+ 24, params
->output_rate
); //Sample rate.
103 write_little32(header
+ 28, params
->output_rate
<< 2); //Data rate.
104 write_little16(header
+ 32, 4); //4 bytes per sample.
105 write_little16(header
+ 34, 16); //16 bits.
106 write_little32(header
+ 36, DATA_MAGIC
); //Actual data.
107 write_little32(header
+ 40, size2
); //Data size.
108 if(fwrite(header
, 1, 44, out
) < 44) {
109 fprintf(stderr
, "Error: Can't write wave header.\n");
114 static void start_output_file(struct converter_parameters
* params
, FILE* out
)
116 if(params
->output_type
== OUTPUT_TYPE_WAV
) {
117 write_wav_header(params
, out
, OUTPUT_MAX_UNLIMITED
);
121 static void finish_output_file(struct converter_parameters
* params
, FILE* out
, uint64_t samples
)
123 if(params
->output_type
== OUTPUT_TYPE_WAV
) {
124 if(fseek(out
, 0, SEEK_SET
)) {
125 fprintf(stderr
, "Warning: Can't seek output to fix wave header.");
127 write_wav_header(params
, out
, samples
);
130 fprintf(stderr
, "Error: Can't close output file.");
135 static short average_s(int64_t accumulator
, uint64_t base
, uint64_t bound
)
139 return (short)(accumulator
/ (int64_t)(bound
- base
));
142 void audioconvert(struct converter_parameters
* params
, struct filter
* filter
)
144 unsigned char inbuf
[SAMPLESIZE
* BLOCKSAMPLES
];
145 unsigned char outbuf
[OUTSAMPLESIZE
* BLOCKSAMPLES
];
146 unsigned inbuf_usage
= 0;
147 unsigned outbuf_usage
= 0;
148 uint64_t output_time
= 0;
149 uint64_t input_time
= 0;
150 unsigned short active_left
= 32768;
151 unsigned short active_right
= 32768;
152 int64_t left_accumulator
= 0;
153 int64_t right_accumulator
= 0;
154 uint64_t last_accumulator_update
= 0;
155 uint64_t accumulator_base
= 0;
158 float left_volume
= 1.0;
159 float right_volume
= 1.0;
160 unsigned subsample
= 0;
161 uint64_t seconds
= 0;
162 uint64_t samples_in_file
= 0;
163 uint64_t clipped
= 0;
167 std::vector
<double>* filter_numerator_ptr
= filter
? &(filter
->numerator
) : NULL
;
168 std::vector
<double>* filter_denumerator_ptr
= filter
? &(filter
->denumerator
) : NULL
;
169 std::vector
<double> dummy_vector
;
170 dummy_vector
.push_back(1.0);
171 if(!filter_numerator_ptr
|| filter_numerator_ptr
->size() == 0)
172 filter_numerator_ptr
= &dummy_vector
;
173 if(!filter_denumerator_ptr
|| filter_denumerator_ptr
->size() == 0)
174 filter_denumerator_ptr
= &dummy_vector
;
176 //Define handy variables for filter stuff.
177 size_t filter_input_delay
= filter
? filter
->input_delay
: 0;
178 std::vector
<double>& filter_numerator
= *filter_numerator_ptr
;
179 std::vector
<double>& filter_denumerator
= *filter_denumerator_ptr
;
180 if(filter_input_delay
>= filter_numerator
.size()) {
181 fprintf(stderr
, "Error: Filter delay too large (not enough coefficients).\n");
185 //Old input/output buffers (also clear them).
186 size_t input_lag
[2] = {0, 0};
187 std::vector
<double> old_input
[2];
188 std::vector
<double> old_output
[2];
189 old_input
[0].resize(filter_numerator
.size());
190 old_input
[1].resize(filter_numerator
.size());
191 for(size_t i
= 0; i
< filter_numerator
.size(); i
++) {
195 old_output
[0].resize(filter_denumerator
.size());
196 old_output
[1].resize(filter_denumerator
.size());
197 for(size_t i
= 0; i
< filter_denumerator
.size(); i
++) {
198 old_output
[0][i
] = 0;
199 old_output
[1][i
] = 0;
202 rate
= params
->output_rate
;
203 FILE* in
= params
->in
;
204 FILE* out
= params
->next_out(params
->opaque
);
206 fprintf(stderr
, "Error: Can't open output file.\n");
209 start_output_file(params
, out
);
211 if(params
->input_type
== INPUT_TYPE_FM
) {
216 if(!eofd
&& inbuf_usage
< BLOCKSAMPLES
* SAMPLESIZE
/ 2) {
217 r
= fread(inbuf
+ inbuf_usage
, 1, BLOCKSAMPLES
* SAMPLESIZE
- inbuf_usage
, in
);
218 if((unsigned)r
< BLOCKSAMPLES
* SAMPLESIZE
- inbuf_usage
)
220 inbuf_usage
+= (unsigned)r
;
222 //Invariant: eofd || inbuf_usage == BLOCKSAMPLES.
223 if(outbuf_usage
== BLOCKSAMPLES
) {
224 // fprintf(stderr, "Dumping block. Input time %llu, Output time %llu.\n", input_time,
226 r
= fwrite(outbuf
, OUTSAMPLESIZE
, BLOCKSAMPLES
, out
);
227 if(r
< BLOCKSAMPLES
) {
228 fprintf(stderr
, "Error: Can't write to output file.\n");
231 samples_in_file
+= BLOCKSAMPLES
;
232 if(samples_in_file
> params
->output_max
) {
233 finish_output_file(params
, out
, samples_in_file
);
234 out
= params
->next_out(params
->opaque
);
236 fprintf(stderr
, "Error: Can't open output file.\n");
239 start_output_file(params
, out
);
244 //Invariant: outbuf_usage < BLOCKSAMPLES.
245 unsigned long delta
= 0;
247 if(eofd
&& inbuf_usage
< SAMPLESIZE
)
251 delta
= ((unsigned long)inbuf
[0] << 24) | ((unsigned long)inbuf
[1] << 16) |
252 ((unsigned long)inbuf
[2] << 8) | (unsigned long)inbuf
[3];
253 if(input_time
+ delta
> output_time
|| !load_delta
) {
254 short active_xleft
, active_xright
;
255 if(params
->input_type
== INPUT_TYPE_FM
) {
257 adlib_getsample(samples
, 1);
258 active_xleft
= samples
[0];
259 active_xright
= samples
[1];
261 left_accumulator
+= (int64_t)(output_time
- last_accumulator_update
) *
263 right_accumulator
+= (int64_t)(output_time
- last_accumulator_update
) *
265 last_accumulator_update
= output_time
;
266 active_xleft
= average_s(left_accumulator
, accumulator_base
, output_time
);
267 active_xright
= average_s(right_accumulator
, accumulator_base
, output_time
);
271 active_xleft
= do_filter(old_input
, old_output
, filter_numerator
, filter_denumerator
,
272 input_lag
, filter_input_delay
, 0, params
->amplification
, left_volume
, active_xleft
,
274 active_xright
= do_filter(old_input
, old_output
, filter_numerator
, filter_denumerator
,
275 input_lag
, filter_input_delay
, 1, params
->amplification
, right_volume
, active_xright
,
278 outbuf
[outbuf_usage
* OUTSAMPLESIZE
+ 0] = (unsigned char)active_xleft
;
279 outbuf
[outbuf_usage
* OUTSAMPLESIZE
+ 1] = (unsigned char)(active_xleft
>> 8);
280 outbuf
[outbuf_usage
* OUTSAMPLESIZE
+ 2] = (unsigned char)active_xright
;
281 outbuf
[outbuf_usage
* OUTSAMPLESIZE
+ 3] = (unsigned char)(active_xright
>> 8);
282 left_accumulator
= 0;
283 right_accumulator
= 0;
284 accumulator_base
= output_time
;
287 if(subsample
== (unsigned)rate
) {
291 output_time
= seconds
* 1000000000 + (1000000000ULL * subsample
) / rate
;
294 } else if(delta
== 0xFFFFFFFFUL
) {
295 input_time
= input_time
+ delta
;
297 memmove(inbuf
, inbuf
+ 4, inbuf_usage
);
299 input_time
= input_time
+ delta
;
300 if(params
->input_type
!= INPUT_TYPE_FM
) {
301 left_accumulator
+= (int64_t)(input_time
- last_accumulator_update
) *
303 right_accumulator
+= (int64_t)(input_time
- last_accumulator_update
) *
305 last_accumulator_update
= input_time
;
307 active_left
= ((unsigned short)inbuf
[4] << 8) | (unsigned short)inbuf
[5];
308 active_right
= ((unsigned short)inbuf
[6] << 8) | (unsigned short)inbuf
[7];
309 inbuf_usage
-= SAMPLESIZE
;
310 memmove(inbuf
, inbuf
+ SAMPLESIZE
, inbuf_usage
);
311 if(params
->input_type
== INPUT_TYPE_FM
) {
312 if(active_left
& 0x800) {
313 left_volume
= (float)(active_left
& 0x7FF) / 255;
314 right_volume
= (float)(active_right
& 0x7FF) / 255;
315 fprintf(stderr
, "Note: Volume now %f:%f.\n", (double)left_volume
,
316 (double)right_volume
);
317 } else if(active_left
== 512) {
320 for(i
= 0; i
< 512; i
++) {
323 } else if(active_left
< 512) {
324 adlib_write(active_left
, active_right
);
326 fprintf(stderr
, "Warning: Ignored unknown FM command: %04X/%04X\n",
327 active_left
, active_right
);
333 r
= fwrite(outbuf
, OUTSAMPLESIZE
, outbuf_usage
, out
);
334 if((unsigned)r
< outbuf_usage
) {
335 fprintf(stderr
, "Error: Can't write to output file.\n");
338 samples_in_file
+= outbuf_usage
;
340 finish_output_file(params
, out
, samples_in_file
);
343 fprintf(stderr
, "Note: %llu samples clipped by filtering / amplification.\n",
344 (unsigned long long)clipped
);