all repos — mgba @ c91c46ce97182d62185e4ff2bc33d9265557639d

mGBA Game Boy Advance Emulator

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
54		size_t currentRead = avresample_convert(avr, (uint8_t**) &output, nSamples * sizeof(struct GBAStereoSample), nSamples, (uint8_t**) samples, sizeof(left), read);
55		nSamples -= currentRead;
56		output += currentRead;
57		totalRead += currentRead;
58		if (read < GBA_AUDIO_SAMPLES && nSamples) {
59			memset(output, 0, nSamples * sizeof(struct GBAStereoSample));
60			break;
61		}
62	}
63	return totalRead;
64}