01/05/2017 at 08:57 •
Uhm, fiddling with the audio samples and recycling one single vowel to produce all the required one by simply freq. shifting with the NCO was an interesting experiment but it definitely fizzled. As in, it just did not work!
I am also disappointed by the results of my (lazy) attempt to re-target to the word "Hackaday". I should either take it more seriously and re-sample new vowels/consonants that are more appropriate for the target word or stick to the original "message". After all there is a whole lot of nostalgia that goes with that (albeit that would apply only for me :) Will revert the "segments" table shortly.
Minor hw update as well. I have separated the PIC10F board from the proto area (that I immediately re-used for another project) and re-soldered the pushbutton (SW1) notably missing in the early pictures... Also added a semi-proper connector for my scope probe and the audio amplifier (just headphones actually).
1 - Be humble. As rudimentary as my audio sample collection/manipulation was 20+ years ago, it was nonetheless somewhat optimal for the target.
2 - NCO peripheral definitely useful for future little tricks. I will explore possibility to freq. shift in WAV-1K project when playing back from an SD card...
12/11/2016 at 22:10 •
So I did try to use the NCO (Numerically Controlled Oscillator) to generate a variable time base for each vowel and it kind of worked. It actually turned out to be easier than expected.
The idea worked like this:
- I kept the PWM working on TMR2 with a fixed frequency of 32kHz.
- I modified the main loop to wait on the NCO interrupt instead of the TMR2 postscaler.
- I assigned an initial NCO "increment" (524) to obtain the standard 8kHz sample rate.
I run a test to verify that this way I would get the same output as before (when using the TMR2 interrupt). it did!
(NOTE: increment = Fout / (Fosc / 2^20) = 8000 / (16MHz/1MB) = 524)
- I removed the tables for the vowels 'e' and 'i' and replaced them in the scheduler with 'a'.
- I added for each 'part' in the schedule a setting for the NCO increment leaving the value to 524 ( the constant EIGHTK) for all non vowels.
- I scaled the value of INC proportionally to the length of each of the vowels tables. (E = 645, I = 870)
While debugging the new code I found out a bug in the "silence" table (the signature was supposed to be changed to 0xff, but I had forgotten to update it).
I created a new branch of the project on Github (NCO) and later went back and fixed the "silence bug" in the "master" too...
12/09/2016 at 09:54 •
So I was looking at the samples (tables) forming the vowels "a", "e", "i" used in the original code and just figured out that they all look very (suspiciously) similar. The length (period) being the most (obvious) distinguishing element. Clearly I had no good tools at the time to "clean up" or simply to handle the audio signal. The effective resolution appears to be awfully small 4-5 bit?
I am amazed in fact in re-discovering the Turbo Pascal code I used back then to "edit" the WAV files and extract semi-automatically those tables. (You will find the source in the "archive" folder...). Does anybody have a copy of the might Borland Turbo Pascal that would run on my Mac? I am almost afraid to ask, somebody actually might!
Today I am sure I would have used an OSS tool such as "Audacity" or a 5 lines script in Python (import wave) or ... simply Excel !!!
(Libre Office I meant!)
12/07/2016 at 10:54 •
I have completed the port to the PIC10 and the little (6-pin) critter speaks!
Very interesting exercise indeed. First of all I had to refresh my PIC assembly. I was amazed how much rust had accumulated in only a couple of years (or is it more) of "only" C programming. The original code was written for 12-bit "baseline" PICs, the old C5X series, and that used to come with a whole lot of restrictions and complications that I had almost completely forgotten about. For example, subroutines could only be called in the lower half of the program space. Since the only way to implement a lookup table in those days was to use the "idiosyncratic" RETLW opcode... tables themselves were restricted or rather we used to jump through hoops!
Now the PIC10F3xx, is a "mid-range" PIC, meaning the instructions are 14-bit wide which allowed me to move things around a bit. I now for a fact that the code does fit now!
The PIC10F32x also comes with a convenient PWM, and that can be clocked fast enough (using only the internal oscillator) to produce an audio D/A, so all I need now is a single output pin.
Most importantly, I programmed the code on the little PIC10F demo board (see picture) and connected (poorly) a little audio amplifier: it does speak, kind of ...
Definitely not happy with the quality of the sound, I am going to investigate how the ... I did come up with those samples back then. What was I thinking?
Also I see a few possible directions (branches?) this project could take from here:
1- Investigate use of the NCO (frequency synthesiser) peripheral (instead of the fixed PWM) to frequency shift a single sample waveform and produce the multiple vowels needed. I need to think this one through...
2- Evaluate replacing the RETLW tables with proper NVM access. The PIC10F3' Flash read/write module allows full access to the program flash word. That would give me 14-bit of data for each word instead of just 8. I could pack double the number of samples...
3- I could get adventurous and try to change the "spoken" word into something more appropriate for the contest ("one k", or "Hackaday"?)