todd@ivucsb.sba.ca.us (Todd Day) (09/25/89)
Here is that crappy pitch shifter I was talking about. It's simply a circular buffer that has another pointer walking through it at a different rate. This was not written by me originally, but I converted it for use in a stereo sampling system. Explanation at end. ;********************************************************** ; ; Frequency Scaler ; This program implements a frequency scaler. It will attempt ; to take the input and provide and output which has its ; frequency scaled by the factor alpha. It does this by ; reading the input in sections and outputting the samples ; at a rate of alpha times the input rate. If alpha is < 1, ; the output frequencies are slowed, and some of the signal ; is lost. If alpha > 1, the output frequencies are sped up, ; and some of the signal is repeated. ; ; Daniel Howell ; 3 Jun 1988 ; ECE 148 ; ; Modified to run in stereo by Todd Day ; ;********************************************************** page 79,66,1,1 include 'defs.inc' include 'ioequ.inc' include 'intequ.inc' buffer equ $0000 ; beginning of buffer L equ 2048 ; buffer length (multiple of 2!) savea0 equ buffer+L ; place to save a register savea1 equ savea0+1 savea2 equ savea1+1 pointer equ savea2+1 ; pointer to buffer ; **************************************** ; SSI receive data vector ; do long interrupt (save stack and ccr) org p:i_ssird jsr dofreq ; **************************************** ; begin program ; org p:pgmram ; setup SSI and others include 'setup.asm' move #buffer,r6 ; r6 points to input of buffer move #L-1,m6 ; mod L addressing move #>1.0/2048,x0 ; alpha (scaling factor) move #buffer,r4 ; r4 points to output of buffer move #L-1,m4 ; mod L addressing clr a #0,n4 ; initialize pointer move a,l:pointer move #L-1,y0 ; mask for mod L update of pointer ; start interrupts movep #$b200,x:m_crb andi #$00,mr ; **************************************** ; monitor the keyboard for changes in alpha ; uses b include 'monitor.asm' ; compare key hit to 'i', get incr, get ready for 'd' move #'i',x1 move #>(1.0/16)/2048,y1 cmp x1,b #'d',x1 jne d ; increment alpha by 1/16 move x0,b add y1,b move b,x0 ; print b in decimal pdec do #12,pdec1 ;get ones place asl b pdec1 jsr pnum ;print number in b2 as ASCII move #'.',a ;print decimal place jsr pwait tfr b,a ;get tenths place do #4,pdec2 ; * 5 add a,b pdec2 asl b ; * 2 jsr pnum tfr b,a ;get hundredths place do #4,pdec3 ; * 5 add a,b pdec3 asl b ; * 2 jsr pnum tfr b,a ;get thousandths place do #4,pdec4 ; * 5 add a,b pdec4 asl b ; * 2 jsr pnum crlf move #13,a ;CR jsr pwait move #10,a ;LF jsr pwait jmp getch ; print number in b2 to serial port as ASCII pnum move b2,a move #>'0',x1 add x1,a #0,b2 do #16,pwait lsl a pwait jclr #m_tdre,x:m_ssr,pwait movep a,x:m_srxh rts ; compare key hit to 'd' d cmp x1,b jne crlf ; decrement alpha by 1/16 move x0,b sub y1,b move b,x0 jmp pdec ; **************************************** ; do frequency shifting ; which channel input? ; when SCO is low, we get left channel data dofreq jclr #m_if0,x:m_sr,left ; **************************************** ; right channel ; right move a2,x:savea2 ; save a register move a1,x:savea1 move a0,x:savea0 movep x:m_rx,a ; get an input sample move a,y:(r6)+ ; store input sample (update pointer) move y:(r4+n4),a ; get output sample movep a,x:m_tx ; output a sample ; ; pointer update - get ready for left channel (it is first in data stream) ; move l:pointer,a ; grab pointer add x0,a ; add alpha to pointer rep #12 ; shift so a1 contains integer part asr a and y0,a ; modulo L move a1,n4 ; update pointer rep #12 ; shift back asl a move a,l:pointer ; save pointer nop resta move x:savea2,a2 ; restore a register move x:savea1,a1 move x:savea0,a0 rti ; **************************************** ; left channel ; left move a2,x:savea2 ; save a register move a1,x:savea1 move a0,x:savea0 movep x:m_rx,a ; get an input sample move a,x:(r6) ; store input sample move x:(r4+n4),a ; get output sample movep a,x:m_tx ; output a sample jmp resta ; restore a register end pgmram You do not need the include files... they are for setting up MY particular system (you can get them off my archive server, though; send the following lines to dsp@ivucsb.sba.ca.us send README send HOWTO to get them). You can get rid of a large part of the code in the center. I am simply monitoring the serial port for keys hit so I can change the pitch shifting on the fly. It also prints out over the serial port the alpha value currently being used. Note that the code for the left channel does not do the update. You can nuke it if you want to do mono. The alpha value determines the frequency multiplication. If you set it to 1.25, you increase the pitch by 25%, and if you set it to 0.75, you decrease the pitch by 25%. Note: this method has serious clicking problems, especially at low values of alpha. You can make it better by changing the buffer length. -- Todd Day | todd@ivucsb.sba.ca.us | ivucsb!todd@anise.acc.com "It takes a smart man to know when he's stupid." - Barney Rubble
cyamamot@castor.usc.edu (Cliff Yamamoto) (09/25/89)
In article <1989Sep25.074206.972@ivucsb.sba.ca.us> todd@ivucsb.sba.ca.us (Todd Day) writes: >This was not written by me originally, but I converted it >for use in a stereo sampling system. > ^^^^^^^^^^^^^^^^^^^^^^ >[code deleted]... > >You can get rid of a large part of the code in the center. I am >simply monitoring the serial port for keys hit so I can change ^^^^^^^^^^^^^^^ >the pitch shifting on the fly. It also prints out over the serial >port the alpha value currently being used. Todd, Did you assemble this "system" yourself? I'd like to get into DSP, but is it really necessary that I spend >$1K to have such a system? I have an AT compatible and I really don't need to have a stand-alone system (like yours with a serial port). Does anyone out there have a 56001 system running on an AT platform that they built/bought for under $1K? Does adding a second pair of ADC/DAC's for stereo increase the cost/complexity a lot? Since I don't have any 56000 data sheets can you tell me what's the difference between the 56000 and the 56001? Thanks for any info! Cliff
mhorne@ka7axd.WV.TEK.COM (Michael T. Horne) (09/26/89)
> compatible and I really don't need to have a stand-alone system (like yours > with a serial port). Does anyone out there have a 56001 system running on > an AT platform that they built/bought for under $1K? If you're looking for a board for the PC to experiment with (assuming you don't want to build one yourself), you can pick up the PC-56 from Ariel. I believe it costs $595 w/o the TI codec option (add $100 for this option). Actually, I suspect you can buy the codec for very little money from a distributor and save yourself the extremely overpriced option that Ariel provides. If you're looking for `CD quality' audio, I suggest you stay away from the codec entirely (it is exactly that; a codec, narrow bandpass and all...). The PC-56 has a wide socket on the board for external peripherals providing access to the 56K's data/address bus. I'd suggest wiring up a separate board for acquisition, preferably external to the PC box with a separate supply, since the PC is loaded with RF and noisy supply lines. If you don't want to spend that much, and you feel you can handle a wire-wrap gun and soldering iron, I'd suggest wire-wrapping a system on a board that drops into the PC. I've done exactly that for a project I'm working on, and its fairly straightforward. If you don't expect to have/need any external RAM (at least for a while), you can really save a lot of time and effort. You should be able to put together a system with 16Kx24 RAM for < $200 bucks, perhaps < $100 in a `stripped down' version. > Does adding a second > pair of ADC/DAC's for stereo increase the cost/complexity a lot? Complexity, no. Cost, probably, depending on the quality of the ADC/DACs that you use. You should be able to configure two complete, good quality, 12-bit channels (both directions) for < $50 extra. Prices rise quickly for more bits. I'd suggest looking at Moto's new S/D ADC (the 56ADC16) which will provide you with clean, 16-bit input at 100KHz (and it interfaces nicely to the 56K). If you are planning on keeping the acquisition circuit internally within the PC, using more than 12 bits may be moot unless you take great care in layout and cleaning up the supply lines. Mike
dean@image.soe.clarkson.edu (Dean Swan) (09/26/89)
> Did you assemble this "system" yourself? I'd like to get into DSP, but is > it really necessary that I spend >$1K to have such a system? I have an AT > compatible and I really don't need to have a stand-alone system (like yours > with a serial port). Does anyone out there have a 56001 system running on > an AT platform that they built/bought for under $1K? Does adding a second > pair of ADC/DAC's for stereo increase the cost/complexity a lot? Well, there are two companies that I can think of to get you going on this. First, Turtle Beach Softworks has announced a 56k card for the AT. I don't know the price off hand, but it's a place to start. Second, a company called Spectral Synthesis makes a system based on TI's 32C020. Each of their cards has two DSP's on board, and you can connect up to seven cards in a system. They can get you going for about $2000, but when I last saw their software, about eight months ago, they were not ready to ship just yet. Their software is called AudioCAD, and basically it lets you connect fundamental blocks (mixers, amplifiers, etc.) graphically under windows, then it compiles the code and assigns it to the bank of DSP's. Their big goal is real time processing, so the have a neat set of resource allocation routines, and process scheduling system to best use however many DSP's you have in your system. A full blown system is about $10k. Oh, and you can write your own primatives too. -Dean Swan dean@sun.soe.clarkson.edu
dean@image.soe.clarkson.edu (Dean Swan) (09/26/89)
Todd, Have you considered using a sample rate conversion filter to do your pitch shifting? To increase the pitch you'd also have to low-pass filter the original to prevent nyquist aliasing, and use the sample rate converter to generate a lower sample rate. Then just output the new samples at the same rate. To decrease pitch, you can skip the low-pass and use the conversion filter to generate a higher sample rate, then just play it back at the same old speed. This method would tend to sound Mickey Mouse-y or Darth Vader-like if you do any extreme pitch shifting, and it's also subject to time compression and expansion problems proportional to the amount of pitch shifting, but it would give the "smoothest" (I hesitate to say "best" because the time compression could be unaccecptable) sounding results. Here's another possibility, which may or may not work: Assume that your input is of the form: Y=Sin( F*A ) Then F = ArcSin(Y)/A Next do F=F+pitch shift amount and reconstruct with Y=Sin(F*A). I've been doing a lot of work with FM synthesis, and this idea just ocurred to me because of that. If it works, let me know, and apropriately credit your sources (i.e. Me). This is not compute intensive at all and it isn't subject to time compression or expansion either. By the way A represents the phase angle. In your case you would use T, the time value and pick some scaling factor so that the trig functions (or more likely, table look-ups and interpolations) will make sense. Good Luck, and let me know what the results are. I'll try to do some math on this and see if it's really workable, if I have some spare time. -Dean Swan dean@sun.soe.clarkson.edu
d88-jwa@nada.kth.se (Jon W{tte) (09/27/89)
In article <1989Sep25.172140.27543@sun.soe.clarkson.edu> dean@image.soe.clarkson.edu (Dean Swan) writes: > Assume that your input is of the form: > Y=Sin( F*A ) > Then F = ArcSin(Y)/A > Next do F=F+pitch shift amount ^^^ That should be a * ! a * ! a * ! > and reconstruct with Y=Sin(F*A). How many times will I have to read this ? Pitch shift isn't about "adding 100 Hz", it's about scaling a spectra. Are you people conspiring against me just to drive me mad ? (note the crosspost) The problem is; input is sum i from 1 to n sin ( Fi * t + Pi ) for some unknown (often large) n, unknown F and unknown P... You could not possibly solve that equation fast enough. Someone mentioned a 1024-point FFT with a sliding window. That just might be the solution ? But the 5600{0,1} does a 1024-point FFT in 3.3 ms which is 100 times too slow for any kind of HiFi quality. (ONE channel only !) h+@nada.kth.se -- Another good night not to sleep in a eucalyptus tree.
jensen@bessel.eedsp.gatech.edu (P. Allen Jensen) (09/30/89)
There is a group here in town (Atlanta, Ga, USA) called Atlanta Signal Processors, Inc. (ASPI) that has a board called a banshee that is based on the TMS320C20 (They also have some stuff for the C30 and C10) If anyone is interested, I can lookup their address and post it.... P. Allen Jensen Georgia Tech, School of Electrical Engineering, Atlanta, GA 30332 USENET: ...!{allegra,hplabs,ihnp4,ulysses}!gatech!eedsp!jensen INTERNET: jensen@eedsp.gatech.edu