//! Seed initial forum data for development. Run with `--seed` flag. use mt_core::types::CommunityRole; use sqlx::PgPool; use uuid::Uuid; pub async fn run(pool: &PgPool) { // Guard: skip if data already exists (threads have no unique constraint) let thread_count: i64 = sqlx::query_scalar("SELECT COUNT(*) FROM threads") .fetch_one(pool) .await .unwrap_or(0); if thread_count > 0 { tracing::info!("seed data already exists, skipping"); return; } // ── Users ────────────────────────────────────────────────────────── let users = seed_users(pool).await; // ── Communities ──────────────────────────────────────────────────── let rust_id = seed_community( pool, "Rust Programming", "rust", Some("All things Rust — language, ecosystem, tooling."), ) .await; let music_id = seed_community( pool, "Music Production", "music", Some("DAWs, plugins, mixing, mastering, sound design."), ) .await; let selfhosted_id = seed_community( pool, "Self-Hosted", "selfhosted", Some("Running your own infrastructure. No cloud required."), ) .await; // ── Categories ───────────────────────────────────────────────────── // Rust let rust_general = seed_category(pool, rust_id, "General", "general", 0, Some("Anything that doesn't fit elsewhere.")).await; let rust_help = seed_category(pool, rust_id, "Help & Questions", "help", 1, Some("Ask for help, get answers.")).await; let _rust_show = seed_category(pool, rust_id, "Show & Tell", "show", 2, Some("Share what you've built.")).await; let _rust_meta = seed_category(pool, rust_id, "Meta", "meta", 3, Some("Discussion about this community itself.")).await; // Music — the main test community let music_general = seed_category(pool, music_id, "General", "general", 0, Some("General music production discussion.")).await; let music_mixing = seed_category(pool, music_id, "Mixing & Mastering", "mixing", 1, Some("Techniques for getting a polished mix.")).await; let music_sound = seed_category(pool, music_id, "Sound Design", "sound-design", 2, Some("Synthesis, sampling, and sound creation.")).await; // Self-Hosted let sh_general = seed_category(pool, selfhosted_id, "General", "general", 0, Some("General self-hosting discussion.")).await; let _sh_homelab = seed_category(pool, selfhosted_id, "Homelab", "homelab", 1, Some("Hardware, networking, and home server setups.")).await; // ── Memberships ──────────────────────────────────────────────────── for user in &users { seed_membership(pool, user.id, music_id, CommunityRole::Member).await; } // admin owns all, maxmj is moderator of music seed_membership_upsert(pool, users[0].id, rust_id, CommunityRole::Owner).await; seed_membership_upsert(pool, users[0].id, music_id, CommunityRole::Owner).await; seed_membership_upsert(pool, users[0].id, selfhosted_id, CommunityRole::Owner).await; seed_membership_upsert(pool, users[1].id, rust_id, CommunityRole::Member).await; seed_membership_upsert(pool, users[1].id, music_id, CommunityRole::Moderator).await; // ── Rust community: a few threads (unchanged from before) ────────── let welcome_id = seed_thread(pool, rust_general, users[0].id, "Welcome — read before posting", true, false).await; seed_post(pool, welcome_id, users[0].id, "Welcome to the Rust Programming community. Please be respectful, stay on topic, and use code blocks for code snippets.").await; let async_id = seed_thread(pool, rust_general, users[1].id, "How do I get started with async Rust?", false, false).await; seed_post(pool, async_id, users[1].id, "I've been writing synchronous Rust for a few months and want to start using async/await. What runtime should I pick? Is tokio the only option?\n\nAny recommended tutorials or blog posts would be great.").await; seed_post(pool, async_id, users[0].id, "Tokio is the most popular and what most web frameworks (Axum, Actix) use. There's also `async-std` and `smol`, but the ecosystem gravitates toward tokio.\n\nStart with the tokio tutorial: it covers spawning tasks, channels, and I/O.").await; let error_id = seed_thread(pool, rust_help, users[1].id, "Best practices for error handling in Axum", false, false).await; seed_post(pool, error_id, users[1].id, "What's the recommended way to handle errors in Axum handlers? Should I use `anyhow`, `thiserror`, or something else? I keep writing `.map_err(|e| ...)` everywhere.").await; // ── Self-Hosted: a few threads ───────────────────────────────────── let caddy_id = seed_thread(pool, sh_general, users[0].id, "Caddy vs nginx for reverse proxy", false, false).await; seed_post(pool, caddy_id, users[0].id, "I have been using nginx for years but Caddy's automatic HTTPS is tempting. Anyone made the switch? What are the tradeoffs?").await; seed_post(pool, caddy_id, users[3].id, "Switched last year. Caddy's config is so much simpler. Automatic cert renewal is great. Only downside is slightly higher memory usage but it is negligible for small setups.").await; // ── Music community: bulk seed ───────────────────────────────────── seed_music_general(pool, music_general, &users).await; seed_music_mixing(pool, music_mixing, &users).await; seed_music_sound_design(pool, music_sound, &users).await; // Backfill denormalized reply_count from actual post data sqlx::query( "UPDATE threads SET reply_count = GREATEST( (SELECT COUNT(*) FROM posts WHERE posts.thread_id = threads.id) - 1, 0)", ) .execute(pool) .await .expect("failed to backfill reply_count"); let total_threads: i64 = sqlx::query_scalar("SELECT COUNT(*) FROM threads") .fetch_one(pool) .await .unwrap_or(0); let total_posts: i64 = sqlx::query_scalar("SELECT COUNT(*) FROM posts") .fetch_one(pool) .await .unwrap_or(0); tracing::info!( "seeded 3 communities, {} users, {} threads, {} posts", users.len(), total_threads, total_posts ); } struct SeedUser { id: Uuid, } async fn seed_users(pool: &PgPool) -> Vec { let user_data = [ ("00000000-0000-0000-0000-000000000001", "admin", "Admin"), ("00000000-0000-0000-0000-000000000002", "maxmj", "Max"), ("00000000-0000-0000-0000-000000000003", "synthwave99", "Juno"), ("00000000-0000-0000-0000-000000000004", "basshunter", "Erik"), ("00000000-0000-0000-0000-000000000005", "tape_hiss", "Rae"), ("00000000-0000-0000-0000-000000000006", "drumroom", "Cole"), ("00000000-0000-0000-0000-000000000007", "patchwork", "Lina"), ("00000000-0000-0000-0000-000000000008", "detuned", "Kai"), ("00000000-0000-0000-0000-000000000009", "resampled", "Noor"), ("00000000-0000-0000-0000-00000000000a", "clipgain", "Wren"), ]; let mut users = Vec::new(); for (uuid_str, username, display_name) in &user_data { let id = Uuid::parse_str(uuid_str).unwrap(); sqlx::query( "INSERT INTO users (mnw_account_id, username, display_name) VALUES ($1, $2, $3) ON CONFLICT (mnw_account_id) DO NOTHING", ) .bind(id) .bind(username) .bind(display_name) .execute(pool) .await .expect("failed to seed user"); users.push(SeedUser { id }); } users } /// 35 threads in Music/General — enough for 2 pages. async fn seed_music_general(pool: &PgPool, category_id: Uuid, users: &[SeedUser]) { let threads: &[(&str, &str, &[&str])] = &[ ( "Welcome to Music Production", "Ground rules: be kind, share knowledge, no self-promo spam. Use the right category for your topic.", &["Glad to be here.", "Thanks for setting this up."], ), ( "What DAW are you using in 2026?", "Curious what everyone is running these days. I have been on Ableton for years but keep hearing about Bitwig.", &[ "Reaper. Lightweight, cheap, endlessly customizable.", "Bitwig since version 4. The modulation system is unmatched.", "FL Studio. Started on it when I was 14, never left.", "Ableton but I keep a Reaper install for editing and batch processing.", "Logic. It just works and the stock plugins are surprisingly good.", ], ), ( "Favorite free plugins?", "What are your go-to free VSTs? Looking for synths, effects, anything.", &[ "Vital is the obvious answer. Best free synth by a mile.", "Valhalla Supermassive for reverb/delay. Sounds incredible for free.", "TDR Nova for EQ. Clean, surgical, zero CPU.", "Dexed if you want FM synthesis. Basically a free DX7.", ], ), ( "How do you organize your sample library?", "My sample folder is a disaster. Thousands of files with no structure. How do you keep things findable?", &[ "Genre > Type > Character. So like Electronic > Kicks > Punchy. Took a weekend to sort but worth it.", "I use tags instead of folders. AudioFiles has been great for this actually.", "Honestly I just search. If the filename is descriptive enough, search wins over folders every time.", ], ), ( "Analog vs digital debate in 2026", "Is there still a meaningful difference? Modern plugins are so good that I genuinely cannot tell in blind tests anymore.", &[ "The difference is workflow, not sound. Hardware forces commitment.", "I sold all my hardware last year. Zero regrets. Plugins are there.", "The tactile experience matters. Turning a real knob is different from clicking a virtual one.", "Both. I track through analog preamps and process in the box.", ], ), ( "How long did it take you to finish your first track?", "Been producing for 3 months and I cannot seem to finish anything. Is this normal?", &[ "Totally normal. Took me a year to finish something I was not embarrassed by.", "Force yourself to finish bad tracks. The skill of finishing is separate from the skill of producing.", "Set a deadline. 48 hours from start to bounce. Quality does not matter, completion does.", "Still working on my first one honestly.", "About 6 months. And it was terrible. But I finished it and that mattered.", ], ), ( "Studio monitors vs headphones for mixing?", "I live in an apartment and cannot treat the room properly. Should I just mix on headphones?", &[ "Headphones are fine if you know their character. Use a reference plugin like Sonarworks.", "I mix on DT 770s and reference on my car stereo. Not ideal but it works.", "Even cheap acoustic treatment helps. Hang some moving blankets.", ], ), ( "What's your creative process?", "Do you start with drums, melody, a sample? Curious how other people approach a blank session.", &[ "Always start with chords. Everything else follows from the harmony.", "I jam on a synth until something clicks, then build around that loop.", "Sound design first. Find an interesting texture, then write something that serves it.", "Drums. Always drums. Get the groove right and the rest writes itself.", "I hum melodies into my phone all day, then sit down and try to recreate them.", "Start with a reference track. Analyze the arrangement, then write something inspired by the structure.", ], ), ( "Best MIDI controllers under $200?", "Looking for something with keys and some knobs. Not a full workstation, just something to play ideas into the DAW.", &[ "Arturia Keystep 37. Great keybed for the price, plus the arpeggiator and sequencer.", "Novation Launchkey MK3. Deep DAW integration if you use Ableton.", "Akai MPK Mini. Tiny but surprisingly capable.", ], ), ( "CPU overload — how do you deal with it?", "My sessions keep hitting 100% CPU. Running a Ryzen 5 3600 with 16GB RAM. Is it time to upgrade or am I doing something wrong?", &[ "Freeze tracks you are not actively working on. Most DAWs support this.", "Bounce MIDI to audio once you are happy with the sound. Frees up the plugin.", "Check your buffer size. 256 for recording, 1024+ for mixing.", "Your CPU is fine. It is probably one plugin eating everything. Check per-plugin CPU.", ], ), ( "Music theory: how much do you actually use?", "I know basic chords and scales but never studied theory formally. How much do you all actually apply?", &[ "Enough to communicate with other musicians. Circle of fifths, chord functions, basic voice leading.", "Almost none. I go by ear and fix what sounds wrong.", "A lot. Understanding why something sounds good helps you recreate it faster.", ], ), ( "Side-chaining techniques", "What is your preferred method for side-chaining? Compressor? Volume automation? LFO tool?", &[ "Trackspacer. Not technically side-chain compression but solves the same problem better.", "Volume shaper plugin. More precise than a compressor and you can draw the exact curve.", "Classic compressor side-chain. Simple, works, everyone knows how to do it.", "I automate the volume manually. Full control, no artifacts.", ], ), ( "How do you avoid ear fatigue?", "I can mix for maybe 2 hours before everything starts sounding the same. Any tips?", &[ "Take breaks every 45 minutes. Walk around, drink water, reset.", "Mix at low volume. If it sounds good quiet, it will sound good loud.", "Reference constantly. Switch to a commercial track every 15 minutes.", ], ), ( "Collaboration: how do you share projects?", "Want to collaborate with a friend who uses a different DAW. What is the best approach?", &[ "Stems. Bounce each track as a WAV, share via cloud storage.", "MIDI + stems for the parts that need to be editable.", "We just use the same DAW. Easier than any workaround.", ], ), ( "Loudness standards for streaming platforms", "Spotify targets -14 LUFS, Apple Music -16. Should I master to a specific target or just make it sound good?", &[ "Master to what sounds best, then check loudness after. Most platforms normalize anyway.", "I aim for -12 to -14. Leaves headroom but still competitive.", "The number matters less than the dynamic range. A dynamic -14 sounds better than a squashed -8.", ], ), ( "What headphones do you use?", "Looking for mixing headphones. Budget around $150-300.", &[ "Sennheiser HD 600. Flat, detailed, comfortable for long sessions.", "Beyerdynamic DT 990 Pro. Wide soundstage. A bit bright but you learn the character.", "AKG K712. Open-back, great imaging.", "Audio-Technica ATH-M50x. Closed-back, good isolation, slightly hyped low end.", ], ), ( "Sampling ethics", "Where do you draw the line with sampling? Royalty-free packs? Vinyl? Other artists' released music?", &[ "Royalty-free is fair game obviously. For anything else, clear it or make it unrecognizable.", "I only sample stuff I have created myself or bought a license for.", "Sampling is an art form. The key is transformation.", ], ), ( "When to call a mix done?", "I keep tweaking endlessly. How do you know when to stop?", &[ "When changes become lateral instead of improvements. If you are just going back and forth, stop.", "Set a deadline. Ship it. You can always do a v2 later.", "Compare to your reference. If it holds up, it is done.", "When you start breaking things that were already working.", ], ), ( "Learning synthesis from scratch", "I have been using presets forever. Want to learn to design my own sounds. Where do I start?", &[ "Start with subtractive synthesis. One oscillator, one filter, one envelope. Understand what each does.", "Syntorial. It is a paid app but it teaches synthesis through ear training, not just theory.", "Pick one synth and learn it deeply. Vital or Serum are good because they visualize everything.", ], ), ( "Vocal processing chain", "What is your typical vocal chain? EQ, compression, de-essing, etc.", &[ "Gain staging, subtractive EQ, compressor (light 2:1), de-esser, additive EQ, reverb send.", "Similar but I add a saturation plugin before the compressor. Gives warmth.", "Depends entirely on the vocal and the genre. There is no universal chain.", ], ), ( "Budget acoustic treatment", "Can I treat a small room for under $200? What should I prioritize?", &[ "First reflections. Put absorption panels at mirror points on side walls.", "Bass traps in the corners are the highest impact single thing you can do.", "Rockwool panels in wooden frames. DIY for about $50 per panel.", "A thick rug on the floor and heavy curtains help more than people think.", ], ), ( "Favorite reverb plugin?", "Looking for something versatile. Plates, halls, rooms, all in one.", &[ "Valhalla Room. $50, sounds amazing, low CPU.", "FabFilter Pro-R 2. The decay rate EQ is genius.", "Stock reverb in your DAW is probably fine for 90% of use cases.", ], ), ( "How important is mastering?", "Can I just slap a limiter on the master bus and call it a day?", &[ "For demos and personal releases, yes. For commercial releases, get it mastered.", "Mastering is about perspective. A second set of ears in a treated room catches things you miss.", "iZotope Ozone is good enough for DIY mastering if you learn what each module does.", ], ), ( "Managing multiple projects at once", "I have like 30 unfinished projects. How do you manage the backlog?", &[ "Pick three. Finish them. Delete the rest. Harsh but effective.", "I give each project a status: idea, in progress, mixing, done. Only 2 can be in progress at once.", "Set a monthly goal. One finished track per month, minimum.", ], ), ( "Track referencing workflow", "How do you reference against commercial tracks while mixing?", &[ "Import the reference directly into the session. Level match with a LUFS meter, A/B constantly.", "I use a dedicated plugin that lets me switch between my mix and references with one click.", "Listen to the reference on the same speakers, back to back. Do not overthink the workflow.", ], ), ( "Gain staging basics", "Keep hearing about gain staging but not sure I understand it. ELI5?", &[ "Every plugin in your chain should receive signal at a reasonable level. If you push hot into a compressor, it behaves differently than if you feed it -18dBFS.", "Basically: do not clip anything in the chain before the final limiter. Use trim/gain plugins if needed.", "Aim for peaks around -12 to -6 on each channel. Leaves headroom on the master.", ], ), ( "Lo-fi production tips", "Want to make lo-fi hip hop style beats. What gives that characteristic sound?", &[ "Bitcrushing, vinyl noise, tape saturation, de-tuned samples, swing on the drums.", "Record stuff through a cheap mic or tape deck. Real degradation sounds better than plugins simulating it.", "Side-chain the whole mix to the kick. Slow attack, slow release. That pumping effect is key.", "Use jazz chord voicings. Maj7, min9, dom13. That is the harmonic foundation.", ], ), ( "What's your backup strategy?", "Lost a project file last week and it hurt. How do you backup your work?", &[ "Git for project files, rsync to a NAS for samples and bounces.", "Time Machine plus a monthly clone to an external drive.", "Cloud sync. Dropbox for active projects, cold storage archive for finished work.", "Three copies: local SSD, NAS, off-site. If it does not exist in three places, it does not exist.", ], ), ( "Distortion as a creative tool", "Using distortion for more than just guitars. What are your favorite ways to use it?", &[ "Parallel saturation on vocals. Blend in just enough to add presence without obvious distortion.", "Run a sub bass through a wavefolder. Instant aggression.", "Distort a reverb return. Shoegaze in a box.", ], ), ( "Hardware synths worth buying in 2026?", "With plugins being so good, is there any reason to buy hardware synths?", &[ "Workflow. Playing a hardware synth is a different experience than clicking a mouse.", "The Korg Minilogue XD is still hard to beat for the price. Four voices, great effects.", "I would skip hardware unless you perform live. For studio work, plugins win on convenience.", "Elektron Digitone. FM synthesis in a box with an incredible sequencer.", ], ), ( "How to get better at arrangement", "My loops sound great but full tracks feel flat. Any tips for arrangement?", &[ "Study arrangements of songs you like. Map them out on paper. Intro, verse, chorus, bridge — note what enters and exits.", "Contrast. If the chorus is dense, strip back the verse. Dynamics come from what you remove.", "Energy curve. Every section should either build tension or release it. Never stay flat.", "Reference tracks. Drop one into your session and match the structure.", "Automate everything. Filter sweeps, volume rides, effect sends. Movement keeps the listener engaged.", ], ), ( "Mixing in mono", "People say to check your mix in mono. Why? And how often should I do it?", &[ "Phase cancellation. If something disappears in mono, your stereo image has phase issues.", "I check mono every 30 minutes during a mix. Just hit the mono button, listen for 10 seconds.", "Some clubs play in mono. If your mix falls apart, half your audience hears a broken version.", ], ), ( "Best YouTube channels for learning production?", "What channels do you actually learn from vs just watch for entertainment?", &[ "Dan Worrall. No-nonsense, deep technical knowledge, great explanations.", "You Suck at Producing. Funny but genuinely educational.", "In The Mix. Good for beginners. Covers basics thoroughly.", "Pensado's Place for mixing techniques from industry engineers.", ], ), ( "Dealing with creative blocks", "Have not made anything in two weeks. Everything I start sounds boring. How do you push through?", &[ "Constraints. Give yourself a rule: only use three sounds, or finish in one hour. Limits breed creativity.", "Listen to music outside your genre. Completely different styles can spark unexpected ideas.", "Recreate a track you love. You will learn technique and usually branch off into something original.", "Take a break. Burnout is real. Come back when you actually want to, not when you feel you should.", ], ), ( "Automation tips", "What do you automate most in your mixes?", &[ "Volume. Subtle 1-2dB rides on vocals and leads make a huge difference.", "Filter cutoff. Automate a low-pass sweep into the chorus for instant energy lift.", "Reverb send. More reverb in quiet sections, less in dense sections.", ], ), ]; // Pinned welcome thread let welcome_id = seed_thread(pool, category_id, users[0].id, threads[0].0, true, false).await; seed_post(pool, welcome_id, users[0].id, threads[0].1).await; for (i, reply) in threads[0].2.iter().enumerate() { seed_post(pool, welcome_id, users[(i + 2) % users.len()].id, reply).await; } // Remaining threads — one with lots of replies for post pagination for (idx, (title, body, replies)) in threads.iter().enumerate().skip(1) { let author = &users[(idx + 1) % users.len()]; let thread_id = seed_thread(pool, category_id, author.id, title, false, false).await; seed_post(pool, thread_id, author.id, body).await; for (i, reply) in replies.iter().enumerate() { let replier = &users[(idx + i + 3) % users.len()]; seed_post(pool, thread_id, replier.id, reply).await; } // Thread #1 (DAW thread): add 55 extra posts to test post pagination (50/page) if idx == 1 { seed_long_discussion(pool, thread_id, users).await; } } } /// 15 threads in Mixing & Mastering. async fn seed_music_mixing(pool: &PgPool, category_id: Uuid, users: &[SeedUser]) { let threads: &[(&str, &str, &[&str])] = &[ ( "EQ before or after compression?", "Classic debate. What is your default chain order and why?", &[ "Subtractive EQ first to clean up, then compress, then additive EQ to shape.", "Depends on the source. Muddy vocal? EQ first. Clean recording? Compress first.", "I do both. Light EQ before, heavier shaping after.", ], ), ( "Parallel compression techniques", "How are you using parallel compression? Just on drums or on everything?", &[ "Drums and vocals mainly. Crush a copy, blend it in at like -12dB.", "I parallel compress the entire mix bus lightly. Adds glue without squashing dynamics.", "The NY compression trick on drums is still unbeatable. Heavy compression, blend to taste.", ], ), ( "Multiband compression: when to use it?", "I never quite know when multiband is the right tool vs a regular compressor.", &[ "When different frequency ranges need different treatment. A boomy vocal with sibilance needs different ratios for lows and highs.", "On the master bus for gentle tonal balancing. Very light ratios, like 1.5:1.", "Rarely. Most problems are better solved with EQ. Multiband comp is a precision tool, not a default.", ], ), ( "Mixing with saturation", "How much saturation do you add and where in the chain?", &[ "A tiny bit on every channel. Tape emulation at the end of each strip. Adds harmonic richness.", "I saturate the mix bus and nothing else. Keeps it cohesive.", "Saturation on bass is essential for me. Makes it audible on small speakers.", "Early in the chain, before compression. Saturated signals compress differently.", ], ), ( "Taming harsh vocals", "My vocal recordings always end up harsh around 3-5kHz. De-esser? EQ? Both?", &[ "Dynamic EQ on the 2-5kHz range. Only dips when it gets harsh, leaves the presence otherwise.", "De-esser is specifically for sibilance (6-10kHz). For 3-5kHz harshness, use a dynamic EQ or multiband.", "Check your microphone and preamp. Some mics just have a harsh presence peak. A different mic might solve it at the source.", ], ), ( "Reverb mixing tips", "My reverbs either sound obvious or nonexistent. How do you make them sit right?", &[ "Pre-delay. 20-50ms of pre-delay separates the dry signal from the reverb and adds clarity.", "High-cut the reverb at 6-8kHz. Bright reverb tails make everything washy.", "Send to reverb, then EQ the return. Treat the reverb as its own instrument.", ], ), ( "Mixing low end: kick and bass coexistence", "How do you make the kick and bass work together without one masking the other?", &[ "Pick one to own the sub frequencies. If the kick has the sub, high-pass the bass at 60Hz. Or vice versa.", "Side-chain the bass to the kick. Classic but effective.", "Complementary EQ. Boost the kick at 60Hz, cut the bass there. Boost the bass at 100Hz, cut the kick.", "In most genres, the kick owns 40-80Hz and the bass lives at 80-200Hz. Arrange them to not compete.", ], ), ( "Mix bus processing", "What do you put on your mix bus? When do you add it?", &[ "Gentle glue compressor (SSL style, 2:1, slow attack) from the start. Mix into it.", "EQ, compression, slight saturation, limiter. But everything is doing very little. 1-2dB each.", "Nothing until the final mix. I want to hear what I actually have before processing it.", ], ), ( "Reference level for mixing", "What volume level do you monitor at while mixing?", &[ "Calibrated to 85dB SPL for critical listening. Most of the time I mix around 75dB.", "Quiet. If I can have a conversation over the mix, the volume is right.", "I check at multiple levels. Low for balance, medium for detail, loud for short reality checks.", ], ), ( "Width and stereo imaging", "How do you create width in a mix without it collapsing in mono?", &[ "Keep the center strong (kick, bass, lead vocal, snare). Spread supporting elements.", "Use different methods: hard panning, stereo delay, chorus, mid-side EQ. Variety avoids phase issues.", "Always check mono. If it sounds thin in mono, your width is relying on phase tricks that cancel.", ], ), ( "Handling dynamic range in modern productions", "Everything is so compressed now. How do you keep dynamics while still being competitive in loudness?", &[ "Mix dynamically. Let the mastering engineer handle loudness. That is literally their job.", "Automate volume instead of compressing. Ride the fader for consistent level without squashing transients.", "Use upward compression. Raises the quiet parts without touching the peaks.", ], ), ( "Delay vs reverb for depth", "When do you reach for a delay instead of a reverb to create depth?", &[ "Delay for rhythmic depth (synced to tempo). Reverb for spatial depth (rooms, halls).", "Short delays (30-80ms) create depth without the wash of reverb. Great for keeping things tight.", "I use both together. Short delay into a reverb return. Best of both worlds.", ], ), ( "Panning strategies", "Do you follow specific panning rules or go by feel?", &[ "LCR panning. Hard left, center, hard right. Simple but effective. Forces commitment.", "I pan where the instruments would be on a stage. Drums from the drummer's perspective.", "By feel. Whatever serves the song. Rules are starting points, not laws.", ], ), ( "Mixing with headphones — tips and tricks", "For those who primarily mix on headphones, what are your strategies?", &[ "Crossfeed plugin. Simulates speaker crosstalk so panning sounds more natural.", "Reference constantly on speakers when you can. Even laptop speakers reveal balance issues.", "Open-back headphones for mixing, closed-back for tracking. The soundstage difference matters.", ], ), ( "The loudness war is over — right?", "With streaming normalization, does anyone still master to -6 LUFS?", &[ "EDM and hip hop still push hard. Genre expectations matter more than streaming targets.", "The war is over for most genres. I master to -10 to -14 depending on the track.", "Yes. And it sounds better. More dynamics, more punch, more musicality. No reason to smash it.", ], ), ]; for (idx, (title, body, replies)) in threads.iter().enumerate() { let author = &users[(idx + 2) % users.len()]; let thread_id = seed_thread(pool, category_id, author.id, title, false, false).await; seed_post(pool, thread_id, author.id, body).await; for (i, reply) in replies.iter().enumerate() { let replier = &users[(idx + i + 4) % users.len()]; seed_post(pool, thread_id, replier.id, reply).await; } } } /// 15 threads in Sound Design. async fn seed_music_sound_design(pool: &PgPool, category_id: Uuid, users: &[SeedUser]) { let threads: &[(&str, &str, &[&str])] = &[ ( "FM synthesis for beginners", "FM synthesis always seemed impenetrable to me. Where do you start?", &[ "Two operators. Carrier and modulator. Change the ratio between them and listen. That is literally it to start.", "Dexed is free and models the DX7. Great for learning because there are tons of tutorials.", "Start with simple ratios: 1:1 for warmth, 1:2 for brightness, 1:3 for nasality. Then experiment.", ], ), ( "Wavetable synthesis tips", "Using Vital/Serum and want to go beyond presets. What are your wavetable tricks?", &[ "Import your own audio as a wavetable. Record a word, import it, scrub through it with an LFO.", "Morph between simple waveforms. A slow morph from saw to square adds movement without being obvious.", "Stack two oscillators with different wavetable positions and detune slightly. Instant width.", ], ), ( "How to make a supersaw", "Every tutorial makes it sound easy but mine never sound as full as professional supersaws.", &[ "More unison voices, more detune, slight chorus. But the real secret is layering: a supersaw is usually 2-3 layers, not one patch.", "High-pass the supersaw and layer a clean sub underneath. The fullness comes from the sub, not the saw.", "OTT on the supersaw bus. Controversial but it works.", "Mid-side processing. Keep the center mono, spread the sides. Instant width and power.", ], ), ( "Granular synthesis — practical uses?", "Granular synths look cool but I cannot figure out when to actually use them. What do you use granular for?", &[ "Pads and textures. Take a field recording, granularize it, and you have a unique atmosphere.", "Glitch effects. Short grain size + random position = controlled chaos.", "Stretching vocals to infinity. Load a vocal chop, set huge grain size, and you have a drone.", ], ), ( "Designing kick drums from scratch", "How do you synthesize a kick drum? I always just use samples.", &[ "Sine wave with a pitch envelope. Start at 200-300Hz, drop to 40-60Hz in about 50ms. Add a click layer for attack.", "Three layers: sub (sine, pitch envelope), body (short noise burst, filtered), click (very short transient).", "Operator in Ableton can do it in seconds. One sine oscillator, pitch envelope with fast decay.", ], ), ( "Making sounds feel organic", "My synth patches sound too static and digital. How do you add life?", &[ "LFOs on everything. Subtle random LFO on pitch, filter, amplitude. Humans are never perfectly steady.", "Velocity sensitivity. Map velocity to filter cutoff and amplitude. Changes how it responds to playing.", "Record the performance, do not program it. Even mouse-drawn MIDI lacks human timing.", "Add noise. A tiny bit of noise mixed in makes digital sounds feel more analog.", ], ), ( "Resampling workflow", "What is your resampling process? Bounce to audio and re-process?", &[ "Exactly. Design a sound, bounce it, chop it up, throw it in a sampler, add new processing.", "I resample through effects. Play a pad, record it through a reverb and delay, chop the result.", "Granular resampling. Take anything, granularize it, it becomes something entirely new.", ], ), ( "Favorite Vital patches you have designed", "Share your favorite sound you have made in Vital. What was the approach?", &[ "A pluck using two wavetables with very fast envelope decay, short reverb. Simple but cuts through any mix.", "A pad that morphs between 4 wavetable frames with a slow random LFO. Different every time it plays.", "A bass using the filter FM feature. Self-oscillating filter modulated by an oscillator. Absolutely nasty.", ], ), ( "Foley and field recording for music", "Anyone incorporate real-world recordings into their music?", &[ "All the time. City ambience, rain, coffee shop noise. Layer it under pads for realism.", "I record weird objects and use them as percussion. A spoon on a mug, keys jangling, books dropped.", "Bird recordings slowed down 10x sound like alien synth pads. Nature is the best sound designer.", "Contact microphone on everything. Metal fences, bridges, pipes. Gold mine of textures.", ], ), ( "Modular synthesis without hardware", "Want to explore modular concepts but cannot afford hardware. Software options?", &[ "VCV Rack. Free, open source, massive module library. It is basically Eurorack on your computer.", "Bitwig's modulation system is semi-modular. Very deep and all built into the DAW.", "Max/MSP or Pure Data if you want to go deep. Steep learning curve but unlimited.", "Cherry Audio Voltage Modular. Cheaper than real hardware and great module selection.", ], ), ( "Designing cinematic impacts and risers", "How do you create those massive cinematic impacts and tension risers?", &[ "Layer, layer, layer. Noise sweep + sub drop + metallic hit + reverb tail = one impact.", "Reverse cymbal with rising pitch is the classic riser. Add a filter sweep and noise for intensity.", "Record something large. Slam a door. Drop a heavy book. Process it with convolution reverb in a cathedral IR.", ], ), ( "Phase distortion synthesis", "Casio CZ-series used phase distortion. Anyone still using this technique?", &[ "Underrated. It is different from FM — smoother harmonics, easier to control.", "There are a few VST recreations. CZ V from Arturia is faithful to the originals.", "You can sort of approximate it in any synth by modulating the phase of one oscillator with another, but true PD has a distinct character.", ], ), ( "Processing drums creatively", "Beyond standard mixing, how do you use creative processing on drums?", &[ "Bit-crush the snare slightly. Adds grit and lo-fi character.", "Send drums to a reverb, compress the reverb return hard. Massive room sound.", "Granular processing on a drum loop. Freeze interesting moments, stretch hits into textures.", "Run the whole drum bus through a guitar amp sim. Instant rock energy.", ], ), ( "Additive synthesis — is it practical?", "Additive seems powerful in theory but is it actually useful for sound design?", &[ "Very useful for evolving pads and organ-like tones. Direct control over individual harmonics.", "Resynthesis is where additive shines. Analyze a sound, then modify individual partials.", "In practice, subtractive and wavetable get you there faster. Additive is more of a research tool.", ], ), ( "Sound design for games vs music", "Anyone here do game audio? How is the process different from music production?", &[ "Everything needs to loop seamlessly. And sounds need to work at different pitches and speeds for real-time variation.", "Much more focus on functionality. A UI click needs to be satisfying but not distracting. Very different from making a synth lead.", "Middleware like FMOD or Wwise adds a whole layer of implementation. You are not just making sounds, you are programming behaviors.", ], ), ]; for (idx, (title, body, replies)) in threads.iter().enumerate() { let author = &users[(idx + 5) % users.len()]; let thread_id = seed_thread(pool, category_id, author.id, title, false, false).await; seed_post(pool, thread_id, author.id, body).await; for (i, reply) in replies.iter().enumerate() { let replier = &users[(idx + i + 6) % users.len()]; seed_post(pool, thread_id, replier.id, reply).await; } } } /// Add 55 extra posts to a thread to test post pagination (50 posts/page). async fn seed_long_discussion(pool: &PgPool, thread_id: Uuid, users: &[SeedUser]) { let posts = [ "Been on Ableton since version 8. Cannot imagine switching at this point.", "I tried Bitwig for a month. The modulation system is amazing but I missed Ableton's workflow.", "Reaper deserves more love. The customization is insane once you learn ReaScript.", "FL Studio's piano roll is still the best. Nothing else comes close for MIDI editing.", "Logic's Drummer track is legitimately good. Saves me hours on demo tracks.", "Has anyone tried Ardour? Curious about the open source option.", "Ardour is great for recording and mixing. Less so for electronic production.", "Studio One has the best drag-and-drop workflow. Everything just snaps where you want it.", "I use different DAWs for different tasks. Ableton for production, Reaper for mixing, FL for beats.", "That sounds exhausting. I would rather master one tool than juggle three.", "Cubase is still king for film scoring. The expression maps and articulation system are unmatched.", "Pro Tools is dead for everything except professional studios that need industry compatibility.", "Hot take: the DAW matters way less than people think. Spend that energy on learning mixing.", "Agree. I have heard incredible music made in every DAW. And terrible music too.", "The best DAW is the one you know. Switching costs months of productivity.", "I switch between FL and Ableton depending on the genre. Hip hop in FL, electronic in Ableton.", "Reason had so much potential. Shame it never gained traction against the big players.", "Anyone using hardware-only setups? No DAW at all?", "I did a hardware-only album last year. It was liberating but the mixdown was painful.", "Renoise. Tracker workflow is incredibly fast once you learn the key commands.", "I miss trackers. Something about the vertical scrolling interface makes rhythm programming intuitive.", "What about Maschine or MPC as a DAW? Those have gotten pretty capable.", "MPC standalone is great for jamming but I always end up exporting to a proper DAW for mixing.", "Bitwig on Linux is underrated. Full native support, no WINE hacks.", "I produce on Linux with Bitwig. Works perfectly. Even plugin support is solid with yabridge.", "The iPad is becoming a legit production platform. GarageBand to Logic transition is seamless now.", "Mobile production is fun for sketching ideas but I would not mix on a tablet.", "Anyone tried the new AI features in some DAWs? Stem separation, auto-mixing, etc.", "AI stem separation is useful for sampling. The mixing AI is gimmicky.", "I use LALAL.ai for stem extraction. Better results than the built-in DAW tools.", "The plugin format wars are annoying. VST3, AU, CLAP. Can we just pick one?", "CLAP is the future. Open standard, better multithreading, no licensing fees.", "VST3 is fine. It works everywhere. CLAP is cool but the ecosystem is not there yet.", "AU is Apple-only, so it is irrelevant for anyone on Windows or Linux.", "Reaper supports everything. VST2, VST3, AU, CLAP, JS, LV2. No format wars needed.", "Honestly the DAW you start with tends to be the one you stick with. The muscle memory runs deep.", "I started on GarageBand, moved to Logic, tried Ableton, came back to Logic. Full circle.", "FL Studio's lifetime free updates are unbeatable. Paid once in 2015, still getting new versions.", "That is genuinely impressive. No other DAW offers that deal.", "The subscription model some companies are pushing is concerning. I want to own my tools.", "Agree. If the company shuts down, subscriptions die. Perpetual licenses survive.", "Ableton's standard-to-suite upgrade price is brutal though. Almost the cost of a new DAW.", "Wait for sales. Ableton does 20-25% off once or twice a year.", "I use the DAW that came free with my audio interface. Ableton Lite. It is enough for what I do.", "Lite versions are a great starting point. Upgrade when you hit the track limit.", "Track limits are artificial but they do force you to commit and bounce stems.", "Anyone still using Cakewalk? It went free and then got acquired again.", "Cakewalk is solid but the UI feels dated compared to modern DAWs.", "UI matters more than people admit. You stare at this thing for hours. It should look good.", "Function over form. I will take ugly and fast over pretty and slow any day.", "My dream DAW would have Ableton's session view, FL's piano roll, Logic's stock plugins, and Reaper's customization.", "So basically everything good from everything. Not unreasonable honestly.", "The DAW market is mature enough that they are all good. Pick one and make music.", "This thread has been going for a while. I think the conclusion is: whatever works for you.", "Final answer: all DAWs are good. Now go make music instead of debating tools.", ]; for (i, body) in posts.iter().enumerate() { let author = &users[(i + 4) % users.len()]; seed_post(pool, thread_id, author.id, body).await; } } // ── Helper functions ─────────────────────────────────────────────────── async fn seed_community(pool: &PgPool, name: &str, slug: &str, description: Option<&str>) -> Uuid { sqlx::query_scalar( "INSERT INTO communities (name, slug, description) VALUES ($1, $2, $3) ON CONFLICT (slug) DO UPDATE SET name = EXCLUDED.name RETURNING id", ) .bind(name) .bind(slug) .bind(description) .fetch_one(pool) .await .expect("failed to seed community") } async fn seed_category( pool: &PgPool, community_id: Uuid, name: &str, slug: &str, sort_order: i32, description: Option<&str>, ) -> Uuid { sqlx::query_scalar( "INSERT INTO categories (community_id, name, slug, description, sort_order) VALUES ($1, $2, $3, $4, $5) ON CONFLICT (community_id, slug) DO UPDATE SET name = EXCLUDED.name RETURNING id", ) .bind(community_id) .bind(name) .bind(slug) .bind(description) .bind(sort_order) .fetch_one(pool) .await .expect("failed to seed category") } async fn seed_membership(pool: &PgPool, user_id: Uuid, community_id: Uuid, role: CommunityRole) { sqlx::query( "INSERT INTO memberships (user_id, community_id, role) VALUES ($1, $2, $3) ON CONFLICT (user_id, community_id) DO NOTHING", ) .bind(user_id) .bind(community_id) .bind(role.as_str()) .execute(pool) .await .expect("failed to seed membership"); } async fn seed_membership_upsert(pool: &PgPool, user_id: Uuid, community_id: Uuid, role: CommunityRole) { sqlx::query( "INSERT INTO memberships (user_id, community_id, role) VALUES ($1, $2, $3) ON CONFLICT (user_id, community_id) DO UPDATE SET role = EXCLUDED.role", ) .bind(user_id) .bind(community_id) .bind(role.as_str()) .execute(pool) .await .expect("failed to seed membership"); } async fn seed_thread( pool: &PgPool, category_id: Uuid, author_id: Uuid, title: &str, pinned: bool, locked: bool, ) -> Uuid { sqlx::query_scalar( "INSERT INTO threads (category_id, author_id, title, pinned, locked) VALUES ($1, $2, $3, $4, $5) RETURNING id", ) .bind(category_id) .bind(author_id) .bind(title) .bind(pinned) .bind(locked) .fetch_one(pool) .await .expect("failed to seed thread") } async fn seed_post( pool: &PgPool, thread_id: Uuid, author_id: Uuid, body_markdown: &str, ) -> Uuid { let body_html = body_markdown .split("\n\n") .map(|p| { let escaped = p .replace('&', "&") .replace('<', "<") .replace('>', ">"); format!("

{escaped}

") }) .collect::(); let post_id: Uuid = sqlx::query_scalar( "INSERT INTO posts (thread_id, author_id, body_markdown, body_html) VALUES ($1, $2, $3, $4) RETURNING id", ) .bind(thread_id) .bind(author_id) .bind(body_markdown) .bind(&body_html) .fetch_one(pool) .await .expect("failed to seed post"); sqlx::query("UPDATE threads SET last_activity_at = now() WHERE id = $1") .bind(thread_id) .execute(pool) .await .expect("failed to update thread activity"); post_id }