void 
sgi_audio_loopback(audio_desc_t ad, int gain)
{
        long pvbuf[4];
        int  pvcnt;

        UNUSED(ad); assert(audio_fd > 0);

        pvcnt = 2;
        pvbuf[0] = AL_MONITOR_CTL;
        pvbuf[1] = AL_MONITOR_OFF;

        if (gain) {
                pvcnt = 6;
                pvbuf[1] = AL_MONITOR_ON;
                pvbuf[2] = AL_LEFT_MONITOR_ATTEN;
                pvbuf[3] = 255 - RAT_TO_SGI_DEVICE(gain);
                pvbuf[4] = AL_RIGHT_MONITOR_ATTEN;
                pvbuf[5] = pvbuf[3];
        }
        
        if (ALsetparams(AL_DEFAULT_DEVICE, pvbuf, pvcnt) != 0) {
                debug_msg("loopback failed\n");
        }
}
Beispiel #2
0
static int
open_audio_port (AudioContext return_ac, AudioContext desc)
{
  ALconfig config = ALnewconfig();
  long params[2];

  adjust_audio_volume (& desc->device);
  return_ac->ac_left_speaker_gain = desc->ac_left_speaker_gain;
  return_ac->ac_right_speaker_gain = desc->ac_right_speaker_gain;
  params[0] = AL_OUTPUT_RATE;
  params[1] = desc->ac_output_rate;
  ALsetparams (desc->ac_device, params, 2);
  return_ac->ac_output_rate = desc->ac_output_rate;
  if (set_channels (config, desc->ac_nchan)==-1)
    return -1;
  return_ac->ac_nchan = desc->ac_nchan;
  if (set_output_format (config, desc->ac_format)==-1)
    return -1;
  return_ac->ac_format = desc->ac_format;
  ALsetqueuesize (config, (long) CHUNKSIZE);
  return_ac->ac_port = ALopenport("XEmacs audio output", "w", config);
  ALfreeconfig (config);
  if (return_ac->ac_port==0)
    {
      report_file_error ("Opening audio output port", Qnil);
      return -1;
    }
  return 0;
}
Beispiel #3
0
int sound_init()
{
  long pvbuf[2];
  pvbuf[0] = AL_OUTPUT_COUNT;
  pvbuf[2] = AL_MONITOR_CTL;
  if (ALgetparams(AL_DEFAULT_DEVICE, pvbuf, 4) < 0) 
  {    
    fprintf(stderr,"sound driver : No audio hardware\n");
    return 0;
  }
  pvbuf[0] = AL_OUTPUT_RATE;
  pvbuf[1] = 11025;
  if (ALsetparams(AL_DEFAULT_DEVICE,pvbuf,4) < 0)
  {    
    fprintf(stderr,"sound driver : Could not set sample rate\n");
    return 0;
  }

  ALseterrorhandler(0);
  audioconfig = ALnewconfig();
  if (!audioconfig)
  {
    fprintf(stderr,"failed to create audio config\n");
    return 0;
  }
  else if (ALsetchannels(audioconfig,AL_MONO))
  { fprintf(stderr,"sound driver : could not set audio channels\n");
    return 0;
  }
  else if (ALsetqueuesize(audioconfig,BUF_SIZE))
  { 
    fprintf(stderr,"sound driver : could not set audio que size\n");
    ALfreeconfig(audioconfig);
    return 0;
  } else if (ALsetwidth (audioconfig, AL_SAMPLE_8))
  {
    fprintf(stderr,"sound driver :could not set 8 bit samples\n");
    ALfreeconfig(audioconfig);
    return 0;
  }

  audioport=ALopenport("Abuse sound driver","w",audioconfig);
  if (!audioport)
  {
    fprintf(stderr,"sound driver : could not open audio port\n");
    ALfreeconfig(audioconfig);
    return 0;
  }

  int i=0,j;
  uchar *vd=volume_table;
  for (;i<32;i++) 
  {
    for (j=0;j<256;j++,vd++)
      *vd=(j-128)*i/31+128;
  }
  return 1;
}
Beispiel #4
0
static void adjust_audio_volume(AudioDevice device)
{
	long params[4];
	params[0] = AL_LEFT_SPEAKER_GAIN;
	params[1] = device->left_speaker_gain;
	params[2] = AL_RIGHT_SPEAKER_GAIN;
	params[3] = device->right_speaker_gain;
	ALsetparams(device->device, params, 4);
}
Beispiel #5
0
static Lisp_Object restore_audio_port(Lisp_Object closure)
{
	Lisp_Object *contents = XVECTOR_DATA(closure);
	saved_device_state[1] = XINT(contents[0]);
	saved_device_state[3] = XINT(contents[1]);
	saved_device_state[5] = XINT(contents[2]);
	ALsetparams(AL_DEFAULT_DEVICE, saved_device_state, 6);
	return Qnil;
}
Beispiel #6
0
/*
 * Set the volume level.
 */
static void sfxSetGain(float l, float r) {
	long pvbuf[4];

	pvbuf[0] = AL_LEFT_SPEAKER_GAIN;
	pvbuf[1] = l * currLeftGain;
	pvbuf[2] = AL_RIGHT_SPEAKER_GAIN;
	pvbuf[3] = r * currRightGain;

	ALsetparams(AL_DEFAULT_DEVICE, pvbuf, 4L);
}
Beispiel #7
0
int esd_audio_write(void *buffer, int buf_size)
{
	ALsetparams(AL_DEFAULT_DEVICE, rate_params, 2);
    if (ALwritesamps(outaudioport, buffer, buf_size / 2) == 0) {
	ALsetfillpoint(outaudioport, ESD_BUF_SIZE);
	return buf_size;
    }
    else
	return 0;    
}
Beispiel #8
0
int esd_audio_read(void *buffer, int buf_size)
{
	ALsetparams(AL_DEFAULT_DEVICE, (rate_params + 2), 2);
    if (ALreadsamps(inaudioport, buffer, buf_size / 2) == 0) {
	ALsetfillpoint(inaudioport, ESD_BUF_SIZE);
	return buf_size;
    }
    else
	return 0;
}
Beispiel #9
0
static Bool audriv_al_set_rate(ALport port, unsigned long rate)
{
    long pv[2];

    pv[0] = (port == out ? AL_OUTPUT_RATE : AL_INPUT_RATE);
    pv[1] = rate;
    if(ALsetparams(AL_DEFAULT_DEVICE, pv, 2) < 0)
	return False;
    return True;
}
Beispiel #10
0
void
sgi_audio_set_igain(audio_desc_t ad, int gain)
{
	long	cmd[4];

        UNUSED(ad); assert(audio_fd > 0);

	cmd[0] = AL_LEFT_INPUT_ATTEN;
	cmd[1] = 255 - RAT_TO_SGI_DEVICE(gain);
	cmd[2] = AL_RIGHT_INPUT_ATTEN;
	cmd[3] = cmd[1];
	ALsetparams(AL_DEFAULT_DEVICE, cmd, 4L);
}
Beispiel #11
0
void
sgi_audio_set_ogain(audio_desc_t ad, int vol)
{
	long	cmd[4];

        UNUSED(ad); assert(audio_fd > 0);

	cmd[0] = AL_LEFT_SPEAKER_GAIN;
	cmd[1] = RAT_TO_SGI_DEVICE(vol);
	cmd[2] = AL_RIGHT_SPEAKER_GAIN;
	cmd[3] = cmd[1];
	ALsetparams(AL_DEFAULT_DEVICE, cmd, 4L);
}
Beispiel #12
0
/*
 * Reset the audio hardware to where we found it when we started.
 */
static void sfxResetAudioHw(void) {
	long pvbuf[6];

	pvbuf[0] = AL_LEFT_SPEAKER_GAIN;
	pvbuf[1] = origLeftGain;
	pvbuf[2] = AL_RIGHT_SPEAKER_GAIN;
	pvbuf[3] = origRightGain;
	pvbuf[4] = AL_OUTPUT_RATE;
	pvbuf[5] = origOutputRate;

	ALsetparams(AL_DEFAULT_DEVICE, pvbuf, 6L);
	return;
}
Beispiel #13
0
void
sgi_audio_iport_set(audio_desc_t ad, audio_port_t port)
{
	long pvbuf[2];

        UNUSED(ad); assert(audio_fd > 0);

        switch(port) {
        case SGI_IPORT_LINE_IN: 
                pvbuf[0] = AL_INPUT_SOURCE;
                pvbuf[1] = AL_INPUT_LINE;
                ALsetparams(AL_DEFAULT_DEVICE, pvbuf, 2);
                break;
        case SGI_IPORT_MICROPHONE: 
        default:
                pvbuf[0] = AL_INPUT_SOURCE;
                pvbuf[1] = AL_INPUT_MIC;
                ALsetparams(AL_DEFAULT_DEVICE, pvbuf, 2);
                break;
	case SGI_IPORT_APANEL:
		break;
        }
        iport = port;
}
Beispiel #14
0
static int sgi_init(const char *param, int *speed, int *fragsize, int *fragnr, int *channels)
{
    long chpars[] = { AL_OUTPUT_RATE, 0 };
    int st;

    /* No stereo capability. */
    *channels = 1;

    ALseterrorhandler(sgi_errorhandler);
    chpars[1] = *speed;
    st = ALsetparams(AL_DEFAULT_DEVICE, chpars, 2);
    if (st < 0) {
        return 1;
    }
    st = ALgetparams(AL_DEFAULT_DEVICE, chpars, 2);
    if (st < 0) {
        return 1;
    }
    *speed = chpars[1];

    sgi_audioconfig = ALnewconfig();
    if (!sgi_audioconfig) {
        return 1;
    }
    st = ALsetchannels(sgi_audioconfig, AL_MONO);
    if (st < 0) {
        goto fail;
    }
    st = ALsetwidth(sgi_audioconfig, AL_SAMPLE_16);
    if (st < 0) {
        goto fail;
    }
    st = ALsetqueuesize(sgi_audioconfig, *fragsize * *fragnr);
    if (st < 0) {
        goto fail;
    }
    sgi_audioport = ALopenport("outport", "w", sgi_audioconfig);
    if (!sgi_audioport) {
        goto fail;
    }
    return 0;
fail:
    ALfreeconfig(sgi_audioconfig);
    sgi_audioconfig = NULL;
    return 1;
}
Beispiel #15
0
FileDescriptor InitAudio(ALport *alpp) {
	/* initialize audio driver 
 	   for 16-bit 44100kHz monophonic sample source to DACs */
	ALconfig alc; 
 	alc = ALnewconfig();
	ALsetwidth (alc, AL_SAMPLE_16);
	ALsetqueuesize (alc, OUTPUTQUEUESIZE);
	ALsetchannels(alc, (long)1);
	*alpp = ALopenport("obuf", "w", alc);
	{
         	long pvbuf[2];
		long pvlen=2;
  	 	 
		pvbuf[0] = AL_OUTPUT_RATE;
		pvbuf[1] = AL_RATE_44100; 
		ALsetparams(AL_DEFAULT_DEVICE, pvbuf, pvlen);
		the_sample_rate = 44100.0f;
	}

	/* obtain a file descriptor associated with sound output port */
	return ALgetfd(*alpp);
}
Beispiel #16
0
int esd_audio_open()
{
    ALconfig audioconfig;
    audioconfig = ALnewconfig();
  
	rate_params[1] = esd_audio_rate;
	rate_params[3] = esd_audio_rate;

    if (!audioconfig) {
	printf( "Couldn't initialize new audio config\n" );
	esd_audio_fd = -1;
	return esd_audio_fd;
    } else {
	long pvbuf[] = { AL_OUTPUT_COUNT, 0, 
			 AL_MONITOR_CTL, 0, 
			 AL_OUTPUT_RATE, 0 };
    
	if (ALgetparams(AL_DEFAULT_DEVICE, pvbuf, 6) < 0)
	    if (oserror() == AL_BAD_DEVICE_ACCESS) {
		esd_audio_fd = -1;
		return esd_audio_fd;
	    }
    
	if (pvbuf[1] == 0 && pvbuf[3] == AL_MONITOR_OFF) {
	    ALsetparams(AL_DEFAULT_DEVICE, rate_params, 2);
	} else
	    if (pvbuf[5] != esd_audio_rate) {
		printf("audio device is already in use with wrong sample output rate\n");
		esd_audio_fd = -1;
		return esd_audio_fd;
	
	    }
    
	/* ALsetsampfmt(audioconfig, AL_SAMPFMT_TWOSCOMP); this is the default */
	/* ALsetwidth(audioconfig, AL_SAMPLE_16); this is the default */
    
	if ( (esd_audio_format & ESD_MASK_CHAN) == ESD_MONO)
	    ALsetchannels(audioconfig, AL_MONO);
	/* else ALsetchannels(audioconfig, AL_STEREO); this is the default */

	ALsetqueuesize(audioconfig, ESD_BUF_SIZE * 2);
    
	outaudioport = ALopenport("esd", "w", audioconfig);
	if (outaudioport == (ALport) 0) {
	    switch (oserror()) {
	    case AL_BAD_NO_PORTS:
		printf( "system is out of ports\n");
		esd_audio_fd = -1;
		return esd_audio_fd;
		break;
	
	    case AL_BAD_DEVICE_ACCESS:
		printf("couldn't access audio device\n");
		esd_audio_fd = -1;
		return esd_audio_fd;
		break;
	
	    case AL_BAD_OUT_OF_MEM:
		printf("out of memory\n");
		esd_audio_fd = -1;
		return esd_audio_fd;
		break;
	    }
	    /* don't know how we got here, but it must be bad */
	    esd_audio_fd = -1;
	    return esd_audio_fd;
	}
	ALsetfillpoint(outaudioport, ESD_BUF_SIZE);

	esd_audio_fd = ALgetfd(outaudioport);

	/*
	 * If we are recording, open a second port to read from
	 * and return that fd instead
	 */
	if ( (esd_audio_format & ESD_MASK_FUNC) == ESD_RECORD ) {
	    inaudioport = ALopenport("esd", "r", audioconfig);
	    if (inaudioport == (ALport) 0) {
		switch (oserror()) {
		case AL_BAD_NO_PORTS:
		    printf( "system is out of ports\n");
		    esd_audio_fd = -1;
		    return esd_audio_fd;
		    break;
	
		case AL_BAD_DEVICE_ACCESS:
		    printf("couldn't access audio device\n");
		    esd_audio_fd = -1;
		    return esd_audio_fd;
		    break;
	
		case AL_BAD_OUT_OF_MEM:
		    printf("out of memory\n");
		    esd_audio_fd = -1;
		    return esd_audio_fd;
		    break;
		default:
		    printf( "Unknown error opening port\n" );
		}
				/* don't know how we got here, but it must be bad */
		esd_audio_fd = -1;
		return esd_audio_fd;
	    }
	    ALsetfillpoint(inaudioport, ESD_BUF_SIZE);
	    ALsetparams(AL_DEFAULT_DEVICE, (rate_params + 2), 2);

	    esd_audio_fd = ALgetfd(inaudioport);
	}

    }
    return esd_audio_fd;
}
Beispiel #17
0
int
sgi_audio_open(audio_desc_t ad, audio_format* ifmt, audio_format *ofmt)
{
	ALconfig	c;
	long		cmd[8];

        if (audio_fd != -1) {
                sgi_audio_close(ad);
        }

        if (ifmt->encoding != DEV_S16) return FALSE;

	if ((c = ALnewconfig()) == NULL) {
		fprintf(stderr, "ALnewconfig error\n");
		exit(1);
	}

        switch(ifmt->channels) {
        case 1:
                ALsetchannels(c, AL_MONO); break;
        case 2:
                ALsetchannels(c, AL_STEREO); break;
        default:
                sgi_audio_close(ad);
        }

	ALsetwidth(c, AL_SAMPLE_16);
	ALsetqueuesize(c, QSIZE);
	ALsetsampfmt(c, AL_SAMPFMT_TWOSCOMP);

	if ((wp = ALopenport("RAT write", "w", c)) == NULL) {
		fprintf(stderr, "ALopenport (write) error\n");
                sgi_audio_close(ad);
                return FALSE;
        }

	if ((rp = ALopenport("RAT read", "r", c)) == NULL) {
		fprintf(stderr, "ALopenport (read) error\n");
                sgi_audio_close(ad);
                return FALSE;
        }

	cmd[0] = AL_OUTPUT_RATE;
	cmd[1] = ofmt->sample_rate;
	cmd[2] = AL_INPUT_RATE;
	cmd[3] = ifmt->sample_rate;
	cmd[4] = AL_MONITOR_CTL;
	cmd[5] = AL_MONITOR_OFF;
	/*cmd[6] = AL_INPUT_SOURCE;*/
	/*cmd[7] = AL_INPUT_MIC;*/

	if (ALsetparams(AL_DEFAULT_DEVICE, cmd, 6L/*was 8L*/) == -1) {
		fprintf(stderr, "audio_open/ALsetparams error\n");
                sgi_audio_close(ad);
        }

	/* Get the file descriptor to use in select */
	audio_fd = ALgetfd(rp);

	if (ALsetfillpoint(rp, ifmt->bytes_per_block) < 0) {
                debug_msg("ALsetfillpoint failed (%d samples)\n", ifmt->bytes_per_block);
        }
        bytes_per_block = ifmt->bytes_per_block;
        
	/* We probably should free the config here... */
        
	return TRUE;
}
Beispiel #18
0
/*
 * Sound handler.
 */
static void sfxSoundHandler(void *arg) {
	ALport *ap = (ALport *)arg;
	Sample samp[MAX_AUDIO_PORTS];

	int idx, nap;
	int treated;
	int nSounds = 1;
	int nextPort = 0;
	long maxSampsPerPass;
	long sampCount;
	long pvbuf[2];
	struct _sfx ss;
	struct pollfd pf;

	prctl(PR_TERMCHILD, 0);

	(void) signal(SIGHUP, sfxDieGracefully);

	maxSampsPerPass = 1600;

	for (idx=0; idx < nAudioPorts; idx++) {
		samp[idx].id = -1;
		samp[idx].sample = NULL;
		samp[idx].sampsToPlay = 0;
		samp[idx].repeat = 0;
	}

	/*
	 * Set sample rate for output device.
	 */
	pvbuf[0] = AL_OUTPUT_RATE;
	pvbuf[1] = AL_RATE_16000;

	(void) ALsetparams(AL_DEFAULT_DEVICE, pvbuf, 2L);

	/*
	 * Prepare to read from pipe.
	 */
	pf.fd = spigot[0];
	pf.events = POLLIN | POLLRDNORM | POLLRDBAND;

#define EVER ;;
	for (EVER) {
		if (nSounds == 0 || (idx=poll(&pf, 1, 0)) > 0) {
			(void) read(spigot[0], &ss, sizeof(ss));
			treated = 0;
			if (ss.loop == 1 && ss.repeat == 0) {
				treated = 1;
				for (idx=0; idx < nAudioPorts; idx++) {
					if (samp[idx].id == ss.id) {
						samp[idx].id = -1;
						samp[idx].repeat = 0;
						samp[idx].sampsToPlay = 0;
						samp[idx].sample = NULL;
					}
				}
			} else if (ss.loop == 1 && ss.count > 1) {
				for (idx=0; idx < nAudioPorts; idx++) {
					if (samp[idx].id == ss.id) {
						treated = 1;
						samp[idx].repeat = ss.repeat;
						samp[idx].sampsToPlay = (long)ss.soundSize[ss.pitch];
						samp[idx].sampsPlayed = 0;
						samp[idx].sample = ss.soundData[ss.pitch];
					}
				}
			}
			if (!treated) {
				for (idx=0; idx < nAudioPorts; idx++) {
					nextPort = (nextPort+1) % nAudioPorts;
					if (samp[nextPort].repeat == 0)
						break;
				}
				samp[nextPort].sample = ss.soundData[ss.pitch];
				samp[nextPort].sampsToPlay = (long)ss.soundSize[ss.pitch];
				samp[nextPort].sampsPlayed = 0;
				samp[nextPort].repeat = ss.repeat;
				samp[nextPort].id = ss.id;
			}
		} else if (idx < 0)
			(void) fprintf(stderr, "panic: input poll failed: %s\n", strerror(errno));

		nSounds = 0;
		nap = 0;

		for (idx=0; idx < nAudioPorts; idx++) {
			if (samp[idx].sampsToPlay > 0) {
				nSounds++;
				if (ALgetfilled(ap[idx]) > 4000) {
					nap++;
					continue;
				}
			}
			if (samp[idx].sampsToPlay >= maxSampsPerPass) {
				(void) ALwritesamps(ap[idx],
						    samp[idx].sample + samp[idx].sampsPlayed, maxSampsPerPass);
				samp[idx].sampsPlayed += maxSampsPerPass;
				samp[idx].sampsToPlay -= maxSampsPerPass;

			} else if (samp[idx].sampsToPlay > 0) {
				if ((samp[idx].sampsToPlay%2) == 1) {
					samp[idx].sampsToPlay -= 1;
					samp[idx].sampsPlayed += 1;
				}
				if (samp[idx].sampsToPlay > 0)
				    (void) ALwritesamps(ap[idx],
							samp[idx].sample+samp[idx].sampsPlayed, samp[idx].sampsToPlay);

				if (samp[idx].repeat) {
					sampCount = maxSampsPerPass - samp[idx].sampsToPlay;
					samp[idx].sampsToPlay += samp[idx].sampsPlayed - sampCount;
					samp[idx].sampsPlayed = sampCount;
					(void) ALwritesamps(ap[idx], samp[idx].sample, sampCount);
				} else
					samp[idx].sampsToPlay = 0;
			}
		}
		if (nap == nSounds)
			sginap(1);
	}
	return;
}
Beispiel #19
0
static BOOL SGI_Init(void)
{
	long chpars[] = { AL_OUTPUT_RATE, AL_RATE_22050 };

	switch(md_mixfreq) {
		case 8000:
			chpars[1] = AL_RATE_8000;
			break;
		case 11025:
			chpars[1] = AL_RATE_11025;
			break;
		case 16000:
			chpars[1] = AL_RATE_16000;
			break;
		case 22050:
			chpars[1] = AL_RATE_22050;
			break;
		case 32000:
			chpars[1] = AL_RATE_32000;
			break;
		case 44100:
			chpars[1] = AL_RATE_44100;
			break;
		case 48000:
			chpars[1] = AL_RATE_48000;
			break;
		default:
			_mm_errno=MMERR_SGI_SPEED;
			return 1;
	}
	ALseterrorhandler(0);
	ALsetparams(AL_DEFAULT_DEVICE, chpars, 2);

	if (!(sgi_config=ALnewconfig())) {
		_mm_errno=MMERR_OPENING_AUDIO;
		return 1;
	}
	
	if (md_mode&DMODE_16BITS) {
		if (ALsetwidth(sgi_config,AL_SAMPLE_16)<0) {
			_mm_errno=MMERR_SGI_16BIT;
			return 1;
		}
		sample_factor = 1;
	} else {
		if (ALsetwidth(sgi_config,AL_SAMPLE_8)<0) {
			_mm_errno=MMERR_SGI_8BIT;
			return 1;
		}
		sample_factor = 0;
	}

	if (md_mode&DMODE_STEREO) {
		if (ALsetchannels(sgi_config,AL_STEREO)<0) {
			_mm_errno=MMERR_SGI_STEREO;
			return 1;
		}
	} else {
		if (ALsetchannels(sgi_config,AL_MONO)<0) {
			_mm_errno=MMERR_SGI_MONO;
			return 1;
		}
	}

	if ((getenv("MM_SGI_FRAGSIZE"))&&(sgi_fragsize!=DEFAULT_SGI_FRAGSIZE))
		sgi_fragsize=atol(getenv("MM_SGI_FRAGSIZE"));
	if (!sgi_fragsize) sgi_fragsize=DEFAULT_SGI_FRAGSIZE;
	if ((getenv("MM_SGI_BUFSIZE"))&&(sgi_bufsize!=DEFAULT_SGI_BUFSIZE))
		sgi_bufsize=atol(getenv("MM_SGI_BUFSIZE"));
	if (!sgi_bufsize) sgi_fragsize=DEFAULT_SGI_BUFSIZE;

	ALsetqueuesize(sgi_config, sgi_bufsize);
	if (!(sgi_port=ALopenport("libmikmod","w",sgi_config))) {
		_mm_errno=MMERR_OPENING_AUDIO;
		return 1;
	}

	if(!(audiobuffer=(SBYTE*)_mm_malloc(sgi_fragsize))) return 1;
	
	return VC_Init();
}
Beispiel #20
0
static int AL_OpenAudio(_THIS, SDL_AudioSpec * spec)
{
	Uint16 test_format = SDL_FirstAudioFormat(spec->format);
	long width = 0;
	long fmt = 0;
	int valid = 0;

#ifdef OLD_IRIX_AUDIO
	{
		long audio_param[2];
		audio_param[0] = AL_OUTPUT_RATE;
		audio_param[1] = spec->freq;
		valid = (ALsetparams(AL_DEFAULT_DEVICE, audio_param, 2) < 0);
	}
#else
	{
		ALpv audio_param;
		audio_param.param = AL_RATE;
		audio_param.value.i = spec->freq;
		valid = (alSetParams(AL_DEFAULT_OUTPUT, &audio_param, 1) < 0);
	}
#endif

	while ((!valid) && (test_format)) {
		valid = 1;
		spec->format = test_format;

		switch (test_format) {
			case AUDIO_S8:
				width = AL_SAMPLE_8;
				fmt = AL_SAMPFMT_TWOSCOMP;
				break;

			case AUDIO_S16SYS:
				width = AL_SAMPLE_16;
				fmt = AL_SAMPFMT_TWOSCOMP;
				break;

			default:
				valid = 0;
				test_format = SDL_NextAudioFormat();
				break;
		}

		if (valid) {
			ALconfig audio_config = alNewConfig();
			valid = 0;
			if (audio_config) {
				if (alSetChannels(audio_config, spec->channels) < 0) {
					if (spec->channels > 2) {  /* can't handle > stereo? */
						spec->channels = 2;  /* try again below. */
					}
				}

				if ((alSetSampFmt(audio_config, fmt) >= 0) &&
				    ((!width) || (alSetWidth(audio_config, width) >= 0)) &&
				    (alSetQueueSize(audio_config, spec->samples * 2) >= 0) &&
				    (alSetChannels(audio_config, spec->channels) >= 0)) {

					audio_port = alOpenPort("SDL audio", "w", audio_config);
					if (audio_port == NULL) {
						/* docs say AL_BAD_CHANNELS happens here, too. */
						int err = oserror();
						if (err == AL_BAD_CHANNELS) {
							spec->channels = 2;
							alSetChannels(audio_config, spec->channels);
							audio_port = alOpenPort("SDL audio", "w",
							                        audio_config);
						}
					}

					if (audio_port != NULL) {
						valid = 1;
					}
				}

				alFreeConfig(audio_config);
			}
		}
	}

	if (!valid) {
		SDL_SetError("Unsupported audio format");
		return (-1);
	}

	/* Update the fragment size as size in bytes */
	SDL_CalculateAudioSpec(spec);

	/* Allocate mixing buffer */
	mixbuf = (Uint8 *) SDL_AllocAudioMem(spec->size);
	if (mixbuf == NULL) {
		SDL_OutOfMemory();
		return (-1);
	}
	SDL_memset(mixbuf, spec->silence, spec->size);

	/* We're ready to rock and roll. :-) */
	return (0);
}
Beispiel #21
0
/*--------------------------------------------------------------------------------------*/
PaError PaHost_OpenStream(internalPortAudioStream *past)
{
	PaError                 result = paNoError;
	PaHostSoundControl      *pahsc;
	unsigned int            minNumBuffers;
	internalPortAudioDevice *padIN, *padOUT;        /* For looking up native AL-numbers. */
    ALconfig                sgiALconfig = NULL;     /* IRIX-datatype.   */
    long                    pvbuf[8];               /* To get/set hardware configs.      */
    long                    sr, ALqsize;
    DBUG(("PaHost_OpenStream() called.\n"));        /* Alloc FASTMEM and init host data. */
    if (!past)
        {
        ERR_RPT(("Streampointer NULL!\n"));
        result = paBadStreamPtr;        goto done;
        }
	pahsc = (PaHostSoundControl*)PaHost_AllocateFastMemory(sizeof(PaHostSoundControl));
	if (pahsc == NULL)
	    {
        ERR_RPT(("FAST Memory allocation failed.\n"));  /* Pass trough some ERR_RPT-exit-  */
        result = paInsufficientMemory;  goto done;      /* code (nothing will be freed).   */
	    }
	memset(pahsc, 0, sizeof(PaHostSoundControl));
/*  pahsc->pahsc_threadPID = -1;                       Should pahsc_threadPID be inited to */
	past->past_DeviceData = (void*)pahsc;           /* -1 instead of 0 ??                  */
    /*--------------------------------------------------- Allocate native buffers: --------*/
    pahsc->pahsc_SamplesPerInputBuffer = past->past_FramesPerUserBuffer * /* Needed by the */
                                         past->past_NumInputChannels;     /* audio-thread. */
	pahsc->pahsc_BytesPerInputBuffer   = pahsc->pahsc_SamplesPerInputBuffer * sizeof(short);
	if (past->past_NumInputChannels > 0)                       /* Assumes short = 16 bits! */
	    {
		pahsc->pahsc_NativeInputBuffer = (short*)PaHost_AllocateFastMemory(pahsc->pahsc_BytesPerInputBuffer);        
		if( pahsc->pahsc_NativeInputBuffer == NULL )
		    {
            ERR_RPT(("Fast memory allocation for input-buffer failed.\n"));
			result = paInsufficientMemory;  goto done;
		    }
	    }
    pahsc->pahsc_SamplesPerOutputBuffer = past->past_FramesPerUserBuffer * /* Needed by the */
                                          past->past_NumOutputChannels;    /* audio-thread. */
	pahsc->pahsc_BytesPerOutputBuffer   = pahsc->pahsc_SamplesPerOutputBuffer * sizeof(short);
	if (past->past_NumOutputChannels > 0)                       /* Assumes short = 16 bits! */
	    {
		pahsc->pahsc_NativeOutputBuffer = (short*)PaHost_AllocateFastMemory(pahsc->pahsc_BytesPerOutputBuffer);
		if (pahsc->pahsc_NativeOutputBuffer == NULL)
		    {
            ERR_RPT(("Fast memory allocation for output-buffer failed.\n"));
			result = paInsufficientMemory;  goto done;
		    }
	    }
    /*------------------------------------------ Manipulate hardware if necessary and allowed: --*/
    ALseterrorhandler(0);                           /* 0 = turn off the default error handler.   */
    pvbuf[0] = AL_INPUT_RATE;
    pvbuf[2] = AL_INPUT_COUNT;
    pvbuf[4] = AL_OUTPUT_RATE;              /* TO FIX: rates may be logically, not always in Hz! */
    pvbuf[6] = AL_OUTPUT_COUNT;
    sr = (long)(past->past_SampleRate + 0.5);   /* Common for input and output :-)               */
    if (past->past_NumInputChannels > 0)                        /* We need to lookup the corre-  */
        {                                                       /* sponding native AL-number(s). */
        padIN = Pa_GetInternalDevice(past->past_InputDeviceID);
        if (!padIN)
            {
            ERR_RPT(("Pa_GetInternalDevice() for input failed.\n"));
	        result = paHostError;  goto done;
            }
        if (ALgetparams(padIN->pad_ALdevice, &pvbuf[0], 4)) /* Although input and output will both be on */
            goto sgiError;                                  /* the same AL-device, the AL-library might  */
        if (pvbuf[1] != sr)                                 /* contain more than AL_DEFAULT_DEVICE in    */
            {  /* Rate different from current harware-rate?    the future. Therefore 2 seperate queries. */
            if (pvbuf[3] > 0)     /* Means, there's other clients using AL-input-ports */
                {
                ERR_RPT(("Sorry, not allowed to switch input-hardware to %ld Hz because \
another process is currently using input at %ld kHz.\n", sr, pvbuf[1]));
                result = paHostError;   goto done;
                }
            pvbuf[1] = sr;                  /* Then set input-rate. */
            if (ALsetparams(padIN->pad_ALdevice, &pvbuf[0], 2))
                goto sgiError;      /* WHETHER THIS SAMPLERATE WAS REALLY PRESENT IN OUR ARRAY OF RATES, */
            }                       /* IS NOT CHECKED, AT LEAST NOT BY ME, WITHIN THIS FILE! Does PA do? */
Beispiel #22
0
static int
IRIXAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
{
    SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
    long width = 0;
    long fmt = 0;
    int valid = 0;

    /* !!! FIXME: Handle multiple devices and capture? */

    /* Initialize all variables that we clean on shutdown */
    this->hidden = (struct SDL_PrivateAudioData *)
        SDL_malloc((sizeof *this->hidden));
    if (this->hidden == NULL) {
        SDL_OutOfMemory();
        return 0;
    }
    SDL_memset(this->hidden, 0, (sizeof *this->hidden));

#ifdef OLD_IRIX_AUDIO
    {
        long audio_param[2];
        audio_param[0] = AL_OUTPUT_RATE;
        audio_param[1] = this->spec.freq;
        valid = (ALsetparams(AL_DEFAULT_DEVICE, audio_param, 2) < 0);
    }
#else
    {
        ALpv audio_param;
        audio_param.param = AL_RATE;
        audio_param.value.i = this->spec.freq;
        valid = (alSetParams(AL_DEFAULT_OUTPUT, &audio_param, 1) < 0);
    }
#endif

    while ((!valid) && (test_format)) {
        valid = 1;
        this->spec.format = test_format;

        switch (test_format) {
        case AUDIO_S8:
            width = AL_SAMPLE_8;
            fmt = AL_SAMPFMT_TWOSCOMP;
            break;

        case AUDIO_S16SYS:
            width = AL_SAMPLE_16;
            fmt = AL_SAMPFMT_TWOSCOMP;
            break;

        case AUDIO_F32SYS:
            width = 0;          /* not used here... */
            fmt = AL_SAMPFMT_FLOAT;
            break;

            /* Docs say there is int24, but not int32.... */

        default:
            valid = 0;
            test_format = SDL_NextAudioFormat();
            break;
        }

        if (valid) {
            ALconfig audio_config = alNewConfig();
            valid = 0;
            if (audio_config) {
                if (alSetChannels(audio_config, this->spec.channels) < 0) {
                    if (this->spec.channels > 2) {      /* can't handle > stereo? */
                        this->spec.channels = 2;        /* try again below. */
                    }
                }

                if ((alSetSampFmt(audio_config, fmt) >= 0) &&
                    ((!width) || (alSetWidth(audio_config, width) >= 0)) &&
                    (alSetQueueSize(audio_config, this->spec.samples * 2) >=
                     0)
                    && (alSetChannels(audio_config, this->spec.channels) >=
                        0)) {

                    this->hidden->audio_port = alOpenPort("SDL audio", "w",
                                                          audio_config);
                    if (this->hidden->audio_port == NULL) {
                        /* docs say AL_BAD_CHANNELS happens here, too. */
                        int err = oserror();
                        if (err == AL_BAD_CHANNELS) {
                            this->spec.channels = 2;
                            alSetChannels(audio_config, this->spec.channels);
                            this->hidden->audio_port =
                                alOpenPort("SDL audio", "w", audio_config);
                        }
                    }

                    if (this->hidden->audio_port != NULL) {
                        valid = 1;
                    }
                }

                alFreeConfig(audio_config);
            }
        }
    }

    if (!valid) {
        IRIXAUDIO_CloseDevice(this);
        SDL_SetError("Unsupported audio format");
        return 0;
    }

    /* Update the fragment size as size in bytes */
    SDL_CalculateAudioSpec(&this->spec);

    /* Allocate mixing buffer */
    this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->spec.size);
    if (this->hidden->mixbuf == NULL) {
        IRIXAUDIO_CloseDevice(this);
        SDL_OutOfMemory();
        return 0;
    }
    SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);

    /* We're ready to rock and roll. :-) */
    return 1;
}
Beispiel #23
0
Error SoundCardPMO::Init(OutputInfo * info)
{
   ALconfig config = ALnewconfig();
   long pvbuffer[2];

   m_properlyInitialized = false;

   if (!info)
   {
      info = myInfo;
   }
   else
   {
      m_iDataSize = info->max_buffer_size;
   }

   pvbuffer[0] = AL_OUTPUT_RATE;
   pvbuffer[1] = info->samples_per_second;

   if (ALsetparams(AL_DEFAULT_DEVICE, pvbuffer, 2) < 0)
   {
      ReportError("Cannot set the soundcard's sampling speed.");
      return (Error) pmoError_IOCTL_SNDCTL_DSP_SPEED;
   }

   int ret = -1;
   if (info->bits_per_sample > 8)
       ret = ALsetwidth(config, AL_SAMPLE_16);
   else
       ret = ALsetwidth(config, AL_SAMPLE_8);

   if (ret < 0)
   {
      ReportError("The soundcard does not support 16 bit sample size.");
      return (Error) pmoError_IOCTL_SNDCTL_DSP_SAMPLESIZE;
   }

   ret = -1;
   if (info->number_of_channels == 2)
       ret = ALsetchannels(config, AL_STEREO);
   else
       ret = ALsetchannels(config, AL_MONO);
   if (ret < 0)
   {
      ReportError("Cannot set the soundcard to stereo.");
      return (Error) pmoError_IOCTL_SNDCTL_DSP_STEREO;
   }

   ALsetqueuesize(config, m_iDataSize);

   outaudioport = ALopenport("freeamp", "w", config);

   if (outaudioport == (ALport)0)
   {
       ReportError("Couldn't open port.");
       return (Error) pmoError_IOCTL_SNDCTL_DSP_STEREO;
   }

   audio_fd = ALgetfd(outaudioport);

   channels = info->number_of_channels;

   // configure the device:
   int       play_precision = info->bits_per_sample;
   int       play_stereo = channels - 1;
   int       play_sample_rate = info->samples_per_second;

   memcpy(myInfo, info, sizeof(OutputInfo));
   m_properlyInitialized = true;

   // PORTING: The GETOSPACE ioctl determines how much space the kernel's
   // output buffer has. Your OS may not have this.

   m_iTotalFragments = 2048; /* arbitrary blah */
   m_iOutputBufferSize = play_precision * m_iTotalFragments;
   m_iBytesPerSample = info->number_of_channels * (info->bits_per_sample / 8);

   return kError_NoErr;
}
Beispiel #24
0
Bool audriv_set_play_volume(int volume)
/* 演奏音量を 0 〜 255 の範囲内で設定します.0 は無音,255 は最大音量.
 * 0 未満は 0,255 を超える値は 255 に等価.
 * 成功した場合は True を,失敗した場合は False を返します.
 */
{
#ifndef SGI_OLDAL
    double gain;
    ALfixed lrgain[2];
    ALpv pv;
    int resource;

    if(volume < 0)
	volume = 0;
    else if(volume > 255)
	volume = 255;

    if(volume == 0)
    {
	if(out_ginfo.specialVals & AL_NEG_INFINITY_BIT)
	    gain = alFixedToDouble(AL_NEG_INFINITY);
	else
	    gain = alFixedToDouble(out_ginfo.min.ll);
    }
    else if(volume == 255)
    {
	gain = alFixedToDouble(out_ginfo.max.ll);
    }
    else
    {
	double min, max;
	min = alFixedToDouble(out_ginfo.min.ll);
	max = alFixedToDouble(out_ginfo.max.ll);
	gain = min + (max - min) * (volume - 1) * (1.0/255);
	if(gain < min)
	    gain = min;
	else if(gain > max)
	    gain = max;
    }

    if(out == NULL)
	resource = AL_DEFAULT_OUTPUT;
    else
	resource = alGetResource(out);

    lrgain[0] = lrgain[1] = alDoubleToFixed(gain);
    pv.param = AL_GAIN;
    pv.value.ptr = lrgain;
    pv.sizeIn = 2;

    if(alSetParams(resource, &pv, 1) < 0)
    {
	audriv_err(ALERROR);
	return False;
    }
    return True;
#else
    long gain[4];

    if(volume < 0)
	volume = 0;
    else if(volume > 255)
	volume = 255;

    gain[0] = AL_LEFT_SPEAKER_GAIN;
    gain[1] = volume;
    gain[2] = AL_RIGHT_SPEAKER_GAIN;
    gain[3] = volume;
    if(ALsetparams(AL_DEFAULT_DEVICE, gain, 4) < 0)
    {
	audriv_err(ALERROR);
	return False;
    }
    return True;
#endif /* SGI_OLDAL */
}
Beispiel #25
0
void *Audio_Irix::open (AudioConfig& cfg, const char *)
{
    // Copy input parameters. May later be replaced with driver defaults.
    _settings = cfg;
    
    _config = ALnewconfig();

    // Set sample format
    ALsetsampfmt(_config, AL_SAMPFMT_TWOSCOMP);

    // stereo or mono mode
    _settings.channels = cfg.channels >= 2 ? 2 : 1;
    if (_settings.channels == 2)
        ALsetchannels(_config, AL_STEREO);
    else
        ALsetchannels(_config, AL_MONO);

    // 16 or 8 bit sample
    _settings.precision = cfg.precision >= 16 ? 16 : 8;
    if (_settings.precision == 16)
        ALsetwidth(_config, AL_SAMPLE_16);
    else
        ALsetwidth(_config, AL_SAMPLE_8);

    // Frequency
    long chpars[] = {AL_OUTPUT_RATE, 0};
    if (cfg.frequency > 48000)
        chpars[1] = AL_RATE_48000;
    else if (cfg.frequency > 44100)
        chpars[1] = AL_RATE_44100;
    else if (cfg.frequency > 32000)
        chpars[1] = AL_RATE_32000;
    else if (cfg.frequency > 22050)
        chpars[1] = AL_RATE_22050;
    else if (cfg.frequency > 16000)
        chpars[1] = AL_RATE_16000;
    else
        chpars[1] = AL_RATE_11025;
    ALsetparams(AL_DEFAULT_DEVICE, chpars, 2);
    ALgetparams(AL_DEFAULT_DEVICE, chpars, 2);
    _settings.frequency = (uint_least32_t) chpars[1];

    // Allocate sound buffers and set audio queue
    ALsetqueuesize(_config, chpars[1]);

    // open audio device
    _audio = ALopenport("SIDPLAY2 sound", "w", _config);
    if (_audio == NULL)
    {
        perror("AUDIO:");
        _errorString = "ERROR: Could not open audio device.\n       See standard error output.";
        ALfreeconfig(_config);
        return 0;
    }

    // Setup internal Config
    _settings.encoding  = AUDIO_SIGNED_PCM;
    _settings.bufSize   = (uint_least32_t) chpars[1];

    // Update the users settings
    getConfig (cfg);

    // Allocate memory same size as buffer
#ifdef HAVE_EXCEPTIONS
    _sampleBuffer = new(std::nothrow) int_least8_t[chpars[1]];
#else
    _sampleBuffer = new int_least8_t[chpars[1]];
#endif

    _errorString = "OK";
    return (void *) _sampleBuffer;
}
static int setaudio(struct xmp_options *o)
{
	int bsize = 32 * 1024;
	ALconfig config;
	long pvbuffer[2];
	char *token, **parm;
	int i;

	parm_init();
	chkparm1("buffer", bsize = strtoul(token, NULL, 0));
	parm_end();

	if ((config = ALnewconfig()) == 0)
		return XMP_ERR_DINIT;

	/*
	 * Set sampling rate
	 */

	pvbuffer[0] = AL_OUTPUT_RATE;

#if 0				/* DOESN'T WORK */
	for (i = 0; srate[i]; i++) {
		if (srate[i] <= o->freq)
			pvbuffer[1] = o->freq = srate[i];
	}
#endif				/* DOESN'T WORK */

	/*
	 * This was flawed as far as I can tell - it just progressively lowered
	 * the sample rate to the lowest possible!
	 * 
	 * o->freq = 44100
	 *
	 * i = 0 / if (48000 <= 44100)
	 * i = 1 / if (44100 <= 44100)
	 *     then pvbuffer[1] = o->freq = 44100
	 * i = 2 / if (32000 <= 44100)
	 *     then pvbuffer[1] = o->freq = 32000
	 * i = 3 / if (22050 <= 32000)
	 *     then pvbuffer[1] = o->freq = 22050
	 * etc...
	 *
	 * Below is my attempt to write a new one.  It picks the next highest
	 * rate available up to the maximum.  This seems a lot more reasonable.
	 *
	 * - 19990706 bdowning
	 */

	for (i = 0; srate[i]; i++) ;	/* find the end of the array */

	while (i-- > 0) {
		if (srate[i] >= o->freq) {
			pvbuffer[1] = o->freq = srate[i];
			break;
		}
	}

	if (i == 0)
		pvbuffer[1] = o->freq = srate[0];	/* 48 kHz. Wow! */

	if (ALsetparams(AL_DEFAULT_DEVICE, pvbuffer, 2) < 0)
		return XMP_ERR_DINIT;

	/*
	 * Set sample format to signed integer
	 */

	if (ALsetsampfmt(config, AL_SAMPFMT_TWOSCOMP) < 0)
		return XMP_ERR_DINIT;

	/*
	 * Set sample width; 24 bit samples are not currently supported by xmp
	 */

	if (o->resol > 8) {
		if (ALsetwidth(config, AL_SAMPLE_16) < 0) {
			if (ALsetwidth(config, AL_SAMPLE_8) < 0)
				return XMP_ERR_DINIT;
			o->resol = 8;
		} else
			al_sample_16 = 1;
	} else {
		if (ALsetwidth(config, AL_SAMPLE_8) < 0) {
			if (ALsetwidth(config, AL_SAMPLE_16) < 0)
				return XMP_ERR_DINIT;
			o->resol = 16;
		} else
			al_sample_16 = 0;
	}

	/*
	 * Set number of channels; 4 channel output is not currently supported
	 */

	if (o->outfmt & XMP_FMT_MONO) {
		if (ALsetchannels(config, AL_MONO) < 0) {
			if (ALsetchannels(config, AL_STEREO) < 0)
				return XMP_ERR_DINIT;
			o->outfmt &= ~XMP_FMT_MONO;
		}
	} else {
		if (ALsetchannels(config, AL_STEREO) < 0) {
			if (ALsetchannels(config, AL_MONO) < 0)
				return XMP_ERR_DINIT;
			o->outfmt |= XMP_FMT_MONO;
		}
	}

	/*
	 * Set buffer size
	 */

	if (ALsetqueuesize(config, bsize) < 0)
		return XMP_ERR_DINIT;

	/*
	 * Open the audio port
	 */

	if ((audio_port = ALopenport("xmp", "w", config)) == 0)
		return XMP_ERR_DINIT;

	return 0;
}
Beispiel #27
0
static int AL_OpenAudio(_THIS, SDL_AudioSpec *spec)
{
	ALconfig audio_config;
#ifdef OLD_IRIX_AUDIO
	long audio_param[2];
#else
	ALpv audio_param;
#endif
	int width;

	/* Determine the audio parameters from the AudioSpec */
	switch ( spec->format & 0xFF ) {

		case 8: { /* Signed 8 bit audio data */
			spec->format = AUDIO_S8;
			width = AL_SAMPLE_8;
		}
		break;

		case 16: { /* Signed 16 bit audio data */
			spec->format = AUDIO_S16MSB;
			width = AL_SAMPLE_16;
		}
		break;

		default: {
			SDL_SetError("Unsupported audio format");
			return(-1);
		}
	}

	/* Update the fragment size as size in bytes */
	SDL_CalculateAudioSpec(spec);

	/* Set output frequency */
#ifdef OLD_IRIX_AUDIO
	audio_param[0] = AL_OUTPUT_RATE;
	audio_param[1] = spec->freq;
	if( ALsetparams(AL_DEFAULT_DEVICE, audio_param, 2) < 0 ) {
#else
	audio_param.param = AL_RATE;
	audio_param.value.i = spec->freq;
	if( alSetParams(AL_DEFAULT_OUTPUT, &audio_param, 1) < 0 ) {
#endif
		SDL_SetError("alSetParams failed");
		return(-1);
	}

	/* Open the audio port with the requested frequency */
	audio_port = NULL;
	audio_config = alNewConfig();
	if ( audio_config &&
	     (alSetSampFmt(audio_config, AL_SAMPFMT_TWOSCOMP) >= 0) &&
	     (alSetWidth(audio_config, width) >= 0) &&
	     (alSetQueueSize(audio_config, spec->samples*2) >= 0) &&
	     (alSetChannels(audio_config, spec->channels) >= 0) ) {
		audio_port = alOpenPort("SDL audio", "w", audio_config);
	}
	alFreeConfig(audio_config);
	if( audio_port == NULL ) {
		SDL_SetError("Unable to open audio port");
		return(-1);
	}

	/* Allocate mixing buffer */
	mixbuf = (Uint8 *)SDL_AllocAudioMem(spec->size);
	if ( mixbuf == NULL ) {
		SDL_OutOfMemory();
		return(-1);
	}
	memset(mixbuf, spec->silence, spec->size);

	/* We're ready to rock and roll. :-) */
	return(0);
}
Beispiel #28
0
static AudioContext
initialize_audio_port (AudioContext desc)
{
  /* we can't use the same port for mono and stereo */
  static AudioContextRec mono_port_state
    = { { 0, 0, 0, 0 },
	{ (ALport) 0, AFunknown, 1, 0 },
	{ (void *) 0, (unsigned long) 0 } };
#if HAVE_STEREO
  static AudioContextRec stereo_port_state
    = { { 0, 0, 0, 0 },
	{ (ALport) 0, AFunknown, 2, 0 },
	{ (void *) 0, (unsigned long) 0 } };
  static AudioContext return_ac;

  switch (desc->ac_nchan)
    {
    case 1:  return_ac = & mono_port_state; break;
    case 2:  return_ac = & stereo_port_state; break;
    default: return (AudioContext) 0;
    }
#else /* not HAVE_STEREO */
  static AudioContext return_ac = & mono_port_state;
#endif /* not HAVE_STEREO */

  return_ac->device = desc->device;
  return_ac->buffer = desc->buffer;
  return_ac->ac_format = desc->ac_format;
  return_ac->ac_queue_size = desc->ac_queue_size;

  if (return_ac->ac_port==(ALport) 0)
    {
      if ((open_audio_port (return_ac, desc))==-1)
	{
	  report_file_error ("Open audio port", Qnil);
	  return (AudioContext) 0;
	}
    }
  else
    {
      ALconfig config = ALgetconfig (return_ac->ac_port);
      int changed = 0;
      long params[2];

      params[0] = AL_OUTPUT_RATE;
      ALgetparams (return_ac->ac_device, params, 2);
      return_ac->ac_output_rate = params[1];

      if (return_ac->ac_output_rate != desc->ac_output_rate)
	{
	  return_ac->ac_output_rate = params[1] = desc->ac_output_rate;
	  ALsetparams (return_ac->ac_device, params, 2);
	}
      if ((changed = set_output_format (config, return_ac->ac_format))==-1)
	return (AudioContext) 0;
      return_ac->ac_format = desc->ac_format;
      if (changed)
	ALsetconfig (return_ac->ac_port, config);
    }
  return_ac->ac_write_chunk_function = desc->ac_write_chunk_function;
  get_current_volumes (& return_ac->device);
  if (return_ac->ac_left_speaker_gain != desc->ac_left_speaker_gain
      || return_ac->ac_right_speaker_gain != desc->ac_right_speaker_gain)
    adjust_audio_volume (& desc->device);
  return return_ac;
}