0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

MAiX Qube 奮闘記03 Video再生への道

Last updated at Posted at 2022-03-31

名曲「Bad apple!」を再生するには

video.py
from machine import I2C
import nes, lcd, sys, time
from sound import CubeAudio # see ../modules/es8374 put sound.py and es8374.py
from fpioa_manager import fm
from Maix import FPIOA, GPIO

sound.py、es8374.py
MAiX Qubeで再生するに二つプログラムが必要みたい。

まずはes8374.py
https://wiki.sipeed.com/soft/maixpy/en/course/media/audio.html?highlight=es8374

es8374.py
# -*- coding: UTF-8 -*-

from machine import I2C

# I2C1_SDA      28 CDATA    -> IO_31
# I2C1_SCL      1 CCLK      -> IO_30

# I2S_MCLK      2 MCLK      -> IO_19
# I2S_SCLK      7 SCLK      -> IO_35
# I2S_DOUT      8 ASDOUT    -> IO_34
# I2S_LRCK(WS)  9 LECK      -> IO_33
# I2S_DIN       10 DSDIN    -> IO_18


# ------------------------------------

class ES8374_I2S_CLOCK:

    _LCLK_DIV_MIN = -1
    _LCLK_DIV_128 = 0
    _LCLK_DIV_192 = 1
    _LCLK_DIV_256 = 2
    _LCLK_DIV_384 = 3
    _LCLK_DIV_512 = 4
    _LCLK_DIV_576 = 5
    _LCLK_DIV_768 = 6
    _LCLK_DIV_1024 = 7
    _LCLK_DIV_1152 = 8
    _LCLK_DIV_1408 = 9
    _LCLK_DIV_1536 = 1
    _LCLK_DIV_2112 = 1
    _LCLK_DIV_2304 = 1

    _LCLK_DIV_125 = 16
    _LCLK_DIV_136 = 17
    _LCLK_DIV_250 = 18
    _LCLK_DIV_272 = 19
    _LCLK_DIV_375 = 20
    _LCLK_DIV_500 = 21
    _LCLK_DIV_544 = 22
    _LCLK_DIV_750 = 23
    _LCLK_DIV_1000 = 24
    _LCLK_DIV_1088 = 25
    _LCLK_DIV_1496 = 26
    _LCLK_DIV_1500 = 27

    _MCLK_DIV_MIN = -1
    _MCLK_DIV_1 = 1
    _MCLK_DIV_2 = 2
    _MCLK_DIV_3 = 3
    _MCLK_DIV_4 = 4
    _MCLK_DIV_6 = 5
    _MCLK_DIV_8 = 6
    _MCLK_DIV_9 = 7
    _MCLK_DIV_11 = 8
    _MCLK_DIV_12 = 9
    _MCLK_DIV_16 = 10
    _MCLK_DIV_18 = 11
    _MCLK_DIV_22 = 12
    _MCLK_DIV_24 = 13
    _MCLK_DIV_33 = 14
    _MCLK_DIV_36 = 15
    _MCLK_DIV_44 = 16
    _MCLK_DIV_48 = 17
    _MCLK_DIV_66 = 18
    _MCLK_DIV_72 = 19
    _MCLK_DIV_5 = 20
    _MCLK_DIV_10 = 21
    _MCLK_DIV_15 = 22
    _MCLK_DIV_17 = 23
    _MCLK_DIV_20 = 24
    _MCLK_DIV_25 = 25
    _MCLK_DIV_30 = 26
    _MCLK_DIV_32 = 27
    _MCLK_DIV_34 = 28
    _MCLK_DIV_7 = 29
    _MCLK_DIV_13 = 30
    _MCLK_DIV_14 = 31

    def __init__(self):
        self.lclk_div = self._LCLK_DIV_256
        self.sclk_div = self._MCLK_DIV_4


class ES8374_CONFIG:

    # es8374_adc_input_t
    _ES8374_ADC_INPUT_LINE1      = 0
    _ES8374_ADC_INPUT_LINE2      = 1
    _ES8374_ADC_INPUT_ALL        = 2
    _ES8374_ADC_INPUT_DIFFERENCE = 3

    # es8374_dac_output_t
    _ES8374_DAC_OUTPUT_LINE1 = 0
    _ES8374_DAC_OUTPUT_LINE2 = 1
    _ES8374_DAC_OUTPUT_ALL   = 2

    # es8374_mode_t
    _ES8374_MODE_ENCODE  = 1
    _ES8374_MODE_DECODE  = 2
    _ES8374_MODE_BOTH    = 3
    _ES8374_MODE_LINE_IN = 4

    def __init__(self):
        self.adc_input      = self._ES8374_ADC_INPUT_LINE1
        self.dac_output     = self._ES8374_DAC_OUTPUT_LINE1
        self.es8374_mode    = self._ES8374_MODE_BOTH
        self.i2s_iface      = self.I2S_IFACE()

    class I2S_IFACE:

        # es8374_iface_mode_t
        _ES8374_MODE_SLAVE  = 0
        _ES8374_MODE_MASTER = 1

        # es8374_iface_format_t
        _ES8374_I2S_NORMAL  = 0
        _ES8374_I2S_LEFT    = 1
        _ES8374_I2S_RIGHT   = 2
        _ES8374_I2S_DSP     = 3

        # es8374_iface_samples_t
        _ES8374_08K_SAMPLES = 0
        _ES8374_11K_SAMPLES = 1
        _ES8374_16K_SAMPLES = 2
        _ES8374_22K_SAMPLES = 3
        _ES8374_24K_SAMPLES = 4
        _ES8374_32K_SAMPLES = 5
        _ES8374_44K_SAMPLES = 6
        _ES8374_48K_SAMPLES = 7

        # es8374_iface_bits_t
        _ES8374_BIT_LENGTH_16BITS   = 1
        _ES8374_BIT_LENGTH_24BITS   = 2
        _ES8374_BIT_LENGTH_32BITS   = 3


        def __init__(self):

            self.mode       = self._ES8374_MODE_SLAVE
            self.fmt        = self._ES8374_I2S_NORMAL
            self.samples    = self._ES8374_44K_SAMPLES
            self.bits       = self._ES8374_BIT_LENGTH_16BITS

#######################

class ES_MODULE:
    _ES_MODULE_MIN      = -1
    _ES_MODULE_ADC      = 0x01
    _ES_MODULE_DAC      = 0x02
    _ES_MODULE_ADC_DAC  = 0x03
    _ES_MODULE_LINE     = 0x04

class ES_BITS_LENGTH:
    _BIT_LENGTH_MIN      = -1
    _BIT_LENGTH_16BITS   = 0x03
    _BIT_LENGTH_18BITS   = 0x02
    _BIT_LENGTH_20BITS   = 0x01
    _BIT_LENGTH_24BITS   = 0x00
    _BIT_LENGTH_32BITS   = 0x04

class MIC_GAIN:
    _MIC_GAIN_MIN   = -1
    _MIC_GAIN_0DB   = 0
    _MIC_GAIN_3DB   = 3
    _MIC_GAIN_6DB   = 6
    _MIC_GAIN_9DB   = 9
    _MIC_GAIN_12DB  = 12
    _MIC_GAIN_15DB  = 15
    _MIC_GAIN_18DB  = 18
    _MIC_GAIN_21DB  = 21
    _MIC_GAIN_24DB  = 24

class D2SE_PGA:
    _D2SE_PGA_GAIN_MIN = -1
    _D2SE_PGA_GAIN_DIS = 0
    _D2SE_PGA_GAIN_EN = 1
    _D2SE_PGA_GAIN_MAX = 2

class BIT_LENGTH:
    _BIT_LENGTH_MIN         = -1
    _BIT_LENGTH_16BITS      = 0x03
    _BIT_LENGTH_18BITS      = 0x02
    _BIT_LENGTH_20BITS      = 0x01
    _BIT_LENGTH_24BITS      = 0x00
    _BIT_LENGTH_32BITS      = 0x04

class AUDIO_BIT_IFACE_LENGTH:
    _AUDIO_BIT_LENGTH_16BITS   = 1
    _AUDIO_BIT_LENGTH_24BITS   = 2
    _AUDIO_BIT_LENGTH_32BITS   = 3

class ES_CTRL:
    _ES8374_CTRL_STOP = 0x00
    _ES8374_CTRL_START = 0x01

# -----------
class ES8374:

    _ES8374_I2CADDR_DEFAULT = 0x10

    def __init__(self, i2c_bus=None, i2c_addr=_ES8374_I2CADDR_DEFAULT):
        if i2c_bus == None:
            self.i2c_bus = I2C(I2C.I2C1, freq=100*1000) # , sda=31, scl=30
        else:
            self.i2c_bus = i2c_bus

        self.i2c_addr = i2c_addr

        # dev_list = self.i2c_bus.scan()
        # # print("i2c devs_list:" + str(dev_list))

        self.clkdiv_cfg = ES8374_I2S_CLOCK()
        self.es8374_cfg = ES8374_CONFIG()
        # # print("self.es8374_cfg.es8374_mode:" + str(self.es8374_cfg.es8374_mode))
        self.stop(self.es8374_cfg.es8374_mode)
        self.init_reg(self.es8374_cfg.i2s_iface.mode,
            ((ES_BITS_LENGTH._BIT_LENGTH_16BITS << 4) | self.es8374_cfg.i2s_iface.fmt),
            self.clkdiv_cfg,
            self.es8374_cfg.dac_output,
            self.es8374_cfg.adc_input)

        self.setMICGain(MIC_GAIN._MIC_GAIN_18DB)
        self.setD2sePga(D2SE_PGA._D2SE_PGA_GAIN_EN)
        self.configI2SFormat(self.es8374_cfg.es8374_mode, self.es8374_cfg.i2s_iface.fmt)
        self.codecConfigI2S(self.es8374_cfg.es8374_mode, self.es8374_cfg.i2s_iface.fmt, self.es8374_cfg.i2s_iface.bits)

        # ---------------------
        # Play init

        # self.codecCtrlSate(self.es8374_cfg.es8374_mode, ES_CTRL._ES8374_CTRL_START)
        # # self.setVoiceVolume(30)
        # self.setVoiceVolume(100)
        # self._writeReg(0x1E, 0xA4)

        # # print("ES8374 |reg value: " + str(self._readREGAll()))
        # ---------------------


    def __deinit__(self):
        self._writeReg(0x00, 0x7F) # IC Rest and STOP

    # read reg value
    def _readReg(self, regAddr):
        self.i2c_bus.writeto(self.i2c_addr, bytes([regAddr]))
        return (self.i2c_bus.readfrom(self.i2c_addr, 1))[0]

    # write value to reg
    def _writeReg(self, regAddr, data):
        return self.i2c_bus.writeto_mem(self.i2c_addr, regAddr, data, mem_size=8)


    # read all reg value
    def _readREGAll(self):
        regValue = bytearray([])
        for i in range(0x6f):
            regValue.append(self._readReg(i))
        return regValue

    def stop(self, mode):
        if (mode == ES_MODULE._ES_MODULE_LINE):
            reg = self._readReg(0x1a) # disable lout
            reg |= 0x08
            self._writeReg(0x1a, reg)
            reg &= 0x9f
            self._writeReg(0x1a, reg)
            self._writeReg(0x1D, 0x12)# mute speaker
            self._writeReg(0x1E, 0x20)# disable class d
            reg = self._readReg(0x1c) #  disable spkmixer
            reg &= 0xbf
            self._writeReg(0x1c, reg)
            self._writeReg(0x1F, 0x00)# spk set

        if ((mode == ES_MODULE._ES_MODULE_DAC) or (mode == ES_MODULE._ES_MODULE_ADC_DAC)):
            self.setVoiceMute(True)
            reg = self._readReg(0x1a) # #disable lout
            reg |= 0x08
            self._writeReg(0x1a, reg)
            reg &= 0xdf
            self._writeReg(0x1a, reg)
            self._writeReg(0x1D, 0x12)# mute speaker
            self._writeReg(0x1E, 0x20)# disable class d
            reg = self._readReg(0x15) #  #power up dac
            reg |= 0x20
            self._writeReg(0x15, reg)

        if (mode == ES_MODULE._ES_MODULE_ADC or mode == ES_MODULE._ES_MODULE_ADC_DAC):
            reg = self._readReg(0x10) # #power up adc and input
            reg |= 0xc0
            self._writeReg(0x10, reg)
            reg = self._readReg(0x21) # #power up adc and input
            reg |= 0xc0
            self._writeReg(0x21, reg)

    def start(self, mode):
        if (mode == ES_MODULE._ES_MODULE_LINE):
            reg = self._readReg(0x1a) # set monomixer
            reg |= 0x60
            reg |= 0x20
            reg &= 0xf7
            self._writeReg(0x1a, reg)
            reg = self._readReg(0x1c) #  set spk mixer
            reg |= 0x40
            self._writeReg(0x1c, reg)
            self._writeReg(0x1D, 0x02) #  spk set
            self._writeReg(0x1F, 0x00) #  spk set
            self._writeReg(0x1E, 0xA0) #  spk on
        if (mode == ES_MODULE._ES_MODULE_ADC
            or mode == ES_MODULE._ES_MODULE_ADC_DAC
            or mode == ES_MODULE._ES_MODULE_LINE):
            reg = self._readReg(0x21) # power up adc and input
            reg &= 0x3f
            self._writeReg(0x21, reg)
            reg = self._readReg(0x10) # power up adc and input
            reg &= 0x3f
            self._writeReg(0x10, reg)

        if (mode == ES_MODULE._ES_MODULE_DAC
            or mode == ES_MODULE._ES_MODULE_ADC_DAC
            or mode == ES_MODULE._ES_MODULE_LINE):
            reg = self._readReg(0x1a) # disable lout
            reg |= 0x08
            self._writeReg(0x1a, reg)
            reg &= 0xdf
            self._writeReg(0x1a, reg)
            self._writeReg(0x1D, 0x12) #  mute speaker
            self._writeReg(0x1E, 0x20) #  disable class d
            reg = self._readReg(0x15)  # power up dac
            reg &= 0xdf
            self._writeReg(0x15, reg)
            reg = self._readReg(0x1a) # disable lout
            reg |= 0x20
            self._writeReg(0x1a, reg)
            reg &= 0xf7
            self._writeReg(0x1a, reg)
            self._writeReg(0x1D, 0x02) #  mute speaker
            self._writeReg(0x1E, 0xa0) #  disable class d

            self.setVoiceMute(False)

        # print("mode is :%d \r\n" % mode)

    def init_reg(self, ms_mode, fmt, cfg, out_channel, in_channel):

        self._writeReg(0x00, 0x3F)# IC Rst start
        self._writeReg(0x00, 0x03)# IC Rst stop
        self._writeReg(0x01, 0x7F)# IC clk on # M ORG 7F

        reg = self._readReg(0x0F)
        reg &= 0x7f
        reg |= (ms_mode << 7)
        self._writeReg(0x0f, reg)# CODEC IN I2S SLAVE MODE

        self._writeReg(0x6F, 0xA0)# pll set:mode enable
        self._writeReg(0x72, 0x41)# pll set:mode set
        #  self._writeReg(0x09,0x01)# pll set:reset on ,set start
        #  self._writeReg(0x0C,0x22)# pll set:k
        #  self._writeReg(0x0D,0x2E)# pll set:k
        #  self._writeReg(0x0E,0xC6)# pll set:k
        #  self._writeReg(0x0A,0x3A)# pll set:
        #  self._writeReg(0x0B,0x07)# pll set:n
        #  self._writeReg(0x09,0x41)# pll set:reset off ,set stop
        self._writeReg(0x09, 0x01)# pll set:reset on ,set start
        self._writeReg(0x0C, 0x08)# pll set:k
        self._writeReg(0x0D, 0x13)# pll set:k
        self._writeReg(0x0E, 0xE0)# pll set:k
        self._writeReg(0x0A, 0x8A)# pll set:
        self._writeReg(0x0B, 0x08)# pll set:n
        self._writeReg(0x09, 0x41)# pll set:reset off ,set stop

        self.i2sConfigClock(cfg)

        self._writeReg(0x24, 0x08)# adc set
        self._writeReg(0x36, 0x00)# dac set
        self._writeReg(0x12, 0x30)# timming set
        self._writeReg(0x13, 0x20)# timming set

        self.configI2SFormat(ES_MODULE._ES_MODULE_ADC, fmt)
        self.configI2SFormat(ES_MODULE._ES_MODULE_DAC, fmt)

        self._writeReg(0x21, 0x50)# adc set: SEL LIN1 CH+PGAGAIN=0DB
        self._writeReg(0x22, 0xFF)# adc set: PGA GAIN=0DB
        self._writeReg(0x21, 0x14)# adc set: SEL LIN1 CH+PGAGAIN=18DB
        self._writeReg(0x22, 0x55)# pga = +15db
        self._writeReg(0x08, 0x21)# set class d divider = 33, to avoid the high frequency tone on laudspeaker
        self._writeReg(0x00, 0x80)#  IC START

        self.setADCDACVolume(ES_MODULE._ES_MODULE_ADC, 0, 0) # 0dB
        self.setADCDACVolume(ES_MODULE._ES_MODULE_DAC, 0, 0) # 0dB

        self._writeReg(0x14, 0x8A)#  IC START
        self._writeReg(0x15, 0x40)#  IC START
        self._writeReg(0x1A, 0xA0)#  monoout set
        self._writeReg(0x1B, 0x19)#  monoout set
        self._writeReg(0x1C, 0x90)#  spk set
        self._writeReg(0x1D, 0x01)#  spk set
        self._writeReg(0x1F, 0x00)#  spk set
        self._writeReg(0x1E, 0x20)#  spk on
        self._writeReg(0x28, 0x70)#  alc set 0x70
        self._writeReg(0x26, 0x4E)#  alc set
        self._writeReg(0x27, 0x10)#  alc set
        self._writeReg(0x29, 0x00)#  alc set
        self._writeReg(0x2B, 0x00)#  alc set

        self._writeReg(0x25, 0x00)#  ADCVOLUME on
        self._writeReg(0x38, 0x00)#  DACVOLUME on
        self._writeReg(0x37, 0x30)#  dac set
        self._writeReg(0x6D, 0x60)# SEL:GPIO1=DMIC CLK OUT+SEL:GPIO2=PLL CLK OUT
        self._writeReg(0x71, 0x05)# for automute setting
        self._writeReg(0x73, 0x70)

        self.configDACOutput(out_channel)# 0x3c Enable DAC and Enable Lout/Rout/1/2
        self.configADCInput(in_channel)# 0x00 LINSEL & RINSEL, LIN1/RIN1 as ADC Input DSSEL,use one DS Reg11 DSR, LINPUT1-RINPUT1
        self.setVoiceVolume(0)
        self._writeReg(0x37, 0x00)#  dac set



    def i2sConfigClock(self, cfg):
        reg = self._readReg(0x0F) # power up adc and input
        reg &= 0xe0
        divratio = 0
        sclk_div_dir = {
            ES8374_I2S_CLOCK._MCLK_DIV_1  : 1, #
            ES8374_I2S_CLOCK._MCLK_DIV_2  : 2, # 2
            ES8374_I2S_CLOCK._MCLK_DIV_3  : 3, # 3
            ES8374_I2S_CLOCK._MCLK_DIV_4  : 4, # 4
            ES8374_I2S_CLOCK._MCLK_DIV_6  : 5, # 20
            ES8374_I2S_CLOCK._MCLK_DIV_8  : 6, # 5
            ES8374_I2S_CLOCK._MCLK_DIV_9  : 7, # 29
            ES8374_I2S_CLOCK._MCLK_DIV_11 : 8, # 6
            ES8374_I2S_CLOCK._MCLK_DIV_12 : 9, # 7
            ES8374_I2S_CLOCK._MCLK_DIV_16 : 10, # 21
            ES8374_I2S_CLOCK._MCLK_DIV_18 : 11, # 8
            ES8374_I2S_CLOCK._MCLK_DIV_22 : 12, # 9
            ES8374_I2S_CLOCK._MCLK_DIV_24 : 13, # 30
            ES8374_I2S_CLOCK._MCLK_DIV_33 : 14, # 31
            ES8374_I2S_CLOCK._MCLK_DIV_36 : 15, # 22
            ES8374_I2S_CLOCK._MCLK_DIV_44 : 16, # 10
            ES8374_I2S_CLOCK._MCLK_DIV_48 : 17, # 23
            ES8374_I2S_CLOCK._MCLK_DIV_66 : 18, # 11
            ES8374_I2S_CLOCK._MCLK_DIV_72 : 19, # 24
            ES8374_I2S_CLOCK._MCLK_DIV_5  : 20, # 12
            ES8374_I2S_CLOCK._MCLK_DIV_10 : 21, # 13
            ES8374_I2S_CLOCK._MCLK_DIV_15 : 22, # 25
            ES8374_I2S_CLOCK._MCLK_DIV_17 : 23, # 26
            ES8374_I2S_CLOCK._MCLK_DIV_20 : 24, # 27
            ES8374_I2S_CLOCK._MCLK_DIV_25 : 25, # 14
            ES8374_I2S_CLOCK._MCLK_DIV_30 : 26, # 28
            ES8374_I2S_CLOCK._MCLK_DIV_32 : 27, # 15
            ES8374_I2S_CLOCK._MCLK_DIV_34 : 28, # 16
            ES8374_I2S_CLOCK._MCLK_DIV_7  : 29, # 17
            ES8374_I2S_CLOCK._MCLK_DIV_13 : 30, # 18
            ES8374_I2S_CLOCK._MCLK_DIV_14 : 31, # 19
        }
        divratio = sclk_div_dir.get(cfg.sclk_div, None)

        reg |= divratio
        self._writeReg(0x0f, reg)

        lclk_div_dacratio_l_dir = {
            ES8374_I2S_CLOCK._LCLK_DIV_128   : (128  &0xFF),
            ES8374_I2S_CLOCK._LCLK_DIV_192   : (192  &0xFF),
            ES8374_I2S_CLOCK._LCLK_DIV_256   : (256  &0xFF),
            ES8374_I2S_CLOCK._LCLK_DIV_384   : (384  &0xFF),
            ES8374_I2S_CLOCK._LCLK_DIV_512   : (512  &0xFF),
            ES8374_I2S_CLOCK._LCLK_DIV_576   : (576  &0xFF),
            ES8374_I2S_CLOCK._LCLK_DIV_768   : (768  &0xFF),
            ES8374_I2S_CLOCK._LCLK_DIV_1024  : (1024 &0xFF),
            ES8374_I2S_CLOCK._LCLK_DIV_1152  : (1152 &0xFF),
            ES8374_I2S_CLOCK._LCLK_DIV_1408  : (1408 &0xFF),
            ES8374_I2S_CLOCK._LCLK_DIV_1536  : (1536 &0xFF),
            ES8374_I2S_CLOCK._LCLK_DIV_2112  : (2112 &0xFF),
            ES8374_I2S_CLOCK._LCLK_DIV_2304  : (2304 &0xFF),
            ES8374_I2S_CLOCK._LCLK_DIV_125   : (125  &0xFF),
            ES8374_I2S_CLOCK._LCLK_DIV_136   : (136  &0xFF),
            ES8374_I2S_CLOCK._LCLK_DIV_250   : (250  &0xFF),
            ES8374_I2S_CLOCK._LCLK_DIV_272   : (272  &0xFF),
            ES8374_I2S_CLOCK._LCLK_DIV_375   : (375  &0xFF),
            ES8374_I2S_CLOCK._LCLK_DIV_500   : (500  &0xFF),
            ES8374_I2S_CLOCK._LCLK_DIV_544   : (544  &0xFF),
            ES8374_I2S_CLOCK._LCLK_DIV_750   : (750  &0xFF),
            ES8374_I2S_CLOCK._LCLK_DIV_1000  : (1000 &0xFF),
            ES8374_I2S_CLOCK._LCLK_DIV_1088  : (1088 &0xFF),
            ES8374_I2S_CLOCK._LCLK_DIV_1496  : (1496 &0xFF),
            ES8374_I2S_CLOCK._LCLK_DIV_1500  : (1500 &0xFF),
        }
        lclk_div_dacratio_h_dir = {
            ES8374_I2S_CLOCK._LCLK_DIV_128   : (128  >>8),
            ES8374_I2S_CLOCK._LCLK_DIV_192   : (192  >>8),
            ES8374_I2S_CLOCK._LCLK_DIV_256   : (256  >>8),
            ES8374_I2S_CLOCK._LCLK_DIV_384   : (384  >>8),
            ES8374_I2S_CLOCK._LCLK_DIV_512   : (512  >>8),
            ES8374_I2S_CLOCK._LCLK_DIV_576   : (576  >>8),
            ES8374_I2S_CLOCK._LCLK_DIV_768   : (768  >>8),
            ES8374_I2S_CLOCK._LCLK_DIV_1024  : (1024 >>8),
            ES8374_I2S_CLOCK._LCLK_DIV_1152  : (1152 >>8),
            ES8374_I2S_CLOCK._LCLK_DIV_1408  : (1408 >>8),
            ES8374_I2S_CLOCK._LCLK_DIV_1536  : (1536 >>8),
            ES8374_I2S_CLOCK._LCLK_DIV_2112  : (2112 >>8),
            ES8374_I2S_CLOCK._LCLK_DIV_2304  : (2304 >>8),
            ES8374_I2S_CLOCK._LCLK_DIV_125   : (125  >>8),
            ES8374_I2S_CLOCK._LCLK_DIV_136   : (136  >>8),
            ES8374_I2S_CLOCK._LCLK_DIV_250   : (250  >>8),
            ES8374_I2S_CLOCK._LCLK_DIV_272   : (272  >>8),
            ES8374_I2S_CLOCK._LCLK_DIV_375   : (375  >>8),
            ES8374_I2S_CLOCK._LCLK_DIV_500   : (500  >>8),
            ES8374_I2S_CLOCK._LCLK_DIV_544   : (544  >>8),
            ES8374_I2S_CLOCK._LCLK_DIV_750   : (750  >>8),
            ES8374_I2S_CLOCK._LCLK_DIV_1000  : (1000 >>8),
            ES8374_I2S_CLOCK._LCLK_DIV_1088  : (1088 >>8),
            ES8374_I2S_CLOCK._LCLK_DIV_1496  : (1496 >>8),
            ES8374_I2S_CLOCK._LCLK_DIV_1500  : (1500 >>8),
        }
        dacratio_l = lclk_div_dacratio_l_dir.get(cfg.lclk_div, None)
        dacratio_h = lclk_div_dacratio_h_dir.get(cfg.lclk_div, None)

        self._writeReg(0x06, dacratio_h)# ADCFsMode,singel SPEED,RATIO=256
        self._writeReg(0x07, dacratio_l)# ADCFsMode,singel SPEED,RATIO=256

    def configI2SFormat(self, mode, fmt):
        fmt_tmp = ((fmt & 0xf0) >> 4)
        fmt_i2s =  fmt & 0x0f
        if (mode == ES_MODULE._ES_MODULE_ADC or mode == ES_MODULE._ES_MODULE_ADC_DAC):
            reg = self._readReg(0x10)
            reg &= 0xfc
            self._writeReg(0x10, (reg|fmt_i2s))
            self.setBitsPerSample(mode, fmt_tmp)

        if (mode == ES_MODULE._ES_MODULE_DAC or mode == ES_MODULE._ES_MODULE_ADC_DAC):
            reg = self._readReg(0x11)
            reg &= 0xfc
            self._writeReg(0x11, (reg|fmt_i2s))
            self.setBitsPerSample(mode, fmt_tmp)

    # set Bits Per Sample
    def setBitsPerSample(self, mode, bit_per_smaple):
        bits = bit_per_smaple & 0x0f

        if (mode == ES_MODULE._ES_MODULE_ADC or mode == ES_MODULE._ES_MODULE_ADC_DAC):
            reg = self._readReg(0x10)
            reg &= 0xe3
            self._writeReg(0x10, (reg| (bits << 2)))

        if (mode == ES_MODULE._ES_MODULE_DAC or mode == ES_MODULE._ES_MODULE_ADC_DAC):
            reg = self._readReg(0x11)
            reg &= 0xe3
            self._writeReg(0x11, (reg| (bits << 2)))

    # set ADC DAC Volume
    def setADCDACVolume(self, mode, volume, dot):
        if ((volume < -96) or (volume>0)):
            # print("Warning: volume < -96! or > 0!")
            if (volume < -96):
                volume = -96
            else:
                volume = 0

        dot = 1 if (dot >= 5) else 0
        volume = (-volume << 1) + dot
        if (mode == ES_MODULE._ES_MODULE_ADC or mode == ES_MODULE._ES_MODULE_ADC_DAC):
            self._writeReg(0x25, volume)
        if (mode == ES_MODULE._ES_MODULE_DAC or mode == ES_MODULE._ES_MODULE_ADC_DAC):
            self._writeReg(0x38, volume)

    def configDACOutput(self, output):
        reg = 0x1d
        self._writeReg(reg, 0x02)
        reg = self._readReg(0x1c) # set spk mixer
        reg |= 0x80
        self._writeReg(0x1c, reg)
        self._writeReg(0x1D, 0x02) # spk set
        self._writeReg(0x1F, 0x00) # spk set
        self._writeReg(0x1E, 0xA0) # spk on

    # NOTE: input not used
    def configADCInput(self, input):
        reg = 0x1d
        reg = self._readReg(0x21)
        reg = (reg & 0xcf) | 0x14
        self._writeReg( 0x21, reg)
        self._writeReg( 0x21, 0x24)

    # set Voice Volume
    def setVoiceVolume(self, volume):
        if volume < 0 :
            volume = 192
        elif volume > 96 :
            volume = 0
        else:
            volume = 192 - volume*2
        return self._writeReg(0x38, volume)

    # get Voice Volume
    def getVoiceVolume(self):
        volume = self._readReg(0x38)
        volume = (192-volume)/2
        if volume > 96:
            volume = 100
        return volume

    # codec Config I2S
    def codecConfigI2S(self, mode, interface_fmt, interface_bits):
        self.configI2SFormat(ES_MODULE._ES_MODULE_ADC, interface_fmt)
        if (interface_bits == AUDIO_BIT_IFACE_LENGTH._AUDIO_BIT_LENGTH_16BITS):
            tmp = BIT_LENGTH._BIT_LENGTH_16BITS
        elif (interface_bits == AUDIO_BIT_IFACE_LENGTH._AUDIO__BIT_LENGTH_24BITS):
            tmp = BIT_LENGTH._BIT_LENGTH_24BITS
        else:
            tmp = BIT_LENGTH._BIT_LENGTH_32BITS

        self.setBitsPerSample(ES_MODULE._ES_MODULE_ADC_DAC, tmp)

    def setVoiceMute(self, enable):
        reg = self._readReg(0x36)
        reg &= 0xdf
        reg = ( reg | (enable << 5))
        # print("SetVoiceMute[%s]:" % str(reg) )
        self._writeReg(0x36, reg)

    # get voice mute
    def getVoiceMute(self):
        value = self._readReg(0x36)
        return True if (value & 0x40) else False

    # set mic gain
    def setMICGain(self, gain):
        if ((gain>MIC_GAIN._MIC_GAIN_MIN) and (gain<MIC_GAIN._MIC_GAIN_24DB)):
            gain_n = 0
            gain_n = int(gain/3)
            reg = (gain_n | (gain_n<<4))
            # print("22H:0x%X" % reg)
            self._writeReg(0x22, reg) # MIC PGA
        else:
            pass
            # print("invalid micropython gain")

    def setD2sePga(self, gain):
        if ((gain>D2SE_PGA._D2SE_PGA_GAIN_MIN) and (gain<D2SE_PGA._D2SE_PGA_GAIN_MAX)):
            reg = self._readReg(0x21)
            reg &= 0xfb
            reg |= gain << 2
            self._writeReg(0x21, reg) # MIC PGA
        else:
            pass
            # print("invalid microphone gain!")

    def codecCtrlSate(self, mode, ctrl_state):
        mode_list = {
            ES8374_CONFIG._ES8374_MODE_ENCODE: ES_MODULE._ES_MODULE_ADC,
            ES8374_CONFIG._ES8374_MODE_LINE_IN: ES_MODULE._ES_MODULE_LINE,
            ES8374_CONFIG._ES8374_MODE_DECODE: ES_MODULE._ES_MODULE_DAC,
            ES8374_CONFIG._ES8374_MODE_BOTH: ES_MODULE._ES_MODULE_ADC_DAC,
        }
        es_mode = mode_list.get(mode, None)
        if (es_mode == None):
            es_mode = ES_MODULE._ES_MODULE_DAC
            # print("Codec mode not support, default is decode mode\r\n")

        if (ES_CTRL._ES8374_CTRL_STOP == ctrl_state):
            res = self.stop(es_mode)
        else:
            res = self.start(es_mode)
            # print("start default is decode mode:%d\r\n" % es_mode)



'''-----------------------------
1.测试 I2S 是否能够输出型号
2.测试 ES8374 是否初始化成功
3.测试 ES8374 是否配置正常
1.I2Sがモデルを出力できるかどうかをテストします
2.ES8374が正常に初期化されているかどうかをテストします
3.ES8374が適切に構成されているかどうかをテストします
-----------------------------'''

if __name__ == "__main__":


    from fpioa_manager import *
    from Maix import GPIO, I2S, FFT

    import audio, time, image, lcd

    # cube
    #fm.register(19,fm.fpioa.I2S0_MCLK, force=True)
    #fm.register(35,fm.fpioa.I2S0_SCLK, force=True)
    #fm.register(33,fm.fpioa.I2S0_WS, force=True)
    #fm.register(34,fm.fpioa.I2S0_IN_D0, force=True)
    #fm.register(18,fm.fpioa.I2S0_OUT_D2, force=True)

    # amigo
    #fm.register(13,fm.fpioa.I2S0_MCLK, force=True)
    #fm.register(21,fm.fpioa.I2S0_SCLK, force=True)
    #fm.register(18,fm.fpioa.I2S0_WS, force=True)
    #fm.register(35,fm.fpioa.I2S0_IN_D0, force=True)
    #fm.register(34,fm.fpioa.I2S0_OUT_D2, force=True)

    #i2c = I2C(I2C.I2C1, freq=100*1000) # , sda=31, scl=30
    #i2c = I2C(I2C.I2C3, freq=600*1000, sda=27, scl=24) # amigo
    i2c = I2C(I2C.I2C3, freq=600*1000, sda=31, scl=30, gscl=fm.fpioa.GPIOHS17, gsda=fm.fpioa.GPIOHS18) # cube

    #fm.register(30,fm.fpioa.I2C1_SCLK, force=True)
    #fm.register(31,fm.fpioa.I2C1_SDA, force=True)

    #fm.register(24,fm.fpioa.I2C1_SCLK, force=True)
    #fm.register(27,fm.fpioa.I2C1_SDA, force=True)

    while True:

        try:
            print(i2c.scan())

            time.sleep_ms(2000)

            dev = ES8374(i2c)

            dev.setVoiceVolume(100)

            dev.start(ES_MODULE._ES_MODULE_ADC_DAC)

            # init i2s(i2s0)
            i2s = I2S(I2S.DEVICE_0, pll2=262144000, mclk=31)

            # config i2s according to audio info # STANDARD_MODE LEFT_JUSTIFYING_MODE RIGHT_JUSTIFYING_MODE
            i2s.channel_config(I2S.CHANNEL_0, I2S.RECEIVER, resolution=I2S.RESOLUTION_16_BIT, cycles=I2S.SCLK_CYCLES_32, align_mode=I2S.STANDARD_MODE)

            # amigo
            #fm.register(13,fm.fpioa.I2S0_MCLK, force=True)
            #fm.register(21,fm.fpioa.I2S0_SCLK, force=True)
            #fm.register(18,fm.fpioa.I2S0_WS, force=True)
            #fm.register(35,fm.fpioa.I2S0_IN_D0, force=True)
            #fm.register(34,fm.fpioa.I2S0_OUT_D2, force=True)

            # cube
            fm.register(19,fm.fpioa.I2S0_MCLK, force=True)
            fm.register(35,fm.fpioa.I2S0_SCLK, force=True)
            fm.register(33,fm.fpioa.I2S0_WS, force=True)
            fm.register(34,fm.fpioa.I2S0_IN_D0, force=True)
            fm.register(18,fm.fpioa.I2S0_OUT_D2, force=True)

            i2s.set_sample_rate(22050)

            player = audio.Audio(path="/sd/record_4.wav", is_create=True, samplerate=22050)
            queue = []
            for i in range(200):
             tmp = i2s.record(1024)
             if len(queue) > 0:
                 print(time.ticks())
                 ret = player.record(queue[0])
                 queue.pop(0)
             i2s.wait_record()
             queue.append(tmp)
            player.finish()

            del i2s, player

            time.sleep_ms(2000)

            dev = ES8374(i2c)

            dev.setVoiceVolume(90)

            dev.start(ES_MODULE._ES_MODULE_ADC_DAC)

            # init i2s(i2s0)
            i2s = I2S(I2S.DEVICE_0, pll2=262144000, mclk=31)

            # config i2s according to audio info # STANDARD_MODE LEFT_JUSTIFYING_MODE RIGHT_JUSTIFYING_MODE
            i2s.channel_config(I2S.CHANNEL_2, I2S.TRANSMITTER, resolution=I2S.RESOLUTION_16_BIT, cycles=I2S.SCLK_CYCLES_32, align_mode=I2S.STANDARD_MODE)

            # amigo
            #fm.register(13,fm.fpioa.I2S0_MCLK, force=True)
            #fm.register(21,fm.fpioa.I2S0_SCLK, force=True)
            #fm.register(18,fm.fpioa.I2S0_WS, force=True)
            #fm.register(35,fm.fpioa.I2S0_IN_D0, force=True)
            #fm.register(34,fm.fpioa.I2S0_OUT_D2, force=True)

            # cube
            fm.register(19,fm.fpioa.I2S0_MCLK, force=True)
            fm.register(35,fm.fpioa.I2S0_SCLK, force=True)
            fm.register(33,fm.fpioa.I2S0_WS, force=True)
            fm.register(34,fm.fpioa.I2S0_IN_D0, force=True)
            fm.register(18,fm.fpioa.I2S0_OUT_D2, force=True)

            for i in range(3):

                time.sleep_ms(10)

                # init audio
                #player = audio.Audio(path="/sd/res/sound/loop.wav")
                player = audio.Audio(path="/sd/record_4.wav")
                player.volume(100)

                # read audio info
                wav_info = player.play_process(i2s)
                # print("wav file head information: ", wav_info)
                i2s.set_sample_rate(wav_info[1])
                # print('loop to play audio')
                while True:
                    ret = player.play()
                    if ret == None:
                        # print("format error")
                        break
                    elif ret == 0:
                        break
                player.finish()

            del i2s, player

            #img = image.Image(size=(240, 240))
            #hist_width = 1 #changeable
            #x_shift = 0
            #for i in range(100):
                #temp = i2s.record(1024)
                #time.sleep_ms(10)
                #fft_res = FFT.run(temp.to_bytes(), 512)
                #fft_amp = FFT.amplitude(fft_res)
                ##print(len(fft_amp))
                ##print(fft_amp)
                #img = img.clear()
                #x_shift = 0
                #for i in range(512):
                    #hist_height = fft_amp[i]
                    #img = img.draw_rectangle((x_shift, 0, 1, hist_height), [255,255,255], 1, True)
                    ##print((x_shift, 0, 1, hist_height))
                    #x_shift = x_shift + 1
                #lcd.display(img)
                #fft_amp.clear()

            #del img, i2s
            #time.sleep_ms(2000)

        finally:
            pass

そしてもう一つの
sound.py

sound.py
from es8374 import ES8374
from Maix import I2S
from fpioa_manager import *
import audio
import time
# from machine import Timer

class CubeAudio:

    i2c, i2s, dev = None, None, None

    # tim = Timer(Timer.TIMER0, Timer.CHANNEL0, start=False, mode=Timer.MODE_PERIODIC, period=15, callback=lambda:None)

    def init(i2c_dev=None):
        CubeAudio.i2c = i2c_dev

    def check():
      if CubeAudio.i2c != None:
        return ES8374._ES8374_I2CADDR_DEFAULT in CubeAudio.i2c.scan()
      return False

    player, is_load, is_ready = None, False, False

    def ready(is_record=False, volume=100):
      CubeAudio.is_ready = CubeAudio.is_load = False
      if CubeAudio.check():
        if CubeAudio.dev != None:
            CubeAudio.dev.stop(0x02)
        CubeAudio.dev = ES8374(CubeAudio.i2c)
        CubeAudio.dev.setVoiceVolume(volume)
        CubeAudio.dev.start(0x03)
        CubeAudio.i2s = I2S(I2S.DEVICE_0, pll2=262144000, mclk=31)#31
        if is_record:
            CubeAudio.i2s.channel_config(I2S.CHANNEL_0, I2S.RECEIVER, resolution=I2S.RESOLUTION_16_BIT,
                                         cycles=I2S.SCLK_CYCLES_32, align_mode=I2S.STANDARD_MODE)
        else:
            CubeAudio.i2s.channel_config(I2S.CHANNEL_2, I2S.TRANSMITTER, resolution=I2S.RESOLUTION_16_BIT,
                                         cycles=I2S.SCLK_CYCLES_32, align_mode=I2S.STANDARD_MODE)
        CubeAudio.is_ready = True
      return CubeAudio.is_ready

    def load(path, volume=100):
        if CubeAudio.player != None:
            CubeAudio.player.finish()
            # CubeAudio.tim.stop()
        CubeAudio.player = audio.Audio(path=path)
        CubeAudio.player.volume(volume)
        wav_info = CubeAudio.player.play_process(CubeAudio.i2s)
        CubeAudio.i2s.set_sample_rate(int(wav_info[1]))

        CubeAudio.is_load = True
        # CubeAudio.tim.callback(CubeAudio.event)
        # CubeAudio.tim.start()
        #time.sleep_ms(1000)

    def event(arg=None):
        if CubeAudio.is_load:
            ret = CubeAudio.player.play()
            if ret == None or ret == 0:
                CubeAudio.player.finish()
                time.sleep_ms(50)
                # CubeAudio.tim.stop()
                CubeAudio.is_load = False
            return True
        return False


if __name__ == "__main__":
    from machine import I2C

    #fm.register(24, fm.fpioa.I2C1_SCLK, force=True)
    #fm.register(27, fm.fpioa.I2C1_SDA, force=True)
    fm.register(30,fm.fpioa.I2C1_SCLK, force=True)
    fm.register(31,fm.fpioa.I2C1_SDA, force=True)
    #i2c = I2C(I2C.I2C3, freq=600*1000, sda=27, scl=24)  # amigo
    i2c = I2C(I2C.I2C3, freq=600*1000, sda=31, scl=30)  # amigo
    CubeAudio.init(i2c)
    tmp = CubeAudio.check()
    print(tmp)
    if (tmp):
        # cube
        fm.register(19,fm.fpioa.I2S0_MCLK, force=True)
        fm.register(35,fm.fpioa.I2S0_SCLK, force=True)
        fm.register(33,fm.fpioa.I2S0_WS, force=True)
        fm.register(34,fm.fpioa.I2S0_IN_D0, force=True)
        fm.register(18,fm.fpioa.I2S0_OUT_D2, force=True)

        # amigo
        #fm.register(13, fm.fpioa.I2S0_MCLK, force=True)
        #fm.register(21, fm.fpioa.I2S0_SCLK, force=True)
        #fm.register(18, fm.fpioa.I2S0_WS, force=True)
        #fm.register(35, fm.fpioa.I2S0_IN_D0, force=True)
        #fm.register(34, fm.fpioa.I2S0_OUT_D2, force=True)

        #CubeAudio.ready()
        #while True:
            #CubeAudio.load(path="/sd/res/sound/loop.wav")
            #while CubeAudio.is_load:
                ##time.sleep_ms(20)
                #CubeAudio.event()
                #print(time.ticks_ms())

        #from Maix import GPIO, I2S, FFT
        #import image, lcd, math
        #
        #from fpioa_manager import fm

        #sample_rate = 38640
        #sample_points = 1024
        #fft_points = 512
        #hist_x_num = 50

        # この部分から修正しました
        # record to wav
        print('play to wav')
        CubeAudio.ready()
        CubeAudio.load("/sd/6.wav",volume=100)
        while CubeAudio.is_load:
            #time.sleep_ms(20)
            CubeAudio.event()
            print(time.ticks_ms())

この二つのコードをPCに保存しMAXI_IDEでSDカードが入った状態のMAiX Qubeへ接続してから
[ツール]→[transfer file to boad]で起動メディア(SDカード)へコピー
てか、SDカードをpcに刺して直接コピーしても良いと思う。
そして次回動画が再生出来ますように。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?