void AudioBufferContainer::Resize(int nCh, int nFrames, bool preserveData)
{
  if (!m_hasData) 
  {
    preserveData = false;
  }

  const int newsz = nCh*nFrames*(int)m_fmt;

  if (preserveData && (nCh != m_nCh || nFrames != m_nFrames))
  {
    GetAllChannels(m_fmt, true);  // causes m_data to be interleaved

    if (newsz > m_data.GetSize()) m_data.Resize(newsz);
    if (nCh != m_nCh && m_data.GetSize() >= newsz)
    {
      char *out = (char *)m_data.Get();
      const char *in = out;
      const int in_adv = m_nCh * m_fmt, out_adv = nCh * m_fmt;
      const int copysz = min(in_adv,out_adv);

      int n = min(nFrames,m_nFrames);
      if (out_adv < in_adv) // decreasing channel count, left to right
      {
        while (n--)
        {
          if (out!=in) memmove(out,in,copysz);
          out+=out_adv;
          in+=in_adv;
        }
      }
      else // increasing channel count, copy right to left
      {
        out += n * out_adv;
        in += n * in_adv;
        while (n--)
        {
          out-=out_adv;
          in-=in_adv;
          if (out!=in) memmove(out,in,copysz);
        }
      }
      // adjust interleaving
    }
  }
  
  m_data.Resize(newsz);
  m_hasData = preserveData;
  m_nCh = nCh;
  m_nFrames = nFrames;
}
void AudioBufferContainer::Resize(int nCh, int nFrames, bool preserveData)
{
  if (!m_hasData) 
  {
    preserveData = false;
  }

  int newsz = nCh*nFrames*(int)m_fmt;

  if (preserveData && (nCh != m_nCh || nFrames != m_nFrames))
  {
    GetAllChannels(m_fmt, true);  // causes m_data to be interleaved
  }
  
  m_data.Resize(newsz);
  m_hasData = preserveData;
  m_nCh = nCh;
  m_nFrames = nFrames;
}
// src=NULL to memset(0)
void* AudioBufferContainer::SetAllChannels(int fmt, void* src, int nCh, int nFrames)
{
  Reformat(fmt, false);
  Resize(nCh, nFrames, false);
  
  int sz = nCh*nFrames*(int)fmt;
  void* dest = GetAllChannels(fmt, false);
  if (src)
  {
    memcpy(dest, src, sz);
  }
  else
  {
    memset(dest, 0, sz);
  }
  
  m_interleaved = true;
  m_hasData = true;  
  return dest;
}