Spin Semiconductor Forum Index Spin Semiconductor
Support forum
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Any thoughts on implementing an "infinite hold" ef
Goto page Previous  1, 2, 3  Next
 
Post new topic   Reply to topic    Spin Semiconductor Forum Index -> Algorithm development
View previous topic :: View next topic  
Author Message
frank



Joined: 19 Oct 2005
Posts: 958

PostPosted: Fri Feb 19, 2010 10:40 am    Post subject: Reply with quote

If you tried to reply to the email notification that will not work, you must log into the web site and reply from the message there.
_________________
Frank Thomson
Experimental Noize
Back to top
View user's profile Send private message Visit poster's website
livingston



Joined: 15 Nov 2009
Posts: 131
Location: New Orleans, LA US

PostPosted: Sat Feb 20, 2010 5:03 pm    Post subject: Reply with quote

Don, I had a chance to try your algo. First, your second equate statement:

;equ lpin reg1 ; filtered input

has a semicolon in front of it which needs to be deleted for things to work right.

As can be expected of this kind of thing, the tracking on a bass isn't great. Tracking a bass is notoriously difficult, so it would need some tweaking to get something useful out of it in that case. But it's definitely a start in the right direction. I'll tack a "MULX POT0" into the frequency register to see if we can get a pitch shift control, might be fun.

Thanks for the code, it'll be a great starting point for experiments with pitch tracking.

Edit:noticed another problem: you have 2 things equated to REG13. That probably explains why I was getting weird distortion - the output signal and ENVFIL were equated to the same register. I don't know why the assembler didn't catch that, seems like it shouldn't let you do that.
Back to top
View user's profile Send private message
donstavely



Joined: 07 Jan 2010
Posts: 50
Location: Windsor, Colorado

PostPosted: Sun Feb 21, 2010 6:52 am    Post subject: Reply with quote

On the bass, I agree that the problem is harder. The lower frequencies are tougher in general - longer periods mean more noticeable errors and delays, since samples are sparse. I was testing only down to low E on guitar. The decay constant on the upper and lower envelope followers is the main knob you have to turn to try to scale another octave down.

The equate of the "lpin" variable was commented out because it isn't used. I tried putting a low-pass filter on the incoming signal to attenuate the 2nd harmonic to improve tracking. I didn't seem to make much difference, so I took out the code, but forget to delete the equate.

You may want to try putting the LP filter back in again for the bass. You could set the corner frequency below your lowest note and operate "on the slope". The falling amplitude at higher frequencies doesn't affect the pitch detection, as long as there is enough signal left. Then you get a 6dB reduction in 2nd harmonic across the board. Come to think of it, make it a shelving filter, so you still get some amplitude at the high end of the fretboard. The pitch detector seems to do better at the high end as it is, so it doesn't need as much "help" from the filter. I think I will try it again for guitar.

Similarly, the "envfil" variable isn't used. I was trying to filter the envelope more before applying it to the sine to clean up the sound of the demo, but I wound up tossing the code out. (It was sloppiness to leave the equate in, I was rushing a bit to add the demo oscillator code before posting.)

I think the assembler doesn't check for multiple equates because some users may want to reuse registers in their code - risky and error-prone, but maybe useful.
_________________
Don Stavely
Back to top
View user's profile Send private message
djmalan



Joined: 06 Mar 2009
Posts: 36

PostPosted: Thu Mar 04, 2010 3:51 am    Post subject: Reply with quote

Hi ,donstavely ,I m interested in your code .I have a question;
Quote:
; Need to convert period to frequency
;
rdax avper, 1 ; get smoothed period
log -1, -0.49 ; need 1/X, the offset scales frequency
exp 1, 0 ; linear frequency
wrax freq, 0 ; save it

if I didn't miss understand this is for 1 octav down or divide by two ,isn't it?
if it's true ,how can I calculate by divide 4 and 8 or canbe said 2 and 3 octave down.
Back to top
View user's profile Send private message
donstavely



Joined: 07 Jan 2010
Posts: 50
Location: Windsor, Colorado

PostPosted: Thu Mar 04, 2010 7:00 am    Post subject: Reply with quote

- "avper" is linear period in unit of time.
- take the log of this to get log period (with the FV-1 caveats about scaling)
- negate this to get log frequency (remember, we are in log space)
- add or subtract a constant from this to scale frequency (still doing log math)
- take the exp of this to get back to linear frequency (again with the caveats about scaling)

The constant I used for the demo was pretty arbitrary - just a number that causes a frequency shift. Frankly, it hurt my head to try to do the math to come up with exact numbers, but it shouldn't be impossible. If you find a constant in the log statement that matches the input pitch, then there will be a second constant that gives an octave up. Then that same interval, added or subtracted (in log space still) will give octaves up or down. (Remembering that multiplies and divides in linear space become adds and subtracts in log space.)

I don't recommend this code as a way to do pitch transposition. It is monophonic, and not perfectly reliable in tracking. It would be better to do the delay-and-ramp pitch transpose for real music signals.

People have tried to do an actual guitar synth using a pitch-to-voltage converter to drive VCO's, with a note trigger driving ADSR's, VCA's, VCF's. I am not sure how "playable" it would be.
_________________
Don Stavely
Back to top
View user's profile Send private message
soundsubs



Joined: 25 Feb 2011
Posts: 24

PostPosted: Wed Mar 02, 2011 8:16 am    Post subject: Reply with quote

...any update on this?

i myself would love to see a "freeze" effect where a single cycle sample from the input is looped until a knob is twisted past a certain value or something like that.
from there we could also mess with playback speed.
Back to top
View user's profile Send private message Send e-mail
donstavely



Joined: 07 Jan 2010
Posts: 50
Location: Windsor, Colorado

PostPosted: Thu Mar 03, 2011 6:45 am    Post subject: Reply with quote

I have not worked on this in a while. First, I switched to a delay-based approach so avoid tracking issues and the single-note limitation. Seancostello's suggestion earlier in this thread is the most promising approach. Second, Electro-Harmonix came out with the Freeze. This is exactly the effect that I was going for.

Sorry,
Don
_________________
Don Stavely
Back to top
View user's profile Send private message
soundsubs



Joined: 25 Feb 2011
Posts: 24

PostPosted: Tue Mar 08, 2011 7:48 pm    Post subject: Reply with quote

getting close to nailing this, but its constantly outputting the same delay time, about 1 second, even though i defined mem at 65. ive tried all sorts of values, nothing changes the time.


; this is borrowed heavily from the delay/play alg posted by frank
; meant to be a "freeze" effect where it samples input and
; outputs a shortened loop of the input audio, near a single cycle.
; If POT0 is 0 to 0.5 we are in record mode
; If 0.5 to 0.999 we are in playback mode
;
delL mem 65 ; Define delay as really really small
ldax pot0 ; Read in POT0
sof 1.0,-0.5 ; Add -0.5 to the POT0 value so it ranges -0.5 to +0.5
skp gez,play ; If ACC is >=0 we are in playback mode so jump to play
ldax adcl ; Read in ADC left
wra delL,1.0 ; Write to left delay line
wrax dacl,0 ; and to DAC left
skp zro, end ; Jump to end
;
; Play back mode
play:
clr ; Clear ACC
rda delL#,1.0 ; Read tail of left delay
wrax dacl,0 ; Write it to DAC left
;
end:
Back to top
View user's profile Send private message Send e-mail
frank



Joined: 19 Oct 2005
Posts: 958

PostPosted: Tue Mar 08, 2011 8:11 pm    Post subject: Reply with quote

(Not in office so haven't tried the changes so may be a typo in it but the logic is correct...)

You are working with a single circular buffer in memory in this case so you want to clear the end of the buffer each cycle so you could try:

delL mem 65 ; Define delay as really really small
ldax pot0 ; Read in POT0
sof 1.0,-0.5 ; Add -0.5 to the POT0 value so it ranges -0.5 to +0.5
skp gez,play ; If ACC is >=0 we are in playback mode so jump to play
ldax adcl ; Read in ADC left
wra delL,1.0 ; Write to left delay line
wrax dacl,0 ; and to DAC left
wra delL#,0 ; write 0 at end of delay line to limit record length
skp zro, end ; Jump to end
;
; Play back mode
play:
clr ; Clear ACC
rda delL#,1.0 ; Read tail of left delay
wrax dacl,0 ; Write it to DAC left
;
end:


But there is a problem with this because it still plays through the entire memory so we hear a short period of sound so we need to also limit the playback to only the buffer area:

delL mem 65 ; Define delay as really really small
ldax pot0 ; Read in POT0
sof 1.0,-0.5 ; Add -0.5 to the POT0 value so it ranges -0.5 to +0.5
skp gez,play ; If ACC is >=0 we are in playback mode so jump to play
ldax adcl ; Read in ADC left
wra delL,1.0 ; Write to left delay line
wrax dacl,0 ; and to DAC left
wra delL#,0 ; write 0 at end of delay line to limit record length
skp zro, end ; Jump to end
;
; Play back mode
play:
clr ; Clear ACC
rda delL#,1.0 ; Read tail of left delay
wra delL,1.0 ; Write to head of delay
wrax dacl,0 ; Write it to DAC left
wra delL#,0 ; write a 0 to end of delay, not really needed but will make sure rest of memory is 0 if you add other functions
;
end:
_________________
Frank Thomson
Experimental Noize
Back to top
View user's profile Send private message Visit poster's website
soundsubs



Joined: 25 Feb 2011
Posts: 24

PostPosted: Tue Mar 08, 2011 9:31 pm    Post subject: Reply with quote

thanks for the reply, frank.

this doesnt really work. this loops a pitched waveform that sounds a lot like a sine wave and which is usually the same thing despite various input sounds.
ive played with it for 15 minutes or so and i would say 80% of the time it puts out the same sine wave.

i toggle between PLAY and PASSTHRU
Back to top
View user's profile Send private message Send e-mail
frank



Joined: 19 Oct 2005
Posts: 958

PostPosted: Tue Mar 08, 2011 9:55 pm    Post subject: Reply with quote

I'll try to code in the office tomorrow but try making the delL length much longer (i.e. 8192), 65 is really short
_________________
Frank Thomson
Experimental Noize
Back to top
View user's profile Send private message Visit poster's website
soundsubs



Joined: 25 Feb 2011
Posts: 24

PostPosted: Wed Mar 09, 2011 7:11 am    Post subject: Reply with quote

doh you did it!
a length of 2048 or 1024 is great for this!

now to make pot1 determine length of buffer and i'll post it back.
Back to top
View user's profile Send private message Send e-mail
soundsubs



Joined: 25 Feb 2011
Posts: 24

PostPosted: Wed Mar 09, 2011 7:29 am    Post subject: Reply with quote

ok i did something wrong.
now sound cuts off after pot0 goes above 0

Code:
; this is borrowed heavily from the delay/play alg posted by frank
; meant to be a "freeze" effect where it samples input and
; outputs a shortened loop of the input audio, near a single cycle.
; If POT0 is 0 to 0.5 we are in record mode
; If 0.5 to 0.999 we are in playback mode
;
delL mem 2048    ; Define delay as kinda small
ldax pot0    ; Read in POT0
sof 1.0,-0.5    ; Add -0.5 to the POT0 value so it ranges -0.5 to +0.5
skp gez,play    ; If ACC is >=0 we are in playback mode so jump to play
ldax adcl    ; Read in ADC left
wra delL,1.0    ; Write to left delay line
wrax dacl,0    ; and to DAC left
wra delL#,0    ; write 0 at end of delay line to limit record length
skp zro, end    ; Jump to end
;
; Play back mode
play:
clr       ; Clear ACC
ldax pot1   ; read POT1 value
wrax reg0,1   ; write the value to reg0, save it for later
rda delL#,1    ; Read tail of left delay
mulx reg0   ; multiply this * reg0 which is pot1
wra delL,1    ; Write to head of delay
wrax dacl,0    ; Write it to DAC left
wra delL#,0    ; write a 0 to end of delay, not really needed but will make sure rest of memory is 0 if you add other functions
;
end:
Back to top
View user's profile Send private message Send e-mail
frank



Joined: 19 Oct 2005
Posts: 958

PostPosted: Wed Mar 09, 2011 9:12 am    Post subject: Reply with quote

Now, I'm going to be a bit of a pain here Wink and force you to do two thing:

First, you don't say what you are trying to do with pot 1. I can tell from the code but making you get in the habit of explicitly stating the intent of any input or controller, helps a lot for others to help debug.

Second, the problem is here:
wrax reg0,1 ; write the value to reg0, save it for later

Consider what is going into the accumulator, what you are doing in the next instruction and what you need to change in this 'wrax' line.
_________________
Frank Thomson
Experimental Noize
Back to top
View user's profile Send private message Visit poster's website
soundsubs



Joined: 25 Feb 2011
Posts: 24

PostPosted: Wed Mar 09, 2011 4:54 pm    Post subject: Reply with quote

well i was able to comply with the first one easy enough.
i really dont know what to do, other than change the line ahead of it, but thats not what i want either.

Code:
; this is borrowed heavily from the delay/play alg posted by frank
; meant to be a "freeze" effect where it samples input and
; outputs a shortened loop of the input audio, near a single cycle.
; If POT0 is 0 to 0.5 we are in record mode
; If 0.5 to 0.999 we are in playback mode
; POT1 will be used to determine length of delay buffer that is read.
;
delL mem 2048   ; Define delay as kinda small
ldax pot0       ; Read in POT0
sof 1.0,-0.5    ; Add -0.5 to the POT0 value so it ranges -0.5 to +0.5
skp gez,play    ; If ACC is >=0 we are in playback mode so jump to play
ldax adcl       ; Read in ADC left
wra delL,1.0    ; Write to left delay line
wrax dacl,0     ; and to DAC left
wra delL#,0     ; write 0 at end of delay line to limit record length
skp zro, end    ; Jump to end
;
; Play back mode
play:
clr          ; Clear ACC
rdax pot1,1     ; read POT1 value
wrax reg0,1      ; write the value to reg0, save it for later
rda delL#,1       ; Read tail of left delay
mulx reg0      ; multiply this * reg0 which is pot1
wra delL,1       ; Write to head of delay
wrax dacl,0       ; Write it to DAC left
wra delL#,0       ; write a 0 to end of delay, not really needed but will make sure rest of memory is 0 if you add other functions
;
end:
Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic   Reply to topic    Spin Semiconductor Forum Index -> Algorithm development All times are GMT - 8 Hours
Goto page Previous  1, 2, 3  Next
Page 2 of 3

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group