Folge dem Video um zu sehen, wie unsere Website als Web-App auf dem Startbildschirm installiert werden kann.
Anmerkung: Diese Funktion ist in einigen Browsern möglicherweise nicht verfügbar.
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Vibe DAW</title>
<style>
:root{--bg:#0d0d0f;--fg:#f2f2f4;--dim:#8a8a93;--acc:#c8ff3d;--panel:#17171b;--line:#2a2a31}
*{box-sizing:border-box}
body{margin:0;min-height:100vh;background:var(--bg);color:var(--fg);font-family:system-ui,-apple-system,sans-serif;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:18px;padding:24px 16px}
h1{font-size:13px;letter-spacing:.25em;color:var(--dim);margin:0;font-weight:600}
input{width:min(560px,90vw);background:var(--panel);border:1px solid var(--line);color:var(--fg);padding:16px 18px;border-radius:14px;font-size:16px;outline:none}
input:focus{border-color:var(--acc)}
button{background:#1d1d23;color:var(--fg);border:1px solid #2e2e36;border-radius:14px;padding:14px 20px;font-size:15px;cursor:pointer}
button:hover{border-color:var(--acc)}
button.big{background:var(--acc);color:#0d0d0f;border:none;font-weight:700;font-size:18px;padding:18px 36px}
.row{display:flex;gap:10px;flex-wrap:wrap;justify-content:center}
canvas{width:min(560px,90vw);height:90px;background:var(--panel);border-radius:12px}
#status{color:var(--dim);font-size:14px;min-height:20px;text-align:center;max-width:560px}
</style>
</head>
<body>
<h1>VIBE DAW</h1>
<input id="prompt" placeholder="z.B. dunkler Trap, 140 bpm, wehmütig" autocomplete="off">
<div class="row">
<button id="beat" class="big">Beat machen</button>
<button id="stop">■ Stop</button>
</div>
<div class="row">
<button id="rec">● Vocals aufnehmen</button>
<button id="slap">Make it slap</button>
<button id="export">WAV exportieren</button>
</div>
<canvas id="wave" width="1120" height="180"></canvas>
<div id="status">Schreib was rein und drück Beat machen. Für Vocals Kopfhörer nutzen, sonst nimmt das Mikro den Beat mit auf.</div>
<script>
const $ = id => document.getElementById(id);
const say = t => { $('status').textContent = t; };
const clamp = (v, lo, hi) => Math.min(hi, Math.max(lo, v));
const midiToFreq = m => 440 * Math.pow(2, (m - 69) / 12);
// 16 steps per bar (16ths)
const KITS = {
trap: { bpm: 140, kick: [0, 7, 10], snare: [8], hat: [0,2,4,6,8,10,12,14,15], bass: [0, 6, 10], mood: 'minor' },
boombap: { bpm: 90, kick: [0, 10], snare: [4, 12], hat: [0,2,4,6,8,10,12,14], bass: [0, 10], mood: 'minor' },
house: { bpm: 124, kick: [0,4,8,12], snare: [4, 12], hat: [2,6,10,14], bass: [2,6,10,14], mood: 'major' },
lofi: { bpm: 78, kick: [0, 10], snare: [4, 12], hat: [0,4,8,12], bass: [0, 8], mood: 'minor' },
};
// Akkorde als MIDI-Noten: Am F C G / C G Am F
const PROG = {
minor: [[57,60,64],[53,57,60],[60,64,67],[55,59,62]],
major: [[60,64,67],[55,59,62],[57,60,64],[53,57,60]],
};
const SLAP_TEXT = ['', 'Lauter.', 'Noch lauter.', 'Mehr Druck.', 'Maximum. Der Limiter sagt nein.'];
let audioCtx = null, src = null;
const state = { params: null, vocal: null, buffer: null, slap: 0 };
// ---------- Prompt -> Parameter (Keywords, kein Modell) ----------
function parsePrompt(text) {
const t = text.toLowerCase();
let kitName = 'boombap';
if (/trap|drill|sheesh|hard|808/.test(t)) kitName = 'trap';
else if (/house|club|dance|tanz/.test(t)) kitName = 'house';
else if (/lo-?fi|chill|study|ruhig/.test(t)) kitName = 'lofi';
const kit = KITS[kitName];
const m = t.match(/(\d{2,3})\s*bpm/);
const bpm = m ? clamp(+m[1], 60, 200) : kit.bpm;
const sad = /wehm|sad|traurig|melanch|emo|dunkel|dark|nacht|night/.test(t);
const happy = /happy|fröhlich|hype|party|sommer|summer|sun/.test(t);
const mood = sad ? 'minor' : happy ? 'major' : kit.mood;
return { kitName, bpm, mood };
}
// ---------- Synth-Bausteine ----------
function noiseBuffer(ctx) {
const b = ctx.createBuffer(1, ctx.sampleRate, ctx.sampleRate);
const d = b.getChannelData(0);
for (let i = 0; i < d.length; i++) d[i] = Math.random() * 2 - 1;
return b;
}
function kick(ctx, t, out) {
const o = ctx.createOscillator(), g = ctx.createGain();
o.frequency.setValueAtTime(150, t);
o.frequency.exponentialRampToValueAtTime(45, t + 0.12);
g.gain.setValueAtTime(1, t);
g.gain.exponentialRampToValueAtTime(0.001, t + 0.4);
o.connect(g).connect(out);
o.start(t); o.stop(t + 0.45);
}
function noiseHit(ctx, t, noise, out, type, freq, vol, len) {
const n = ctx.createBufferSource(); n.buffer = noise;
const f = ctx.createBiquadFilter(); f.type = type; f.frequency.value = freq;
const g = ctx.createGain();
g.gain.setValueAtTime(vol, t);
g.gain.exponentialRampToValueAtTime(0.001, t + len);
n.connect(f).connect(g).connect(out);
n.start(t, Math.random() * 0.5); n.stop(t + len + 0.05);
}
function pad(ctx, t, dur, freqs, out) {
const g = ctx.createGain(), f = ctx.createBiquadFilter();
f.type = 'lowpass'; f.frequency.value = 1100;
g.gain.setValueAtTime(0, t);
g.gain.linearRampToValueAtTime(0.07, t + 0.05);
g.gain.setValueAtTime(0.07, t + dur - 0.1);
g.gain.linearRampToValueAtTime(0, t + dur);
g.connect(f).connect(out);
freqs.forEach(fr => [-7, 7].forEach(det => {
const o = ctx.createOscillator();
o.type = 'sawtooth'; o.frequency.value = fr; o.detune.value = det;
o.connect(g); o.start(t); o.stop(t + dur);
}));
}
function bassNote(ctx, t, d, freq, out) {
const o = ctx.createOscillator(), f = ctx.createBiquadFilter(), g = ctx.createGain();
o.type = 'sawtooth'; o.frequency.value = freq;
f.type = 'lowpass'; f.frequency.value = 260;
g.gain.setValueAtTime(0.35, t);
g.gain.exponentialRampToValueAtTime(0.001, t + d);
o.connect(f).connect(g).connect(out);
o.start(t); o.stop(t + d + 0.05);
}
// ---------- Master-Chain: "Make it slap" ----------
function softClip(k) {
const n = 2048, c = new Float32Array(n);
for (let i = 0; i < n; i++) { const x = (i * 2) / n - 1; c[i] = Math.tanh(k * x) / Math.tanh(k); }
return c;
}
function buildMaster(ctx, level) {
const input = ctx.createGain();
const hp = ctx.createBiquadFilter(); hp.type = 'highpass'; hp.frequency.value = 30;
const comp = ctx.createDynamicsCompressor();
comp.threshold.value = -20 - level * 4;
comp.ratio.value = 3 + level * 2;
comp.attack.value = 0.005; comp.release.value = 0.2;
const shaper = ctx.createWaveShaper();
shaper.curve = softClip(0.5 + level * 0.6);
shaper.oversample = '4x';
const lim = ctx.createDynamicsCompressor();
lim.threshold.value = -1; lim.ratio.value = 20; lim.attack.value = 0.001; lim.release.value = 0.05;
const out = ctx.createGain(); out.gain.value = 0.9;
input.connect(hp).connect(comp).connect(shaper).connect(lim).connect(out).connect(ctx.destination);
return input;
}
// ---------- Loop rendern (offline, dann loopen / exportieren) ----------
function renderLoop(p) {
const spb = 60 / p.bpm, stepDur = spb / 4, barSec = spb * 4;
const ctx = new OfflineAudioContext(2, Math.ceil(barSec * p.bars * 44100), 44100);
const kit = KITS[p.kitName];
const master = buildMaster(ctx, p.slap);
const noise = noiseBuffer(ctx);
const prog = PROG[p.mood];
for (let bar = 0; bar < p.bars; bar++) {
const barT = bar * barSec;
for (let s = 0; s < 16; s++) {
const t = barT + s * stepDur;
if (kit.kick.includes(s)) kick(ctx, t, master);
if (kit.snare.includes(s)) noiseHit(ctx, t, noise, master, 'bandpass', 1800, 0.5, 0.2);
if (kit.hat.includes(s)) noiseHit(ctx, t, noise, master, 'highpass', 7000, 0.15, 0.05);
}
const chord = prog[bar % prog.length];
pad(ctx, barT, barSec, chord.map(midiToFreq), master);
kit.bass.forEach(s => bassNote(ctx, barT + s * stepDur, stepDur * 2, midiToFreq(chord[0] - 24), master));
}
// Vocals: Original + Ad-lib-Delay (3/4-Beat)
if (p.vocal) {
const src = ctx.createBufferSource(); src.buffer = p.vocal;
const vg = ctx.createGain(); vg.gain.value = 1.1;
src.connect(vg).connect(master);
const d = ctx.createDelay(); d.delayTime.value = spb * 0.75;
const fb = ctx.createGain(); fb.gain.value = 0.3;
const wet = ctx.createGain(); wet.gain.value = 0.35;
vg.connect(d); d.connect(fb).connect(d); d.connect(wet).connect(master);
src.start(0);
}
return ctx;
}
// ---------- Playback ----------
function stop() {
if (src) { try { src.stop(); } catch (e) {} src = null; }
}
async function play(msg) {
if (!state.params) { say('Erst Beat machen.'); return; }
const p = { ...state.params, slap: state.slap, vocal: state.vocal };
const barSec = 4 * 60 / p.bpm;
p.bars = p.vocal ? clamp(Math.ceil(p.vocal.duration / barSec), 2, 16) : 8;
say('Rendert…');
state.buffer = await renderLoop(p).startRendering();
audioCtx ??= new AudioContext();
await audioCtx.resume();
stop();
src = audioCtx.createBufferSource();
src.buffer = state.buffer; src.loop = true;
src.connect(audioCtx.destination); src.start();
drawWave(state.buffer);
say(msg || `${p.kitName} · ${p.bpm} bpm · ${p.mood === 'minor' ? 'wehmütig (moll)' : 'hell (dur)'}`);
}
function drawWave(buf) {
const c = $('wave'), g = c.getContext('2d');
g.clearRect(0, 0, c.width, c.height);
const d = buf.getChannelData(0), step = Math.max(1, Math.floor(d.length / c.width));
g.fillStyle = '#c8ff3d';
for (let x = 0; x < c.width; x++) {
let mx = 0;
for (let i = 0; i < step; i++) mx = Math.max(mx, Math.abs(d[x * step + i] || 0));
const h = mx * c.height;
g.fillRect(x, (c.height - h) / 2, 1, h);
}
}
// ---------- WAV-Export ----------
function encodeWav(buf) {
const ch = buf.numberOfChannels, sr = buf.sampleRate, len = buf.length;
const view = new DataView(new ArrayBuffer(44 + len * ch * 2));
const w = (o, s) => { for (let i = 0; i < s.length; i++) view.setUint8(o + i, s.charCodeAt(i)); };
w(0, 'RIFF'); view.setUint32(4, 36 + len * ch * 2, true); w(8, 'WAVE');
w(12, 'fmt '); view.setUint32(16, 16, true); view.setUint16(20, 1, true);
view.setUint16(22, ch, true); view.setUint32(24, sr, true);
view.setUint32(28, sr * ch * 2, true); view.setUint16(32, ch * 2, true);
view.setUint16(34, 16, true); w(36, 'data'); view.setUint32(40, len * ch * 2, true);
const chans = [...Array(ch)].map((_, i) => buf.getChannelData(i));
let o = 44;
for (let i = 0; i < len; i++) for (let c = 0; c < ch; c++) {
const s = Math.max(-1, Math.min(1, chans[c][i]));
view.setInt16(o, s < 0 ? s * 0x8000 : s * 0x7fff, true); o += 2;
}
return view.buffer;
}
// ---------- Vocals aufnehmen ----------
let recorder = null, chunks = [];
$('rec').onclick = async () => {
if (recorder && recorder.state === 'recording') { recorder.stop(); return; }
try {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
chunks = [];
recorder = new MediaRecorder(stream);
recorder.ondataavailable = e => chunks.push(e.data);
recorder.onstop = async () => {
stream.getTracks().forEach(t => t.stop());
$('rec').textContent = '● Vocals aufnehmen';
const blob = new Blob(chunks, { type: recorder.mimeType });
const tmp = new AudioContext();
state.vocal = await tmp.decodeAudioData(await blob.arrayBuffer());
tmp.close();
say('Vocals drin. Nochmal aufnehmen oder Make it slap.');
if (state.params) play('Vocals drin · ' + state.params.bpm + ' bpm');
};
recorder.start();
$('rec').textContent = '■ Stopp';
say('Nimmt auf… nochmal klicken zum Stoppen.');
} catch (e) {
say('Mikro geht nicht: ' + e.message);
}
};
// ---------- Buttons ----------
$('beat').onclick = () => {
audioCtx ??= new AudioContext();
state.params = parsePrompt($('prompt').value || 'boom bap');
state.slap = 0;
play();
};
$('stop').onclick = () => { stop(); say('Gestoppt.'); };
$('slap').onclick = () => {
if (!state.params) { say('Erst Beat machen.'); return; }
state.slap = Math.min(state.slap + 1, 4);
play(SLAP_TEXT[state.slap]);
};
$('export').onclick = () => {
if (!state.buffer) { say('Erst Beat machen.'); return; }
const url = URL.createObjectURL(new Blob([encodeWav(state.buffer)], { type: 'audio/wav' }));
const a = document.createElement('a');
a.href = url; a.download = `vibe-${Date.now()}.wav`; a.click();
setTimeout(() => URL.revokeObjectURL(url), 2000);
say('WAV gespeichert (ein Loop). Den Rest machst du selbst.');
};
$('prompt').addEventListener('keydown', e => { if (e.key === 'Enter') $('beat').click(); });
</script>
</body>
</html>
Ist das nicht naiv? Hoffentlich ist das nicht der einzige Grund für Deine DAW.Ich habe mich entschieden für meine DAW genügend Geld zu bezahlen, damit Menschen damit ihr Leben finanzieren können.
Schon bald wird man sagen können, dass man z.B. einen Cubase Clone haben will, aber mit zusätzlich dies und jenem und die KI wird das perfekt ausspucken. Die Vorarbeit haben dann die Steinberg* Leute geleistet, genauso wie die damaligen Synthesizer Pioniere.Ich empfehle eine reine KI DAW zu meiden, selbst wenn sie einigermassen brauchbar ist. Ansonsten werdet ihr bald nichts mehr andres auf dem Mark finden, da die humanen Entwickler brotlos und entlassen sind. Dann werdet ihr nur noch solche DAW runterladen können.
Das ist genau der Knackpunkt!Die ganzen Software Schmieden werden bzw tun es doch längst genauso KI einsetzen. Die binden Dir das nicht auf Deine Nase.
So siehts aus. Technologie und Vorgehensweise ändern sich. Ob man das nun gut findet oder nicht.Niemand braucht mehr Kupplungsgehäuse. Bremssattel werden auch immer weniger gebraucht.
Da kannste gleich weiter machen mit Deiner Solidarität.
Kaufst Dir weiter Verbrenner Auto damit die Leute weiter arbeiten können.
Programmierer werden definitiv durch KI ersetzt werden und sind damit nicht nur billiger, sondern auch noch erheblich leistungsfähiger.
Deswegen sind auch Restaurants und Imbissbuden im vorherigen Jahrhundert ausgestorben, da unser Essen jetzt einfach und schnell von uns selbst in der Mikrowelle zubereitet werden kann.Jeder wird seine zukünftig benötigte Software einfach mit wenigen Sätzen und quasi fast kostenlos bei einer KI bestellen können.
Ob in 5, 10 oder 20 Jahren, aber das ist völlig vorhersehbar, ganz ohne Glaskugel. Programmierer werden definitiv durch KI ersetzt werden und sind damit nicht nur billiger, sondern auch noch erheblich leistungsfähiger. Wir erleben gerade erst die Anfänge.

Schon bald wird man sagen können, dass man z.B. einen Cubase Clone haben will, aber mit zusätzlich dies und jenem und die KI wird das perfekt ausspucken. Die Vorarbeit haben dann die Steinberg Leute geleistet, genauso wie die damaligen Synthesizer Pioniere.
Jeder wird seine zukünftig benötigte Software einfach mit wenigen Sätzen und quasi fast kostenlos bei einer KI bestellen können.
Ob in 5, 10 oder 20 Jahren, aber das ist völlig vorhersehbar, ganz ohne Glaskugel. Programmierer werden definitiv durch KI ersetzt werden und sind damit nicht nur billiger, sondern auch noch erheblich leistungsfähiger. Wir erleben gerade erst die Anfänge.
Der technische Fortschritt schreitet extrem schnell voran, die Kurve geht steil nach oben und niemand weiß, wo das endet.
... Ich sollte wieder mehr einfach mal ohne Rechner klampfen glaub ich.Der Lachsmiley war wegen deinem PessimismusJa nee, sign of time. Don't look back in Anger...
, nicht weil Leute auch in anderen Bereichen ihre Arbeitsplätze verlieren. That's not f'cking funny.Doch natürlich braucht man sie. Sie werden nur nicht mehr hier hergestellt sondern im Ausland. Eigentlich ist es andersrum: man braucht weiterhin Autozulieferer aber Deutschland braucht man nicht unbedingt mehr. Wenn hier nur noch Wald ist oder das ganze Land aus elektrobetrieben Dienstleistungen (Lieferando und Lastenräder) besteht, dreht sich die Erde weiter und andere übernehmen die Aufgaben ehemals deutscher Firmen.Niemand braucht mehr Kupplungsgehäuse. Bremssattel werden auch immer weniger gebraucht.
Der Unterschied ist aber, dass Programmierer wissen was der KI ausgegebene Code bedeutet und ob er eventuell falsch ist. Ein Prompteingeber weiß es nicht.Die ganzen Software Schmieden werden bzw tun es doch längst genauso KI einsetzen. Die binden Dir das nicht auf Deine Nase.
Generell sehe ich schwarz für die gesamte Gilde der Software Entwickler.
Was hindert Steinberg*/ Yamaha daran, ein Cubase zu veröffentlichen, welches vom Nutzer über prompts selbst modifizierbar ist? Aber mit Qualitätskontrolle und rechtlich auf der sicheren Seite.Schon bald wird man sagen können, dass man z.B. einen Cubase Clone haben will, aber mit zusätzlich dies und jenem und die KI wird das perfekt ausspucken. Die Vorarbeit haben dann die Steinberg Leute geleistet
Doch natürlich braucht man sie. Sie werden nur nicht mehr hier hergestellt sondern im Ausland. Eigentlich ist es andersrum: man braucht weiterhin Autozulieferer aber Deutschland braucht man nicht unbedingt mehr. Wenn hier nur noch Wald ist oder das ganze Land aus elektrobetrieben Dienstleistungen (Lieferando und Lastenräder) besteht, dreht sich die Erde weiter und andere übernehmen die Aufgaben ehemals deutscher Firmen.

