mirror of https://github.com/mgba-emu/mgba.git
Python: Experimental audio API
This commit is contained in:
parent
b790dd8e75
commit
4346c5db1b
1
CHANGES
1
CHANGES
|
@ -111,6 +111,7 @@ Features:
|
||||||
- Qt: State file load/save menu options
|
- Qt: State file load/save menu options
|
||||||
- Windows installer
|
- Windows installer
|
||||||
- Tile viewer now has adjustable width
|
- Tile viewer now has adjustable width
|
||||||
|
- Python: Experimental audio API
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
- PSP2: Fix audio crackling after fast forward
|
- PSP2: Fix audio crackling after fast forward
|
||||||
- PSP2: Fix audio crackling when buffer is full
|
- PSP2: Fix audio crackling when buffer is full
|
||||||
|
|
|
@ -35,6 +35,7 @@ void free(void*);
|
||||||
|
|
||||||
#include "flags.h"
|
#include "flags.h"
|
||||||
|
|
||||||
|
#include <mgba/core/blip_buf.h>
|
||||||
#include <mgba/core/cache-set.h>
|
#include <mgba/core/cache-set.h>
|
||||||
#include <mgba/core/core.h>
|
#include <mgba/core/core.h>
|
||||||
#include <mgba/core/map-cache.h>
|
#include <mgba/core/map-cache.h>
|
||||||
|
|
|
@ -20,6 +20,7 @@ ffi.set_source("mgba._pylib", """
|
||||||
#define inline
|
#define inline
|
||||||
#include "flags.h"
|
#include "flags.h"
|
||||||
#define OPAQUE_THREADING
|
#define OPAQUE_THREADING
|
||||||
|
#include <mgba/core/blip_buf.h>
|
||||||
#include <mgba/core/cache-set.h>
|
#include <mgba/core/cache-set.h>
|
||||||
#include <mgba-util/common.h>
|
#include <mgba-util/common.h>
|
||||||
#include <mgba/core/core.h>
|
#include <mgba/core/core.h>
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
# Copyright (c) 2013-2018 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/.
|
||||||
|
from ._pylib import ffi, lib # pylint: disable=no-name-in-module
|
||||||
|
|
||||||
|
|
||||||
|
class Buffer(object):
|
||||||
|
def __init__(self, native, internal_rate):
|
||||||
|
self._native = native
|
||||||
|
self._internal_rate = internal_rate
|
||||||
|
|
||||||
|
@property
|
||||||
|
def available(self):
|
||||||
|
return lib.blip_samples_avail(self._native)
|
||||||
|
|
||||||
|
def set_rate(self, rate):
|
||||||
|
lib.blip_set_rates(self._native, self._internal_rate, rate)
|
||||||
|
|
||||||
|
def read(self, samples):
|
||||||
|
buffer = ffi.new("short[%i]" % samples)
|
||||||
|
count = self.read_into(buffer, samples, 1, 0)
|
||||||
|
return buffer[:count]
|
||||||
|
|
||||||
|
def read_into(self, buffer, samples, channels=1, interleave=0):
|
||||||
|
return lib.blip_read_samples(self._native, ffi.addressof(buffer, interleave), samples, channels == 2)
|
||||||
|
|
||||||
|
def clear(self):
|
||||||
|
lib.blip_clear(self._native)
|
||||||
|
|
||||||
|
|
||||||
|
class StereoBuffer(object):
|
||||||
|
def __init__(self, left, right):
|
||||||
|
self._left = left
|
||||||
|
self._right = right
|
||||||
|
|
||||||
|
@property
|
||||||
|
def available(self):
|
||||||
|
return min(self._left.available, self._right.available)
|
||||||
|
|
||||||
|
def set_rate(self, rate):
|
||||||
|
self._left.set_rate(rate)
|
||||||
|
self._right.set_rate(rate)
|
||||||
|
|
||||||
|
def read(self, samples):
|
||||||
|
buffer = ffi.new("short[%i]" % (2 * samples))
|
||||||
|
count = self.read_into(buffer, samples)
|
||||||
|
return buffer[0:2 * count]
|
||||||
|
|
||||||
|
def read_into(self, buffer, samples):
|
||||||
|
samples = self._left.read_into(buffer, samples, 2, 0)
|
||||||
|
return self._right.read_into(buffer, samples, 2, 1)
|
||||||
|
|
||||||
|
def clear(self):
|
||||||
|
self._left.clear()
|
||||||
|
self._right.clear()
|
|
@ -4,7 +4,7 @@
|
||||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
# 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/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
from ._pylib import ffi, lib # pylint: disable=no-name-in-module
|
from ._pylib import ffi, lib # pylint: disable=no-name-in-module
|
||||||
from . import tile
|
from . import tile, audio
|
||||||
from cached_property import cached_property
|
from cached_property import cached_property
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
|
||||||
|
@ -225,6 +225,22 @@ class Core(object):
|
||||||
def set_video_buffer(self, image):
|
def set_video_buffer(self, image):
|
||||||
self._core.setVideoBuffer(self._core, image.buffer, image.stride)
|
self._core.setVideoBuffer(self._core, image.buffer, image.stride)
|
||||||
|
|
||||||
|
@protected
|
||||||
|
def set_audio_buffer_size(self, size)
|
||||||
|
self._core.setAudioBufferSize(self._core, size)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def audio_buffer_size(self):
|
||||||
|
return self._core.getAudioBufferSize(self._core)
|
||||||
|
|
||||||
|
@protected
|
||||||
|
def get_audio_channels(self):
|
||||||
|
return audio.StereoBuffer(self.get_audio_channel(0), self.get_audio_channel(1));
|
||||||
|
|
||||||
|
@protected
|
||||||
|
def get_audio_channel(self, channel):
|
||||||
|
return audio.Buffer(self._core.getAudioChannel(self._core, channel), self.frequency)
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self._core.reset(self._core)
|
self._core.reset(self._core)
|
||||||
|
|
Loading…
Reference in New Issue