/ Wave_Freq_Generator / generator.py
generator.py
  1  # SPDX-FileCopyrightText: 2018 Dave Astels for Adafruit Industries
  2  #
  3  # SPDX-License-Identifier: MIT
  4  
  5  """
  6  Outpout generator code for signal generator.
  7  
  8  Adafruit invests time and resources providing this open source code.
  9  Please support Adafruit and open source hardware by purchasing
 10  products from Adafruit!
 11  
 12  Written by Dave Astels for Adafruit Industries
 13  Copyright (c) 2018 Adafruit Industries
 14  Licensed under the MIT license.
 15  
 16  All text above must be included in any redistribution.
 17  """
 18  
 19  import math
 20  import array
 21  import board
 22  import audioio
 23  import audiocore
 24  import shapes
 25  
 26  
 27  def length(frequency):
 28      return int(32000 / frequency)
 29  
 30  
 31  
 32  class Generator:
 33  
 34      sample = None
 35      dac = None
 36      shape = None
 37      frequency = None
 38  
 39  
 40      def __init__(self):
 41          self.dac = audioio.AudioOut(board.A0)
 42  
 43  
 44      def reallocate(self, frequency):
 45          self.sample = array.array("h", [0] * length(frequency))
 46  
 47  
 48      def make_sine(self):
 49          l = len(self.sample)
 50          for i in range(l):
 51              self.sample[i] = min(2 ** 15 - 1, int(math.sin(math.pi * 2 * i / l) * (2 ** 15)))
 52  
 53  
 54      def make_square(self):
 55          l = len(self.sample)
 56          half_l = l // 2
 57          for i in range(l):
 58              if i < half_l:
 59                  self.sample[i] = -1 * ((2 ** 15) - 1)
 60              else:
 61                  self.sample[i] = (2 ** 15) - 1
 62  
 63  
 64      def make_triangle(self):
 65          l = len(self.sample)
 66          half_l = l // 2
 67          s = 0
 68          for i in range(l):
 69              if i <= half_l:
 70                  s = int((i / half_l) * (2 ** 16)) - (2 ** 15)
 71              else:
 72                  s = int((1 - ((i - half_l) / half_l)) * (2 ** 16)) - (2 ** 15)
 73              self.sample[i] = min(2 ** 15 -1, s)
 74  
 75  
 76  
 77      def make_sawtooth(self):
 78          l = len(self.sample)
 79          for i in range(l):
 80              self.sample[i] = int((i / l) * (2 ** 16)) - (2 ** 15)
 81  
 82  
 83      def update(self, shape, frequency):
 84          if shape == self.shape and frequency == self.frequency:
 85              return
 86  
 87          if frequency != self.frequency:
 88              self.reallocate(frequency)
 89              self.frequency = frequency
 90  
 91          self.shape = shape
 92          if shape == shapes.SINE:
 93              self.make_sine()
 94          elif shape == shapes.SQUARE:
 95              self.make_square()
 96          elif shape == shapes.TRIANGLE:
 97              self.make_triangle()
 98          elif shape == shapes.SAWTOOTH:
 99              self.make_sawtooth()
100  
101          self.dac.stop()
102          self.dac.play(audiocore.RawSample(self.sample, channel_count=1, sample_rate=64000), loop=True)