Skip to content

Commit

Permalink
Switch to pyamapping
Browse files Browse the repository at this point in the history
  • Loading branch information
dreinsch committed Aug 3, 2023
1 parent 0531afd commit 4c3bea6
Show file tree
Hide file tree
Showing 7 changed files with 18 additions and 108 deletions.
9 changes: 5 additions & 4 deletions pya/amfcc.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import numpy as np
from warnings import warn
from pyamapping import mel_to_hz, hz_to_mel
from .helper import next_pow2, signal_to_frame, round_half_up, magspec
from .helper import mel2hz, hz2mel, is_pow2
from .helper import is_pow2
from .helper import basicplot
from scipy.signal import get_window
from scipy.fftpack import dct
Expand Down Expand Up @@ -260,12 +261,12 @@ def mel_filterbanks(sr, nfilters=26, nfft=512, lowfreq=0, highfreq=None):
highfreq = highfreq or sr // 2

# compute points evenly spaced in mels
lowmel = hz2mel(lowfreq)
highmel = hz2mel(highfreq)
lowmel = hz_to_mel(lowfreq)
highmel = hz_to_mel(highfreq)
melpoints = np.linspace(lowmel, highmel, nfilters + 2)
# our points are in Hz, but we use fft bins, so we have to convert
# from Hz to fft bin number
bin = np.floor((nfft + 1) * mel2hz(melpoints) / sr)
bin = np.floor((nfft + 1) * mel_to_hz(melpoints) / sr)

filter_banks = np.zeros([nfilters, nfft // 2 + 1])
for j in range(0, nfilters):
Expand Down
6 changes: 3 additions & 3 deletions pya/arecorder.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import pyaudio
from . import Asig
from . import Aserver
from .helper import dbamp
from pyamapping import db_to_amp


_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -71,10 +71,10 @@ def set_tracks(self, tracks, gains):
elif len(tracks) > self.channels or len(gains) > self.channels:
raise AttributeError("argument cannot be larger than channels.")
self.tracks = tracks
self.gains = np.array([dbamp(g) for g in gains], dtype="float32")
self.gains = np.array([db_to_amp(g) for g in gains], dtype="float32")
elif isinstance(tracks, numbers.Number) and isinstance(gains, numbers.Number):
self.tracks = [tracks]
self.gains = dbamp(gains)
self.gains = db_to_amp(gains)
else:
raise TypeError("Arguments need to be both list or both number.")

Expand Down
12 changes: 6 additions & 6 deletions pya/asig.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import pya.aspec
import pya.astft
import pya.amfcc
from .helper import ampdb, dbamp, linlin
from pyamapping import amp_to_db, db_to_amp, linlin
from .helper import spectrum, audio_from_file, padding
from .helper import basicplot

Expand Down Expand Up @@ -874,7 +874,7 @@ def norm(self, norm=1, in_db=False, dcflag=False):
"""
if in_db:
norm = dbamp(norm)
norm = db_to_amp(norm)
if dcflag:
sig = self.sig - np.mean(self.sig, 0)
else:
Expand All @@ -901,7 +901,7 @@ def gain(self, amp=None, db=None):
if db is not None and amp is not None:
raise AttributeError("Both amp and db are set, use one only.")
elif db is not None: # overwrites amp
amp = dbamp(db)
amp = db_to_amp(db)
elif amp is None: # default 1 if neither is given
amp = 1
return Asig(self.sig * amp, self.sr, label=self.label + "_scaled", cn=self.cn)
Expand Down Expand Up @@ -958,7 +958,7 @@ def plot(
if fn == "db":

def fn(x):
return np.sign(x) * ampdb((abs(x) * 2 ** 16 + 1))
return np.sign(x) * amp_to_db((abs(x) * 2 ** 16 + 1))

elif not callable(fn):
msg = "Asig.plot: fn is neither keyword nor function"
Expand Down Expand Up @@ -1223,7 +1223,7 @@ def find_events(
warn(msg)
return -1
step_samples = int(step_dur * self.sr)
sil_thr_amp = dbamp(sil_thr)
sil_thr_amp = db_to_amp(sil_thr)
sil_flag = True
sil_count = 0
sil_min_steps = int(sil_min_dur / step_dur)
Expand Down Expand Up @@ -1443,7 +1443,7 @@ def plot_freqz(self, worN, **kwargs):
"""
w, h = scipy.signal.freqz(self._["b"], self._["a"], worN)
plt.plot(w * self.sr / 2 / np.pi, ampdb(abs(h)), **kwargs)
plt.plot(w * self.sr / 2 / np.pi, amp_to_db(abs(h)), **kwargs)

def envelope(self, amps, ts=None, curve=1, kind="linear"):
"""Create an envelop and multiply by the signal.
Expand Down
1 change: 0 additions & 1 deletion pya/helper/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# from .helpers import ampdb, dbamp, cpsmidi, midicps, linlin
# from .helpers import audio_from_file, buf_to_float, spectrum, audio_from_file
# from .helpers import normalize, device_info, find_device
# from .helpers import padding, shift_bit_length
Expand Down
75 changes: 0 additions & 75 deletions pya/helper/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,49 +12,6 @@ class _error(Exception):
pass


def linlin(x, smi, sma, dmi, dma):
"""Linear mapping
Parameters
----------
x : float
input value
smi : float
input range's minimum
sma : float
input range's maximum
dmi : float
input range's minimum
dma :
Returns
-------
_ : float
mapped output
"""
return (x - smi) / (sma - smi) * (dma - dmi) + dmi


def midicps(m):
"""Convert midi number into cycle per second"""
return 440.0 * 2 ** ((m - 69) / 12.0)


def cpsmidi(c):
"""Convert cycle per second into midi number"""
return 69 + 12 * np.log2(c / 440.0)


def dbamp(db):
"""Convert db to amplitude"""
return 10 ** (db / 20.0)


def ampdb(amp):
"""Convert amplitude to db"""
return 20 * np.log10(amp)


def spectrum(sig, samples, channels, sr):
"""Return spectrum of a given signal. This method return spectrum matrix if input signal is multi-channels.
Expand Down Expand Up @@ -340,35 +297,3 @@ def powspec(frames, NFFT):
Each row has the size of NFFT / 2 + 1 due to rfft.
"""
return 1.0 / NFFT * np.square(magspec(frames, NFFT))


def hz2mel(hz):
"""Convert a value in Hertz to Mels
Parameters
----------
hz : number of array
value in Hz, can be an array
Returns:
--------
_ : number of array
value in Mels, same type as the input.
"""
return 2595 * np.log10(1 + hz / 700.)


def mel2hz(mel):
"""Convert a value in Hertz to Mels
Parameters
----------
hz : number of array
value in Hz, can be an array
Returns:
--------
_ : number of array
value in Mels, same type as the input.
"""
return 700 * (10 ** (mel / 2595.0) - 1)
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pyamapping
scipy>=1.7.3
matplotlib>=3.5.3
pyaudio>=0.2.12; python_version >= '3.10'
Expand Down
22 changes: 3 additions & 19 deletions tests/test_helpers.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from unittest import TestCase
from pya import Asig, Ugen
from pya.helper import spectrum, padding, next_pow2, is_pow2, midicps, cpsmidi
from pya.helper import signal_to_frame, magspec, powspec, linlin
from pya.helper import hz2mel, mel2hz
from pya.helper import spectrum, padding, next_pow2, is_pow2
from pya.helper import signal_to_frame, magspec, powspec

import numpy as np
import pyaudio

Expand Down Expand Up @@ -34,18 +34,6 @@ def setUp(self):
def tearDown(self):
pass

def test_linlin(self):
self.assertTrue(np.array_equal(linlin(np.arange(0, 10),
smi=0, sma=10, dmi=0., dma=1.0),
np.array([0., 0.1, 0.2, 0.3, 0.4, 0.5,
0.6, 0.7, 0.8, 0.9])))

def test_midi_conversion(self):
m = 69
f = 440
self.assertEqual(f, midicps(m))
self.assertEqual(m, cpsmidi(f))

def test_spectrum(self):
# Not tested expected outcome yet.
frq, Y = spectrum(self.asine.sig, self.asine.samples, self.asine.channels, self.asine.sr)
Expand Down Expand Up @@ -126,7 +114,3 @@ def test_magspec_pspec(self):
ps = powspec(frames, 512)
self.assertEqual(ps.shape, (20, 257))
self.assertTrue((ps >= 0.).all()) # All elements should be non-negative

def test_melhzconversion(self):
self.assertAlmostEqual(hz2mel(440), 549.64, 2)
self.assertAlmostEqual(mel2hz(549.64), 440, 2)

0 comments on commit 4c3bea6

Please sign in to comment.