小怪物米米卡

标签:arduino DIY intel Edison

短笛大魔王 发布于 2016-09-26 14:17

1.jpg

~~ 我是小怪物米米卡!你说什么?嗷~~我是小怪物米米卡!

这个小怪物刚刚来到地球,你需要教它怎么说话!如果你对着它的音频天线说话,它就会重复你的话。按一下按键,它还会改变音调。

在动手之前,intel edison需要:1. 已经升级了硬件

2. 能连到无线网络

3. 可以用迷你USB或wifi连接ssh/scp


Step 1: 准备需要的工具和材料

step1.jpg

1. intel Edisonarduino 扩展板

2. 1intel Edison 电源

3. 1个麦克风 1个USB声卡(带音频输入输出)

4. 带迷你杰克头的电源控制的扬声器

5. 螺母和螺栓

6. 喷胶或胶布

Step 2: 准备米米卡的外壳

s2-1.jpg

根据附件的图纸,准备好外壳的各个部分,打印出装饰的图片,方便最后组装


附件:

Step 3: 焊电路

s3-1.jpg
根据电路图焊电路

Step 4: 组装

s4-1.jpg step4-2.jpg step4-3.jpg

1. 把A7和A8装到A1上

2. 用胶布或双面胶把彩色外观贴到A1,A2,A3上

3. 把按钮放到A1上设计好的孔里, 注意按钮的顺序要与LEDs匹配,把LED放进A1上设计好的孔里,注意LED的顺序要与按钮匹配

4. 在A4上安装Arduino扩展板

5. 连接声音元件、声卡、麦克风和扬声器、把电路装到Arduino 扩展板上

6. 把A5和A6连到A1上

7. 从上面的孔装入麦克风,从下面的孔装电线

8. 在A7和A8上插入A2和A3,用橡皮筋固定它们

9. 用A4完成组装,小心电线。在盖上最后的盖子前,最好先测试下电路是否能用

Step 5: 配置声卡+编程

s5-1.jpg

如果你有最新的intel Edison系统映像,那很可能你不需要装任何驱动,声卡就能用。插好USB声卡,打开开关。在打开开关前,请确保连好电源。否则,Intel Edison 无法加电

先用通用的 alsamixer检查下声卡能否正常工作和控制音量

在控制台输入“alsamixer”打开界面。按下F6,选择声卡。在这里,我是选的C-Media USB头戴式耳机设置。把输出音量调低,这样不会太吵。通过调节这个,找到合适的音量。

安装python库

升级设置工具,它是用来安装程序包的Python工具。确保你能连上网络,在命令控制台输入如下语句:

wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py -O - | python

下载pyaudio,这是我们要用来处理声音输入/输出的Python库。在命令控制台输入如下语句:

wget people.csail.mit.edu/hubert/pyaudio/packages/pyaudio-0.2.8.tar.gz -o ./pyaudio.tar.gz

命令控制台输入如下语句解码:

tar -x pyaudio.tar.gz

安装pyaudio 根据导航进入pyaudio的文件夹,在命令控制台输入如下语句:

python setup.py install

安装portaudio,这是让音频设备正常工作的Linux工具。在命令控制台输入如下语句:

opkg install libportaudio2

安装numpy,这是处理数据的Python库,它会在音频处理的实际进程上用到。在命令控制台输入如下语句:

opkg install python-numpy

intel Edison的移动脚本

从附件下载python脚本,用sip把它全部复制到intel Edison

命令控制台输入如下语句:

scp Mimic.py root@your-edison-ip:~/

命令控制台开始编写小怪物米米卡的程序:

python ~/Mimic.py

源代码如下:

"""
Mimic:
Let Edison mimic your voice in a funny way

"""

import pyaudio
import audioop
import numpy as np
import struct
import wave
import time
import mraa

led_pins=[13,12,11,10]
btn_pins=[9,8,7,6]
levels=[-7,-3,3,7]
leds=[]
btns=[]

CHUNK = 1024
WIDTH = 2
CHANNELS = 1 
RATE = 44100
RECORD_SECONDS = 5
level=-1
swidth=2

#Volume needed to activate the programme
activate_volume=2000

def dimAllLeds():
    for i in range(4):
        leds[i].write(0)

def speedx(snd_array, factor):
    """ Speeds up / slows down a sound, by some factor. """
    indices = np.round( np.arange(0, len(snd_array), factor) )
    indices = indices[indices < len(snd_array)].astype(int)
    return snd_array[ indices ]

def stretch(snd_array, factor, window_size, h):
    """ Stretches/shortens a sound, by some factor. """
    phase  = np.zeros(window_size)
    hanning_window = np.hanning(window_size)
    result = np.zeros( len(snd_array) /factor + window_size)

    for i in np.arange(0, len(snd_array)-(window_size+h), h*factor):

        # two potentially overlapping subarrays
        a1 = snd_array[i: i + window_size]
        a2 = snd_array[i + h: i + window_size + h]

        # the spectra of these arrays
        s1 =  np.fft.fft(hanning_window * a1)
        s2 =  np.fft.fft(hanning_window * a2)

        #  rephase all frequencies
        phase = (phase + np.angle(s2/s1)) % 2*np.pi

        a2_rephased = np.fft.ifft(np.abs(s2)*np.exp(1j*phase))
        i2 = int(i/factor)
        result[i2 : i2 + window_size] += hanning_window*a2_rephased

    result = ((2**(16-4)) * result/result.max()) # normalize (16bit)

    return result.astype('int16')

def pitchshift(snd_array, n, window_size=2**13, h=2**11):
    """ Changes the pitch of a sound by ``n`` semitones. """
    factor = 2**(1.0 * n / 12.0)
    stretched = stretch(snd_array, 1.0/factor, window_size, h)
    return speedx(stretched[window_size:], factor)


if __name__=="__main__":
    #Initialize the buttons and leds
    for i in range(0,4):
        led=mraa.Gpio(led_pins[i])
        led.dir(mraa.DIR_OUT)
        btn=mraa.Gpio(btn_pins[i])
        btn.dir(mraa.DIR_IN)
        btn.mode(mraa.MODE_PULLUP)
        leds.append(led)
        btns.append(btn)

    #Initialize audio stream
    p = pyaudio.PyAudio()
    stream = p.open(format=p.get_format_from_width(WIDTH),
                    channels=CHANNELS,
                    rate=RATE,
                    input=True,
                    output=True,
                    frames_per_buffer=CHUNK)



    #The main loop
    while True:
        frames=""
        stream.start_stream()
        
        #Work to do before mimic starts
        while True:
            #Check if buttons are pressed
            for i in range(4):
                if btns[i].read()==0:
                    dimAllLeds()
                    leds[i].write(1)
                    level=levels[i]
            #Check if someone is speaking 
            data = stream.read(CHUNK)
            rms=audioop.rms(data,2)
            if rms>activate_volume:
                frames=frames+data
                break
                
        #Start recording
        timer=0
        print("* recording")
        while True:
            try:
                data = stream.read(CHUNK)
                frames=frames+data
                rms=audioop.rms(data,2)
                if rms<activate_volume:
                    if time.time()-timer>1:
                        break
                else:
                    timer=time.time()
            except:
                pass
                
        #Do the pitch shifting magic
        frames = struct.unpack("%dh"%(len(frames)/swidth), frames)
        frames = np.array(frames)
        frames=pitchshift(frames, level)
        frames=struct.pack("%dh"%(len(frames)),*list(frames))
        
        #Play the modified sound
        data = frames[0:CHUNK] 
        i=0
        while data != '':
            stream.write(data)
            i=i+1
            data = frames[i*CHUNK:(i+1)*CHUNK] 

        print("* done")
        stream.stop_stream()
        
    stream.close()
    p.terminate()

对准麦克风清楚大声的说话,小怪物米米卡就会用搞笑的声音重复你的话了~~~~



 

作者

短笛大魔王

上海,闵行

2粉丝 1作品 0随笔
  关注 私信

作者的最新作品


阅读数: 5489