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) { 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 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; char *dev; char *token; char **parm = o->parm; static char desc[80]; be_app = new BApplication("application/x-vnd.cm-xmp"); chunk_size = 4096; chunk_num = 20; parm_init(); chkparm2("buffer", "%d,%d", &chunk_num, &chunk_size); parm_end(); snprintf(desc, 80, "%s [%d fragments of %d bytes]", drv_beos.description, chunk_num, chunk_size); drv_beos.description = desc; fmt.frame_rate = o->freq; fmt.channel_count = o->outfmt & XMP_FMT_MONO ? 1 : 2; fmt.format = o->resol > 8 ? B_AUDIO_SHORT : B_AUDIO_CHAR; fmt.byte_order = B_HOST_IS_LENDIAN ? B_MEDIA_LITTLE_ENDIAN : B_MEDIA_BIG_ENDIAN; fmt.buffer_size = chunk_size * chunk_num; buffer_len = chunk_size * chunk_num; buffer = (uint8 *)calloc(1, buffer_len); buf_read_pos = 0; buf_write_pos = 0; paused = 1; player = new BSoundPlayer(&fmt, "xmp output", render_proc); 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); }
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; }
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(¶ms, 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, ¶ms)) < 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); }