示例#1
0
static void *
read_thread(void *dp)
{
	sndio_in_driver *d = dp;
	struct pollfd pfd;
	int size, ret, off, nfds;

	if (!sio_start(d->hdl)) {
		error_error("could not start sndio");
		goto done;
	}

	while (d->read_trun) {
		nfds = sio_pollfd(d->hdl, &pfd, POLLIN);
		poll(&pfd, nfds, -1);
		if (sio_revents(d->hdl, &pfd) & POLLIN) {
			size = d->par.rchan * d->par.bps * d->bufsize;
			off = 0;
			while (size > 0) {
				ret = sio_read(d->hdl, d->sndbuf + off, size);
				off += ret;
				size -= ret;
			}
			sample_editor_sampled(d->sndbuf, d->bufsize,
			    d->par.rate, d->mf);
		}
	}
done:
	pthread_exit(NULL);
	return NULL;
}
static void
alsa_error (const gchar *msg, gint err)
{
    static char buf[256];
    g_sprintf(buf, "%s: %s\n", _(msg), snd_strerror(err));
    error_error(buf);
}
static void
instrument_editor_load_instrument (gchar *fn)
{
    STInstrument *instr = current_instrument;
    FILE *f;

    g_assert(instr != NULL);

    // Instead of locking the instrument and samples, we simply stop playing.
    gui_play_stop();

    f = fopen(fn, "rb");
    if(f) {
        statusbar_update(STATUS_LOADING_INSTRUMENT, TRUE);
        xm_load_xi(instr, f);
       statusbar_update(STATUS_INSTRUMENT_LOADED, FALSE);
	fclose(f);
    } else {
	error_error(_("Can't open file."));
    }

    current_instrument = NULL;
    instrument_editor_set_instrument(instr);
    sample_editor_set_sample(&instr->samples[0]);
}
static gboolean
file_open (void *dp)
{
    file_driver * const d = dp;
    AFfilesetup outfilesetup;

    outfilesetup = afNewFileSetup();
    afInitFileFormat(outfilesetup, AF_FILE_WAVE);
    afInitChannels(outfilesetup, AF_DEFAULT_TRACK, 2);
    afInitSampleFormat(outfilesetup, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16);
    d->outfile = afOpenFile(d->filename, "w", outfilesetup);
    afFreeFileSetup(outfilesetup);

    if(!d->outfile) {
	error_error(_("Can't open file for writing."));
	goto out;
    }

    /* In case we're running setuid root... */
    chown(d->filename, getuid(), getgid());

    d->sndbuf_size = 16384;
    d->sndbuf = malloc(d->sndbuf_size);
    if(!d->sndbuf) {
	error_error("Can't allocate mix buffer.");
	goto out;
    }

    d->polltag = audio_poll_add(d->pipe[1], GDK_INPUT_WRITE, file_poll_ready_playing, d);
    d->firstpoll = TRUE;
    d->playtime = 0.0;

    return TRUE;

  out:
    file_release(dp);
    return FALSE;
}
static gboolean
sndfile_open (void *dp)
{
    sndfile_driver * const d = dp;

    d->sfinfo.channels = 2 ;
    d->sfinfo.samplerate = 44100 ;
    d->sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16 ;

    d->outfile = sf_open (d->filename, SFM_WRITE, &d->sfinfo);

    if(!d->outfile) {
	error_error(_("Can't open file for writing."));
	goto out;
    }

    /* In case we're running setuid root... */
    chown(d->filename, getuid(), getgid());

    d->sndbuf_size = 16384;
    d->sndbuf = malloc(d->sndbuf_size);
    if(!d->sndbuf) {
	error_error("Can't allocate mix buffer.");
	goto out;
    }

    d->polltag = audio_poll_add(d->pipe[1], GDK_INPUT_WRITE, sndfile_poll_ready_playing, d);
    d->firstpoll = TRUE;
    d->playtime = 0.0;

    return TRUE;

  out:
    sndfile_release(dp);
    return FALSE;
}
void
fileops_open_dialog (void *dummy,
		     void *index)
{
    int n = GPOINTER_TO_INT(index);

    if(!fileops_dialogs[n]) {
	error_error(_("Operation not supported."));
	return;
    }
    
    if(fileops_dialogs[n] == (GtkWidget*)fileops_current_dialog) {
	gui_go_to_fileops_page();
    } else {
	gtk_widget_show(fileops_dialogs[n]);
	fileops_refresh_list(GTK_FILE_SELECTION(fileops_dialogs[n]), TRUE);
    }
}
static void
instrument_editor_save_instrument (gchar *fn)
{
    STInstrument *instr = current_instrument;
    FILE *f;

    g_assert(instr != NULL);

    f = fopen(fn, "wb");
    if(f) {
        statusbar_update(STATUS_SAVING_INSTRUMENT, TRUE);
	xm_save_xi(instr, f);
        statusbar_update(STATUS_INSTRUMENT_SAVED, FALSE);
	fclose(f);
    } else {
	error_error(_("Can't open file."));
    }
}
static gboolean
alsa_open (void *dp)
{
    alsa_driver * const d = dp;
    gint mf, err, pers;

    if(pcm_open_and_load_hwparams(d) < 0)
	goto out;

    // ---
    // Set non-blocking mode.
    // ---

    d->outtime = 0;

    // --
    // Set channel parameters
    // --
    if((err = snd_pcm_hw_params_set_access(d->soundfd, d->hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0){
	alsa_error(N_("Unable to set access"), err);
	goto out;
    }

    if((err = snd_pcm_hw_params_set_format(d->soundfd, d->hwparams,
				    (d->bits - 8) ? d->signedness16 ? SND_PCM_FORMAT_S16 : SND_PCM_FORMAT_U16 :
						    d->signedness8 ? SND_PCM_FORMAT_S8 : SND_PCM_FORMAT_U8) < 0)) {
	alsa_error(N_("Unable to set audio format"), err);
	goto out;
    }
    /* Handle endianess aspects. TODO! */
    switch(d->bits) {
	case 16:
	    mf = d->signedness16 ? ST_MIXER_FORMAT_S16_LE : ST_MIXER_FORMAT_U16_LE;
	    break;
	case 8:
	default:
	    mf = d->signedness8 ? ST_MIXER_FORMAT_S8 : ST_MIXER_FORMAT_U8;
	    break;
    }

    if((err = snd_pcm_hw_params_set_channels(d->soundfd, d->hwparams, d->stereo + 1)) < 0) {
	alsa_error(N_("Unable to set channels number"), err);
	goto out;
    }
    if((d->stereo)) {
	mf |= ST_MIXER_FORMAT_STEREO;
    }
    d->mf = mf;

    d->p_mixfreq = d->playrate;
    if ((err = snd_pcm_hw_params_set_rate_near(d->soundfd, d->hwparams, &(d->p_mixfreq), NULL)) < 0) {
	alsa_error(N_("Unable to set sample rate"), err);
	goto out;
    }

    if(snd_pcm_hw_params_set_buffer_size(d->soundfd, d->hwparams, 1 << d->buffer_size) < 0) {
	/* Some soundcards report wrong maximal buffer size (maybe alsa bug). So we should try
	   to downscale its value before the reporting an error. The spinbutton still may display
	   the wrong number, but actually the correct value will be implemented.*/
	while((--d->buffer_size) >= 8)
	    if(!snd_pcm_hw_params_set_buffer_size(d->soundfd, d->hwparams, 1 << d->buffer_size))
		break;
	if(d->buffer_size < 8) {
	    error_error(N_("Unable to set appropriate buffer size"));
	    goto out;
	}
    }
    pers = 1 << d->num_periods;
    if ((err = snd_pcm_hw_params_set_periods_near(d->soundfd, d->hwparams, &pers, NULL)) < 0) {
	alsa_error(N_("Unable to set periods number"), err);
	goto out;
    }
    if ((err = snd_pcm_hw_params_get_period_size(d->hwparams, &(d->p_fragsize), NULL)) < 0) {
	alsa_error(N_("Unable to get period size"), err);
	goto out;
    }

    if((err = snd_pcm_hw_params(d->soundfd, d->hwparams))) {
	alsa_error(N_("Error setting hw parameters"), err);
	goto out;
    }

    /* The following piece of code is directly c_n_p'ed from the ALSA pcm example (whith a little adopting) */
    /* get the current swparams */
    err = snd_pcm_sw_params_current(d->soundfd, d->swparams);
    if (err < 0) {
            alsa_error(N_("Unable to determine current swparams for playback"), err);
	    goto out;
    }
    /* start the transfer when the buffer is full */
    err = snd_pcm_sw_params_set_start_threshold(d->soundfd, d->swparams, d->p_fragsize);
    if (err < 0) {
            alsa_error(N_("Unable to set start threshold mode for playback"), err);
	    goto out;
    }
    /* allow the transfer when at least period_size samples can be processed */
    err = snd_pcm_sw_params_set_avail_min(d->soundfd, d->swparams, d->p_fragsize);
    if (err < 0) {
            alsa_error(N_("Unable to set avail min for playback"), err);
	    goto out;
    }
    /* align all transfers to 1 sample */
    err = snd_pcm_sw_params_set_xfer_align(d->soundfd, d->swparams, 1);
    if (err < 0) {
            alsa_error(N_("Unable to set transfer align for playback"), err);
	    goto out;
    }
    /* write the parameters to the playback device */
    err = snd_pcm_sw_params(d->soundfd, d->swparams);
    if (err < 0) {
            alsa_error(N_("Unable to set sw params for playback"), err);
	    goto out;
    }

    err = snd_pcm_prepare(d->soundfd);
    if (err < 0) {
            alsa_error(N_("Unable to prepare playback"), err);
	    goto out;
    }
    // ---
    // Get buffering parameters
    // ---
   
    if(d->verbose)
        snd_pcm_dump(d->soundfd, d->output);
    d->sndbuf = calloc((d->stereo + 1) * (d->bits / 8), d->p_fragsize);

    d->pfd = malloc(sizeof(struct pollfd));
    if ((err = snd_pcm_poll_descriptors(d->soundfd, d->pfd, 1)) < 0) {
        alsa_error(N_("Unable to obtain poll descriptors for playback"), err);
        goto out;
    }

    d->polltag = audio_poll_add(d->pfd->fd, GDK_INPUT_WRITE, alsa_poll_ready_playing, d);

    d->playtime = 0;
    d->firstpoll = TRUE;

    return TRUE;

  out:
    alsa_release(dp);
    return FALSE;
}
static void
device_test (GtkWidget *w, alsa_driver *d)
{
    guint chmin, chmax, i;
    gint err;
    gchar *new_device;

    d->can8 = FALSE;
    d->can16 = FALSE;
    d->canmono = FALSE;
    d->canstereo = FALSE;
    d->signedness8 = FALSE;
    d->signedness16 = FALSE;

    new_device = gtk_combo_box_get_active_text(GTK_COMBO_BOX(d->alsa_device));
    if(g_ascii_strcasecmp(d->device, new_device)) {
	g_free(d->device);
	d->device = g_strdup(new_device);
	gui_hlp_combo_box_prepend_text_or_set_active(GTK_COMBO_BOX(d->alsa_device), d->device, FALSE);
    }

    for(i = 0; i < NUM_FORMATS; i++){
	d->devcap[i].minfreq = 8000;
	d->devcap[i].maxfreq = 44100;
	d->devcap[i].minbufsize = 256;
    }
    d->devcap[MONO8].maxbufsize = 65536;
    d->devcap[STEREO8].maxbufsize = 32768;
    d->devcap[MONO16].maxbufsize = 32768;
    d->devcap[STEREO16].maxbufsize = 16384;

    if(pcm_open_and_load_hwparams(d) < 0)
	return;

    if(!snd_pcm_hw_params_test_format(d->soundfd, d->hwparams, SND_PCM_FORMAT_U8)) {
	d->can8 = TRUE;
    }
    if(!snd_pcm_hw_params_test_format(d->soundfd, d->hwparams, SND_PCM_FORMAT_S8)) {
	d->can8 = TRUE;
	d->signedness8 = TRUE;
    }
    if(!snd_pcm_hw_params_test_format(d->soundfd, d->hwparams, SND_PCM_FORMAT_U16)) {
	d->can16 = TRUE;
    }
    if(!snd_pcm_hw_params_test_format(d->soundfd, d->hwparams, SND_PCM_FORMAT_S16)) {
	d->can16 = TRUE;
	d->signedness16 = TRUE;
    }

    if((err = snd_pcm_hw_params_get_channels_min(d->hwparams, &chmin)) < 0) {
	alsa_error(N_("Unable to get minimal channels number"), err);
	snd_pcm_close(d->soundfd);
	return;
    }
    if((err = snd_pcm_hw_params_get_channels_max(d->hwparams, &chmax)) < 0) {
	alsa_error(N_("Unable to get maximal channels number"), err);
	snd_pcm_close(d->soundfd);
	return;
    }
    if(chmin > 2) {
	error_error("Both mono and stereo are not supported by ALSA device!!!");
	snd_pcm_close(d->soundfd);
	return;
    }
    if(chmin == 1)
	d->canmono = TRUE;
    if(chmax >= 2)
	d->canstereo = TRUE;

    if(d->can8) {
	if((err = snd_pcm_hw_params_set_format(d->soundfd, d->hwparams,
					d->signedness8 ? SND_PCM_FORMAT_S8 : SND_PCM_FORMAT_U8)) < 0) {
	    alsa_error(N_("Unable to set audio format"), err);
	    snd_pcm_close(d->soundfd);
	    return;
	}
	if(d->canmono) {
	    if(set_rates(d, 1, MONO8) < 0) {
		snd_pcm_close(d->soundfd);
		return;
	    }
	}

	if(d->canstereo) {
	    snd_pcm_close(d->soundfd);
	    if(pcm_open_and_load_hwparams(d) < 0)
		return;
	    if(set_rates(d, 2, STEREO8) < 0) {
		snd_pcm_close(d->soundfd);
		return;
	    }
	}
    }

    if(d->can16) {
	snd_pcm_close(d->soundfd);
	if(pcm_open_and_load_hwparams(d) < 0)
	    return;
	if((err = snd_pcm_hw_params_set_format(d->soundfd, d->hwparams,
					d->signedness16 ? SND_PCM_FORMAT_S16 : SND_PCM_FORMAT_U16)) < 0) {
	    alsa_error(N_("Unable to set audio format"), err);
	    snd_pcm_close(d->soundfd);
	    return;
	}
	if(d->canmono) {
	    if(set_rates(d, 1, MONO16) < 0) {
		snd_pcm_close(d->soundfd);
		return;
	    }
	}
	if(d->canstereo) {
	    snd_pcm_close(d->soundfd);
	    if(pcm_open_and_load_hwparams(d) < 0)
		return;
	    if(set_rates(d, 2, STEREO16) < 0) {
		snd_pcm_close(d->soundfd);
		return;
	    }
	}
    }

    snd_pcm_close(d->soundfd);
    update_controls(d);
}
static void
check_period_sizes (alsa_driver *d)
{
    /* Almost everything (luckily except sampling frequency) can affect period size: buffer size,
       format, channel numbers... So we need to recheck it after at least one of the parameters is
       changed -- mutab0r */
    gint err;
    guint address = PARAMS_TO_ADDRESS(d);

    /* The procedure is time-consuming and may cause audio system lock. So be sure if we really
       need it before starting... -- mutab0r */
    if(d->bits == 0)
	return;
    if((address == d->address_old) && (d->buffer_size == d->bufsize_old))
	return;

    if(pcm_open_and_load_hwparams(d) < 0)
	return;

    if((err = snd_pcm_hw_params_set_format(d->soundfd, d->hwparams,
				    (d->bits - 8) ? d->signedness16 ? SND_PCM_FORMAT_S16 : SND_PCM_FORMAT_U16 :
						    d->signedness8 ? SND_PCM_FORMAT_S8 : SND_PCM_FORMAT_U8)) < 0) {
	alsa_error(N_("Unable to set audio format"), err);
	snd_pcm_close(d->soundfd);
	return;
    }
    if((err = snd_pcm_hw_params_set_channels(d->soundfd, d->hwparams, d->stereo + 1)) < 0) {
	alsa_error(N_("Unable to set channels number"), err);
	snd_pcm_close(d->soundfd);
	return;
    }
    if(snd_pcm_hw_params_set_buffer_size(d->soundfd, d->hwparams, 1 << d->buffer_size) < 0) {
	/* Some soundcards report wrong maximal buffer size (maybe alsa bug). So we should try
	   to downscale its value before the reporting an error. The spinbutton still may display
	   the wrong number, but actually the correct value will be implemented.*/
	while((--d->buffer_size) >= 8)
	    if(!snd_pcm_hw_params_set_buffer_size(d->soundfd, d->hwparams, 1 << d->buffer_size))
		break;
	if(d->buffer_size < 8) {
	    error_error(N_("Unable to set appropriate buffer size"));
	    snd_pcm_close(d->soundfd);
	    return;
	}
    }

    snd_pcm_close(d->soundfd);

    if ((err = snd_pcm_hw_params_get_period_size_min(d->hwparams, &(d->persizemin), 0)) < 0) {
	alsa_error(N_("Unable to get minimal period size"), err);
	return;
    }
    if ((err = snd_pcm_hw_params_get_period_size_max(d->hwparams, &(d->persizemax), 0)) < 0) {
	alsa_error(N_("Unable to get maximal period size"), err);
	return;
    }

    update_periods_range(d);
    update_estimate(d);

    d->address_old = address;
    d->bufsize_old = d->buffer_size;
}
示例#11
0
static gboolean
sndio_open(void *dp)
{
	sndio_in_driver *d = dp;
	char buf[256];

	sio_initpar(&d->par);

	d->hdl = sio_open(NULL, SIO_REC, 0);
	if (d->hdl == NULL) {
		snprintf(buf, sizeof(buf), "can't open sndio rec device");
		goto out;
	}

	d->par.rate = 44100;
	d->par.bits = 16;
	d->par.rchan = 1;
	d->par.appbufsz = 2048;

	if (!sio_setpar(d->hdl, &d->par) || !sio_getpar(d->hdl, &d->par)) {
		snprintf(buf, sizeof(buf), "can't configure sndio device");
		goto out;
	}

	if (d->par.bits == 16) {
		if (d->par.sig) {
			if (d->par.le)
				d->mf = ST_MIXER_FORMAT_S16_LE;
			else
				d->mf = ST_MIXER_FORMAT_S16_BE;
		} else {
			if (d->par.le)
				d->mf = ST_MIXER_FORMAT_U16_LE;
			else
				d->mf = ST_MIXER_FORMAT_U16_BE;
		}
	} else if (d->par.bits == 8) {
		if (d->par.sig)
			d->mf = ST_MIXER_FORMAT_S8;
		else
			d->mf = ST_MIXER_FORMAT_U8;
	} else {
		snprintf(buf, sizeof(buf), "invalid sndio bit-depth");
		goto out;
	}

	if (d->par.rchan == 2) {
		d->mf |= ST_MIXER_FORMAT_STEREO;
	} else if (d->par.rchan != 1) {
		snprintf(buf, sizeof(buf), "invalid sndio channel count");
		goto out;
	}

	d->bufsize = d->par.round;

	d->sndbuf = calloc(1, d->bufsize * d->par.bps * d->par.rchan);

	d->read_trun = 1;
	if (pthread_create(&d->read_tid, NULL, read_thread, d)) {
		snprintf(buf, sizeof(buf), "couldn't spawn reading thread");
		goto out;
	}

	return TRUE;

out:
	error_error(buf);
	sndio_release(dp);
	return FALSE;
}
示例#12
0
static gboolean
alsa_open (void *dp)
{
    alsa_driver * const d = dp;
    int mf, err;

    snd_pcm_format_t pf;

    //    snd_pcm_channel_info_t pcm_info;
    snd_pcm_channel_params_t pp;
    snd_pcm_channel_setup_t setup;

    snd_pcm_channel_flush(d->soundfd, SND_PCM_CHANNEL_PLAYBACK);
    memset(&pp, 0, sizeof(pp));

    err = snd_pcm_open(&(d->soundfd), d->card_number, d->device_number, SND_PCM_OPEN_PLAYBACK);
    if (err != 0) {
	char buf[256];
	g_sprintf(buf, _("Couldn't open ALSA device for sound output (card:%d, device:%d):\n%s"), 
		d->card_number, d->device_number, snd_strerror(err));
	error_error(buf);
	goto out;
    }

    // ---
    // Set non-blocking mode.
    // ---
    //    snd_pcm_nonblock_mode(d->soundfd, 1);

    d->outtime = 0;
    d->bits = 0;
    mf = 0;

    // --
    // Set channel parameters
    // --
    pp.mode = SND_PCM_MODE_BLOCK;
    pp.channel = SND_PCM_CHANNEL_PLAYBACK;
    pp.start_mode = SND_PCM_START_FULL;
    pp.stop_mode = SND_PCM_STOP_ROLLOVER;

    // ---
    // Select audio format
    // ---
    memset(&pf, 0, sizeof(pf));
    pf.interleave = 1;
    if (d->p_resolution == 16) {
      pf.format = SND_PCM_SFMT_S16_LE;
      d->bits = 16;
      mf = ST_MIXER_FORMAT_S16_LE;
    }
    else {
      pf.format = SND_PCM_SFMT_U8;
      d->bits = 8;
      mf = ST_MIXER_FORMAT_S8;
    }

    pf.rate = d->p_mixfreq;
    d->playrate = d->p_mixfreq;

    if(d->p_channels == 2) {
	d->stereo = 1;
	pf.voices = d->p_channels;
	mf |= ST_MIXER_FORMAT_STEREO;
    }
    else {
      pf.voices = d->p_channels;
      d->stereo = 0;
    }
    d->mf = mf;
    memcpy(&pp.format, &pf, sizeof(pf));

    //    pp.buf.block.frag_size = d->p_fragsize * pf.voices * (d->bits / 8);
    pp.buf.block.frag_size = d->p_fragsize;
    pp.buf.block.frags_max = -1;
    pp.buf.block.frags_min = 1;

    err = snd_pcm_channel_params(d->soundfd, &pp);
    if (err < 0) {
      error_error(_("Required output-channel parameters not supported.\n"));
      goto out;
    }

    if (snd_pcm_channel_prepare(d->soundfd, SND_PCM_CHANNEL_PLAYBACK) < 0) {
      error_error(_("Unable to prepare ALSA channel.\n"));
      goto out;
    }

    // ---
    // Get buffering parameters
    // ---
   
    memset(&setup, 0, sizeof(setup));
    setup.mode = SND_PCM_MODE_BLOCK;
    setup.channel = SND_PCM_CHANNEL_PLAYBACK;
    err = snd_pcm_channel_setup(d->soundfd, &setup);
    if (err < 0) {
      error_error(_("Alsa setup error.\n"));
      goto out;
    }

    //    snd_pcm_channel_status(d->soundfd, &pbstat);
    //    d->fragsize = pbstat.fragment_size;

    d->numfrags = setup.buf.block.frags;
    d->fragsize = setup.buf.block.frag_size;
    /*    fprintf(stderr, "Numfrags: %d\n", d->numfrags);
	  fprintf(stderr, "Fragsize: %d\n", d->fragsize); */

    d->sndbuf = calloc(1, d->fragsize);

    if(d->stereo == 1) { 
      d->fragsize /= 2;  
    } 
    if(d->bits == 16) {  
      d->fragsize /= 2;  
    } 
    
    d->polltag = audio_poll_add(snd_pcm_file_descriptor(d->soundfd, SND_PCM_CHANNEL_PLAYBACK), GDK_INPUT_WRITE, alsa_poll_ready_playing, d);
    /*    d->firstpoll = TRUE; */
    d->firstpoll = TRUE;
    d->playtime = 0;

    return TRUE;

  out:
    alsa_release(dp);
    return FALSE;
}
示例#13
0
static gboolean
oss_open (void *dp)
{
    oss_driver * const d = dp;
    int mf;
    int i;
    audio_buf_info info;

    /* O_NONBLOCK is required for the es1370 driver in Linux
       2.2.9, for example. It's open() behaviour is not
       OSS-conformant (though Thomas Sailer says it's okay). */
    if((d->soundfd = open(d->p_devdsp, O_WRONLY | O_NONBLOCK)) < 0) {
	char buf[256];
	g_sprintf(buf, _("Couldn't open %s for sound output:\n%s"), d->p_devdsp, strerror(errno));
	error_error(buf);
	goto out;
    }

    // Clear O_NONBLOCK again
    fcntl(d->soundfd, F_SETFL, 0);

    d->bits = 0;
    mf = 0;
    if(d->p_resolution == 16) {
	if(oss_try_format(d, AFMT_S16_LE)) {
	    d->bits = 16;
	    mf = ST_MIXER_FORMAT_S16_LE;
	} else if(oss_try_format(d, AFMT_S16_BE)) {
	    d->bits = 16;
	    mf = ST_MIXER_FORMAT_S16_BE;
	} else if(oss_try_format(d, AFMT_U16_LE)) {
	    d->bits = 16;
	    mf = ST_MIXER_FORMAT_U16_LE;
	} else if(oss_try_format(d, AFMT_U16_BE)) {
	    d->bits = 16;
	    mf = ST_MIXER_FORMAT_U16_BE;
	}
    }
    if(d->bits != 16) {
	if(oss_try_format(d, AFMT_S8)) {
	    d->bits = 8;
	    mf = ST_MIXER_FORMAT_S8;
	} else if(oss_try_format(d, AFMT_U8)) {
	    d->bits = 8;
	    mf = ST_MIXER_FORMAT_U8;
	} else {
	    error_error(_("Required sound output format not supported.\n"));
	    goto out;
	}
    }

    if(d->p_channels == 2 && oss_try_stereo(d, 1)) {
	d->stereo = 1;
	mf |= ST_MIXER_FORMAT_STEREO;
    } else if(oss_try_stereo(d, 0)) {
	d->stereo = 0;
    }

    d->mf = mf;

    d->playrate = d->p_mixfreq;
    ioctl(d->soundfd, SNDCTL_DSP_SPEED, &d->playrate);
	
    i = 0x00020000 + d->p_fragsize + d->stereo + (d->bits / 8 - 1);
    ioctl(d->soundfd, SNDCTL_DSP_SETFRAGMENT, &i);

    // Find out how many fragments OSS actually uses and how large they are.
    ioctl(d->soundfd, SNDCTL_DSP_GETOSPACE, &info);
    d->fragsize = info.fragsize;
    d->numfrags = info.fragstotal;

    ioctl(d->soundfd, SNDCTL_DSP_GETCAPS, &i);
    d->realtimecaps = i & DSP_CAP_REALTIME;

    d->sndbuf = calloc(1, d->fragsize);

    if(d->stereo == 1) {
	d->fragsize /= 2;
    }
    if(d->bits == 16) {
	d->fragsize /= 2;
    }

    d->polltag = audio_poll_add(d->soundfd, GDK_INPUT_WRITE, oss_poll_ready_playing, d);
    d->firstpoll = TRUE;
    d->playtime = 0;

    return TRUE;

  out:
    oss_release(dp);
    return FALSE;
}
示例#14
0
static gboolean
alsa_open (void *dp)
{
    alsa_driver * const d = dp;
    int mf;

    snd_pcm_format_t pf;
    snd_pcm_capture_info_t pcm_info;
    snd_pcm_capture_params_t pp;
    snd_pcm_capture_status_t pbstat;

    //    int err = snd_pcm_open(&(d->soundfd), d->card_number, d->device_number,
    //         		 	  SND_PCM_OPEN_CAPTURE);
    int err = snd_pcm_open(&(d->soundfd), 0, 0,  SND_PCM_OPEN_CAPTURE);

    if (err != 0) {
	char buf[256];
	g_sprintf(buf, _("Couldn't open ALSA device for sound input (card:%d, device:%d):\n%s"), 
		d->card_number, d->device_number, snd_strerror(err));
	error_error(buf);
	goto out;
    }

    // ---
    // Set non-blocking mode.
    // ---

    snd_pcm_block_mode(d->soundfd, 1);    // enable block mode

    d->bits = 0;
    mf = 0;

    // ---
    // Select audio format
    // ---

    memset(&pf, 0, sizeof(pf));

    if (d->p_resolution == 16) {
      pf.format = SND_PCM_SFMT_S16_LE;
      d->bits = 16;
      mf = ST_MIXER_FORMAT_S16_LE;
    }
      else { 
        pf.format = SND_PCM_SFMT_U8; 
        d->bits = 8; 
        mf = ST_MIXER_FORMAT_S8; 
      } 

/*      if(d->p_channels == 2) { */
/*  	d->stereo = 1; */
/*  	pf.channels = d->p_channels; */
/*  	mf |= ST_MIXER_FORMAT_STEREO; */
/*      } */
/*      else { */
/*        pf.channels = d->p_channels; */
/*        d->stereo = 0; */
/*      } */

    d->stereo = 0;
    pf.channels = 1;

    pf.rate = d->p_mixfreq;
    d->playrate = d->p_mixfreq;
    mf = ST_MIXER_FORMAT_S16_LE;
    d->mf = mf;

    err = snd_pcm_capture_format(d->soundfd, &pf);
    if (err < 0) {
      error_error(_("Required sound output format not supported.\n"));
      goto out;
    }

    snd_pcm_capture_info(d->soundfd, &pcm_info);

    memset(&pp, 0, sizeof(pp));

    pp.fragment_size = d->p_fragsize * pf.channels * d->bits / 8;
    pp.fragments_min = 1;

    err = snd_pcm_capture_params(d->soundfd, &pp);
    if (err < 0) {
      error_error(_("Required sound output parameters not supported.\n"));
      goto out;
    }

    snd_pcm_capture_status(d->soundfd, &pbstat);
    /*    d->numfrags = pbstat.fragments; */
    d->numfrags = 1;
    d->fragsize = pbstat.fragment_size;
	
    d->sndbuf = calloc(1, d->fragsize);

    if(d->stereo == 1) {
      d->fragsize /= 2;
    }
    if(d->bits == 16) {
      d->fragsize /= 2;
    }
    
    d->polltag = gdk_input_add(snd_pcm_file_descriptor(d->soundfd), GDK_INPUT_READ, alsa_poll_ready_sampling, d); 
    //    d->firstpoll = TRUE;
    //    d->playtime = 0;

    return TRUE;

  out:
    alsa_release(dp);
    return FALSE;
}
示例#15
0
static gboolean
alsa_open (void *dp)
{
    alsa_driver * const d = dp;
    int mf;

    snd_pcm_format_t pf;
    snd_pcm_playback_info_t pcm_info;
    snd_pcm_playback_params_t pp;
    snd_pcm_playback_status_t pbstat;

    int err = snd_pcm_open(&(d->soundfd), d->card_number, d->device_number,
         		 	  SND_PCM_OPEN_PLAYBACK);
    if (err != 0) {
	char buf[256];
	g_sprintf(buf, _("Couldn't open ALSA device for sound output (card:%d, device:%d):\n%s"), 
		d->card_number, d->device_number, snd_strerror(err));
	error_error(buf);
	goto out;
    }

    // ---
    // Set non-blocking mode.
    // ---

    snd_pcm_block_mode(d->soundfd, 0);    // enable block mode

    d->outtime = 0;
    d->bits = 0;
    mf = 0;

    // ---
    // Select audio format
    // ---

    memset(&pf, 0, sizeof(pf));

    if (d->p_resolution == 16) {
      pf.format = SND_PCM_SFMT_S16_LE;
      d->bits = 16;
      mf = ST_MIXER_FORMAT_S16_LE;
    }
    else {
      pf.format = SND_PCM_SFMT_U8;
      d->bits = 8;
      mf = ST_MIXER_FORMAT_S8;
    }

    if(d->p_channels == 2) {
	d->stereo = 1;
	pf.channels = d->p_channels;
	mf |= ST_MIXER_FORMAT_STEREO;
    }
    else {
      pf.channels = d->p_channels;
      d->stereo = 0;
    }

    pf.rate = d->p_mixfreq;
    d->playrate = d->p_mixfreq;
    d->mf = mf;

    err = snd_pcm_playback_format(d->soundfd, &pf);
    if (err < 0) {
      error_error(_("Required sound output format not supported.\n"));
      goto out;
    }

    snd_pcm_playback_info(d->soundfd, &pcm_info);

    memset(&pp, 0, sizeof(pp));

    pp.fragment_size = d->p_fragsize * pf.channels * (d->bits / 8);
    pp.fragments_max = 1;
    //    pp.fragments_max = 16pcm_info.buffer_size / pp.fragment_size;
    pp.fragments_room = 1;

    err = snd_pcm_playback_params(d->soundfd, &pp);
    if (err < 0) {
      error_error(_("Required sound output parameters not supported.\n"));
      goto out;
    }

    snd_pcm_playback_status(d->soundfd, &pbstat);
    //    d->numfrags = pbstat.fragments;
    //    d->numfrags = 1;
    d->fragsize = pbstat.fragment_size;
    d->numfrags = 1;
    
    /*    fprintf(stderr, "Numfrags: %d\n", d->numfrags);
	  fprintf(stderr, "Fragsize: %d\n", d->fragsize); */

    d->sndbuf = calloc(1, d->fragsize);

    if(d->stereo == 1) { 
      d->fragsize /= 2;  
    } 
    if(d->bits == 16) {  
      d->fragsize /= 2;  
    } 
    
    d->polltag = audio_poll_add(snd_pcm_file_descriptor(d->soundfd), GDK_INPUT_WRITE, alsa_poll_ready_playing, d);
    /*    d->firstpoll = TRUE; */
    d->firstpoll = TRUE;
    d->playtime = 0;

    return TRUE;

  out:
    alsa_release(dp);
    return FALSE;
}