#!/usr/bin/env python
#version    :       2024.03.07
#language   :       en


import pyaudio
import numpy as np
from maix import camera, image, display
import time

def waterFallShow(inputVal):
    global intensity_recorder,intensity_show,img
    if(len(intensity_recorder)<40):
        intensity_recorder.append(inputVal)
    else:
        for i in range(0,39):
            intensity_recorder[i]=intensity_recorder[i+1]
        intensity_recorder[39]=inputVal
    for i in range(0,len(intensity_recorder)):
        height=int(intensity_recorder[i])
        intensity_show[i] = image.new(size=(7, height), color=(40, 144, 152), mode="RGB")
        img.draw_image(intensity_show[i], i*8, 240-height)
    
image.load_freetype("/root/preset/fonts/CascadiaCodePL-Italic.ttf")
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
p = pyaudio.PyAudio()

img = image.new(size=(320, 240), color=(0, 0, 0), mode="RGB")  # 创建一张红色背景图
stream = p.open(format=FORMAT,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                frames_per_buffer=CHUNK)

intensity_recorder = []
intensity_show = [0]*40
print(len(intensity_show))
# 循环读取音频数据
while True:
    stream.start_stream()
    str_data = stream.read(CHUNK)  # 从麦克风获取一帧音频数据
    stream.stop_stream()
    # 将音频数据转换为NumPy数组
    arr = np.frombuffer(str_data, dtype=np.int16)
    # 计算音频数据的绝对值之和，即为声音强度
    # 1024个16位的wav采样点(-32768~32767)的绝对值之和，需要将其映射到0~1023
    intensity = int(np.abs(arr).sum()/32768)
    #print(intensity)
    img.clear()
    waterFallShow(intensity)
    img.draw_string(140, 20, "Loudness of sound:"+str(intensity), scale=1.0,color=(255, 255, 255), thickness=1)
    display.show(img)
    print("main_thread_time:", time.time())

# 关闭流和PyAudio对象
stream.stop_stream()
stream.close()
p.terminate()