Example #1
0
static int open_output(void)
{
  int include_enc, exclude_enc;

  include_enc = exclude_enc = 0;

  /* only 16 bit is supported */
  include_enc |= PE_16BIT|PE_SIGNED;
  exclude_enc |= PE_BYTESWAP|PE_24BIT;
  dpm.encoding = validate_encoding(dpm.encoding, include_enc, exclude_enc);

#if !defined (IA_W32GUI) && !defined (IA_W32G_SYN)
  if (dpm.name == NULL) {
    dpm.flag |= PF_AUTO_SPLIT_FILE;
  }
  else {
    dpm.flag &= ~PF_AUTO_SPLIT_FILE;
    if ((dpm.fd = speex_output_open(dpm.name, NULL)) == -1)
      return -1;
  }
#else
  if (w32g_auto_output_mode > 0){
    dpm.flag |= PF_AUTO_SPLIT_FILE;
    dpm.name = NULL;
  }
  else {
    dpm.flag &= ~PF_AUTO_SPLIT_FILE;
    if ((dpm.fd = speex_output_open(dpm.name, NULL)) == -1)
      return -1;
  }
#endif
  return 0;
}
Example #2
0
File: flac_a.c Project: ranvis/tina
static int open_output(void)
{
  int include_enc, exclude_enc;  

#ifdef AU_FLAC_DLL
	if (g_load_libFLAC_dll("libFLAC.dll")) {
		return -1;
	}
#endif
#ifdef AU_OGGFLAC_DLL
	if (g_load_libOggFLAC_dll("libOggFLAC.dll")) {
#ifdef AU_FLAC_DLL
		g_free_libFLAC_dll ();
#endif
		return -1;
	}
#endif

  include_enc = exclude_enc = 0;

  /* only 16 bit is supported */
  include_enc |= PE_16BIT | PE_SIGNED;
  exclude_enc |= PE_BYTESWAP | PE_24BIT;
  dpm.encoding = validate_encoding(dpm.encoding, include_enc, exclude_enc);

#ifdef AU_OGGFLAC
  if (flac_options.isogg) {
    ctl->cmsg(CMSG_WARNING, VERB_NORMAL, "*** cannot write back seekpoints when encoding to Ogg yet ***");
    ctl->cmsg(CMSG_WARNING, VERB_NORMAL, "*** and stream end will not be written.                   ***");
  }
#endif

#ifndef __W32G__
  if(dpm.name == NULL) {
    dpm.flag |= PF_AUTO_SPLIT_FILE;
  } else {
    dpm.flag &= ~PF_AUTO_SPLIT_FILE;
    if(flac_output_open(dpm.name, NULL) == -1)
      return -1;
  }
#else
  if(w32g_auto_output_mode > 0) {
    dpm.flag |= PF_AUTO_SPLIT_FILE;
    dpm.name = NULL;
    } else {
    dpm.flag &= ~PF_AUTO_SPLIT_FILE;
    if (flac_output_open(dpm.name, NULL) == -1)
      return -1;
  }
#endif

  return 0;
}
Example #3
0
static int open_output(void)
{
  dpm.encoding = validate_encoding(dpm.encoding, 0, 0);

  if(dpm.name == NULL) {
    dpm.flag |= PF_AUTO_SPLIT_FILE;
    dpm.name = NULL;
  } else {
    dpm.flag &= ~PF_AUTO_SPLIT_FILE;
    if((dpm.fd = raw_output_open(dpm.name)) == -1)
      return -1;
  }

  return 0;
}
Example #4
0
static int try_open(void)
{
    //int fd, tmp, i;
    int include_enc, exclude_enc;
    esd_format_t esdformat;

    include_enc = 0;
    exclude_enc = PE_ULAW|PE_ALAW|PE_BYTESWAP; /* They can't mean these */
    if(dpm.encoding & PE_16BIT)
	include_enc |= PE_SIGNED;
    else
	exclude_enc |= PE_SIGNED;
    dpm.encoding = validate_encoding(dpm.encoding, include_enc, exclude_enc);

    /* Open the audio device */
    esdformat = (dpm.encoding & PE_16BIT) ? ESD_BITS16 : ESD_BITS8;
    esdformat |= (dpm.encoding & PE_MONO) ? ESD_MONO : ESD_STEREO;
    return esd_play_stream_fallback(esdformat,dpm.rate,NULL,"timidity");
}
Example #5
0
static int open_output(void)
{
    int include_enc, exclude_enc;

    include_enc = exclude_enc = 0;
    if(dpm.encoding & PE_16BIT)
    {
#ifdef LITTLE_ENDIAN
	exclude_enc = PE_BYTESWAP;
#else
	include_enc = PE_BYTESWAP;
#endif /* LITTLE_ENDIAN */
	include_enc |= PE_SIGNED;
    }
    else if(!(dpm.encoding & (PE_ULAW|PE_ALAW)))
    {
	exclude_enc = PE_SIGNED;
    }

    dpm.encoding = validate_encoding(dpm.encoding, include_enc, exclude_enc);

    if(dpm.name == NULL) {
      dpm.flag |= PF_AUTO_SPLIT_FILE;
      dpm.name = NULL;
    } else {
      dpm.flag &= ~PF_AUTO_SPLIT_FILE;
      if((dpm.fd = wav_output_open(dpm.name)) == -1)
	return -1;
    }

    /* Reset the length counter */
    bytes_output = 0;
    next_bytes = bytes_output + UPDATE_HEADER_STEP;
    already_warning_lseek = 0;

    return 0;
}
static int open_output(void)
{
  int include_enc, exclude_enc;

  /********** Encode setup ************/

  include_enc = exclude_enc = 0;

  /* only 16 bit is supported */
  include_enc |= PE_16BIT|PE_SIGNED;
  exclude_enc |= PE_BYTESWAP;
  dpm.encoding = validate_encoding(dpm.encoding, include_enc, exclude_enc);

  if(dpm.name == NULL) {
    dpm.flag |= PF_AUTO_SPLIT_FILE;
    dpm.name = NULL;
  } else {
    dpm.flag &= ~PF_AUTO_SPLIT_FILE;
    if((dpm.fd = ogg_output_open(dpm.name, NULL)) == -1)
      return -1;
  }

  return 0;
}
Example #7
0
static int open_output(void)
{
	double rate;
	int n, nrates, include_enc, exclude_enc, ret;
	PaSampleFormat SampleFormat, nativeSampleFormats;
	
	if( dpm.name != NULL)
		ret = sscanf(dpm.name, "%d", &opt_pa_device_id);
	if (dpm.name == NULL || ret == 0 || ret == EOF)
		opt_pa_device_id = -2;
	
#ifdef AU_PORTAUDIO_DLL
#if PORTAUDIO_V19
  {
		if(&dpm == &portaudio_asio_play_mode){
			HostApiTypeId = paASIO;
		} else if(&dpm == &portaudio_win_ds_play_mode){
			HostApiTypeId = paDirectSound;
		} else if(&dpm == &portaudio_win_wmme_play_mode){
			HostApiTypeId = paMME;
		} else {
			return -1;
		}
		if(load_portaudio_dll(0))
				return -1;
  }
#else
  {
		if(&dpm == &portaudio_asio_play_mode){
			if(load_portaudio_dll(PA_DLL_ASIO))
				return -1;
		} else if(&dpm == &portaudio_win_ds_play_mode){
			if(load_portaudio_dll(PA_DLL_WIN_DS))
				return -1;
		} else if(&dpm == &portaudio_win_wmme_play_mode){
			if(load_portaudio_dll(PA_DLL_WIN_WMME))
				return -1;
		} else {
			return -1;
		}
  }
#endif
#endif
	/* if call twice Pa_OpenStream causes paDeviceUnavailable error  */
	if(pa_active == 1) return 0; 
	if(pa_active == 0){
		err = Pa_Initialize();
		if( err != paNoError ) goto error;
		pa_active = 1;
	}

	if (opt_pa_device_id == -1){
		print_device_list();
		goto error2;
	}
#ifdef PORTAUDIO_V19
#ifdef AU_PORTAUDIO_DLL
       {	
        PaHostApiIndex i, ApiCount;
	i = 0;
	ApiCount = Pa_GetHostApiCount();
	do{
		HostApiInfo=Pa_GetHostApiInfo(i);
		if( HostApiInfo->type == HostApiTypeId ) break;
		i++;
	}while ( i < ApiCount );
	if ( i == ApiCount ) goto error;
	
	DeviceIndex = HostApiInfo->defaultOutputDevice;
	if(DeviceIndex==paNoDevice) goto error;
        }
#else
	DeviceIndex = Pa_GetDefaultOutputDevice();
	if(DeviceIndex==paNoDevice) goto error;
#endif
	DeviceInfo = Pa_GetDeviceInfo( DeviceIndex);
	if(DeviceInfo==NULL) goto error;

	if(opt_pa_device_id != -2){
		const PaDeviceInfo *id_DeviceInfo;
    	id_DeviceInfo=Pa_GetDeviceInfo((PaDeviceIndex)opt_pa_device_id);
		if(id_DeviceInfo==NULL) goto error;
		if( DeviceInfo->hostApi == id_DeviceInfo->hostApi){
			DeviceIndex=(PaDeviceIndex)opt_pa_device_id;
			DeviceInfo = id_DeviceInfo;
		}
    }


	if (dpm.encoding & PE_24BIT) {
		SampleFormat = paInt24;
	}else if (dpm.encoding & PE_16BIT) {
		SampleFormat = paInt16;
	}else {
		SampleFormat = paInt8;
	}

	stereo = (dpm.encoding & PE_MONO) ? 1 : 2;
	data_nbyte = (dpm.encoding & PE_16BIT) ? 2 : 1;
	data_nbyte = (dpm.encoding & PE_24BIT) ? 3 : data_nbyte;
	
	pa_data.samplesToGo = 0;
	pa_data.bufpoint = pa_data.buf;
	pa_data.bufepoint = pa_data.buf;
//	firsttime = 1;
	numBuffers = 1; //Pa_GetMinNumBuffers( framesPerBuffer, dpm.rate );
	framesPerInBuffer = numBuffers * framesPerBuffer;
	if (framesPerInBuffer < 4096) framesPerInBuffer = 4096;
	bytesPerInBuffer = framesPerInBuffer * data_nbyte * stereo;

	/* set StreamParameters */
	StreamParameters.device = DeviceIndex;
	StreamParameters.channelCount = stereo;
	if(ctl->id_character != 'r' && ctl->id_character != 'A' && ctl->id_character != 'W' && ctl->id_character != 'P'){
		StreamParameters.suggestedLatency = DeviceInfo->defaultHighOutputLatency;
	}else{
		StreamParameters.suggestedLatency = DeviceInfo->defaultLowOutputLatency;
	}
	StreamParameters.hostApiSpecificStreamInfo = NULL;
	
	if( SampleFormat == paInt16){
		StreamParameters.sampleFormat = paInt16;
		if( paFormatIsSupported != Pa_IsFormatSupported( NULL , 
							&StreamParameters,(double) dpm.rate )){
			StreamParameters.sampleFormat = paInt32;
			conv16_32 = 1;
		} else {
			StreamParameters.sampleFormat = paInt16;
			conv16_32 = 0;
		}
	}else{
		StreamParameters.sampleFormat = SampleFormat;
	}
	err = Pa_IsFormatSupported( NULL ,
                             &StreamParameters,
							(double) dpm.rate );
	if ( err != paNoError) goto error;
	err = Pa_OpenStream(    
		& stream,			/* passes back stream pointer */
		NULL,			 	/* inputStreamParameters */
		&StreamParameters,	/* outputStreamParameters */
		(double) dpm.rate,	/* sample rate */
		paFramesPerBufferUnspecified,	/* frames per buffer */
		paFramesPerBufferUnspecified,	/* PaStreamFlags */
		paCallback,			/* specify our custom callback */
		&pa_data			/* pass our data through to callback */
		);
//		Pa_Sleeep(1);
	if ( err != paNoError) goto error;
	return 0;
	
#else
	if(opt_pa_device_id == -2){
		DeviceID = Pa_GetDefaultOutputDeviceID();
	    if(DeviceID==paNoDevice) goto error2;
	}else{
		DeviceID = opt_pa_device_id;
	}
	DeviceInfo = Pa_GetDeviceInfo( DeviceID);	
	if(DeviceInfo==NULL) goto error2;
	nativeSampleFormats = DeviceInfo->nativeSampleFormats;

	exclude_enc = PE_ULAW | PE_ALAW | PE_BYTESWAP;
	include_enc = PE_SIGNED;
	if (!(nativeSampleFormats & paInt16) && !(nativeSampleFormats & paInt32)) {exclude_enc |= PE_16BIT;}
	if (!(nativeSampleFormats & paInt24)) {exclude_enc |= PE_24BIT;}
    dpm.encoding = validate_encoding(dpm.encoding, include_enc, exclude_enc);

	if (dpm.encoding & PE_24BIT) {
		SampleFormat = paInt24;
	}else if (dpm.encoding & PE_16BIT) {
		if(nativeSampleFormats & paInt16) SampleFormat = paInt16;
		else{
			SampleFormat = paInt32;
			conv16_32 = 1;
		}
	}else {
		SampleFormat = paInt8;
	}

	stereo = (dpm.encoding & PE_MONO) ? 1 : 2;
	data_nbyte = (dpm.encoding & PE_16BIT) ? 2 : 1;
	data_nbyte = (dpm.encoding & PE_24BIT) ? 3 : data_nbyte;

	nrates = DeviceInfo->numSampleRates;
	if (nrates == -1) {	/* range supported */
		rate = dpm.rate;
		if (dpm.rate < DeviceInfo->sampleRates[0]) rate = DeviceInfo->sampleRates[0];
		if (dpm.rate > DeviceInfo->sampleRates[1]) rate = DeviceInfo->sampleRates[1];
	} else {
		rate = DeviceInfo->sampleRates[nrates-1];
		for (n = nrates - 1; n >= 0; n--) {	/* find nearest sample rate */
			if (dpm.rate <= DeviceInfo->sampleRates[n]) rate=DeviceInfo->sampleRates[n];
		}
	}
	dpm.rate = (int32)rate;
	
	pa_data.samplesToGo = 0;
	pa_data.bufpoint = pa_data.buf;
	pa_data.bufepoint = pa_data.buf;
//	firsttime = 1;
	numBuffers = Pa_GetMinNumBuffers( framesPerBuffer, dpm.rate );
	framesPerInBuffer = numBuffers * framesPerBuffer;
	if (framesPerInBuffer < 4096) framesPerInBuffer = 4096;
	bytesPerInBuffer = framesPerInBuffer * data_nbyte * stereo;
//	printf("%d\n",framesPerInBuffer);
//	printf("%d\n",dpm.rate);
	err = Pa_OpenDefaultStream(
    	&stream,        /* passes back stream pointer */
    	0,              /* no input channels */
    	stereo,              /* 2:stereo 1:mono output */
    	SampleFormat,      /* 24bit 16bit 8bit output */
		(double)dpm.rate,          /* sample rate */
    	framesPerBuffer,            /* frames per buffer */
    	numBuffers,              /* number of buffers, if zero then use default minimum */
    	paCallback, /* specify our custom callback */
    	&pa_data);   /* pass our data through to callback */
	if ( err != paNoError && err != paHostError) goto error;
	return 0;

#endif

error:
	ctl->cmsg(  CMSG_ERROR, VERB_NORMAL, "PortAudio error: %s\n", Pa_GetErrorText( err ) );
error2:
	Pa_Terminate(); pa_active = 0;
#ifdef AU_PORTAUDIO_DLL
#ifndef PORTAUDIO_V19
  free_portaudio_dll();
#endif
#endif

	return -1;
}
Example #8
0
static int open_output(void)
{
    int include_enc = 0, exclude_enc = PE_BYTESWAP;
    struct stat sb;
    audio_info_t auinfo;
    char *audio_dev, *audio_ctl_dev, *tmp_audio;


    /* See if the AUDIODEV environment variable is defined, and set the
       audio device accordingly  - Lalit Chhabra 23/Oct/2001 */
    if((audio_dev  = getenv("AUDIODEV")) != NULL)
    {
      dpm.id_name = safe_malloc(strlen(audio_dev));
      dpm.name = safe_malloc(strlen(audio_dev));
      strcpy(dpm.name, audio_dev);
      strcpy(dpm.id_name, audio_dev);

      tmp_audio = safe_malloc(strlen(audio_dev) + 3);
      audio_ctl_dev = safe_malloc(strlen(audio_dev) + 3);

      strcpy(tmp_audio, audio_dev);
      strcpy(audio_ctl_dev, strcat(tmp_audio, "ctl"));
    }
    else
    {
      audio_ctl_dev = safe_malloc(strlen(AUDIO_CTLDEV) + 3);
      strcpy(audio_ctl_dev, AUDIO_CTLDEV);
    }

    output_counter = play_samples_offset = 0;

    /* Open the audio device */
    if((audioctl_fd = open(audio_ctl_dev, O_RDWR)) < 0)
    {
	ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
		  "%s: %s", audio_ctl_dev, strerror(errno));
	return -1;
    }

/* ############## */
#if 0
    if((dpm.fd = open(dpm.name, O_WRONLY | O_NDELAY)) == -1)
    {
	ctl->cmsg(CMSG_WARNING, VERB_NORMAL,
		  "%s: %s", dpm.name, strerror(errno));
	if(errno == EBUSY)
	{
	    if((dpm.fd = open(dpm.name, O_WRONLY)) == -1)
	    {
		ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
			  "%s: %s", dpm.name, strerror(errno));
		close_output();
		return -1;
	    }
	}
    }
#endif

    if((dpm.fd = open(dpm.name, O_WRONLY)) == -1)
    {
	ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
		  "%s: %s", dpm.name, strerror(errno));
	close_output();
	return -1;
    }

    if(stat(dpm.name, &sb) < 0)
    {
	ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
		  "%s: %s", dpm.name, strerror(errno));
	close_output();
	return -1;
    }

    if(!S_ISCHR(sb.st_mode))
    {
	ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
		  "%s: Not a audio device", dpm.name);
	close_output();
	return -1;
    }

    if(sun_audio_getinfo(&auinfo) < 0)
    { 
	/* from Francesco Zanichelli's */
	/* If it doesn't give info, it probably won't take requests
	    either. Assume it's an old device that does 8kHz uLaw only.

	      Disclaimer: I don't know squat about the various Sun audio
		  devices, so if this is not what we should do, I'll gladly
		      accept modifications. */
	ctl->cmsg(CMSG_WARNING, VERB_NORMAL, "Cannot inquire %s", dpm.name);
	include_enc = PE_ULAW|PE_ALAW|PE_MONO;
	exclude_enc = PE_SIGNED|PE_16BIT|PE_BYTESWAP;
	dpm.encoding = validate_encoding(dpm.encoding,
					 include_enc, exclude_enc);
	if(dpm.rate != 8000)
	    ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,
		      "Sample rate is changed %d to 8000",
		      dpm.rate);
	dpm.rate = 8000;
	return 1;
    }

    if(!(dpm.encoding & PE_16BIT))
	exclude_enc |= PE_SIGNED; /* Always unsigned */
    dpm.encoding = validate_encoding(dpm.encoding, include_enc, exclude_enc);

    AUDIO_INITINFO(&auinfo);
    auinfo.play.sample_rate = dpm.rate;
    auinfo.play.channels = (dpm.encoding & PE_MONO) ? 1 : 2;
    auinfo.play.encoding = sun_audio_encoding(dpm.encoding);
    auinfo.play.precision = (dpm.encoding & PE_16BIT) ? 16 : 8;

    if(sun_audio_setinfo(&auinfo) == -1)
    {
	ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
		  "rate=%d, channels=%d, precision=%d, encoding=%s",
		  auinfo.play.sample_rate, auinfo.play.channels,
		  auinfo.play.precision, output_encoding_string(dpm.encoding));
	close_output();
	return -1;
    }

    return 0;
}
Example #9
0
static int open_output(void)
{
    int i, include_enc, exclude_enc;
    int sample_width, channels;

    include_enc = 0;
    exclude_enc = PE_ULAW|PE_ALAW|PE_BYTESWAP; /* They can't mean these */
    if(dpm.encoding & PE_16BIT)
	include_enc |= PE_SIGNED;
    else
	exclude_enc |= PE_SIGNED;
    dpm.encoding = validate_encoding(dpm.encoding, include_enc, exclude_enc);
    sample_width = (dpm.encoding & PE_16BIT) ? 16 : 8;
    channels = (dpm.encoding & PE_MONO) ? 1 : 2;

    /* Open the audio device */
    switch (arts_init_state) {
    case 0:
	if((i = arts_init()) != 0)
	{
	    ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s",
		      dpm.name, arts_error_text(i));
	    return -1;
	}
	arts_init_state = 1;
	break;
    case 2:
	ctl->cmsg(CMSG_ERROR, VERB_NORMAL, 
	    "TiMidity aRts bug: open_output() after close_output() not supported");
	return -1;
    }
    stream = arts_play_stream(dpm.rate,
			      LE_LONG(sample_width),
			      channels,
			      "timidity");
    if(stream == NULL)
    {
	ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s",
		  dpm.name, strerror(errno));
	return -1;
    }
    arts_stream_set(stream, ARTS_P_BLOCKING, 1);

    server_buffer = arts_stream_get(stream, ARTS_P_SERVER_LATENCY) * dpm.rate * (sample_width/8) * channels / 1000;
    output_count = 0;
    return 0;
    /* "this aRts function isnot yet implemented"
     *
    if (dpm.extra_param[0]) {
        i = arts_stream_set(stream,
            ARTS_P_PACKET_COUNT,
            dpm.extra_param[0]);
	if (i < 0) {
            ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s",
              dpm.name, arts_error_text(i));
	    return 1;
        }
    }
    return 0;
     *
     */
}
Example #10
0
static int open_output(void)
{
    int fd, tmp, i, warnings = 0;
    int include_enc, exclude_enc;
#ifdef SNDCTL_DSP_GETOSPACE
    audio_buf_info info;
#endif /* SNDCTL_DSP_GETOSPACE */

    /* Open the audio device */
    fd = open(dpm.name, O_WRONLY);
    if(fd < 0)
    {
	ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s",
		  dpm.name, strerror(errno));
	return -1;
    }

    /*
     * Modified: Fri Nov 20 1998
     *
     * Reported from http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html
     *   by Thomas Sailer <*****@*****.**>
     * OSS/Free sets nonblocking mode with an ioctl, unlike the rest of the
     * kernel, which uses the O_NONBLOCK flag. I want to regularize that API,
     * and this trips on Timidity.
     */
    fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NDELAY);

    include_enc = 0;
    exclude_enc = PE_ULAW|PE_ALAW|PE_BYTESWAP; /* They can't mean these */
    if(dpm.encoding & PE_16BIT)
	include_enc |= PE_SIGNED;
    else
	exclude_enc |= PE_SIGNED;
    dpm.encoding = validate_encoding(dpm.encoding, include_enc, exclude_enc);

    /* Set sample width to whichever the user wants. If it fails, try
       the other one. */

    i = tmp = (dpm.encoding & PE_16BIT) ? AFMT_S16_NE : AFMT_U8;
    if(ioctl(fd, SNDCTL_DSP_SETFMT, &tmp) < 0 || tmp != i)
    {
	/* Try the other one */
	i = tmp = (dpm.encoding & PE_16BIT) ? AFMT_U8 : AFMT_S16_NE;
	if(ioctl(fd, SNDCTL_DSP_SETFMT, &tmp) < 0 || tmp != i)
	{
	    ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
		      "%s doesn't support 16- or 8-bit sample width",
		      dpm.name);
	    close(fd);
	    return -1;
	}
	ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,
		  "Sample width adjusted to %d bits", tmp);
	dpm.encoding ^= PE_16BIT;
	warnings = 1;
    }

    /* Try stereo or mono, whichever the user wants. If it fails, try
       the other. */

    i = tmp = (dpm.encoding & PE_MONO) ? 1 : 2;
    if((ioctl(fd, SNDCTL_DSP_CHANNELS, &tmp) < 0) || tmp != i)
    {
	i = tmp = (dpm.encoding & PE_MONO) ? 2 : 1;

	if((ioctl(fd, SNDCTL_DSP_CHANNELS, &tmp) < 0) || tmp != i)
	{
	    ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
		      "%s doesn't support mono or stereo samples",
		      dpm.name);
	    close(fd);
	    return -1;
	}
	if(tmp == 1) dpm.encoding |= PE_MONO;
	else dpm.encoding &= ~PE_MONO;
	ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, "Sound adjusted to %sphonic",
		  (tmp==1) ? "mono" : "stereo");
	warnings = 1;
    }


    /* Set the sample rate */

    tmp = dpm.rate;
    if(ioctl(fd, SNDCTL_DSP_SPEED, &tmp) < 0)
    {
	ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
		  "%s doesn't support a %d Hz sample rate",
		  dpm.name, dpm.rate);
	close(fd);
	return -1;
    }
    if(tmp != dpm.rate)
    {
	ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,
		  "Output rate adjusted to %d Hz (requested %d Hz)",
		  tmp, dpm.rate);
	dpm.rate = tmp;
	warnings = 1;
    }

    /* Older VoxWare drivers don't have buffer fragment capabilities */
#ifdef SNDCTL_DSP_SETFRAGMENT
    /* Set buffer fragments (in extra_param[0]) */

    tmp = audio_buffer_bits;
    if(!(dpm.encoding & PE_MONO)) tmp++;
    if(dpm.encoding & PE_16BIT) tmp++;
    i = tmp;
    tmp |= (dpm.extra_param[0] << 16);
    if(ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &tmp) < 0)
    {
	ctl->cmsg(CMSG_WARNING, VERB_NORMAL,
		  "%s doesn't support %d-byte buffer fragments (%d)",
		  dpm.name, 1<<i, i);
	/* It should still work in some fashion. We should use a
	   secondary buffer anyway -- 64k isn't enough. */
	warnings = 1;
    }
#else
    if(dpm.extra_param[0])
    {
	ctl->cmsg(CMSG_WARNING, VERB_NORMAL,
		  "%s doesn't support buffer fragments", dpm.name);
	warnings = 1;
    }
#endif

#ifdef SNDCTL_DSP_GETOSPACE
    if(ioctl(fd, SNDCTL_DSP_GETOSPACE, &info) != -1) {
	total_bytes = info.fragstotal * info.fragsize;
	ctl->cmsg(CMSG_INFO, VERB_NOISY, "Audio device buffer: %d x %d bytes",
		  info.fragstotal, info.fragsize);
    }
    else
#endif /* SNDCTL_DSP_GETOSPACE */
	total_bytes = -1; /* Unknown */

    dpm.fd = fd;
    output_counter = 0;

    return warnings;
}