Questions about CTR and sound synthesis
mrgosh
Posts: 23
I have rtfm, and am still not exactly clear on the uses / abilities of CTR(a/b). Is it that for each cog, there is a CTR (and thus, 16 CTR registers total?) or is it that there is a CTR(a/b) register for the prop chip as a whole, and it can be assigned to work with a cog?
Needless to say, I am new to the prop chip, but an averagely experienced programmer. My end goal would be to have a propeller chip act as a polyphonic synthesizer. What I am working on now is having 3 to 8 different tones generated by one chip, played out of 3 to 8 different speakers (pins 0 - 7). I am noticing though that no matter what I try to hack together from the examples, or the simple attempts I have made on my own, that once I get to CTR overlaps, a second register address rewrites the first regardless of cog assignment (example: (pin 0, cog 0, ctra, 800 hz); (pin 1, cog1, ctrb, 900hz); (pin 2, cog2, ctra, 1000hz); i hear 900hz and 1000hz, pin 0 is silent).
So, my guess: there is something I am missing, especially based on this line from the manual:
Each cog has two identical counter modules (A and that can perform many repetitive tasks. pg 204
Help?
-M
Needless to say, I am new to the prop chip, but an averagely experienced programmer. My end goal would be to have a propeller chip act as a polyphonic synthesizer. What I am working on now is having 3 to 8 different tones generated by one chip, played out of 3 to 8 different speakers (pins 0 - 7). I am noticing though that no matter what I try to hack together from the examples, or the simple attempts I have made on my own, that once I get to CTR overlaps, a second register address rewrites the first regardless of cog assignment (example: (pin 0, cog 0, ctra, 800 hz); (pin 1, cog1, ctrb, 900hz); (pin 2, cog2, ctra, 1000hz); i hear 900hz and 1000hz, pin 0 is silent).
So, my guess: there is something I am missing, especially based on this line from the manual:
Each cog has two identical counter modules (A and that can perform many repetitive tasks. pg 204
Help?
-M
Comments
Each cog can generate two different frequencies, one using each counter. The output of the counter is a square wave pulse stream which may or may not be what you want. If you haven't looked at it yet, download AN001, the application note on the counters.
Keep in mind that each cog has its own copy of the DIRA and OUTA registers. When using more than one cog, the DIR registers are OR'd together, so any cog that sets a pin as an output will make that pin an output. The OUTA registers are also OR'd together, so any cog that sets a pin to 1 will make that pin a 1. The counter outputs are OR'd with the OUTA register when they're enabled.
You can get it from here: http://forums.parallax.com/showthread.php?p=617192
Mike, thanks for the tip on the AN001. Should have been smart enough to find that on my own. I still might not be 100% on your explanation of the DIR / OUTA registers being OR'd, and its correlation to my original question. Or maybe I am just expecting that this is more complicated than it really is? Are you simply saying that if you call cognew and in the parameters a pin # is passed, this pins DIRA will automatically be set to HIGH? This seems strange to me, as you would not always - necessarily - be init'ing a new cog and immediately associating it with a pin output, correct? So maybe I am misreading...
m1nuteman, thanks for the link to the education kit.
Thanks for the help, guys.
You're misreading. I was simply trying to restate how the DIRA / OUTA registers in the individual cogs interact to produce the I/O pin behavior. It's described in the Propeller Manual and the datasheet.
Well you started this thread with a mysterious problem... Is it solved in the meantime? When you need further help you have to post your code..
in the entry section of the asm, timea0 and timeb0 have cnt value read into them successively. perioda0 and b0 are arbitrary frequencies (1400 and 1500 right now i think). the A register ouput pin 0, the B pin 1.
The Problem
Both frequencies play, simultaneously, from two pins, on the same cog. They only play, however, for about half a second before they stop. After, there emits a small click every minute or so, but nothing else. I am wrecking my brain trying to figure out what I am missing. Hoping it is just another pair of eyes that will do the trick.
Both counters are intialized to the same value, with no apparent change of pin number.
If you simply want two symmetric square waves, at two different frequencies, then the counters can do that autonomously, without any program intervention after the initialization. Do you understand how to do that? Then filter it externally if necessary. On the other hand, if you want the Prop itself to generate more complex waveforms on each output pin, it might be better for this application to have the two counters operating in duty mode (%00110), and create two numerical oscillators in pasm to modulate the duty cycle of the output waveform. The duty mode is easy to filter.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com
Your program is basically all right, so it can be diffucult to find the weak spot, as Tracy with his great experience has done immediately.
To explain it to others: What Mrgosh does is:
- set the PHSx so the timerx can generate the signal
- wait to the earliest moment where either this timer or the other timer needs service again (CMP)
As Tracy pointed out, this time can sometimes be a little bit in the past, thus leading to a "longer" wait..
A simple fix is to check for this situation before each WAITCNT. Dont fear overflows of CNT, it will always come out correctly
The difference is generally very small, but if you want to be very precise you have to decide, how to keep up the phase (reduce just next "newtime" or reduce pulse and "newtime")
Post Edited (deSilva) : 8/29/2007 6:06:36 PM GMT
if 'time' is set as a constant does this situation still arise?
In this same project as the code above, I am also running into the fact that sound stops (even just simple sq. wave generation) after about 67 seconds (2^32 / clkfreq). This, I am assuming, has to do with clock roll over from 64,000,000 to 0. If someone could point me to a resource so I might better understand how to program with these facts in mind, it would be greatly appreciated. One goal, lets say, would be to have a frequency emit for 15 minutes, stop, and then start again at 20 minutes. I am finding these things to be a great challenge, so thanks for your input everyone.
should change to:
When you want to time things >1 minute you have to construct a "clock"; this is possible, but there are some obstacles... Ariba had a good idea the other day: He suggested using ONE timer to output to a pin, and the OTHER counter to use that pin as input. As you need the counters this means doing it in a different COG,
But when using a new COG you could find as well a pure software solution...
or whatever your code which should go for longer than 1 minute and then stop happens to be.
I cannot seem to make this work, so - once again - there must be something I do not know.
EDIT:
or even, somewhat more simply:
Post Edited (mrgosh) : 8/31/2007 6:29:59 PM GMT
Try this:
I shall find a simpler solution...
RA is an intermediate cell, use what is free
Yes these will be examples of what I called ".. a pure software solution..."!
They however block a COG totally. Aribas idea using two timer/counters would be a fully automated clock....
WAITCNT waits upto this very number you give... and it has to wait for about a minute
do