Skip to content

Commit 4751781

Browse files
committed
documentation improvements
1 parent 3f42a97 commit 4751781

File tree

4 files changed

+402
-134
lines changed

4 files changed

+402
-134
lines changed

README.md

Lines changed: 120 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
# Bungee: Audio Time-Stretching & Pitch-Shifting Library
22

3-
Bungee is a modern, open-source C++ library for high-quality audio time-stretching and pitch-shifting in real-time or offline. Easily integrate advanced audio timescale processing into your application.
3+
Bungee is a modern, open-source C++ library for high-quality audio time-stretching and pitch-shifting in real-time or offline. Easily integrate powerful audio timescale processing into your application.
44

5-
Bungee can adjust the speed of audio without affecting pitch; transpose audio pitch without affecting speed; or any combination of playhead position and pitch manipulation.
6-
* Simple, fast phase-vocoder-based algorithm with good quality audio output ([🎧 hear some comparisons](https://bungee.parabolaresearch.com/compare-audio-stretch-tempo-pitch-change.html) with other algorithms)
5+
Bungee can adjust the speed of audio without affecting pitch; transpose audio pitch without affecting speed; or apply any combination of playhead position and pitch manipulation.
6+
* Simple, fast phase-vocoder-based algorithm with good quality audio output (🎧 hear [some comparisons](https://bungee.parabolaresearch.com/compare-audio-stretch-tempo-pitch-change.html) with other algorithms)
77
* Modern C++ for clean and resilient code
88

99
Bungee is unique in its controllability, allowing continually changing audio tempo and pitch manipulation with seamless support of zero and negative playback speeds. So it can be used for a "smooth scrub" or for rendering lifelike audio for slow-motion videos.
1010

11+
Bungee is often used for slowing down music or speech without affecting pitch. It is also popular in music software for changing tempo, transposing and other effects.
12+
1113
⭐️ _To support Bungee, please consider [giving this repo a star](https://github.com/bungee-audio-stretch/bungee/stargazers)_ .
1214

1315
![GitHub Release](https://img.shields.io/github/v/release/bungee-audio-stretch/bungee)
@@ -17,6 +19,8 @@ Bungee is unique in its controllability, allowing continually changing audio tem
1719

1820
## Getting started with Bungee Audio Time-Stretching
1921

22+
### Clone and Build
23+
2024
Bungee's dependencies are managed as git submodules; so clone like this:
2125
```
2226
git clone --recurse-submodules https://github.com/bungee-audio-stretch/bungee
@@ -30,32 +34,47 @@ cmake ..
3034
cmake --build .
3135
```
3236

33-
After a successful build, run the bungee executable
37+
After a successful build, try the bungee executable
3438
```
3539
./bungee --help
3640
```
41+
### Pre-built Releases
42+
43+
Every commit pushed to this repo's main branch is automatically tagged and built into a release. Each release contains Bungee built as a shared library together with headers, sample code and a sample command-line executable that uses the shared library. Releases support common platforms including Linux, Windows, MacOS, Android and iOS.
44+
3745

3846
## Integrating Bungee C++ Audio Library
3947

40-
Every commit pushed to this repo's main branch is automatically tagged and built into a release. Each release contains Bungee built as a shared library together with headers, sample code and a sample command-line executable that uses the shared library. Releases support common platforms including Linux, Windows, MacOS, Android and iOS.
48+
Bungee operates on discrete, overlapping "grains" of audio, typically processing around 100 grains per second. Parameters such as position and pitch are provided on a per-grain basis so that they can be changed continuously as audio rendering progresses.
4149

42-
## Example: Real-Time Audio Pitch-Shifting in C++
50+
The Bungee API supports two modes of operation: "granular" and "streaming". Both modes offer identical audio quality and similar CPU performance. Developers should select the mode that best suits the needs of their application.
4351

44-
Bungee operates on discrete, overlapping "grains" of audio, typically processing around 100 grains per second. Parameters such as position and pitch are provided on a per-grain basis so that they can be changed continuously as audio rendering progresses. This means that only minimal parameters are required for instantiation.
52+
| Mode | Granular | Streaming |
53+
|--|--|--|
54+
| `#include` | `<bungee/Bungee.h>` | `<bungee/Stream.h>` |
55+
| Description | Fundamental, low-level interface. | Simplified API built atop the granular interface. |
56+
| Operation | The caller iterates over a "granular loop" where they control exactly what happens at each of the Bungee grains. | The granular nature of the underlying library is hidden and the caller instead manages an input audio stream and an output audio stream. Iterations are over "chunks" of audio that need not map to the underlying grains. |
57+
| Benefits | Allows any arbritrary movements within the input audio: play at any speed, reverse play, infinite stretch, trick play. Lowest latency and no additional data copies | Simpler "FIFO" operation, more similar to traditional "linear playback" audio processing code. Designed to be easy to integrate to frameworks such as JUCE and FFmpeg. |
58+
| Restrictions | | Supports only forward playback.|
59+
| Example | [cmd/main.cpp](./cmd/main.cpp) with `--push 0` | [cmd/main.cpp](./cmd/main.cpp) when `--push` has a non-zero value |
4560

46-
For a working example of this API, see [cmd/main.cpp](./cmd/main.cpp).
4761

48-
### Instantiation
62+
### Granular Audio Time-Stretching and Pitch-Shifting Example
4963

50-
To instantiate, include the [bungee/Bungee.h](./bungee/Bungee.h) header file, create a `Stretcher<Basic>` object and initialise a `Request` object:
64+
#### Instantiation for Granular Processing
5165

5266
``` C++
53-
#include "Bungee.h"
54-
#include <cmath>
67+
#include <bungee/Bungee.h>
68+
```
69+
``` C++
70+
// Define stretcher input and output sample rates
71+
const Bungee::SampleRates sampleRates{44100, 44100};
5572

56-
const int sampleRate = 44100;
73+
// Instantiate a stretcher for two-channel (stereo) operation.
74+
Bungee::Stretcher<Bungee::Basic> stretcher(sampleRates, 2);
5775

58-
Bungee::Stretcher<Bungee::Basic> stretcher({sampleRate, sampleRate}, 2);
76+
// Enable instrumentation. When done debugging, this can be removed.
77+
stretcher.enableInstrumentation(true);
5978

6079
Bungee::Request request{};
6180

@@ -66,14 +85,14 @@ request.pitch = std::pow(2., 1. / 12.);
6685
request.speed = 0.75;
6786

6887
// Set initial starting position at 0.5 seconds offset from the start of the input buffer.
69-
request.position = 0.5;
88+
request.position = 0.5 * sampleRate;
7089

7190
// This call adjusts request.position so that stretcher's pipeline will be fully initialised by the
7291
// time it reaches the starting position of 0.5 seconds offset.
7392
stretcher.preroll(request);
7493
```
7594
76-
### Granular loop
95+
#### Granular Loop
7796
7897
`Stretcher`'s processing functions are typically called from within a loop, each iteration of which corresponds to a grain of audio. For each grain, the functions `Stretcher<Basic>::specifyGrain`, `Stretcher<Basic>::analyseGain` and `Stretcher<Basic>::synthesiseGrain` should be called in sequence.
7998
```C++
@@ -104,9 +123,7 @@ while (true)
104123
}
105124
```
106125

107-
### Things to note
108-
109-
* Bungee is most commonly used for stereo and mono operation at sample rates of 44.1kHz and 48kHz. In principle, though, any practical sample rate and number of audio channels are supported.
126+
#### Granular Notes
110127

111128
* `Request::position` is a timestamp, it defines the grain centre point in terms of an input audio frame offset. It is the primary control for speed adjustments and is also the driver for seek and scrub operations. The caller is responsible for deciding `Request::position` for each grain.
112129

@@ -116,13 +133,84 @@ while (true)
116133

117134
* Output audio is timestamped. The original `Request` objects corresponding to the start and end of the chunk are provided by `OutputChunk`.
118135

136+
### Streaming Audio Time-Stretching and Pitch-Shifting Example
137+
138+
#### Streaming Instantiation
139+
140+
``` C++
141+
#include <bungee/Stream.h>
142+
```
143+
144+
``` C++
145+
// Define stretcher input and output sample rates
146+
const Bungee::SampleRates sampleRates{44100, 44100};
147+
const auto channelCount = 2;
148+
149+
// What is the maximum number of input
150+
const auto maxInputFrameCount = 1024; // for example
151+
152+
// Instantiate a stretcher.
153+
Bungee::Stretcher<Bungee::Basic> stretcher(sampleRates, channelCount);
154+
155+
// Enable instrumentation. When done debugging, this can be removed.
156+
stretcher.enableInstrumentation(true);
157+
158+
// Instantiate a Stream object.
159+
Stream stream(stretcher, maxInputFrameCount, channelCount);
160+
```
161+
162+
#### Streaming Loop
163+
164+
```C++
165+
while (true)
166+
{
167+
// Each iteration of this loop processes the next contiguous chunk of audio data.
168+
169+
std::vector<const float *> inputChannelPointers(channelCount);
170+
int inputSampleCount;
171+
172+
std::vector<float *> outputChannelPointers(channelCount);
173+
174+
// ...
175+
// Insert code here to:
176+
// 1. Receive the next chunk of input audio, set inputChannelPointers and inputSampleCount accordingly
177+
// 2. Set outputChannelPointers to a user maintained buffer where output audio should be written by Bungee.
178+
// ...
179+
180+
// Set these control variables as desired.
181+
const double speed=1., pitch=1.;
182+
183+
const double outputFrameCountIdeal = (inputSampleCount * sampleRates.output) / (speed * sampleRates.input);
184+
185+
// This call does the stretching.
186+
const auto outputFrameCountActual = stream.process(inputChannelPointers.data(), outputChannelPointers.data(), inputSampleCount, outputFrameCountIdeal, pitch);
187+
188+
// ...
189+
// Place code to handle output of the time-stretched / pitch-shifted audio.
190+
// The processed audio resides in memory at the buffer indicated by outputChannelPointers
191+
// and each channel will have outputFrameCountActual samples of new audio.
192+
// ...
193+
}
194+
```
195+
### Streaming Notes
196+
* The caller specifies its desired output audio speed (tempo) by the value of `outputFrameCountIdeal` above. Because the stretcher cannot output a fractional number of audio frames, `outputFrameCountActual` will be returned as one of the two closest integral values to `outputFrameCountIdeal`.
197+
198+
199+
## General Bungee C++ API Notes
200+
201+
* In Bungee code and API, a "frame" refers to a single time-aligned set of audio samples—one sample from each channel at a specific point in time. For example, in stereo audio, a frame consists of one left and one right sample occurring simultaneously.
202+
203+
* Bungee is most commonly used for stereo and mono operation at sample rates of 44.1kHz and 48kHz. In principle, though, any practical sample rate and number of audio channels are supported and results should be similar.
204+
119205
* Bungee works with 32-bit floating point audio samples and expects sample values in the range -1 to +1 on both input and output. The algorithm performs no clipping.
120206

121207
* When configured for 1x speed and no pitch adjustment, the difference between input and output signals should be small: minor windowing discrepencies only.
122208

123-
* Any special or non-numeric float values such as NaN and inf within the input audio may disrupt or cause loss of output audio.
209+
* Any special or non-numeric float values such as NaN or infinity within the input audio may disrupt or cause loss of output audio.
210+
211+
* It is strongly recommended to enable Bungee's internal instrumentation whem working on the integration of the Bungee API. The instrumentation is particuarly helpful for the granular mode of operation because it can detect common usage errors.
124212

125-
## Dependencies
213+
## Bungee's Dependencies
126214

127215
The Bungee library gratefully depends on:
128216
* The Eigen C++ library for buffer management and mathematical operations on vectors and arrays
@@ -131,21 +219,21 @@ The Bungee library gratefully depends on:
131219
The sample `bungee` command-line utility also uses:
132220
* cxxopts library for parsing command-line options
133221

134-
See this repo's [.gitmodules](.gitmodules) for versioned links to these projects.
222+
See this repo's [.gitmodules](.gitmodules) file for versioned links to these projects.
135223

136-
## License
224+
## Bungee License
137225

138-
Bungee is permissively licensed under the Mozilla Public License Version 2.0.
226+
Bungee is permissively licensed under the Mozilla Public License Version 2.0.
139227

140-
## Support
228+
## Bungee Support
141229

142-
Bungee's goal is to be the _best open source audio timescale manipulation library_ available. User feedback is invaluable: please use Github issues to report anything that could be improved.
230+
Bungee's goal is to be the _best open source audio timescale manipulation library_ available. User feedback is invaluable: please use Github issues or contact the team directly to report anything that could be improved.
143231

144-
> ## Bungee Pro
232+
> # Bungee Pro
145233
>
146-
> Bungee Pro is a commercial product providing an upgrade path from this open-source project. It uses novel algorithms for sharp and clear professional-grade audio and runs at least as fast as Bungee, thanks to platform-specific performance optimisations.
234+
> Bungee Pro is a commercial product providing an upgrade path from the open-source Bungee audio time stretcher. It uses proprietary new algorithms for sharp and clear professional-grade audio and runs at least as fast as Bungee, thanks to platform-specific performance optimisations.
147235
>
148-
> Whilst open-source Bungee aims to be the best open-source audio time stretch algorithm, the goal of Bungee Pro is to be the _best algorithm available commercially_.
236+
> Whilst open-source Bungee aims to be the best open-source audio time-stretch algorithm, the goal of Bungee Pro is to be the _best commercially-available audio time-stretch and pitch-adjustment technology_.
149237
>
150238
> * Novel processing techniques that deliver crisp transients and preserve vocal and instrumental timbre
151239
> * Adaptive to all genres of speech, music and sound with subjective transparency up to infinite time stretch
@@ -156,10 +244,10 @@ Bungee's goal is to be the _best open source audio timescale manipulation librar
156244
> * A ready-to-use Web Audio implementation
157245
> * Professional support
158246
>
159-
> Bungee Pro is used in a wide variety of applications including movie post production software, educational apps and musicians' tools.
247+
> Bungee Pro is today deployed in a wide variety of applications including movie post production software, educational apps and popular musicians' tools.
160248
>
161-
> [Listen to an extensive evaluation](https://bungee.parabolaresearch.com/compare-audio-stretch-tempo-pitch-change.html) of Bungee and Bungee Pro against state-of-the-art techniques.
249+
> Check out an [extensive evaluation](https://bungee.parabolaresearch.com/compare-audio-stretch-tempo-pitch-change.html) of Bungee and Bungee Pro against state-of-the-art techniques.
162250
>
163-
> | ![waveform animation](./README.md-waveform.png) | Try the [WebAssembly demo](https://bungee.parabolaresearch.com/change-audio-speed-pitch.html) of Bungee Pro in your browser.|
251+
> | ![Bungee waveform animation: audio time-stretching and pitch-shifting demo](./README.md-waveform.png) | Try the [WebAssembly demo](https://bungee.parabolaresearch.com/change-audio-speed-pitch.html) of Bungee Pro in your browser.|
164252
> |--|--|
165253
>

0 commit comments

Comments
 (0)