Let your projects be heard - give them a voice, respond to different events with different pre-recorded audio announcements (in different voices, and even different languages), or respond to events by playing different sounds, or perhaps just play music.
The JQ6500 Serial Audio Player module allows storing MP3
or WAV audio files in 16M Flash memory for selective playback controlled by the ESP.
The on-board audio amplifier can directly drive a small
loudspeaker, which makes the module rather 'juicy', so I suggest powering via a USB charger.
The JQ6500-28p version (above) has on-board Micro-SD card reader offering up to 32Gb of additional storage.
The 28-pin version with on-board SD card reader costs about a fiver from ebay, and the 16-pin non-SD version is available for less than 2 quid. USB can be used to copy files directly from computer to the modules on-board Flash memory, or to an inserted SD card on the 28-pin version. Therefore only the 3 solid connections are required, the dotted pink connection is optional if you wish to experiment with receiving query codes.
Here is a good link for more information about how to use the JQ6500 family of audio modules: http://goo.gl/bJFCFU
The script has a 'stretchy' FIFO queue which expands to fill with sequences of audio file names, then uses the 'Busy' pin to control the FIFO output to create in effect a 'sentence' of chained 'words' which are announced one after the other, thus allowing sentences to be made up from individual words and numbers.I've tried various other audio player modules, and although this is so far the best, they typically squeeze a cut-down version of Filing System into a limited space which is primarily aimed at selecting files by number (typically in the order the files were written to the FAT (file allocation table). In fairness I suspect the JQ6500 players may actually select by the filename representation of number rather than by file copy order, but no matter if not, because there are free sort utilities available if needed that can physically re-order the file entries in the FAT. The JQ6500 has various different control methods allowing for button and even IR operation, but we are interested in using Serial Control codes from Annex. Serial mode uses 1 byte for sending folder information, but I think I've seen somewhere that the limit is 99 folders... which is ample. It also uses 1 byte for sending the file number, therefore limiting to 255 files even though apparently able to store up to a thousand per folder. In fairness, up to 99 folders each containing up to 255 files should suffice for any realistic applications requirements. My choice is to adopt a file convention which uses 1 folder for all required files. Therefore I reserve the first numbers 1 to 24 for the corresponding 'channel' number alert message, and the next 24 are reserved for a matching complimentary message, ie: x = ChannelxON, x+24=ChannelxOFF (even if not needed for momentary triggers). Numbers 50 to 99 are available for specific 'system' messages such as 75=MuteON, 81=Volume, 82=UP, 83=DOWN etc. Numbers above 100 are for a chained-word vocabulary. Such a convention makes it fairly easy to use other folders to hold other 'sets' of alternative voice 'messages if wished, eg: in different languages. Or, as in my case, to add 'custom' sets of messages tailored to location and requirements - so instead of announcing default "Channel 6 Alert" and "Channel 6 Clear" messages, my system announces "Shed Door Open" and "Shed Door Closed" for the appropriate channel 6 sensor. Changing between English Defaults, English Custom, French Defaults, French Custom etc etc is just a simple matter of changing folders. It is easy to create your own voice announcement recordings (in different languages and various TTS voices) using a variety of free online 'Text to Speech' services, or by recording 'speaking' google translate, or by using a free Text2Speech utility on computer, or by simply recording your voice. If you wish to 'chain' together individual recorded words and numbers into spoken sentences you will need to trim off any intro and exit silences. I used the free Audacity Portable to record and edit audio files: https://portableapps.com/apps/music_video/audacity_portable The script below is just the stripped out audio part of a sensor monitoring system I am doing, so the audio examples I have included below are some of my systems recordings. The numbered file names need to be in a folder called "01" on the SD card, so unzip the supplied audio files from the zip into a folder called "01" where the script can find them. File 10.wav is an intro message, followed by the first 5 files in the folder, which will be played via the voice queue at startup. Then pressing the gpio0 button simply speaks the message number "001.wav"... other event triggers (eg: from a port expander) could of course speak other messages. It is just intended as an example to 'open the door' and help you give voice to your own systems.. My system is using a pcf8574 port expander to read various sensors and speak the appropriate messages when triggered - I expect I will eventually publish the system when it is perfect, but not till then, because I don't want to be spending much of my time ironing out any wrinkles that people would find.. So this script is merely to demonstrate how to use Annex to play selected audio files in response to events. If you want to try out your own audio recordings you can copy them into a different folder eg: "02" and select the appropriate folder and file from the Output page. Note that if you change either the folder or file in the textbox windows you need to PRESS ENTER to register the changed contents back to the variable.and then click the "Play Selected File" button. else it will ignore your typed in changes.
Basic:
title$ = "Audio Player - Version JQ6500 - by Electroguard"
'Requires JQ6500-28P module, using serial control mode to play selected file. q$ = "" 'FIFO queue, add files to be played to end of queue, eg: q$ = q$ + " " + filename number (ie: "5"), then GOSUB TALK serial2.mode 9600, 5, 4 'tx, rx - Only needs TX to send control codes to JQ6500 RX onserial2 serial2in 'only needed if expecting responses from jq6500 response = 0 'var to receive serial2 response byte busypin = 13 busy = 1 pin.mode busypin, input, pullup interrupt busypin, talk buttonpin = 0: pin.mode buttonpin, input, pullup 'using active low gpio0 button interrupt buttonpin, pressed vdir = &h01 ' Default audio folder vfile = &h01 ' Default audio file vol = 19 'Default to mid-volume (max=30) 'JQ6500 serial codes are defined below for convenience. vstart = 126 'Serial command start byte vend = 239 'Serial command end byte vplay = 13 vpause = 14 vnext = 1 vprev = 2 volup = 4 voldown = 5 vset = 6 vreset = &h0C vdirfile = &h12 vsource = &h09 vloopmode = &h11 vdchange = &h0F vdnext = &h01 vdprev = &h00 gosub VOICERESET gosub setvol gosub paint onhtmlchange DOREFRESH pause 500 q$ = "10" wlog q$ gosub talk for c = 1 to 5 q$ = trim$(q$ + " " + str$(c)) 'adding demo recordings to the queue, should be played out in order without loss next c wlog q$ wait talk: if pin(busypin) = busy then do pause 200 loop until pin(busypin) <> busy else Q$ = trim$(Q$) if Q$ > "" then bite$ = word$(Q$,1) vfile = val(bite$) print2 chr$(vstart);chr$(04);chr$(vdirfile);chr$(vdir);chr$(vfile);chr$(vend) Q$ = trim$(word.delete$(Q$,1)) endif endif return paint: cls a$ = title$ + "<BR><BR>" a$ = a$ + "Folder " + textbox$(vdir) a$ = a$ + " File " + textbox$(vfile) a$ = a$ + "<BR>" a$ = a$ + button$("Play selected file", PLAYFILE) a$ = a$ + "<BR><BR>" a$ = a$ + button$( "<", PREV) a$ = a$ + button$( "Play", PLAY) a$ = a$ + button$( ">", NEXTf) a$ = a$ + "<BR><BR>" a$ = a$ + button$( "< Folder", DPREV) a$ = a$ + button$( "Folder >", DNEXT) a$ = a$ + "<BR><BR>" a$ = a$ + button$( "< Vol", VOLd) a$ = a$ + button$( "Vol >", VOLu) a$ = a$ + slider$( vol, 0, 30) a$ = a$ + textbox$(vol) a$ = a$ + button$( "Set Volume", SETVOL) a$ = a$ + "<BR><BR>" a$ = a$ + "<BR><BR>" html a$ a$ = "" refresh return DOREFRESH: refresh return PLAY: 'Play current (last played) file print2 chr$(vstart);chr$(02);chr$(vplay);chr$(vend) refresh return SETVOL: 'Set absolute volume value print2 chr$(vstart);chr$(03);chr$(vset);chr$(vol);chr$(vend) refresh return VOLd: 'Relative volume decrease print2 chr$(vstart);chr$(02);chr$(voldown);chr$(vend) refresh return VOLu: 'Relative volume increase print2 chr$(vstart);chr$(02);chr$(volup);chr$(vend) refresh return PLAYFILE: 'Play specified 'vfile' audio file from 'vdir' folder print2 chr$(vstart);chr$(04);chr$(vdirfile);chr$(vdir);chr$(vfile);chr$(vend) refresh return NEXTf: 'Play next file print2 chr$(vstart);chr$(02);chr$(vnext);chr$(vend) refresh return PREV: 'Play previous file print2 chr$(vstart);chr$(02);chr$(vprev);chr$(vend) refresh return DNEXT: 'Select next folder print2 chr$(vstart);chr$(03);chr$(vdchange);chr$(vdnext);chr$(vend) refresh return DPREV: 'Select previous folder print2 chr$(vstart);chr$(03);chr$(vdchange);chr$(vdprev);chr$(vend) refresh return VOICERESET: 'Reset JQ6500 print2 chr$(vstart);chr$(02);chr$(vreset);chr$(vend) pause 400 print2 chr$(vstart);chr$(03);chr$(vsource);chr$(1);chr$(vend) return serial2in: temp$ = serial2.input$ wlog "Response=" + hex$(asc(temp$)) return pressed: wlog "button" if pin(buttonpin) = 0 then q$ = q$ + " " + "1" gosub talk endif return end '------------- end --------------- UPDATE Apparently at least one person has been using the JQ6500 audio player module, so I will report a problem I have discovered with mine. You can easily test if yours is similarly affected by repeatedly using the scripts Play button in the Output page. If the same sensor alert message is replayed several times, it starts missing the first part of the message, and can eventually miss out all of the message entirely. Eg: "Gate 1 visitor" becomes "1 visitor" then "visitor" then "or" then "". I have tried resetting the JQ6500 before playing the message, but makes no difference. I'm guessing it is a problem with its stripped-down filing system confusing locations of the various file names to locations of the pause and play memory position within files. When a file is first accessed it references to the beginning of the recording ok. But after that, it assumes it should be referencing within the same file for Pause and Play position, and if it hasn't already been paused, it seems it just creates a reference point for itself. That is obviously a bug that would be easily correctable, but asia does not have a good reputation for fixing obvious faults, nor aftercare responsibility. So it seems the only way for the file system to get the start of the file position correct is when playing it for the first time after playing a different file, else it switches to referencing within the same file and gets it wrong. Therefore perhaps the problem can be skirted by playing something like a "Ding dong" attention-grabber message first, then playing the required recording. Or perhaps just use the serial Text to Speech module that featured in the next project. |