Skip to content

Commit

Permalink
Add a convenience method for producing a FrequencyBand instance repre…
Browse files Browse the repository at this point in the history
…senting the audible frequency range of a given audio sample rate
  • Loading branch information
JohnVinyard committed Feb 9, 2019
1 parent df63339 commit bb9de3e
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 5 deletions.
2 changes: 1 addition & 1 deletion zounds/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
SpectralFlatness, AWeighting, LinearScale, FrequencyBand, \
FrequencyScale, FrequencyDimension, GeometricScale, HanningWindowingFunc, \
FrequencyAdaptiveTransform, ExplicitScale, ExplicitFrequencyDimension, \
FrequencyAdaptive, FrequencyWeighting, Hertz, BarkScale, MelScale, \
FrequencyAdaptive, FrequencyWeighting, Hertz, Hz, BarkScale, MelScale, \
ChromaScale, fir_filter_bank

from loudness import \
Expand Down
2 changes: 1 addition & 1 deletion zounds/spectral/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

from frequencyscale import \
LinearScale, FrequencyBand, FrequencyScale, GeometricScale, ExplicitScale, \
Hertz, BarkScale, MelScale, ChromaScale
Hertz, Hz, BarkScale, MelScale, ChromaScale

from frequencyadaptive import FrequencyAdaptive

Expand Down
11 changes: 9 additions & 2 deletions zounds/spectral/frequencyscale.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@ def __neg__(self):
return Hertz(-self.hz)

def __add__(self, other):
return Hertz(self + other)
return Hertz(self.hz + other.hz)


class Hz(Hertz):
pass


# TODO: What commonalities can be factored out of this class and TimeSlice?
# TODO: Deprecate stuff in psychoacoustics.py in favor of these classes
class FrequencyBand(object):
"""
Represents an interval, or band of frequencies in hertz (cycles per second)
Expand Down Expand Up @@ -71,6 +74,10 @@ def intersect(self, other):
highest_start = max(self.start_hz, other.start_hz)
return FrequencyBand(highest_start, lowest_stop)

@classmethod
def audible_range(cls, samplerate):
return FrequencyBand(Hz(20), Hz(samplerate.nyquist))

def bandwidth_ratio(self, other):
return other.bandwidth / self.bandwidth

Expand Down
19 changes: 18 additions & 1 deletion zounds/spectral/test_frequencyscale.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import division
import unittest2
from frequencyscale import \
FrequencyBand, LinearScale, ExplicitScale, GeometricScale, Hertz
FrequencyBand, LinearScale, ExplicitScale, GeometricScale, Hertz, Hz
from zounds.timeseries import SR44100
import numpy as np

Expand All @@ -11,6 +11,14 @@ def test_can_negate_hertz(self):
hz = -Hertz(10)
self.assertIsInstance(hz, Hertz)

def test_can_add_hertz(self):
hz = Hertz(20) + Hertz(30)
self.assertEqual(Hertz(50), hz)

def test_can_subtract_hertz(self):
hz = Hz(100) - Hz(20)
self.assertEqual(Hz(80), hz)


class FrequencyBandTests(unittest2.TestCase):
def test_can_create_from_center_frequency(self):
Expand Down Expand Up @@ -46,6 +54,15 @@ def test_intersection_ratio(self):
ratio = fb1.intersection_ratio(fb2)
self.assertEqual(0.5, ratio)

def test_audible_range_lower_bound(self):
band = FrequencyBand.audible_range(SR44100())
self.assertEqual(20, band.start_hz)

def test_audible_range_upper_bound(self):
sr = SR44100()
band = FrequencyBand.audible_range(sr)
self.assertEqual(int(sr) // 2, band.stop_hz)


class FrequencyScaleTests(unittest2.TestCase):
def test_get_slice_converts_frequency_band_to_integer_based_slice(self):
Expand Down

0 comments on commit bb9de3e

Please sign in to comment.