|
@@ -145,6 +145,10 @@ static volatile uint16_t volumes[8] = {
|
|
|
DEFAULT_VOLUME_LEVEL, DEFAULT_VOLUME_LEVEL, DEFAULT_VOLUME_LEVEL, DEFAULT_VOLUME_LEVEL,
|
|
DEFAULT_VOLUME_LEVEL, DEFAULT_VOLUME_LEVEL, DEFAULT_VOLUME_LEVEL, DEFAULT_VOLUME_LEVEL,
|
|
|
DEFAULT_VOLUME_LEVEL, DEFAULT_VOLUME_LEVEL, DEFAULT_VOLUME_LEVEL, DEFAULT_VOLUME_LEVEL
|
|
DEFAULT_VOLUME_LEVEL, DEFAULT_VOLUME_LEVEL, DEFAULT_VOLUME_LEVEL, DEFAULT_VOLUME_LEVEL
|
|
|
};
|
|
};
|
|
|
|
|
+static volatile uint16_t channels[8] = {
|
|
|
|
|
+ AUDIO_CHANNEL_ENABLE_MASK, AUDIO_CHANNEL_ENABLE_MASK, AUDIO_CHANNEL_ENABLE_MASK, AUDIO_CHANNEL_ENABLE_MASK,
|
|
|
|
|
+ AUDIO_CHANNEL_ENABLE_MASK, AUDIO_CHANNEL_ENABLE_MASK, AUDIO_CHANNEL_ENABLE_MASK, AUDIO_CHANNEL_ENABLE_MASK
|
|
|
|
|
+};
|
|
|
|
|
|
|
|
// mechanism for cleanly stopping DMA units
|
|
// mechanism for cleanly stopping DMA units
|
|
|
static volatile bool audio_stopping = false;
|
|
static volatile bool audio_stopping = false;
|
|
@@ -165,10 +169,17 @@ static uint8_t invert = 0; // biphase encode help: set if last wire bit was '1'
|
|
|
*/
|
|
*/
|
|
|
static void snd_encode(uint8_t* samples, uint16_t* wire_patterns, uint16_t len, uint8_t swap) {
|
|
static void snd_encode(uint8_t* samples, uint16_t* wire_patterns, uint16_t len, uint8_t swap) {
|
|
|
uint16_t wvol = volumes[audio_owner & 7];
|
|
uint16_t wvol = volumes[audio_owner & 7];
|
|
|
- uint8_t vol = ((wvol >> 8) + (wvol & 0xFF)) >> 1; // average of both values
|
|
|
|
|
|
|
+ uint8_t lvol = ((wvol >> 8) + (wvol & 0xFF)) >> 1; // average of both values
|
|
|
// limit maximum volume; with my DACs I've had persistent issues
|
|
// limit maximum volume; with my DACs I've had persistent issues
|
|
|
// with signal clipping when sending data in the highest bit position
|
|
// with signal clipping when sending data in the highest bit position
|
|
|
- vol = vol >> 2;
|
|
|
|
|
|
|
+ lvol = lvol >> 2;
|
|
|
|
|
+ uint8_t rvol = lvol;
|
|
|
|
|
+ // enable or disable based on the channel information for both output
|
|
|
|
|
+ // ports, where the high byte and mask control the right channel, and
|
|
|
|
|
+ // the low control the left channel
|
|
|
|
|
+ uint16_t chn = channels[audio_owner & 7] & AUDIO_CHANNEL_ENABLE_MASK;
|
|
|
|
|
+ if (!(chn >> 8)) rvol = 0;
|
|
|
|
|
+ if (!(chn & 0xFF)) lvol = 0;
|
|
|
|
|
|
|
|
uint16_t widx = 0;
|
|
uint16_t widx = 0;
|
|
|
for (uint16_t i = 0; i < len; i += 2) {
|
|
for (uint16_t i = 0; i < len; i += 2) {
|
|
@@ -182,7 +193,11 @@ static void snd_encode(uint8_t* samples, uint16_t* wire_patterns, uint16_t len,
|
|
|
rsamp = (int16_t)(samples[i] + (samples[i + 1] << 8));
|
|
rsamp = (int16_t)(samples[i] + (samples[i + 1] << 8));
|
|
|
}
|
|
}
|
|
|
// linear scale to requested audio value
|
|
// linear scale to requested audio value
|
|
|
- rsamp *= vol;
|
|
|
|
|
|
|
+ if (i & 2) {
|
|
|
|
|
+ rsamp *= rvol;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ rsamp *= lvol;
|
|
|
|
|
+ }
|
|
|
// use 20 bits of value only, which allows ignoring the lowest 8
|
|
// use 20 bits of value only, which allows ignoring the lowest 8
|
|
|
// bits during biphase conversion (after including sample shift)
|
|
// bits during biphase conversion (after including sample shift)
|
|
|
sample = ((uint32_t)rsamp) & 0xFFFFF0;
|
|
sample = ((uint32_t)rsamp) & 0xFFFFF0;
|
|
@@ -562,4 +577,12 @@ void audio_set_volume(uint8_t id, uint16_t vol) {
|
|
|
volumes[id & 7] = vol;
|
|
volumes[id & 7] = vol;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+uint16_t audio_get_channel(uint8_t id) {
|
|
|
|
|
+ return channels[id & 7];
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void audio_set_channel(uint8_t id, uint16_t chn) {
|
|
|
|
|
+ channels[id & 7] = chn;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
#endif // ENABLE_AUDIO_OUTPUT
|
|
#endif // ENABLE_AUDIO_OUTPUT
|