mirror of https://github.com/mgba-emu/mgba.git
GBA Audio: Rip out FFmpeg resampler
This commit is contained in:
parent
b92ed79a85
commit
73a6b47879
1
CHANGES
1
CHANGES
|
@ -3,7 +3,6 @@ Features:
|
|||
- Support for gamepad axes, e.g. analog sticks or triggers
|
||||
- Add scale presets for up to 6x
|
||||
- Debugger: Add CLI "frame", frame advance command
|
||||
- Better audio resampling via FFmpeg
|
||||
- Settings window
|
||||
- Bilinear resampling option
|
||||
- Add option to skip BIOS start screen
|
||||
|
|
|
@ -101,9 +101,6 @@ if(HAVE_STRNDUP)
|
|||
add_definitions(-DHAVE_STRNDUP)
|
||||
endif()
|
||||
|
||||
set(USE_RESAMPLE OFF)
|
||||
set(RESAMPLE_LIBRARY "None")
|
||||
|
||||
# Platform support
|
||||
if(WIN32)
|
||||
add_definitions(-D_WIN32_WINNT=0x0600)
|
||||
|
@ -161,23 +158,21 @@ if(USE_FFMPEG)
|
|||
include_directories(AFTER ${LIBAVCODEC_INCLUDE_DIRS} ${LIBAVFORMAT_INCLUDE_DIRS} ${LIBAVRESAMPLE_INCLUDE_DIRS} ${LIBAVUTIL_INCLUDE_DIRS} ${LIBSWSCALE_INCLUDE_DIRS})
|
||||
link_directories(${LIBAVCODEC_LIBRARY_DIRS} ${LIBAVFORMAT_LIBRARY_DIRS} ${LIBAVRESAMPLE_LIBRARY_DIRS} ${LIBAVUTIL_LIBRARY_DIRS} ${LIBSWSCALE_LIBRARY_DIRS})
|
||||
list(APPEND UTIL_SRC "${CMAKE_SOURCE_DIR}/src/platform/ffmpeg/ffmpeg-encoder.c")
|
||||
set(RESAMPLE_SRC "${CMAKE_SOURCE_DIR}/src/platform/ffmpeg/ffmpeg-resample.c")
|
||||
string(REGEX MATCH "^[0-9]+" LIBAVCODEC_VERSION_MAJOR ${libavcodec_VERSION})
|
||||
string(REGEX MATCH "^[0-9]+" LIBAVFORMAT_VERSION_MAJOR ${libavformat_VERSION})
|
||||
string(REGEX MATCH "^[0-9]+" LIBAVRESAMPLE_VERSION_MAJOR ${libavresample_VERSION})
|
||||
string(REGEX MATCH "^[0-9]+" LIBAVUTIL_VERSION_MAJOR ${libavutil_VERSION})
|
||||
string(REGEX MATCH "^[0-9]+" LIBSWSCALE_VERSION_MAJOR ${libswscale_VERSION})
|
||||
list(APPEND DEPENDENCY_LIB ${LIBAVCODEC_LIBRARIES} ${LIBAVFORMAT_LIBRARIES} ${LIBAVRESAMPLE_LIBRARIES} ${LIBAVUTIL_LIBRARIES} ${LIBSWSCALE_LIBRARIES})
|
||||
set(RESAMPLE_LIBRARY "FFmpeg")
|
||||
set(USE_RESAMPLE ON)
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libavcodec${LIBAVCODEC_VERSION_MAJOR},libavformat${LIBAVFORMAT_VERSION_MAJOR},libavresample${LIBAVRESAMPLE_VERSION_MAJOR},libavutil${LIBAVUTIL_VERSION_MAJOR},libswscale${LIBSWSCALE_VERSION_MAJOR}")
|
||||
set(CPACK_DEBIAN_PACKAGE_RECOMMENDS "libavcodec-extra")
|
||||
endif()
|
||||
|
||||
if(USE_BLIP)
|
||||
set(RESAMPLE_SRC "${CMAKE_SOURCE_DIR}/src/third-party/blip_buf/blip_buf.c")
|
||||
set(RESAMPLE_LIBRARY "blip_buf")
|
||||
set(USE_RESAMPLE ON)
|
||||
list(APPEND UTIL_SRC "${CMAKE_SOURCE_DIR}/src/third-party/blip_buf/blip_buf.c")
|
||||
add_definitions(-DRESAMPLE_LIBRARY=RESAMPLE_BLIP_BUF)
|
||||
else()
|
||||
add_definitions(-DRESAMPLE_LIBRARY=RESAMPLE_NN)
|
||||
endif()
|
||||
|
||||
if(USE_MAGICK)
|
||||
|
@ -210,15 +205,6 @@ if(USE_LIBZIP)
|
|||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},libzip2")
|
||||
endif()
|
||||
|
||||
if(USE_RESAMPLE)
|
||||
string(TOUPPER ${RESAMPLE_LIBRARY} RESAMPLE_DEFINE)
|
||||
set(RESAMPLE_DEFINE "RESAMPLE_${RESAMPLE_DEFINE}")
|
||||
list(APPEND UTIL_SRC ${RESAMPLE_SRC})
|
||||
add_definitions(-DRESAMPLE_LIBRARY=${RESAMPLE_DEFINE})
|
||||
else()
|
||||
add_definitions(-DRESAMPLE_LIBRARY=RESAMPLE_NN)
|
||||
endif()
|
||||
|
||||
# Binaries
|
||||
add_library(${BINARY_NAME} SHARED
|
||||
${ARM_SRC}
|
||||
|
@ -278,7 +264,7 @@ message(STATUS " Video recording: ${USE_FFMPEG}")
|
|||
message(STATUS " GIF recording: ${USE_MAGICK}")
|
||||
message(STATUS " Screenshot/advanced savestate support: ${USE_PNG}")
|
||||
message(STATUS " ZIP support: ${USE_LIBZIP}")
|
||||
message(STATUS " Better audio resampling (${RESAMPLE_LIBRARY}): ${USE_RESAMPLE}")
|
||||
message(STATUS " Better audio resampling: ${USE_BLIP}")
|
||||
message(STATUS "Frontend summary:")
|
||||
message(STATUS " Qt: ${BUILD_QT}")
|
||||
message(STATUS " SDL (${SDL_VERSION}): ${BUILD_SDL}")
|
||||
|
|
|
@ -20,7 +20,6 @@ struct GBADMA;
|
|||
extern const unsigned GBA_AUDIO_SAMPLES;
|
||||
|
||||
#define RESAMPLE_NN 0
|
||||
#define RESAMPLE_FFMPEG 1
|
||||
#define RESAMPLE_BLIP_BUF 2
|
||||
|
||||
DECL_BITFIELD(GBAAudioRegisterEnvelope, uint16_t);
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
/* Copyright (c) 2013-2014 Jeffrey Pfau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include "ffmpeg-resample.h"
|
||||
|
||||
#include "gba-audio.h"
|
||||
|
||||
#include <libavresample/avresample.h>
|
||||
#include <libavutil/opt.h>
|
||||
|
||||
struct AVAudioResampleContext* GBAAudioOpenLAVR(unsigned inputRate, unsigned outputRate) {
|
||||
AVAudioResampleContext *avr = avresample_alloc_context();
|
||||
av_opt_set_int(avr, "in_channel_layout", AV_CH_LAYOUT_STEREO, 0);
|
||||
av_opt_set_int(avr, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0);
|
||||
av_opt_set_int(avr, "in_sample_rate", inputRate, 0);
|
||||
av_opt_set_int(avr, "out_sample_rate", outputRate, 0);
|
||||
av_opt_set_int(avr, "in_sample_fmt", AV_SAMPLE_FMT_S16P, 0);
|
||||
av_opt_set_int(avr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
|
||||
if (avresample_open(avr)) {
|
||||
avresample_free(&avr);
|
||||
return 0;
|
||||
}
|
||||
return avr;
|
||||
}
|
||||
|
||||
struct AVAudioResampleContext* GBAAudioReopenLAVR(struct AVAudioResampleContext* avr, unsigned inputRate, unsigned outputRate) {
|
||||
avresample_close(avr);
|
||||
av_opt_set_int(avr, "in_sample_rate", inputRate, 0);
|
||||
av_opt_set_int(avr, "out_sample_rate", outputRate, 0);
|
||||
if (avresample_open(avr)) {
|
||||
avresample_free(&avr);
|
||||
return 0;
|
||||
}
|
||||
return avr;
|
||||
}
|
||||
|
||||
unsigned GBAAudioResampleLAVR(struct GBAAudio* audio, struct AVAudioResampleContext* avr, struct GBAStereoSample* output, unsigned nSamples) {
|
||||
int16_t left[GBA_AUDIO_SAMPLES];
|
||||
int16_t right[GBA_AUDIO_SAMPLES];
|
||||
int16_t* samples[2] = { left, right };
|
||||
|
||||
size_t totalRead = 0;
|
||||
size_t available = avresample_available(avr);
|
||||
if (available) {
|
||||
totalRead = avresample_read(avr, (uint8_t**) &output, nSamples);
|
||||
nSamples -= totalRead;
|
||||
output += totalRead;
|
||||
}
|
||||
while (nSamples) {
|
||||
unsigned read = GBAAudioCopy(audio, left, right, GBA_AUDIO_SAMPLES);
|
||||
if (read == 0) {
|
||||
memset(output, 0, nSamples * sizeof(struct GBAStereoSample));
|
||||
break;
|
||||
}
|
||||
|
||||
size_t currentRead = avresample_convert(avr, (uint8_t**) &output, nSamples * sizeof(struct GBAStereoSample), nSamples, (uint8_t**) samples, sizeof(left), read);
|
||||
nSamples -= currentRead;
|
||||
output += currentRead;
|
||||
totalRead += currentRead;
|
||||
}
|
||||
return totalRead;
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
/* Copyright (c) 2013-2014 Jeffrey Pfau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#ifndef FFMPEG_RESAMPLE
|
||||
#define FFMPEG_RESAMPLE
|
||||
|
||||
struct AVAudioResampleContext;
|
||||
struct GBAAudio;
|
||||
struct GBAStereoSample;
|
||||
|
||||
struct AVAudioResampleContext* GBAAudioOpenLAVR(unsigned inputRate, unsigned outputRate);
|
||||
struct AVAudioResampleContext* GBAAudioReopenLAVR(struct AVAudioResampleContext* avr, unsigned inputRate, unsigned outputRate);
|
||||
unsigned GBAAudioResampleLAVR(struct GBAAudio* audio, struct AVAudioResampleContext* avr, struct GBAStereoSample* output, unsigned nSamples);
|
||||
|
||||
#endif
|
|
@ -8,10 +8,7 @@
|
|||
#include "gba.h"
|
||||
#include "gba-thread.h"
|
||||
|
||||
#if RESAMPLE_LIBRARY == RESAMPLE_FFMPEG
|
||||
#include "platform/ffmpeg/ffmpeg-resample.h"
|
||||
#include <libavresample/avresample.h>
|
||||
#elif RESAMPLE_LIBRARY == RESAMPLE_BLIP_BUF
|
||||
#if RESAMPLE_LIBRARY == RESAMPLE_BLIP_BUF
|
||||
#include "third-party/blip_buf/blip_buf.h"
|
||||
#endif
|
||||
|
||||
|
@ -46,10 +43,6 @@ bool GBASDLInitAudio(struct GBASDLAudio* context, struct GBAThread* threadContex
|
|||
threadContext->audioBuffers = context->samples * 2;
|
||||
}
|
||||
|
||||
#if RESAMPLE_LIBRARY == RESAMPLE_FFMPEG
|
||||
context->avr = 0;
|
||||
#endif
|
||||
|
||||
SDL_PauseAudio(0);
|
||||
return true;
|
||||
}
|
||||
|
@ -59,9 +52,6 @@ void GBASDLDeinitAudio(struct GBASDLAudio* context) {
|
|||
SDL_PauseAudio(1);
|
||||
SDL_CloseAudio();
|
||||
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||
#if RESAMPLE_LIBRARY == RESAMPLE_FFMPEG
|
||||
avresample_free(&context->avr);
|
||||
#endif
|
||||
}
|
||||
|
||||
void GBASDLPauseAudio(struct GBASDLAudio* context) {
|
||||
|
@ -91,22 +81,6 @@ static void _GBASDLAudioCallback(void* context, Uint8* data, int len) {
|
|||
if (audioContext->obtainedSpec.channels == 2) {
|
||||
GBAAudioResampleNN(&audioContext->thread->gba->audio, audioContext->ratio, &audioContext->drift, ssamples, len);
|
||||
}
|
||||
#elif RESAMPLE_LIBRARY == RESAMPLE_FFMPEG
|
||||
float ratio = GBAAudioCalculateRatio(audioContext->thread->gba->audio.sampleRate, audioContext->thread->fpsTarget, audioContext->thread->gba->audio.sampleRate);
|
||||
if (!audioContext->avr) {
|
||||
if (!audioContext->thread->gba->audio.sampleRate) {
|
||||
memset(data, 0, len);
|
||||
return;
|
||||
}
|
||||
audioContext->ratio = ratio;
|
||||
audioContext->avr = GBAAudioOpenLAVR(audioContext->thread->gba->audio.sampleRate / ratio, audioContext->obtainedSpec.freq);
|
||||
} else if (ratio != audioContext->ratio) {
|
||||
audioContext->ratio = ratio;
|
||||
audioContext->avr = GBAAudioReopenLAVR(audioContext->avr, audioContext->thread->gba->audio.sampleRate / ratio, audioContext->obtainedSpec.freq);
|
||||
}
|
||||
struct GBAStereoSample* ssamples = (struct GBAStereoSample*) data;
|
||||
len /= 2 * audioContext->obtainedSpec.channels;
|
||||
GBAAudioResampleLAVR(&audioContext->thread->gba->audio, audioContext->avr, ssamples, len);
|
||||
#elif RESAMPLE_LIBRARY == RESAMPLE_BLIP_BUF
|
||||
double fauxClock = GBAAudioCalculateRatio(1, audioContext->thread->fpsTarget, 1);
|
||||
GBASyncLockAudio(&audioContext->thread->sync);
|
||||
|
|
|
@ -24,8 +24,6 @@ struct GBASDLAudio {
|
|||
#endif
|
||||
#if RESAMPLE_LIBRARY == RESAMPLE_NN
|
||||
float drift;
|
||||
#elif RESAMPLE_LIBRARY == RESAMPLE_FFMPEG
|
||||
struct AVAudioResampleContext* avr;
|
||||
#endif
|
||||
|
||||
struct GBAThread* thread;
|
||||
|
|
Loading…
Reference in New Issue