218
218
#ifdef WITH_FFMPEG
220
#define RESAMPLE_FILL_RATIO (7.0/4.0)
222
static void sound_hdaudio_run_resampler_seek(
223
struct hdaudio * hdaudio)
225
int in_frame_size = (long long) hdaudio->sample_rate
226
* hdaudio->frame_duration / AV_TIME_BASE;
228
hdaudio->resample_samples_in = in_frame_size * RESAMPLE_FILL_RATIO;
229
hdaudio->resample_samples_written
230
= audio_resample(hdaudio->resampler,
231
hdaudio->resample_cache,
232
hdaudio->decode_cache_zero,
233
in_frame_size * RESAMPLE_FILL_RATIO);
236
static void sound_hdaudio_run_resampler_continue(
237
struct hdaudio * hdaudio)
239
int target_rate = hdaudio->target_rate;
240
int target_channels = hdaudio->target_channels;
242
int frame_size = (long long) target_rate
243
* hdaudio->frame_duration / AV_TIME_BASE;
244
int in_frame_size = (long long) hdaudio->sample_rate
245
* hdaudio->frame_duration / AV_TIME_BASE;
247
int reuse_tgt = (hdaudio->resample_samples_written
248
- frame_size) * target_channels;
249
int reuse_src = (hdaudio->resample_samples_in
250
- in_frame_size) * hdaudio->channels;
251
int next_samples_in =
252
in_frame_size * RESAMPLE_FILL_RATIO
253
- reuse_src / hdaudio->channels;
255
memmove(hdaudio->resample_cache,
256
hdaudio->resample_cache + frame_size * target_channels,
257
reuse_tgt * sizeof(short));
259
hdaudio->resample_samples_written
262
hdaudio->resample_cache + reuse_tgt,
263
hdaudio->decode_cache_zero + reuse_src,
265
+ reuse_tgt / target_channels;
267
hdaudio->resample_samples_in = next_samples_in
268
+ reuse_src / hdaudio->channels;
271
static void sound_hdaudio_init_resampler(
272
struct hdaudio * hdaudio,
273
int frame_position, int target_rate, int target_channels)
275
int frame_size = (long long) target_rate
276
* hdaudio->frame_duration / AV_TIME_BASE;
278
if (hdaudio->resampler &&
279
(hdaudio->target_rate != target_rate
280
|| hdaudio->target_channels != target_channels)) {
281
audio_resample_close(hdaudio->resampler);
282
hdaudio->resampler = 0;
284
if (!hdaudio->resampler) {
285
hdaudio->resampler = av_audio_resample_init(
286
target_channels, hdaudio->channels,
287
target_rate, hdaudio->sample_rate,
288
SAMPLE_FMT_S16, SAMPLE_FMT_S16,
290
hdaudio->target_rate = target_rate;
291
hdaudio->target_channels = target_channels;
292
if (hdaudio->resample_cache) {
293
MEM_freeN(hdaudio->resample_cache);
297
hdaudio->resample_cache = (short*) MEM_mallocN(
299
hdaudio->target_channels
302
"hdaudio resample cache");
303
if (frame_position == hdaudio->frame_position ||
304
frame_position == hdaudio->frame_position + 1) {
305
sound_hdaudio_run_resampler_seek(hdaudio);
219
310
static void sound_hdaudio_extract_small_block(
220
311
struct hdaudio * hdaudio,
221
312
short * target_buffer,
225
316
int nb_samples /* in target */)
229
int frame_size = (long long) target_rate
230
* hdaudio->frame_duration / AV_TIME_BASE;
231
int in_frame_size = (long long) hdaudio->sample_rate
232
* hdaudio->frame_duration / AV_TIME_BASE;
233
int rate_conversion =
319
int frame_position, frame_size, in_frame_size, rate_conversion;
322
if (hdaudio == 0) return;
324
frame_size = (long long) target_rate
325
* hdaudio->frame_duration / AV_TIME_BASE;
326
in_frame_size = (long long) hdaudio->sample_rate
327
* hdaudio->frame_duration / AV_TIME_BASE;
234
329
(target_rate != hdaudio->sample_rate)
235
330
|| (target_channels != hdaudio->channels);
236
int sample_ofs = target_channels * (sample_position % frame_size);
331
sample_ofs = target_channels * (sample_position % frame_size);
238
333
frame_position = sample_position / frame_size;
240
if (hdaudio == 0) return;
242
335
if (rate_conversion) {
243
if (hdaudio->resampler &&
244
(hdaudio->target_rate != target_rate
245
|| hdaudio->target_channels != target_channels)) {
246
audio_resample_close(hdaudio->resampler);
247
hdaudio->resampler = 0;
249
if (!hdaudio->resampler) {
250
hdaudio->resampler = audio_resample_init(
251
target_channels, hdaudio->channels,
252
target_rate, hdaudio->sample_rate);
253
hdaudio->target_rate = target_rate;
254
hdaudio->target_channels = target_channels;
255
if (hdaudio->resample_cache) {
256
MEM_freeN(hdaudio->resample_cache);
260
hdaudio->resample_cache = (short*) MEM_mallocN(
262
hdaudio->target_channels
265
"hdaudio resample cache");
266
if (frame_position == hdaudio->frame_position) {
267
hdaudio->resample_samples_in =
268
in_frame_size * 7 / 4;
269
hdaudio->resample_samples_written
272
hdaudio->resample_cache,
273
hdaudio->decode_cache_zero,
274
in_frame_size * 7 / 4);
336
sound_hdaudio_init_resampler(
337
hdaudio, frame_position,
338
target_rate, target_channels);
279
341
if (frame_position == hdaudio->frame_position + 1
412
hdaudio->decode_pos = decode_pos;
349
414
if (rate_conversion) {
350
int written = hdaudio->resample_samples_written
352
int ofs = target_channels * frame_size;
353
int recycle = written - ofs;
354
int next_in = in_frame_size
356
- (double) recycle / (double)
357
(frame_size * target_channels)
360
memmove(hdaudio->resample_cache,
361
hdaudio->resample_cache + ofs,
362
recycle * sizeof(short));
364
hdaudio->resample_samples_written
367
hdaudio->resample_cache + recycle,
368
hdaudio->decode_cache_zero
369
+ hdaudio->resample_samples_in
373
+ recycle / target_channels;
375
hdaudio->resample_samples_in = next_in;
415
sound_hdaudio_run_resampler_continue(hdaudio);
378
hdaudio->decode_pos = decode_pos;
381
419
if (frame_position != hdaudio->frame_position) {
555
hdaudio->decode_pos = decode_pos;
515
557
if (rate_conversion) {
516
hdaudio->resample_samples_written
517
= audio_resample(hdaudio->resampler,
518
hdaudio->resample_cache,
519
hdaudio->decode_cache_zero,
520
in_frame_size * 7 / 4);
521
hdaudio->resample_samples_in =
522
in_frame_size * 7 / 4;
558
sound_hdaudio_run_resampler_seek(hdaudio);
524
hdaudio->decode_pos = decode_pos;
527
562
memcpy(target_buffer, (rate_conversion
528
563
? hdaudio->resample_cache
529
564
: hdaudio->decode_cache_zero) + sample_ofs,
530
565
nb_samples * target_channels * sizeof(short));