#21 Feature proposal: Compressor

Open
opened 7 months ago by dronus · 3 comments
dronus commented 7 months ago

As we already have non-DX additions like reverb and chorus, how about a compressor?

My feeling is that even with 16bit audio, the large possible dynamic (eg. playing one smooth voice versus. all keys down rough voice) sometimes lead to bad signal-to-noise-ratio (at least with Teensy Audio Shield’s headphone output) which could be improved by a smaller dynamic range, hence a compressor.

I have some implementation in progress, using the AudioCompressor effect from the OpenAudio library. This however is implemented with 32-bit float audio, and needs two conversions. But seem to run well either.

The implementation is a little bit flaky as it needs the import of some of OpenAudio’s code files into MicroDexed, as the MicroDexed environment reacts toxic to the import of the OpenAudio library (many symbols already defined, no guess why).

So maybe someone knows a good integer-based compressor implementation to be plugged into?

Otherwise I could add some configuration / controlls for the compressor as-is and upload it.

As we already have non-DX additions like reverb and chorus, how about a compressor? My feeling is that even with 16bit audio, the large possible dynamic (eg. playing one smooth voice versus. all keys down rough voice) sometimes lead to bad signal-to-noise-ratio (at least with Teensy Audio Shield's headphone output) which could be improved by a smaller dynamic range, hence a compressor. I have some implementation in progress, using the AudioCompressor effect from the OpenAudio library. This however is implemented with 32-bit float audio, and needs two conversions. But seem to run well either. The implementation is a little bit flaky as it needs the import of some of OpenAudio's code files into MicroDexed, as the MicroDexed environment reacts toxic to the import of the OpenAudio library (many symbols already defined, no guess why). So maybe someone knows a good integer-based compressor implementation to be plugged into? Otherwise I could add some configuration / controlls for the compressor as-is and upload it.
dcoredump commented 7 months ago
Owner

The original DX7 has a problem with velocity. It used only values from 0..100 and not to 127. So external MIDI keyboards sounded to harsh. I added the scaler for mapping the values end of last week (dexed.cpp, line 195; enable/disable in config.h: NORMALIZE_DX_VELOCITY). Perhaps this was the problem? Can you check this?

AFAIK there is no integer based compressor. The Teensy audio shield (SGTL5000) has a builtin (light) compressor. But perhaps we don’t need any (see velocity above).

I don’t want to add too much additional fx, because the T_3.6 has not enough power for a full stack fx chain. Delay eats nearly no cpu time, only RAM. Chorus both. But reverb is really heavy. When reverb is enabled I can only use a maximum of 11 notes at a time (before 16!). So if not really needed, I would like to avoid it currently.

The original DX7 has a problem with velocity. It used only values from 0..100 and not to 127. So external MIDI keyboards sounded to harsh. I added the scaler for mapping the values end of last week (dexed.cpp, line 195; enable/disable in config.h: NORMALIZE_DX_VELOCITY). Perhaps this was the problem? Can you check this? AFAIK there is no integer based compressor. The Teensy audio shield (SGTL5000) has a builtin (light) compressor. But perhaps we don't need any (see velocity above). I don't want to add too much additional fx, because the T_3.6 has not enough power for a full stack fx chain. Delay eats nearly no cpu time, only RAM. Chorus both. But reverb is really heavy. When reverb is enabled I can only use a maximum of 11 notes at a time (before 16!). So if not really needed, I would like to avoid it currently.
dronus commented 6 months ago
Poster

No, I don’t think velocity is the problem.

But polyphony is, using 16bit DAC. As 16 notes may playing simulttaneously, the peak sample value is actually 16 times that of a single oscillator. Hence the Dexed code scales the output down in some fashion, there is a explicit division by 16 at dexed.cpp:148 to cope for the 16x polyphony, and maybe some further attenuation depending on the algorithm to cope with the parallel carrier outputs.

That means playing only one note, only 12 of 16bit amplitude would be used, this can be clearly seen if audio is recorded via USB and all volume and carrier output levels are at 100.

At this point, were already down to the original DX7 12bit quality.

But it is getting worse: The original DX7 has an additional discrete 4 bit DAC for volume adjustments, that may handle carrier output level or algorithm attenuation level. If this is the case, we can expect usage of the whole 12bit range for monophonic single carrier waveforms.

As the original DX7 uses time multiplex (all voices are played one after another in every 60kHz sample interval), every voice may get 12bit by its own.

So it may turn out that Dexed’s mangled 16bit output give a worse SNR than the original ‘12-bit’ DX7 system (that is in fact a 16-times 12 bit mantissa 4 bit exponent floating point DAC).

Also MicroDexed operate at a lower sample rate (44.1kHz) in respect to the DX7 (57kHz).

I guess that is why the original Dexed choses a 24bit implementation, which may give reasonable SNR to pass the DX7 quality. But that would need further 24bit processing (like amplification or compression) before conversion to 16bit to get a full range 16bit signal.

No, I don't think velocity is the problem. But polyphony is, using 16bit DAC. As 16 notes may playing simulttaneously, the peak sample value is actually 16 times that of a single oscillator. Hence the Dexed code scales the output down in some fashion, there is a explicit division by 16 at dexed.cpp:148 to cope for the 16x polyphony, and maybe some further attenuation depending on the algorithm to cope with the parallel carrier outputs. That means playing only one note, only 12 of 16bit amplitude would be used, this can be clearly seen if audio is recorded via USB and all volume and carrier output levels are at 100. At this point, were already down to the original DX7 12bit quality. But it is getting worse: The original DX7 has an additional discrete 4 bit DAC for volume adjustments, that may handle carrier output level or algorithm attenuation level. If this is the case, we can expect usage of the whole 12bit range for monophonic single carrier waveforms. As the original DX7 uses time multiplex (all voices are played one after another in every 60kHz sample interval), every voice may get 12bit by its own. So it may turn out that Dexed's mangled 16bit output give a worse SNR than the original '12-bit' DX7 system (that is in fact a 16-times 12 bit mantissa 4 bit exponent floating point DAC). Also MicroDexed operate at a lower sample rate (44.1kHz) in respect to the DX7 (57kHz). I guess that is why the original Dexed choses a 24bit implementation, which may give reasonable SNR to pass the DX7 quality. But that would need further 24bit processing (like amplification or compression) before conversion to 16bit to get a full range 16bit signal.
dcoredump commented 6 months ago
Owner

Ahhh, ok. You know the internals of a DX7 really well!

What about trying to use an audio queue based on floats? So the output of the dexed object is a float and can be better scaled after processing?

Ahhh, ok. You know the internals of a DX7 really well! What about trying to use an audio queue based on floats? So the output of the dexed object is a float and can be better scaled after processing?
Sign in to join this conversation.
No Label
No Milestone
No Assignees
2 Participants
Notifications
Due Date

No due date set.

Dependencies

This issue currently doesn't have any dependencies.

Loading…
There is no content yet.