def testReadWrite(self):
    original = self._encoder(self.n, name=self.name)
    originalValue = original.encode([1,0,1,0,1,0,1,0,1])

    proto1 = SparsePassThroughEncoderProto.new_message()
    original.write(proto1)

    # Write the proto to a temp file and read it back into a new proto
    with tempfile.TemporaryFile() as f:
      proto1.write(f)
      f.seek(0)
      proto2 = SparsePassThroughEncoderProto.read(f)

    encoder = SparsePassThroughEncoder.read(proto2)

    self.assertIsInstance(encoder, SparsePassThroughEncoder)
    self.assertEqual(encoder.name, original.name)
    self.assertEqual(encoder.verbosity, original.verbosity)
    self.assertEqual(encoder.w, original.w)
    self.assertEqual(encoder.n, original.n)
    self.assertEqual(encoder.description, original.description)
    self.assertTrue(numpy.array_equal(encoder.encode([1,0,1,0,1,0,1,0,1]),
                                      originalValue))
    self.assertEqual(original.decode(encoder.encode([1,0,1,0,1,0,1,0,1])),
                     encoder.decode(original.encode([1,0,1,0,1,0,1,0,1])))

    # Feed in a new value and ensure the encodings match
    result1 = original.encode([0,1,0,1,0,1,0,1,0])
    result2 = encoder.encode([0,1,0,1,0,1,0,1,0])
    self.assertTrue(numpy.array_equal(result1, result2))
    def testReadWrite(self):
        original = self._encoder(self.n, name=self.name)
        originalValue = original.encode([1, 0, 1, 0, 1, 0, 1, 0, 1])

        proto1 = SparsePassThroughEncoderProto.new_message()
        original.write(proto1)

        # Write the proto to a temp file and read it back into a new proto
        with tempfile.TemporaryFile() as f:
            proto1.write(f)
            f.seek(0)
            proto2 = SparsePassThroughEncoderProto.read(f)

        encoder = SparsePassThroughEncoder.read(proto2)

        self.assertIsInstance(encoder, SparsePassThroughEncoder)
        self.assertEqual(encoder.name, original.name)
        self.assertEqual(encoder.verbosity, original.verbosity)
        self.assertEqual(encoder.w, original.w)
        self.assertEqual(encoder.n, original.n)
        self.assertEqual(encoder.description, original.description)
        self.assertTrue(
            numpy.array_equal(encoder.encode([1, 0, 1, 0, 1, 0, 1, 0, 1]),
                              originalValue))
        self.assertEqual(
            original.decode(encoder.encode([1, 0, 1, 0, 1, 0, 1, 0, 1])),
            encoder.decode(original.encode([1, 0, 1, 0, 1, 0, 1, 0, 1])))

        # Feed in a new value and ensure the encodings match
        result1 = original.encode([0, 1, 0, 1, 0, 1, 0, 1, 0])
        result2 = encoder.encode([0, 1, 0, 1, 0, 1, 0, 1, 0])
        self.assertTrue(numpy.array_equal(result1, result2))
Example #3
0
    def __init__(self):
        """
    Instantiate temporal pooler, encoder, audio sampler, filter, & freq plot
    """
        self.vis = Visualizations()
        """
    The number of columns in the input and therefore the TP
     2**9 = 512
     Trial and error pulled that out
     numCols should be tested during benchmarking
    """
        self.numCols = 2**9
        sparsity = 0.10
        self.numInput = int(self.numCols * sparsity)
        """
    Create a bit map encoder
    
    From the encoder's __init__ method:
     1st arg: the total bits in input
     2nd arg: the number of bits used to encode each input bit
    """
        self.e = SparsePassThroughEncoder(self.numCols, 1)
        """
    Sampling details
     rate: The sampling rate in Hz of my soundcard
     buffersize: The size of the array to which we will save audio segments (2^12 = 4096 is very good)
     secToRecord: The length of each sampling
     buffersToRecord: how many multiples of buffers are we recording?
    """
        rate = 44100
        secToRecord = .1
        self.buffersize = 2**12
        self.buffersToRecord = int(rate * secToRecord / self.buffersize)
        if not self.buffersToRecord:
            self.buffersToRecord = 1
        """
    Filters in Hertz
     highHertz: lower limit of the bandpass filter, in Hertz
     lowHertz: upper limit of the bandpass filter, in Hertz
       max lowHertz = (buffersize / 2 - 1) * rate / buffersize
    """
        highHertz = 500
        lowHertz = 10000
        """
    Convert filters from Hertz to bins
     highpass: convert the highHertz into a bin for the FFT
     lowpass: convert the lowHertz into a bin for the FFt
     NOTES:
      highpass is at least the 1st bin since most mics only pick up >=20Hz
      lowpass is no higher than buffersize/2 - 1 (highest array index)
      passband needs to be wider than size of numInput - not checking for that
    """
        self.highpass = max(int(highHertz * self.buffersize / rate), 1)
        self.lowpass = min(int(lowHertz * self.buffersize / rate),
                           self.buffersize / 2 - 1)
        """
    The call to create the temporal pooler region
    """
        self.tp = TP(numberOfCols=self.numCols,
                     cellsPerColumn=4,
                     initialPerm=0.5,
                     connectedPerm=0.5,
                     minThreshold=10,
                     newSynapseCount=10,
                     permanenceInc=0.1,
                     permanenceDec=0.07,
                     activationThreshold=8,
                     globalDecay=0.02,
                     burnIn=2,
                     checkSynapseConsistency=False,
                     pamLength=100)
        """
    Creating the audio stream from our mic
    """
        p = pyaudio.PyAudio()
        #self.inStream = p.open(format=pyaudio.paInt32,channels=1,rate=rate,input=True,frames_per_buffer=self.buffersize)
        self.inStream = p.open(format=pyaudio.paInt32,
                               channels=1,
                               rate=rate,
                               input=True,
                               input_device_index=4,
                               frames_per_buffer=self.buffersize)

        #参考 成功したpyaudio の設定
        #stream = audio.open(format=pyaudio.paInt16, channels=CHANNELS,rate=RATE, input=True,input_device_index=4,frames_per_buffer=CHUNK)
        """
    Setting up the array that will handle the timeseries of audio data from our input
    """
        self.audio = numpy.empty((self.buffersToRecord * self.buffersize),
                                 dtype="uint32")
        """
    Print out the inputs
    """
        print "Number of columns:\t" + str(self.numCols)
        print "Max size of input:\t" + str(self.numInput)
        print "Sampling rate (Hz):\t" + str(rate)
        print "Passband filter (Hz):\t" + str(highHertz) + " - " + str(
            lowHertz)
        print "Passband filter (bin):\t" + str(self.highpass) + " - " + str(
            self.lowpass)
        print "Bin difference:\t\t" + str(self.lowpass - self.highpass)
        print "Buffersize:\t\t" + str(self.buffersize)
        """
    Setup the plot
     Use the bandpass filter frequency range as the x-axis
     Rescale the y-axis
    """
        plt.ion()
        bin = range(self.highpass, self.lowpass)
        xs = numpy.arange(len(bin)) * rate / self.buffersize + highHertz
        self.freqPlot = plt.plot(xs, xs)[0]
        plt.ylim(0, 10**12)

        while True:
            self.processAudio()
Example #4
0
class AudioStream:
    def __init__(self):
        """
    Instantiate temporal pooler, encoder, audio sampler, filter, & freq plot
    """
        self.vis = Visualizations()
        """
    The number of columns in the input and therefore the TP
     2**9 = 512
     Trial and error pulled that out
     numCols should be tested during benchmarking
    """
        self.numCols = 2**9
        sparsity = 0.10
        self.numInput = int(self.numCols * sparsity)
        """
    Create a bit map encoder
    
    From the encoder's __init__ method:
     1st arg: the total bits in input
     2nd arg: the number of bits used to encode each input bit
    """
        self.e = SparsePassThroughEncoder(self.numCols, 1)
        """
    Sampling details
     rate: The sampling rate in Hz of my soundcard
     buffersize: The size of the array to which we will save audio segments (2^12 = 4096 is very good)
     secToRecord: The length of each sampling
     buffersToRecord: how many multiples of buffers are we recording?
    """
        rate = 44100
        secToRecord = .1
        self.buffersize = 2**12
        self.buffersToRecord = int(rate * secToRecord / self.buffersize)
        if not self.buffersToRecord:
            self.buffersToRecord = 1
        """
    Filters in Hertz
     highHertz: lower limit of the bandpass filter, in Hertz
     lowHertz: upper limit of the bandpass filter, in Hertz
       max lowHertz = (buffersize / 2 - 1) * rate / buffersize
    """
        highHertz = 500
        lowHertz = 10000
        """
    Convert filters from Hertz to bins
     highpass: convert the highHertz into a bin for the FFT
     lowpass: convert the lowHertz into a bin for the FFt
     NOTES:
      highpass is at least the 1st bin since most mics only pick up >=20Hz
      lowpass is no higher than buffersize/2 - 1 (highest array index)
      passband needs to be wider than size of numInput - not checking for that
    """
        self.highpass = max(int(highHertz * self.buffersize / rate), 1)
        self.lowpass = min(int(lowHertz * self.buffersize / rate),
                           self.buffersize / 2 - 1)
        """
    The call to create the temporal pooler region
    """
        self.tp = TP(numberOfCols=self.numCols,
                     cellsPerColumn=4,
                     initialPerm=0.5,
                     connectedPerm=0.5,
                     minThreshold=10,
                     newSynapseCount=10,
                     permanenceInc=0.1,
                     permanenceDec=0.07,
                     activationThreshold=8,
                     globalDecay=0.02,
                     burnIn=2,
                     checkSynapseConsistency=False,
                     pamLength=100)
        """
    Creating the audio stream from our mic
    """
        p = pyaudio.PyAudio()
        #self.inStream = p.open(format=pyaudio.paInt32,channels=1,rate=rate,input=True,frames_per_buffer=self.buffersize)
        self.inStream = p.open(format=pyaudio.paInt32,
                               channels=1,
                               rate=rate,
                               input=True,
                               input_device_index=4,
                               frames_per_buffer=self.buffersize)

        #参考 成功したpyaudio の設定
        #stream = audio.open(format=pyaudio.paInt16, channels=CHANNELS,rate=RATE, input=True,input_device_index=4,frames_per_buffer=CHUNK)
        """
    Setting up the array that will handle the timeseries of audio data from our input
    """
        self.audio = numpy.empty((self.buffersToRecord * self.buffersize),
                                 dtype="uint32")
        """
    Print out the inputs
    """
        print "Number of columns:\t" + str(self.numCols)
        print "Max size of input:\t" + str(self.numInput)
        print "Sampling rate (Hz):\t" + str(rate)
        print "Passband filter (Hz):\t" + str(highHertz) + " - " + str(
            lowHertz)
        print "Passband filter (bin):\t" + str(self.highpass) + " - " + str(
            self.lowpass)
        print "Bin difference:\t\t" + str(self.lowpass - self.highpass)
        print "Buffersize:\t\t" + str(self.buffersize)
        """
    Setup the plot
     Use the bandpass filter frequency range as the x-axis
     Rescale the y-axis
    """
        plt.ion()
        bin = range(self.highpass, self.lowpass)
        xs = numpy.arange(len(bin)) * rate / self.buffersize + highHertz
        self.freqPlot = plt.plot(xs, xs)[0]
        plt.ylim(0, 10**12)

        while True:
            self.processAudio()

    def processAudio(self):
        """
    Sample audio, encode, send it to the TP
    
    Pulls the audio from the mic
    Conditions that audio as an SDR
    Computes a prediction via the TP
    Update the visualizations
    """
        """
    Cycle through the multiples of the buffers we're sampling
    Sample audio to store for each frame in buffersize
     Mic voltage-level timeseries is saved as 32-bit binary
    Convert that 32-bit binary into integers, and save to array for the FFT
    """
        for i in range(self.buffersToRecord):
            try:
                audioString = self.inStream.read(self.buffersize)
            except IOError:
                print "Overflow error from 'audiostring = inStream.read(buffersize)'. Try decreasing buffersize."
                quit()
            self.audio[i * self.buffersize:(i + 1) *
                       self.buffersize] = numpy.fromstring(audioString,
                                                           dtype="uint32")
        """
    Get int array of strength for each bin of frequencies via fast fourier transform
    Get the indices of the strongest frequencies (the top 'numInput')
    Scale the indices so that the frequencies fit to within numCols
    Pick out the unique indices (we've reduced the mapping, so we likely have multiples)
    Encode those indices into an SDR via the SparsePassThroughEncoder
    Cast the SDR as a float for the TP
    """
        ys = self.fft(self.audio, self.highpass, self.lowpass)  #fft の結果
        fs = numpy.sort(
            ys.argsort()[-self.numInput:])  #ysを昇順にソートして結果の上位から入力数だけのインデックス
        ufs = fs.astype(numpy.float32) / (
            self.lowpass -
            self.highpass) * self.numCols  #fsをフロートに変換して、バンド幅で割り、カラム数で割る。
        ufs = ufs.astype(numpy.int32)
        ufs = numpy.unique(ufs)  #重複をなくす

        actual = numpy.zeros(self.numCols, dtype=numpy.int32)

        for index in ufs:
            actual += self.e.encode(index)

        actualInt = actual
        """
    Pass the SDR to the TP
    Collect the prediction SDR from the TP
    Pass the prediction & actual SDRS to the anomaly calculator & array comparer
    Update the frequency plot
    """

        self.tp.compute(actual, enableLearn=True, computeInfOutput=True)
        predictedInt = self.tp.getPredictedState().max(axis=1)
        compare = self.vis.compareArray(actualInt, predictedInt)
        anomaly = self.vis.calcAnomaly(actualInt, predictedInt)

        print ".".join(compare)
        print self.vis.hashtagAnomaly(anomaly)

        self.freqPlot.set_ydata(ys)
        #plt.plot(self.xs,ys)
        plt.show(block=False)
        plt.draw()

    def fft(self, audio, highpass, lowpass):
        """
    Fast fourier transform conditioning

    Output:
    'output' contains the strength of each frequency in the audio signal
    frequencies are marked by its position in 'output':
    frequency = index * rate / buffesize
    output.size = buffersize/2 
    Method:
    Use numpy's FFT (numpy.fft.fft)
    Find the magnitude of the complex numbers returned (abs value)
    Split the FFT array in half, because we have mirror frequencies
     (they're the complex conjugates)
    Use just the first half to apply the bandpass filter

    Great info here: http://stackoverflow.com/questions/4364823/how-to-get-frequency-from-fft-result
    """
        left, right = numpy.split(numpy.abs(numpy.fft.fft(audio)), 2)
        output = left[highpass:lowpass]
        return output
Example #5
0
  def __init__(self):
    """
    Instantiate temporal pooler, encoder, audio sampler, filter, & freq plot
    """
    self.vis = Visualizations()
    
    """
    The number of columns in the input and therefore the TP
     2**9 = 512
     Trial and error pulled that out
     numCols should be tested during benchmarking
    """
    self.numCols = 2**9
    sparsity = 0.10
    self.numInput = int(self.numCols * sparsity)

    """
    Create a bit map encoder
    
    From the encoder's __init__ method:
     1st arg: the total bits in input
     2nd arg: the number of bits used to encode each input bit
    """
    self.e = SparsePassThroughEncoder(self.numCols, 1)

    """
    Sampling details
     rate: The sampling rate in Hz of my soundcard
     buffersize: The size of the array to which we will save audio segments (2^12 = 4096 is very good)
     secToRecord: The length of each sampling
     buffersToRecord: how many multiples of buffers are we recording?
    """
    rate=44100
    secToRecord=.1
    self.buffersize=2**12
    self.buffersToRecord=int(rate*secToRecord/self.buffersize)
    if not self.buffersToRecord: 
      self.buffersToRecord=1

    """
    Filters in Hertz
     highHertz: lower limit of the bandpass filter, in Hertz
     lowHertz: upper limit of the bandpass filter, in Hertz
       max lowHertz = (buffersize / 2 - 1) * rate / buffersize
    """
    highHertz = 500
    lowHertz = 10000

    """
    Convert filters from Hertz to bins
     highpass: convert the highHertz into a bin for the FFT
     lowpass: convert the lowHertz into a bin for the FFt
     NOTES:
      highpass is at least the 1st bin since most mics only pick up >=20Hz
      lowpass is no higher than buffersize/2 - 1 (highest array index)
      passband needs to be wider than size of numInput - not checking for that
    """
    self.highpass = max(int(highHertz * self.buffersize / rate),1)
    self.lowpass = min(int(lowHertz * self.buffersize / rate), self.buffersize/2 - 1)

    """
    The call to create the temporal pooler region
    """
    self.tp = TP(numberOfCols=self.numCols, cellsPerColumn=4,
      initialPerm=0.5, connectedPerm=0.5,
      minThreshold=10, newSynapseCount=10,
      permanenceInc=0.1, permanenceDec=0.07,
      activationThreshold=8,
      globalDecay=0.02, burnIn=2,
      checkSynapseConsistency=False,
      pamLength=100)
  
    """
    Creating the audio stream from our mic
    """
    p = pyaudio.PyAudio()
    self.inStream = p.open(format=pyaudio.paInt32,channels=1,rate=rate,input=True,frames_per_buffer=self.buffersize)

    """
    Setting up the array that will handle the timeseries of audio data from our input
    """
    self.audio = numpy.empty((self.buffersToRecord*self.buffersize),dtype="uint32")

    """
    Print out the inputs
    """
    print "Number of columns:\t" + str(self.numCols)
    print "Max size of input:\t" + str(self.numInput)
    print "Sampling rate (Hz):\t" + str(rate)
    print "Passband filter (Hz):\t" + str(highHertz) + " - " + str(lowHertz)
    print "Passband filter (bin):\t" + str(self.highpass) + " - " + str(self.lowpass)
    print "Bin difference:\t\t" + str(self.lowpass - self.highpass)
    print "Buffersize:\t\t" + str(self.buffersize)

    """
    Setup the plot
     Use the bandpass filter frequency range as the x-axis
     Rescale the y-axis
    """
    plt.ion()
    bin = range(self.highpass,self.lowpass)
    xs = numpy.arange(len(bin))*rate/self.buffersize + highHertz
    self.freqPlot = plt.plot(xs,xs)[0]
    plt.ylim(0, 10**12)
    
    while True:
      self.processAudio()
Example #6
0
class AudioStream:

  def __init__(self):
    """
    Instantiate temporal pooler, encoder, audio sampler, filter, & freq plot
    """
    self.vis = Visualizations()
    
    """
    The number of columns in the input and therefore the TP
     2**9 = 512
     Trial and error pulled that out
     numCols should be tested during benchmarking
    """
    self.numCols = 2**9
    sparsity = 0.10
    self.numInput = int(self.numCols * sparsity)

    """
    Create a bit map encoder
    
    From the encoder's __init__ method:
     1st arg: the total bits in input
     2nd arg: the number of bits used to encode each input bit
    """
    self.e = SparsePassThroughEncoder(self.numCols, 1)

    """
    Sampling details
     rate: The sampling rate in Hz of my soundcard
     buffersize: The size of the array to which we will save audio segments (2^12 = 4096 is very good)
     secToRecord: The length of each sampling
     buffersToRecord: how many multiples of buffers are we recording?
    """
    rate=44100
    secToRecord=.1
    self.buffersize=2**12
    self.buffersToRecord=int(rate*secToRecord/self.buffersize)
    if not self.buffersToRecord: 
      self.buffersToRecord=1

    """
    Filters in Hertz
     highHertz: lower limit of the bandpass filter, in Hertz
     lowHertz: upper limit of the bandpass filter, in Hertz
       max lowHertz = (buffersize / 2 - 1) * rate / buffersize
    """
    highHertz = 500
    lowHertz = 10000

    """
    Convert filters from Hertz to bins
     highpass: convert the highHertz into a bin for the FFT
     lowpass: convert the lowHertz into a bin for the FFt
     NOTES:
      highpass is at least the 1st bin since most mics only pick up >=20Hz
      lowpass is no higher than buffersize/2 - 1 (highest array index)
      passband needs to be wider than size of numInput - not checking for that
    """
    self.highpass = max(int(highHertz * self.buffersize / rate),1)
    self.lowpass = min(int(lowHertz * self.buffersize / rate), self.buffersize/2 - 1)

    """
    The call to create the temporal pooler region
    """
    self.tp = TP(numberOfCols=self.numCols, cellsPerColumn=4,
      initialPerm=0.5, connectedPerm=0.5,
      minThreshold=10, newSynapseCount=10,
      permanenceInc=0.1, permanenceDec=0.07,
      activationThreshold=8,
      globalDecay=0.02, burnIn=2,
      checkSynapseConsistency=False,
      pamLength=100)
  
    """
    Creating the audio stream from our mic
    """
    p = pyaudio.PyAudio()
    self.inStream = p.open(format=pyaudio.paInt32,channels=1,rate=rate,input=True,frames_per_buffer=self.buffersize)

    """
    Setting up the array that will handle the timeseries of audio data from our input
    """
    self.audio = numpy.empty((self.buffersToRecord*self.buffersize),dtype="uint32")

    """
    Print out the inputs
    """
    print "Number of columns:\t" + str(self.numCols)
    print "Max size of input:\t" + str(self.numInput)
    print "Sampling rate (Hz):\t" + str(rate)
    print "Passband filter (Hz):\t" + str(highHertz) + " - " + str(lowHertz)
    print "Passband filter (bin):\t" + str(self.highpass) + " - " + str(self.lowpass)
    print "Bin difference:\t\t" + str(self.lowpass - self.highpass)
    print "Buffersize:\t\t" + str(self.buffersize)

    """
    Setup the plot
     Use the bandpass filter frequency range as the x-axis
     Rescale the y-axis
    """
    plt.ion()
    bin = range(self.highpass,self.lowpass)
    xs = numpy.arange(len(bin))*rate/self.buffersize + highHertz
    self.freqPlot = plt.plot(xs,xs)[0]
    plt.ylim(0, 10**12)
    
    while True:
      self.processAudio()
  
  
  def processAudio (self): 
    """
    Sample audio, encode, send it to the TP
    
    Pulls the audio from the mic
    Conditions that audio as an SDR
    Computes a prediction via the TP
    Update the visualizations
    """
    
    """
    Cycle through the multiples of the buffers we're sampling
    Sample audio to store for each frame in buffersize
     Mic voltage-level timeseries is saved as 32-bit binary
    Convert that 32-bit binary into integers, and save to array for the FFT
    """
    for i in range(self.buffersToRecord):
      try:
        audioString = self.inStream.read(self.buffersize)
      except IOError:
        print "Overflow error from 'audiostring = inStream.read(buffersize)'. Try decreasing buffersize."
        quit()
      self.audio[i*self.buffersize:(i + 1)*self.buffersize] = numpy.fromstring(audioString,dtype = "uint32")
    
    """
    Get int array of strength for each bin of frequencies via fast fourier transform
    Get the indices of the strongest frequencies (the top 'numInput')
    Scale the indices so that the frequencies fit to within numCols
    Pick out the unique indices (we've reduced the mapping, so we likely have multiples)
    Encode those indices into an SDR via the SparsePassThroughEncoder
    Cast the SDR as a float for the TP
    """
    ys = self.fft(self.audio, self.highpass, self.lowpass)
    fs = numpy.sort(ys.argsort()[-self.numInput:])
    rfs = fs.astype(numpy.float32) / (self.lowpass - self.highpass) * self.numCols
    ufs = numpy.unique(rfs)
    actualInt = self.e.encode(ufs)
    actual = actualInt.astype(numpy.float32)
    
    """
    Pass the SDR to the TP
    Collect the prediction SDR from the TP
    Pass the prediction & actual SDRS to the anomaly calculator & array comparer
    Update the frequency plot
    """
    self.tp.compute(actual, enableLearn = True, computeInfOutput = True)
    predictedInt = self.tp.getPredictedState().max(axis=1)
    compare = self.vis.compareArray(actualInt, predictedInt)
    anomaly = self.vis.calcAnomaly(actualInt, predictedInt)
    print "." . join(compare)
    print self.vis.hashtagAnomaly(anomaly)
    self.freqPlot.set_ydata(ys)
    plt.show(block = False)
    plt.draw()
  
  
  def fft(self, audio, highpass, lowpass):
    """
    Fast fourier transform conditioning

    Output:
    'output' contains the strength of each frequency in the audio signal
    frequencies are marked by its position in 'output':
    frequency = index * rate / buffesize
    output.size = buffersize/2 
    Method:
    Use numpy's FFT (numpy.fft.fft)
    Find the magnitude of the complex numbers returned (abs value)
    Split the FFT array in half, because we have mirror frequencies
     (they're the complex conjugates)
    Use just the first half to apply the bandpass filter

    Great info here: http://stackoverflow.com/questions/4364823/how-to-get-frequency-from-fft-result
    """
    left,right = numpy.split(numpy.abs(numpy.fft.fft(audio)),2)
    output = left[highpass:lowpass]
    return output