New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

pym2149

Package Overview
Dependencies
Maintainers
1
Versions
42
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

pym2149 - pypi Package Compare versions

Comparing version
33
to
34
+42
pym2149/client/__init__.py
# Copyright 2014, 2018, 2019, 2020 Andrzej Cichocki
# This file is part of pym2149.
#
# pym2149 is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# pym2149 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with pym2149. If not, see <http://www.gnu.org/licenses/>.
class BufferFiller:
def __init__(self, portcount, buffersize, init, flip):
self.portcount = portcount
self.buffersize = buffersize
self._newbuf(init)
self.flip = flip
def __call__(self, outbufs):
n = len(outbufs[0])
i = 0
while i < n:
m = min(n - i, self.buffersize - self.cursor)
for portindex in range(self.portcount):
self.outbuf[portindex, self.cursor:self.cursor + m] = outbufs[portindex].buf[i:i + m]
self.cursor += m
i += m
if self.cursor == self.buffersize:
self._newbuf(self.flip)
def _newbuf(self, factory):
outbuf = factory().view()
outbuf.shape = self.portcount, self.buffersize
self.outbuf = outbuf
self.cursor = 0
# Copyright 2014, 2018, 2019, 2020 Andrzej Cichocki
# This file is part of pym2149.
#
# pym2149 is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# pym2149 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with pym2149. If not, see <http://www.gnu.org/licenses/>.
from . import BufferFiller
from ..const import clientname
from ..iface import AmpScale, Config, Platform, Stream
from ..nod import Node
from ..out import FloatStream, StereoInfo
from diapyr import types
import outjack.jackclient as jc, logging
log = logging.getLogger(__name__)
class JackClient(jc.JackClient, Platform):
@types(Config, StereoInfo)
def __init__(self, config, stereoinfo):
portcount = stereoinfo.getoutchans.size + config.SID.enabled # FIXME: This is a hack.
super().__init__(clientname, portcount, config.jackringsize, config.jackcoupling)
def start(self):
super().start()
log.debug(
"JACK block size: %s or %.3f seconds",
self.buffersize,
self.buffersize / self.outputrate)
class JackStream(Stream, Node, metaclass = AmpScale):
log2maxpeaktopeak = 1
@types(Config, [FloatStream], JackClient)
def __init__(self, config, streams, client):
super().__init__()
self.systemchannelcount = config.systemchannelcount
for stream in streams:
for chanindex in range(stream.chancount):
client.port_register_output(f"{stream.streamname}_{1 + chanindex}")
self.streams = streams
self.client = client
def start(self):
self.client.activate()
for stream in self.streams:
# Connect all system channels, cycling over our streams if necessary:
for syschanindex in range(self.systemchannelcount):
chanindex = syschanindex % stream.chancount
self.client.connect(f"{clientname}:{stream.streamname}_{1 + chanindex}", f"system:playback_{1 + syschanindex}")
self.filler = BufferFiller(sum(s.chancount for s in self.streams), self.client.buffersize, self.client.current_output_buffer, self.client.send_and_get_output_buffer)
def callimpl(self):
self.filler([self.chain(wav) for stream in self.streams for wav in stream])
def flush(self):
pass # Nothing to be done.
def stop(self):
self.client.deactivate()
def configure(di):
di.add(JackClient)
di.add(JackStream)
# Copyright 2014, 2018, 2019, 2020 Andrzej Cichocki
# This file is part of pym2149.
#
# pym2149 is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# pym2149 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with pym2149. If not, see <http://www.gnu.org/licenses/>.
from . import BufferFiller
from ..iface import AmpScale, Config, Platform, Stream
from ..nod import Node
from ..out import FloatStream, StereoInfo
from diapyr import types
import logging, outjack.portaudioclient as pac
log = logging.getLogger(__name__)
class PortAudioClient(pac.PortAudioClient, Platform):
@types(Config, StereoInfo)
def __init__(self, config, stereoinfo):
config = config.PortAudio
super().__init__(stereoinfo.getoutchans.size, config.outputrate, config.buffersize, config.ringsize, config.coupling)
class PortAudioStream(Node, Stream, metaclass = AmpScale):
log2maxpeaktopeak = 1
@types(StereoInfo, FloatStream, PortAudioClient)
def __init__(self, stereoinfo, wavs, client):
super().__init__()
self.chancount = stereoinfo.getoutchans.size
self.wavs = wavs
self.client = client
def start(self):
self.client.activate()
self.filler = BufferFiller(self.chancount, self.client.buffersize, self.client.current_output_buffer, self.client.send_and_get_output_buffer)
def callimpl(self):
self.filler([self.chain(wav) for wav in self.wavs])
def flush(self):
pass
def stop(self):
self.client.deactivate()
def configure(di):
di.add(PortAudioClient)
di.add(PortAudioStream)
+14
-5
Metadata-Version: 2.1
Name: pym2149
Version: 33
Version: 34
Summary: YM2149 emulator supporting YM files, OSC to JACK, PortAudio, WAV
Home-page: https://github.com/combatopera/pym2149
Author: Andrzej Cichocki
Author-email: 3613868+combatopera@users.noreply.github.com
Description-Content-Type: text/markdown
License-File: COPYING
Requires-Dist: aridity>=78
Requires-Dist: diapyr>=26
Requires-Dist: lagoon>=31
Requires-Dist: Lurlene>=13
Requires-Dist: minBlepy>=16
Requires-Dist: numpy>=2.0.2
Requires-Dist: outjack>=15
Requires-Dist: pyrbo>=13
Requires-Dist: splut>=4
Requires-Dist: timelyOSC>=4

@@ -27,2 +38,3 @@ # pym2149

python3 -m venv venvname
venvname/bin/pip install -U pip
venvname/bin/pip install pym2149

@@ -34,8 +46,5 @@ . venvname/bin/activate

```
# GitHub trick to download some files to play:
svn export https://github.com/combatopera/pym2149/trunk/contrib
# Play a tune written in the Lurlene live coding language:
lc2portaudio 'contrib/Jochen Hippel - 7 Gates of Jambala Level 9.py'
lc2jack 'contrib/Jochen Hippel - 7 Gates of Jambala Level 9.py'
lc2portaudio 'contrib/Jochen Hippel - 7 Gates of Jambala Level 9.py'

@@ -42,0 +51,0 @@ # Play a Dosound sound effect:

Metadata-Version: 2.1
Name: pym2149
Version: 33
Version: 34
Summary: YM2149 emulator supporting YM files, OSC to JACK, PortAudio, WAV
Home-page: https://github.com/combatopera/pym2149
Author: Andrzej Cichocki
Author-email: 3613868+combatopera@users.noreply.github.com
Description-Content-Type: text/markdown
License-File: COPYING
Requires-Dist: aridity>=78
Requires-Dist: diapyr>=26
Requires-Dist: lagoon>=31
Requires-Dist: Lurlene>=13
Requires-Dist: minBlepy>=16
Requires-Dist: numpy>=2.0.2
Requires-Dist: outjack>=15
Requires-Dist: pyrbo>=13
Requires-Dist: splut>=4
Requires-Dist: timelyOSC>=4

@@ -27,2 +38,3 @@ # pym2149

python3 -m venv venvname
venvname/bin/pip install -U pip
venvname/bin/pip install pym2149

@@ -34,8 +46,5 @@ . venvname/bin/activate

```
# GitHub trick to download some files to play:
svn export https://github.com/combatopera/pym2149/trunk/contrib
# Play a tune written in the Lurlene live coding language:
lc2portaudio 'contrib/Jochen Hippel - 7 Gates of Jambala Level 9.py'
lc2jack 'contrib/Jochen Hippel - 7 Gates of Jambala Level 9.py'
lc2portaudio 'contrib/Jochen Hippel - 7 Gates of Jambala Level 9.py'

@@ -42,0 +51,0 @@ # Play a Dosound sound effect:

@@ -1,9 +0,10 @@

aridity>=48
diapyr>=18
aridity>=78
diapyr>=26
lagoon>=31
Lurlene>=13
minBlepy>=13
minBlepy>=16
numpy>=2.0.2
outjack>=15
pyrbo>=5
pyrbo>=13
splut>=4
timelyOSC>=4

@@ -16,3 +16,2 @@ COPYING

pym2149/iface.py
pym2149/jackclient.py
pym2149/lfsr.py

@@ -28,5 +27,3 @@ pym2149/lha.py

pym2149/pitch.py
pym2149/portaudioclient.py
pym2149/power.py
pym2149/realtime.arid
pym2149/reg.py

@@ -78,2 +75,5 @@ pym2149/resid.py

pym2149/buf_turbo/putstrided_float32ETint16ETuint8.pyxbld
pym2149/client/__init__.py
pym2149/client/jack.py
pym2149/client/portaudio.py
pym2149/native/__init__.py

@@ -80,0 +80,0 @@ pym2149/native/calsa.c

@@ -8,13 +8,2 @@ # cython: language_level=3

@cython.cdivision(True) # Don't check for divide-by-zero.
def copyasprefix_uint8(self, np.uint32_t endframe, that):
cdef np.ndarray[np.uint8_t] py_self_buf = self.buf
cdef np.uint8_t* self_buf = &py_self_buf[0]
cdef np.ndarray[np.uint8_t] py_that_buf = that.buf
cdef np.uint8_t* that_buf = &py_that_buf[0]
cdef np.uint32_t i
for i in range(endframe):
self_buf[i] = that_buf[i]
@cython.boundscheck(False)
@cython.cdivision(True) # Don't check for divide-by-zero.
def copyasprefix_float32(self, np.uint32_t endframe, that):

@@ -39,1 +28,12 @@ cdef np.ndarray[np.float32_t] py_self_buf = self.buf

self_buf[i] = that_buf[i]
@cython.boundscheck(False)
@cython.cdivision(True) # Don't check for divide-by-zero.
def copyasprefix_uint8(self, np.uint32_t endframe, that):
cdef np.ndarray[np.uint8_t] py_self_buf = self.buf
cdef np.uint8_t* self_buf = &py_self_buf[0]
cdef np.ndarray[np.uint8_t] py_that_buf = that.buf
cdef np.uint8_t* that_buf = &py_that_buf[0]
cdef np.uint32_t i
for i in range(endframe):
self_buf[i] = that_buf[i]

@@ -8,14 +8,2 @@ # cython: language_level=3

@cython.cdivision(True) # Don't check for divide-by-zero.
def copywindow_uint8(self, that, np.uint32_t startframe, np.uint32_t endframe):
cdef np.ndarray[np.uint8_t] py_self_buf = self.buf
cdef np.uint8_t* self_buf = &py_self_buf[0]
cdef np.ndarray[np.uint8_t] py_that_buf = that.buf
cdef np.uint8_t* that_buf = &py_that_buf[0]
cdef np.uint32_t i
for i in range(endframe - startframe):
self_buf[i] = that_buf[startframe]
startframe += 1
@cython.boundscheck(False)
@cython.cdivision(True) # Don't check for divide-by-zero.
def copywindow_float32(self, that, np.uint32_t startframe, np.uint32_t endframe):

@@ -42,1 +30,13 @@ cdef np.ndarray[np.float32_t] py_self_buf = self.buf

startframe += 1
@cython.boundscheck(False)
@cython.cdivision(True) # Don't check for divide-by-zero.
def copywindow_uint8(self, that, np.uint32_t startframe, np.uint32_t endframe):
cdef np.ndarray[np.uint8_t] py_self_buf = self.buf
cdef np.uint8_t* self_buf = &py_self_buf[0]
cdef np.ndarray[np.uint8_t] py_that_buf = that.buf
cdef np.uint8_t* that_buf = &py_that_buf[0]
cdef np.uint32_t i
for i in range(endframe - startframe):
self_buf[i] = that_buf[startframe]
startframe += 1

@@ -8,13 +8,2 @@ # cython: language_level=3

@cython.cdivision(True) # Don't check for divide-by-zero.
def fill_i1_uint8(self, np.int8_t value):
cdef np.ndarray[np.uint8_t] py_self_buf = self.buf
cdef np.uint8_t* self_buf = &py_self_buf[0]
cdef np.uint8_t v
cdef np.uint32_t i
v = value # Cast once.
for i in range(py_self_buf.size):
self_buf[i] = v
@cython.boundscheck(False)
@cython.cdivision(True) # Don't check for divide-by-zero.
def fill_i1_float32(self, np.int8_t value):

@@ -39,1 +28,12 @@ cdef np.ndarray[np.float32_t] py_self_buf = self.buf

self_buf[i] = v
@cython.boundscheck(False)
@cython.cdivision(True) # Don't check for divide-by-zero.
def fill_i1_uint8(self, np.int8_t value):
cdef np.ndarray[np.uint8_t] py_self_buf = self.buf
cdef np.uint8_t* self_buf = &py_self_buf[0]
cdef np.uint8_t v
cdef np.uint32_t i
v = value # Cast once.
for i in range(py_self_buf.size):
self_buf[i] = v

@@ -8,11 +8,2 @@ # cython: language_level=3

@cython.cdivision(True) # Don't check for divide-by-zero.
def fill_same_uint8(self, np.uint8_t value):
cdef np.ndarray[np.uint8_t] py_self_buf = self.buf
cdef np.uint8_t* self_buf = &py_self_buf[0]
cdef np.uint32_t i
for i in range(py_self_buf.size):
self_buf[i] = value
@cython.boundscheck(False)
@cython.cdivision(True) # Don't check for divide-by-zero.
def fill_same_float32(self, np.float32_t value):

@@ -33,1 +24,10 @@ cdef np.ndarray[np.float32_t] py_self_buf = self.buf

self_buf[i] = value
@cython.boundscheck(False)
@cython.cdivision(True) # Don't check for divide-by-zero.
def fill_same_uint8(self, np.uint8_t value):
cdef np.ndarray[np.uint8_t] py_self_buf = self.buf
cdef np.uint8_t* self_buf = &py_self_buf[0]
cdef np.uint32_t i
for i in range(py_self_buf.size):
self_buf[i] = value

@@ -8,11 +8,2 @@ # cython: language_level=3

@cython.cdivision(True) # Don't check for divide-by-zero.
def fillpart_uint8(self, np.uint32_t startframe, np.uint32_t endframe, np.uint8_t value):
cdef np.ndarray[np.uint8_t] py_self_buf = self.buf
cdef np.uint8_t* self_buf = &py_self_buf[0]
while startframe < endframe:
self_buf[startframe] = value
startframe += 1
@cython.boundscheck(False)
@cython.cdivision(True) # Don't check for divide-by-zero.
def fillpart_float32(self, np.uint32_t startframe, np.uint32_t endframe, np.float32_t value):

@@ -33,1 +24,10 @@ cdef np.ndarray[np.float32_t] py_self_buf = self.buf

startframe += 1
@cython.boundscheck(False)
@cython.cdivision(True) # Don't check for divide-by-zero.
def fillpart_uint8(self, np.uint32_t startframe, np.uint32_t endframe, np.uint8_t value):
cdef np.ndarray[np.uint8_t] py_self_buf = self.buf
cdef np.uint8_t* self_buf = &py_self_buf[0]
while startframe < endframe:
self_buf[startframe] = value
startframe += 1

@@ -8,14 +8,2 @@ # cython: language_level=3

@cython.cdivision(True) # Don't check for divide-by-zero.
def mapbuf_uint8(self, that, np.ndarray[np.uint8_t] py_lookup):
cdef np.ndarray[np.uint8_t] py_self_buf = self.buf
cdef np.uint8_t* self_buf = &py_self_buf[0]
cdef np.ndarray[np.uint8_t] py_that_buf = that.buf
cdef np.uint8_t* that_buf = &py_that_buf[0]
cdef np.uint8_t* lookup = &py_lookup[0]
cdef np.uint32_t i
for i in range(py_that_buf.size):
self_buf[i] = lookup[that_buf[i]]
@cython.boundscheck(False)
@cython.cdivision(True) # Don't check for divide-by-zero.
def mapbuf_float32(self, that, np.ndarray[np.float32_t] py_lookup):

@@ -42,1 +30,13 @@ cdef np.ndarray[np.float32_t] py_self_buf = self.buf

self_buf[i] = lookup[that_buf[i]]
@cython.boundscheck(False)
@cython.cdivision(True) # Don't check for divide-by-zero.
def mapbuf_uint8(self, that, np.ndarray[np.uint8_t] py_lookup):
cdef np.ndarray[np.uint8_t] py_self_buf = self.buf
cdef np.uint8_t* self_buf = &py_self_buf[0]
cdef np.ndarray[np.uint8_t] py_that_buf = that.buf
cdef np.uint8_t* that_buf = &py_that_buf[0]
cdef np.uint8_t* lookup = &py_lookup[0]
cdef np.uint32_t i
for i in range(py_that_buf.size):
self_buf[i] = lookup[that_buf[i]]

@@ -8,13 +8,2 @@ # cython: language_level=3

@cython.cdivision(True) # Don't check for divide-by-zero.
def partcopyintonp_uint8(self, np.uint32_t startframe, np.uint32_t endframe, np.ndarray[np.uint8_t] py_thatnp):
cdef np.ndarray[np.uint8_t] py_self_buf = self.buf
cdef np.uint8_t* self_buf = &py_self_buf[0]
cdef np.uint8_t* thatnp = &py_thatnp[0]
cdef np.uint32_t j
for j in range(endframe - startframe):
thatnp[j] = self_buf[startframe]
startframe += 1
@cython.boundscheck(False)
@cython.cdivision(True) # Don't check for divide-by-zero.
def partcopyintonp_float32(self, np.uint32_t startframe, np.uint32_t endframe, np.ndarray[np.float32_t] py_thatnp):

@@ -39,1 +28,12 @@ cdef np.ndarray[np.float32_t] py_self_buf = self.buf

startframe += 1
@cython.boundscheck(False)
@cython.cdivision(True) # Don't check for divide-by-zero.
def partcopyintonp_uint8(self, np.uint32_t startframe, np.uint32_t endframe, np.ndarray[np.uint8_t] py_thatnp):
cdef np.ndarray[np.uint8_t] py_self_buf = self.buf
cdef np.uint8_t* self_buf = &py_self_buf[0]
cdef np.uint8_t* thatnp = &py_thatnp[0]
cdef np.uint32_t j
for j in range(endframe - startframe):
thatnp[j] = self_buf[startframe]
startframe += 1

@@ -8,6 +8,6 @@ # cython: language_level=3

@cython.cdivision(True) # Don't check for divide-by-zero.
def putstrided_uint8(self, np.uint32_t start, np.uint32_t end, np.uint32_t step, np.ndarray[np.uint8_t] py_data):
cdef np.ndarray[np.uint8_t] py_self_buf = self.buf
cdef np.uint8_t* self_buf = &py_self_buf[0]
cdef np.uint8_t* data = &py_data[0]
def putstrided_float32(self, np.uint32_t start, np.uint32_t end, np.uint32_t step, np.ndarray[np.float32_t] py_data):
cdef np.ndarray[np.float32_t] py_self_buf = self.buf
cdef np.float32_t* self_buf = &py_self_buf[0]
cdef np.float32_t* data = &py_data[0]
cdef np.uint32_t j

@@ -22,6 +22,6 @@ j = 0

@cython.cdivision(True) # Don't check for divide-by-zero.
def putstrided_float32(self, np.uint32_t start, np.uint32_t end, np.uint32_t step, np.ndarray[np.float32_t] py_data):
cdef np.ndarray[np.float32_t] py_self_buf = self.buf
cdef np.float32_t* self_buf = &py_self_buf[0]
cdef np.float32_t* data = &py_data[0]
def putstrided_int16(self, np.uint32_t start, np.uint32_t end, np.uint32_t step, np.ndarray[np.int16_t] py_data):
cdef np.ndarray[np.int16_t] py_self_buf = self.buf
cdef np.int16_t* self_buf = &py_self_buf[0]
cdef np.int16_t* data = &py_data[0]
cdef np.uint32_t j

@@ -36,6 +36,6 @@ j = 0

@cython.cdivision(True) # Don't check for divide-by-zero.
def putstrided_int16(self, np.uint32_t start, np.uint32_t end, np.uint32_t step, np.ndarray[np.int16_t] py_data):
cdef np.ndarray[np.int16_t] py_self_buf = self.buf
cdef np.int16_t* self_buf = &py_self_buf[0]
cdef np.int16_t* data = &py_data[0]
def putstrided_uint8(self, np.uint32_t start, np.uint32_t end, np.uint32_t step, np.ndarray[np.uint8_t] py_data):
cdef np.ndarray[np.uint8_t] py_self_buf = self.buf
cdef np.uint8_t* self_buf = &py_self_buf[0]
cdef np.uint8_t* data = &py_data[0]
cdef np.uint32_t j

@@ -42,0 +42,0 @@ j = 0

@@ -22,6 +22,5 @@ # Copyright 2014, 2018, 2019, 2020 Andrzej Cichocki

from aridity.config import ConfigCtrl
from aridity.model import wrap
from aridity.model import Boolean, Resource, wrap
from diapyr import DI, types, UnsatisfiableRequestException
from importlib import import_module
from pathlib import Path
from io import StringIO
import logging, sys

@@ -33,4 +32,2 @@

namespace = 'pym2149'
def __init__(self, *params, args = sys.argv[1:], name = 'root'):

@@ -43,15 +40,12 @@ parser = ArgumentParser()

self.additems = parser.parse_args(args)
self.path = Path(__file__).resolve().parent / f"{name}.arid"
self.resource = Resource(__name__, f"{name}.arid")
@types(DI, this = Config)
def loadconfig(self, di):
config = ConfigCtrl()
config.put('enter', function = enter)
config.put('py', function = lambda *args: py(getattr(config.node, self.namespace), *args))
config.put('resolve', function = lambda *args: AsScope.resolve(di, *args))
config.printf("cwd = %s", self.path.parent)
config.printf("%s . %s", self.namespace, self.path.name)
cc = ConfigCtrl()
config = cc._loadappconfig('pym2149', self.resource)
config.diref = DIRef(di)
if not self.additems.ignore_settings:
try:
config.loadsettings()
cc.loadsettings()
except FileNotFoundError as e:

@@ -61,39 +55,31 @@ log.warning("Settings not found: %s", e)

if 'config' == name:
with config.repl() as repl:
for text in value:
repl.printf("%s", self.namespace)
for line in text.splitlines():
repl(f"\t{line}")
for text in value:
(-config).load(StringIO(text))
else:
setattr(getattr(config.node, self.namespace), name, value)
return getattr(config.node, self.namespace)
setattr(config, name, value)
return config
class AsScope:
class DIRef:
@classmethod
def resolve(cls, di, scope, resolvable):
def __init__(self, di):
self.di = di
def __call__(self, scope, resolvable):
try:
return cls(scope, di(_getglobal(scope, resolvable).scalar))
return wrap(self.di(resolvable.resolve(scope).scalar))
except UnsatisfiableRequestException:
raise NoSuchPathException
def __init__(self, parent, obj):
self.parent = parent
self.obj = obj
def isvalue(scope, resolvable):
try:
resolvable.resolve(scope)
val = True
except NoSuchPathException:
val = False
return Boolean(val)
def resolved(self, name):
try:
return wrap(getattr(self.obj, name))
except AttributeError:
return self.parent.resolved(name)
def pyattr(scope, objresolvable, attrresolvable):
return wrap(getattr(objresolvable.resolve(scope).scalar, attrresolvable.resolve(scope).cat()))
def _getglobal(scope, resolvable):
spec = resolvable.resolve(scope).cat()
lastdot = spec.rindex('.')
return wrap(getattr(import_module(spec[:lastdot], __package__), spec[lastdot + 1:]))
def enter(scope, scoperesolvable, resolvable):
return resolvable.resolve(scoperesolvable.resolve(scope))
def py(config, scope, *clauses):
return wrap(eval(' '.join(c.cat() for c in clauses), dict(config = config)))
def py(scope, coderesolvable):
return wrap(eval(coderesolvable.resolve(scope).cat(), {}))

@@ -18,3 +18,2 @@ # Copyright 2014, 2018, 2019, 2020 Andrzej Cichocki

from minBlepy.const import u4
import numpy as np

@@ -24,5 +23,5 @@

u1 = np.uint8
u4 = u4
u4 = np.uint32
u8 = np.uint64
i4 = np.int32
i8 = np.int64

@@ -29,2 +29,3 @@ # Copyright 2014, 2018, 2019, 2020 Andrzej Cichocki

from diapyr.util import singleton
from minBlepy.minblep import Translator
import logging, numpy as np

@@ -123,16 +124,2 @@

class Translator: # TODO: Convert to Node.
naivex = 0
def __init__(self, clockinfo, minbleps):
self.naiverate = clockinfo.implclock
self.minbleps = minbleps
def step(self, framecount):
naivex = self.naivex
outcount = self.minbleps.getoutcount(naivex, framecount)
self.naivex = (naivex + framecount) % self.naiverate
return naivex, outcount
class WavBuf(Node):

@@ -156,3 +143,3 @@

self.carrybuf = BufType.float().ensureandcrop(self.overflowsize)
self.translator = Translator(clockinfo, minbleps)
self.translator = Translator(clockinfo.implclock, minbleps)
self.dc = floatdtype(0) # Last naive value of previous block.

@@ -175,3 +162,3 @@ self.carrybuf.fill_same(self.dc) # Initial carry can be the initial dc level.

outbuf.fillpart(self.overflowsize, outsize, self.dc)
self.minbleps.paste(naivex, diffbuf, outbuf)
self.minbleps.paste(naivex, diffbuf.buf, outbuf.buf)
self.carrybuf.copywindow(outbuf, outcount, outsize)

@@ -178,0 +165,0 @@ self.dc = naivebuf.last()

@@ -25,6 +25,7 @@ # Copyright 2014, 2018, 2019, 2020 Andrzej Cichocki

from .nod import Node
from .out import FloatStream, Translator
from .out import FloatStream
from .reg import Reg, regproperty
from diapyr import types
from lurlene import topitch
from minBlepy.minblep import Translator

@@ -109,3 +110,3 @@ PAL = 4.43361875e6 * 4 / 18

super().__init__()
self.translator = Translator(clockinfo, minbleps)
self.translator = Translator(clockinfo.implclock, minbleps)
self.shortmaster = BufType.short()

@@ -112,0 +113,0 @@ self.outmaster = BufType.float()

@@ -20,3 +20,3 @@ # Copyright 2014, 2018, 2019, 2020 Andrzej Cichocki

from . import boot, srcbytecodefactory
from .. import jackclient
from ..client import jack
from ..config import ConfigName

@@ -33,3 +33,3 @@ from ..timerimpl import SyncTimer

di.add(srcbytecodefactory)
jackclient.configure(di)
jack.configure(di)
di.add(SyncTimer)

@@ -36,0 +36,0 @@ di.add(PhysicalBundle)

@@ -20,3 +20,3 @@ # Copyright 2014, 2018, 2019, 2020 Andrzej Cichocki

from . import boot
from .. import jackclient
from ..client import jack
from ..config import ConfigName

@@ -39,3 +39,3 @@ from ..lurlene import loadcontext, LurleneBridge

di.add(LogicalBundle)
jackclient.configure(di)
jack.configure(di)
di.add(Player)

@@ -42,0 +42,0 @@ di.all(Started)

@@ -20,3 +20,3 @@ # Copyright 2014, 2018, 2019, 2020 Andrzej Cichocki

from . import boot
from .. import portaudioclient
from ..client import portaudio
from ..config import ConfigName

@@ -39,3 +39,3 @@ from ..lurlene import loadcontext, LurleneBridge

di.add(LogicalBundle)
portaudioclient.configure(di)
portaudio.configure(di)
di.add(Player)

@@ -42,0 +42,0 @@ di.all(Started)

@@ -20,3 +20,3 @@ # Copyright 2014, 2018, 2019, 2020 Andrzej Cichocki

from . import boot
from .. import jackclient
from ..client import jack
from ..config import ConfigName

@@ -34,3 +34,3 @@ from ..timerimpl import SyncTimer

di.add(YMOpen)
jackclient.configure(di)
jack.configure(di)
di.add(SyncTimer)

@@ -37,0 +37,0 @@ di.add(PhysicalBundle)

@@ -20,3 +20,3 @@ # Copyright 2014, 2018, 2019, 2020 Andrzej Cichocki

from . import boot
from .. import portaudioclient
from ..client import portaudio
from ..config import ConfigName

@@ -34,3 +34,3 @@ from ..timerimpl import SyncTimer

di.add(YMOpen)
portaudioclient.configure(di)
portaudio.configure(di)
di.add(SyncTimer)

@@ -37,0 +37,0 @@ di.add(PhysicalBundle)

@@ -19,3 +19,3 @@ # Copyright 2014, 2018, 2019, 2020 Andrzej Cichocki

from .const import u4
from minBlepy.shapes import floatdtype
from minBlepy import floatdtype
import math, numpy as np

@@ -22,0 +22,0 @@

[build-system]
requires = ["setuptools", "wheel", "Cython<3", "numpy"]
requires = ["setuptools", "wheel", "Cython==3.0.11", "numpy==2.0.2"]

@@ -18,2 +18,3 @@ # pym2149

python3 -m venv venvname
venvname/bin/pip install -U pip
venvname/bin/pip install pym2149

@@ -25,8 +26,5 @@ . venvname/bin/activate

```
# GitHub trick to download some files to play:
svn export https://github.com/combatopera/pym2149/trunk/contrib
# Play a tune written in the Lurlene live coding language:
lc2portaudio 'contrib/Jochen Hippel - 7 Gates of Jambala Level 9.py'
lc2jack 'contrib/Jochen Hippel - 7 Gates of Jambala Level 9.py'
lc2portaudio 'contrib/Jochen Hippel - 7 Gates of Jambala Level 9.py'

@@ -33,0 +31,0 @@ # Play a Dosound sound effect:

+32
-72

@@ -1,2 +0,2 @@

import setuptools
from setuptools import setup

@@ -11,4 +11,2 @@ def long_description():

suffixes = '.pyx', '.c'
def __init__(self, module, path):

@@ -18,9 +16,5 @@ self.module = module

def buildrequires(self):
if self.path.endswith('.pyx'):
yield 'Cython<3'
def make_ext(self):
g = {}
with open(self.path + 'bld') as f: # Assume project root.
with open("%sbld" % self.path) as f: # Assume project root.
exec(f.read(), g)

@@ -30,73 +24,39 @@ return g['make_ext'](self.module, self.path)

def __init__(self, rootdir):
import os, setuptools, subprocess
self.packages = setuptools.find_packages(rootdir)
def addextpaths(dirpath, moduleprefix, suffix = '.pyx'):
for name in sorted(os.listdir(os.path.join(rootdir, dirpath))):
if name.endswith(suffix):
module = "%s%s" % (moduleprefix, name[:-len(suffix)])
if module not in extpaths:
extpaths[module] = self.PYXPath(module, os.path.join(dirpath, name))
from setuptools import find_packages
import os
self.packages = find_packages(rootdir)
extpaths = {}
def addextpaths(dirpath, moduleprefix):
names = sorted(os.listdir(os.path.join(rootdir, dirpath)))
for suffix in self.PYXPath.suffixes:
for name in names:
if name.endswith(suffix):
module = "%s%s" % (moduleprefix, name[:-len(suffix)])
if module not in extpaths:
extpaths[module] = self.PYXPath(module, os.path.join(dirpath, name))
addextpaths('.', '')
for package in self.packages:
addextpaths(package.replace('.', os.sep), "%s." % package)
extpaths = extpaths.values()
if extpaths and os.path.isdir(os.path.join(rootdir, '.git')): # We could be an unpacked sdist.
check_ignore = subprocess.Popen(['git', 'check-ignore'] + [p.path for p in extpaths], cwd = rootdir, stdout = subprocess.PIPE)
ignoredpaths = set(check_ignore.communicate()[0].decode().splitlines())
assert check_ignore.wait() in [0, 1]
self.extpaths = [path for path in extpaths if path.path not in ignoredpaths]
else:
self.extpaths = extpaths
self.extpaths = extpaths.values()
def lazy(clazz, init, *initbefore):
from threading import Lock
initlock = Lock()
init = [init]
def overridefactory(name):
orig = getattr(clazz, name)
def override(*args, **kwargs):
with initlock:
if init:
init[0](obj)
del init[:]
return orig(*args, **kwargs)
return override
Lazy = type('Lazy', (clazz, object), {name: overridefactory(name) for name in initbefore})
obj = Lazy()
return obj
# FIXME: The idea was to defer anything Cython/numpy to pyximport time, but this doesn't achieve that.
def cythonize(extensions):
def init(ext_modules):
ordinary = []
cythonizable = []
for e in extensions:
(cythonizable if any(s.endswith('.pyx') for s in e.sources) else ordinary).append(e)
if cythonizable:
def setup_kwargs(self):
kwargs = dict(packages = self.packages)
if self.extpaths:
from Cython.Build import cythonize
ordinary += cythonize(cythonizable)
ext_modules[:] = ordinary
return lazy(list, init, '__getitem__', '__iter__', '__len__')
kwargs['ext_modules'] = cythonize([path.make_ext() for path in self.extpaths])
return kwargs
def ext_modules():
extensions = [path.make_ext() for path in sourceinfo.extpaths]
return dict(ext_modules = cythonize(extensions)) if extensions else {}
sourceinfo = SourceInfo('.')
setuptools.setup(
name = 'pym2149',
version = '33',
description = 'YM2149 emulator supporting YM files, OSC to JACK, PortAudio, WAV',
long_description = long_description(),
long_description_content_type = 'text/markdown',
url = 'https://github.com/combatopera/pym2149',
author = 'Andrzej Cichocki',
packages = sourceinfo.packages,
py_modules = [],
install_requires = ['aridity>=48', 'diapyr>=18', 'lagoon>=31', 'Lurlene>=13', 'minBlepy>=13', 'outjack>=15', 'pyrbo>=5', 'splut>=4', 'timelyOSC>=4'],
package_data = {'': ['*.pxd', '*.pyx', '*.pyxbld', '*.arid', '*.aridt']},
entry_points = {'console_scripts': ['bpmtool=pym2149.scripts.bpmtool:main', 'dosound2jack=pym2149.scripts.dosound2jack:main', 'dosound2txt=pym2149.scripts.dosound2txt:main', 'dosound2wav=pym2149.scripts.dosound2wav:main', 'dsd2wav=pym2149.scripts.dsd2wav:main', 'lc2jack=pym2149.scripts.lc2jack:main', 'lc2portaudio=pym2149.scripts.lc2portaudio:main', 'lc2txt=pym2149.scripts.lc2txt:main', 'lc2wav=pym2149.scripts.lc2wav:main', 'ym2jack=pym2149.scripts.ym2jack:main', 'ym2portaudio=pym2149.scripts.ym2portaudio:main', 'ym2txt=pym2149.scripts.ym2txt:main', 'ym2wav=pym2149.scripts.ym2wav:main', 'mkdsd=ymtests.mkdsd:main']},
**ext_modules())
setup(
name = 'pym2149',
version = '34',
description = 'YM2149 emulator supporting YM files, OSC to JACK, PortAudio, WAV',
long_description = long_description(),
long_description_content_type = 'text/markdown',
url = 'https://github.com/combatopera/pym2149',
author = 'Andrzej Cichocki',
author_email = '3613868+combatopera@users.noreply.github.com',
py_modules = [],
install_requires = ['aridity>=78', 'diapyr>=26', 'lagoon>=31', 'Lurlene>=13', 'minBlepy>=16', 'numpy>=2.0.2', 'outjack>=15', 'pyrbo>=13', 'splut>=4', 'timelyOSC>=4'],
package_data = {'': ['*.pxd', '*.pyx', '*.pyxbld', '*.arid', '*.aridt']},
entry_points = {'console_scripts': ['bpmtool=pym2149.scripts.bpmtool:main', 'dosound2jack=pym2149.scripts.dosound2jack:main', 'dosound2txt=pym2149.scripts.dosound2txt:main', 'dosound2wav=pym2149.scripts.dosound2wav:main', 'dsd2wav=pym2149.scripts.dsd2wav:main', 'lc2jack=pym2149.scripts.lc2jack:main', 'lc2portaudio=pym2149.scripts.lc2portaudio:main', 'lc2txt=pym2149.scripts.lc2txt:main', 'lc2wav=pym2149.scripts.lc2wav:main', 'ym2jack=pym2149.scripts.ym2jack:main', 'ym2portaudio=pym2149.scripts.ym2portaudio:main', 'ym2txt=pym2149.scripts.ym2txt:main', 'ym2wav=pym2149.scripts.ym2wav:main', 'mkdsd=ymtests.mkdsd:main']},
**sourceinfo.setup_kwargs(),
)
# Copyright 2014, 2018, 2019, 2020 Andrzej Cichocki
# This file is part of pym2149.
#
# pym2149 is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# pym2149 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with pym2149. If not, see <http://www.gnu.org/licenses/>.
from .const import clientname
from .iface import AmpScale, Config, Platform, Stream
from .nod import Node
from .out import FloatStream, StereoInfo
from diapyr import types
import outjack.jackclient as jc, logging
log = logging.getLogger(__name__)
class JackClient(jc.JackClient, Platform):
@types(Config, StereoInfo)
def __init__(self, config, stereoinfo):
portcount = stereoinfo.getoutchans.size + config.SID.enabled # FIXME: This is a hack.
super().__init__(clientname, portcount, config.jackringsize, config.jackcoupling)
def start(self):
super().start()
log.debug(
"JACK block size: %s or %.3f seconds",
self.buffersize,
self.buffersize / self.outputrate)
class JackStream(Stream, Node, metaclass = AmpScale):
log2maxpeaktopeak = 1
@types(Config, [FloatStream], JackClient)
def __init__(self, config, streams, client):
super().__init__()
self.systemchannelcount = config.systemchannelcount
for stream in streams:
for chanindex in range(stream.chancount):
client.port_register_output(f"{stream.streamname}_{1 + chanindex}")
self.streams = streams
self.client = client
def start(self):
self.client.activate()
for stream in self.streams:
# Connect all system channels, cycling over our streams if necessary:
for syschanindex in range(self.systemchannelcount):
chanindex = syschanindex % stream.chancount
self.client.connect(f"{clientname}:{stream.streamname}_{1 + chanindex}", f"system:playback_{1 + syschanindex}")
self.filler = BufferFiller(sum(s.chancount for s in self.streams), self.client.buffersize, self.client.current_output_buffer, self.client.send_and_get_output_buffer)
def callimpl(self):
self.filler([self.chain(wav) for stream in self.streams for wav in stream])
def flush(self):
pass # Nothing to be done.
def stop(self):
self.client.deactivate()
class BufferFiller:
def __init__(self, portcount, buffersize, init, flip):
self.portcount = portcount
self.buffersize = buffersize
self._newbuf(init)
self.flip = flip
def __call__(self, outbufs):
n = len(outbufs[0])
i = 0
while i < n:
m = min(n - i, self.buffersize - self.cursor)
for portindex in range(self.portcount):
self.outbuf[portindex, self.cursor:self.cursor + m] = outbufs[portindex].buf[i:i + m]
self.cursor += m
i += m
if self.cursor == self.buffersize:
self._newbuf(self.flip)
def _newbuf(self, factory):
outbuf = factory().view()
outbuf.shape = self.portcount, self.buffersize
self.outbuf = outbuf
self.cursor = 0
def configure(di):
di.add(JackClient)
di.add(JackStream)
# Copyright 2014, 2018, 2019, 2020 Andrzej Cichocki
# This file is part of pym2149.
#
# pym2149 is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# pym2149 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with pym2149. If not, see <http://www.gnu.org/licenses/>.
from .iface import AmpScale, Config, Platform, Stream
from .jackclient import BufferFiller
from .nod import Node
from .out import FloatStream, StereoInfo
from diapyr import types
import logging, outjack.portaudioclient as pac
log = logging.getLogger(__name__)
class PortAudioClient(pac.PortAudioClient, Platform):
@types(Config, StereoInfo)
def __init__(self, config, stereoinfo):
config = config.PortAudio
super().__init__(stereoinfo.getoutchans.size, config.outputrate, config.buffersize, config.ringsize, config.coupling)
class PortAudioStream(Node, Stream, metaclass = AmpScale):
log2maxpeaktopeak = 1
@types(StereoInfo, FloatStream, PortAudioClient)
def __init__(self, stereoinfo, wavs, client):
super().__init__()
self.chancount = stereoinfo.getoutchans.size
self.wavs = wavs
self.client = client
def start(self):
self.client.activate()
self.filler = BufferFiller(self.chancount, self.client.buffersize, self.client.current_output_buffer, self.client.send_and_get_output_buffer)
def callimpl(self):
self.filler([self.chain(wav) for wav in self.wavs])
def flush(self):
pass
def stop(self):
self.client.deactivate()
def configure(di):
di.add(PortAudioClient)
di.add(PortAudioStream)

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet