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; 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); }