1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
//! Circle of fifths - key relationships in Western music
//!
//! The circle of fifths is a fundamental concept in music theory showing the relationship
//! between the twelve tones of the chromatic scale through intervals of perfect fifths.
//!
//! Starting from any note and moving up by a perfect fifth (7 semitones) repeatedly,
//! you traverse all 12 chromatic notes before returning to the starting note.
//!
//! # Musical Application
//! - Generate chord progressions (jazz, classical, pop)
//! - Key modulations and transitions
//! - Harmonic exploration and voice leading
//! - Bass lines with strong harmonic movement
//! - Combine with scales for harmonic melodies
//!
//! # Theory
//! Starting from C (0): C(0) → G(7) → D(2) → A(9) → E(4) → B(11) → F#(6) → C#(1) → G#(8) → D#(3) → A#(10) → F(5) → C(0)
//!
//! # Example
//! ```
//! use tunes::sequences::circle_of_fifths;
//! use tunes::consts::{C4, G4, D4, A4, E4};
//!
//! // Generate 8 steps through circle of fifths starting from C
//! let fifths = circle_of_fifths(8, 0);
//! // Returns chromatic intervals: [0, 7, 2, 9, 4, 11, 6, 1]
//! // Which maps to notes: C, G, D, A, E, B, F#, C#
//!
//! // Add to root note to get actual frequencies
//! let root = C4;
//! let notes: Vec<f32> = fifths.iter()
//! .map(|&semitones| root * 2.0f32.powf(semitones as f32 / 12.0))
//! .collect();
//! ```
/// Generate a sequence through the circle of fifths
///
/// Returns chromatic semitone offsets (0-11) moving through the circle of fifths.
/// Each step is a perfect fifth (7 semitones) up from the previous note, wrapped to one octave.
///
/// # Arguments
/// * `n` - Number of steps to generate
/// * `start` - Starting chromatic note (0-11, where 0 = C, 1 = C#, etc.)
///
/// # Returns
/// Vector of chromatic semitone offsets (0-11) representing steps through the circle
///
/// # Example
/// ```
/// use tunes::sequences::circle_of_fifths;
///
/// // Starting from C (0)
/// let fifths = circle_of_fifths(5, 0);
/// assert_eq!(fifths, vec![0, 7, 2, 9, 4]); // C, G, D, A, E
///
/// // Starting from F (5)
/// let fifths_from_f = circle_of_fifths(4, 5);
/// assert_eq!(fifths_from_f, vec![5, 0, 7, 2]); // F, C, G, D
/// ```
/// Generate a sequence through the circle of fourths (reverse of fifths)
///
/// Returns chromatic semitone offsets moving backwards through the circle of fifths.
/// Each step is a perfect fourth (5 semitones) up, or equivalently a fifth down.
///
/// # Arguments
/// * `n` - Number of steps to generate
/// * `start` - Starting chromatic note (0-11)
///
/// # Returns
/// Vector of chromatic semitone offsets (0-11)
///
/// # Example
/// ```
/// use tunes::sequences::circle_of_fourths;
///
/// let fourths = circle_of_fourths(5, 0);
/// assert_eq!(fourths, vec![0, 5, 10, 3, 8]); // C, F, Bb, Eb, Ab
/// ```