Beispiel #1
0
static int init(struct xmp_context *ctx)
{
    struct xmp_options *o = &ctx->o;
    int rc, rate, bits, stereo, bsize;
    char *dev;
    char *token;
    char **parm = o->parm;
 
    parm_init();
    chkparm1("dev", dev = token);
    chkparm1("buffer", bsize = strtoul(token, NULL, 0));
    parm_end();

    rate = o->freq;
    bits = o->resol;
    stereo = 1;
    bufsize = 32 * 1024;

    fd_audio = open (dev, O_WRONLY);
    if (fd_audio < 0) {
	fprintf (stderr, "can't open audio device\n");
	return XMP_ERR_DINIT;
    }

    if (o->outfmt & XMP_FMT_MONO)
	stereo = 0;

    if (ioctl(fd_audio, SOUND_PCM_WRITE_BITS, &bits) < 0) {
	perror ("can't set resolution");
	goto error;
    }

    if (ioctl(fd, SNDCTL_DSP_STEREO, &stereo) < 0) {
	perror ("can't set channels");
	goto error;
    }

    if (ioctl(fd, SNDCTL_DSP_SPEED, &rate) < 0) {
	perror ("can't set rate");
	goto error;
    }

    if (ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &buf.size) < 0) {
	perror ("can't set rate");
	goto error;
    }

    if (ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &bufsize) < 0) {
	perror ("can't set buffer");
	goto error;
    }

    return xmp_smix_on(ctx);

error:
    close(fd_audio);
    return XMP_ERR_DINIT;
}
static int init(struct xmp_context *ctx)
{
	snd_pcm_hw_params_t *hwparams;
	int ret;
	char *token, **parm;
	unsigned int channels, rate;
	unsigned int btime = 2000000;	/* 2s */
	unsigned int ptime = 100000;	/* 100ms */
	char *card_name = "default";
	struct xmp_options *o = &ctx->o;

	parm_init();  
	chkparm1("buffer", btime = 1000 * strtoul(token, NULL, 0));
	chkparm1("period", btime = 1000 * strtoul(token, NULL, 0));
	chkparm1("card", card_name = token);
	parm_end();

	if ((ret = snd_pcm_open(&pcm_handle, card_name,
		SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
		fprintf(stderr, "Unable to initialize ALSA pcm device: %s\n",
					snd_strerror(ret));
		return XMP_ERR_DINIT;
	}

	channels = (o->outfmt & XMP_FMT_MONO) ? 1 : 2;
	rate = o->freq;

	snd_pcm_hw_params_alloca(&hwparams);
	snd_pcm_hw_params_any(pcm_handle, hwparams);
	snd_pcm_hw_params_set_access(pcm_handle, hwparams,
		SND_PCM_ACCESS_RW_INTERLEAVED);
	snd_pcm_hw_params_set_format(pcm_handle, hwparams, to_fmt(o));
	snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &rate, 0);
	snd_pcm_hw_params_set_channels_near(pcm_handle, hwparams, &channels);
	snd_pcm_hw_params_set_buffer_time_near(pcm_handle, hwparams, &btime, 0);
	snd_pcm_hw_params_set_period_time_near(pcm_handle, hwparams, &ptime, 0);
	snd_pcm_nonblock(pcm_handle, 0);
	
	if ((ret = snd_pcm_hw_params(pcm_handle, hwparams)) < 0) {
		fprintf(stderr, "Unable to set ALSA output parameters: %s\n",
					snd_strerror(ret));
		return XMP_ERR_DINIT;
	}

	if (prepare_driver() < 0)
		return XMP_ERR_DINIT;
  
	o->freq = rate;

	return xmp_smix_on(ctx);
}
static int init(struct xmp_context *ctx)
{
	struct xmp_options *o = &ctx->o;
	MMRESULT res;
	WAVEFORMATEX wfe;
	int i;
	char *token, **parm;

	num_buffers = 10;
	
	parm_init();
	chkparm1("buffers", num_buffers = strtoul(token, NULL, 0));
	parm_end();

	if (num_buffers > MAXBUFFERS)
		num_buffers = MAXBUFFERS;

	if (!waveOutGetNumDevs())
		return XMP_ERR_DINIT;

	wfe.wFormatTag = WAVE_FORMAT_PCM;
	wfe.wBitsPerSample = o->resol;
	wfe.nChannels = o->flags & XMP_FMT_MONO ? 1 : 2;
	wfe.nSamplesPerSec = o->freq;
	wfe.nAvgBytesPerSec = wfe.nSamplesPerSec * wfe.nChannels *
	    wfe.wBitsPerSample / 8;
	wfe.nBlockAlign = wfe.nChannels * wfe.wBitsPerSample / 8;

	res = waveOutOpen(&hwaveout, WAVE_MAPPER, &wfe, (DWORD) wave_callback,
			  0, CALLBACK_FUNCTION);

	if (res != MMSYSERR_NOERROR) {
		show_error(res);
		return XMP_ERR_DINIT;
	}

	waveOutReset(hwaveout);

	for (i = 0; i < num_buffers; i++) {
		buffer[i] = malloc(OUT_MAXLEN);
		header[i].lpData = buffer[i];

		if (!buffer[i] || res != MMSYSERR_NOERROR) {
			show_error(res);
			return XMP_ERR_DINIT;
		}
	}

	freebuffer = nextbuffer = 0;

	return xmp_smix_on(ctx);
}
static int setaudio(struct xmp_options *o)
{
	audio_info_t ainfo, ainfo2;
	int gain;
	int bsize = 32 * 1024;
	int port;
	char *token, **parm;
	AUDIO_INITINFO(&ainfo);

	/* try to open audioctl device */
	if ((audioctl_fd = open("/dev/audioctl", O_RDWR)) < 0) {
		fprintf(stderr, "couldn't open audioctl device\n");
		close(audio_fd);
		return -1;
	}

	/* sleep(2); -- Really needed? */

	/* empty buffers before change config */
	ioctl(audio_fd, AUDIO_DRAIN, 0);	/* drain everything out */
	ioctl(audio_fd, I_FLUSH, FLUSHRW);	/* flush everything     */
	ioctl(audioctl_fd, I_FLUSH, FLUSHRW);	/* flush everything */

	/* get audio parameters. */
	if (ioctl(audioctl_fd, AUDIO_GETINFO, &ainfo) < 0) {
		fprintf(stderr, "AUDIO_GETINFO failed!\n");
		close(audio_fd);
		close(audioctl_fd);
		return -1;
	}

	close(audioctl_fd);

	/* KH: Sun Dbri doesn't support 8bits linear. I dont muck with the gain
	 *     or the port setting. I hate when a program does that. There is
	 *     nothing more frustrating then having a program change your volume
	 *     and change from external speakers to the tiny one
	 */

	gain = ainfo.play.gain;
	port = ainfo.play.port;

	parm_init();
	chkparm1("gain", gain = strtoul(token, NULL, 0));
	chkparm1("buffer", bsize = strtoul(token, NULL, 0));
	chkparm1("port", port = (int)*token)
	    parm_end();

	switch (port) {
	case 'h':
		port = AUDIO_HEADPHONE;
		break;
	case 'l':
		port = AUDIO_LINE_OUT;
		break;
	case 's':
		port = AUDIO_SPEAKER;
	}

	if (gain < AUDIO_MIN_GAIN)
		gain = AUDIO_MIN_GAIN;
	if (gain > AUDIO_MAX_GAIN)
		gain = AUDIO_MAX_GAIN;

	AUDIO_INITINFO(&ainfo);	/* For CS4231 */
	AUDIO_INITINFO(&ainfo2);	/* For AMD 7930 if needed */

	ainfo.play.sample_rate = o->freq;
	ainfo.play.channels = o->outfmt & XMP_FMT_MONO ? 1 : 2;
	ainfo.play.precision = o->resol;
	ainfo.play.encoding = AUDIO_ENCODING_LINEAR;
	ainfo2.play.gain = ainfo.play.gain = gain;
	ainfo2.play.port = ainfo.play.port = port;
	ainfo2.play.buffer_size = ainfo.play.buffer_size = bsize;

	if (ioctl(audio_fd, AUDIO_SETINFO, &ainfo) == -1) {
		/* CS4231 initialization Failed, perhaps we have an AMD 7930 */
		if (ioctl(audio_fd, AUDIO_SETINFO, &ainfo2) == -1) {
			close(audio_fd);
			return XMP_ERR_DINIT;
		}

		o->resol = 0;
		o->freq = 8000;
		o->outfmt |= XMP_FMT_MONO;
		drv_solaris.description = "Solaris AMD7930 PCM audio";
	} else {
		drv_solaris.description = "Solaris CS4231 PCM audio";
	}

	return 0;
}
static int init(struct xmp_context *ctx)
{
	struct xmp_options *o = &ctx->o;
	int channels, rate, format, buf_samples;
	int duration, gain, watermark;
	char *server;
	AuDeviceID device = AuNone;
	AuElement element[2];
	char *token, **parm;
	int i;

	duration = 2;
	gain = 100;
	server = NULL;
	watermark = 10;
	channels = 2;
	rate = o->freq;

	parm_init();
	chkparm1("duration", duration = atoi(token));
	chkparm1("gain", gain = atoi(token));
	chkparm1("server", server = token);
	chkparm1("watermark", watermark = atoi(token));
	parm_end();

	if (o->resol == 8) {
		format = o->outfmt & XMP_FMT_UNS ?
		    AuFormatLinearUnsigned8 : AuFormatLinearSigned8;
	} else {
		if (o->big_endian) {
			format = o->outfmt & XMP_FMT_UNS ?
				AuFormatLinearUnsigned16MSB :
				AuFormatLinearSigned16MSB;
		} else {
			format = o-> outfmt & XMP_FMT_UNS ?
				AuFormatLinearUnsigned16LSB :
				AuFormatLinearSigned16LSB;
		}
	}

	if (o->outfmt & XMP_FMT_MONO)
		channels = 1;

	info.aud = AuOpenServer(server, 0, NULL, 0, NULL, NULL);
	if (!info.aud) {
		fprintf(stderr, "xmp: drv_nas: can't connect to server %s\n",
			server ? server : "");
		return XMP_ERR_DINIT;
	}

	for (i = 0; i < AuServerNumDevices(info.aud); i++) {
		if (((AuDeviceKind(AuServerDevice(info.aud, i)) ==
		     AuComponentKindPhysicalOutput) &&
		     AuDeviceNumTracks(AuServerDevice(info.aud, i)) ==
		     channels)) {
			device =
			    AuDeviceIdentifier(AuServerDevice(info.aud, i));
			break;
		}
	}

	info.da = AuGetDeviceAttributes(info.aud, device, NULL);
	if (!info.da) {
		fprintf(stderr, "xmp: drv_nas: can't get device attributes\n");
		AuCloseServer(info.aud);
		return XMP_ERR_DINIT;
	}

	AuDeviceGain(info.da) = AuFixedPointFromSum(gain, 0);
	AuSetDeviceAttributes(info.aud, AuDeviceIdentifier(info.da),
			      AuCompDeviceGainMask, info.da, NULL);

	info.flow = AuCreateFlow(info.aud, NULL);
	if (!info.flow) {
		fprintf(stderr, "xmp: drv_nas: can't create flow\n");
		AuCloseServer(info.aud);
		return XMP_ERR_DINIT;
	}

	buf_samples = rate * duration;

	AuMakeElementImportClient(&element[0], rate, format, channels, AuTrue,
				  buf_samples,
				  (AuUint32) (buf_samples * watermark / 100), 0,
				  NULL);

	AuMakeElementExportDevice(&element[1], 0, device, rate,
				  AuUnlimitedSamples, 0, NULL);

	AuSetElements(info.aud, info.flow, AuTrue, 2, element, NULL);

	AuRegisterEventHandler(info.aud, AuEventHandlerIDMask, 0, info.flow,
			       nas_event, (AuPointer) & info);

	info.buf_size = buf_samples * channels * AuSizeofFormat(format);
	info.buf = (char *)malloc(info.buf_size);
	info.buf_cnt = 0;
	info.data_sent = AuFalse;
	info.finished = AuFalse;

	AuStartFlow(info.aud, info.flow, NULL);

	return xmp_smix_on(ctx);
}
Beispiel #6
0
static int init(struct options *options)
{
	char **parm = options->driver_parm;
	audio_info_t ainfo;
	int gain = 128;
	int bsize = 32 * 1024;

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

	if ((audio_fd = open("/dev/sound", O_WRONLY)) == -1)
		return -1;

	/* try to open audioctldevice */
	if ((audioctl_fd = open("/dev/audioctl", O_RDWR)) < 0) {
		fprintf(stderr, "couldn't open audioctldevice\n");
		close(audio_fd);
		return -1;
	}

	/* empty buffers before change config */
	ioctl(audio_fd, AUDIO_DRAIN, 0);	/* drain everything out */
	ioctl(audio_fd, AUDIO_FLUSH);		/* flush audio */
	ioctl(audioctl_fd, AUDIO_FLUSH);	/* flush audioctl */

	/* get audio parameters. */
	if (ioctl(audioctl_fd, AUDIO_GETINFO, &ainfo) < 0) {
		fprintf(stderr, "AUDIO_GETINFO failed!\n");
		close(audio_fd);
		close(audioctl_fd);
		return -1;
	}

	close(audioctl_fd);

	if (gain < AUDIO_MIN_GAIN)
		gain = AUDIO_MIN_GAIN;
	if (gain > AUDIO_MAX_GAIN)
		gain = AUDIO_MAX_GAIN;

	AUDIO_INITINFO(&ainfo);

	ainfo.play.sample_rate = options->rate;
	ainfo.play.channels = options->format & XMP_FORMAT_MONO ? 1 : 2;

	if (options->format & XMP_FORMAT_8BIT) {
		ainfo.play.precision = 8;
		ainfo.play.precision = AUDIO_ENCODING_ULINEAR;
		options->format |= XMP_FORMAT_UNSIGNED;
	} else {
		ainfo.play.precision = 16;
		ainfo.play.precision = AUDIO_ENCODING_SLINEAR;
		options->format &= ~XMP_FORMAT_UNSIGNED;
	}

	ainfo.play.gain = gain;
	ainfo.play.buffer_size = bsize;

	if (ioctl(audio_fd, AUDIO_SETINFO, &ainfo) == -1) {
		close(audio_fd);
		return -1;
	}

	return 0;
}
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 #8
0
static int init(struct xmp_context *ctx)
{
	struct xmp_options *o = &ctx->o;
	snd_pcm_channel_params_t params;
	snd_pcm_channel_setup_t setup;
	int card = 0;
	int dev = 0;
	int rc;
	char *token, **parm;

	parm_init();
	chkparm2("frag", "%d,%d", &frag_num, &frag_size);
	if (frag_num > 8)
		frag_num = 8;
	if (frag_num < 4)
		frag_num = 4;
	if (frag_size > 65536)
		frag_size = 65536;
	if (frag_size < 16)
		frag_size = 16;
	chkparm1("card", card_name = token);
	//  card = snd_card_name(card_name); /* ? */
	//  dev = snd_defaults_pcm_device(); /* ? */
	parm_end();

	mybuffer = malloc(frag_size);
	if (mybuffer) {
		mybuffer_nextfree = mybuffer;
	} else {
		printf("Unable to allocate memory for mixer buffer\n");
		return XMP_ERR_DINIT;
	}

	if ((rc =
	     snd_pcm_open(&pcm_handle, card, dev, SND_PCM_OPEN_PLAYBACK)) < 0) {
		printf("Unable to initialize pcm device: %s\n",
		       snd_strerror(rc));
		return XMP_ERR_DINIT;
	}

	memset(&params, 0, sizeof(snd_pcm_channel_params_t));

	params.mode = SND_PCM_MODE_BLOCK;
	params.buf.block.frag_size = frag_size;
	params.buf.block.frags_min = 1;
	params.buf.block.frags_max = frag_num;

	//params.mode = SND_PCM_MODE_STREAM;
	//params.buf.stream.queue_size = 16384;
	//params.buf.stream.fill = SND_PCM_FILL_NONE;
	//params.buf.stream.max_fill = 0;

	params.channel = SND_PCM_CHANNEL_PLAYBACK;
	params.start_mode = SND_PCM_START_FULL;
	params.stop_mode = SND_PCM_STOP_ROLLOVER;

	params.format.interleave = 1;
	params.format.format = to_fmt(o);
	params.format.rate = o->freq;
	params.format.voices = (o->outfmt & XMP_FMT_MONO) ? 1 : 2;

	if ((rc = snd_pcm_plugin_params(pcm_handle, &params)) < 0) {
		printf("Unable to set output parameters: %s\n",
					snd_strerror(rc));
		return XMP_ERR_DINIT;
	}

	if (prepare_driver() < 0)
		return XMP_ERR_DINIT;

	memset(&setup, 0, sizeof(setup));
	setup.mode = SND_PCM_MODE_STREAM;
	setup.channel = SND_PCM_CHANNEL_PLAYBACK;

	if ((rc = snd_pcm_channel_setup(pcm_handle, &setup)) < 0) {
		printf("Unable to setup channel: %s\n", snd_strerror(rc));
		return XMP_ERR_DINIT;
	}

	return xmp_smix_on(ctx);
}