【问题标题】:Problems with audio playback using arduino使用 arduino 播放音频的问题
【发布时间】:2020-04-27 10:41:10
【问题描述】:

我正在尝试创建一个系统,其中一部分需要将麦克风连接到 arduino。我没有经常使用麦克风。

我已将麦克风 (Adafruit Electret Microphone Amplifier - MAX9814 with Auto Gain Control) 连接到 arduino nano。我想从这里录制音频数据。

void setup() {
  Serial.begin(9600);
  pinMode(A2, INPUT);
}

void loop() {
  if(Serial.available())
  {
    Serial.println(analogRead(A2));
    }
}

我将数据发送到计算机并使用 python 脚本记录并转换为 WAV 文件以确保麦克风正常工作。我尝试了多种方法,使用 ADC 值,在 -1 和 1 之间缩放 ADC 值,转换成电压然后缩放它,但似乎没有任何效果。当我播放它时,我能听到的只是静止的声音,只需点击几下声音应该在的地方。

下面是我为使用 println 发送 ADC 值的配置编写的 python 代码。在这里,我使用 pyserial 库收集数据并将其转换为浮点数。然后我在 -1 和 1 之间进行标准化。然后我将它保存在一个 wav 文件中。

import serial
import matplotlib.pyplot as plt
import sounddevice as sd
import numpy as np
from scipy.io.wavfile import write

import pyaudio
import wave

def audnorm(aud):
    normaud=  -1+2*((aud-np.amin(aud))/(np.amax(aud)-np.amin(aud)))
    return normaud

ser = serial.Serial('/dev/ttyACM0',115200)
ser.flushInput()

sound=[]
sound2=[]

while True:
    try:
        ser_bytes = ser.readline()
        ser_bytes2= float(ser_bytes)
        sound.append(ser_bytes2)
        sound2.append(ser_bytes)
        print(ser_bytes+"\t"+str(ser_bytes2))
        print(type(ser_bytes))
    except:
        print("Keyboard Interrupt")
        break
print(str(len(sound)))

soundnp= np.asarray(sound)

soundnp= soundnp - np.mean(soundnp)


soundnorm= audnorm(soundnp)

soundnormstr= [str(x) for x in soundnorm]

plt.plot(soundnp)
plt.show()

plt.plot(soundnorm)
plt.show()


wf = wave.open("output.wav", 'wb')
wf.setnchannels(1)
wf.setsampwidth(2)
wf.setframerate(10000)
wf.writeframes(b''.join(soundnormstr))
wf.close()

我附上了 2 张我使用此代码记录的数据的图像。

我做错了什么?

Raw Data Normalized Data

【问题讨论】:

  • Serial.available() 当有可供 Arduino 读取的输入时为真。因为您没有向 Arduino 发送数据,所以您可以删除 if (Serial.available()) 语句。

标签: python arduino audio-recording microphone


【解决方案1】:

我同意布拉德福德的观点。您需要进行统一采样以获取音频信号,最低为 8000 Hz。

我认为你需要设置一个更高的串行波特率来达到这个采样频率。我稍微修改了您的代码,以用示波器测量串行“传输”(加上模拟写入)的“实际最大频率”。

void setup() {
  // Serial.begin(9600);
  Serial.begin(115200);
  pinMode(A2, INPUT);
}

void loop() {
  //if(Serial.available())
  {
    int val = analogRead(A2);
    Serial.write(0);
    }

}

在示波器上,它大约为 9 kHz 频率,在串行线上仅发送零。见附件figure。这可能是可行的(对于语音,而不是音乐)。

【讨论】:

    【解决方案2】:

    要在不失真的情况下录制,您尝试录制的信号(我假设它是音频信号)需要三件事:1)以统一的速率采样,2)以每秒超过 8,000 个样本的速度采样才能能够几乎听不懂声音,以及 3) 以获取数据的速度传输或存储数据。

    re: 1 & 2) 有一个教程介绍了在 Arduino 上录制高保真音频的所有混乱细节。它包含的信息比我在这里写的要多得多。见https://www.instructables.com/id/Arduino-Audio-Input/

    如果您的应用程序需要 Arduino 简单地检测到有声音 - 例如拍手 - 您可以使用较低且不均匀的采样率。搜索“Arduino Clapper”以获得一些想法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多