SYN-6988 Speech with MicroPython

Full repo, with module and instructions, here: scruss/micropython-SYN6988: MicroPython library for the VoiceTX SYN6988 text to speech module

(and for those that CircuitPython is the sort of thing they like, there’s this: scruss/circuitpython-SYN6988: CircuitPython library for the YuTone VoiceTX SYN6988 text to speech module.)

I have a bunch of other boards on order to see if the other chips (SYN6288, SYN6658, XF5152) work in the same way. I really wonder which I’ll end up receiving!

Update (2023-07-09): Got the SYN6658. It does not support English TTS and thus is not recommended. It does have some cool sounds, though.

Embedded Text Command Sound Table

The github repo references Embedded text commands, but all of the sound references was too difficult to paste into a table there. So here are all of the ones that the SYN-6988 knows about:

  • Name is the string you use to play the sound, eg: [x1]sound101
  • Alias is an alternative name by which you can call some of the sounds. This is for better compatibility with the SYN6288 apparently. So [x1]sound101 is exactly the same as specifying [x1]sounda
  • Type is the sound description from the manual. Many of these are blank
  • Link is a playable link for a recording of the sound.
NameAliasTypeLink
sound101sounda
sound102soundb
sound103soundc
sound104soundd
sound105sounde
sound106soundf
sound107soundg
sound108soundh
sound109soundi
sound110soundj
sound111soundk
sound112soundl
sound113soundm
sound114soundn
sound115soundo
sound116soundp
sound117soundq
sound118soundr
sound119soundt
sound120soundu
sound121soundv
sound122soundw
sound123soundx
sound124soundy
sound201phone ringtone
sound202phone ringtone
sound203phone ringtone
sound204phone rings
sound205phone ringtone
sound206doorbell
sound207doorbell
sound208doorbell
sound209doorbell
sound301alarm
sound302alarm
sound303alarm
sound304alarm
sound305alarm
sound306alarm
sound307alarm
sound308alarm
sound309alarm
sound310alarm
sound311alarm
sound312alarm
sound313alarm
sound314alarm
sound315alert/emergency
sound316alert/emergency
sound317alert/emergency
sound318alert/emergency
sound401credit card successful
sound402credit card successful
sound403credit card successful
sound404credit card successful
sound405credit card successful
sound406credit card successful
sound407credit card successful
sound408successfully swiped the card
SYN-6988 Sound Reference

It works! It works!

on a messy desk, a small USB midi keyboard is connected to a Korg NTS-1 mini synthesizer via a small micro-controller board that acts as a USB host for the Akai keyboard, converting USB MIDI to traditional MIDI for the Korg
Akai LPK25 keyboard has USB MIDI out, but the Korg NTS-1 only has regular MIDI in. The little board in the middle acts as a USB host for the Akai and MIDI source for the Korg

This is great: gdsports/midiuartusbh: MIDI DIN to MIDI USB Host Converter allows your USB MIDI instruments to act as traditional MIDI controllers. It uses a Adafruit Trinket M0 to act as the USB host and MIDI output.

I modified gdsports’ design very slightly:

  1. Instead of using a 74AHCT125 Logic level converter and driver, I used a FET-based SparkFun Logic Level Converter
  2. Instead of a 5-pin DIN socket, I used a 3.5 mm stereo socket.

And it works!

breadboard showing Trinket M0 microcontroller board, logic level shifter, audio socket breakout and two resistors
Breadboard layout for MIDI-standard 3.5 mm output (Korg). The resistors are both 220 ohm, and the boards need 5 V power

Circuit Playground Express Chord Guitar

Hey! This doesn’t work any more, as CircuitPython changed and I haven’t found a way to update it with the new interpreter.

Since there are seven touch pads on a Circuit Playground Express, that’s enough for traditional 3-chord (â… , â…£, â…¤) songs in the keys of C, D and G. That leaves one pad extra for a â…¥min chord for so you can play Neutral Milk Hotel songs in G, of course.

CircuitPython source and samples: cpx-chord_guitar.zip. Alternatively, on github: v1.0 from scruss/cpx_chord_guitar

The code is really simple: poll the seven touch pads on the CPX, and if one of them is touched, play a sample and pause for a short time:

# Circuit Playground Express Chord Guitar
# scruss - 2017-12

# these libraries should be installed by default in CircuitPython
import touchio
import board
import time
import neopixel
import digitalio
import audioio

# touch pins, anticlockwise from battery connector
touch_pins= [
    touchio.TouchIn(board.A1),
    touchio.TouchIn(board.A2),
    touchio.TouchIn(board.A3),
    touchio.TouchIn(board.A4),
    touchio.TouchIn(board.A5),
    touchio.TouchIn(board.A6),
    touchio.TouchIn(board.A7)
]

# 16 kHz 16-bit mono audio files, in same order as pins
chord_files = [
    "chord-C.wav",
    "chord-D.wav",
    "chord-E.wav",
    "chord-Em.wav",
    "chord-F.wav",
    "chord-G.wav",
    "chord-A.wav"
]

# nearest pixels to touch pads
chord_pixels = [ 6, 8, 9, 0, 1, 3, 4 ]

# set up neopixel access
pixels = neopixel.NeoPixel(board.NEOPIXEL, 10, brightness=.2)
pixels.fill((0, 0, 0))
pixels.show()

# set up speaker output
speaker_enable = digitalio.DigitalInOut(board.SPEAKER_ENABLE)
speaker_enable.switch_to_output(value=True)

# poll touch pins
while True:
    for i in range(len(touch_pins)):
        # if a pin is touched
        if touch_pins[i].value:
            # set nearest pixel
            pixels[chord_pixels[i]] = (0, 0x10, 0)
            pixels.show()
            # open and play corresponding file
            f=open(chord_files[i], "rb")
            a = audioio.AudioOut(board.A0, f)
            a.play()
            # blank nearest pixel
            pixels[chord_pixels[i]] = (0, 0, 0)
            pixels.show()
            # short delay to let chord sound
            # might want to try this a little shorter for faster play
            time.sleep(0.2)

This is roughly how I synthesized the samples, but I made them quieter (the MEMS speaker on the CPX went all buzzy at full volume, and not in a good way) and added a bit of reverb. Here’s the sox command from the modified script:

sox -n -r 16000 -b 16 "chord-${chord}.wav" synth 1 pl "$first" pl "$third" pl "$fifth" delay 0 .05 .1 remix - fade p 0 1 0.5 norm -5 reverb

Really, you do want to take a look at shortening the delay between the samples: you want it long enough for all of the notes of the chord to sound, but short enough that you can play faster songs. I came up with something that worked for me, kinda, and quickly; it’s worth fixing if you have the time.