|  | @@ -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
 |