src/platform/ffmpeg/ffmpeg-resample.c (view raw)
1/* Copyright (c) 2013-2014 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include "ffmpeg-resample.h"
7
8#include "gba-audio.h"
9
10#include <libavresample/avresample.h>
11#include <libavutil/opt.h>
12
13struct AVAudioResampleContext* GBAAudioOpenLAVR(unsigned inputRate, unsigned outputRate) {
14 AVAudioResampleContext *avr = avresample_alloc_context();
15 av_opt_set_int(avr, "in_channel_layout", AV_CH_LAYOUT_STEREO, 0);
16 av_opt_set_int(avr, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0);
17 av_opt_set_int(avr, "in_sample_rate", inputRate, 0);
18 av_opt_set_int(avr, "out_sample_rate", outputRate, 0);
19 av_opt_set_int(avr, "in_sample_fmt", AV_SAMPLE_FMT_S16P, 0);
20 av_opt_set_int(avr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
21 if (avresample_open(avr)) {
22 avresample_free(&avr);
23 return 0;
24 }
25 return avr;
26}
27
28struct AVAudioResampleContext* GBAAudioReopenLAVR(struct AVAudioResampleContext* avr, unsigned inputRate, unsigned outputRate) {
29 avresample_close(avr);
30 av_opt_set_int(avr, "in_sample_rate", inputRate, 0);
31 av_opt_set_int(avr, "out_sample_rate", outputRate, 0);
32 if (avresample_open(avr)) {
33 avresample_free(&avr);
34 return 0;
35 }
36 return avr;
37}
38
39unsigned GBAAudioResampleLAVR(struct GBAAudio* audio, struct AVAudioResampleContext* avr, struct GBAStereoSample* output, unsigned nSamples) {
40 int16_t left[GBA_AUDIO_SAMPLES];
41 int16_t right[GBA_AUDIO_SAMPLES];
42 int16_t* samples[2] = { left, right };
43
44 size_t totalRead = 0;
45 size_t available = avresample_available(avr);
46 if (available) {
47 totalRead = avresample_read(avr, (uint8_t**) &output, nSamples);
48 nSamples -= totalRead;
49 output += totalRead;
50 }
51 while (nSamples) {
52 unsigned read = GBAAudioCopy(audio, left, right, GBA_AUDIO_SAMPLES);
53 if (read == 0) {
54 memset(output, 0, nSamples * sizeof(struct GBAStereoSample));
55 break;
56 }
57
58 size_t currentRead = avresample_convert(avr, (uint8_t**) &output, nSamples * sizeof(struct GBAStereoSample), nSamples, (uint8_t**) samples, sizeof(left), read);
59 nSamples -= currentRead;
60 output += currentRead;
61 totalRead += currentRead;
62 }
63 return totalRead;
64}