Skip to content

Commit 4bb8f3b

Browse files
Create music_without_midi.md
1 parent 164d034 commit 4bb8f3b

File tree

1 file changed

+82
-0
lines changed

1 file changed

+82
-0
lines changed

extras/music_without_midi.md

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# Playing Notes Without a Hardware MIDI Interface
2+
3+
This document explains how to play notes in a library without relying on an external MIDI interface or receiving MIDI notes via a serial interface. All projects/modules are designed to function without additional hardware and use an interface defined in `z_config.ino`.
4+
5+
## Default Setup
6+
Each project typically uses an interface that is configured in `z_config.ino`. The configuration looks like this:
7+
8+
```
9+
struct midiMapping_s midiMapping =
10+
{
11+
NULL,
12+
Organ_NoteOn,
13+
Organ_NoteOff,
14+
[...]
15+
};
16+
```
17+
18+
or
19+
20+
```
21+
struct midiMapping_s midiMapping =
22+
{
23+
NULL,
24+
Sampler_NoteOn,
25+
Sampler_NoteOff,
26+
[...]
27+
};
28+
```
29+
30+
These lines indicate that the `Organ_NoteOn` and `Organ_NoteOff` functions are used to handle note-on and note-off events for an organ. Similarly, `Sampler_NoteOn` and `Sampler_NoteOff` are used for a sampler module.
31+
32+
## Manual Function Calls
33+
To manually call these functions, you can find their declarations in the specific header files. For example:
34+
35+
### Organ
36+
```
37+
void Organ_NoteOn(uint8_t ch __attribute__((unused)), uint8_t note, uint8_t vel __attribute__((unused)));
38+
void Organ_NoteOff(uint8_t ch __attribute__((unused)), uint8_t note);
39+
```
40+
41+
### Sampler
42+
```
43+
void Sampler_NoteOn(uint8_t ch, uint8_t note, uint8_t vel);
44+
void Sampler_NoteOff(uint8_t ch, uint8_t note, uint8_t vel __attribute__((unused)));
45+
```
46+
47+
You can then play notes programmatically by calling these functions. For example:
48+
49+
### Playing Notes
50+
To turn a note on:
51+
```
52+
Organ_NoteOn(0, 64, 127);
53+
```
54+
55+
To turn the note off:
56+
```
57+
Organ_NoteOff(0, 64);
58+
```
59+
60+
In this example:
61+
- **Channel:** `0` (corresponds to Channel 1 in MIDI terms).
62+
- **Note:** `64` (E4; see the [MIDI Note Numbers Reference](https://inspiredacoustics.com/en/MIDI_note_numbers_and_center_frequencies)).
63+
- **Velocity:** `127` (maximum volume).
64+
65+
For some instruments (e.g., an organ), the velocity (`vel`) may be ignored. The `__attribute__((unused))` annotation indicates that a parameter is not used by the function in such cases.
66+
67+
## Timing Limitations
68+
### Avoiding `delay(...)`
69+
Using `delay(...)` in the `loop` function is not recommended, as it will interfere with sound processing and cause distortion. Instead, implement precise timing mechanisms.
70+
71+
### Timing Calculations
72+
To manage timing, calculate the elapsed time per loop cycle using this formula:
73+
74+
```
75+
Elapsed Time = SAMPLE_BUFFER_SIZE / SAMPLE_RATE
76+
```
77+
78+
If a precise loop delay is required (e.g., for 1 Hz timing), consider using a counter to handle timing instead of relying on `delay(...)`.
79+
80+
---
81+
82+
This guide should help you effectively use the library to play notes programmatically without a hardware MIDI interface. Let me know if further clarification is needed!

0 commit comments

Comments
 (0)