Skip to content

Commit

Permalink
Merge branch 'tidalcycles:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
edcrub authored Jan 31, 2025
2 parents 67a8c43 + f558b4b commit d9287e6
Show file tree
Hide file tree
Showing 14 changed files with 659 additions and 69 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ jobs:
uses: actions/configure-pages@v2

- name: Upload artifact
uses: actions/upload-pages-artifact@v1
uses: actions/upload-pages-artifact@v3
with:
# Upload entire repository
path: "./website/dist"

- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v1
uses: actions/deploy-pages@v4
72 changes: 72 additions & 0 deletions packages/motion/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# @strudel/motion

This package adds device motion sensing functionality to strudel Patterns.

## Install

```sh
npm i @strudel/motion --save
```

## Usage

| Motion | Long Names & Aliases | Description |
|----------------------------|-----------------------------------------------------------|------------------------------------------|
| Acceleration | accelerationX (accX), accelerationY (accY), accelerationZ (accZ) | X, Y, Z-axis acceleration values |
| Gravity | gravityX (gravX), gravityY (gravY), gravityZ (gravZ) | X, Y, Z-axis gravity values |
| Rotation | rotationAlpha (rotA, rotZ), rotationBeta (rotB, rotX), rotationGamma (rotG, rotY) | Rotation around alpha, beta, gamma axes and mapped to X, Y, Z |
| Orientation | orientationAlpha (oriA, oriZ), orientationBeta (oriB, oriX), orientationGamma (oriG, oriY) | Orientation alpha, beta, gamma values and mapped to X, Y, Z |
| Absolute Orientation | absoluteOrientationAlpha (absOriA, absOriZ), absoluteOrientationBeta (absOriB, absOriX), absoluteOrientationGamma (absOriG, absOriY) | Absolute orientation alpha, beta, gamma values and mapped to X, Y, Z |

## Example

```js
enableMotion() //enable DeviceMotion

setcpm(200/4)

$_: accX.segment(16).gain().log()

$:n("0 1 3 1 5 4")
.scale("Bb:lydian")
.sometimesBy(0.5,sub(note(12)))
.lpf(gravityY.range(20,1000))
.lpq(gravityZ.range(1,30))
.lpenv(gravityX.range(2,2))
.gain(oriX.range(0.2,0.8))
.room(oriZ.range(0,0.5))
.attack(oriY.range(0,0.3))
.delay(rotG.range(0,1))
.decay(rotA.range(0,1))
.attack(rotB.range(0,0.1))
.sound("sawtooth")
```

## Setup SSL for Local Development

`DeviceMotionEvent` only works with HTTPS, so you'll need to enable SSL for local development.
Try installing an SSL plugin for Vite.

```sh
cd website
pnpm install -D @vitejs/plugin-basic-ssl
```

add the basicSsl plugin to the defineConfig block in `strudel/website/astro.config.mjs`

```js
vite: {
plugins: [basicSsl()],
server: {
host: '0.0.0.0', // Ensures it binds to all network interfaces
// https: {
// key: '../../key.pem', //
// cert: '../../cert.pem',
// },
},
},
```

generate an SSL certificate to avoid security warnings.

`openssl req -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout key.pem -out cert.pem`
82 changes: 82 additions & 0 deletions packages/motion/docs/devicemotion.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { MiniRepl } from '../../../website/src/docs/MiniRepl';
import { JsDoc } from '../../../website/src/docs/JsDoc';

# Device Motion

Devicemotion module allows you to use your mobile device's motion sensors (accelerometer, gyroscope, and orientation sensors) to control musical parameters in real-time. This creates opportunities for expressive, movement-based musical interactions.

## Basic Setup

First, you need to enable device motion sensing:

<MiniRepl client:idle tune={`enableMotion()`} />

This will prompt the user for permission to access device motion sensors.

## Available Motion Parameters

You can access different types of motion data:

| Motion | Long Names & Aliases | Description |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| Acceleration | accelerationX (accX), accelerationY (accY), accelerationZ (accZ) | Measures linear acceleration of the device, excluding gravity. Raw values are normalized from g-force. |
| Gravity | gravityX (gravX), gravityY (gravY), gravityZ (gravZ) | Indicates device's orientation relative to Earth's gravity. Raw values are normalized from ±9.81 m/s². |
| Rotation | rotationAlpha (rotA, rotZ), rotationBeta (rotB, rotX), rotationGamma (rotG, rotY) | Measures rotation rate around each axis. Raw values (±180°/s) are normalized. |
| Orientation | orientationAlpha (oriA, oriZ), orientationBeta (oriB, oriX), orientationGamma (oriG, oriY) | Relative orientation from its starting device position. Normalized from:<br/>- Alpha: 0° to 360°<br/>- Beta: -180° to 180°<br/>- Gamma: -90° to 90° |
| Absolute Orientation | absoluteOrientationAlpha (absOriA, absOriZ), absoluteOrientationBeta (absOriB, absOriX), absoluteOrientationGamma (absOriG, absOriY) | **Not available for iOS** <br/> Earth-referenced orientation using magnetometer. Same normalization as Orientation. |

Note:

- All motion values are normalized to a range of 0 to 1.
- Not all devices have the same sensors available
Check [DeviceMotionEvent API](https://developer.mozilla.org/en-US/docs/Web/API/DeviceMotionEvent) for browser compatibility
- Refer to [Oritentation and motion data explained](https://developer.mozilla.org/en-US/docs/Web/API/Device_orientation_events/Orientation_and_motion_data_explained) for more details

### Orientation vs Absolute Orientation

The key difference between regular orientation and absolute orientation is:

- Regular orientation (`oriX/Y/Z`) measures relative changes in device orientation from its starting position
- Absolute orientation (`absOriX/Y/Z`) measures orientation relative to Earth's magnetic field and gravity, providing consistent absolute values regardless of starting position

For example, if you rotate your device 90 degrees clockwise and then back:

- Regular orientation will show a change during rotation but return to initial values
- Absolute orientation will show the actual compass heading throughout

This makes absolute orientation particularly useful for creating direction-based musical interactions - for example, performers facing north could play one melody while those facing south play another, creating spatially-aware ensemble performances. Regular orientation, on the other hand, is better suited for detecting relative motion and gestures regardless of which direction the performer is facing.

## Basic Example

Here's a simple example that uses device motion to control a synthesizer:

<MiniRepl
client:idle
tune={`enableMotion()
// Create a simple melody
$:n("0 1 3 5")
.scale("C:major")
// Use tilt (gravity) to control filter
.lpf(gravityY.range(200, 2000)) // tilt forward/back for filter cutoff
// Use rotation to control effects
.room(rotZ.range(0, 0.8)) // rotate device for reverb amount
.gain(oriX.range(0.2, 0.8)) // tilt left/right for volume
.sound("sawtooth")`}
/>

## Tips for Using Motion Controls

1. Use `.range(min, max)` to map sensor values to musically useful ranges
2. Consider using `.segment()` to smooth out rapid changes in sensor values

## Debugging

You can use `segment(16).log()` to see the raw values from any motion sensor:

```javascript
$_: accX.segment(16).log(); // logs acceleration values to the console
```

This is helpful when calibrating your ranges and understanding how your device responds to different movements.

Remember that device motion works best on mobile devices and may not be available on all desktop browsers. Always test your motion-controlled pieces on the target device type!
3 changes: 3 additions & 0 deletions packages/motion/index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import './motion.mjs';

export * from './motion.mjs';
Loading

0 comments on commit d9287e6

Please sign in to comment.