Пример #1
0
int16_t WebRtcOpus_DecoderCreate(OpusDecInst** inst, int channels) {
  int error_l;
  int error_r;
  OpusDecInst* state;

  // Create Opus decoder memory.
  state = (OpusDecInst*) calloc(1, sizeof(OpusDecInst));
  if (state == NULL) {
    return -1;
  }

  // Create new memory for left and right channel, always at 48000 Hz.
  state->decoder_left = opus_decoder_create(48000, channels, &error_l);
  state->decoder_right = opus_decoder_create(48000, channels, &error_r);
  if (error_l == OPUS_OK && error_r == OPUS_OK && state->decoder_left != NULL
      && state->decoder_right != NULL) {
    // Creation of memory all ok.
    state->channels = channels;
    *inst = state;
    return 0;
  }

  // If memory allocation was unsuccessful, free the entire state.
  if (state->decoder_left) {
    opus_decoder_destroy(state->decoder_left);
  }
  if (state->decoder_right) {
    opus_decoder_destroy(state->decoder_right);
  }
  free(state);
  state = NULL;
  return -1;
}
Пример #2
0
static void audio_renderer_init() {
  int rc;
  decoder = opus_decoder_create(SAMPLE_RATE, CHANNEL_COUNT, &rc);

  snd_pcm_hw_params_t *hw_params;
  snd_pcm_sw_params_t *sw_params;
  snd_pcm_uframes_t period_size = FRAME_SIZE * CHANNEL_COUNT * 2;
  snd_pcm_uframes_t buffer_size = 12 * period_size;
  unsigned int sampleRate = SAMPLE_RATE;

  /* Open PCM device for playback. */
  CHECK_RETURN(snd_pcm_open(&handle, audio_device, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK))

  /* Set hardware parameters */
  CHECK_RETURN(snd_pcm_hw_params_malloc(&hw_params));
  CHECK_RETURN(snd_pcm_hw_params_any(handle, hw_params));
  CHECK_RETURN(snd_pcm_hw_params_set_access(handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED));
  CHECK_RETURN(snd_pcm_hw_params_set_format(handle, hw_params, SND_PCM_FORMAT_S16_LE));
  CHECK_RETURN(snd_pcm_hw_params_set_rate_near(handle, hw_params, &sampleRate, NULL));
  CHECK_RETURN(snd_pcm_hw_params_set_channels(handle, hw_params, CHANNEL_COUNT));
  CHECK_RETURN(snd_pcm_hw_params_set_buffer_size_near(handle, hw_params, &buffer_size));
  CHECK_RETURN(snd_pcm_hw_params_set_period_size_near(handle, hw_params, &period_size, NULL));
  CHECK_RETURN(snd_pcm_hw_params(handle, hw_params));
  snd_pcm_hw_params_free(hw_params);

  /* Set software parameters */
  CHECK_RETURN(snd_pcm_sw_params_malloc(&sw_params));
  CHECK_RETURN(snd_pcm_sw_params_current(handle, sw_params));
  CHECK_RETURN(snd_pcm_sw_params_set_start_threshold(handle, sw_params, buffer_size - period_size));
  CHECK_RETURN(snd_pcm_sw_params_set_avail_min(handle, sw_params, period_size));
  CHECK_RETURN(snd_pcm_sw_params(handle, sw_params));
  snd_pcm_sw_params_free(sw_params);

  CHECK_RETURN(snd_pcm_prepare(handle));
}
Пример #3
0
static int opus_decoder_construct(struct ast_trans_pvt *pvt, int sampling_rate)
{
	struct opus_coder_pvt *opvt = pvt->pvt;
	int error = 0;

	if (!valid_sampling_rate(sampling_rate)) {
		return -1;
	}

	opvt->sampling_rate = sampling_rate;
	opvt->multiplier = 48000/sampling_rate;
	opvt->fec = USE_FEC;	/* FIXME: should be triggered by chan_sip */

	opvt->opus = opus_decoder_create(sampling_rate, 1, &error);

	if (error != OPUS_OK) {
		ast_log(LOG_ERROR, "Error creating the Opus decoder: %s\n", opus_strerror(error));
		return -1;
	}

	opvt->id = ast_atomic_fetchadd_int(&usage.decoder_id, 1) + 1;

	ast_atomic_fetchadd_int(&usage.decoders, +1);

	ast_debug(3, "Created decoder #%d (opus -> %d)\n", opvt->id, sampling_rate);

	return 0;
}
Пример #4
0
static int tdav_codec_opus_open(tmedia_codec_t* self)
{
    tdav_codec_opus_t* opus = (tdav_codec_opus_t*)self;
    int opus_err;

    if(!opus) {
        TSK_DEBUG_ERROR("Invalid parameter");
        return -1;
    }

    // Initialize the decoder
    if(!opus->decoder.inst) {
        TSK_DEBUG_INFO("[OPUS] Open decoder: rate=%d, channels=%d", (int)self->in.rate, (int)TMEDIA_CODEC_AUDIO(self)->in.channels);
        if(!(opus->decoder.inst = opus_decoder_create((opus_int32)self->in.rate, (int)TMEDIA_CODEC_AUDIO(self)->in.channels, &opus_err)) || opus_err != OPUS_OK) {
            TSK_DEBUG_ERROR("Failed to create Opus decoder(rate=%d, channels=%d) instance with error code=%d.", (int)self->in.rate, (int)TMEDIA_CODEC_AUDIO(self)->in.channels, opus_err);
            return -2;
        }
    }
    opus->decoder.last_seq  = 0;

    // Initialize the encoder
    if(!opus->encoder.inst) {
        TSK_DEBUG_INFO("[OPUS] Open encoder: rate=%d, channels=%d", (int)self->out.rate, (int)TMEDIA_CODEC_AUDIO(self)->out.channels);
        if(!(opus->encoder.inst = opus_encoder_create((opus_int32)self->out.rate, (int)TMEDIA_CODEC_AUDIO(self)->out.channels, OPUS_APPLICATION_VOIP, &opus_err)) || opus_err != OPUS_OK) {
            TSK_DEBUG_ERROR("Failed to create Opus decoder(rate=%d, channels=%d) instance with error code=%d.", (int)self->out.rate, (int)TMEDIA_CODEC_AUDIO(self)->out.channels, opus_err);
            return -2;
        }
    }
#if TDAV_UNDER_MOBILE /* iOS, Android and WP8 */
    opus_encoder_ctl(opus->encoder.inst, OPUS_SET_COMPLEXITY(3));
#endif
    opus_encoder_ctl(opus->encoder.inst, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE));

    return 0;
}
Пример #5
0
void SoundOpusData::onRender()
{
	if(_samples && samplesDecodingProgress != _frames)
	{
		Decoder* dec = 0;
		foreach(e, decoders)
		{
			if(e->first == 0)
			{
				dec = e;
				break;
			}
		}

		if(!dec)
		{
			dec = decoders.push();
			int err;
			dec->decoder = opus_decoder_create(AUDIOLIB_FRAME_RATE, _channels, &err);
			dec->first = 0;
			dec->end = 0;
		}

		if(dec->end == samplesDecodingProgress)
		{
			uint packet = dec->end / SOUNDLIB_OPUS_PACKET_FRAMES;
			opus_decode(dec->decoder, _opusData + SOUNDLIB_OPUS_PACKET_SIZE * _channels * packet, SOUNDLIB_OPUS_PACKET_SIZE * _channels, _samples + _channels * packet * SOUNDLIB_OPUS_PACKET_FRAMES, SOUNDLIB_OPUS_PACKET_FRAMES, 0);
			dec->end += SOUNDLIB_OPUS_PACKET_FRAMES;
			dec->unusedCount = 0;
		}
		samplesDecodingProgress = dec->end;
	}
Пример #6
0
bool reconfigure_audio_decoder(ACSession *ac, int32_t sampling_rate, int8_t channels)
{
    if (sampling_rate != ac->ld_sample_rate || channels != ac->ld_channel_count) {
        if (current_time_monotonic() - ac->ldrts < 500) {
            return false;
        }

        int status;
        OpusDecoder *new_dec = opus_decoder_create(sampling_rate, channels, &status);

        if (status != OPUS_OK) {
            LOGGER_ERROR(ac->log, "Error while starting audio decoder(%d %d): %s", sampling_rate, channels, opus_strerror(status));
            return false;
        }

        ac->ld_sample_rate = sampling_rate;
        ac->ld_channel_count = channels;
        ac->ldrts = current_time_monotonic();

        opus_decoder_destroy(ac->decoder);
        ac->decoder = new_dec;

        LOGGER_DEBUG(ac->log, "Reconfigured audio decoder sr: %d cc: %d", sampling_rate, channels);
    }

    return true;
}
Пример #7
0
EncodeManager::EncodeManager()
{
  _enc = opus_encoder_create(SAMPLE_RATE, 2, OPUS_APPLICATION_VOIP, &_err);
  _dec = opus_decoder_create(SAMPLE_RATE, 2, &_err);
  opus_encoder_ctl(this->_enc, OPUS_GET_BANDWIDTH(&this->_len));
  this->_len = FRAMES_PER_BUFFER;
}
Пример #8
0
long opus_create(const char* format_parameters, const char** format_parameters_out,
		 amci_codec_fmt_info_t** format_description) {
  opus_state_t* codec_inst;
  int error;

  unsigned int maxbandwidth = _OPUS_RATE;
  int useinbandfec = _OPUS_INBAND_FEC_;
  int stereo = 0;

  if (format_parameters) {
    DBG("OPUS params: >>%s<<.\n", format_parameters);
    decode_format_parameters(format_parameters, &maxbandwidth, &useinbandfec, &stereo);
  } 
    
  codec_inst = (opus_state_t*)malloc(sizeof(opus_state_t));

  if (!codec_inst) 
    return -1;

  DBG("OPUS: creating encoder with maxbandwidth=%u, stereo=%s, useinbandfec=%s\n",
      maxbandwidth, stereo?"true":"false", useinbandfec?"true":"false");

  codec_inst->opus_enc = opus_encoder_create(_OPUS_RATE,1,_OPUS_APPLICATION_,&error);
  if (error) {
    DBG("OPUS: error %d while creating encoder state.\n", error);
    return -1;
  }

  opus_encoder_ctl(codec_inst->opus_enc, OPUS_SET_FORCE_CHANNELS(stereo ? 2:1));

  unsigned int opus_set_bw = _OPUS_RATE;
  if (maxbandwidth <= 8000) {
    opus_set_bw = OPUS_BANDWIDTH_NARROWBAND;
  } else if (maxbandwidth <= 12000) {
    opus_set_bw = OPUS_BANDWIDTH_MEDIUMBAND;
  } else if (maxbandwidth <= 16000) {
    opus_set_bw = OPUS_BANDWIDTH_WIDEBAND;
  } else if (maxbandwidth <= 24000) {
    opus_set_bw = OPUS_BANDWIDTH_SUPERWIDEBAND;
  } else {
    opus_set_bw = OPUS_BANDWIDTH_FULLBAND;
  }
  opus_encoder_ctl(codec_inst->opus_enc, OPUS_SET_MAX_BANDWIDTH(opus_set_bw));

  opus_encoder_ctl(codec_inst->opus_enc, OPUS_SET_PACKET_LOSS_PERC(_OPUS_PKT_LOSS_PCT_));
  opus_encoder_ctl(codec_inst->opus_enc, OPUS_SET_COMPLEXITY(_OPUS_COMPLEXITY_));
  opus_encoder_ctl(codec_inst->opus_enc, OPUS_SET_INBAND_FEC(useinbandfec ? 1:0));
  opus_encoder_ctl(codec_inst->opus_enc, OPUS_SET_DTX(_OPUS_DTX_));

  codec_inst->opus_dec = opus_decoder_create(_OPUS_RATE,1,&error);
  if (error) {
    DBG("OPUS: error %d while creating decoder state.\n", error);
    opus_encoder_destroy(codec_inst->opus_enc);
    return -1;
  }

  *format_description = opus_fmt_description;

  return (long)codec_inst;
}
Пример #9
0
void Opus::setOptimalFormat(uint32_t sample_rate, uint8_t channels)
{
    // Use a SR higher or equal to sample_rate.
    // Typical case: 44.1kHz => 48kHz.
    unsigned i = 0;
    while (i < VALID_SAMPLING_RATE_NUM - 1 and VALID_SAMPLING_RATE[i] < sample_rate)
        i++;
    sample_rate = VALID_SAMPLING_RATE[i];

    // Opus supports 1 or 2 channels.
    channels = std::max(std::min(channels, (uint8_t) 2), (uint8_t) 1);

    if (not (!encoder_ || !decoder_ || sample_rate != clockRateCur_ || channels != channelsCur_))
        return;

    clockRateCur_ = sample_rate;
    channelsCur_ = channels;

    int err;
    if (encoder_)
        opus_encoder_destroy(encoder_);
    encoder_ = opus_encoder_create(sample_rate, channels, OPUS_APPLICATION_VOIP, &err);
    if (err)
        throw std::runtime_error("opus: could not create encoder");

    if (decoder_)
        opus_decoder_destroy(decoder_);
    lastDecodedFrameSize_ = 0;
    decoder_ = opus_decoder_create(sample_rate, channels, &err);
    if (err)
        throw std::runtime_error("opus: could not create decoder");
}
Пример #10
0
bool FVoiceDecoderOpus::Init(int32 InSampleRate, int32 InNumChannels)
{
	UE_LOG(LogVoiceDecode, Display, TEXT("DecoderVersion: %s"), ANSI_TO_TCHAR(opus_get_version_string()));

	SampleRate = InSampleRate;
	NumChannels = InNumChannels;

	FrameSize = SampleRate / 50;

	int32 DecSize = 0;
	int32 DecError = 0;

#if USE_UE4_MEM_ALLOC
	DecSize = opus_decoder_get_size(NumChannels);
	Decoder = (OpusDecoder*)FMemory::Malloc(DecSize);
	DecError = opus_decoder_init(Decoder, SampleRate, NumChannels);
#else
	Decoder = opus_decoder_create(SampleRate, NumChannels, &DecError);
#endif
	if (DecError != OPUS_OK)
	{
		UE_LOG(LogVoiceDecode, Warning, TEXT("Failed to init Opus Decoder: %s"), ANSI_TO_TCHAR(opus_strerror(DecError)));
		Destroy();
	}

	return DecError == OPUS_OK;
}
Пример #11
0
static int alloc(struct aucodec_st **stp, struct aucodec *ac,
		 struct aucodec_prm *encp, struct aucodec_prm *decp,
		 const char *fmtp)
{
	struct aucodec_st *st;
	const uint32_t srate = aucodec_srate(ac);
	const uint8_t ch = aucodec_ch(ac);
	uint32_t ptime = DEFAULT_PTIME;
	int use_inbandfec;
	int use_dtx;
	int err = 0;
	int opuserr;

	(void)decp;
	(void)fmtp;

	st = mem_zalloc(sizeof(*st), destructor);
	if (!st)
		return ENOMEM;

	if (encp && encp->ptime)
		ptime = encp->ptime;

	st->ac         = mem_ref(ac);
	st->frame_size = srate * ptime / 1000;
	st->fsize      = 2 * st->frame_size * ch;

	/* Encoder */
	st->enc = opus_encoder_create(srate, ch, opus.app, &opuserr);
	if (!st->enc) {
		err = ENOMEM;
		goto out;
	}

	use_inbandfec = 1;
	use_dtx = 1;

	opus_encoder_ctl(st->enc, OPUS_SET_BITRATE(opus.bitrate));
	opus_encoder_ctl(st->enc, OPUS_SET_BANDWIDTH(opus.bandwidth));
	opus_encoder_ctl(st->enc, OPUS_SET_VBR(opus.vbr));
	opus_encoder_ctl(st->enc, OPUS_SET_COMPLEXITY(opus.complex));
	opus_encoder_ctl(st->enc, OPUS_SET_INBAND_FEC(use_inbandfec));
	opus_encoder_ctl(st->enc, OPUS_SET_DTX(use_dtx));

	/* Decoder */
	st->dec = opus_decoder_create(srate, ch, &opuserr);
	if (!st->dec) {
		err = ENOMEM;
		goto out;
	}

 out:
	if (err)
		mem_deref(st);
	else
		*stp = st;

	return err;
}
Пример #12
0
int init_receive_audio(codec_state *cs)
{
    int err = OPUS_OK;
    cs->audio_decoder = opus_decoder_create(48000, 1, &err);
    opus_decoder_init(cs->audio_decoder, 48000, 1);
    printf("init audio decoder successful\n");
    return 1;
}
Пример #13
0
// This function must be called before
// any other decoding functions
int nv_opus_init(void) {
	int err;
	decoder = opus_decoder_create(
		nv_opus_get_sample_rate(),
		nv_opus_get_channel_count(),
		&err);
	return err;
}
Пример #14
0
    virtual bool Construct()
    {
      int error;
      if ((m_decoder = opus_decoder_create(m_sampleRate, m_channels, &error)) != NULL)
        return true;

      PTRACE(1, MY_CODEC_LOG, "Decoder create error " << error << ' ' << opus_strerror(error));
      return false;
    }
Пример #15
0
EMSCRIPTEN_KEEPALIVE
Encoder* create_encoder_and_decoder(opus_int32 sample_rate, int channels, int application) {
    Encoder* enc = malloc(sizeof(Encoder));

    enc->encoder = opus_encoder_create( sample_rate, channels, application, &enc->encoder_error );
    enc->decoder = opus_decoder_create( sample_rate, channels, &enc->decoder_error );

    return enc;
}
Пример #16
0
static void ms_opus_dec_preprocess(MSFilter *f) {
	int error;
	OpusDecData *d = (OpusDecData *)f->data;
	d->state = opus_decoder_create(d->samplerate, d->channels, &error);
	if (error != OPUS_OK) {
		ms_error("Opus decoder creation failed: %s", opus_strerror(error));
	}
	/* initialise the concealer context */
	d->concealer = ms_concealer_context_new(UINT32_MAX);
}
Пример #17
0
AudioCodec::AudioCodec() {
  this->FrameSize = 24000;
  this->num_channels = 2;
  this->enc = opus_encoder_create(this->FrameSize, this->num_channels,
                                  OPUS_APPLICATION_VOIP, &this->error);
  this->dec =
      opus_decoder_create(this->FrameSize, this->num_channels, &this->error);
  opus_int32 size;
  opus_encoder_ctl(enc, OPUS_GET_BANDWIDTH(&size));
  this->data_size = size;
}
JNIEXPORT jlong JNICALL
Java_org_jitsi_impl_neomedia_codec_audio_opus_Opus_decoder_1create
    (JNIEnv *env, jclass clazz, jint Fs, jint channels)
{
    int error;
    OpusDecoder *decoder = opus_decoder_create(Fs, channels, &error);

    if (OPUS_OK != error)
        decoder = 0;
    return (jlong) (intptr_t) decoder;
}
Пример #19
0
int init_audio_decoder(CodecState *cs, uint32_t audio_channels)
{
    int rc;
    cs->audio_decoder = opus_decoder_create(cs->audio_sample_rate, audio_channels, &rc );

    if ( rc != OPUS_OK ) {
        LOGGER_ERROR("Error while starting audio decoder: %s", opus_strerror(rc));
        return -1;
    }

    return 0;
}
Пример #20
0
            opus_decoder::opus_decoder()
            {
                int err;
                _opus = opus_decoder_create(SAMPLE_RATE, CHANNELS, &err);

                if(err != OPUS_OK) 
                {
                    LOG << "opus decoder create error: "; log_opus_error(err);
                }

                ENSURE(_opus);
            }
Пример #21
0
//function sets up the encoder/decoder structs and buffers, returns required samples/frame
int setup_codecs(){
  //create the encoder and decoder state structs
  int error = 0;
  if(!(enc_state = opus_encoder_create(SAMPLE_RATE,1,APP_MODE,&error)))
    printf("Error Creating Encoder: %d\n",error);
  if(!(dec_state = opus_decoder_create(SAMPLE_RATE,1,&error)))
    printf("Error Creating Decoder: %d\n",error);
  
  opus_encoder_ctl(enc_state, OPUS_SET_COMPLEXITY(QUALITY));
  
  return FRAME_SIZE;  //return the frame size (
}
Пример #22
0
static int init_audio_decoder(CSSession *cs)
{
    int rc;
    cs->audio_decoder = opus_decoder_create(cs->audio_decoder_sample_rate, cs->audio_decoder_channels, &rc );

    if ( rc != OPUS_OK ) {
        LOGGER_ERROR("Error while starting audio decoder: %s", opus_strerror(rc));
        return -1;
    }

    return 0;
}
Пример #23
0
OpusDecoder *tc_opus_create_decoder(int sample_rate, int channels)
{
   int err;

   OpusDecoder * decoder = opus_decoder_create(sample_rate, channels, &err);
   if (err<0) {
      pa_log_error("failed to create decoder: %s", opus_strerror(err));
      return NULL;
   }

   return decoder;
}
Пример #24
0
int init_audio_decoder(CodecState *cs, uint32_t audio_channels)
{
    int rc;
    cs->audio_decoder = opus_decoder_create(cs->audio_sample_rate, audio_channels, &rc );

    if ( rc != OPUS_OK ) {
        fprintf(stderr, "Error while starting audio decoder!\n");
        return -1;
    }

    return 0;
}
Пример #25
0
WebRtc_Word16 WebRtcOpus_CreateDec(OPUS_decinst_t** inst, WebRtc_Word16 samplFreq){
  
  *inst=(OPUS_decinst_t*)malloc(sizeof(OPUS_Dec_Inst_t));
  if (*inst==NULL) {
    return(-1);
  }
  
  int err;
  
  ((OPUS_Dec_Inst_t*)*inst)->dec = opus_decoder_create(16000, 1, &err);
  if(err != OPUS_OK || ((OPUS_Dec_Inst_t*)*inst)->dec==NULL) {
    return (-1);
  }
  
  return(0);
}
Пример #26
0
int16_t WebRtcOpus_DecoderCreate(OpusDecInst** inst, int channels) {
  OpusDecInst* state;
  state = (OpusDecInst*) calloc(1, sizeof(OpusDecInst));
  if (state) {
    int error;
    // Always create a 48000 Hz Opus decoder.
    state->decoder = opus_decoder_create(48000, channels, &error);
    if (error == OPUS_OK && state->decoder != NULL ) {
      *inst = state;
      return 0;
    }
    free(state);
    state = NULL;
  }
  return -1;
}
Пример #27
0
void OpusDecode::start(int CHANNELS, int SAMPLE_RATE)
{
    initialized = false;

    /* Create a new decoder state. */
    int err;
    decoder = opus_decoder_create(SAMPLE_RATE, CHANNELS, &err);
    if (err<0)
    {
        qDebug() << "failed to create decoder:" << opus_strerror(err);
        return;
    }

    channels = CHANNELS;

    initialized = true;
}
Пример #28
0
void OpusDecoderClass::startPrivate(int sample_rate, int channels, int frame_size, int max_frame_size)
{
    if (m_initialized)
        return;

    /* Create a new decoder state. */
    int err;
    m_decoder = opus_decoder_create(sample_rate, channels, &err);
    if (err < 0)
    {
        emit error(QString("Failed to create Opus decoder: %0").arg(opus_strerror(err)));
        return;
    }

    m_channels = channels;
    m_frame_size = frame_size;
    m_max_frame_size = max_frame_size;

    m_initialized = true;
}
Пример #29
0
JNIEXPORT jlong JNICALL Java_aopus_OpusLibrary_decoderCreate
  (JNIEnv *env, jobject obj, jint clockRate, jint channels, jint packetTime)
{
    Decoder *decoder = malloc(sizeof* decoder);
    
    decoder->frameSizePerChannel = (clockRate * packetTime) / 1000;
    decoder->maxBufferSize = clockRate * channels * packetTime * 2 / 1000; // 2 bytes per sample, 1000 ms per second
    decoder->buffer = malloc(decoder->maxBufferSize);

    decoder->channels = channels;
    decoder->previousPacketInvalid = 0;

    // initialize decoder
    int error;
    decoder->dec = opus_decoder_create(clockRate, channels, &error);
    if (error != OPUS_OK)
    {
        __android_log_print(ANDROID_LOG_ERROR, "fm.libopus", "Could not initialize decoder. %d", error);
        return 0;
    }
    return decoder;
}
Пример #30
0
static void sdl_renderer_init() {
  int rc;
  decoder = opus_decoder_create(SAMPLE_RATE, CHANNEL_COUNT, &rc);

  SDL_InitSubSystem(SDL_INIT_AUDIO);

  SDL_AudioSpec want, have;
  SDL_zero(want);
  want.freq = SAMPLE_RATE;
  want.format = AUDIO_S16LSB;
  want.channels = CHANNEL_COUNT;
  want.samples = 4096;

  dev = SDL_OpenAudioDevice(NULL, 0, &want, &have, SDL_AUDIO_ALLOW_FORMAT_CHANGE);
  if (dev == 0) {
    printf("Failed to open audio: %s\n", SDL_GetError());
  } else {
    if (have.format != want.format)  // we let this one thing change.
      printf("We didn't get requested audio format.\n");
    SDL_PauseAudioDevice(dev, 0);  // start audio playing.
  }
}