Skip to main content

Someone wanted to learn this too, so Grasp built them a personal learning path.

You can keep exploring this one or create your own

Optimizing Percussion in DAC-Limited Environments

Hello! Welcome back to your course on the composers of Sega.

In our last lesson, we examined the fundamental choice composers faced between synthesizing percussion with FM operators and playing pre-recorded samples via the DAC. We concluded that while samples offered superior realism and genre authenticity, they came at a high cost in terms of memory, CPU cycles, and available polyphony.

This lesson directly follows that discussion and addresses the learning outcome: Analyze how composers optimized DAC sample usage to balance percussion quality with memory and channel limitations. We will investigate the specific techniques, from basic data reduction to sophisticated driver-level strategies, that enabled composers to make the most of this powerful but expensive feature.

1. The Fundamental Trade-off: Quality vs. Memory

The most direct way to manage the high memory cost of samples was to reduce their data footprint. This involved a direct trade-off with audio quality. Composers had three main levers to pull: sample rate, bit depth, and length.

To see these concepts in action, let's start with a practical overview.

How to make Sega Genesis music (in 1994)

This clip from the GST Channel's video 'How to make Sega Genesis music (in 1994)' provides a concise summary of the core issues composers faced when using the GEMS sound driver.

Please watch the segment from 00:06:55 to 00:08:04. Pay close attention to the narrator's comments on the relationship between sample rate, memory, and quality, as well as the option to reduce bit depth.

As the video explains, using the DAC was a "balancing act between memory and quality." Let's formalize the techniques involved:

  • Sample Rate Reduction: A sample's rate determines its frequency range. The standard CD quality is 44.1 kHz, but Genesis samples were often 8 kHz or even lower. Reducing the sample rate drastically cuts file size (e.g., halving the rate halves the size) but also lowers the Nyquist frequency, filtering out high-frequency content and making the sample sound duller or "muffled."
  • Bit Depth Reduction: The video mentions converting 8-bit samples to 4-bit to halve their size. This process, known as reducing bit depth, decreases the sample's dynamic range and increases the quantization noise floor. The result is a "crunchier," more distorted sound, as the audio waveform is represented with fewer discrete steps.
  • Sample Truncation: The most straightforward optimization was simply to make samples shorter. For percussive sounds, which have a sharp attack followed by a decay, composers would often cut off the tail of the decay. A kick drum or snare doesn't need to ring out for a full second. By trimming the sample to only the essential attack and early decay, memory usage could be significantly reduced with minimal perceived loss in impact.

2. Advanced Memory Optimization: Looping and Reuse

Beyond simple data reduction, programmers employed more sophisticated techniques to get more mileage out of the samples they could afford to store.

Sample Looping

For sounds with a long sustain, like a cymbal crash or a melodic instrument, storing the entire sound was prohibitively expensive. The solution was to record a short "attack" portion and then seamlessly loop an even shorter "sustain" portion of the waveform.

This technique is detailed in the technical manual for an advanced, homebrew sound driver called Dual PCM.

Dual PCM - Technical Manual

The 'Dual PCM - Flexible Edition - Technical Manual' provides an excellent case study of advanced sound programming. This section demonstrates how looping was implemented to save ROM space.

Please read the section titled 'Looping sample example' (page 12). The saxophone example perfectly illustrates the concept of separating a sound into an 'attack' and a 'sustain' loop to create a long note from a small amount of data.

As the manual shows, this allows for an infinitely sustained note while only storing the initial attack and a tiny, looping segment. This was crucial for using the DAC for anything other than short, percussive hits.

Pitch Shifting for Sample Reuse

Another powerful memory-saving technique was to store a single sample and play it back at different speeds to create different pitches. Instead of storing separate samples for a low tom, mid tom, and high tom, a composer could store one tom sample and simply pitch it up or down.

The Dual PCM manual also explains the low-level mechanism for this.

Dual PCM - Technical Manual

Let's return to the 'Dual PCM - Technical Manual' to understand how pitch control was achieved.

Read the 'Thorough explanation' within the 'Pitch control' section (page 15) and the 'End Markers' section (page 16). Focus on how pitch is altered by 'stretching' (repeating) and 'squashing' (skipping) sample bytes. This is a fantastic low-level insight into the optimization.

This method is highly efficient in terms of memory but has audible side effects. Pitching a sample up shortens its duration and can introduce aliasing, while pitching it down lengthens it and can reduce high-frequency content, a phenomenon you may recognize from early digital samplers. The manual's explanation for why the "End Marker" needs to be so large ($180 bytes) is a direct consequence of this pitch-shifting implementation—the driver needs a large block of stop-codes to ensure it doesn't accidentally skip over the end of the sample when playing at a high pitch.

3. Managing the CPU and Bus Contention

Optimizing memory was only half the battle. As we learned previously, the YM2612 has no Direct Memory Access (DMA) for its DAC channel. The Z80 CPU had to manually feed every single sample byte from the cartridge ROM to the sound chip in a precisely timed loop.

The Cycle-Counting Challenge

This manual process required what is known as a cycle-counted loop. Programmers had to write Z80 assembly code where the instructions in the loop took a specific, known number of CPU cycles to execute. By controlling the loop's execution time, they could ensure that new sample data was delivered to the DAC at a steady rate (e.g., 8,000 times per second for an 8kHz sample).

Genesis: Digital Playback | Bumbershoot Software

The article 'Genesis: Digital Playback' from Bumbershoot Software provides a superb, code-level analysis of this process. It's an excellent resource for understanding the fundamental CPU-level challenges.

Please read the introduction, then the sections 'Working Out the Details' and 'The Playback Loop'. You don't need to analyze the assembly code line-by-line, but focus on the principle: the calculation of cycles per sample (447.5 cycles for 8kHz) and the construction of a software loop to approximate this timing. This is the baseline technique for DAC playback.

The DMA Halt Problem and Buffering

This manual process was fragile. The biggest threat was the main 68000 CPU initiating a DMA transfer to the Video Display Processor (VDP), which was common for updating graphics. This would halt the Z80's access to the ROM, starving the DAC of data and causing an audible pop or glitch.

Advanced sound drivers solved this with a classic computer science technique: buffering.

Dual PCM - Technical Manual

The 'Dual PCM' manual again provides the solution. Its primary innovation was a robust buffering system to ensure smooth playback.

Read the section 'DMA interrupt loss prevention' (page 13). It explains how the driver reads sample data from ROM into a buffer in the Z80's own RAM faster than it plays it back. When a DMA halt occurs, the Z80 can continue playing from this buffer, masking the interruption.

This producer-consumer model (Z80-as-producer filling the buffer, Z80-as-consumer emptying it to the DAC) was a critical optimization for achieving high-quality sample playback. The main trade-off, as the manual later notes, is a slight latency, as the audio is always playing from a buffer that was filled a fraction of a second earlier.

4. System-Level Optimization in Advanced Drivers

The most sophisticated drivers treated the entire sound system as a single entity to be optimized, managing not just the DAC but its interaction with the FM channels.

  • The YM2612 Queue: Writing new instructions to the FM channels (e.g., to change a note) also required halting the Z80. Doing this frequently could cause the same audio glitches as a DMA halt. The solution was a command queue. The 68k would write its FM commands to a list in Z80 RAM without a long halt. The Z80 would then process this queue in the small gaps between feeding bytes to the DAC. This minimized Z80 stall time and kept the PCM stream flowing smoothly. This is detailed in the "YM2612 queue" section (page 22) of the Dual PCM manual.

  • Channel Priority Systems: When using the DAC, one of the six FM channels is lost. This makes channel management critical. Sound drivers like GEMS implemented a priority system. A composer could assign a priority level to each musical part. If the music required more channels than were available, the driver would automatically drop the lowest-priority notes. This is a graceful failure mechanism, ensuring that essential elements like a melody or bassline would play even if a less important harmony part had to be sacrificed.

Conclusion

Optimizing DAC sample usage on the Sega Genesis was a multi-faceted challenge that pushed the boundaries of real-time programming on 16-bit hardware. Composers and programmers worked together to balance the competing demands of audio quality, memory constraints, and CPU availability.

Key Takeaways:

  • Memory Optimization: Sample size was managed by reducing sample rate, bit depth, and length. More advanced techniques like looping sustain portions and reusing single samples via pitch-shifting offered greater efficiency.
  • CPU and Quality Optimization: The lack of DMA was overcome with precisely timed, cycle-counted software loops. To prevent audio glitches from bus contention (like VDP DMA), advanced drivers used buffering to ensure a continuous stream of data to the DAC.
  • System-Level Integration: The most effective solutions treated the entire sound system holistically, using command queues to decouple FM updates from PCM playback and priority systems to gracefully manage the reduced channel count.

These techniques were not just technical footnotes; they were creative enablers. By mastering these optimizations, composers could use the DAC not just for an occasional drum hit, but as an integral part of their musical toolkit, paving the way for the sample-heavy, genre-defining soundtracks of the mid-90s.

Preview of the Next Lesson:
Now that we've covered the technical management of percussion through both FM synthesis and optimized sample playback, we will turn to the musical application. Our next lesson will analyze the techniques composers used for creating rhythmic complexity and groove within the Genesis's limited polyphony and sequencing capabilities.

Can't find a good explanation? Sign up and we'll make it for you

Sign up