Skip to content

Instantly share code, notes, and snippets.

@jepler
Last active February 28, 2020 20:24
Show Gist options
  • Save jepler/2701e024cdea2c2f60527d674a7b28bc to your computer and use it in GitHub Desktop.
Save jepler/2701e024cdea2c2f60527d674a7b28bc to your computer and use it in GitHub Desktop.
class DynamicSampleInterface:
"""What the sample protocol might look like, if exposed to Python
Such types probably also have to subclass from a particular native
type which implements the protocol (not shown)"""
def get(self):
"""Return a buffer with the next samples"""
def reset(self):
"""Move the position to the first sample, if inapplicable"""
@property
def more(self):
"""False when the end of a finite sample is reached, True otherwise"""
@property
def sample_rate(self):
"""Return the sample rate in Hz"""
@property
def bits_per_sample(self):
"""Return the bits per sample (must be 8 or 16)"""
@property
def channel_count(self):
"""Return the number of channels (must be 1 or 2)"""
@property
def max_samples(self):
"""Return the maximum number of samples returned by one get() call"""
class PDMInSample: # implements DynamicSampleInterface
def __init__(..., *, buffer, ...):
"""Initialize the PDM Input Stream, including a buffer object. The buffer object is divided in half and one half of it will be returned by get()"""
def get(self):
"""Returns the next samples, blocking if necessary"""
@property
def more(self):
"""PDMInStream is an infinite sample, so always returns True"""
return True
@property
def sample_rate(self):
"""Return the sample rate in Hz"""
@property
def bits_per_sample(self):
"""Return the bits per sample (must be 8 or 16)"""
@property
def channel_count(self):
"""Return the number of channels (must be 1 or 2)"""
@property
def max_samples(self):
"""Return the maximum number of samples returned by one get() call"""
# This is an addition to the API of DynamicSampleInterface. It may not
# be useful; in reality, samples have to come lock step (clocked from the
# same source with the same divisor) or bad things happen.
#
# Actually, it might make things better that you can check ready() once
# and then actually start playing the PDMInSample...
@property
def ready(self):
"""Returns true if the next samples are ready, False otherwise"""
class FIRFilterSample: # implements DynamicSampleInterface
def __init__(self, sample, taps):
self.sample = sample
self.taps = taps
def get(self):
... get from sample, deal with boundary conditions ...
... convolve with taps, return value ...
@property
def more(self):
return self.sample.more
@property
def sample_rate(self):
return self.sample.sample_rate
@property
def bits_per_sample(self):
return self.sample.bits_per_sample
@property
def channel_count(self):
return self.sample.channel_count
@property
def max_samples(self):
return self.sample.max_samples
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment