Fake Microphone input for QuickStart board
In this thread Beau Schwabe posted code for a Phase modulator for the Demo board that digitizes the microphone, then "modulates the samples over the desired synthesized frequency generated on CTRB."
I'm using a Quickstart board though, and therefore no real microphone so .....
I tried to modify the code, adding a "fakeMic" routine that would supply the microphone pin (9 ??) with the
samples from an 8bit /11_025 sample rate .wav file.
But I'm just getting "white noise" output.
The fakeMic is started in a new cog :
I changed the "bits" constant from 11 to 8, but it still doesn't work.
I also tried the "fakeMic" routine with both a delay (simulating an 11K sample rate) and without, and both just yield
"noise".
Is the "fakeMic" spin code too slow ?
Mike
I'm using a Quickstart board though, and therefore no real microphone so .....
I tried to modify the code, adding a "fakeMic" routine that would supply the microphone pin (9 ??) with the
samples from an 8bit /11_025 sample rate .wav file.
But I'm just getting "white noise" output.
The fakeMic is started in a new cog :
cognew(fakeMic,@fakeMicStack)
I changed the "bits" constant from 11 to 8, but it still doesn't work.
I also tried the "fakeMic" routine with both a delay (simulating an 11K sample rate) and without, and both just yield
"noise".
Is the "fakeMic" spin code too slow ?
Mike
CON
SampRate = 11_025
PUB fakeMic |p,time,x
dira[9]~~ 'pin the ADC routine thinks the microphone is connected to (demo board)
x := clkfreq / SampRate
repeat
p := @wav1 + 44
time := cnt
repeat while p++ < @wav1_end
outa[9] := p
' wait to simulate sample rate
waitcnt(time += x)
DAT
wav1 byte
File "be_back.wav"
wav1_end byte 0
Comments
This just outputs the LSB of the referred-to byte. That's why you're hearing white noise. You need to configure a counter in DUTY mode that outputs to pin 9. Then write the waveform value to frqx.
(You may need to use a different output pin, along with an RC filter between that and pin 9. I've forgotten how the mic input on the demo board is wired.)
-Phil
PUB fakeMic |p,time,x,txpin txpin := 9 dira[txpin]~~ 'pin the ADC routine thinks the microphone is connected to CTRA := %00110 << 26 | txpin 'Duty single ended mode x := clkfreq / SampRate repeat p := @wav1 + 44 time := cnt repeat while p++ < @wav1_end FRQA := byte[p] ' wait to simulate sample rate waitcnt(time += x)
CON SampRate = 11_025 PUB fakeMic |p,time,x ctra := %00110 << 26 + 9 'DUTY output on pin 9 dira[9]~~ 'pin the ADC routine thinks the microphone is connected to (demo board) x := clkfreq / SampRate repeat p := @wav1 + 44 time := cnt repeat while p++ < @wav1_end frqa := byte[p] << 24 'write sample to DUTY modulator ' wait to simulate sample rate waitcnt(time += x) DAT wav1 byte File "be_back.wav" wav1_end byte 0
Andy
What you need to do is pry the microphone out of its socket. Then connect a different port pin (e.g. P7) to an RC lowpass filter. The counter's DUTY mode output should be directed to this pin. The output of the RC filter should connect to the lower pin of the mic socket. This can be done via a 1/8 watt resistor, since it has skinny leads that will fit the socket. The other end of the resistor should be doubled over and pinched tight so it can make contact with the RC filter in the breadboard area.
-Phil
FRQA := byte[p] << 24
the 8 bit sample must be at the top 8 bits of FRQA. Sorry - I have edited that in my previous post.@Phil
He uses a Quickstart board not a Demoboard.
Andy
The first post states it is a demo board. I can't find that it was changed to a QuickStart?
I'm using a quickstart, which I put in the thread title.
I wrote in the OP that the program had been written for the demoboard
Sorry for the confusion.
>What you need to do is pry the microphone out of its socket.
If I had an actual Demoboard, I wouldn't need a "fakeMic"
-Phil
Where are you getting those from ?
The "ADC circuitry" is just the prop itself. (doing Sigma-Delta ADC) per the app note : AN001-P8X32ACounters-v2.0.pdf (pg 17 ... which looks very similar to Beau's code (maybe he wrote *that* too ?)
>You still can't output to P8 or P9, since they are part of the ADC circuitry. You >will have to output your DUTY mode counter to another pin, then connect that >pin to the input terminal of J8.
Output from one COG to the same pin another COG is reading was going to be the subject of another thread, or maybe a question I was going to ask in my OP.
But I did some very slow tests with writing / reading to the same pin from two cogs and it seemed to be working.
If that is the problem, then maybe that's why this is not working ?
@ariba -
FRQA := byte[p] << 24
wasn't the "magic fix" I neededMike
You can do that, but not here. The reason is that you have to convert from digital to analog, before you can convert back to digital. That series resistor from the input pin of J8 is important.
I assume, when you mean "fake the microphone input" that that's what you want to do. But if you just want to play a tune from your wave file, there are easier ways to go about it, since it's already in digital format.
-Phil
But it makes not much sense to go over a DAC -> ADC on a Pin just to use a premade object. If you look how the Phase is modulated in Beau's object then it's just an addition of the signal to the PHSx register. So you can modulate the phase directly from the samples like that:
{{ Phase Modulation from a WAV file }} CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 Freq = 900_000 'Carrier frequency OutPin = 11 'Pin that outputs moduladet carrier ModInt = 3 'Modulation Intensity 0..23 PUB Main | x,p,time Synth(OutPin, Freq) 'set NCO out with Freq dira[OutPin] := 1 'enable output on Pin x := clkfreq / 11_025 time := cnt repeat p := @wav1 + 44 repeat while p++ < @wav1_end phsa += byte[p] << ModInt 'phase modulate Freq output waitcnt(time += x) DAT wav1 file "be_back.wav" wav1_end byte 0 PUB Synth(Pin_, Freq_) | s, d Freq_ := Freq_ #> 0 <# 128_000_000 'limit frequency range if Freq_ < 500_000 'if 0 to 499_999 Hz, CTRA := constant(%00100 << 26) '..set NCO mode s := 1 '..shift = 1 else 'if 500_000 to 128_000_000 Hz, CTRA := constant(%00010 << 26) '..set PLL mode d := >|((Freq_ - 1) / 1_000_000) 'determine PLLDIV s := 4 - d 'determine shift CTRA |= d << 23 'set PLLDIV FRQA := fraction(Freq_, CLKFREQ, s) 'Compute FRQx value CTRA |= Pin_ 'set PINA to complete CTRx value PRI fraction(a, b, shift) : f if shift > 0 'if shift, pre-shift a or b left a <<= shift 'to maintain significant bits while if shift < 0 'insuring proper result b <<= -shift repeat 32 'perform long division of a/b f <<= 1 if a => b a -= b f++ a <<= 1
I don't have a receiver for the modulated carrier, so I can't really test it. There may well be some little mistake somewhere in the posted code.Andy
-Phil
-Phil
>I don't have a receiver for the modulated carrier, so I can't really test it.
I'm just using a cheap am/fm "clock" radio (prob ~30 years old), doncha have one of those ?
>But it makes not much sense to go over a DAC -> ADC on a Pin just to use a premade object. If you look how the Phase is modulated in Beau's object then it's just an addition of the signal to the PHSx register. So you can modulate the phase directly from the samples like that
This was part of a "greater plan"
I've been trying to find or write a "generic" radio transmitter object than I can "hook" into any of the audio objects in the Obex or prop library.
I.e. the Sidcog, SneCog, morse etc.
So far the following code works (kinda) with SneCog but only with one "channel" (left or right) at a time.)
With SidCog I just hear noise though.
It is from Pedward's demo-direct-2m-fm-broadcast-modulation-with-the-propeller" code
That code btw is so far the "gold standard" for playing a wav file over the radio !
With NO TRANSMITTING antenna, my cheap clock radio gets an almost crystal clear / no static signal from anywhere in my tiny condo !
I guess?? the wav file is MUCH "cleaner" than the SneCog / Sidcog ??, or is it more likely an incompatibilty with the way I'm trying to use the counter's PLL mode ?
Instead of playing a wav file like this :
Con _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 SAMPRATE = 11_025 PUB FmTransmit |p,x,time CTRA := %00010_111 << 23 | txpin '+ 0 'PLL SingleEnded x := clkfreq / SampRate repeat p := @wav1 '+ 44 time := cnt repeat while p++ < @wav1_end ' just continue from one 'File to next FRQA := magicnum + byte[p] << Vol ' 10 '10 seems best waitcnt(time += x) DAT wav1 byte 'File "be_back.wav" wav1_end byte 0
I'm transmitting the SneCog with this :
..... as above code block till repeat repeat p := INA[rightPin] ' or leftpin time := cnt FRQA := magicnum + byte[p] << Vol ' 10 '10 seems best waitcnt(time += x)
Beau's Adc object was just another code example I thought might be doing something differently than other objects I have looked at.
I have read the prop manual, and the AN001-P8X32ACounters-v2.0.pdf, and have searched / read every example I can find on how to do modulation with the counters.