Skip to content

Commit bf43797

Browse files
committed
Transform site from Scribbletune docs to 'Music with Code' platform
- Restructure navigation: Projects, Plugins, Articles (replacing Documentation, Examples, Github) - Move existing Scribbletune content under Projects > Scribbletune - Create scalable structure for adding new projects, plugins, and articles - Update homepage to reflect broader mission of music creation through programming - Add sample article on mathematical patterns in music - Maintain all existing functionality while enabling easy content expansion
1 parent 682fc87 commit bf43797

16 files changed

Lines changed: 978 additions & 57 deletions

File tree

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
import CodeBlock from "@/components/code-block"
2+
import { Calendar, Clock, ArrowLeft } from "lucide-react"
3+
import Link from "next/link"
4+
5+
export default function ArticlePage() {
6+
return (
7+
<div className="max-w-4xl mx-auto px-4 py-8">
8+
<Link
9+
href="/articles"
10+
className="text-blue-400 hover:text-blue-300 inline-flex items-center gap-1 mb-8"
11+
>
12+
<ArrowLeft size={16} />
13+
Back to Articles
14+
</Link>
15+
16+
<article className="prose prose-invert max-w-none">
17+
<header className="mb-8">
18+
<h1 className="text-4xl font-bold mb-4">The Mathematics of Musical Patterns</h1>
19+
<div className="flex items-center gap-4 text-gray-400 text-sm mb-4">
20+
<div className="flex items-center gap-1">
21+
<Calendar size={14} />
22+
January 15, 2025
23+
</div>
24+
<div className="flex items-center gap-1">
25+
<Clock size={14} />
26+
8 min read
27+
</div>
28+
</div>
29+
<div className="flex gap-2 mb-6">
30+
<span className="bg-blue-900/50 text-blue-400 px-3 py-1 rounded-full text-sm">Mathematics</span>
31+
<span className="bg-purple-900/50 text-purple-400 px-3 py-1 rounded-full text-sm">Patterns</span>
32+
<span className="bg-green-900/50 text-green-400 px-3 py-1 rounded-full text-sm">Algorithms</span>
33+
</div>
34+
</header>
35+
36+
<p className="text-xl text-gray-300 mb-8 leading-relaxed">
37+
Music and mathematics have been intertwined since ancient times. From the mathematical ratios
38+
that define harmony to the fractal patterns found in Bach's compositions, understanding these
39+
relationships can unlock new creative possibilities in algorithmic music generation.
40+
</p>
41+
42+
<h2>Fractals in Music Composition</h2>
43+
44+
<p>
45+
Fractals are mathematical objects that exhibit self-similarity at different scales. In music,
46+
we can apply fractal principles to create patterns that have structure across multiple time scales.
47+
</p>
48+
49+
<CodeBlock
50+
code={`const scribble = require('scribbletune');
51+
52+
// Generate a fractal-like melody using recursive subdivision
53+
function generateFractalMelody(scale, depth, length) {
54+
if (depth === 0) {
55+
return [scale[Math.floor(Math.random() * scale.length)]];
56+
}
57+
58+
const subPattern = generateFractalMelody(scale, depth - 1, length / 2);
59+
return [...subPattern, ...subPattern.map(note =>
60+
scribble.transpose(note, Math.random() > 0.5 ? '2M' : '-2M')
61+
)];
62+
}
63+
64+
// Create a clip with fractal structure
65+
const fractalScale = scribble.scale('C4 major');
66+
const fractalMelody = generateFractalMelody(fractalScale, 3, 16);
67+
68+
const clip = scribble.clip({
69+
notes: fractalMelody,
70+
pattern: 'x'.repeat(fractalMelody.length)
71+
});`}
72+
/>
73+
74+
<h2>Cellular Automata for Rhythm Generation</h2>
75+
76+
<p>
77+
Cellular automata are discrete mathematical models that can generate complex patterns from
78+
simple rules. Rule 30, for example, can create rhythmic patterns that feel both structured
79+
and unpredictable.
80+
</p>
81+
82+
<CodeBlock
83+
code={`// Implement Rule 30 cellular automaton for rhythm generation
84+
function rule30(left, center, right) {
85+
const state = (left << 2) | (center << 1) | right;
86+
return (30 >> state) & 1;
87+
}
88+
89+
function generateCellularRhythm(initialState, generations) {
90+
let currentState = initialState;
91+
const patterns = [currentState];
92+
93+
for (let i = 0; i < generations; i++) {
94+
const nextState = [];
95+
for (let j = 0; j < currentState.length; j++) {
96+
const left = currentState[(j - 1 + currentState.length) % currentState.length];
97+
const center = currentState[j];
98+
const right = currentState[(j + 1) % currentState.length];
99+
nextState[j] = rule30(left, center, right);
100+
}
101+
patterns.push([...nextState]);
102+
currentState = nextState;
103+
}
104+
105+
return patterns;
106+
}
107+
108+
// Generate drum pattern using cellular automata
109+
const initialPattern = [1, 0, 0, 1, 0, 1, 0, 0];
110+
const rhythmEvolution = generateCellularRhythm(initialPattern, 8);
111+
112+
rhythmEvolution.forEach((pattern, index) => {
113+
const clip = scribble.clip({
114+
notes: ['C2'],
115+
pattern: pattern.map(bit => bit ? 'x' : '-').join('')
116+
});
117+
scribble.midi(clip, \`cellular_rhythm_\${index}.mid\`);
118+
});`}
119+
/>
120+
121+
<h2>The Golden Ratio in Musical Structure</h2>
122+
123+
<p>
124+
The golden ratio (φ ≈ 1.618) appears frequently in nature and has been used by composers
125+
to create aesthetically pleasing musical structures. We can use this ratio to determine
126+
optimal lengths for musical sections and phrase structures.
127+
</p>
128+
129+
<h2>Practical Applications</h2>
130+
131+
<p>
132+
These mathematical concepts aren't just theoretical curiosities—they can be powerful tools
133+
for creating music that feels both familiar and surprising. Here are some practical ways
134+
to incorporate mathematical patterns into your compositions:
135+
</p>
136+
137+
<ul>
138+
<li><strong>Fractal melodies</strong> for creating coherent themes across different time scales</li>
139+
<li><strong>Cellular automata</strong> for generating evolving rhythmic patterns</li>
140+
<li><strong>Prime number sequences</strong> for creating non-repeating but structured patterns</li>
141+
<li><strong>Fibonacci numbers</strong> for determining phrase lengths and structural proportions</li>
142+
</ul>
143+
144+
<h2>Conclusion</h2>
145+
146+
<p>
147+
Mathematics provides a rich toolkit for algorithmic composition. By understanding and
148+
applying these concepts, we can create music that has both the complexity of natural
149+
phenomena and the intentionality of human creativity. The key is finding the right
150+
balance between mathematical structure and musical expression.
151+
</p>
152+
153+
<div className="bg-gray-800/50 rounded-lg p-6 mt-8">
154+
<h3 className="text-lg font-semibold mb-3">Try It Yourself</h3>
155+
<p className="text-gray-300 mb-4">
156+
Experiment with these mathematical concepts in your own compositions. Start with simple
157+
patterns and gradually increase complexity as you become comfortable with the techniques.
158+
</p>
159+
<Link
160+
href="/projects/scribbletune/documentation/getting-started/installation"
161+
className="text-blue-400 hover:text-blue-300 inline-flex items-center gap-1"
162+
>
163+
Get Started with Scribbletune
164+
</Link>
165+
</div>
166+
</article>
167+
</div>
168+
)
169+
}

app/(articles)/articles/page.tsx

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
import Link from "next/link"
2+
import { Calendar, Clock, ArrowRight, Tag } from "lucide-react"
3+
4+
export default function ArticlesPage() {
5+
const articles = [
6+
{
7+
title: "The Mathematics of Musical Patterns",
8+
excerpt: "Exploring how mathematical concepts like fractals and cellular automata can generate compelling musical sequences.",
9+
date: "2025-01-15",
10+
readTime: "8 min read",
11+
category: "Algorithm Design",
12+
tags: ["Mathematics", "Patterns", "Algorithms"],
13+
slug: "mathematics-of-musical-patterns",
14+
featured: true
15+
},
16+
{
17+
title: "Building Real-time Audio Processing with Web Audio API",
18+
excerpt: "A deep dive into creating responsive audio effects and synthesis engines in the browser.",
19+
date: "2025-01-10",
20+
readTime: "12 min read",
21+
category: "Web Audio",
22+
tags: ["WebAudio", "JavaScript", "Real-time"],
23+
slug: "realtime-audio-processing-web-audio-api",
24+
featured: false
25+
}
26+
// Future articles will be added here
27+
]
28+
29+
const categories = [
30+
{ name: "Algorithm Design", count: 1 },
31+
{ name: "Web Audio", count: 1 },
32+
{ name: "Music Theory", count: 0 },
33+
{ name: "Plugin Development", count: 0 },
34+
{ name: "Machine Learning", count: 0 }
35+
]
36+
37+
const formatDate = (dateString: string) => {
38+
return new Date(dateString).toLocaleDateString('en-US', {
39+
year: 'numeric',
40+
month: 'long',
41+
day: 'numeric'
42+
})
43+
}
44+
45+
return (
46+
<div className="max-w-7xl mx-auto px-4 py-8">
47+
<div className="mb-12">
48+
<h1 className="text-4xl md:text-5xl font-bold mb-4 bg-clip-text text-transparent bg-gradient-to-r from-blue-400 to-purple-400">
49+
Articles
50+
</h1>
51+
<p className="text-xl text-gray-300 max-w-3xl">
52+
Research, insights, and deep dives into music technology, algorithmic composition, and creative coding.
53+
</p>
54+
</div>
55+
56+
<div className="grid lg:grid-cols-4 gap-8">
57+
<div className="lg:col-span-3">
58+
{/* Featured Article */}
59+
{articles.filter(article => article.featured).map((article, index) => (
60+
<div key={index} className="bg-gradient-to-r from-blue-900/30 to-purple-900/30 rounded-lg p-8 mb-8 border border-blue-500/20">
61+
<div className="flex items-center gap-2 mb-3">
62+
<span className="bg-blue-600 text-white px-2 py-1 rounded text-xs font-semibold">
63+
FEATURED
64+
</span>
65+
<span className="text-gray-400 text-sm">{article.category}</span>
66+
</div>
67+
<h2 className="text-3xl font-bold mb-4">{article.title}</h2>
68+
<p className="text-gray-300 text-lg mb-4">{article.excerpt}</p>
69+
<div className="flex items-center gap-4 mb-4">
70+
<div className="flex items-center gap-1 text-gray-400 text-sm">
71+
<Calendar size={14} />
72+
{formatDate(article.date)}
73+
</div>
74+
<div className="flex items-center gap-1 text-gray-400 text-sm">
75+
<Clock size={14} />
76+
{article.readTime}
77+
</div>
78+
</div>
79+
<div className="flex items-center justify-between">
80+
<div className="flex gap-2">
81+
{article.tags.map((tag, tagIndex) => (
82+
<span
83+
key={tagIndex}
84+
className="bg-gray-700 text-gray-300 px-2 py-1 rounded text-xs"
85+
>
86+
{tag}
87+
</span>
88+
))}
89+
</div>
90+
<Link
91+
href={`/articles/${article.slug}`}
92+
className="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-md flex items-center gap-2 transition-colors"
93+
>
94+
Read Article <ArrowRight size={16} />
95+
</Link>
96+
</div>
97+
</div>
98+
))}
99+
100+
{/* Regular Articles */}
101+
<div className="space-y-6">
102+
{articles.filter(article => !article.featured).map((article, index) => (
103+
<div key={index} className="bg-gray-800/50 rounded-lg p-6 border border-gray-700">
104+
<div className="flex items-center gap-2 mb-3">
105+
<span className="text-gray-400 text-sm">{article.category}</span>
106+
</div>
107+
<h3 className="text-2xl font-bold mb-3">{article.title}</h3>
108+
<p className="text-gray-300 mb-4">{article.excerpt}</p>
109+
<div className="flex items-center gap-4 mb-4">
110+
<div className="flex items-center gap-1 text-gray-400 text-sm">
111+
<Calendar size={14} />
112+
{formatDate(article.date)}
113+
</div>
114+
<div className="flex items-center gap-1 text-gray-400 text-sm">
115+
<Clock size={14} />
116+
{article.readTime}
117+
</div>
118+
</div>
119+
<div className="flex items-center justify-between">
120+
<div className="flex gap-2">
121+
{article.tags.map((tag, tagIndex) => (
122+
<span
123+
key={tagIndex}
124+
className="bg-gray-700 text-gray-300 px-2 py-1 rounded text-xs"
125+
>
126+
{tag}
127+
</span>
128+
))}
129+
</div>
130+
<Link
131+
href={`/articles/${article.slug}`}
132+
className="text-blue-400 hover:text-blue-300 flex items-center gap-1"
133+
>
134+
Read More <ArrowRight size={14} />
135+
</Link>
136+
</div>
137+
</div>
138+
))}
139+
</div>
140+
141+
{/* Coming Soon */}
142+
<div className="mt-8 bg-gray-800/30 rounded-lg p-6 text-center">
143+
<h3 className="text-xl font-semibold mb-3">More Articles Coming Soon</h3>
144+
<p className="text-gray-400">
145+
Research in progress on topics like machine learning for music generation,
146+
advanced synthesis techniques, and creative coding workflows.
147+
</p>
148+
</div>
149+
</div>
150+
151+
{/* Sidebar */}
152+
<div className="lg:col-span-1">
153+
<div className="bg-gray-800/50 rounded-lg p-6 border border-gray-700">
154+
<h3 className="text-lg font-semibold mb-4">Categories</h3>
155+
<div className="space-y-2">
156+
{categories.map((category, index) => (
157+
<div key={index} className="flex items-center justify-between">
158+
<span className="text-gray-300">{category.name}</span>
159+
<span className="bg-gray-700 text-gray-300 px-2 py-1 rounded text-xs">
160+
{category.count}
161+
</span>
162+
</div>
163+
))}
164+
</div>
165+
</div>
166+
167+
<div className="bg-gray-800/50 rounded-lg p-6 border border-gray-700 mt-6">
168+
<h3 className="text-lg font-semibold mb-4">Newsletter</h3>
169+
<p className="text-gray-400 text-sm mb-4">
170+
Get notified when new articles about music technology and creative coding are published.
171+
</p>
172+
<button className="w-full bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-md transition-colors">
173+
Subscribe
174+
</button>
175+
</div>
176+
</div>
177+
</div>
178+
</div>
179+
)
180+
}

app/(articles)/layout.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import type React from "react";
2+
import Header from "@/components/header";
3+
4+
export default function ArticlesLayout({
5+
children,
6+
}: {
7+
children: React.ReactNode;
8+
}) {
9+
return (
10+
<div className="min-h-screen bg-[#1a1e24] text-gray-200">
11+
<Header />
12+
<main>{children}</main>
13+
</div>
14+
);
15+
}

0 commit comments

Comments
 (0)