-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Change playback speed exponentially (#840)
Co-authored-by: Mikael Finstad <[email protected]>
- Loading branch information
Showing
4 changed files
with
90 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import clamp from 'lodash/clamp'; | ||
|
||
/** | ||
* @constant {number} | ||
* @default | ||
* The default playback rate multiplier is used to adjust the current playback | ||
* rate when no additional modifiers are applied. This is set to ∛2 so that striking | ||
* the fast forward key (`l`) three times speeds playback up to twice the speed. | ||
*/ | ||
export const DEFAULT_PLAYBACK_RATE = (2 ** (1 / 3)); | ||
|
||
/** | ||
* Adjusts the current playback rate up or down | ||
* @param {number} playbackRate current playback rate | ||
* @param {number} direction positive for forward, negative for reverse | ||
* @param {number} [multiplier] rate multiplier, defaults to {@link DEFAULT_PLAYBACK_RATE} | ||
* @returns a new playback rate | ||
*/ | ||
export function adjustRate(playbackRate, direction, multiplier) { | ||
const m = multiplier || DEFAULT_PLAYBACK_RATE; | ||
const factor = direction > 0 ? m : (1 / m); | ||
let newRate = playbackRate * factor; | ||
// If the multiplier causes us to go faster than real time or slower than real time, | ||
// stop along the way at 1.0. This could happen if the current playbackRate was reached | ||
// using a different multiplier (e.g., holding the shift key). | ||
// https://github.com/mifi/lossless-cut/issues/447#issuecomment-766339083 | ||
if ((newRate > 1.0 && playbackRate < 1.0) || (newRate < 1.0 && playbackRate > 1.0)) { | ||
newRate = 1.0; | ||
} | ||
// And, clean up any rounding errors that get us to almost 1.0 (e.g., treat 1.00001 as 1) | ||
if ((newRate > (m ** (-1 / 2))) && (newRate < (m ** (1 / 2)))) { | ||
newRate = 1.0; | ||
} | ||
return clamp(newRate, 0.1, 16); | ||
} | ||
|
||
export default adjustRate; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { adjustRate, DEFAULT_PLAYBACK_RATE } from './rate-calculator'; | ||
|
||
it('inverts for reverse direction', () => { | ||
const r = adjustRate(1, -1, 2); | ||
expect(r).toBeLessThan(1); | ||
}); | ||
|
||
it('uses default rate', () => { | ||
const r = adjustRate(1, 1); | ||
expect(r).toBe(1 * DEFAULT_PLAYBACK_RATE); | ||
}); | ||
|
||
it('allows multiplier override', () => { | ||
const r = adjustRate(1, 1, Math.PI); | ||
expect(r).toBe(1 * Math.PI); | ||
}); | ||
|
||
describe('speeding up', () => { | ||
it('sets rate to 1 if close to 1', () => { | ||
expect(adjustRate(1 / DEFAULT_PLAYBACK_RATE + 0.01, 1)).toBe(1); | ||
}); | ||
|
||
it('sets rate to 1 if passing 1 ', () => { | ||
expect(adjustRate(0.5, 1, 2)).toBe(1); | ||
}); | ||
|
||
it('will not play faster than 16', () => { | ||
expect(adjustRate(15.999999, 1, 2)).toBe(16); | ||
}); | ||
}); | ||
|
||
describe('slowing down', () => { | ||
it('sets rate to 1 if close to 1', () => { | ||
expect(adjustRate(DEFAULT_PLAYBACK_RATE + 0.01, -1)).toBe(1); | ||
}); | ||
|
||
it('sets rate to 1 if passing 1', () => { | ||
expect(adjustRate(1.1, -1, 2)).toBe(1); | ||
}); | ||
|
||
it('will not play slower than 0.1', () => { | ||
expect(adjustRate(0.1111, -1, 2)).toBe(0.1); | ||
}); | ||
}); |