audio-mixer-ui
v1.1.0
Published
Vue 3 component library for audio mixer interfaces with musical navigation
Maintainers
Readme
Audio Mixer UI Components
Vue 3 component library for building audio mixer interfaces with musical navigation and control features.
Features
- Audio controls with level meters and visual feedback
- Musical navigation (bar/beat input, practice marks, tempo controls)
- Responsive design for mobile, tablet, and desktop
- Event-driven architecture with separate UI and audio layers
- Keyboard navigation with ARIA labels and screen reader support
Installation
npm install audio-mixer-ui piniaQuick Start
<template>
<div class="app">
<MixerLayout>
<template #menu>
<button @click="selectScore" class="menu-item">Load Score</button>
</template>
</MixerLayout>
</div>
</template>
<script setup>
import { onMounted } from 'vue'
import { MixerLayout, useMasterAudioControl } from 'audio-mixer-ui'
import 'audio-mixer-ui/style.css'
const masterAudio = useMasterAudioControl()
const musicData = {
title: "Demo Song",
parts: [
{ name: 'Soprano', volume: 0.75 },
{ name: 'Alto', volume: 0.75 },
{ name: 'Tenor', volume: 0.75 },
{ name: 'Bass', volume: 0.75 }
],
beats: [
{ bar: 1, beat: 1, repeat: 0, tempo: 80, time: 0, timeSig: 4 },
{ bar: 1, beat: 2, repeat: 0, tempo: 80, time: 0.75, timeSig: 4 },
// ... more beat data
],
marks: { A: 1, B: 5, C: 9 }
}
onMounted(() => {
masterAudio.initialize(musicData)
})
function selectScore() {
console.log('Load different score')
}
</script>Setup your app with Pinia:
// main.js
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const app = createApp(App)
app.use(createPinia())
app.mount('#app')Core Components
Components automatically integrate with Pinia stores:
MixerLayout- Responsive container that renders parts from store dataMixerControls- Transport controls (play, stop, pause)AudioSlider- Fader with live level indicatorsPartControl- Individual part mixer (volume, mute, solo)BarInput- Bar navigation with practice marksTimeInput- Time display synced to playbackSpeedInput- Playback speed control
State Management
Components connect to Pinia stores automatically:
import {
useAudioStateStore, // Playback state (time, volume, playing)
useMusicDataStore, // Musical structure (beats, parts, marks)
usePlaybackStateStore, // Transport settings (loop, metronome)
useMasterAudioControl // Master composable for control
} from 'audio-mixer-ui'
const masterAudio = useMasterAudioControl()
// Initialize with musical data
masterAudio.initialize(musicData)
// Control playback
masterAudio.play()
masterAudio.stop()
masterAudio.setBar(5, 1)
masterAudio.setPartVolume('Soprano', 0.8)Audio Engine Configuration
Choose between SpessaSynth (soundfont-based, 10-50MB) or Lightweight (sample-based, ~4MB):
import { audioEngineConfig } from 'audio-mixer-ui'
// Use LightweightAudioEngine (default is SpessaSynth)
audioEngineConfig.setEngineType('lightweight')
// Then initialize as normal
const masterAudio = useMasterAudioControl()
await masterAudio.initialize(musicData)Note: Engine type must be set before initialization. See audio-mixer-engine for setup details.
Soundfont Configuration
Important: The audio mixer requires a General MIDI soundfont for synthesis. The library does NOT bundle a soundfont to keep the npm package lightweight (~1MB instead of ~26MB).
Option 1: Host Soundfont in Your Public Folder (Default)
Place a soundfont file in your app's public folder:
your-app/
public/
FluidR3Mono_GM.sf3 ← Place soundfont here
src/
...The library will automatically look for /FluidR3Mono_GM.sf3 by default. No configuration needed!
Option 2: Use a CDN or Custom URL
Configure a custom soundfont URL when initializing:
const masterAudio = useMasterAudioControl({
soundfontUrl: 'https://your-cdn.com/soundfonts/FluidR3Mono_GM.sf3'
})
// Then initialize as normal
await masterAudio.initialize(musicData)Recommended Soundfonts
FluidR3Mono_GM.sf3 (23MB) - High quality, mono, General MIDI
- MIT licensed
- Download: Search for "FluidR3Mono_GM" or check FluidSynth documentation
FluidR3_GM.sf2 (142MB) - Stereo version with more detail
- Larger file size, higher quality
Demo Soundfont
The live demo at GitLab Pages includes a bundled soundfont for convenience. Your production app should host its own soundfont file.
Fallback Behavior
If the custom soundfont URL fails to load, the library will try these default paths in order:
/FluidR3Mono_GM.sf3/FluidR3_GM.sf2/soundfont.sf2
If none are found, initialization will fail with an error.
Example: Environment-Based Configuration
// Use CDN in production, local in development
const soundfontUrl = import.meta.env.PROD
? 'https://cdn.example.com/FluidR3Mono_GM.sf3'
: '/FluidR3Mono_GM.sf3'
const masterAudio = useMasterAudioControl({ soundfontUrl })Musical Data Structure
The components expect musical timing data in this format:
// Beat mapping array
const beats = [
{ bar: 1, beat: 1, repeat: 1, tempo: 80, time: 0, timeSig: 4 },
{ bar: 1, beat: 2, repeat: 1, tempo: 80, time: 0.75, timeSig: 4 },
// ...
]
// Practice marks object
const practiceMarks = {
A: 1, // Mark A at bar 1
B: 5, // Mark B at bar 5
C: 13 // Mark C at bar 13
}
// Parts configuration
const parts = [
{ name: 'Soprano', volume: 0.75 },
{ name: 'Alto', volume: 0.7 },
// ...
]Development
# Install dependencies
npm install
# Run development server with demo
npm run dev
# Build library
npm run build
# Build demo
npm run build:demo
# Run tests
npm run test
# Lint code
npm run lintArchitecture
Event-driven layered architecture:
- Components - Vue 3 with Composition API
- Composables - Shared logic for audio control and state
- Stores - Pinia for reactive state management
- Services - Audio engine integration
Key principles: Audio thread isolation, event-driven coordination, runtime part discovery.
Requirements
- Vue 3.4+
- Pinia
- Modern browser with Web Audio API support
License
MIT License - see LICENSE file for details.
