|
Forum Index : Microcontroller and PC projects : Produce wobble tones
| Author | Message | ||||
| Frank N. Furter Guru Joined: 28/05/2012 Location: GermanyPosts: 1060 |
Hi, I would like to set up a simple hearing test and need to generate wobble tones ranging from 125 Hz to 8 kHz. The frequency sweep should cover approximately 4% to 12.5% of the centre frequency, and the modulation frequency should be around 8 Hz, following a triangular waveform. Can I achieve this using an Picomite, and if so, how? Frank |
||||
| phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 3078 |
Would something like this be adequate? do :for n=900 to 1100:play tone n,n: pause 5:next :for n=1100 to 900 step -1:play tone n,n: pause 5:next :loop I don't have an amplifier set up at the moment so can't hear the result but it runs without error. Edited 2026-03-17 20:47 by phil99 |
||||
| Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 5795 |
Hi Phil, Your modulation frequency is 0.5Hz (200 steps @5ms x2). Frank, is there a requirement for output ? sine wave ? square wave ? I have a program to create a function generator, using an external resistor network as a DAC. The waveform is mathmatically calculated, so the math should be capable of calculating the desired waveform, and you "stream it" out. The waveform is a MMbasic array, by tuning the PIO frequency you "wobble". This (most likely, not tested) can be achieved by direct writing to the PIO frequency divider (not by re-initializing the PIO, becuase that would generate clicks). This is the code 'test HW for sine wave generator using DMA and PIO 'there is a flaw: the DMA stops after 2^32 sine samples 'this is running in basic bits% = 8 length% = 4096 'allows up to 16kHz full resolution 'Dim o%(length%-1) level=2^(bits%-1)*0.9 'amplitude of sine signal 'calculate sinewave table 'calc_sin 'pack data in ring buffer Dim pkd% PIO make ring buffer pkd%,length%*8 'length in 32 bit fifo values 'PIO make ring buffer pkd%,length%*4 'length in 32 bit fifo values 'PIO make ring buffer pkd%,length% 'length in 8 bit fifo values 'pio pins SetPin gp6,pio1 SetPin gp7,pio1 SetPin gp8,pio1 SetPin gp9,pio1 SetPin gp10,pio1 SetPin gp11,pio1 SetPin gp12,pio1 SetPin gp13,pio1 'pio program PIO assemble 1,".program out" PIO assemble 1,".line 0" PIO assemble 1,"mov osr ,!null" 'fill osr with &hffffffff PIO assemble 1,"out pindirs,8" 'set all associated pins (8) output PIO assemble 1,".wrap target" PIO assemble 1,"pull noblock" 'get data from fifo PIO assemble 1,"out pins,8" 'write out to 7(8) pins PIO assemble 1,"out pins,8 [1]" 'write out to 7(8) pins delay 1 --- 8bit transfers only PIO assemble 1,"out pins,8 [1]" 'write out to 7(8) pins delay 1 --- 8bit transfers only PIO assemble 1,"out pins,8 [1]" 'write out to 7(8) pins delay 1 --- 8bit transfers only PIO assemble 1,".wrap" PIO assemble 1,".end program"' list" 'pio config f=133e6 'modify this value to tune to other frequencies p=Pio(pinctrl 0,0,bits%,,,,gp6) e=Pio(execctrl gp0,Pio(.wrap target),Pio(.wrap)) s=Pio(shiftctrl 0,0,0,0,0,1) 'here we do UI and create sine waves Do 'input frequency Input "what frequency ";x y%=1+x/16000 'y%=number of sine cycles in one buffer f=x*2*length%/y% Print x,y%,f 'Timer = 0 'stop running machine If MM.Info(PIO TX DMA)=1 Then PIO dma tx off 'calculate sinewave table 'calc_sin 'Memory pack o%(),pkd%(),length%,32 'fill it with values from the sine wave 32 bit 'Memory pack o%(),pkd%(),length%,8 'fill it with values from the sine wave 8 bit calc_sin_pkd 'restart machine PIO init machine 1,0,f,p,e,s,0 PIO dma tx 1,0,&hffffffff,pkd%(),help,,length% '32 bit transfers 'PIO dma tx 1,0,&hffffffff,pkd%(),help,,length%/4 '8 bit transfers Loop End Sub help 'Print "stopped after ";Timer;" ms" PIO stop 1,0 End Sub Sub calc_modsin 'calculate sinewave table For i=0 To length%-1 alpha=i*2*Pi/length% o%(i)=Int(level*(1.1+(Sin(y%*alpha))*Sin(alpha)*Sin(alpha))) Next End Sub Sub calc_sin 'calculate sinewave table For i=0 To length%-1 o%(i)=Int(level*(1.1+Sin(y%*i*2*Pi/length%))) Next End Sub Sub calc_sin_pkd 'calculate sinewave table directly in pkd%() For i=0 To length%-1 pkd%(i)=0 For j=0 To 3 pkd%(i)=pkd%(i)+(Int(level*(1.1+Sin(y%*(i*4+j)*2*Pi/length%))))<<(j*8) Next j Next i End Sub End Volhout Edited 2026-03-17 21:10 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
| phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 3078 |
I was just seeing if the concept is any good, rather than using realistic numbers. The pause can be reduced or perhaps eliminated depending on the time Play Tone takes to change frequency. The frequency steps could also be increased to further increase the modulation frequency. > timer=0:for n=900 to 1100 step 3:play tone n,n: pause 1:next :for n=1100 to 900 step -3:play tone n,n: pause 1:next:? timer 136.828 > 8 Hz=125mS so not far off, provided it actually sounds ok. Edited 2026-03-17 21:18 by phil99 |
||||
| Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 5795 |
Frank, But if you can work with a square wave, you could also direct write to the PWM divider register when the PWM is put in "symmetrical mode" using MMbasic commands. Phils solution is even simpler.... Volhout Edited 2026-03-17 21:20 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
| Frank N. Furter Guru Joined: 28/05/2012 Location: GermanyPosts: 1060 |
Thank you very much for your suggestions! It is supposed to be a sine wave that lies within a triangular envelope. It should sound something like this in the end: https://hearingtest.online/ This code, which is based on the code from phil99, sounds quite similar: Do Play volume 100,100 For z=1 To 4 For n=980 To 1020 Play tone n,n Pause 2 Next For n=1020 To 980 Step -1 Play tone n,n Pause 2 Next Next z Play volume 0,0 'Play stop Pause 200 Loop That should be 4% at 1 kHz. The problem is the 'pop' when the sound is turned off. I suppose I’ll have to take a look at that with an oscilloscope... Frank |
||||
| Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 5795 |
Hi Frank, What version firmware are you using. I know Peter adapted the play tone command to exit with a soft silence (no plop) between 5.09.00 and 6.01.00. But maybe that is changed now the sample calculation is taken out of the HW interrupt (the problem in 60201 rc4,5,6). Or maybe it is caused by VOLUME cutting off hard. Volhout Edited 2026-03-17 22:17 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
| Frank N. Furter Guru Joined: 28/05/2012 Location: GermanyPosts: 1060 |
Hi Volhout, I am currently using version V6.02.01RC2. It seems to work better with Play tone 0,0 instead of Play volume 0,0. I can't tell the difference between Play stop and Play volume 0,0. I hear the 'pop' in both versions. Frank |
||||
| Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 5795 |
Frank, Don't try rc4 or newer. I posted Peter with the result. PLAY STOP is not as good as VOLUME 0,0. Actually volume 0,0 is perfect. PLAY STOP has minimal artefacts. But both do not show large DC jumps (actually tested on 602.00rc8). Just confirmed: 60201rc2 works identical to 60200rc8. Volhout Edited 2026-03-17 22:54 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
| The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2026 |