AI generated node.js convolution player

Changes

  • in server.js
    • added aif to file types
    • modify IP from localhost to IP address to support network access

Prompt

generate a node.js application that builds a list of audio file from a sample folder and a list of audio impulse from an impulse folder and allows a user to select the sample and play that through the selected convolution

Snapshot of the page

Response

To build this application, you can use Express to serve the audio files and a simple front-end with the Web Audio API to handle the convolution.

Project Setup

  1. Initialize the project:mkdir audio-convolution-app && cd audio-convolution-app npm init -y npm install express
  2. Folder Structure: Create two folders, samples and impulses, and add your .wav or .mp3 files to them.audio-convolution-app/ ├── public/ │ └── index.html ├── samples/ ├── impulses/ └── server.js
audio-convolution-app/
├── public/
│   └── index.html
├── samples/
├── impulses/
└── server.js

Server Side (server.js)

This script uses the fs module to list the files and Express to serve them.

const express = require('express');
const fs = require('fs');
const path = require('path');
const app = express();

app.use(express.static('public'));
app.use('/samples', express.static('samples'));
app.use('/impulses', express.static('impulses'));

// API to list files in a folder
app.get('/api/files/:folder', (req, res) => {
    const folderPath = path.join(__dirname, req.params.folder);
    fs.readdir(folderPath, (err, files) => {
        if (err) return res.status(500).json({ error: 'Folder not found' });
        // Filter for audio files only
        const audioFiles = files.filter(file => /\.(mp3|wav|ogg)$/i.test(file));
        res.json(audioFiles);
    });
});

app.listen(3000, () => console.log('Server running on http://localhost:3000'));

Client Side (public/index.html)

The frontend fetches the file lists and uses a ConvolverNode for the effect.

<!DOCTYPE html>
<html>
<body>
    <h1>Audio Convolution</h1>
    <label>Sample: <select id="sampleList"></select></label><br>
    <label>Impulse: <select id="impulseList"></select></label><br>
    <button id="playBtn">Play with Convolution</button>

    <script>
        const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
        
        async function loadList(folder, elementId) {
            const res = await fetch(`/api/files/${folder}`);
            const files = await res.json();
            const select = document.getElementById(elementId);
            files.forEach(f => select.add(new Option(f, f)));
        }

        async function getBuffer(url) {
            const response = await fetch(url);
            const arrayBuffer = await response.arrayBuffer();
            return await audioCtx.decodeAudioData(arrayBuffer);
        }

        document.getElementById('playBtn').onclick = async () => {
            if (audioCtx.state === 'suspended') await audioCtx.resume();

            const sampleFile = document.getElementById('sampleList').value;
            const impulseFile = document.getElementById('impulseList').value;

            // Load buffers
            const [sampleBuffer, impulseBuffer] = await Promise.all([
                getBuffer(`/samples/${sampleFile}`),
                getBuffer(`/impulses/${impulseFile}`)
            ]);

            // Setup Nodes
            const source = audioCtx.createBufferSource();
            source.buffer = sampleBuffer;

            const convolver = audioCtx.createConvolver();
            convolver.buffer = impulseBuffer;

            // Routing: Source -> Convolver -> Output
            source.connect(convolver);
            convolver.connect(audioCtx.destination);
            
            source.start();
        };

        loadList('samples', 'sampleList');
        loadList('impulses', 'impulseList');
    </script>
</body>
</html>

How to use

  1. Run node server.js.
  2. Open http://localhost:3000 in your browser.
  3. Select a sound from your samples folder and an environment from impulses to hear the effect.

Would you like to add a dry/wet mix control or a visualizer to this application?

Suggest the easiest way to host this on a public site

Click here to expand

The easiest way to host a Node.js application today is using a Platform-as-a-Service (PaaS) that connects directly to your GitHub repository for automatic deployments [1, 2] .

1. Recommended Platforms (Free Tier)

These services automatically detect Node.js and provide a live URL without requiring server configuration:

  • Render: Highly recommended for its simplicity [3, 4] .
    • Pros: Easy “no-config” setup, supports standard Node.js/Express, and includes a free tier [5, 6] .
    • Note: The free instance “sleeps” after 15 minutes of inactivity, causing a “cold start” (delay) when accessed again [7, 8] .
  • Railway: Widely considered one of the fastest and smoothest deployment experiences [1, 9] .
    • Pros: Instant builds and a modern, developer-friendly interface [10] .
    • Note: It uses a usage-based free trial (credits), so check your limits for long-running apps [7, 11] .
  • Vercel: Excellent if you primarily want a “serverless” approach [12, 13] .
    • Pros: Best for frontend-heavy apps and extremely fast globally [1, 14] .
    • Note: Requires a vercel.json configuration file to correctly route Express API requests [15, 16] .

2. Steps to Host on Render

Since your app is a simple Express server with static files, Render is the most straightforward choice.

  1. Prepare your code: Ensure your package.json has a start script:"scripts": { "start": "node server.js" } Add a .gitignore file with node_modules/ to avoid uploading unnecessary files [3, 4] .
  2. Push to GitHub: Create a repository and push your local code there [9] .
  3. Connect to Render Dashboard:
    • Click New > Web Service [6] .
    • Connect your GitHub account and select your repository [2] .
  4. Configure & Deploy:
    • Runtime: Select Node [7] .
    • Build Command: npm install [6] .
    • Start Command: node server.js [3] .
    • Select the Free instance type and click Create Web Service [7] .

3. Key Considerations for Audio Apps

  • Storage: Most free platforms use ephemeral storage, meaning any files you upload manually to the server while it’s running will be deleted when the server restarts [17] . Ensure your samples and impulses folders are part of your Git repository so they are included in the build.
  • Port Management: Use process.env.PORT || 3000 in your server.js so the host can assign its own port [3] .

Would you like help setting up a database to store user-uploaded samples permanently?

[1] https://www.linkedin.com

[2] https://www.youtube.com

[3] https://www.youtube.com

[4] https://www.youtube.com

[5] https://www.reddit.com

[6] https://render.com

[7] https://geshan.com.np

[8] https://www.freecodecamp.org

[9] https://dev.to

[10] https://medium.com

[11] https://docs.railway.com

[12] https://www.youtube.com

[13] https://medium.com

[14] https://blog.boltops.com

[15] https://javascript.plainenglish.io

[16] https://www.youtube.com

[17] https://www.youtube.com

Non-AI Generated commens on next steps

Intent is to integrate wit IMU input. To comply with brower privacy contols, this likely needs addition of certificate for https activation.. One approach for just local usage, is to constrain to local domain instead of “localhost”. Self signed certficates required a couple of extra clicks whit is ok for a demo though not preferrabel for end state.

The current cieweb.net ISP, the Host Group is not clear on whether node.js is supported without additional costs. Capability is documented and the control to add is visible in cpanel though comes back with message to contact administrator.

This should port to a RPI with relative ease. Given FIOS internet, should be able to expose this on a home hosted server using cieweb.ddns.net  from No-IP.