Skip to content

Commit 9e7ed87

Browse files
committed
feat: add documentation and rename package to rescript-tone
Add README.md with installation, quick start, and usage examples. Add docs/API.md with comprehensive API reference for all modules. Rename package from rescript-tonejs to rescript-tone across all configs.
1 parent ec4ecec commit 9e7ed87

5 files changed

Lines changed: 1572 additions & 6 deletions

File tree

README.md

Lines changed: 175 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,175 @@
1-
# rescript-tonejs
2-
Bindings for ToneJS
1+
# rescript-tone
2+
3+
ReScript bindings for [Tone.js](https://tonejs.github.io/), a Web Audio framework for creating interactive music in the browser.
4+
5+
## Installation
6+
7+
```bash
8+
npm install rescript-tone tone
9+
```
10+
11+
Add to your `rescript.json`:
12+
13+
```json
14+
{
15+
"bs-dependencies": ["rescript-tone"]
16+
}
17+
```
18+
19+
## Quick Start
20+
21+
```rescript
22+
open RescriptTone
23+
24+
// Create a synth and connect it to the speakers
25+
let synth = ToneJs_Synth.make()
26+
let node = synth->ToneJs_Synth.asAudioNode->ToneJs_AudioNode.toDestination
27+
28+
// Play a note
29+
let _ = synth->ToneJs_Synth.triggerAttackRelease(440.0, ToneJs_Types.Time.seconds(0.5))
30+
31+
// Start the audio context (required by browsers)
32+
let _ = ToneJs_Tone.start()
33+
```
34+
35+
## Usage Examples
36+
37+
### Playing Notes with a Synth
38+
39+
```rescript
40+
open RescriptTone
41+
42+
let synth = ToneJs_Synth.makeWithOptions({
43+
oscillator: ?Some({\"type": ?Some(ToneJs_Types.Sawtooth)}),
44+
envelope: ?Some({
45+
attack: ?Some(ToneJs_Types.Time.seconds(0.1)),
46+
decay: ?Some(ToneJs_Types.Time.seconds(0.2)),
47+
sustain: ?Some(0.5),
48+
release: ?Some(ToneJs_Types.Time.seconds(0.8)),
49+
}),
50+
})
51+
52+
let _ = synth->ToneJs_Synth.asAudioNode->ToneJs_AudioNode.toDestination
53+
let _ = synth->ToneJs_Synth.triggerAttackRelease(440.0, ToneJs_Types.Time.seconds(0.5))
54+
```
55+
56+
### Chaining Effects
57+
58+
```rescript
59+
open RescriptTone
60+
61+
let synth = ToneJs_Synth.make()
62+
let reverb = ToneJs_Reverb.makeWithDecay(1.5)
63+
let delay = ToneJs_FeedbackDelay.makeWithTimeFeedback(ToneJs_Types.Time.notation("8n"), 0.5)
64+
let dest = ToneJs_Tone.getDestination()
65+
66+
// Chain: synth -> delay -> reverb -> destination
67+
let _ = synth
68+
->ToneJs_Synth.asAudioNode
69+
->ToneJs_AudioNode.chain([
70+
delay->ToneJs_FeedbackDelay.asAudioNode,
71+
reverb->ToneJs_Reverb.asAudioNode,
72+
dest->ToneJs_Destination.asAudioNode,
73+
])
74+
```
75+
76+
### Scheduling with Transport
77+
78+
```rescript
79+
open RescriptTone
80+
81+
let synth = ToneJs_Synth.make()
82+
let _ = synth->ToneJs_Synth.asAudioNode->ToneJs_AudioNode.toDestination
83+
84+
let transport = ToneJs_Tone.getTransport()
85+
86+
// Set BPM
87+
let bpm = transport->ToneJs_Transport.bpm
88+
ToneJs_Param.setValue(bpm, 120.0)
89+
90+
// Schedule a repeating note
91+
let _ = transport->ToneJs_Transport.scheduleRepeat(
92+
_time => {
93+
let _ = synth->ToneJs_Synth.triggerAttackRelease(440.0, ToneJs_Types.Time.notation("8n"))
94+
},
95+
ToneJs_Types.Time.notation("4n"),
96+
)
97+
98+
// Start the transport
99+
let _ = transport->ToneJs_Transport.start
100+
```
101+
102+
### Looping Patterns
103+
104+
```rescript
105+
open RescriptTone
106+
107+
let synth = ToneJs_Synth.make()
108+
let _ = synth->ToneJs_Synth.asAudioNode->ToneJs_AudioNode.toDestination
109+
110+
let notes = ["C4", "E4", "G4", "B4"]
111+
112+
let seq = ToneJs_Sequence.makeWithSubdivision(
113+
(time, note) => {
114+
let _ = synth->ToneJs_Synth.triggerAttackReleaseAt(
115+
ToneJs_Types.Frequency.fromNotation(note),
116+
ToneJs_Types.Time.notation("8n"),
117+
~time=ToneJs_Types.Time.fromFloat(time),
118+
)
119+
},
120+
notes,
121+
ToneJs_Types.Time.notation("4n"),
122+
)
123+
124+
let _ = seq->ToneJs_Sequence.start
125+
let _ = ToneJs_Tone.getTransport()->ToneJs_Transport.start
126+
```
127+
128+
### Polyphonic Synth
129+
130+
```rescript
131+
open RescriptTone
132+
133+
let poly = ToneJs_PolySynth.makeWithOptions({maxPolyphony: ?Some(4)})
134+
let _ = poly->ToneJs_PolySynth.asAudioNode->ToneJs_AudioNode.toDestination
135+
136+
// Play a chord
137+
let _ = poly->ToneJs_PolySynth.triggerAttackRelease(
138+
[261.63, 329.63, 392.0],
139+
ToneJs_Types.Time.seconds(1.0),
140+
)
141+
```
142+
143+
## API Reference
144+
145+
See [docs/API.md](docs/API.md) for the complete API reference.
146+
147+
## Architecture
148+
149+
The library is organized into modules that mirror Tone.js's structure:
150+
151+
| Category | Modules |
152+
|----------|---------|
153+
| **Core** | `Tone`, `Context`, `Transport`, `Destination`, `Param`, `AudioNode`, `Types` |
154+
| **Instruments** | `Synth`, `AMSynth`, `FMSynth`, `MonoSynth`, `PolySynth` |
155+
| **Sources** | `Oscillator`, `Player`, `Noise` |
156+
| **Effects** | `Reverb`, `FeedbackDelay`, `Chorus`, `Distortion`, `AutoFilter`, `AutoPanner`, `AutoWah`, `BitCrusher`, `Chebyshev`, `Freeverb`, `JCReverb`, `Phaser`, `PingPongDelay`, `PitchShift`, `Tremolo`, `Vibrato`, `FrequencyShifter`, `StereoWidener` |
157+
| **Components** | `Compressor`, `Limiter`, `Gate`, `Filter`, `EQ3`, `Panner` |
158+
| **Signal & Channel** | `Signal`, `Volume`, `Gain`, `Channel`, `CrossFade` |
159+
| **Scheduling** | `Loop`, `Event`, `Part`, `Sequence` |
160+
161+
Each Tone.js class maps to a ReScript module with an abstract `type t`. Modules expose:
162+
- `make` / `makeWithOptions` constructors
163+
- `@send` methods for instance operations
164+
- `@get` / `@set` for properties
165+
- `asAudioNode` for casting to the base `ToneJs_AudioNode.t` type (for `connect`, `chain`, etc.)
166+
167+
## Requirements
168+
169+
- ReScript >= 12.0.0
170+
- Tone.js >= 15.0.0
171+
- A browser environment with Web Audio API support
172+
173+
## License
174+
175+
MIT

0 commit comments

Comments
 (0)