How to simply generate a "cuckoo" sound?
Hi, this is a question for the sound specialists.
I want to build a cuckoo clock with P1 and Tachyon. A cuckoo clock is a wall clock which opens a little door every full hour. A little bird is visible and "cuckoo" is heard.
Due to memory constrains of P1, I would like to sythesize this sound. (In a former project with a different processor, I used a wav player.) It is somewhat funny, that in German language, the bird sings "Kuckuck", so there is a third "k" in the sound.
So there are two "oo" with different frequencies and one or two or 3 "k" to be generated.
So far I have found this (sorry in German), https://www.phonetik.uni-muenchen.de/studium/skripten/SGL/SGLKap2.html
which seems to indicate, that a "oo" (u) could be generated with a table, that contains the added sine waves of 4 frequencies F0, F1, F2, F3. If I would multiply that with some sort of envelope?
I would be happy and thankful for some hints, how I could achieve this. It would be very interesting, if it could be done in Forth, without using assembler. I think, I can dedicate a cog for the job.
Thanks in advance, Christof
Comments
I think that @Ahle2 and @Wuerfel_21 are experts on sound so maybe they could jump in ? Not sure about the Tachyon part, but still may give you some general ideas.
This link shows a circuit that is used to generate a cuckoo sound. It consists of a square wave oscillator that generates 667 Hz followed by 545 Hz. The square wave is filtered and white noise is added to make is sound like a cuckoo. Maybe you can write some code for the P1 to simulate something like this.
Propeller Tool comes with a
VocalTract.spin
that is not very good at actually talking, but decently good if you hand-tune a command sequence. It's mostly PASM, but you'd need to translate a couple Spin methods into forth. It's a bit hard to get it to do what you want though. IIRC there's also a line you need to change if you need high glottal pitch.Thank you both for your answers!
As I was asking for something simple, I will try to emulate the circuit Dave pointed out. Just a single sine plus noise to disguise the vowel + a sequencer with simple envelope. (No "K" at all.) :-)
There's usually a chime that accompanies the cuckoo sound:
https://freesound.org/people/Dean-Raul_DiArchangeli/sounds/462930/
Were you planning to include that?
-Phil
Yes, Phil, at my former project with wav files I had this chime too. And depending from the time I have a "cock-a-doodle-doo" (very different vowels in German with "Kikeriki") in the morning and a small owl "huhuuh" in the evening. Some ( steamer ships) bell is marking quarter hours.
Minimum requirement is "Kuckuck."
Anyway: Any ideas how to synthesize the chime? Simple!
At the very moment I am able to output a sine wave but it looks as if the sequencer and the generation of the envelope must be done in a second cog, if no assembler is to be used. The update frequency of the DDS is not very high with tachyon.
Daves link with hardware is very nice for my project, because there are fallbacks: P1 can generate the square wave via counter, the sequencer and the on-off of the envelope via software, while its shaping and the filtering can be done with the circuit. I am not yet sure about the white noise, because I only have 5V.
This cuckoo clock shall have a different main attraction. It shall be a trip hammer https://en.wikipedia.org/wiki/Trip_hammer with a water wheel. So there will be plenty of noise.... (If I succeed....) I want to drive the mechanics of the hammer with a stepper motor. So the number of hammer blows should be able to be controlled.
The clock dial shall be represented by a neopixel ring.
Perhaps some neopixel light effects for the smiths hearth and the waterflow?
Time shall come from a DCF-77 long wave receiver which has to be decoded.
Plenty of work for P1...
so you can do quarter blows 1 / 2 / 3 / 4 - and then Kuckuck at full clock 1 .. 12 as the hour is (like the original black forest cocoo clock)
Peter provides SIDcog as a COGlet to load into Tachyon.
Might be overkill to generate a cocoo but if there is a cog free - why not use it?
OK, this is the code so far, does not sound too bad:
I had no real idea what this SIDcog was about -
pretty impressing:
https://youtube.com/watch?v=zgUMfNJieO4
Just for fun I converted the program to Spin. It sounded a little distorted with a sample rate of 2.5 KHz, so I increased it to 4.88 KHz. It sounds pretty good. I'm not sure what is required to make it sound more like a real cuckoo clock. It would be interesting to generate the chime, and mix that with the cuckoo sound.
It needs some "breathiness." Cuckoo clocks use bellows-activated whistles, and a lot of the air escapes without being modulated. What results is a flute-like sound with a lot of brown noise.
-Phil
I found the source of the distortion. I was masking the sine table index with $3C instead of $3F. I fixed that and it sounds better now. I also added some noise, but I don't think it improves it much. It's probably because I'm adding white noise instead of band-pass filtered noise. I also had to switch to FlexProp to get higher speed. The Spin bytecode interpreter was a little slow to keep up.
Hi, Dave, great!
Don't you want to build the complete clock now?
((The neopixel ring does make a nice clock face, simple to use, if you have a WS2812 driver, and an opening door can be made quiet easily with a servo....))
I too have had the impression, that adding the "breathiness" noise did not improve the sound. Due to the limited update frequency there seems to be enough noise? I also have the impression, that a real bird does not have that breathiness.
Perhaps it would be better to have a separate envelope for the noise.
sound= sine * envelopeA + noise * envelopeB
It should be possible to "low pass filter the noise" using the same number more than once.
I ask myself, if something like a chime could be achieved, with this setup too, something like "tshing".
With the compiler now, you could put the sinvalout loop into the other cog?
Have fun, Christof
those have been in EXTEND in previous versions using the SIN-table in P1 ROM
pub COS ( angle -- cosine \ the angle is in radians scaled to ?? bits ?? )
$800 +
pub SIN ( angle -- sine \ the angle is in radians scaled to ?? bits ?? )
DUP $1000 AND SWAP \ test quadrant 3|4
DUP $800 AND IF NEGATE THEN \ test quadrant 2|4 and negate if true
$7000 OR 2* W@ \ lookup word from sin table
SWAP IF NEGATE THEN \ if quadrant 3|4, negate sample
;