Adapted Ext. Audio StereoOutput Constructor to send 2xStereo/4xMono

7 views
Skip to first unread message

justin jools

unread,
Jul 24, 2024, 9:02:17 AM (3 days ago) Jul 24
to Mozzi-users
Hi, I have two DACs and wanted to send 4 separate mono waveforms. The constructor only accepts two arguments L/R so I added an additional 2. This would useful to add to library for anyone else wanting to do this called StereoOutput2.

Example usage:
#define SS_PIN PB0 // 10 Arduino
#define SS_PIN2 PB1

DAC_MCP49xx dac(DAC_MCP49xx::MCP4922, SS_PIN);
DAC_MCP49xx dac2(DAC_MCP49xx::MCP4922, SS_PIN2);

void audioOutput(const AudioOutput f)  // f is a structure containing both channels
{
  // signal is passed as 16 bit. This DAC expects 12 bits so shift back four bits, and add a bias of 2^(12-1)=2048
  uint16_t outL = (f.l() >> 4) + 2048;
  uint16_t outR = (f.r() >> 4) + 2048;
  uint16_t outL2 = (f.l2() >> 4) + 2048;
  uint16_t outR2 = (f.r2() >> 4) + 2048;

  dac.outputA(outL);
  dac.outputB(outR);
  dac2.outputA(outL2);
  dac2.outputB(outR2);
}

AudioOutput updateAudio() {  

  return StereoOutput::fromNBit(12, aSaw1.next() * env1, aCos2.next() * env2, aSaw1.next() * env1, aCos2.next() * env2);

}


/** This struct encapsulates one frame of mono audio output. Internally, it really just boils down to two int values, but the struct provides
 *  useful API an top of that. For more detail see @ref MonoOutput . */
struct StereoOutput {
  /** Construct an audio frame from raw values (zero-centered) */
//  StereoOutput(AudioOutputStorage_t l, AudioOutputStorage_t r) : _l(l), _r(r) {};
  StereoOutput(AudioOutputStorage_t l, AudioOutputStorage_t r, AudioOutputStorage_t l2, AudioOutputStorage_t r2) : _l(l), _r(r), _l2(l2), _r2(r2) {};  

  /** Default constructor. Does not initialize the sample! */
  StereoOutput() {};
#if !MOZZI_IS(MOZZI_AUDIO_CHANNELS, MOZZI_STEREO)
  /** Conversion to int operator: If used in a mono config, returns only the left channel (and gives a compile time warning).
      This _could_ be turned into an operator for implicit conversion in this case. For now we chose to apply conversion on demand, only, as most of the time
      using StereoOutput in a mono config, is not intended. */
  inline AudioOutput portable() const __attribute__((deprecated("Sketch generates stereo output, but Mozzi is configured for mono. Check MOZZI_AUDIO_CHANNELS setting."))) { return _l; };
#  if GITHUB_RUNNER_ACCEPT_STEREO_IN_MONO
  inline operator AudioOutput() const __attribute__((deprecated("Stereo converted to mono on github runner"))) { return _l; };
#  endif
#endif
  AudioOutputStorage_t l() const { return _l; };
  AudioOutputStorage_t r() const { return _r; };
  AudioOutputStorage_t l2() const { return _l2; };
  AudioOutputStorage_t r2() const { return _r2; };
  /** See @ref MonoOutput::clip(). Clips both channels. */
  StereoOutput& clip() { _l = CLIP_AUDIO(_l); _r = CLIP_AUDIO(_r); return *this; };

  /** See @ref MonoOutput::fromNBit(), stereo variant */
template<typename T> static inline StereoOutput fromNBit(uint8_t bits, T l, T r, T l2, T r2) { return StereoOutput(SCALE_AUDIO(l, bits), SCALE_AUDIO(r, bits), SCALE_AUDIO(l2, bits), SCALE_AUDIO(r2, bits)); }

private:
  AudioOutputStorage_t _l;
  AudioOutputStorage_t _r;
  AudioOutputStorage_t _l2;
  AudioOutputStorage_t _r2;

};
Reply all
Reply to author
Forward
0 new messages