# Module `lib.plugins.ambientsound.uda1334`

Class to drive DAC module uda1334a I2S, stereo audio decoder module board

Expand source code

    """ Class to drive DAC module uda1334a I2S, stereo audio decoder module board """
    # pylint:disable=consider-using-f-string
    import struct
    import math
    import io
    import gc
    from machine import I2S, Pin

    class Uda1334:
            """ Class to drive DAC module uda1334a I2S, stereo audio decoder module board """
            def __init__(self, sck=26, ws=25, sd=22):
                    """ Constructor
                    BCLK (Bit Clock) : GPIO26
                    LRCLK (Left/Right Clock) : GPIO25
                    DATA : GPIO22
                    """
                    self.sck = sck
                    self.ws = ws
                    self.sd = sd
                    self.wave = None
                    self.i2s = None

            def play(self, wave, rate, duration=10):
                    """ Play sound wave """
                    self.wave = wave
                    self.i2s = I2S(0, sck=Pin(self.sck), ws=Pin(self.ws), sd=Pin(self.sd), mode=I2S.TX, bits=16, format=I2S.STEREO, rate=rate, ibuf=4096)

                    t = 1/(rate/(len(wave.getvalue())/4))
                    try:
                            buf = bytearray(self.wave.getvalue())
                            gc.disable()
                            for i in range(int(duration/t)):
                                    self.i2s.write(buf)
                    finally:
                            gc.enable()
                            self.i2s.deinit()

            def create_wave(self, frequency, shape):
                    """ Create sound wave with frequency and shape of wave """
                    if frequency > 100:
                            rate = 100000
                            step = rate//frequency
                    else:
                            step = 1000
                            rate = step*frequency
                    sample = io.BytesIO()
                    shape(sample,step)
                    return sample, rate

            def triangle(self, buf, step):
                    """ Creates a triangle wave """
                    inc = 65536//(step//2)
                    for i in range(-(32767-inc), 32767, inc):
                            buf.write(struct.pack("<h",i))
                            buf.write(struct.pack("<h",-i))
                    for i in range(32767-inc,-32767, -inc):
                            buf.write(struct.pack("<h",i))
                            buf.write(struct.pack("<h",-i))

            def sinus(self, buf, step):
                    """ Creates a sine wave """
                    inc = 100000//step
                    for angle in range(0, 100000, inc):
                            sample = math.cos(angle*(2*math.pi)/100000) * 32767
                            buf.write(struct.pack("<h",int(sample)))
                            buf.write(struct.pack("<h",-int(sample)))

            def bits_frame(self, byte, bits, parity, stop):
                    """ Returns the bits that compose a byte sent on a uart """
                    result = [0]
                    bits_count = 0

                    data = int(byte)
                    for i in range(bits):
                            if data & 1:
                                    bits_count += 1
                                    result.append(1)
                            else:
                                    result.append(0)
                            if data <= 1:
                                    break
                            data >>= 1

                    if parity is not None:
                            if parity == 1:
                                    if bits_count & 1:
                                            result.append(0)
                                    else:
                                            result.append(1)
                            else:
                                    if bits_count & 1:
                                            result.append(1)
                                    else:
                                            result.append(0)

                    if stop == 1:
                            result.append(1)
                    if stop == 2:
                            result.append(1)
                    return result

            def create_uart(self, data, baud, bits=7, parity=1, stop=1):
                    """ Create uart wave """
                    sample = io.BytesIO()
                    rate = 100000
                    for char in data:
                            bitfield = self.bits_frame(char, bits, parity, stop)

                            for bit in bitfield:
                                    if bit:
                                            for i in range(rate*2//baud):
                                                    sample.write(struct.pack("<h",32767))
                                    else:
                                            for i in range(rate*2//baud):
                                                    sample.write(struct.pack("<h",-32767))
                    return sample, rate

            def play_raw(self, filename):
                    """ Plays a file containing a sound wave in raw 44khz stereo format """
                    buf = bytearray(4096)
                    self.i2s = I2S(0, sck=Pin(self.sck), ws=Pin(self.ws), sd=Pin(self.sd), mode=I2S.TX, bits=16, format=I2S.STEREO, rate=44100, ibuf=4096)
                    with open(filename,'rb') as file:
                            try:
                                    gc.disable()
                                    i = 0
                                    while True:
                                            length = file.readinto(buf)
                                            if length == 0:
                                                    break
                                            if length < len(buf):
                                                    self.i2s.write(buf[:length])
                                                    break
                                            else:
                                                    self.i2s.write(buf)
                                            print(i)
                                            i += 1
                            finally:
                                    gc.enable()
                                    self.i2s.deinit()

    def test():
            """ Plays multiple frequencies and waveform """
            uda = Uda1334()
            for i in range(10,5000, 100):
                    print("Sinus    %d hz"%i)
                    wave,rate = uda.create_wave(frequency=i, shape=uda.sinus)
                    uda.play(wave,rate,3)
                    print("Triangle %d hz"%i)
                    wave,rate = uda.create_wave(frequency=i, shape=uda.triangle)
                    uda.play(wave,rate,3)

    def calibration():
            """ Plays a sine wave at 1khz """
            uda = Uda1334()
            wave, rate = uda.create_wave(frequency=1000, shape=uda.sinus)
            uda.play(wave, rate, 600)

    def test_uart():
            """ Plays a uart type wave at 9600 baud """
            uda = Uda1334()
            wave, rate = uda.create_uart(b"Hello world", 9600)
            uda.play(wave, rate, 600)

    def test_raw():
            """ Play raw file """
            uda = Uda1334()
            uda.play_raw("/sd/ambience.wav")

## Functions

`def calibration()`

  Plays a sine wave at 1khz

  Expand source code

      def calibration():
              """ Plays a sine wave at 1khz """
              uda = Uda1334()
              wave, rate = uda.create_wave(frequency=1000, shape=uda.sinus)
              uda.play(wave, rate, 600)

`def test()`

  Plays multiple frequencies and waveform

  Expand source code

      def test():
              """ Plays multiple frequencies and waveform """
              uda = Uda1334()
              for i in range(10,5000, 100):
                      print("Sinus    %d hz"%i)
                      wave,rate = uda.create_wave(frequency=i, shape=uda.sinus)
                      uda.play(wave,rate,3)
                      print("Triangle %d hz"%i)
                      wave,rate = uda.create_wave(frequency=i, shape=uda.triangle)
                      uda.play(wave,rate,3)

`def test_raw()`

  Play raw file

  Expand source code

      def test_raw():
              """ Play raw file """
              uda = Uda1334()
              uda.play_raw("/sd/ambience.wav")

`def test_uart()`

  Plays a uart type wave at 9600 baud

  Expand source code

      def test_uart():
              """ Plays a uart type wave at 9600 baud """
              uda = Uda1334()
              wave, rate = uda.create_uart(b"Hello world", 9600)
              uda.play(wave, rate, 600)

## Classes

`class Uda1334 (sck=26, ws=25, sd=22)`

  Class to drive DAC module uda1334a I2S, stereo audio decoder module board

  Constructor BCLK (Bit Clock) : GPIO26 LRCLK (Left/Right Clock) : GPIO25 DATA : GPIO22

  Expand source code

      class Uda1334:
              """ Class to drive DAC module uda1334a I2S, stereo audio decoder module board """
              def __init__(self, sck=26, ws=25, sd=22):
                      """ Constructor
                      BCLK (Bit Clock) : GPIO26
                      LRCLK (Left/Right Clock) : GPIO25
                      DATA : GPIO22
                      """
                      self.sck = sck
                      self.ws = ws
                      self.sd = sd
                      self.wave = None
                      self.i2s = None

              def play(self, wave, rate, duration=10):
                      """ Play sound wave """
                      self.wave = wave
                      self.i2s = I2S(0, sck=Pin(self.sck), ws=Pin(self.ws), sd=Pin(self.sd), mode=I2S.TX, bits=16, format=I2S.STEREO, rate=rate, ibuf=4096)

                      t = 1/(rate/(len(wave.getvalue())/4))
                      try:
                              buf = bytearray(self.wave.getvalue())
                              gc.disable()
                              for i in range(int(duration/t)):
                                      self.i2s.write(buf)
                      finally:
                              gc.enable()
                              self.i2s.deinit()

              def create_wave(self, frequency, shape):
                      """ Create sound wave with frequency and shape of wave """
                      if frequency > 100:
                              rate = 100000
                              step = rate//frequency
                      else:
                              step = 1000
                              rate = step*frequency
                      sample = io.BytesIO()
                      shape(sample,step)
                      return sample, rate

              def triangle(self, buf, step):
                      """ Creates a triangle wave """
                      inc = 65536//(step//2)
                      for i in range(-(32767-inc), 32767, inc):
                              buf.write(struct.pack("<h",i))
                              buf.write(struct.pack("<h",-i))
                      for i in range(32767-inc,-32767, -inc):
                              buf.write(struct.pack("<h",i))
                              buf.write(struct.pack("<h",-i))

              def sinus(self, buf, step):
                      """ Creates a sine wave """
                      inc = 100000//step
                      for angle in range(0, 100000, inc):
                              sample = math.cos(angle*(2*math.pi)/100000) * 32767
                              buf.write(struct.pack("<h",int(sample)))
                              buf.write(struct.pack("<h",-int(sample)))

              def bits_frame(self, byte, bits, parity, stop):
                      """ Returns the bits that compose a byte sent on a uart """
                      result = [0]
                      bits_count = 0

                      data = int(byte)
                      for i in range(bits):
                              if data & 1:
                                      bits_count += 1
                                      result.append(1)
                              else:
                                      result.append(0)
                              if data <= 1:
                                      break
                              data >>= 1

                      if parity is not None:
                              if parity == 1:
                                      if bits_count & 1:
                                              result.append(0)
                                      else:
                                              result.append(1)
                              else:
                                      if bits_count & 1:
                                              result.append(1)
                                      else:
                                              result.append(0)

                      if stop == 1:
                              result.append(1)
                      if stop == 2:
                              result.append(1)
                      return result

              def create_uart(self, data, baud, bits=7, parity=1, stop=1):
                      """ Create uart wave """
                      sample = io.BytesIO()
                      rate = 100000
                      for char in data:
                              bitfield = self.bits_frame(char, bits, parity, stop)

                              for bit in bitfield:
                                      if bit:
                                              for i in range(rate*2//baud):
                                                      sample.write(struct.pack("<h",32767))
                                      else:
                                              for i in range(rate*2//baud):
                                                      sample.write(struct.pack("<h",-32767))
                      return sample, rate

              def play_raw(self, filename):
                      """ Plays a file containing a sound wave in raw 44khz stereo format """
                      buf = bytearray(4096)
                      self.i2s = I2S(0, sck=Pin(self.sck), ws=Pin(self.ws), sd=Pin(self.sd), mode=I2S.TX, bits=16, format=I2S.STEREO, rate=44100, ibuf=4096)
                      with open(filename,'rb') as file:
                              try:
                                      gc.disable()
                                      i = 0
                                      while True:
                                              length = file.readinto(buf)
                                              if length == 0:
                                                      break
                                              if length < len(buf):
                                                      self.i2s.write(buf[:length])
                                                      break
                                              else:
                                                      self.i2s.write(buf)
                                              print(i)
                                              i += 1
                              finally:
                                      gc.enable()
                                      self.i2s.deinit()

  ### Methods

  `def bits_frame(self, byte, bits, parity, stop)`

    Returns the bits that compose a byte sent on a uart

    Expand source code

        def bits_frame(self, byte, bits, parity, stop):
                """ Returns the bits that compose a byte sent on a uart """
                result = [0]
                bits_count = 0

                data = int(byte)
                for i in range(bits):
                        if data & 1:
                                bits_count += 1
                                result.append(1)
                        else:
                                result.append(0)
                        if data <= 1:
                                break
                        data >>= 1

                if parity is not None:
                        if parity == 1:
                                if bits_count & 1:
                                        result.append(0)
                                else:
                                        result.append(1)
                        else:
                                if bits_count & 1:
                                        result.append(1)
                                else:
                                        result.append(0)

                if stop == 1:
                        result.append(1)
                if stop == 2:
                        result.append(1)
                return result

  `def create_uart(self, data, baud, bits=7, parity=1, stop=1)`

    Create uart wave

    Expand source code

        def create_uart(self, data, baud, bits=7, parity=1, stop=1):
                """ Create uart wave """
                sample = io.BytesIO()
                rate = 100000
                for char in data:
                        bitfield = self.bits_frame(char, bits, parity, stop)

                        for bit in bitfield:
                                if bit:
                                        for i in range(rate*2//baud):
                                                sample.write(struct.pack("<h",32767))
                                else:
                                        for i in range(rate*2//baud):
                                                sample.write(struct.pack("<h",-32767))
                return sample, rate

  `def create_wave(self, frequency, shape)`

    Create sound wave with frequency and shape of wave

    Expand source code

        def create_wave(self, frequency, shape):
                """ Create sound wave with frequency and shape of wave """
                if frequency > 100:
                        rate = 100000
                        step = rate//frequency
                else:
                        step = 1000
                        rate = step*frequency
                sample = io.BytesIO()
                shape(sample,step)
                return sample, rate

  `def play(self, wave, rate, duration=10)`

    Play sound wave

    Expand source code

        def play(self, wave, rate, duration=10):
                """ Play sound wave """
                self.wave = wave
                self.i2s = I2S(0, sck=Pin(self.sck), ws=Pin(self.ws), sd=Pin(self.sd), mode=I2S.TX, bits=16, format=I2S.STEREO, rate=rate, ibuf=4096)

                t = 1/(rate/(len(wave.getvalue())/4))
                try:
                        buf = bytearray(self.wave.getvalue())
                        gc.disable()
                        for i in range(int(duration/t)):
                                self.i2s.write(buf)
                finally:
                        gc.enable()
                        self.i2s.deinit()

  `def play_raw(self, filename)`

    Plays a file containing a sound wave in raw 44khz stereo format

    Expand source code

        def play_raw(self, filename):
                """ Plays a file containing a sound wave in raw 44khz stereo format """
                buf = bytearray(4096)
                self.i2s = I2S(0, sck=Pin(self.sck), ws=Pin(self.ws), sd=Pin(self.sd), mode=I2S.TX, bits=16, format=I2S.STEREO, rate=44100, ibuf=4096)
                with open(filename,'rb') as file:
                        try:
                                gc.disable()
                                i = 0
                                while True:
                                        length = file.readinto(buf)
                                        if length == 0:
                                                break
                                        if length < len(buf):
                                                self.i2s.write(buf[:length])
                                                break
                                        else:
                                                self.i2s.write(buf)
                                        print(i)
                                        i += 1
                        finally:
                                gc.enable()
                                self.i2s.deinit()

  `def sinus(self, buf, step)`

    Creates a sine wave

    Expand source code

        def sinus(self, buf, step):
                """ Creates a sine wave """
                inc = 100000//step
                for angle in range(0, 100000, inc):
                        sample = math.cos(angle*(2*math.pi)/100000) * 32767
                        buf.write(struct.pack("<h",int(sample)))
                        buf.write(struct.pack("<h",-int(sample)))

  `def triangle(self, buf, step)`

    Creates a triangle wave

    Expand source code

        def triangle(self, buf, step):
                """ Creates a triangle wave """
                inc = 65536//(step//2)
                for i in range(-(32767-inc), 32767, inc):
                        buf.write(struct.pack("<h",i))
                        buf.write(struct.pack("<h",-i))
                for i in range(32767-inc,-32767, -inc):
                        buf.write(struct.pack("<h",i))
                        buf.write(struct.pack("<h",-i))