Revert to YouTube player for music to support vocals and diverse beats
This commit is contained in:
@@ -7,13 +7,11 @@ window.rainData = function() {
|
|||||||
rainIntensity: 50,
|
rainIntensity: 50,
|
||||||
wind: 0,
|
wind: 0,
|
||||||
lofiFilter: 800,
|
lofiFilter: 800,
|
||||||
musicVolume: 50,
|
|
||||||
drops: [],
|
drops: [],
|
||||||
audioCtx: null,
|
audioCtx: null,
|
||||||
noiseNode: null,
|
noiseNode: null,
|
||||||
filterNode: null,
|
filterNode: null,
|
||||||
gainNode: null,
|
gainNode: null,
|
||||||
beatInterval: null,
|
|
||||||
|
|
||||||
generateDrops(val) {
|
generateDrops(val) {
|
||||||
this.drops = [];
|
this.drops = [];
|
||||||
@@ -25,7 +23,7 @@ window.rainData = function() {
|
|||||||
try {
|
try {
|
||||||
this.audioCtx = new (window.AudioContext || window.webkitAudioContext)();
|
this.audioCtx = new (window.AudioContext || window.webkitAudioContext)();
|
||||||
|
|
||||||
// --- REGEN-SOUND (Weißes Rauschen) ---
|
// --- REGEN-SOUND ---
|
||||||
let bufferSize = 2 * this.audioCtx.sampleRate;
|
let bufferSize = 2 * this.audioCtx.sampleRate;
|
||||||
let noiseBuffer = this.audioCtx.createBuffer(1, bufferSize, this.audioCtx.sampleRate);
|
let noiseBuffer = this.audioCtx.createBuffer(1, bufferSize, this.audioCtx.sampleRate);
|
||||||
let output = noiseBuffer.getChannelData(0);
|
let output = noiseBuffer.getChannelData(0);
|
||||||
@@ -50,87 +48,11 @@ window.rainData = function() {
|
|||||||
|
|
||||||
this.noiseNode.start();
|
this.noiseNode.start();
|
||||||
|
|
||||||
// --- BEAT GENERATOR (Lofi Hip Hop) ---
|
|
||||||
let bpm = 70;
|
|
||||||
let stepTime = 60 / bpm / 2; // 8tel Noten
|
|
||||||
let step = 0;
|
|
||||||
|
|
||||||
this.beatInterval = setInterval(() => {
|
|
||||||
let now = this.audioCtx.currentTime;
|
|
||||||
|
|
||||||
// Boom Bap Beat (Kick, Snare, Hi-Hat)
|
|
||||||
if (step === 0 || step === 3) {
|
|
||||||
this.playKick(now);
|
|
||||||
}
|
|
||||||
if (step === 4) {
|
|
||||||
this.playSnare(now, noiseBuffer);
|
|
||||||
}
|
|
||||||
if (step % 2 === 1) {
|
|
||||||
this.playHiHat(now, noiseBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
step = (step + 1) % 8;
|
|
||||||
}, stepTime * 1000);
|
|
||||||
|
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
console.log('Audio failed', e);
|
console.log('Audio failed', e);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
playKick(time) {
|
|
||||||
let osc = this.audioCtx.createOscillator();
|
|
||||||
let gain = this.audioCtx.createGain();
|
|
||||||
osc.type = 'sine';
|
|
||||||
osc.frequency.setValueAtTime(120, time);
|
|
||||||
osc.frequency.exponentialRampToValueAtTime(40, time + 0.15); // Pitch drop
|
|
||||||
|
|
||||||
gain.gain.setValueAtTime((this.musicVolume / 100) * 0.4, time);
|
|
||||||
gain.gain.linearRampToValueAtTime(0, time + 0.2);
|
|
||||||
|
|
||||||
osc.connect(gain);
|
|
||||||
gain.connect(this.audioCtx.destination);
|
|
||||||
osc.start(time);
|
|
||||||
osc.stop(time + 0.2);
|
|
||||||
},
|
|
||||||
|
|
||||||
playSnare(time, noiseBuffer) {
|
|
||||||
let noise = this.audioCtx.createBufferSource();
|
|
||||||
noise.buffer = noiseBuffer;
|
|
||||||
|
|
||||||
let filter = this.audioCtx.createBiquadFilter();
|
|
||||||
filter.type = 'bandpass';
|
|
||||||
filter.frequency.setValueAtTime(1000, time);
|
|
||||||
|
|
||||||
let gain = this.audioCtx.createGain();
|
|
||||||
gain.gain.setValueAtTime((this.musicVolume / 100) * 0.2, time);
|
|
||||||
gain.gain.linearRampToValueAtTime(0, time + 0.15);
|
|
||||||
|
|
||||||
noise.connect(filter);
|
|
||||||
filter.connect(gain);
|
|
||||||
gain.connect(this.audioCtx.destination);
|
|
||||||
noise.start(time);
|
|
||||||
noise.stop(time + 0.15);
|
|
||||||
},
|
|
||||||
|
|
||||||
playHiHat(time, noiseBuffer) {
|
|
||||||
let noise = this.audioCtx.createBufferSource();
|
|
||||||
noise.buffer = noiseBuffer;
|
|
||||||
|
|
||||||
let filter = this.audioCtx.createBiquadFilter();
|
|
||||||
filter.type = 'highpass';
|
|
||||||
filter.frequency.setValueAtTime(6000, time);
|
|
||||||
|
|
||||||
let gain = this.audioCtx.createGain();
|
|
||||||
gain.gain.setValueAtTime((this.musicVolume / 100) * 0.05, time);
|
|
||||||
gain.gain.linearRampToValueAtTime(0, time + 0.05);
|
|
||||||
|
|
||||||
noise.connect(filter);
|
|
||||||
filter.connect(gain);
|
|
||||||
gain.connect(this.audioCtx.destination);
|
|
||||||
noise.start(time);
|
|
||||||
noise.stop(time + 0.05);
|
|
||||||
},
|
|
||||||
|
|
||||||
updateAudio() {
|
updateAudio() {
|
||||||
if (this.gainNode) {
|
if (this.gainNode) {
|
||||||
this.gainNode.gain.linearRampToValueAtTime(this.rainIntensity / 200 * 0.05, this.audioCtx.currentTime + 0.2);
|
this.gainNode.gain.linearRampToValueAtTime(this.rainIntensity / 200 * 0.05, this.audioCtx.currentTime + 0.2);
|
||||||
@@ -186,19 +108,26 @@ window.rainData = function() {
|
|||||||
<label class="block text-xs font-mono text-stone-500 uppercase mb-2 tracking-widest">Lofi-Filter (Muffigkeit): <span x-text="lofiFilter" class="text-emerald-400"></span> Hz</label>
|
<label class="block text-xs font-mono text-stone-500 uppercase mb-2 tracking-widest">Lofi-Filter (Muffigkeit): <span x-text="lofiFilter" class="text-emerald-400"></span> Hz</label>
|
||||||
<input type="range" min="200" max="2000" x-model="lofiFilter" class="w-full h-2 bg-stone-800 rounded-lg appearance-none cursor-pointer accent-emerald-500">
|
<input type="range" min="200" max="2000" x-model="lofiFilter" class="w-full h-2 bg-stone-800 rounded-lg appearance-none cursor-pointer accent-emerald-500">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Music Volume -->
|
|
||||||
<div>
|
|
||||||
<label class="block text-xs font-mono text-stone-500 uppercase mb-2 tracking-widest">Beat-Lautstärke: <span x-text="musicVolume" class="text-emerald-400"></span>%</label>
|
|
||||||
<input type="range" min="0" max="100" x-model="musicVolume" class="w-full h-2 bg-stone-800 rounded-lg appearance-none cursor-pointer accent-emerald-500">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex justify-between text-xs text-stone-600 font-mono pt-4 border-t border-stone-800">
|
<div class="flex justify-between text-xs text-stone-600 font-mono pt-4 border-t border-stone-800">
|
||||||
<span>Sound läuft automatisch</span>
|
<span>Sound läuft automatisch</span>
|
||||||
<span class="text-emerald-400">Realtime Web Audio Rain & Lofi Beat</span>
|
<span class="text-emerald-400">Realtime Web Audio Rain</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- YouTube Player with Vocals/Diverse Beats -->
|
||||||
|
<div class="glass p-6 rounded-2xl border border-stone-800 space-y-4">
|
||||||
|
<div>
|
||||||
|
<span class="block text-xs font-mono text-stone-500 uppercase mb-1 tracking-widest">Musik (Lofi mit Vocals)</span>
|
||||||
|
<span class="text-xs text-stone-400">Echte Tracks für mehr Vielfalt & Gesang</span>
|
||||||
|
</div>
|
||||||
|
<div class="rounded-lg overflow-hidden border border-stone-800 aspect-video">
|
||||||
|
<!-- Größerer Player für bessere Bedienung -->
|
||||||
|
<iframe width="100%" height="100%" src="https://www.youtube.com/embed/jfKfPfyJRdk" title="Lofi Hip Hop" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
|
||||||
|
</div>
|
||||||
|
<p class="text-xs text-stone-500 leading-relaxed">Da echte Vocals und komplexe Beats nicht im Browser generiert werden können, nutzen wir diesen Stream. Spiele ihn ab und nutze die Regler oben für den Regensound!</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Content -->
|
<!-- Content -->
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-8 text-stone-400 text-sm leading-relaxed">
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-8 text-stone-400 text-sm leading-relaxed">
|
||||||
<div class="space-y-4">
|
<div class="space-y-4">
|
||||||
|
|||||||
Reference in New Issue
Block a user