Music notes
Miscellaneous notes about computer music
Contents
Ode To Joy
This is a handy quicky test:
int odeToJoy[] = { F2S,QUARTER, F2S,QUARTER, G2 ,QUARTER, A3 ,QUARTER, A3 ,QUARTER, G2 ,QUARTER, F2S,QUARTER, E2 ,QUARTER, D2 ,QUARTER, D2 ,QUARTER, E2 ,QUARTER, F2S,QUARTER, F2S,DOTTED_QUARTER, E2,EIGHTH, E2,HALF, F2S,QUARTER, F2S,QUARTER, G2 ,QUARTER, A3 ,QUARTER, A3 ,QUARTER, G2 ,QUARTER, F2S,QUARTER, E2 ,QUARTER, D2 ,QUARTER, D2 ,QUARTER, E2 ,QUARTER, F2S,QUARTER, E2 ,DOTTED_QUARTER, D2,EIGHTH, D2,HALF, E2 ,QUARTER, E2 ,QUARTER, F2S,QUARTER, D2 ,QUARTER, E2 ,QUARTER, F2S,EIGHTH, G2,EIGHTH, F2S,QUARTER, D2 ,QUARTER, E2 ,QUARTER, F2S,EIGHTH, G2,EIGHTH, F2S,QUARTER, E2 ,QUARTER, D2 ,QUARTER, E2 ,QUARTER, A,QUARTER, REST,ETERNITY } ;
Digital filter
filter ( input, tunefactor, damping ) { lowpass += tunefactor * bandpass ; highpass = input - lowwpass - damping * bandpass ; bandpass += tunefactor * highpass ; notch = lowpass + highpass ; // Optional! }
Another Low-pass filter
Calculate each output-signal sample as the sum of the input signal and the previous output signal with scaling. This defines a low pass single-pole filter:
Y_{n} = X_{n}.(1-T) + Y_{n-1}.T
Where:
- X_{n} is the input
- Y_{n} is the output, Y_{n–1} is the output from the previous loop.
- T is our frequency control: 0<T<1
Physically, T is the amount of decay between adjacent output samples for a 'step' input. You can directly specify the value of T or derive it from the time constant of the filter, d, which is the number of samples it takes the output to rise to 63.2% of the steady-state level for a lowpass filter. T=e^{–1/d}.
Instead of multiplying by 1–T, it is more convenient to divide by the F=1/(1–T):
Y_{n} = Y_{n–1} + (X_{n}–Y_{n–1})/F
You can determine the digital filter’s parameters using the following steps:
- Choose a value for F. Suppose F==8, so you can do a right-shift instead of a divide.
- Calculate T = 1–1/F = 1–1/8 = 0.875.
- Calculate the time constant as d = –1/ln(T) = –1/ln(0.875) = 7.49 samples.
- Multiply that into your sample rate: 22000/7.49 = 2.9kHz
Here are some sample values for a 22000Hz sample rate:
Freq. (Hz) | t | F | Freq. (Hz) | t | F | Freq. (Hz) | t | F | Freq. (Hz) | t | F | |||
22000 | 0.367 | 1.58 | 21000 | 0.384 | 1.62 | 20000 | 0.402 | 1.67 | 19000 | 0.421 | 1.72 | |||
18000 | 0.441 | 1.78 | 17000 | 0.461 | 1.85 | 16000 | 0.483 | 1.93 | 15000 | 0.505 | 2.02 | |||
14000 | 0.529 | 2.12 | 13000 | 0.553 | 2.24 | 12000 | 0.579 | 2.37 | 11000 | 0.606 | 2.54 | |||
10000 | 0.634 | 2.73 | 9000 | 0.664 | 2.98 | 8000 | 0.695 | 3.28 | 7000 | 0.727 | 3.66 | |||
6000 | 0.761 | 4.18 | 5000 | 0.796 | 4.91 | 4000 | 0.833 | 6.01 | 3000 | 0.872 | 7.84 | |||
2000 | 0.913 | 11.5 | 1000 | 0.955 | 22.5 | 900 | 0.959 | 24.9 | 850 | 0.962 | 26.4 | |||
800 | 0.964 | 27.9 | 750 | 0.966 | 29.8 | 700 | 0.968 | 31.9 | 650 | 0.970 | 34.3 | |||
600 | 0.973 | 37.1 | 550 | 0.975 | 40.5 | 500 | 0.977 | 44.4 | 450 | 0.979 | 49.4 | |||
400 | 0.981 | 55.4 | 375 | 0.983 | 59.1 | 350 | 0.984 | 63.3 | 325 | 0.985 | 68.2 | |||
300 | 0.986 | 73.7 | 275 | 0.987 | 80.4 | 250 | 0.988 | 88.5 | 225 | 0.989 | 98.4 | |||
200 | 0.990 | 110.0 | 175 | 0.992 | 126.0 | 149 | 0.993 | 147.0 | 100 | 0.995 | 219.0 | |||
75 | 0.996 | 292.0 | 50 | 0.997 | 440.0 |
Yet another
Summarized from this paper.
First order filter
(Similar to Y_{n} = Y_{n–1} + (X_{n}–Y_{n–1})/F as described above)
- Y = X.B0 + Z[0].B1 - Z[1].A1
- Z[1] = Y
- Z[0] = X
Where:
- X is the input
- Y is the output
Second order filter
- Y = X.B0 + Z[0].B1 + Z[1].B2 + Z[2].A1 + Z[3].A2
- Z[3] = Z[2]
- Z[2] = Y
- Z[1] = Z[0]
- Z[0] = X
The first order version is just this with B2 = A2 = 0.
Input parameters:
- Fc = cutoff frequency (Hz)
- Fs = sample rate (Hz)
- W = tan(pi.Fc/Fs)
- Q = quality factor
Filter Parameters | H(S) | N | B0 | B1 | B2 | A1 | A2 |
Lowpass 1st order | 1/(S + 1) | 1/(W + 1) | W*N | B0 | 0.0 | N*(W-1) | 0.0 |
Highpass 1st order | S/(S + 1) | 1/(W + 1) | N | -B0 | 0.0 | N*(W-1) | 0.0 |
Lowpass 2nd order | 1/(S^{2} + S/Q + 1) | 1/(W^{2} + W/Q + 1) | N*W^{2} | 2*B0 | B0 | 2*N*(W^{2} + 1) | N*(W^{2} + W/Q + 1) |
Highpass 2nd order | S^{2}/(S^{2} + S/Q + 1) | 1/(W^{2} + W/Q + 1) | N | -2*N | B0 | 2*N*(W^{2} + 1) | N*(W^{2} + W/Q + 1) |
Bandpass 2nd order | (S/Q)/(S^{2} + S/Q + 1) | 1/(W^{2} + W/Q + 1) | N*W/Q | 0.0 | -B0 | 2*N*(W^{2} + 1) | N*(W^{2} + W/Q + 1) |
Multiple cascaded filters
The first order lowpass or highpass section has a slope of 6dB/Octave, and the second order section has a slope of 12dB/Octave. If the better slope is required, you have to cascade several sections.
Butterworth
All stages of Butterworth filter have the same cutoff frequency Fc. The parameter which is different for the stages is the filter Q. Here is the table for Q for Butterworth up to 6-th order:
- ---
- 0.71
- --- 1.0
- 0.54 1.31
- --- 0.62 1.62
- 0.52 0.71 1.93
If the value of Q is skipped, it means this is a first order section. Otherwise it is a second order section.
Linkwitz-Riley
LR consists of two identical Butterworth filters in series. Use the same table that is used for Butterworth filter design.
Bessel
Bessel design is a little bit more complicated, since not only Q but the Fc also differs from the stage to stage.
You should multiply the Fc for each stage by the following coefficients:
- 1.00
- 1.27
- 1.32 1.45
- 1.60 1.43
- 1.50 1.76 1.56
- 1.90 1.69 1.60
The corresponding Q values are:
- ---
- 0.58
- --- 0.69
- 0.81 0.52
- ---- 0.92 0.56
- 1.02 0.61 0.51
If the value of Q is skipped, it means this is a first order section. Otherwise it is a second order section.
Wikiid Pages relating to Arduino (edit) |
Arduino |
Command line Arduino |
Startup code for Arduino |
Low level functions for Arduino |
Putting data in flash on the Arduino |
External resources for Arduino |
Board schematics for Arduino |
Misc notes: Circuit notes, Music notes, Stepper motors |
Wikiid Pages relating to MIDIfile (edit) |
MIDIfile player library API |
MIDIfile documentation |
Sources of MIDIfiles |