int mix()

in src/cubeb_mixer.cpp [523:589]


  int mix(size_t frames, const void * input_buffer, size_t input_buffer_size,
          void * output_buffer, size_t output_buffer_size) const
  {
    if (frames <= 0 || _context._out_ch_count == 0) {
      return 0;
    }

    // Check if output buffer is of sufficient size.
    size_t size_read_needed =
        frames * _context._in_ch_count * cubeb_sample_size(_context._format);
    if (input_buffer_size < size_read_needed) {
      // We don't have enough data to read!
      return -1;
    }
    if (output_buffer_size * _context._in_ch_count <
        size_read_needed * _context._out_ch_count) {
      return -1;
    }

    if (!valid()) {
      // The channel layouts were invalid or unsupported, instead we will simply
      // either drop the extra channels, or fill with silence the missing ones
      if (_context._format == CUBEB_SAMPLE_FLOAT32NE) {
        copy_and_trunc(frames, static_cast<const float *>(input_buffer),
                       static_cast<float *>(output_buffer));
      } else {
        assert(_context._format == CUBEB_SAMPLE_S16NE);
        copy_and_trunc(frames, static_cast<const int16_t *>(input_buffer),
                       reinterpret_cast<int16_t *>(output_buffer));
      }
      return 0;
    }

    switch (_context._format) {
    case CUBEB_SAMPLE_FLOAT32NE: {
      auto f = [](float x) { return x; };
      return rematrix(&_context, static_cast<float *>(output_buffer),
                      static_cast<const float *>(input_buffer),
                      _context._matrix_flt, f, frames);
    }
    case CUBEB_SAMPLE_S16NE:
      if (_context._clipping) {
        auto f = [](int x) {
          int y = (x + 16384) >> 15;
          // clip the signed integer value into the -32768,32767 range.
          if ((y + 0x8000U) & ~0xFFFF) {
            return (y >> 31) ^ 0x7FFF;
          }
          return y;
        };
        return rematrix(&_context, static_cast<int16_t *>(output_buffer),
                        static_cast<const int16_t *>(input_buffer),
                        _context._matrix32, f, frames);
      } else {
        auto f = [](int x) { return (x + 16384) >> 15; };
        return rematrix(&_context, static_cast<int16_t *>(output_buffer),
                        static_cast<const int16_t *>(input_buffer),
                        _context._matrix32, f, frames);
      }
      break;
    default:
      assert(false);
      break;
    }

    return -1;
  }