algorithmic-harmony-maestro / generator.html
flen-crypto's picture
generate random track descriptions via an animated dice button, with suggestions taken from using Deepseeks API
edb69f0 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Track Generator - Algorithmic Harmony Maestro</title>
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
<link rel="stylesheet" href="style.css">
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
<script src="https://unpkg.com/feather-icons"></script>
</head>
<body class="bg-gradient-to-br from-purple-900 via-blue-900 to-indigo-900 min-h-screen">
<custom-navbar></custom-navbar>
<main class="container mx-auto px-4 py-8 pt-20">
<div class="max-w-4xl mx-auto">
<h1 class="text-4xl md:text-5xl font-bold text-white text-center mb-8">
AI Music Generator
</h1>
<p class="text-gray-300 text-center mb-12">
Describe your musical vision and let AI create an algorithm-optimized masterpiece
</p>
<!-- Prompt Input Section -->
<div class="glass rounded-2xl p-8 mb-8">
<div class="flex items-center justify-between mb-6">
<h2 class="text-2xl font-semibold text-white">Enter Your Music Prompt</h2>
<div class="flex gap-2">
<button id="dice-btn" class="bg-purple-600 hover:bg-purple-700 p-3 rounded-full transition-all">
<i data-feather="dice" class="text-white"></i>
</button>
<button id="voice-btn" class="bg-purple-600 hover:bg-purple-700 p-3 rounded-full transition-all">
<i data-feather="mic" class="text-white"></i>
</button>
</div>
</div>
<div class="space-y-6">
<div>
<label class="block text-gray-300 mb-2">Describe your track:</label>
<textarea
id="music-prompt"
placeholder="e.g., 'Upbeat 115 BPM house track with soulful vocals, optimized for workout playlists'"
class="w-full h-32 bg-gray-800/50 border border-gray-700 rounded-lg p-4 text-white resize-none focus:outline-none focus:ring-2 focus:ring-purple-500"
></textarea>
</div>
<!-- Quick Templates -->
<div>
<label class="block text-gray-300 mb-2">Quick Templates:</label>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<button class="template-btn bg-gray-800/50 hover:bg-gray-700/50 border border-gray-700 rounded-lg p-4 text-left text-white transition-all">
<div class="font-semibold">Workout Energy</div>
<div class="text-sm text-gray-400">High BPM, driving beat, motivational</button>
<button class="template-btn bg-gray-800/50 hover:bg-gray-700/50 border border-gray-700 rounded-lg p-4 text-left text-white transition-all">
<div class="font-semibold">Chill Focus</div>
<div class="text-sm text-gray-400">Ambient, lo-fi, study-friendly</button>
<button class="template-btn bg-gray-800/50 hover:bg-gray-700/50 border border-gray-700 rounded-lg p-4 text-left text-white transition-all">
<div class="font-semibold">Emotional Ballad</div>
<div class="text-sm text-gray-400">Slow tempo, emotional vocals, cinematic</button>
<button class="template-btn bg-gray-800/50 hover:bg-gray-700/50 border border-gray-700 rounded-lg p-4 text-left text-white transition-all">
<div class="font-semibold">Party Anthem</div>
<div class="text-sm text-gray-400">Catchy hooks, danceable, festival-ready</button>
</div>
</div>
<!-- Advanced Settings -->
<div class="bg-gray-800/30 rounded-lg p-4">
<div class="flex items-center justify-between cursor-pointer" onclick="toggleAdvancedSettings()">
<span class="text-white font-semibold">Advanced Settings</span>
<i data-feather="chevron-down" class="text-gray-400"></i>
</div>
<div id="advanced-settings" class="hidden space-y-4 mt-4">
<div class="grid grid-cols-2 gap-4">
<div>
<label class="block text-gray-300 text-sm mb-1">BPM Range</label>
<input type="range" min="60" max="200" value="120" class="w-full">
</div>
<div>
<label class="block text-gray-300 text-sm mb-1">Energy Level</label>
<input type="range" min="1" max="10" value="7" class="w-full">
</div>
</div>
<div class="grid grid-cols-2 gap-4">
<div>
<label class="block text-gray-300 text-sm mb-1">Duration (seconds)</label>
<input type="number" value="180" class="w-full bg-gray-700/50 border border-gray-600 rounded px-3 py-2 text-white">
</div>
<div>
<label class="block text-gray-300 text-sm mb-1">Key</label>
<select class="w-full bg-gray-700/50 border border-gray-600 rounded px-3 py-2 text-white">
<option>C Major</option>
<option>A Minor</option>
<option>G Major</option>
<option>E Minor</option>
</select>
</div>
</div>
</div>
</div>
<button id="generate-btn" class="w-full bg-gradient-to-r from-purple-600 to-pink-600 hover:from-purple-700 hover:to-pink-700 text-white font-semibold py-4 rounded-lg transition-all transform hover:scale-105 pulse-glow">
<i data-feather="zap" class="inline mr-2"></i>
Generate Track
</button>
</div>
</div>
<!-- Results Section -->
<div id="results-section" class="hidden glass rounded-2xl p-8">
<h2 class="text-2xl font-semibold text-white mb-6">Generated Track</h2>
<!-- Audio Player -->
<div class="mb-6">
<div class="bg-gray-800/50 rounded-lg p-4">
<div class="flex items-center justify-between mb-4">
<div class="text-white font-semibold" id="track-title">Your Generated Track</div>
<div class="text-gray-400 text-sm" id="track-duration">0:00 / 3:00</div>
</div>
<audio id="audio-player" controls class="w-full">
Your browser does not support the audio element.
</audio>
</div>
<!-- Algorithm Analysis -->
<div class="grid md:grid-cols-2 gap-6 mb-6">
<div class="bg-gray-800/30 rounded-lg p-4">
<h3 class="text-white font-semibold mb-3">Algorithm Compatibility</h3>
<div class="space-y-3">
<div class="flex justify-between items-center">
<span class="text-gray-300">Spotify Fit</span>
<span class="text-green-400 font-semibold" id="spotify-fit">84%</span>
</div>
<div class="flex justify-between items-center">
<span class="text-gray-300">SoundCloud Match</span>
<span class="text-green-400 font-semibold" id="soundcloud-match">92%</span>
</div>
<div class="flex justify-between items-center">
<span class="text-gray-300">Skip Resistance</span>
<span class="text-green-400 font-semibold" id="skip-resistance">88%</span>
</div>
</div>
</div>
<div class="bg-gray-800/30 rounded-lg p-4">
<h3 class="text-white font-semibold mb-3">Audio Features</h3>
<div class="space-y-2">
<div class="text-sm text-gray-300">Loudness: -14.2 LUFS</div>
<div class="text-sm text-gray-300">Tempo: 115 BPM</div>
<div class="text-sm text-gray-300">Key: C Major</div>
</div>
</div>
</div>
<!-- Recommended Tags -->
<div class="bg-gray-800/30 rounded-lg p-4">
<h3 class="text-white font-semibold mb-3">Optimized Metadata</h3>
<div class="space-y-3">
<div>
<label class="text-gray-300 text-sm">Title Suggestion:</label>
<input type="text" value="Soulful House Workout" class="w-full bg-gray-700/50 border border-gray-600 rounded px-3 py-2 text-white">
</div>
<div>
<label class="text-gray-300 text-sm">Tags:</label>
<div class="flex flex-wrap gap-2 mt-2">
<span class="bg-purple-600/50 text-white px-3 py-1 rounded-full text-sm">
house
</span>
<span class="bg-blue-600/50 text-white px-3 py-1 rounded-full text-sm">
workout
</span>
<span class="bg-pink-600/50 text-white px-3 py-1 rounded-full text-sm">
soulful
</span>
<span class="bg-indigo-600/50 text-white px-3 py-1 rounded-full text-sm">
electronic
</span>
</div>
</div>
</div>
<!-- Action Buttons -->
<div class="flex flex-col sm:flex-row gap-4 mt-6">
<button class="flex-1 bg-green-600 hover:bg-green-700 text-white py-3 rounded-lg font-semibold transition-all">
<i data-feather="upload" class="inline mr-2"></i>
Upload to SoundCloud
</button>
<button class="flex-1 bg-blue-600 hover:bg-blue-700 text-white py-3 rounded-lg font-semibold transition-all">
<i data-feather="music" class="inline mr-2"></i>
Submit to Spotify
</button>
<button class="flex-1 bg-gray-600 hover:bg-gray-700 text-white py-3 rounded-lg font-semibold transition-all">
<i data-feather="download" class="inline mr-2"></i>
Download WAV
</button>
</div>
</div>
</div>
</div>
</main>
<custom-footer></custom-footer>
<script src="components/navbar.js"></script>
<script src="components/footer.js"></script>
<script src="script.js"></script>
<script>
feather.replace();
// Dice button for random prompts
const diceBtn = document.getElementById('dice-btn');
const voiceBtn = document.getElementById('voice-btn');
const promptTextarea = document.getElementById('music-prompt');
const voiceRecognition = new VoiceRecognition();
diceBtn.addEventListener('click', async function() {
// Add rotation animation
diceBtn.classList.add('animate-spin');
try {
const response = await fetch('https://api.deepseek.com/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_DEEPSEEK_API_KEY' // Replace with actual API key
},
body: JSON.stringify({
model: 'deepseek-chat',
messages: [
{
role: 'user',
content: 'Generate 5 creative and diverse music track descriptions for AI music generation. Include different genres, moods, and styles. Format as a JSON array of strings.'
}
],
max_tokens: 500,
temperature: 0.8
})
});
if (!response.ok) {
throw new Error('Failed to fetch random prompts');
}
const data = await response.json();
const prompts = JSON.parse(data.choices[0].message.content);
// Pick a random prompt from the generated ones
const randomPrompt = prompts[Math.floor(Math.random() * prompts.length)];
promptTextarea.value = randomPrompt;
// Remove animation after a delay
setTimeout(() => {
diceBtn.classList.remove('animate-spin');
}, 1000);
} catch (error) {
console.error('Error fetching random prompt:', error);
// Fallback to predefined prompts if API fails
const fallbackPrompts = [
"Melodic deep house track with ethereal female vocals, perfect for sunset drives and chill vibes",
"Aggressive dubstep with heavy bass drops and glitch effects, optimized for festival crowds",
"Lo-fi hip hop beat with vinyl crackle and smooth jazz samples, ideal for study sessions",
"Upbeat pop anthem with catchy hooks and electronic elements, radio-ready production",
"Cinematic orchestral piece with epic brass and string sections, suitable for film trailers"
];
const randomPrompt = fallbackPrompts[Math.floor(Math.random() * fallbackPrompts.length)];
promptTextarea.value = randomPrompt;
diceBtn.classList.remove('animate-spin');
}
});
voiceBtn.addEventListener('click', function() {
if (voiceRecognition.isListening) {
voiceRecognition.stopListening();
voiceBtn.innerHTML = '<i data-feather="mic" class="text-white"></i>';
feather.replace();
} else {
voiceRecognition.startListening(
(transcript) => {
promptTextarea.value = transcript;
voiceBtn.innerHTML = '<i data-feather="mic" class="text-white"></i>';
feather.replace();
},
(error) => {
alert('Voice recognition error: ' + error);
}
);
voiceBtn.innerHTML = '<i data-feather="square" class="text-white"></i>';
feather.replace();
}
});
// Template buttons
document.querySelectorAll('.template-btn').forEach(btn => {
btn.addEventListener('click', function() {
const title = this.querySelector('.font-semibold').textContent;
const description = this.querySelector('.text-sm').textContent;
promptTextarea.value = `${title} - ${description}`;
});
});
// Generate button
document.getElementById('generate-btn').addEventListener('click', async function() {
const prompt = promptTextarea.value.trim();
if (!prompt) {
alert('Please enter a music prompt first!');
return;
}
// Show loading state
this.innerHTML = '<i data-feather="loader" class="animate-spin inline mr-2"></i> Generating...';
feather.replace();
// Simulate generation process
setTimeout(() => {
document.getElementById('results-section').classList.remove('hidden');
this.innerHTML = '<i data-feather="zap" class="inline mr-2"></i> Generate Track';
feather.replace();
}, 3000);
});
function toggleAdvancedSettings() {
const settings = document.getElementById('advanced-settings');
const icon = settings.previousElementSibling.querySelector('i');
settings.classList.toggle('hidden');
if (settings.classList.contains('hidden')) {
icon.setAttribute('data-feather', 'chevron-down');
} else {
icon.setAttribute('data-feather', 'chevron-up');
}
feather.replace();
}
</script>
</body>
</html>