Skip to content

Commit

Permalink
Add BufferedProcess class for sending output to a numpy buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewryanscott committed Sep 16, 2016
1 parent 031aa6a commit 2bdf7d9
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 1 deletion.
1 change: 1 addition & 0 deletions sunvox/buffered/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .process import *
68 changes: 68 additions & 0 deletions sunvox/buffered/process.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
from multiprocessing import sharedctypes

import numpy
from numpy import ctypeslib, int16, float32

from sunvox import SV_INIT_FLAG, Process
from .processor import BufferedProcessor


class BufferedProcess(Process):

freq = 44100
channels = 2
data_type = float32
size = freq // 60

processor_class = BufferedProcessor

def __init__(self, freq=freq, channels=channels, data_type=data_type,
size=size):
super(BufferedProcess, self).__init__()
self.freq = freq
self.channels = channels
self.data_type = data_type
self.size = size
flags = SV_INIT_FLAG.USER_AUDIO_CALLBACK | SV_INIT_FLAG.ONE_THREAD
flags |= {
int16: SV_INIT_FLAG.AUDIO_INT16,
float32: SV_INIT_FLAG.AUDIO_FLOAT32,
}[self.data_type]
self.init(None, self.freq, self.channels, flags)
self.init_buffer()

def _send(self, name, *args, **kwargs):
return self._conn.send((name, args, kwargs))

def _recv(self):
return self._conn.recv()

@property
def samples(self):
return self.size * self.channels

@property
def shape(self):
return self.size, self.channels

@property
def type_code(self):
return {int16: 'h', float32: 'f'}[self.data_type]

def init_buffer(self):
self._send('init_buffer', self.size)
return self._recv()

def fill_buffer(self):
self._send('fill_buffer')
raw = self._recv()
buffer = numpy.fromstring(raw, self.data_type)
buffer.shape = self.shape
return buffer


__all__ = [
'BufferedProcess',
'int16',
'float32',
]
29 changes: 29 additions & 0 deletions sunvox/buffered/processor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import ctypes

import sunvox
from sunvox.processor import Processor


class BufferedProcessor(Processor):

def __init__(self, conn):
super().__init__(conn)

def init(self, device, freq, channels, flags):
super().init(device, freq, channels, flags)
self.channels = channels
if flags & sunvox.SV_INIT_FLAG.AUDIO_INT16:
self.type_code = 'h'
elif flags & sunvox.SV_INIT_FLAG.AUDIO_FLOAT32:
self.type_code = 'f'
self.type_size = {'h': 2, 'f': 4}[self.type_code]

def init_buffer(self, size):
self._buffer_size = size
self._buffer_bytes = self.type_size * self.channels * size
self._buffer = ctypes.create_string_buffer(self._buffer_bytes)

def fill_buffer(self):
sunvox.audio_callback(
ctypes.byref(self._buffer), self._buffer_size, 0, 0)
return self._buffer.raw
2 changes: 1 addition & 1 deletion sunvox/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def __init__(self, *args, **kwargs):
self._conn, child_conn = mp.Pipe()
args = (child_conn,) + args
self._process = self._ctx.Process(
target=Processor, args=args, kwargs=kwargs)
target=self.processor_class, args=args, kwargs=kwargs)
self._process.start()

_k, _v = None, None
Expand Down

0 comments on commit 2bdf7d9

Please sign in to comment.