Creació de jocs amb PyBadge

Programació Gràfics     Recursos CITCEA
Tutorial Exemples Projectes   Inici

Afegir sons

Podem emprar la sortida A0 per generar sons de qualitat i reproduir-los a l'altaveu de la placa.

Disposem de dues famílies de biblioteques per al so, que dependran de com fem els gràfics. Si fem servir gràfics fets amb stage farem servir ugame; mentre que si fem els gràfics amb displayio tindrem audiocore i audioio.

Sons amb ugame

Amb aquesta biblioteca podem reproduir sons que estiguin en fitxers WAV. Cal que el fitxer estigui gravat al disc CIRCUITPY en format wav monoaural (no estereofònic) amb una freqüència de mostreig més petita o igual de 22 kHz amb format 16 bit PCM. Per fer servir un so, cal primer importar la biblioteca.

import ugame

Abans de fer servir el so, caldrà obrir el fitxer, crear un objecte de so i dir-li que no està silenciat.

so_rebot = open("pew.wav", 'rb')
sons = ugame.audio
sons.mute(False)

Després podem reproduir el so en el moment que ho necessitem.

            sons.play(so_rebot)

Podeu veure un programa complet en aquest exemple.

Els objectes de so tenen algunes funcions que ens poden ser útils.

La funció play fa sonar el so corresponent al fitxer indicat.

    sons.play(so_rebot)

La funció mute silencia (True) o no (False) el so.

    sons.mute(False)

La funció stop atura la reproducció del so.

    sons.stop()

Generació de tons amb audiocore i audioio

Amb aquestes biblioteques podem generar una nota solta o fer una melodia encadenant-ne unes quantes. Atès que només podem indicar valors enters de la freqüència, caldrà fer una aproximació. La taula següent indica els valors de freqüència per obtenir les notes de l'escala central del piano:

piano

Nota Freqüència teòrica (Hz) Valor recomanat (Hz)
do3 C4 261,626 262
do#3 re b3 C#4 Db4 277,183 277
re3 D4 293,665 294
re#3 mi b3 D#4 Eb4 311,127 311
mi3 E4 329,628 330
fa3 F4 349,228 349
fa#3 sol b3 F#4 Gb4 369,994 370
sol3 G4 391,995 392
sol#3 la b3 G#4 Ab4 415,305 415
la3 A4 440,000 440
la#3 si b3 A#4 Bb4 466,164 466
si3 B4 493,883 494
do4 C5 523,251 523

El programa següent mostra com crear un so d'una sola nota.

import audiocore
import array
import math
import time
import audioio
import board
import digitalio
Freq = 440    # Frequencia que volem fer sonar (La3)
Mostreig = 8000    # 8000 mostres/segon, valor recomanat
NumValors = Mostreig//Freq    # Nombre de valors diferents per cicle
    # Creem una estructura array per guardar l'ona
ona = array.array("H", [0] * NumValors)
    # La "H" indica que seran valors enters ocupant dos bytes cada un
    # Definint-ho aixi estalviem memoria
    # Aquest array s'omplira amb NumValors elements [0]
    #
    # Anem a calcular els valors
for k in range(NumValors):
    ona[k] = int((1 + math.sin(2 * math.pi * k / NumValors)) * 32767)
        # La funcio sin dona valors entre -1 i 1
        # Li sumem 1 per tenir un valor entre 0 i 2
        # Multipliquem per 32768 per tenir un valor entre 0 i 65535
        # 
    # Anem a activar l'altaveu de la placa
altaveu = digitalio.DigitalInOut(board.SPEAKER_ENABLE)
altaveu.direction = digitalio.Direction.OUTPUT
altaveu.value = True    # Si posessim False l'altaveu estaria desactivat
sons = audioio.AudioOut(board.SPEAKER)
sinusoide = audiocore.RawSample(ona)
sons.play(sinusoide, loop=True)  # Fem sonar l'array repetidament
time.sleep(1)    # durant un segon
sons.stop()    # i el parem
sons.deinit()    # Alliberem l'objecte
                 # per si hi ha un altre so posterior

Podem afegir un control de volum afegint un paràmetre en el càlcul de l'ona:

    ona[k] = int((1 + math.sin(2 * math.pi * k / NumValors)) * 32767 * Vol)

on el paràmetre Vol ha d'estar entre 0 i 1.

Hem creat la biblioteca audio_lib.py (que podeu baixar picant amb el botó dret sobre l'enllaç) que ens permet fer sonar una nota determinada durant un temps concret i amb un volum que podem escollir. Aquí tenim un exemple en el que es fa sonar un Mi i un Sol durant mig segon cada un:

import audio_lib
import board
import digitalio
import time
import audioio
altaveu = digitalio.DigitalInOut(board.SPEAKER_ENABLE)
altaveu.direction = digitalio.Direction.OUTPUT
altaveu.value = True
sons = audioio.AudioOut(board.SPEAKER)
while True:
    sinusoide = audio_lib.nota(330, 1) # Mi
    # El segon parametre es el volum, entre 0 i 1
    sons.play(sinusoide, loop=True)
    time.sleep(0.5)
    sinusoide = audio_lib.nota(392, 1) # Sol
    sons.play(sinusoide, loop=True)
    time.sleep(0.5)
    sons.stop()
    time.sleep(2)

No és imprescindible que l'ona de so sigui sinusoïdal. En aquest exemple es compara com sona la mateixa nota segons si l'ona és sinusoïdal, triangular o quadrada. Podeu trobar l'explicació del programa a partir de la pàgina 74 del número 26 de la revista HackSpace magazine.

Reproducció de fitxers de so amb audiocore i audioio

També podem reproduir un fitxer de so. Cal que el fitxer estigui gravat al disc CIRCUITPY en format wav monoaural (no estereofònic) amb una freqüència de mostreig més petita o igual de 22 kHz amb format 16 bit PCM.

El programa següent reprodueix el fitxer de so ring.wav cada minut.

import audiocore
import audioio
import board
import digitalio
import time
# Configura l'altaveu
altaveu = digitalio.DigitalInOut(board.SPEAKER_ENABLE)
altaveu.direction = digitalio.Direction.OUTPUT
altaveu.value = True
# Funcio per reproduir el fitxer de so
def play_file(nom_fitxer):
    print("Inici del so")
    fitxer = open(nom_fitxer, "rb")
    with audiocore.WaveFile(fitxer) as wave:
        with audioio.AudioOut(board.A0) as audio:
            audio.play(wave)
            while audio.playing:
                pass
    print("Fi del so")
while True:
    play_file("ring.wav")
    time.sleep(60)

Podeu veure un programa complet en aquest exemple.

 

 

 

 

 

 

 

 

 

 

Licencia de Creative Commons
Esta obra de Oriol Boix está licenciada bajo una licencia no importada Creative Commons Reconocimiento-NoComercial-SinObraDerivada 3.0.