4

I would like to accomplish two things at the same time:

1) change playback rate of a sound file to 1/2 speed

2) lower pitch by a fifth

Lastly, Instead of using a separate button to play the result I would like to hook this up to an audio tag and use the play button there.

Below is the closest I got so far using Tone.js. I am really struggling with the documentation but I understand that Tone.Transport.bpm.value = 60; changes the bpm from 120 to 60 and Tone.PitchShift transposes the song. I just don't see how to combine the two to 'stack' the effects.

Here are some links I followed:

How to change the pitch with JavaScript?

https://tonejs.github.io/docs/r12/PitchShift

https://tonejs.github.io/docs/13.8.25/Transport

Thanks in advance for the help!

<audio id="myAudio" controls preload="none">
      <source src="my_tune.m4a" type="audio/mp4" >
</audio>

<script src="https://unpkg.com/tone@next/build/Tone.js"></script>

<script>

Tone.Transport.bpm.value = 60;  // setting the bpm like this is not working. where to put this?


var player = new Tone.Player("my_tune.m4a").sync().start(0);
// is it possible to use audio tag instead of creating this player?

var pitchShift = new Tone.PitchShift({
    pitch: -5 // this is working and lowers pitch by a fifth
}).toMaster();

player.connect(pitchShift);
window.play = function() {
    Tone.Transport.start();
}

<script>

<button onclick="setPlaySpeed()" type="button">separate button</button><br>

wittgenstein
  • 3,670
  • 7
  • 24
  • 41
mandmeier
  • 355
  • 5
  • 16
  • I think there might be a misconception here. [Transport](https://tonejs.github.io/docs/13.8.25/Transport) is _for timing musical events_. Look at the [Player Example](https://tonejs.github.io/examples/player.html) and how that deals with playback speed. Playback rate changes pitch and speed, so you would then need to compensate with the pitch shift. Or you could look into creating your own [phase vocoder using web audio](https://github.com/echo66/PhaseVocoderJS) – fdcpp Jan 06 '20 at 19:58
  • Any update on this? I have the same problem. – gskema May 03 '20 at 17:49
  • @gskema: updated ;) let me know if this helps. – mandmeier May 04 '20 at 22:26

1 Answers1

2

UPDATE: WORKING SOLUTION

I found a way that works: Set the playback rate first. Then, when setting the pitch you need to calculate how much pitch shift to add/subtract to compensate for the playback rate. In my example I had to compensate +12 pitch shift for 0.5 playback rate.

player = new Tone.Player("url/to/audio.mp3");
playback_rate = 0.5 // or 1 (I only implemented these two options)
transpose_by = 7 // up 7 half steps, -7 would be down 7 half steps

// set playback rate
player.playbackRate = playback_rate
player.toDestination();


// set pitch shift
if (playback_rate == 1){
    pitch_shift = new Tone.PitchShift({
    pitch: transpose_by.toString()
    }).toDestination();
} else { //if playbackrate == 0.5 add +12 to pitch to correct
    trans = transpose_by + 12
    trans = trans.toString()
    pitch_shift = new Tone.PitchShift({
    pitch: trans
  }).toDestination();
}
player.disconnect(); // disconnect old player (get overlay of two players otherwise if you repeat this)
player.connect(pitch_shift);

player.start()

See it in action on my website: https://www.lickstack.com

I still have no idea how to connect a Tone.js player to an audio element though. Any help would be appreciated. See my post here: create html <audio> element from Tone.js object

mandmeier
  • 355
  • 5
  • 16