Every school with a bell has the same story: the speakers in the ceilings are fine, the wiring in the walls is fine, but the grey box in the office that actually controls them is a relic nobody has a manual for. When it dies, the vendor quotes you four figures for a replacement appliance. You do not need the appliance.
A secondary school with eight wings. The bell system had been in place for nearly twenty years — two amplifier racks fed a distribution of ceiling speakers across the main teaching block, the sports hall, and the dining area. The controller was a dedicated bell-scheduler unit that had begun silently dropping bells. Some mornings period 3 never rang.
The existing analogue inputs to the amplifier racks were 3.5 mm jacks. That turned out to be the whole hack: anything that could put audio on a jack could drive the PA.
.wav bell tones in one folder, short lunch chimes in anotherThe critical feature is setting #25: MirrorDevices. When the office plays a bell, it must go out of both USB outputs simultaneously, in sync, at the same volume. Without mirroring you’d hear an echo as one wing’s bell landed fractions of a second after the other. In Multilarm you declare it once:
<MAConfig><PlaybackDevice>3</PlaybackDevice></MAConfig>
<MAConfig><MirrorDevices>4|5</MirrorDevices></MAConfig>
Device 3 is the primary output; devices 4 and 5 are mirrored copies driven from the same decoded audio buffer. The schedule fires once and all three outputs start within the same audio frame.
<idx>: <device name> [default] [disabled] [init]. Copy the indices you want straight into the XML. You never have to guess.
An academic day is extremely repetitive once you write it down. The bell schedule lives in the same XML as every other setting. Weekday-only bells use RecurEveryWeek with an entry per day:
<MAConfig><RecurEveryWeek>True</RecurEveryWeek></MAConfig>
<MAConfig><DateIdentifier>*</DateIdentifier></MAConfig>
<MAConfig><TimeDelimiter>|</TimeDelimiter></MAConfig>
<MAConfig><AlarmPath>C:\Bells\Standard|C:\Bells\Short|C:\Bells\Chimes|C:\Bells\Dismissal</AlarmPath></MAConfig>
<MAConfig><AlarmIndexData>1|1|2|3|4</AlarmIndexData></MAConfig>
<MAConfig><DateAndTimeData>*mon|8:50|9:45|10:45|12:30|15:15*tue|8:50|9:45|10:45|12:30|15:15*wed|8:50|9:45|10:45|12:30|15:15*thu|8:50|9:45|10:45|12:30|15:15*fri|8:50|9:45|10:45|12:30|15:15</DateAndTimeData></MAConfig>
Each slot’s position in DateAndTimeData picks the matching folder via AlarmIndexData — period bells use index 1 (Standard), break uses 2 (Short), lunch uses 3 (Chimes) and end-of-day uses 4 (Dismissal). Each folder holds several tones. Multilarm randomises within the folder, so the end-of-day bell doesn’t become monotonous — a small thing that matters when you hear it five times a week for a year. Because Sat and Sun are absent from DateAndTimeData, no bells fire at the weekend.
Schools don’t ring bells every day of the calendar. Inset days, half-term weeks, bank holidays — the bell schedule should silently not fire. AlternateConfig handles this by swapping the whole config file on date-scoped rules, so a school-inset.xml (empty schedule) or school-holiday.xml loads automatically on the dates that match. The currently loaded config filename is printed top-right of the dashboard so anyone walking past the office screen can see school-termtime.xml, school-inset.xml or school-holiday.xml at a glance, and the Web Remote’s live config editor lets the office swap in a different file without editing the AlternateConfig rule itself.
This is the hidden requirement nobody writes down. Fire drills. Surprise assemblies. A teacher asking the office to ring the bell two minutes early because a class is running over.
The Web Remote has a Test Alarm control next to a folder picker. Pick Dismissal from the dropdown, tap Test, the same bell the schedule fires at 3:15 plays on every mirrored output right now. For fire drills, a separate Alert folder is wired up the same way — the office runs the drill from the same phone interface they use for everything else.
Voice Broadcast covers the “would the owner of the blue Fiesta please move it” problem. The office laptop has a USB microphone plugged into the record device (RecordDevice, setting #25). In the Web Remote:
The transmit step is gated by a {"confirm":true} payload — a deliberate two-step so nobody accidentally blasts a fragment of someone tapping the mic down the corridor.
Every fire is written to Multilarm.playlist.log with a timestamp, the alarm name, the folder it picked from, and the actual track chosen. If an SLT member asks “did period 3 ring on Tuesday?” the answer is one grep away. Errors (a missing folder, a file that won’t decode) go to a separate Multilarm.error.log with the same durable-append writer.
Both logs are exposed through the dashboard’s Console Log card, so office staff can read the last few hundred lines without touching the file system.
Quoted replacement controller: mid-four figures, plus install. Actual replacement: one mini-PC they already owned, two £12 USB dongles, and an afternoon of writing XML. The rest of the PA hardware — the bit that’s expensive to pull out of walls — wasn’t touched.
Download, extract, point it at a folder of .wav bells, and your next period rings on time. Get Multilarm.