diff --git a/README.md b/README.md
index aee06ec..f835716 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,149 @@
# Dittytoy
+
+The dittytoy package is a powerful package that allows you to compile and play ditties
+from [Dittytoy.net](https://dittytoy.net).
+
+[Dittytoy.net](https://dittytoy.net) is an online platform that allows you to create generative music using a
+minimalistic javascript API using Web Audio.
+
+The API syntax is loosely based on the syntax of [Sonic Pi](https://sonic-pi.net/tutorial.html). You can find the
+full [Dittytoy API Reference here](https://dittytoy.net/syntax).
+
+## Getting started
+
+### Installing
+
+Add `dittytoy` to your project:
+
+```sh
+npm i dittytoy
+```
+
+## Basic usage
+
+Compile a ditty and play.
+
+```ts
+import {Dittytoy} from 'dittytoy';
+
+const dittytoy = new Dittytoy();
+
+dittytoy.compile(`
+ditty.bpm = 120;
+
+loop( () => {
+
+ for (let i=0; i<4; i++) {
+ sine.play(c4, { attack: 0.01, release: 0.25, duration: 0.125, pan: Math.random() * 2 - 1, amp: 1.0 });
+ sleep( 0.25 );
+ }
+
+ sine.play(d4, { attack: 0.01, release: 0.25, duration: 0.25 }); // attack and release in seconds, duration in ticks
+ sleep(0.5); // sleep in ticks
+
+ sine.play(f4, { attack: 0.01, release: 0.75, duration: 0.25 });
+ sleep(0.5);
+
+}, { name: 'my first loop' });
+`).then(() => {
+ dittytoy.play();
+})
+```
+
+Note: most browsers only allow audio to be played after a user interaction. You should use the `play` method to start the
+audio after a user interaction.
+
+### Events
+
+Dittytoy emits events that you can listen to by subscribing to the `addEventListener` method.
+
+```ts
+dittytoy.addEventListener(MSG_PLAY, () => {
+ console.log('Dittytoy starts playing');
+});
+```
+
+Some of the events you can listen to are:
+
+#### Logging
+
+```ts
+dittytoy.addEventListener(MSG_LOG, (data: any) => {
+ console.log(data.message);
+});
+
+dittytoy.addEventListener(MSG_ERROR, (data: any) => {
+ console.error(data.message);
+});
+```
+
+#### Initialization
+
+```ts
+dittytoy.addEventListener(MSG_INIT, (data:any) => {
+ console.log('Dittytoy is initialized, ready to play');
+ console.log('Structure of compiled ditty:', data.structure);
+});
+```
+
+
+#### Playback
+
+```ts
+dittytoy.addEventListener(MSG_NOTE_PLAYED, (data:any) => {
+ console.log(`♪ tick: ${data.tick.toFixed(3)}, note: ${data.note} (${data.loop}.${data.synth})`);
+});
+dittytoy.addEventListener(MSG_UPDATE, (data:any) => {
+ // data.amp contains information about the volume of the ditty and the separate loops
+ const state = data.state;
+ if (state) {
+ console.log(`tick: ${(state.tick || 0).toFixed(3)}, time: ${(state.time || 0).toFixed(3)} (${state.bpm.toFixed(0)} bpm)`);
+ }
+});
+```
+
+#### Flow
+
+```ts
+dittytoy.addEventListener(MSG_PLAY, () => {
+ console.log('play');
+});
+dittytoy.addEventListener(MSG_PAUSE, () => {
+ console.log('pause');
+});
+dittytoy.addEventListener(MSG_STOP, () => {
+ console.log('stop');
+});
+dittytoy.addEventListener(MSG_RESUME, () => {
+ console.log('resume');
+});
+```
+
+## Building
+
+To build Dittytoy, ensure that you have [Git](http://git-scm.com/downloads)
+and [Node.js](http://nodejs.org/) installed.
+
+Clone a copy of the repo:
+
+```sh
+git clone https://github.com/reindernijhoff/dittytoy-package.git
+```
+
+Change to the dittytoy directory:
+
+```sh
+cd dittytoy-package
+```
+
+Install dev dependencies:
+
+```sh
+npm i
+```
+
+Build package:
+
+```sh
+npm run build
+```
diff --git a/example/package-lock.json b/example/package-lock.json
index 01ed1d9..32bf403 100644
--- a/example/package-lock.json
+++ b/example/package-lock.json
@@ -8,7 +8,7 @@
"name": "dittytoyjukebox",
"version": "0.0.0",
"dependencies": {
- "dittytoy": "0.1.0-dev.12b7a9a"
+ "dittytoy": "0.1.1"
},
"devDependencies": {
"vite": "^5.1.6"
@@ -561,9 +561,9 @@
"dev": true
},
"node_modules/dittytoy": {
- "version": "0.1.0-dev.12b7a9a",
- "resolved": "https://registry.npmjs.org/dittytoy/-/dittytoy-0.1.0-dev.12b7a9a.tgz",
- "integrity": "sha512-yGIwCvBJ5yX2f6AVmkETNHzjxwQd9Fg3Eb3x3xYlpA+Qq5vCUHvk9TOxNY/IkeQegwMuLNfsT21jxJLbzGisZw==",
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/dittytoy/-/dittytoy-0.1.1.tgz",
+ "integrity": "sha512-kSdPXHnhf4WJpiLt6sd227lctPbehkqkVGh9An+iW17dJ58d8lvAy59Z1pgDPsim7Qeu6e+H0TduOpJKqEAl/Q==",
"engines": {
"node": ">=20.0.0"
}
diff --git a/example/src/dittytoyJukebox.js b/example/src/dittytoyJukebox.js
index c2c186d..7f9d47f 100644
--- a/example/src/dittytoyJukebox.js
+++ b/example/src/dittytoyJukebox.js
@@ -38,7 +38,7 @@ export default class DittytoyJukebox {
if (state) $('log2').innerText = `▸ tick: ${(state.tick || 0).toFixed(3)}, time: ${(state.time || 0).toFixed(3)} (${state.bpm.toFixed(0)} bpm)`;
});
this.dittytoy.addListener(MSG_NOTE_PLAYED, (data) => {
- $('log3').innerText = `♪ tick: ${data.tick.toFixed(2)}, note: ${data.note.toFixed(2)} (${data.loop}.${data.synth})`;
+ $('log3').innerText = `♪ tick: ${data.tick.toFixed(3)}, note: ${data.note.toFixed(2)} (${data.loop}.${data.synth})`;
});
}
@@ -58,7 +58,7 @@ export default class DittytoyJukebox {
this.ditty = await fetch(`https://dittytoy.net/api/v1/ditty/${id}/`).then(e => e.json()).then(ditty => {
$('song-name').innerHTML = `${ditty.title}`;
- $('artist-name').innerHTML = `By ${ditty.user_id}`;
+ $('artist-name').innerHTML = `By ${ditty.user_id}`;
return ditty;
});
diff --git a/package.json b/package.json
index 576228b..6b6216c 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,14 @@
"version": "0.1.2",
"description": "",
"keywords": [
- "dittytoy"
+ "Dittytoy",
+ "music",
+ "generative",
+ "DSP",
+ "audio",
+ "Sonic Pi",
+ "javascript",
+ "Web Audio API"
],
"repository": "git@github.com:reindernijhoff/dittytoy-package.git",
"author": "Reinder Nijhoff ",