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
|
||||
- Windows installer
|
||||
- Tile viewer now has adjustable width
|
||||
- Python: Experimental audio API
|
||||
Bugfixes:
|
||||
- PSP2: Fix audio crackling after fast forward
|
||||
- PSP2: Fix audio crackling when buffer is full
|
||||
|
|
|
@ -35,6 +35,7 @@ void free(void*);
|
|||
|
||||
#include "flags.h"
|
||||
|
||||
#include <mgba/core/blip_buf.h>
|
||||
#include <mgba/core/cache-set.h>
|
||||
#include <mgba/core/core.h>
|
||||
#include <mgba/core/map-cache.h>
|
||||
|
|
|
@ -20,6 +20,7 @@ ffi.set_source("mgba._pylib", """
|
|||
#define inline
|
||||
#include "flags.h"
|
||||
#define OPAQUE_THREADING
|
||||
#include <mgba/core/blip_buf.h>
|
||||
#include <mgba/core/cache-set.h>
|
||||
#include <mgba-util/common.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
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
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 functools import wraps
|
||||
|
||||
|
@ -225,6 +225,22 @@ class Core(object):
|
|||
def set_video_buffer(self, image):
|
||||
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
|
||||
def reset(self):
|
||||
self._core.reset(self._core)
|
||||
|
|
Loading…
Reference in New Issue