Shop OBEX P1 Docs P2 Docs Learn Events
change speed of WAV playback? — Parallax Forums

change speed of WAV playback?

im using the wavplayer program with simpleIDE, is there anyway to speed up or slow down the playback speed of a wav track? thanks.

Comments

  • With or without changing the pitch?

    -Phil
  • im not sure really? its a diesel engine track and i am wanting it to simulate speeding up and slowing down
  • RaymanRayman Posts: 14,640
    edited 2020-10-21 20:15
    Can you post the .spin file that plays the wav?

    Usually this kind of code will read the .wav header to get the playback sample rate (and other things). Usually around 24 to 48 kHz.
    If you can find this part of the code, just change this number to be higher or lower to change the playback speed...
  • My WAV object (Spin) allows you to set the playback speed -- depending on the encoding rate -- between 50% and 200%. The point is, it can be done.
  • I need to do the same thing with my engine railroad controller. The sounds need to be played back at different speeds, but have the pitch remain the same.

    I figured the prop wasn't up to doing the pitch bending, so I decided to pitch bend the waves myself in a audio program, and save a bunch of them for different speeds.
    And then play the set of waves for the speed I am running.

    @JonnyMac does your object preserve the pitch? (i would imagine not?)
  • RaymanRayman Posts: 14,640
    That’s a neat trick... I’ve radio stations do that to speed up music and speech

    Wonder if audacity can do that...
  • Rayman wrote: »
    Wonder if audacity can do that...


    Actually it can.
    214 x 98 - 10K
  • You may not get the results you expect from just varying the playback speed.

    Think of a diesel engine as being like the human vocal tract. The pitch is controlled by the excitation of the vocal chords. In an engine, this would be the engine RPMs, which can vary up and down. But what gives speech its distinctive quality are the formants formed by resonances in the mouth and nasal cavity. These do not vary with pitch. In an engine, the formants are formed by resonances in the exhaust system: the manifold, exhaust pipe, muffler, and tailpipe. As with voice formants, these also do not change with pitch.

    But adjusting the playback speed will change both the pitch and formant frequencies, rendering the engine with a different sound, rather than just revving higher. When this is done to a voice recording, you get Alvin and the Chipmunks, rather than hearing the same person singing at a higher pitch.

    -Phil
  • The music world seems to think autotune is ok, so why shouldn't we use it.


    Someone needs to get the prop running autotune code! ;)
    What say you phil, you wanna code that monstrosity of pointless....
    oh nevermind, im sure the science behind autotune is much more complicated and interesting than the actual results and uses FOR autotune.


    I didn't find any autotuned train engines on youtube.

    Perhaps a new autotune trend should be started.
  • @JonnyMac does your object preserve the pitch? (i would imagine not?)
    No. You would have to buffer and resample the audio -- there is not enough horsepower or RAM in the P1 for that.
  • As Phil suggests, changing the playback speed will change the pitch of the sound.

    YouTube manages to change playback speed without changing pitch but I'm pretty sure this requires a lot of processing power and some very clever algorithms. My guess is they're using fourier transformations and lots of newt eyes for that kind of magic.
  • JonnyMacJonnyMac Posts: 9,102
    edited 2020-10-22 00:38
    I'm betting that YouTube preprocess and saves multiple audio streams for each video file. Note that speed changes are at fixed rates. If you could vary the speed to any value on the fly I would believe they're doing it in real time.
  • ElectrodudeElectrodude Posts: 1,657
    edited 2020-10-24 02:32
    JonnyMac wrote: »
    I'm betting that YouTube preprocess and saves multiple audio streams for each video file. Note that speed changes are at fixed rates. If you could vary the speed to any value on the fly I would believe they're doing it in real time.

    I'm betting they don't. YouTube recently added a "Custom" option that lets you set it to any arbitrary value. VLC has been able to do it in realtime for as long as I've used it.
  • I'm betting they don't. YouTube recently added a "Custom" option that lets you set it to any arbitrary value. VLC has been able to do it in realtime for as long as I've used it.

    Yeah, because we all run the youtube.exe application, just like VLC.exe
  • well it is more the Chrome.exe rendering the audio and video stream it gets from youtube...

    Mike
  • @Rayman the .spin file is audiosynth.spin and wont post because of the length, it was with the C file im using.

    here is the begining of the spin file.
    CON
        SAMPLES     = 512                                                           ' samples per cycle
        PERIOD      = 80_000_000 / 40_000                                           ' clkfreq / sample rate
        OSCILLATORS = 4                                                             ' hardcoded oscillators used by synthesizer
    
        #0, _SQUARE, _SAW, _TRIANGLE, _SINE, _NOISE, _SAMPLE                        ' waveform options
        #0, _ENV, _ATK, _DEC, _SUS, _REL, _WAV
        #0, _O, _A, _D, _S, _R
        'AUDIO       = 27
        'AUDIO2      = 26
    
    
    VAR
        long    osc_sample         '0
    
        long    osc_envelope       '$01010101 
        long    osc_attack         '$7F7F7F7F
        long    osc_decay          '0
        long    osc_sustain        '$7F7F7F7F
        long    osc_release        '0
        long    osc_waveform       '0
    
        long    osc_state          '0
        
        long    osc_target[4]      '0[4]
        long    osc_vol[4]         '(127<<12)[4]
        
        long    osc_inc[4]         '0[4]
        long    osc_acc[4]         '0[4]    
      
        long    freqtable[12]       '439638, 465780, 493477, 522820, 553909, 586846      ' precalculated frequency constants
                                    '621742, 658713, 697882, 739380, 783346, 829926      ' see frequencytiming
    
    PUB null
       
    PUB Start
        osc_sample      :=    0
    
        osc_envelope    :=    $01010101 
        osc_attack      :=    $7F7F7F7F
        osc_decay       :=    0
        osc_sustain     :=    $7F7F7F7F
        osc_release     :=    0
        osc_waveform    :=    0
    
        osc_state       :=    0
        
        osc_target[0]   :=    0
        osc_target[1]   :=    0
        osc_target[2]   :=    0
        osc_target[3]   :=    0
        
        osc_vol[0]      :=    (127<<12)
        osc_vol[1]      :=    (127<<12)
        osc_vol[2]      :=    (127<<12)
        osc_vol[3]      :=    (127<<12)
        
        osc_inc[0]         :=    0
        osc_inc[1]         :=    0
        osc_inc[2]         :=    0
        osc_inc[3]         :=    0
    
        osc_acc[0]         :=    0    
        osc_acc[1]         :=    0    
        osc_acc[2]         :=    0    
        osc_acc[3]         :=    0    
      
        freqtable[0]       :=    439638
        freqtable[1]       :=    465780
        freqtable[2]       :=    493477
        freqtable[3]       :=    522820
        freqtable[4]       :=    553909
        freqtable[5]       :=    586846      ' precalculated frequency constants
        freqtable[6]       :=    621742
        freqtable[7]       :=    658713
        freqtable[8]       :=    697882
        freqtable[9]       :=    739380
        freqtable[10]      :=    783346
        freqtable[11]      :=    829926      ' see frequencytiming
        
        cognew(@entry, @osc_sample)    'start assembly cog
        
    PUB SetVolume(channel, value)
        
        osc_vol[channel] := value << 12
        
    PUB SetNote(channel, value)
        
        osc_inc[channel] := freqtable[value//12] >> (9 - value/12)
        
    PUB SetFreq(channel, value)
        
        osc_inc[channel] := value
    
    PUB SetParam(channel, type, value)
    
        byte[@osc_envelope[type]][channel] := value
        
    PUB SetADSR(channel, attackvar, decayvar, sustainvar, releasevar)
        
        osc_attack.byte[channel] := attackvar
        osc_decay.byte[channel] := decayvar
        osc_sustain.byte[channel] := sustainvar
        osc_release.byte[channel] := releasevar
        
    PUB LoadPatch(patchAddr) | i, j, t, c
    
        c := byte[patchAddr] & $F
            
        repeat j from 0 to 3
            if c & $1
                SetEnvelope(j,1)
                t := patchAddr + 1
                repeat i from _ATK to _WAV
                    SetParam(j, i, byte[t++])
            c >>= 1
        
    PUB SetWaveform(channel, value)
        
        osc_waveform.byte[channel] := value
        
    PUB SetEnvelope(channel, value)
       
        osc_envelope.byte[channel] &= constant(!1)
        if value
            osc_envelope.byte[channel] |= 1
        
    PUB StartEnvelope(channel, enable)
        osc_envelope.byte[channel] &= constant(!2)
        if enable
            osc_envelope.byte[channel] |= 2
        osc_envelope.byte[channel] |= 4
        osc_envelope.byte[channel] &= !4
     
    PUB SetSample(value)
        
        osc_sample := value
    
    PUB PlaySound(channel, value)
        
        SetEnvelope(channel, 1)
        StartEnvelope(channel, 1)
        SetNote(channel, value)
    
    PUB StopSound(channel)
        
        StartEnvelope(channel, 0)
        
    PUB StopAllSound | i
    
        repeat i from 0 to 3
            StopSound(i)
            
    DAT
                            org
    ' ---------------------------------------------------------------
    ' Setup
    ' ---------------------------------------------------------------
    entry                  '{
                            mov      addr, par
                            add      addr, #144
                            rdlong   ctraval, addr
                            add      addr, #4
                            rdlong   diraval, addr
                            add      addr, #4
    

  • RaymanRayman Posts: 14,640
    I'd guess changing the value of "Period" would do it...
Sign In or Register to comment.