Exemplo n.º 1
0
static int
setparams(int32 sps, snd_pcm_t *handle)
{
    int err;
    struct snd_pcm_channel_params params;

    memset(&params, 0, sizeof(params));
    params.mode = SND_PCM_MODE_BLOCK;
    params.channel = SND_PCM_CHANNEL_PLAYBACK;
    params.format.format = SND_PCM_SFMT_MU_LAW;
    params.format.voices = 1;
    params.format.rate = 8000;
    if ((err = snd_pcm_plugin_params(handle, &params)) < 0) {
	fprintf(stderr, "Playback parameters error: %s\n", snd_strerror(err));
	return -1;
    }
    memset(&params, 0, sizeof(params));
    params.mode = SND_PCM_MODE_BLOCK;
    params.channel = SND_PCM_CHANNEL_CAPTURE;
    params.format.format = SND_PCM_SFMT_S16_LE;
    params.format.voices = 1;
    params.format.rate = sps;
    if ((err = snd_pcm_plugin_params(handle, &params)) < 0) {
	fprintf(stderr, "Record parameters error: %s\n", snd_strerror(err));
	return -1;
    }
    return 0;
}
Exemplo n.º 2
0
Arquivo: qsa.c Projeto: Atom66/tain335
static int get_formats_qsa(audio_output_t* ao)
{
    qsa_internal_t* userptr;
    int status;
    int it=0;

    userptr=ao->userptr;
    if (userptr!=NULL);
    {
        userptr->cpars.format.rate=ao->rate;
        userptr->cpars.format.voices=ao->channels;
        it=0;
        do {
            if ((format_map[it].qsa_format==0) && (format_map[it].mp_format==0))
            {
                break;
            }
            userptr->cpars.format.format=format_map[it].qsa_format;
            status=snd_pcm_plugin_params(userptr->audio_handle, &userptr->cpars);
            if (status<0)
            {
                it++;
            }
            else
            {
                return format_map[it].mp_format;
            }
        } while(1);
    }

    return 0;
}
Exemplo n.º 3
0
	void OpenAudio()
	{
		int card = -1, dev = 0;

		snd_pcm_channel_info_t pi;
		snd_mixer_group_t group;
		snd_pcm_channel_params_t pp;
		snd_pcm_channel_setup_t setup;

		mixlen = 2*AUDIO_CHANNELS*AUDIO_SAMPLES;
		mixbuf = (uint8_t*)malloc(mixlen);
		if (mixbuf == NULL)
			return;
		memset(mixbuf, 0, mixlen);

		if ((snd_pcm_open_preferred(&pcm_handle, &card, &dev, SND_PCM_OPEN_PLAYBACK)) < 0)
			return;

		memset(&pi, 0, sizeof (pi));
		pi.channel = SND_PCM_CHANNEL_PLAYBACK;
		if ((snd_pcm_plugin_info (pcm_handle, &pi)) < 0)
			return;

		memset(&pp, 0, sizeof (pp));
		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_STOP;

		pp.buf.block.frag_size = pi.max_fragment_size;
		pp.buf.block.frags_max = -1;
		pp.buf.block.frags_min = 1;

		pp.format.interleave = 1;
		pp.format.rate = AUDIO_FREQ;
		pp.format.voices = AUDIO_CHANNELS;
		pp.format.format = SND_PCM_SFMT_S16_LE;

		if ((snd_pcm_plugin_params (pcm_handle, &pp)) < 0)
			return;

		snd_pcm_plugin_prepare(pcm_handle, SND_PCM_CHANNEL_PLAYBACK);

		memset (&setup, 0, sizeof(setup));
		memset (&group, 0, sizeof(group));
		setup.channel = SND_PCM_CHANNEL_PLAYBACK;
		setup.mixer_gid = &group.gid;
		if ((snd_pcm_plugin_setup (pcm_handle, &setup)) < 0)
			return;
		setup.buf.block.frag_size;
		if ((snd_mixer_open(&mixer_handle, card, setup.mixer_device)) < 0)
			return;
		pthread_attr_t attr;
		pthread_attr_init(&attr);
		pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
		pthread_create(&thread_handle, &attr, &BlackberryAudio::staticThreadProc, this);
	}
Exemplo n.º 4
0
static int alsa_init_sound (SINT16 *b)
{
	snd_pcm_channel_params_t params;
	snd_pcm_channel_setup_t setup;
	int err;

	buffer = b;

	if ((err = snd_pcm_open (&pcm_handle, 0, 0, SND_PCM_OPEN_PLAYBACK)) < 0){
		report ("sound_alsa: Error: %s\n", snd_strerror (err));
		return -1;
	}

	report ("ALSA driver written by [email protected].\n");

	memset (&params, 0, sizeof(snd_pcm_channel_params_t));
	params.mode = SND_PCM_MODE_BLOCK;
	params.buf.block.frag_size = FRAGSIZE;
	params.buf.block.frags_min = 1;
	params.buf.block.frags_max = FRAGNUM;

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

	/* Set sound device to 16 bit, 22 kHz mono */

	params.format.interleave = 1;
	params.format.format = SND_PCM_SFMT_S16_LE;
	params.format.rate = 22050;
	params.format.voices = 1;

	if ((err = snd_pcm_plugin_params (pcm_handle, &params)) < 0) {
		report ("sound_alsa: Error: %s\n", snd_strerror (err));
		return -1;
	}

	if (snd_pcm_plugin_prepare (pcm_handle, SND_PCM_CHANNEL_PLAYBACK) < 0) {
		report ("sound_alsa: can't prepare\n");
		return -1;
	}

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

	if (snd_pcm_channel_setup (pcm_handle, &setup) < 0) {
		report ("sound_alsa: can't setup\n");
		return -1;
	}

	pthread_create (&thread, NULL, sound_thread, NULL);
	pthread_detach (thread);

	return 0;
}
Exemplo n.º 5
0
int
main (int argc, char **argv)
{
    int     card = -1;
    int     dev = 0;
    snd_pcm_t *pcm_handle;
    FILE   *file;
    wave_hdr wav_header;
    int     samples;
    int     sample_rate;
    int     sample_channels;
    int     sample_bits;
    char   *sample_buffer;
    int     fragsize = -1;
    int     verbose = 0;

    int     rtn;
    int     final_return_code = -1;
    snd_pcm_channel_info_t pi;
    snd_mixer_t *mixer_handle;
    snd_mixer_group_t group;
    snd_pcm_channel_params_t pp;
    snd_pcm_channel_setup_t setup;
    int     bsize, bytes_read, total_written = 0;
    fd_set  rfds, wfds;
    uint32_t voice_mask[] = { 0, 0, 0, 0 };
    snd_pcm_voice_conversion_t voice_conversion;
    int     voice_override = 0;
    int     num_frags = -1;
    char input_file[PATH_MAX];
    char cwd[PATH_MAX];
    screen_context_t screen_cxt;
    screen_window_t screen_win;
    screen_buffer_t screen_buf;
    int screen_fill_attribs[] = { SCREEN_BLIT_COLOR, COLOR_PURPLE, SCREEN_BLIT_END };
    int screen_dirty[4] = { 0, 0, 1024, 600 }; //start with sane default values

    int idle_mode = SCREEN_IDLE_MODE_KEEP_AWAKE;
    int usage = SCREEN_USAGE_NATIVE;

    if (screen_create_context(&screen_cxt, 0) != 0)
    {
    	return err("failed to create context");
    }

    if (screen_create_window(&screen_win, screen_cxt) != 0)
    {
    	err("failed to create window");
    	goto fail1;
    }

    if (screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_USAGE, &usage) != 0)
    {
    	err("failed to set native usage mode");
    	goto fail2;
    }

    if (screen_create_window_buffers(screen_win, 1) != 0)
    {
    	err("failed to set native usage mode");
    	goto fail2;
    }

    if(screen_get_window_property_pv(screen_win, SCREEN_PROPERTY_RENDER_BUFFERS, (void **)&screen_buf) != 0)
    {
    	err("failed to get screen buffer");
    	goto fail2;
    }

    if (screen_fill(screen_cxt, screen_buf, screen_fill_attribs) != 0) {
    	err("failed to fill the screen");
    	goto fail3;
    }

    if (screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, screen_dirty+2) != 0) {
    	err("failed to get window size");
    	goto fail3;
    }

    if (screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_IDLE_MODE, &idle_mode) != 0)
    {
    	err("failed to set idle mode");
    	goto fail3;
    }

    if (screen_post_window(screen_win, screen_buf, 1, screen_dirty, 0) != 0) {
    	err("failed to post the window");
    	goto fail3;
    }

    if ((rtn = snd_pcm_open_preferred (&pcm_handle, &card, &dev, SND_PCM_OPEN_PLAYBACK)) < 0)
    {
        err ("device open");
        goto fail3;
    }

    getcwd(cwd, PATH_MAX);
    rtn = snprintf(input_file, PATH_MAX, "%s%s", cwd, WAV_RELATIVE_PATH);
    if (rtn > PATH_MAX - 1)
    {
    	err ("File name and path too long");
    	goto fail4;
    }

    if ((file = fopen (input_file, "r")) == 0)
    {
    	err ("File open failed");
    	goto fail4;
    }

    if (check_hdr (file) == -1) {
        err ("check_hdr failed");
        goto fail5;
    }

    samples = find_tag (file, "fmt ");
    fread (&wav_header, sizeof (wav_header), 1, file);
    fseek (file, (samples - sizeof (wave_hdr)), SEEK_CUR);

    sample_rate = ENDIAN_LE32 (wav_header.samples_per_sec);
    sample_channels = ENDIAN_LE16 (wav_header.channels);
    sample_bits = ENDIAN_LE16 (wav_header.bits_per_sample);

    printf ("SampleRate = %d, channels = %d, SampleBits = %d\n", sample_rate, sample_channels,
        sample_bits);

    /* disabling mmap is not actually required in this example but it is included to
     * demonstrate how it is used when it is required.
     */
    if ((rtn = snd_pcm_plugin_set_disable (pcm_handle, PLUGIN_DISABLE_MMAP)) < 0)
    {
        fprintf (stderr, "snd_pcm_plugin_set_disable failed: %s\n", snd_strerror (rtn));
        goto fail5;
    }

    memset (&pi, 0, sizeof (pi));
    pi.channel = SND_PCM_CHANNEL_PLAYBACK;
    if ((rtn = snd_pcm_plugin_info (pcm_handle, &pi)) < 0)
    {
        fprintf (stderr, "snd_pcm_plugin_info failed: %s\n", snd_strerror (rtn));
        goto fail5;
    }

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

    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_STOP;
    pp.buf.block.frag_size = pi.max_fragment_size;

    if (fragsize != -1)
    {
        pp.buf.block.frag_size = fragsize;
    }
    pp.buf.block.frags_max = num_frags;
    pp.buf.block.frags_min = 1;

    pp.format.interleave = 1;
    pp.format.rate = sample_rate;
    pp.format.voices = sample_channels;

    if (ENDIAN_LE16 (wav_header.format_tag) == 6)
        pp.format.format = SND_PCM_SFMT_A_LAW;
    else if (ENDIAN_LE16 (wav_header.format_tag) == 7)
        pp.format.format = SND_PCM_SFMT_MU_LAW;
    else if (sample_bits == 8)
        pp.format.format = SND_PCM_SFMT_U8;
    else if (sample_bits == 24)
        pp.format.format = SND_PCM_SFMT_S24;
    else
        pp.format.format = SND_PCM_SFMT_S16_LE;

    strcpy (pp.sw_mixer_subchn_name, "Wave playback channel");
    if ((rtn = snd_pcm_plugin_params (pcm_handle, &pp)) < 0)
    {
        fprintf (stderr, "snd_pcm_plugin_params failed: %s\n", snd_strerror (rtn));
        goto fail5;
    }

    if ((rtn = snd_pcm_plugin_prepare (pcm_handle, SND_PCM_CHANNEL_PLAYBACK)) < 0) {
        fprintf (stderr, "snd_pcm_plugin_prepare failed: %s\n", snd_strerror (rtn));
        goto fail5;
    }

    if (voice_override)
    {
        snd_pcm_plugin_get_voice_conversion (pcm_handle, SND_PCM_CHANNEL_PLAYBACK,
            &voice_conversion);
        voice_conversion.matrix[0] = voice_mask[0];
        voice_conversion.matrix[1] = voice_mask[1];
        voice_conversion.matrix[2] = voice_mask[2];
        voice_conversion.matrix[3] = voice_mask[3];
        snd_pcm_plugin_set_voice_conversion (pcm_handle, SND_PCM_CHANNEL_PLAYBACK,
            &voice_conversion);
    }

    memset (&setup, 0, sizeof (setup));
    memset (&group, 0, sizeof (group));
    setup.channel = SND_PCM_CHANNEL_PLAYBACK;
    setup.mixer_gid = &group.gid;

    if ((rtn = snd_pcm_plugin_setup (pcm_handle, &setup)) < 0)
    {
        fprintf (stderr, "snd_pcm_plugin_setup failed: %s\n", snd_strerror (rtn));
        goto fail5;
    }

    printf ("Format %s \n", snd_pcm_get_format_name (setup.format.format));
    printf ("Frag Size %d \n", setup.buf.block.frag_size);
    printf ("Total Frags %d \n", setup.buf.block.frags);
    printf ("Rate %d \n", setup.format.rate);
    printf ("Voices %d \n", setup.format.voices);
    bsize = setup.buf.block.frag_size;

    if (group.gid.name[0] == 0)
    {
        fprintf (stderr, "Mixer Pcm Group [%s] Not Set \n", group.gid.name);
        goto fail5;
    }

    printf ("Mixer Pcm Group [%s]\n", group.gid.name);
    if ((rtn = snd_mixer_open (&mixer_handle, card, setup.mixer_device)) < 0)
    {
        fprintf (stderr, "snd_mixer_open failed: %s\n", snd_strerror (rtn));
        goto fail5;
    }

    samples = find_tag (file, "data");
    sample_buffer = malloc (bsize);
    FD_ZERO (&rfds);
    FD_ZERO (&wfds);
    bytes_read = 1;
    while (total_written < samples && bytes_read > 0)
    {
        if (tcgetpgrp (0) == getpid ())
            FD_SET (STDIN_FILENO, &rfds);
        FD_SET (snd_mixer_file_descriptor (mixer_handle), &rfds);
        FD_SET (snd_pcm_file_descriptor (pcm_handle, SND_PCM_CHANNEL_PLAYBACK), &wfds);

        rtn = max (snd_mixer_file_descriptor (mixer_handle),
            snd_pcm_file_descriptor (pcm_handle, SND_PCM_CHANNEL_PLAYBACK));

        if (select (rtn + 1, &rfds, &wfds, NULL, NULL) == -1)
        {
        	err ("select");
        	goto fail6;
        }

        if (FD_ISSET (snd_pcm_file_descriptor (pcm_handle, SND_PCM_CHANNEL_PLAYBACK), &wfds))
        {
            snd_pcm_channel_status_t status;
            int     written = 0;

            if ((bytes_read = fread (sample_buffer, 1, min (samples - total_written, bsize), file)) <= 0)
                continue;
            written = snd_pcm_plugin_write (pcm_handle, sample_buffer, bytes_read);
            if (verbose)
                printf ("bytes written = %d \n", written);

            if (written < bytes_read)
            {
                memset (&status, 0, sizeof (status));
                status.channel = SND_PCM_CHANNEL_PLAYBACK;
                if (snd_pcm_plugin_status (pcm_handle, &status) < 0)
                {
                    fprintf (stderr, "underrun: playback channel status error\n");
                    goto fail6;
                }

                if (status.status == SND_PCM_STATUS_READY ||
                    status.status == SND_PCM_STATUS_UNDERRUN)
                {
                    if (snd_pcm_plugin_prepare (pcm_handle, SND_PCM_CHANNEL_PLAYBACK) < 0)
                    {
                        fprintf (stderr, "underrun: playback channel prepare error\n");
                        goto fail6;
                    }
                }
                if (written < 0)
                    written = 0;
                written += snd_pcm_plugin_write (pcm_handle, sample_buffer + written, bytes_read - written);
            }
            total_written += written;
        }
    }

    bytes_read = snd_pcm_plugin_flush (pcm_handle, SND_PCM_CHANNEL_PLAYBACK);
    final_return_code = 0;

fail6:
    rtn = snd_mixer_close (mixer_handle);
fail5:
    fclose (file);
fail4:
    rtn = snd_pcm_close (pcm_handle);
fail3:
    screen_destroy_buffer(screen_buf);
fail2:
    screen_destroy_window(screen_win);
fail1:
    screen_destroy_context(screen_cxt);
    return final_return_code;
}
Exemplo n.º 6
0
void *Audio_ALSA::open (AudioConfig &cfg, const char *)
{
    AudioConfig tmpCfg;
    int mask, wantedFormat, format;
    int rtn;
    int card = -1, dev = 0;
   
    if (_audioHandle != NULL)
    {
        _errorString = "ERROR: Device already in use";
        return NULL;
    }

    if ((rtn = snd_pcm_open_preferred (&_audioHandle, &card, &dev, SND_PCM_OPEN_PLAYBACK)))
    {
        _errorString = "ERROR: Could not open audio device.";
        goto open_error;
    }
    
    // Transfer input parameters to this object.
    // May later be replaced with driver defaults.
    tmpCfg = cfg;

    snd_pcm_channel_params_t pp;
    snd_pcm_channel_setup_t setup;
 
    snd_pcm_channel_info_t pi;
   
    memset (&pi, 0, sizeof (pi));
    pi.channel = SND_PCM_CHANNEL_PLAYBACK;
    if ((rtn = snd_pcm_plugin_info (_audioHandle, &pi)))
    {
        _errorString = "ALSA: snd_pcm_plugin_info failed.";
        goto open_error;
    }
			
    memset(&pp, 0, sizeof (pp));
	
    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_STOP;
				     
    pp.buf.block.frag_size = pi.max_fragment_size;

    pp.buf.block.frags_max = 1;
    pp.buf.block.frags_min = 1;
   
    pp.format.interleave = 1;
    pp.format.rate = tmpCfg.frequency;
    pp.format.voices = tmpCfg.channels;
   
    // Set sample precision and type of encoding.
    if ( tmpCfg.precision == 8 )
    {
        tmpCfg.encoding = AUDIO_UNSIGNED_PCM;
        pp.format.format = SND_PCM_SFMT_U8;
    }
    if ( tmpCfg.precision == 16 )
    {
        tmpCfg.encoding = AUDIO_SIGNED_PCM;
        pp.format.format = SND_PCM_SFMT_S16_LE;
    }

    if ((rtn = snd_pcm_plugin_params (_audioHandle, &pp)) < 0)
    {
        _errorString = "ALSA: snd_pcm_plugin_params failed.";
        goto open_error;
    }
   
    if ((rtn = snd_pcm_plugin_prepare (_audioHandle, SND_PCM_CHANNEL_PLAYBACK)) < 0)
    {
        _errorString = "ALSA: snd_pcm_plugin_prepare failed.";
        goto open_error;
    }
   
    memset (&setup, 0, sizeof (setup));
    setup.channel = SND_PCM_CHANNEL_PLAYBACK;
    if ((rtn = snd_pcm_plugin_setup (_audioHandle, &setup)) < 0)
    {
        _errorString = "ALSA: snd_pcm_plugin_setup failed.";
        goto open_error;
    }

    tmpCfg.bufSize = setup.buf.block.frag_size;
#ifdef HAVE_EXCEPTIONS
    _sampleBuffer = new(std::nothrow) int_least8_t[tmpCfg.bufSize];
#else
    _sampleBuffer = new int_least8_t[tmpCfg.bufSize];
#endif

    if (!_sampleBuffer)
    {
        _errorString = "AUDIO: Unable to allocate memory for sample buffers.";
        goto open_error;
    }

    // Setup internal Config
    _settings = tmpCfg;
    // Update the users settings
    getConfig (cfg);
    return _sampleBuffer;

open_error:
    if (_audioHandle != NULL)
    {
        close ();
    }

    perror ("ALSA");
return NULL;
}
Exemplo n.º 7
0
static pj_status_t bb10_open_capture (struct bb10_stream *stream,
                                      const pjmedia_aud_param *param)
{
    int ret = 0;
    unsigned int rate;
    unsigned long tmp_buf_size;
    int frame_size;
    snd_pcm_channel_info_t pi;
    snd_mixer_group_t group;
    snd_pcm_channel_params_t pp;
    snd_pcm_channel_setup_t setup;

    if (param->rec_id < 0 || param->rec_id >= stream->af->dev_cnt)
        return PJMEDIA_EAUD_INVDEV;

    PJ_ASSERT_RETURN(param->bits_per_sample == 16, PJMEDIA_EAUD_SAMPFORMAT);

    if ((ret=audio_manager_snd_pcm_open_name(AUDIO_TYPE_VIDEO_CHAT,
                                             &stream->ca_pcm,
                                             &stream->ca_audio_manager_handle,
                                             (char*)"voice",
                                             SND_PCM_OPEN_CAPTURE)) < 0)
    {
	TRACE_((THIS_FILE, "audio_manager_snd_pcm_open_name ret = %d", ret));
	return PJMEDIA_EAUD_SYSERR;
    }
    /* Required call from January 2013 gold OS release */
    snd_pcm_plugin_set_disable (stream->ca_pcm, PLUGIN_DISABLE_MMAP);

    /* Required call from January 2013 gold OS release */
    snd_pcm_plugin_set_enable(stream->ca_pcm, PLUGIN_ROUTING);

    /* sample reads the capabilities of the capture */
    memset (&pi, 0, sizeof (pi));
    pi.channel = SND_PCM_CHANNEL_CAPTURE;
    if ((ret = snd_pcm_plugin_info (stream->ca_pcm, &pi)) < 0) {
        TRACE_((THIS_FILE, "snd_pcm_plugin_info ret = %d", ret));
        return PJMEDIA_EAUD_SYSERR;
    }

    /* Request the VoIP parameters
     * These parameters are different to waverec sample
     */
    memset (&pp, 0, sizeof (pp));
    /* Blocking read */
    pp.mode = SND_PCM_MODE_BLOCK;
    pp.channel = SND_PCM_CHANNEL_CAPTURE;
    pp.start_mode = SND_PCM_START_FULL;
    /* Auto-recover from errors */
    pp.stop_mode = SND_PCM_STOP_ROLLOVER;
    pp.buf.block.frag_size = param->samples_per_frame * param->bits_per_sample / 8;
    /* From January 2013 gold OS release. RIM recommend these for capture */
    pp.buf.block.frags_max = 3;
    pp.buf.block.frags_min = 1;
    pp.format.interleave = 1;
    pp.format.rate = param->clock_rate;
    pp.format.voices = param->channel_count;
    pp.format.format = get_alsa_pcm_fmt(param);

    /* make the request */
    if ((ret = snd_pcm_plugin_params (stream->ca_pcm, &pp)) < 0) {
        TRACE_((THIS_FILE, "snd_pcm_plugin_params ret = %d", ret));
        return PJMEDIA_EAUD_SYSERR;
    }

    /* Again based on the sample */
    memset (&setup, 0, sizeof (setup));
    memset (&group, 0, sizeof (group));
    setup.channel = SND_PCM_CHANNEL_CAPTURE;
    setup.mixer_gid = &group.gid;
    if ((ret = snd_pcm_plugin_setup (stream->ca_pcm, &setup)) < 0) {
        TRACE_((THIS_FILE, "snd_pcm_plugin_setup ret = %d", ret));
        return PJMEDIA_EAUD_SYSERR;
    }

    frame_size = setup.buf.block.frag_size;

    if (group.gid.name[0] == 0) {
    } else {
    }

    frame_size = setup.buf.block.frag_size;
    PJ_UNUSED_ARG(frame_size); /* Warning about unused var */

    /* Set clock rate */
    rate = param->clock_rate;
    stream->ca_frames = (unsigned long) param->samples_per_frame /
			param->channel_count;

    /* Set the sound device buffer size and latency */
    if (param->flags & PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY) {
        tmp_buf_size = rate * param->input_latency_ms / 1000;
    } else {
        tmp_buf_size = rate * PJMEDIA_SND_DEFAULT_REC_LATENCY / 1000;
    }

    stream->param.input_latency_ms = tmp_buf_size * 1000 / rate;

    /* Set our buffer */
    stream->ca_buf_size = stream->ca_frames * param->channel_count *
			  param->bits_per_sample / 8;
    stream->ca_buf = (char *)pj_pool_alloc (stream->pool, stream->ca_buf_size);

    TRACE_((THIS_FILE, "bb10_open_capture: ca_frames = %d clock = %d",
                       stream->ca_frames, param->clock_rate));

    return PJ_SUCCESS;
}
static void playsetup() {

	snd_pcm_channel_setup_t setup;
	//Enabling Echo canceller
	int ret;
	snd_pcm_channel_info_t pi;
	snd_mixer_group_t group;
	snd_pcm_channel_params_t pp;

	//audio routing enabled with AEC
	if ((ret = audio_manager_snd_pcm_open_name(AUDIO_TYPE_VIDEO_CHAT,
			&g_pcm_handle_p, &g_audio_manager_handle_p, (char*) "voice",
			SND_PCM_OPEN_PLAYBACK)) < 0) {
		return;
	}

	snd_pcm_plugin_set_disable(g_pcm_handle_p, PLUGIN_DISABLE_MMAP);
    snd_pcm_plugin_set_enable(g_pcm_handle_p, PLUGIN_ROUTING);


	memset(&pi, 0, sizeof(pi));
	pi.channel = SND_PCM_CHANNEL_PLAYBACK;
	if ((ret = snd_pcm_plugin_info(g_pcm_handle_p, &pi)) < 0) {
		fprintf(stderr, "snd_pcm_plugin_info failed: %s\n", snd_strerror (ret));
		return;
	}

	fprintf(stderr,"PLAY Minimum Rate = %d\n",pi.min_rate);
	// Interestingly on the simulator this returns 4096 but in reality always 170 is the result
	fprintf(stderr,"PLAY Minimum fragment size = %d\n",pi.min_fragment_size);

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

	// Request VoIP compatible capabilities
	// On simulator frag_size is always negotiated to 170
	pp.mode = SND_PCM_MODE_BLOCK;
	pp.channel = SND_PCM_CHANNEL_PLAYBACK;
	//pp.start_mode = SND_PCM_START_DATA;
	pp.stop_mode = SND_PCM_STOP_ROLLOVER;
	pp.start_mode = SND_PCM_START_FULL;
	pp.buf.block.frag_size = PREFERRED_FRAME_SIZE;
	// Increasing this internal buffer count delays write failure in the loop
	pp.buf.block.frags_max = 5;
	pp.buf.block.frags_min = 1;
	pp.format.interleave = 1;
	pp.format.rate = VOIP_SAMPLE_RATE;
	pp.format.voices = 1;
	pp.format.format = SND_PCM_SFMT_S16_LE;




	// Make the calls as per the wave sample
	if ((ret = snd_pcm_plugin_params(g_pcm_handle_p, &pp)) < 0) {
		fprintf(stderr, "pb snd_pcm_plugin_params failed: %s\n", snd_strerror (ret));
		return;
	}

	memset(&setup, 0, sizeof(setup));
	memset(&group, 0, sizeof(group));
	setup.channel = SND_PCM_CHANNEL_PLAYBACK;
	setup.mixer_gid = &group.gid;
	if ((ret = snd_pcm_plugin_setup(g_pcm_handle_p, &setup)) < 0) {
		fprintf(stderr, "snd_pcm_plugin_setup failed: %s\n", snd_strerror (ret));
		return;
	}

	fprintf(stderr,"PLAY frame_size %d \n", setup.buf.block.frag_size);
	fprintf(stderr,"PLAY Rate %d \n", setup.format.rate);
	g_frame_size_p = setup.buf.block.frag_size;

	if (group.gid.name[0] == 0) {
		fprintf(stderr,"FATAL Mixer Pcm Group [%s] Not Set \n", group.gid.name);
		exit (-1);
	}
	printf("Mixer Pcm Group [%s]\n", group.gid.name);
	if ((ret = snd_pcm_plugin_prepare(g_pcm_handle_p, SND_PCM_CHANNEL_PLAYBACK))
			< 0) {
		fprintf(stderr, "snd_pcm_plugin_prepare failed: %s\n", snd_strerror (ret));
	}
}
Exemplo n.º 9
0
static ALCenum qsa_open_capture(ALCdevice* device, const ALCchar* deviceName)
{
    qsa_data *data;
    int card, dev;
    int format=-1;
    int status;

    data=(qsa_data*)calloc(1, sizeof(qsa_data));
    if (data==NULL)
    {
        return ALC_OUT_OF_MEMORY;
    }

    if(!deviceName)
        deviceName = qsaDevice;

    if(strcmp(deviceName, qsaDevice) == 0)
        status = snd_pcm_open_preferred(&data->pcmHandle, &card, &dev, SND_PCM_OPEN_CAPTURE);
    else
    {
        const DevMap *iter;

        if(VECTOR_SIZE(CaptureNameMap) == 0)
            deviceList(SND_PCM_CHANNEL_CAPTURE, &CaptureNameMap);

#define MATCH_DEVNAME(iter) ((iter)->name && strcmp(deviceName, (iter)->name)==0)
        VECTOR_FIND_IF(iter, const DevMap, CaptureNameMap, MATCH_DEVNAME);
#undef MATCH_DEVNAME
        if(iter == VECTOR_ITER_END(CaptureNameMap))
        {
            free(data);
            return ALC_INVALID_DEVICE;
        }

        status = snd_pcm_open(&data->pcmHandle, iter->card, iter->dev, SND_PCM_OPEN_CAPTURE);
    }

    if(status < 0)
    {
        free(data);
        return ALC_INVALID_DEVICE;
    }

    data->audio_fd = snd_pcm_file_descriptor(data->pcmHandle, SND_PCM_CHANNEL_CAPTURE);
    if(data->audio_fd < 0)
    {
        snd_pcm_close(data->pcmHandle);
        free(data);
        return ALC_INVALID_DEVICE;
    }

    al_string_copy_cstr(&device->DeviceName, deviceName);
    device->ExtraData = data;

    switch (device->FmtType)
    {
        case DevFmtByte:
             format=SND_PCM_SFMT_S8;
             break;
        case DevFmtUByte:
             format=SND_PCM_SFMT_U8;
             break;
        case DevFmtShort:
             format=SND_PCM_SFMT_S16_LE;
             break;
        case DevFmtUShort:
             format=SND_PCM_SFMT_U16_LE;
             break;
        case DevFmtInt:
             format=SND_PCM_SFMT_S32_LE;
             break;
        case DevFmtUInt:
             format=SND_PCM_SFMT_U32_LE;
             break;
        case DevFmtFloat:
             format=SND_PCM_SFMT_FLOAT_LE;
             break;
    }

    /* we actually don't want to block on reads */
    snd_pcm_nonblock_mode(data->pcmHandle, 1);
    /* Disable mmap to control data transfer to the audio device */
    snd_pcm_plugin_set_disable(data->pcmHandle, PLUGIN_DISABLE_MMAP);

    /* configure a sound channel */
    memset(&data->cparams, 0, sizeof(data->cparams));
    data->cparams.mode=SND_PCM_MODE_BLOCK;
    data->cparams.channel=SND_PCM_CHANNEL_CAPTURE;
    data->cparams.start_mode=SND_PCM_START_GO;
    data->cparams.stop_mode=SND_PCM_STOP_STOP;

    data->cparams.buf.block.frag_size=device->UpdateSize*
        ChannelsFromDevFmt(device->FmtChans)*BytesFromDevFmt(device->FmtType);
    data->cparams.buf.block.frags_max=device->NumUpdates;
    data->cparams.buf.block.frags_min=device->NumUpdates;

    data->cparams.format.interleave=1;
    data->cparams.format.rate=device->Frequency;
    data->cparams.format.voices=ChannelsFromDevFmt(device->FmtChans);
    data->cparams.format.format=format;

    if(snd_pcm_plugin_params(data->pcmHandle, &data->cparams) < 0)
    {
        snd_pcm_close(data->pcmHandle);
        free(data);
        device->ExtraData=NULL;

        return ALC_INVALID_VALUE;
    }

    return ALC_NO_ERROR;
}
Exemplo n.º 10
0
bool QnxAudioInput::open()
{
    if (!m_format.isValid() || m_format.sampleRate() <= 0) {
        if (!m_format.isValid())
            qWarning("QnxAudioInput: open error, invalid format.");
        else
            qWarning("QnxAudioInput: open error, invalid sample rate (%d).", m_format.sampleRate());

        return false;
    }

    int errorCode = 0;

    int card = 0;
    int device = 0;
    if ((errorCode = snd_pcm_open_preferred(&m_pcmHandle, &card, &device, SND_PCM_OPEN_CAPTURE)) < 0) {
        qWarning("QnxAudioInput: open error, couldn't open card (0x%x)", -errorCode);
        return false;
    }

    // Necessary so that bytesFree() which uses the "free" member of the status struct works
    snd_pcm_plugin_set_disable(m_pcmHandle, PLUGIN_DISABLE_MMAP);

    snd_pcm_channel_info_t info;
    memset(&info, 0, sizeof(info));
    info.channel = SND_PCM_CHANNEL_CAPTURE;
    if ((errorCode = snd_pcm_plugin_info(m_pcmHandle, &info)) < 0) {
        qWarning("QnxAudioInput: open error, couldn't get channel info (0x%x)", -errorCode);
        close();
        return false;
    }

    snd_pcm_channel_params_t params = QnxAudioUtils::formatToChannelParams(m_format, QAudio::AudioInput, info.max_fragment_size);

    if ((errorCode = snd_pcm_plugin_params(m_pcmHandle, &params)) < 0) {
        qWarning("QnxAudioInput: open error, couldn't set channel params (0x%x)", -errorCode);
        close();
        return false;
    }

    if ((errorCode = snd_pcm_plugin_prepare(m_pcmHandle, SND_PCM_CHANNEL_CAPTURE)) < 0) {
        qWarning("QnxAudioInput: open error, couldn't prepare channel (0x%x)", -errorCode);
        close();
        return false;
    }

    snd_pcm_channel_setup_t setup;

    memset(&setup, 0, sizeof(setup));
    setup.channel = SND_PCM_CHANNEL_CAPTURE;
    if ((errorCode = snd_pcm_plugin_setup(m_pcmHandle, &setup)) < 0) {
        qWarning("QnxAudioInput: open error, couldn't get channel setup (0x%x)", -errorCode);
        close();
        return false;
    }

    m_periodSize = qMin(2048, setup.buf.block.frag_size);

    m_clockStamp.restart();
    m_timeStamp.restart();
    m_elapsedTimeOffset = 0;
    m_totalTimeValue = 0;
    m_bytesRead = 0;

    m_pcmNotifier = new QSocketNotifier(snd_pcm_file_descriptor(m_pcmHandle, SND_PCM_CHANNEL_CAPTURE),
                                        QSocketNotifier::Read, this);
    connect(m_pcmNotifier, SIGNAL(activated(int)), SLOT(userFeed()));

    return true;
}
Exemplo n.º 11
0
/* Plays a sound with the Advanced Linux Sound Architecture, ALSA.
   Returns 0 on successful playback, nonzero on error. */
int PlayerALSA(u_int8_t *samples, unsigned int bits, unsigned int channels,
               unsigned int rate, unsigned int bytes)
{
    int i;

    /* ALSA is a bit verbose, and it tends to require
       lots of structures. */
    unsigned int alsa_device = 0, alsa_card = 0;
    char *alsa_card_name;
    snd_ctl_t *alsa_ctl;
    snd_ctl_hw_info_t alsa_hw_info;
    snd_pcm_t *alsa_pcm;
    snd_pcm_channel_params_t alsa_params;
	
    /* Playback status variables. */
    unsigned int position;

    /* Scan for ALSA cards and devices. Each card has an integer ID
       less than snd_cards(). We scan for the first available card
       in order to demonstrate ALSA's organization, but we could
       find the default card and PCM device numbers immediately with
       the snd_defaults_pcm_card(), snd_defaults_pcm_device() functions. */
    alsa_pcm = NULL;
    for (alsa_card = 0; alsa_card < (unsigned)snd_cards(); alsa_card++) {

	/* Try to open this card. */
	if (snd_ctl_open(&alsa_ctl,alsa_card) < 0)
	    continue;
		
	/* Retrieve card info. */
	if (snd_ctl_hw_info(alsa_ctl,&alsa_hw_info) < 0) {
	    snd_ctl_close(alsa_ctl);
	    continue;
	}
		
	snd_ctl_close(alsa_ctl);
		
	/* Find a suitable device on this card. */
	alsa_pcm = NULL;
	for (alsa_device = 0; alsa_device < alsa_hw_info.pcmdevs; alsa_device++) {
	    if (snd_pcm_open(&alsa_pcm,alsa_card,
			     alsa_device,SND_PCM_OPEN_PLAYBACK) < 0) continue;
	    
	    /* Device successfully opened. */
	    break;
	}
		
	if (alsa_pcm != NULL) break;
    }
	
    /* Were we able to open a device? */
    if (alsa_card == (unsigned)snd_cards()) {
	printf("ALSA player: unable to find a configured device.\n");
	return -1;
    }
	
    /* Print info about the device. */
    if (snd_card_get_longname(alsa_card,&alsa_card_name) < 0)
	alsa_card_name = "(unknown)";
    printf("ALSA player: using device %i:%i (%s)\n",
	   alsa_card, alsa_device, alsa_card_name);
	
    /* Configure the device for the loaded sound data. */
    memset(&alsa_params,0,sizeof (alsa_params));
    alsa_params.channel = SND_PCM_CHANNEL_PLAYBACK;

    /* Use stream mode. In this mode, we don't have to give ALSA complete
       blocks; we can send it data as we get it. Block mode is needed for
       mmap() functionality. Unlike OSS, ALSA's mmap() functionality is
       quite reliable, and easily accessible through library functions.
       We won't use it here, though; there's no need. */
    alsa_params.mode = SND_PCM_MODE_STREAM;
    alsa_params.format.interleave = 1;
    
    /* We'll assume little endian samples. You may wish to use the data in
       the GNU C Library's endian.h to support other endiannesses. We're
       ignoring that case for simplicity. */
    if (bits == 8)
	alsa_params.format.format = SND_PCM_SFMT_U8;
    else if (bits == 16)
	alsa_params.format.format = SND_PCM_SFMT_S16_LE;
    else {
	printf("ALSA player: invalid sample size.\n");
	return -1;
    }
    alsa_params.format.rate = rate;
    alsa_params.format.voices = channels;
    alsa_params.start_mode = SND_PCM_START_DATA;
    alsa_params.stop_mode = SND_PCM_STOP_ROLLOVER;
    alsa_params.buf.block.frag_size = 4096;
    alsa_params.buf.block.frags_min = 1;
    alsa_params.buf.block.frags_max = 2;
	
    if ((i = snd_pcm_plugin_params(alsa_pcm,&alsa_params)) < 0) {
	printf("ALSA player: unable to set parameters.\n");
	snd_pcm_close(alsa_pcm);
	return -1;
    }

    if (snd_pcm_plugin_prepare(alsa_pcm, SND_PCM_CHANNEL_PLAYBACK) < 0) {
	printf("ALSA player: unable to prepare playback.\n");
	snd_pcm_close(alsa_pcm);
	return -1;
    }
	
    /* Feed the sound data to ALSA. */
    position = 0;
    while (position < bytes) {
	int written, blocksize;
		
	if (bytes-position < 4096)
	    blocksize = bytes-position;
	else
	    blocksize = 4096;
		
	/* Write to the sound device. */
	written = snd_pcm_plugin_write(alsa_pcm, &samples[position], blocksize);

	/* If ALSA can't take any more data right now, it'll return -EAGAIN.
	   If this were sound code for a game, we'd probably just contine the
	   game loop and try to write data the next time around.
	   In a game, you'd probably also want to put the device in nonblocking
	   mode (see the snd_pcm_nonblock_mode() function). */
	if (written == -EAGAIN) {
	    /* Waste some time. This keeps us from using 100% CPU. */
	    usleep(1000);

	    written = 0;
	} else {
	    if (written < 0) {
		perror("\nALSA player: error writing to sound device");
		snd_pcm_close(alsa_pcm);
		return -1;
	    }
	}

	/* Update the position. */
	position += written;

	/* Print some information. */
	WritePlaybackStatus(position, bytes, channels, bits, rate);
	printf("\r");
	fflush(stdout);
    }

    printf("\n");

    /* Wait until ALSA's internal buffers are empty, then stop playback.
       This will make sure that the entire sound clip has played. */
    snd_pcm_channel_flush(alsa_pcm, SND_PCM_CHANNEL_PLAYBACK);
    snd_pcm_close(alsa_pcm);

    return 0;
}
Exemplo n.º 12
0
static int NTO_OpenAudio(_THIS, SDL_AudioSpec* spec)
{
    int rval;
    int format;
    Uint16 test_format;
    int found;

    audio_handle = NULL;
    this->enabled = 0;

    if (pcm_buf != NULL)
    {
        SDL_FreeAudioMem(pcm_buf); 
        pcm_buf = NULL;
    }

    /* initialize channel transfer parameters to default */
    NTO_InitAudioParams(&cparams);

    /* Open the audio device */
    rval = snd_pcm_open_preferred(&audio_handle, &cardno, &deviceno, OPEN_FLAGS);
    if (rval < 0)
    {
        SDL_SetError("NTO_OpenAudio(): snd_pcm_open failed: %s\n", snd_strerror(rval));
        return (-1);
    }

    if (!NTO_CheckBuggyCards(this, QSA_MMAP_WORKAROUND))
    {
        /* enable count status parameter */
        if ((rval = snd_pcm_plugin_set_disable(audio_handle, PLUGIN_DISABLE_MMAP)) < 0)
        {
            SDL_SetError("snd_pcm_plugin_set_disable failed: %s\n", snd_strerror(rval));
            return (-1);
        }
    }

    /* Try for a closest match on audio format */
    format = 0;
    /* can't use format as SND_PCM_SFMT_U8 = 0 in nto */
    found = 0;

    for (test_format=SDL_FirstAudioFormat(spec->format); !found ;)
    {
        /* if match found set format to equivalent ALSA format */
        switch (test_format)
        {
            case AUDIO_U8:
                           format = SND_PCM_SFMT_U8;
                           found = 1;
                           break;
            case AUDIO_S8:
                           format = SND_PCM_SFMT_S8;
                           found = 1;
                           break;
            case AUDIO_S16LSB:
                           format = SND_PCM_SFMT_S16_LE;
                           found = 1;
                           break;
            case AUDIO_S16MSB:
                           format = SND_PCM_SFMT_S16_BE;
                           found = 1;
                           break;
            case AUDIO_U16LSB:
                           format = SND_PCM_SFMT_U16_LE;
                           found = 1;
                           break;
            case AUDIO_U16MSB:
                           format = SND_PCM_SFMT_U16_BE;
                           found = 1;
                           break;
            default:
                           break;
        }

        if (!found)
        {
            test_format = SDL_NextAudioFormat();
        }
    }

    /* assumes test_format not 0 on success */
    if (test_format == 0)
    {
        SDL_SetError("NTO_OpenAudio(): Couldn't find any hardware audio formats");
        return (-1);
    }

    spec->format = test_format;

    /* Set the audio format */
    cparams.format.format = format;

    /* Set mono or stereo audio (currently only two channels supported) */
    cparams.format.voices = spec->channels;
	
    /* Set rate */
    cparams.format.rate = spec->freq;

    /* Setup the transfer parameters according to cparams */
    rval = snd_pcm_plugin_params(audio_handle, &cparams);
    if (rval < 0)
    {
        SDL_SetError("NTO_OpenAudio(): snd_pcm_channel_params failed: %s\n", snd_strerror(rval));
        return (-1);
    }

    /* Make sure channel is setup right one last time */
    SDL_memset(&csetup, 0x00, sizeof(csetup));
    csetup.channel = SND_PCM_CHANNEL_PLAYBACK;
    if (snd_pcm_plugin_setup(audio_handle, &csetup) < 0)
    {
        SDL_SetError("NTO_OpenAudio(): Unable to setup playback channel\n");
        return -1;
    }


    /* Calculate the final parameters for this audio specification */
    SDL_CalculateAudioSpec(spec);

    pcm_len = spec->size;

    if (pcm_len==0)
    {
        pcm_len = csetup.buf.block.frag_size * spec->channels * (snd_pcm_format_width(format)/8);
    }

    /* Allocate memory to the audio buffer and initialize with silence (Note that
       buffer size must be a multiple of fragment size, so find closest multiple)
    */
    pcm_buf = (Uint8*)SDL_AllocAudioMem(pcm_len);
    if (pcm_buf == NULL)
    {
        SDL_SetError("NTO_OpenAudio(): pcm buffer allocation failed\n");
        return (-1);
    }
    SDL_memset(pcm_buf, spec->silence, pcm_len);

    /* get the file descriptor */
    if ((audio_fd = snd_pcm_file_descriptor(audio_handle, SND_PCM_CHANNEL_PLAYBACK)) < 0)
    {
        SDL_SetError("NTO_OpenAudio(): snd_pcm_file_descriptor failed with error code: %s\n", snd_strerror(rval));
        return (-1);
    }

    /* Trigger audio playback */
    rval = snd_pcm_plugin_prepare(audio_handle, SND_PCM_CHANNEL_PLAYBACK);
    if (rval < 0)
    {
        SDL_SetError("snd_pcm_plugin_prepare failed: %s\n", snd_strerror(rval));
        return (-1);
    }

    this->enabled = 1;

    /* Get the parent process id (we're the parent of the audio thread) */
    parent = getpid();

    /* We're really ready to rock and roll. :-) */
    return (0);
}
Exemplo n.º 13
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);
}
Exemplo n.º 14
0
Arquivo: qsa.c Projeto: Atom66/tain335
static int open_qsa(audio_output_t* ao)
{
    int status;
    int cardno;
    int deviceno;
    int it;
    snd_pcm_t* audio_handle;
    qsa_internal_t* userptr;

    ao->userptr=NULL;

    status=snd_pcm_open_preferred(&audio_handle, &cardno, &deviceno, SND_PCM_OPEN_PLAYBACK);
    if (status<0)
    {
        return FALSE;
    }

    status=snd_pcm_plugin_set_disable(audio_handle, PLUGIN_DISABLE_MMAP);
    if (status<0)
    {
        return FALSE;
    }

    userptr=calloc(1, sizeof(qsa_internal_t));
    if (userptr==NULL)
    {
        return FALSE;
    }
    ao->userptr=userptr;
    userptr->audio_handle=audio_handle;
    userptr->cardno=cardno;
    userptr->deviceno=deviceno;

    memset(&userptr->cpars, 0, sizeof(userptr->cpars));

    userptr->cpars.channel=SND_PCM_CHANNEL_PLAYBACK;
    userptr->cpars.mode=SND_PCM_MODE_BLOCK;
    userptr->cpars.start_mode=SND_PCM_START_DATA;
    userptr->cpars.stop_mode=SND_PCM_STOP_STOP;
    userptr->cpars.format.format=0;
    it=0;
    do {
        if ((format_map[it].qsa_format==0) && (format_map[it].mp_format==0))
        {
            break;
        }
        if (ao->format==format_map[it].mp_format)
        {
            userptr->cpars.format.format=format_map[it].qsa_format;
            break;
        }
        it++;
    } while(1);
    userptr->cpars.format.interleave=1;
    userptr->cpars.format.rate=ao->rate;
    userptr->cpars.format.voices=ao->channels;
    userptr->cpars.buf.block.frag_size=4096;
    userptr->cpars.buf.block.frags_min=8;
    userptr->cpars.buf.block.frags_max=16;

    if ((ao->channels!=-1) && (ao->rate!=-1))
    {
        status=snd_pcm_plugin_params(userptr->audio_handle, &userptr->cpars);
        if (status<0)
        {
            return FALSE;
        }

        status=snd_pcm_plugin_prepare(userptr->audio_handle, SND_PCM_CHANNEL_PLAYBACK);
        if (status<0)
        {
            return FALSE;
        }
    }

    return TRUE;
}
Exemplo n.º 15
0
void *Audio_ALSA::open (AudioConfig &cfg, const char *)
{
    AudioConfig tmpCfg;

    if (_audioHandle != NULL)
    {
        _errorString = "ERROR: Device already in use";
        return NULL;
     }

#ifdef HAVE_ALSA_ASOUNDLIB_H
    snd_pcm_uframes_t    buffer_frames;
    snd_pcm_hw_params_t *hw_params = 0;

    if (snd_pcm_open (&_audioHandle, "default", SND_PCM_STREAM_PLAYBACK, 0))
    {
        _errorString = "ERROR: Could not open audio device.";
        goto open_error;
    }

    // May later be replaced with driver defaults.
    tmpCfg = cfg;

    if (snd_pcm_hw_params_malloc (&hw_params))
    {
        _errorString = "ERROR: could not malloc hwparams.";
        goto open_error;
    }

    if (snd_pcm_hw_params_any (_audioHandle, hw_params))
    {
        _errorString = "ERROR: could not initialize hw params";
        goto open_error;
    }

    if (snd_pcm_hw_params_set_access (_audioHandle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED))
    {
        _errorString = "ERROR: could not set access type";
        goto open_error;
    }

    snd_pcm_format_t alsamode;
    switch (tmpCfg.precision)
    {
    case 8:
        tmpCfg.encoding = AUDIO_UNSIGNED_PCM;
        alsamode = SND_PCM_FORMAT_U8;
        break;
    case 16:
        tmpCfg.encoding = AUDIO_SIGNED_PCM;
        alsamode = SND_PCM_FORMAT_S16;
        break;
    default:
        _errorString = "ERROR: set desired number of bits for audio device.";
        goto open_error;
    }

    if (snd_pcm_hw_params_set_format (_audioHandle, hw_params, alsamode))
    {
        _errorString = "ERROR: could not set sample format";
        goto open_error;
    }

    if (snd_pcm_hw_params_set_channels (_audioHandle, hw_params, tmpCfg.channels))
    {
        _errorString = "ERROR: could not set channel count";
        goto open_error;
    }

    {   // Gentoo bug #98769, comment 4
        unsigned int rate = tmpCfg.frequency;
        if (snd_pcm_hw_params_set_rate_near (_audioHandle, hw_params, &rate, 0))
        {
            _errorString = "ERROR: could not set sample rate";
            goto open_error;
        }
    }

    _alsa_to_frames_divisor = tmpCfg.channels * tmpCfg.precision / 8;
    buffer_frames = 4096;
    snd_pcm_hw_params_set_period_size_near(_audioHandle, hw_params, &buffer_frames, 0);

    if (snd_pcm_hw_params (_audioHandle, hw_params))
    {
        _errorString = "ERROR: could not set hw parameters";
        goto open_error;
    }

    snd_pcm_hw_params_free (hw_params);
    hw_params = 0;

    if (snd_pcm_prepare (_audioHandle))
    {
        _errorString = "ERROR: could not prepare audio interface for use";
        goto open_error;
    }

    tmpCfg.bufSize = buffer_frames * _alsa_to_frames_divisor;					
#else // HAVE_ALSA_ASOUNDLIB_H
    // Obsolete interface
    int mask, wantedFormat, format;
    int rtn;
    int card = -1, dev = 0;
   
    if ((rtn = snd_pcm_open_preferred (&_audioHandle, &card, &dev, SND_PCM_OPEN_PLAYBACK)))
    {
        _errorString = "ERROR: Could not open audio device.";
        goto open_error;
    }
    
    // Transfer input parameters to this object.
    // May later be replaced with driver defaults.
    tmpCfg = cfg;

    snd_pcm_channel_params_t pp;
    snd_pcm_channel_setup_t setup;
 
    snd_pcm_channel_info_t pi;
   
    memset (&pi, 0, sizeof (pi));
    pi.channel = SND_PCM_CHANNEL_PLAYBACK;
    if ((rtn = snd_pcm_plugin_info (_audioHandle, &pi)))
    {
        _errorString = "ALSA: snd_pcm_plugin_info failed.";
        goto open_error;
    }
			
    memset(&pp, 0, sizeof (pp));
	
    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_STOP;
				     
    pp.buf.block.frag_size = pi.max_fragment_size;

    pp.buf.block.frags_max = 1;
    pp.buf.block.frags_min = 1;
   
    pp.format.interleave = 1;
    pp.format.rate = tmpCfg.frequency;
    pp.format.voices = tmpCfg.channels;
   
    // Set sample precision and type of encoding.
    if ( tmpCfg.precision == 8 )
    {
        tmpCfg.encoding = AUDIO_UNSIGNED_PCM;
        pp.format.format = SND_PCM_SFMT_U8;
    }
    if ( tmpCfg.precision == 16 )
    {
        tmpCfg.encoding = AUDIO_SIGNED_PCM;
        pp.format.format = SND_PCM_SFMT_S16_LE;
    }

    if ((rtn = snd_pcm_plugin_params (_audioHandle, &pp)) < 0)
    {
        _errorString = "ALSA: snd_pcm_plugin_params failed.";
        goto open_error;
    }
   
    if ((rtn = snd_pcm_plugin_prepare (_audioHandle, SND_PCM_CHANNEL_PLAYBACK)) < 0)
    {
        _errorString = "ALSA: snd_pcm_plugin_prepare failed.";
        goto open_error;
    }
   
    memset (&setup, 0, sizeof (setup));
    setup.channel = SND_PCM_CHANNEL_PLAYBACK;
    if ((rtn = snd_pcm_plugin_setup (_audioHandle, &setup)) < 0)
    {
        _errorString = "ALSA: snd_pcm_plugin_setup failed.";
        goto open_error;
    }

    tmpCfg.bufSize = setup.buf.block.frag_size;
#endif
    
#ifdef HAVE_EXCEPTIONS
    _sampleBuffer = new(std::nothrow) int_least8_t[tmpCfg.bufSize];
#else
    _sampleBuffer = new int_least8_t[tmpCfg.bufSize];
#endif

    if (!_sampleBuffer)
    {
        _errorString = "AUDIO: Unable to allocate memory for sample buffers.";
        goto open_error;
    }

    // Setup internal Config
    _settings = tmpCfg;
    // Update the users settings
    getConfig (cfg);
    return _sampleBuffer;

open_error:
#ifdef HAVE_ALSA_ASOUNDLIB_H
    if (hw_params)
        snd_pcm_hw_params_free (hw_params);
#endif
    if (_audioHandle != NULL)
        close ();
    perror ("ALSA");
    return NULL;
}
Exemplo n.º 16
0
static ALCboolean qsa_reset_playback(ALCdevice* device)
{
    qsa_data* data=(qsa_data*)device->ExtraData;
    int32_t format=-1;

    switch(device->FmtType)
    {
        case DevFmtByte:
             format=SND_PCM_SFMT_S8;
             break;
        case DevFmtUByte:
             format=SND_PCM_SFMT_U8;
             break;
        case DevFmtShort:
             format=SND_PCM_SFMT_S16_LE;
             break;
        case DevFmtUShort:
             format=SND_PCM_SFMT_U16_LE;
             break;
        case DevFmtInt:
             format=SND_PCM_SFMT_S32_LE;
             break;
        case DevFmtUInt:
             format=SND_PCM_SFMT_U32_LE;
             break;
        case DevFmtFloat:
             format=SND_PCM_SFMT_FLOAT_LE;
             break;
    }

    /* we actually don't want to block on writes */
    snd_pcm_nonblock_mode(data->pcmHandle, 1);
    /* Disable mmap to control data transfer to the audio device */
    snd_pcm_plugin_set_disable(data->pcmHandle, PLUGIN_DISABLE_MMAP);
    snd_pcm_plugin_set_disable(data->pcmHandle, PLUGIN_DISABLE_BUFFER_PARTIAL_BLOCKS);

    // configure a sound channel
    memset(&data->cparams, 0, sizeof(data->cparams));
    data->cparams.channel=SND_PCM_CHANNEL_PLAYBACK;
    data->cparams.mode=SND_PCM_MODE_BLOCK;
    data->cparams.start_mode=SND_PCM_START_FULL;
    data->cparams.stop_mode=SND_PCM_STOP_STOP;

    data->cparams.buf.block.frag_size=device->UpdateSize*
        ChannelsFromDevFmt(device->FmtChans)*BytesFromDevFmt(device->FmtType);
    data->cparams.buf.block.frags_max=device->NumUpdates;
    data->cparams.buf.block.frags_min=device->NumUpdates;

    data->cparams.format.interleave=1;
    data->cparams.format.rate=device->Frequency;
    data->cparams.format.voices=ChannelsFromDevFmt(device->FmtChans);
    data->cparams.format.format=format;

    if ((snd_pcm_plugin_params(data->pcmHandle, &data->cparams))<0)
    {
        int original_rate=data->cparams.format.rate;
        int original_voices=data->cparams.format.voices;
        int original_format=data->cparams.format.format;
        int it;
        int jt;

        for (it=0; it<1; it++)
        {
            /* Check for second pass */
            if (it==1)
            {
                original_rate=ratelist[0].rate;
                original_voices=channellist[0].channels;
                original_format=formatlist[0].format;
            }

            do {
                /* At first downgrade sample format */
                jt=0;
                do {
                    if (formatlist[jt].format==data->cparams.format.format)
                    {
                        data->cparams.format.format=formatlist[jt+1].format;
                        break;
                    }
                    if (formatlist[jt].format==0)
                    {
                        data->cparams.format.format=0;
                        break;
                    }
                    jt++;
                } while(1);

                if (data->cparams.format.format==0)
                {
                    data->cparams.format.format=original_format;

                    /* At secod downgrade sample rate */
                    jt=0;
                    do {
                        if (ratelist[jt].rate==data->cparams.format.rate)
                        {
                            data->cparams.format.rate=ratelist[jt+1].rate;
                            break;
                        }
                        if (ratelist[jt].rate==0)
                        {
                            data->cparams.format.rate=0;
                            break;
                        }
                        jt++;
                    } while(1);

                    if (data->cparams.format.rate==0)
                    {
                        data->cparams.format.rate=original_rate;
                        data->cparams.format.format=original_format;

                        /* At third downgrade channels number */
                        jt=0;
                        do {
                            if(channellist[jt].channels==data->cparams.format.voices)
                            {
                                data->cparams.format.voices=channellist[jt+1].channels;
                                break;
                            }
                            if (channellist[jt].channels==0)
                            {
                                data->cparams.format.voices=0;
                                break;
                            }
                           jt++;
                        } while(1);
                    }

                    if (data->cparams.format.voices==0)
                    {
                        break;
                    }
                }

                data->cparams.buf.block.frag_size=device->UpdateSize*
                    data->cparams.format.voices*
                    snd_pcm_format_width(data->cparams.format.format)/8;
                data->cparams.buf.block.frags_max=device->NumUpdates;
                data->cparams.buf.block.frags_min=device->NumUpdates;
                if ((snd_pcm_plugin_params(data->pcmHandle, &data->cparams))<0)
                {
                    continue;
                }
                else
                {
                    break;
                }
            } while(1);

            if (data->cparams.format.voices!=0)
            {
                break;
            }
        }

        if (data->cparams.format.voices==0)
        {
            return ALC_FALSE;
        }
    }

    if ((snd_pcm_plugin_prepare(data->pcmHandle, SND_PCM_CHANNEL_PLAYBACK))<0)
    {
        return ALC_FALSE;
    }

    memset(&data->csetup, 0, sizeof(data->csetup));
    data->csetup.channel=SND_PCM_CHANNEL_PLAYBACK;
    if (snd_pcm_plugin_setup(data->pcmHandle, &data->csetup)<0)
    {
        return ALC_FALSE;
    }

    /* now fill back to the our AL device */
    device->Frequency=data->cparams.format.rate;

    switch (data->cparams.format.voices)
    {
        case 1:
             device->FmtChans=DevFmtMono;
             break;
        case 2:
             device->FmtChans=DevFmtStereo;
             break;
        case 4:
             device->FmtChans=DevFmtQuad;
             break;
        case 6:
             device->FmtChans=DevFmtX51;
             break;
        case 7:
             device->FmtChans=DevFmtX61;
             break;
        case 8:
             device->FmtChans=DevFmtX71;
             break;
        default:
             device->FmtChans=DevFmtMono;
             break;
    }

    switch (data->cparams.format.format)
    {
        case SND_PCM_SFMT_S8:
             device->FmtType=DevFmtByte;
             break;
        case SND_PCM_SFMT_U8:
             device->FmtType=DevFmtUByte;
             break;
        case SND_PCM_SFMT_S16_LE:
             device->FmtType=DevFmtShort;
             break;
        case SND_PCM_SFMT_U16_LE:
             device->FmtType=DevFmtUShort;
             break;
        case SND_PCM_SFMT_S32_LE:
             device->FmtType=DevFmtInt;
             break;
        case SND_PCM_SFMT_U32_LE:
             device->FmtType=DevFmtUInt;
             break;
        case SND_PCM_SFMT_FLOAT_LE:
             device->FmtType=DevFmtFloat;
             break;
        default:
             device->FmtType=DevFmtShort;
             break;
    }

    SetDefaultChannelOrder(device);

    device->UpdateSize=data->csetup.buf.block.frag_size/
        (ChannelsFromDevFmt(device->FmtChans)*BytesFromDevFmt(device->FmtType));
    device->NumUpdates=data->csetup.buf.block.frags;

    data->size=data->csetup.buf.block.frag_size;
    data->buffer=malloc(data->size);
    if (!data->buffer)
    {
        return ALC_FALSE;
    }

    return ALC_TRUE;
}
Exemplo n.º 17
0
/* public methods (static but exported through the sysdep_dsp or plugin
   struct) */
static void *alsa_dsp_create(const void *flags)
{
	int i, j;
//	audio_buf_info info;
	struct alsa_dsp_priv_data *priv = NULL;
	struct sysdep_dsp_struct *dsp = NULL;
	const struct sysdep_dsp_create_params *params = flags;
	const char *device = params->device;
	int err;
	int bytespersample;

	fprintf(stderr,"info: dsp_create called\n");
   
	/* allocate the dsp struct */
	if (!(dsp = calloc(1, sizeof(struct sysdep_dsp_struct))))
	{
		fprintf(stderr,
			"error: malloc failed for struct sysdep_dsp_struct\n");
		return NULL;
	}
   
	/* alloc private data */
	if(!(priv = calloc(1, sizeof(struct alsa_dsp_priv_data))))
	{
		fprintf(stderr,
			"error: malloc failed for struct dsp_priv_data\n");
		alsa_dsp_destroy(dsp);
		return NULL;
	}
   
	/* fill in the functions and some data */
	dsp->_priv = priv;
	dsp->get_freespace = alsa_dsp_get_freespace;
	dsp->write = alsa_dsp_write;
	dsp->destroy = alsa_dsp_destroy;
	dsp->hw_info.type = params->type;
	dsp->hw_info.samplerate = params->samplerate;

	priv->audio_dev.bMute = 0;
	priv->audio_dev.m_AudioHandle = NULL;
	priv->audio_dev.m_MixerHandle = NULL;
	priv->audio_dev.m_Acard = 0;
	priv->audio_dev.m_Adevice = 0;


	if (preferred_device)
	{	
 		if((err = snd_pcm_open_preferred(&(priv->audio_dev.m_AudioHandle), &priv->audio_dev.m_Acard,
                                       &priv->audio_dev.m_Adevice, SND_PCM_OPEN_PLAYBACK)) < 0)
    	{
			fprintf(stderr,"info: snd_pcm_open_preferred failed: %s \n", snd_strerror(err));
    	            alsa_dsp_destroy(dsp);
			return NULL;
    	}
	}
	else
	{
		fprintf(stderr,"info: audio is using primary device\n");
		if((err = snd_pcm_open(&(priv->audio_dev.m_AudioHandle), 0, 0, SND_PCM_OPEN_PLAYBACK)) < 0)
		{
			fprintf(stderr,"info: snd_pcm_open failed: %s \n", snd_strerror(err));
			alsa_dsp_destroy(dsp);
			return NULL;
		}
	}
	
	memset (&(priv->audio_dev.m_Achaninfo), 0, sizeof (priv->audio_dev.m_Achaninfo));
	priv->audio_dev.m_Achaninfo.channel = SND_PCM_CHANNEL_PLAYBACK;
	if ((err = snd_pcm_plugin_info (priv->audio_dev.m_AudioHandle, &(priv->audio_dev.m_Achaninfo))) < 0)
	{
		fprintf (stderr, "info: snd_pcm_plugin_info failed: %s\n", snd_strerror (err));
		alsa_dsp_destroy(dsp);
		return NULL;
	}

	//needed to enable the count status parameter, mmap plugin disables this
	if((err = snd_plugin_set_disable(priv->audio_dev.m_AudioHandle, PLUGIN_DISABLE_MMAP)) < 0)
	{
		fprintf (stderr, "info: snd_plugin_set_disable failed: %s\n", snd_strerror (err));
		alsa_dsp_destroy(dsp);
		return NULL;
	}

	/* calculate and set the fragsize & number of frags */
	/* fragsize (as power of 2) */
	i = 8;
	if (dsp->hw_info.type & SYSDEP_DSP_16BIT) i++;
	if (dsp->hw_info.type & SYSDEP_DSP_STEREO) i++;
	i += dsp->hw_info.samplerate / 22000;

	/* number of frags */
	j = ((dsp->hw_info.samplerate * alsa_dsp_bytes_per_sample[dsp->hw_info.type] *
		params->bufsize) / (0x01 << i)) + 1;

	bytespersample=1;
//	dsp->hw_info.type &= ~SYSDEP_DSP_16BIT;
//	dsp->hw_info.type &= ~SYSDEP_DSP_STEREO;
	if (dsp->hw_info.type & SYSDEP_DSP_16BIT) bytespersample++;
	if (dsp->hw_info.type & SYSDEP_DSP_STEREO) bytespersample <<= 1;
	
	memset( &(priv->audio_dev.m_Aparams), 0, sizeof(priv->audio_dev.m_Aparams));
	priv->audio_dev.m_Aparams.mode = SND_PCM_MODE_BLOCK;
	priv->audio_dev.m_Aparams.channel = SND_PCM_CHANNEL_PLAYBACK;
	priv->audio_dev.m_Aparams.start_mode = SND_PCM_START_FULL;
	priv->audio_dev.m_Aparams.stop_mode = SND_PCM_STOP_ROLLOVER;
#if 0
	priv->audio_dev.m_Aparams.buf.stream.queue_size = 512 * bytespersample;
	priv->audio_dev.m_Aparams.buf.stream.fill = SND_PCM_FILL_SILENCE;
	priv->audio_dev.m_Aparams.buf.stream.max_fill = 512 * bytespersample;
#endif
        priv->audio_dev.m_Aparams.format.interleave = 1;
        priv->audio_dev.m_Aparams.format.rate = dsp->hw_info.samplerate;
        priv->audio_dev.m_Aparams.format.voices = (dsp->hw_info.type & SYSDEP_DSP_STEREO) ? 2 : 1;

	priv->audio_dev.m_Aparams.buf.block.frag_size = 1000;
	priv->audio_dev.m_Aparams.buf.block.frags_min = 1;
	priv->audio_dev.m_Aparams.buf.block.frags_max = 5;

        priv->audio_dev.m_BytesPerSample = bytespersample;
        priv->audio_dev.m_Aparams.format.format = 
#ifdef LSB_FIRST
				(dsp->hw_info.type & SYSDEP_DSP_16BIT) ? SND_PCM_SFMT_S16_LE : SND_PCM_SFMT_U8; 
#else
				(dsp->hw_info.type & SYSDEP_DSP_16BIT) ? SND_PCM_SFMT_S16_BE : SND_PCM_SFMT_U8;
#endif

	if ((err = snd_pcm_plugin_params (priv->audio_dev.m_AudioHandle, &(priv->audio_dev.m_Aparams))) < 0)
	{
		fprintf (stderr, "info: snd_pcm_plugin_params failed: %s\n", snd_strerror (err));
		alsa_dsp_destroy(dsp);
		return NULL;
	}

	if ((err = snd_pcm_plugin_prepare (priv->audio_dev.m_AudioHandle, SND_PCM_CHANNEL_PLAYBACK)) < 0)
	{
		fprintf (stderr, "warning: snd_pcm_plugin_prepare failed: %s\n", snd_strerror (err));
	}

	memset (&(priv->audio_dev.m_Asetup), 0, sizeof (priv->audio_dev.m_Asetup));
	priv->audio_dev.m_Asetup.channel = SND_PCM_CHANNEL_PLAYBACK;
	if ((err = snd_pcm_plugin_setup (priv->audio_dev.m_AudioHandle, &(priv->audio_dev.m_Asetup))) < 0)
	{
		fprintf (stderr, "warning: snd_pcm_plugin_setup failed: %s\n", snd_strerror (err));
		alsa_dsp_destroy(dsp);
		return NULL;
	}
	
	memset (&(priv->audio_dev.m_Astatus), 0, sizeof (priv->audio_dev.m_Astatus));
	priv->audio_dev.m_Astatus.channel = SND_PCM_CHANNEL_PLAYBACK;
	if ((err = snd_pcm_plugin_status (priv->audio_dev.m_AudioHandle, &(priv->audio_dev.m_Astatus))) < 0)
	{
		fprintf (stderr, "warning: snd_pcm_plugin_status failed: %s\n", snd_strerror (err));
        }
	dsp->hw_info.bufsize = priv->audio_dev.m_Asetup.buf.stream.queue_size  
	             		/ alsa_dsp_bytes_per_sample[dsp->hw_info.type];
#if 0
	if ((err=snd_pcm_nonblock_mode(priv->audio_dev.m_AudioHandle, 1))<0)
	{
		fprintf(stderr, "error: error with non block mode: %s\n", snd_strerror (err));
	}
#endif
	return dsp;
}
Exemplo n.º 18
0
static int
QSA_OpenDevice(_THIS, const char *devname, int iscapture)
{
    int status = 0;
    int format = 0;
    SDL_AudioFormat test_format = 0;
    int found = 0;
    snd_pcm_channel_setup_t csetup;
    snd_pcm_channel_params_t cparams;

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

    /* Initialize channel transfer parameters to default */
    QSA_InitAudioParams(&cparams);

    /* Initialize channel direction: capture or playback */
    this->hidden->iscapture = iscapture;

    /* Find deviceid and cardid by device name for playback */
    if ((!this->hidden->iscapture) && (devname != NULL)) {
        uint32_t device;
        int32_t status;

        /* Search in the playback devices */
        device = 0;
        do {
            status = SDL_strcmp(qsa_playback_device[device].name, devname);
            if (status == 0) {
                /* Found requested device */
                this->hidden->deviceno = qsa_playback_device[device].deviceno;
                this->hidden->cardno = qsa_playback_device[device].cardno;
                break;
            }
            device++;
            if (device >= qsa_playback_devices) {
                QSA_CloseDevice(this);
                return SDL_SetError("No such playback device");
            }
        } while (1);
    }

    /* Find deviceid and cardid by device name for capture */
    if ((this->hidden->iscapture) && (devname != NULL)) {
        /* Search in the capture devices */
        uint32_t device;
        int32_t status;

        /* Searching in the playback devices */
        device = 0;
        do {
            status = SDL_strcmp(qsa_capture_device[device].name, devname);
            if (status == 0) {
                /* Found requested device */
                this->hidden->deviceno = qsa_capture_device[device].deviceno;
                this->hidden->cardno = qsa_capture_device[device].cardno;
                break;
            }
            device++;
            if (device >= qsa_capture_devices) {
                QSA_CloseDevice(this);
                return SDL_SetError("No such capture device");
            }
        } while (1);
    }

    /* Check if SDL requested default audio device */
    if (devname == NULL) {
        /* Open system default audio device */
        if (!this->hidden->iscapture) {
            status = snd_pcm_open_preferred(&this->hidden->audio_handle,
                                            &this->hidden->cardno,
                                            &this->hidden->deviceno,
                                            SND_PCM_OPEN_PLAYBACK);
        } else {
            status = snd_pcm_open_preferred(&this->hidden->audio_handle,
                                            &this->hidden->cardno,
                                            &this->hidden->deviceno,
                                            SND_PCM_OPEN_CAPTURE);
        }
    } else {
        /* Open requested audio device */
        if (!this->hidden->iscapture) {
            status =
                snd_pcm_open(&this->hidden->audio_handle,
                             this->hidden->cardno, this->hidden->deviceno,
                             SND_PCM_OPEN_PLAYBACK);
        } else {
            status =
                snd_pcm_open(&this->hidden->audio_handle,
                             this->hidden->cardno, this->hidden->deviceno,
                             SND_PCM_OPEN_CAPTURE);
        }
    }

    /* Check if requested device is opened */
    if (status < 0) {
        this->hidden->audio_handle = NULL;
        QSA_CloseDevice(this);
        return QSA_SetError("snd_pcm_open", status);
    }

    if (!QSA_CheckBuggyCards(this, QSA_MMAP_WORKAROUND)) {
        /* Disable QSA MMAP plugin for buggy audio drivers */
        status =
            snd_pcm_plugin_set_disable(this->hidden->audio_handle,
                                       PLUGIN_DISABLE_MMAP);
        if (status < 0) {
            QSA_CloseDevice(this);
            return QSA_SetError("snd_pcm_plugin_set_disable", status);
        }
    }

    /* Try for a closest match on audio format */
    format = 0;
    /* can't use format as SND_PCM_SFMT_U8 = 0 in qsa */
    found = 0;

    for (test_format = SDL_FirstAudioFormat(this->spec.format); !found;) {
        /* if match found set format to equivalent QSA format */
        switch (test_format) {
        case AUDIO_U8:
            {
                format = SND_PCM_SFMT_U8;
                found = 1;
            }
            break;
        case AUDIO_S8:
            {
                format = SND_PCM_SFMT_S8;
                found = 1;
            }
            break;
        case AUDIO_S16LSB:
            {
                format = SND_PCM_SFMT_S16_LE;
                found = 1;
            }
            break;
        case AUDIO_S16MSB:
            {
                format = SND_PCM_SFMT_S16_BE;
                found = 1;
            }
            break;
        case AUDIO_U16LSB:
            {
                format = SND_PCM_SFMT_U16_LE;
                found = 1;
            }
            break;
        case AUDIO_U16MSB:
            {
                format = SND_PCM_SFMT_U16_BE;
                found = 1;
            }
            break;
        case AUDIO_S32LSB:
            {
                format = SND_PCM_SFMT_S32_LE;
                found = 1;
            }
            break;
        case AUDIO_S32MSB:
            {
                format = SND_PCM_SFMT_S32_BE;
                found = 1;
            }
            break;
        case AUDIO_F32LSB:
            {
                format = SND_PCM_SFMT_FLOAT_LE;
                found = 1;
            }
            break;
        case AUDIO_F32MSB:
            {
                format = SND_PCM_SFMT_FLOAT_BE;
                found = 1;
            }
            break;
        default:
            {
                break;
            }
        }

        if (!found) {
            test_format = SDL_NextAudioFormat();
        }
    }

    /* assumes test_format not 0 on success */
    if (test_format == 0) {
        QSA_CloseDevice(this);
        return SDL_SetError("QSA: Couldn't find any hardware audio formats");
    }

    this->spec.format = test_format;

    /* Set the audio format */
    cparams.format.format = format;

    /* Set mono/stereo/4ch/6ch/8ch audio */
    cparams.format.voices = this->spec.channels;

    /* Set rate */
    cparams.format.rate = this->spec.freq;

    /* Setup the transfer parameters according to cparams */
    status = snd_pcm_plugin_params(this->hidden->audio_handle, &cparams);
    if (status < 0) {
        QSA_CloseDevice(this);
        return QSA_SetError("snd_pcm_channel_params", status);
    }

    /* Make sure channel is setup right one last time */
    SDL_memset(&csetup, 0, sizeof(csetup));
    if (!this->hidden->iscapture) {
        csetup.channel = SND_PCM_CHANNEL_PLAYBACK;
    } else {
        csetup.channel = SND_PCM_CHANNEL_CAPTURE;
    }

    /* Setup an audio channel */
    if (snd_pcm_plugin_setup(this->hidden->audio_handle, &csetup) < 0) {
        QSA_CloseDevice(this);
        return SDL_SetError("QSA: Unable to setup channel");
    }

    /* Calculate the final parameters for this audio specification */
    SDL_CalculateAudioSpec(&this->spec);

    this->hidden->pcm_len = this->spec.size;

    if (this->hidden->pcm_len == 0) {
        this->hidden->pcm_len =
            csetup.buf.block.frag_size * this->spec.channels *
            (snd_pcm_format_width(format) / 8);
    }

    /*
     * Allocate memory to the audio buffer and initialize with silence
     *  (Note that buffer size must be a multiple of fragment size, so find
     *  closest multiple)
     */
    this->hidden->pcm_buf =
        (Uint8 *) SDL_AllocAudioMem(this->hidden->pcm_len);
    if (this->hidden->pcm_buf == NULL) {
        QSA_CloseDevice(this);
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden->pcm_buf, this->spec.silence,
               this->hidden->pcm_len);

    /* get the file descriptor */
    if (!this->hidden->iscapture) {
        this->hidden->audio_fd =
            snd_pcm_file_descriptor(this->hidden->audio_handle,
                                    SND_PCM_CHANNEL_PLAYBACK);
    } else {
        this->hidden->audio_fd =
            snd_pcm_file_descriptor(this->hidden->audio_handle,
                                    SND_PCM_CHANNEL_CAPTURE);
    }

    if (this->hidden->audio_fd < 0) {
        QSA_CloseDevice(this);
        return QSA_SetError("snd_pcm_file_descriptor", status);
    }

    /* Prepare an audio channel */
    if (!this->hidden->iscapture) {
        /* Prepare audio playback */
        status =
            snd_pcm_plugin_prepare(this->hidden->audio_handle,
                                   SND_PCM_CHANNEL_PLAYBACK);
    } else {
        /* Prepare audio capture */
        status =
            snd_pcm_plugin_prepare(this->hidden->audio_handle,
                                   SND_PCM_CHANNEL_CAPTURE);
    }

    if (status < 0) {
        QSA_CloseDevice(this);
        return QSA_SetError("snd_pcm_plugin_prepare", status);
    }

    /* We're really ready to rock and roll. :-) */
    return 0;
}
Exemplo n.º 19
0
/*
 * General setup of the libasound audio mixer and pcm components.
 * Some of the settings are based on the format of the wav data.
 */
int
setup_snd(const char * name)
{
    int fragsize = -1;
    int num_frags = -1;
    int rtn;
    char *dev_name;

    if (NULL == name) {
        dev_name = "pcmPreferred";
    } else {
        dev_name = (char *) name;
    }

    if ((rtn = snd_pcm_open_name(&pcm_handle, dev_name, SND_PCM_OPEN_PLAYBACK)) < 0) {
        snprintf(msg, MSG_SIZE, "snd_pcm_open_name failed: %s\n", snd_strerror(rtn));
        show_dialog_message(msg);
        return FAILURE;
    }

    if ((rtn = snd_pcm_info(pcm_handle, &info)) < 0) {
        snprintf(msg, MSG_SIZE, "snd_pcm_info failed: %s\n", snd_strerror(rtn));
        goto setup_failure;
    }
    card = info.card;

    /* disabling mmap is not actually required in this example but it is included to
     * demonstrate how it is used when it is required.
     */
    if ((rtn = snd_pcm_plugin_set_disable(pcm_handle, PLUGIN_DISABLE_MMAP)) < 0) {
        snprintf(msg, MSG_SIZE, "snd_pcm_plugin_set_disable failed: %s\n", snd_strerror(rtn));
        goto setup_failure;
    }

    memset(&pi, 0, sizeof(pi));
    pi.channel = SND_PCM_CHANNEL_PLAYBACK;
    if ((rtn = snd_pcm_plugin_info(pcm_handle, &pi)) < 0) {
        snprintf(msg, MSG_SIZE, "snd_pcm_plugin_info failed: %s\n", snd_strerror(rtn));
        goto setup_failure;
    }

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

    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_STOP;
    pp.buf.block.frag_size = pi.max_fragment_size;

    if (fragsize != -1) {
        pp.buf.block.frag_size = fragsize;
    }

    pp.buf.block.frags_max = num_frags;
    pp.buf.block.frags_min = 1;

    pp.format.interleave = 1;
    pp.format.rate = sample_rate;
    pp.format.voices = sample_channels;

    if (ENDIAN_LE16(wav_header.format_tag) == 6)
        pp.format.format = SND_PCM_SFMT_A_LAW;
    else if (ENDIAN_LE16(wav_header.format_tag) == 7)
        pp.format.format = SND_PCM_SFMT_MU_LAW;
    else if (sample_bits == 8)
        pp.format.format = SND_PCM_SFMT_U8;
    else if (sample_bits == 24)
        pp.format.format = SND_PCM_SFMT_S24;
    else
        pp.format.format = SND_PCM_SFMT_S16_LE;

    strcpy(pp.sw_mixer_subchn_name, "Wave playback channel");
    if ((rtn = snd_pcm_plugin_params(pcm_handle, &pp)) < 0) {
        snprintf(msg, MSG_SIZE, "snd_pcm_plugin_params failed: %s\n", snd_strerror(rtn));
        goto setup_failure;
    }

    if ((rtn = snd_pcm_plugin_prepare(pcm_handle, SND_PCM_CHANNEL_PLAYBACK)) < 0) {
        snprintf(msg, MSG_SIZE, "snd_pcm_plugin_prepare failed: %s\n", snd_strerror(rtn));
        goto setup_failure;
    }

    memset(&setup, 0, sizeof(setup));
    memset(&group, 0, sizeof(group));
    setup.channel = SND_PCM_CHANNEL_PLAYBACK;
    setup.mixer_gid = &group.gid;

    if ((rtn = snd_pcm_plugin_setup(pcm_handle, &setup)) < 0) {
        snprintf(msg, MSG_SIZE, "snd_pcm_plugin_setup failed: %s\n", snd_strerror(rtn));
        goto setup_failure;
    }

    if (group.gid.name[0] == 0) {
        snprintf(msg, MSG_SIZE, "Mixer Pcm Group [%s] Not Set \n", group.gid.name);
        goto setup_failure;
    }

    if ((rtn = snd_mixer_open(&mixer_handle, card, setup.mixer_device)) < 0) {
        snprintf(msg, MSG_SIZE, "snd_mixer_open failed: %s\n", snd_strerror(rtn));
        goto setup_failure;
    }

    char tmp[MSG_SIZE];
    snprintf(msg, MSG_SIZE, "Format %s \n", snd_pcm_get_format_name(setup.format.format));
    snprintf(tmp, MSG_SIZE, "Frag Size %d \n", setup.buf.block.frag_size);
    strlcat(msg, tmp, MSG_SIZE);
    snprintf(tmp, MSG_SIZE, "Total Frags %d \n", setup.buf.block.frags);
    strlcat(msg, tmp, MSG_SIZE);
    snprintf(tmp, MSG_SIZE, "Rate %d \n", setup.format.rate);
    strlcat(msg, tmp, MSG_SIZE);
    snprintf(tmp, MSG_SIZE, "Voices %d \n", setup.format.voices);
    strlcat(msg, tmp, MSG_SIZE);
    snprintf(tmp, MSG_SIZE, "Mixer Pcm Group [%s]\n", group.gid.name);
    strlcat(msg, tmp, MSG_SIZE);
    show_dialog_message(msg);

    return SUCCESS;

setup_failure:
    show_dialog_message(msg);
    snd_pcm_close(pcm_handle);
    return FAILURE;
}
static void capturesetup() {

	snd_pcm_channel_setup_t setup;
	int ret;
	snd_pcm_channel_info_t pi;
	snd_mixer_group_t group;
	snd_pcm_channel_params_t pp;
	int card = setup.mixer_card;


	if ((ret = audio_manager_snd_pcm_open_name(AUDIO_TYPE_VIDEO_CHAT, &g_pcm_handle_c,
			&g_audio_manager_handle_c, (char*) "voice", SND_PCM_OPEN_CAPTURE)) < 0) {

		return;
	}

	snd_pcm_plugin_set_disable(g_pcm_handle_c, PLUGIN_DISABLE_MMAP);
	snd_pcm_plugin_set_enable(g_pcm_handle_c, PLUGIN_ROUTING);

	// sample reads the capabilities of the capture
	memset(&pi, 0, sizeof(pi));
	pi.channel = SND_PCM_CHANNEL_CAPTURE;
	if ((ret = snd_pcm_plugin_info(g_pcm_handle_c, &pi)) < 0) {
		fprintf(stderr, "snd_pcm_plugin_info failed: %s\n", snd_strerror (ret));
		return;
	}

	fprintf(stderr,"CAPTURE Minimum Rate = %d\n",pi.min_rate);

	// Request the VoIP parameters
	// These parameters are different to waverec sample
	memset(&pp, 0, sizeof(pp));
	fprintf(stderr,"CAPTURE Minimum fragment size = %d\n",pi.min_fragment_size);
	// Blocking read
	pp.mode = SND_PCM_MODE_BLOCK;
	pp.channel = SND_PCM_CHANNEL_CAPTURE;
	//pp.start_mode = SND_PCM_START_DATA;
	// Auto-recover from errors
	pp.stop_mode = SND_PCM_STOP_ROLLOVER;
	pp.start_mode = SND_PCM_START_DATA;
	pp.buf.block.frag_size = PREFERRED_FRAME_SIZE;
	pp.buf.block.frags_max = 3;
	pp.buf.block.frags_min = 1;
	pp.format.interleave = 1;
	pp.format.rate = VOIP_SAMPLE_RATE;
	pp.format.voices = 1;
	pp.format.format = SND_PCM_SFMT_S16_LE;
	// make the request
	if ((ret = snd_pcm_plugin_params(g_pcm_handle_c, &pp)) < 0) {
		fprintf(stderr, "ca snd_pcm_plugin_params failed: %s\n", snd_strerror (ret));
		return;
	}

	// Again based on the sample
	memset(&setup, 0, sizeof(setup));
	memset(&group, 0, sizeof(group));
	setup.channel = SND_PCM_CHANNEL_CAPTURE;
	setup.mixer_gid = &group.gid;
	if ((ret = snd_pcm_plugin_setup(g_pcm_handle_c, &setup)) < 0) {
		fprintf(stderr, "snd_pcm_plugin_setup failed: %s\n", snd_strerror (ret));
		return;
	}
	// On the simulator at least, our requested capabilities are accepted.
	fprintf(stderr,"CAPTURE Format %s card = %d\n", snd_pcm_get_format_name (setup.format.format),card);
	fprintf(stderr,"CAPTURE Rate %d \n", setup.format.rate);
	g_frame_size_c = setup.buf.block.frag_size;

	if (group.gid.name[0] == 0) {
		printf("Mixer Pcm Group [%s] Not Set \n", group.gid.name);
		printf("***>>>> Input Gain Controls Disabled <<<<*** \n");
	} else {
		printf("Mixer Pcm Group [%s]\n", group.gid.name);
	}


	g_frame_size_c = setup.buf.block.frag_size;
	fprintf(stderr, "CAPTURE frame_size = %d\n", g_frame_size_c);

	// Sample calls prepare()
	if ((ret = snd_pcm_plugin_prepare(g_pcm_handle_c, SND_PCM_CHANNEL_CAPTURE))
			< 0) {
		fprintf(stderr, "snd_pcm_plugin_prepare failed: %s\n", snd_strerror (ret));
	}
}
Exemplo n.º 21
0
Error AudioDriverBB10::init(const char *p_name) {

	active = false;
	thread_exited = false;
	exit_thread = false;
	pcm_open = false;
	samples_in = NULL;
	samples_out = NULL;

	mix_rate = 44100;
	speaker_mode = SPEAKER_MODE_STEREO;

	char *dev_name;
	if (p_name == NULL) {
		dev_name = "pcmPreferred";
	} else {
		dev_name = (char *)p_name;
	}
	printf("******** reconnecting to device %s\n", dev_name);
	int ret = snd_pcm_open_name(&pcm_handle, dev_name, SND_PCM_OPEN_PLAYBACK);
	ERR_FAIL_COND_V(ret < 0, FAILED);
	pcm_open = true;

	snd_pcm_channel_info_t cinfo;
	zeromem(&cinfo, sizeof(cinfo));
	cinfo.channel = SND_PCM_CHANNEL_PLAYBACK;
	snd_pcm_plugin_info(pcm_handle, &cinfo);

	printf("rates %i, %i, %i, %i, %i\n", cinfo.rates, cinfo.rates & SND_PCM_RATE_44100, cinfo.rates & SND_PCM_RATE_32000, cinfo.rates & SND_PCM_RATE_22050, cinfo.max_rate);

	mix_rate = cinfo.max_rate;

	printf("formats %i, %i, %i\n", cinfo.formats, cinfo.formats & SND_PCM_FMT_S16_BE, cinfo.formats & SND_PCM_FMT_S16_LE);
	ERR_FAIL_COND_V(!(cinfo.formats & SND_PCM_FMT_S16_LE), FAILED);

	printf("voices %i\n", cinfo.max_voices);
	speaker_mode = SPEAKER_MODE_STEREO;

	snd_pcm_channel_params_t cp;
	zeromem(&cp, sizeof(cp));
	cp.mode = SND_PCM_MODE_BLOCK;
	cp.channel = SND_PCM_CHANNEL_PLAYBACK;
	cp.start_mode = SND_PCM_START_DATA;
	cp.stop_mode = SND_PCM_STOP_STOP;
	//cp.buf.block.frag_size = cinfo.max_fragment_size;
	cp.buf.block.frag_size = 512;
	cp.buf.block.frags_max = 1;
	cp.buf.block.frags_min = 1;
	cp.format.interleave = 1;
	cp.format.rate = mix_rate;
	cp.format.voices = speaker_mode;
	cp.format.format = SND_PCM_SFMT_S16_LE;

	ret = snd_pcm_plugin_params(pcm_handle, &cp);
	printf("ret is %i, %i\n", ret, cp.why_failed);
	ERR_FAIL_COND_V(ret < 0, FAILED);

	ret = snd_pcm_plugin_prepare(pcm_handle, SND_PCM_CHANNEL_PLAYBACK);
	ERR_FAIL_COND_V(ret < 0, FAILED);

	snd_mixer_group_t group;
	zeromem(&group, sizeof(group));
	snd_pcm_channel_setup_t setup;
	zeromem(&setup, sizeof(setup));
	setup.channel = SND_PCM_CHANNEL_PLAYBACK;
	setup.mode = SND_PCM_MODE_BLOCK;
	setup.mixer_gid = &group.gid;
	ret = snd_pcm_plugin_setup(pcm_handle, &setup);
	ERR_FAIL_COND_V(ret < 0, FAILED);

	pcm_frag_size = setup.buf.block.frag_size;
	pcm_max_frags = 1;

	sample_buf_count = pcm_frag_size * pcm_max_frags / 2;
	printf("sample count %i, %i, %i\n", sample_buf_count, pcm_frag_size, pcm_max_frags);
	samples_in = memnew_arr(int32_t, sample_buf_count);
	samples_out = memnew_arr(int16_t, sample_buf_count);

	thread = Thread::create(AudioDriverBB10::thread_func, this);

	return OK;
};
Exemplo n.º 22
0
static pj_status_t bb10_open_playback (struct bb10_stream *stream,
                                       const pjmedia_aud_param *param)
{
    int ret = 0;
    snd_pcm_channel_info_t pi;
    snd_pcm_channel_setup_t setup;
    snd_mixer_group_t group;
    snd_pcm_channel_params_t pp;
    unsigned int rate;
    unsigned long tmp_buf_size;

    if (param->play_id < 0 || param->play_id >= stream->af->dev_cnt) {
        return PJMEDIA_EAUD_INVDEV;
    }

    PJ_ASSERT_RETURN(param->bits_per_sample == 16, PJMEDIA_EAUD_SAMPFORMAT);

    /* Use the bb10 audio manager API to open as opposed to QNX core audio
     * Echo cancellation built in
     */
    if ((ret = audio_manager_snd_pcm_open_name(
	    AUDIO_TYPE_VIDEO_CHAT,
            &stream->pb_pcm, &stream->pb_audio_manager_handle,
            (char*)"voice",
            SND_PCM_OPEN_PLAYBACK)) < 0)
    {
        TRACE_((THIS_FILE, "audio_manager_snd_pcm_open_name ret = %d", ret));
        return PJMEDIA_EAUD_SYSERR;
    }

    /* Required call from January 2013 gold OS release */
    snd_pcm_plugin_set_disable(stream->pb_pcm, PLUGIN_DISABLE_MMAP);

    /* Required call from January 2013 gold OS release */
    snd_pcm_plugin_set_enable(stream->pb_pcm, PLUGIN_ROUTING);

    memset (&pi, 0, sizeof (pi));
    pi.channel = SND_PCM_CHANNEL_PLAYBACK;
    if ((ret = snd_pcm_plugin_info (stream->pb_pcm, &pi)) < 0) {
	TRACE_((THIS_FILE, "snd_pcm_plugin_info ret = %d", ret));
	return PJMEDIA_EAUD_SYSERR;
    }

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

    /* Request VoIP compatible capabilities */
    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;
    pp.buf.block.frag_size = param->samples_per_frame * param->bits_per_sample / 8;
    /* RIM recommends maximum of 5 */
    pp.buf.block.frags_max = 5;
    pp.buf.block.frags_min = 1;
    pp.format.interleave = 1;
    pp.format.rate = param->clock_rate;
    pp.format.voices = param->channel_count;
    pp.format.format = get_alsa_pcm_fmt(param);

    /* Make the calls as per the wave sample */
    if ((ret = snd_pcm_plugin_params (stream->pb_pcm, &pp)) < 0) {
        TRACE_((THIS_FILE, "snd_pcm_plugin_params ret = %d", ret));
        return PJMEDIA_EAUD_SYSERR;
    }

    memset (&setup, 0, sizeof (setup));
    memset (&group, 0, sizeof (group));
    setup.channel = SND_PCM_CHANNEL_PLAYBACK;
    setup.mixer_gid = &group.gid;

    if ((ret = snd_pcm_plugin_setup (stream->pb_pcm, &setup)) < 0) {
        TRACE_((THIS_FILE, "snd_pcm_plugin_setup ret = %d", ret));
        return PJMEDIA_EAUD_SYSERR;
    }

    if (group.gid.name[0] == 0) {
        return PJMEDIA_EAUD_SYSERR;
    }

    rate = param->clock_rate;
    /* Set the sound device buffer size and latency */
    if (param->flags & PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY) {
        tmp_buf_size = rate * param->output_latency_ms / 1000;
    } else {
	tmp_buf_size = rate * PJMEDIA_SND_DEFAULT_PLAY_LATENCY / 1000;
    }
    /* Set period size to samples_per_frame frames. */
    stream->pb_frames = param->samples_per_frame / param->channel_count;
    stream->param.output_latency_ms = tmp_buf_size * 1000 / rate;

    /* Set our buffer */
    stream->pb_buf_size = stream->pb_frames * param->channel_count *
                          param->bits_per_sample / 8;
    stream->pb_buf = (char *) pj_pool_alloc(stream->pool, stream->pb_buf_size);

    TRACE_((THIS_FILE, "bb10_open_playback: pb_frames = %d clock = %d",
                       stream->pb_frames, param->clock_rate));

    return PJ_SUCCESS;
}
Exemplo n.º 23
0
static pj_status_t bb10_open_playback (struct bb10_stream *stream,
                                       const pjmedia_aud_param *param)
{
    int card = -1;
    int dev = 0;
    int ret = 0;
    snd_pcm_channel_info_t pi;
    snd_pcm_channel_setup_t setup;
    snd_mixer_group_t group;
    snd_pcm_channel_params_t pp;
    unsigned int rate;
    unsigned long tmp_buf_size;
    unsigned int handle;

    if (param->play_id < 0 || param->play_id >= stream->af->dev_cnt) {
        return PJMEDIA_EAUD_INVDEV;
    }

#if PJ_BBSDK_VER >= 0x100006
    if ((ret = audio_manager_snd_pcm_open_name(AUDIO_TYPE_VOICE,
                                               &stream->pb_pcm, &handle,
                                               "/dev/snd/voicep",
                                               SND_PCM_OPEN_PLAYBACK)) < 0)
    {
        TRACE_((THIS_FILE, "audio_manager_snd_pcm_open_name ret = %d", ret));
        return PJMEDIA_EAUD_SYSERR;
    }

#else
    if ((ret = snd_pcm_open_preferred (&stream->pb_pcm, &card, &dev,
                                       SND_PCM_OPEN_PLAYBACK)) < 0)
    {
        TRACE_((THIS_FILE, "snd_pcm_open_preferred ret = %d", ret));
        return PJMEDIA_EAUD_SYSERR;
    }
#endif

    /* TODO PJ_ZERO */
    memset (&pi, 0, sizeof (pi));
    pi.channel = SND_PCM_CHANNEL_PLAYBACK;
    if ((ret = snd_pcm_plugin_info (stream->pb_pcm, &pi)) < 0) {
        TRACE_((THIS_FILE, "snd_pcm_plugin_info ret = %d", ret));
        return PJMEDIA_EAUD_SYSERR;
    }

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

    /* Request VoIP compatible capabilities
     * On simulator frag_size is always negotiated to 170
     */
    pp.mode = SND_PCM_MODE_BLOCK;
    pp.channel = SND_PCM_CHANNEL_PLAYBACK;
    pp.start_mode = SND_PCM_START_DATA;
    pp.stop_mode = SND_PCM_STOP_ROLLOVER;
    /* HARD CODE for the time being PJMEDIA expects 640 for 16khz */
    pp.buf.block.frag_size = PREFERRED_FRAME_SIZE*2;
    /* Increasing this internal buffer count delays write failure in the loop */
    pp.buf.block.frags_max = 4;
    pp.buf.block.frags_min = 1;
    pp.format.interleave = 1;
    /* HARD CODE for the time being PJMEDIA expects 16khz */
    PJ_TODO(REMOVE_SAMPLE_RATE_HARD_CODE);
    pj_assert(param->clock_rate == VOIP_SAMPLE_RATE * 2);
    pp.format.rate = VOIP_SAMPLE_RATE*2;
    pp.format.voices = 1;
    pp.format.format = SND_PCM_SFMT_S16_LE;

    /* Make the calls as per the wave sample */
    if ((ret = snd_pcm_plugin_params (stream->pb_pcm, &pp)) < 0) {
        TRACE_((THIS_FILE, "snd_pcm_plugin_params ret = %d", ret));
        return PJMEDIA_EAUD_SYSERR;
    }

    memset (&setup, 0, sizeof (setup));
    memset (&group, 0, sizeof (group));
    setup.channel = SND_PCM_CHANNEL_PLAYBACK;
    setup.mixer_gid = &group.gid;

    if ((ret = snd_pcm_plugin_setup (stream->pb_pcm, &setup)) < 0) {
        TRACE_((THIS_FILE, "snd_pcm_plugin_setup ret = %d", ret));
        return PJMEDIA_EAUD_SYSERR;
    }

    if (group.gid.name[0] == 0) {
        return PJMEDIA_EAUD_SYSERR;
    }

    rate = param->clock_rate;
    /* Set the sound device buffer size and latency */
    if (param->flags & PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY) {
        tmp_buf_size = (rate / 1000) * param->output_latency_ms;
    } else {
	tmp_buf_size = (rate / 1000) * PJMEDIA_SND_DEFAULT_PLAY_LATENCY;
    }
    /* Set period size to samples_per_frame frames. */
    stream->pb_frames = param->samples_per_frame;
    stream->param.output_latency_ms = tmp_buf_size / (rate / 1000);

    /* Set our buffer */
    stream->pb_buf_size = stream->pb_frames * param->channel_count *
                          (param->bits_per_sample/8);
    stream->pb_buf = (char *) pj_pool_alloc(stream->pool, stream->pb_buf_size);

    TRACE_((THIS_FILE, "bb10_open_playback: pb_frames = %d clock = %d",
                       stream->pb_frames, param->clock_rate));

    return PJ_SUCCESS;
}
Exemplo n.º 24
0
cst_audiodev *audio_open_alsa(int sps, int channels, cst_audiofmt fmt)
{
    snd_pcm_channel_info_t pinfo;
    snd_pcm_channel_params_t params;
    snd_pcm_channel_setup_t setup;
    snd_pcm_t *pcm;
    cst_audiodev *ad;
    int err;

#ifdef __QNXNTO__
    if (snd_pcm_open_preferred(&pcm,&alsa_card,&alsa_device,SND_PCM_OPEN_PLAYBACK) < 0)
    {
	cst_errmsg("alsa_audio: failed to open audio device\n");
	cst_error();
    }
    if (snd_pcm_plugin_set_disable(pcm,PLUGIN_DISABLE_MMAP) < 0)
    {
	cst_errmsg("alsa_audio: failed to disable mmap\n");
	snd_pcm_close(pcm);
	cst_error();
    }
#else
    if (snd_pcm_open(&pcm,alsa_card,alsa_device,SND_PCM_OPEN_PLAYBACK) < 0)
    {
	cst_errmsg("alsa_audio: failed to open audio device\n");
	cst_error();
    }
#endif


    memset(&pinfo, 0, sizeof(pinfo));
    memset(&params, 0, sizeof(params));
    memset(&setup, 0, sizeof(setup));

    pinfo.channel = SND_PCM_CHANNEL_PLAYBACK;
    snd_pcm_plugin_info(pcm,&pinfo);

    params.mode = SND_PCM_MODE_BLOCK;
    params.channel = SND_PCM_CHANNEL_PLAYBACK;
    params.start_mode = SND_PCM_START_DATA;
    params.stop_mode = SND_PCM_STOP_STOP;

    params.buf.block.frag_size = pinfo.max_fragment_size;
    params.buf.block.frags_max = 1;
    params.buf.block.frags_min = 1;
    
    params.format.interleave = 1;
    params.format.rate = sps;
    params.format.voices = channels;

    switch (fmt)
    {
    case CST_AUDIO_LINEAR16:
	if (CST_LITTLE_ENDIAN)
	    params.format.format = SND_PCM_SFMT_S16_LE;
	else
	    params.format.format = SND_PCM_SFMT_S16_BE;
	break;
    case CST_AUDIO_LINEAR8:
	params.format.format = SND_PCM_SFMT_U8;
	break;
    case CST_AUDIO_MULAW:
	params.format.format = SND_PCM_SFMT_MU_LAW;
	break;
    }

    if((err = snd_pcm_plugin_params(pcm,&params)) < 0)
    {
	cst_errmsg("alsa_audio params setting failed: %s\n",snd_strerror(err));
	snd_pcm_close(pcm);	
	cst_error();
    }
    if((err = snd_pcm_plugin_setup(pcm,SND_PCM_CHANNEL_PLAYBACK)) > 0) {
	cst_errmsg("alsa_audio sound prepare setting failed: %s\n",snd_strerror(err));
	snd_pcm_close(pcm);
	cst_error();
    }
    if((err = snd_pcm_plugin_prepare(pcm,SND_PCM_CHANNEL_PLAYBACK)) > 0) {
	cst_errmsg("alsa_audio sound prepare setting failed: %s\n",snd_strerror(err));
	snd_pcm_close(pcm);
	cst_error();
    }

    pinfo.channel = SND_PCM_CHANNEL_PLAYBACK;
    snd_pcm_plugin_info(pcm,&pinfo);

    ad = cst_alloc(cst_audiodev, 1);
    ad->platform_data = pcm;
    ad->sps = ad->real_sps = sps;
    ad->channels = ad->real_channels = channels;
    ad->fmt = ad->real_fmt = fmt;

    return ad;
}
Exemplo n.º 25
0
static pj_status_t bb10_open_capture (struct bb10_stream *stream,
                                      const pjmedia_aud_param *param)
{
    int ret = 0;
    unsigned int rate;
    unsigned long tmp_buf_size;
    int card = -1;
    int dev = 0;
    int frame_size;
    snd_pcm_channel_info_t pi;
    snd_mixer_group_t group;
    snd_pcm_channel_params_t pp;
    snd_pcm_channel_setup_t setup;
    unsigned int handle;

    if (param->rec_id < 0 || param->rec_id >= stream->af->dev_cnt)
        return PJMEDIA_EAUD_INVDEV;

#if PJ_BBSDK_VER >= 0x100006
    if ((ret = audio_manager_snd_pcm_open_name(AUDIO_TYPE_VOICE,
                                               &stream->ca_pcm,
                                               &handle,
                                               "/dev/snd/voicec",
                                               SND_PCM_OPEN_CAPTURE)) < 0)
    {
	TRACE_((THIS_FILE, "audio_manager_snd_pcm_open_name ret = %d", ret));
	return PJMEDIA_EAUD_SYSERR;
    }
#else
    /* BB10 Audio init here (not prepare) */
    PJ_UNUSED_ARG(handle);
    if ((ret = snd_pcm_open_preferred (&stream->ca_pcm, &card, &dev,
                                       SND_PCM_OPEN_CAPTURE)) < 0)
    {
        TRACE_((THIS_FILE, "snd_pcm_open_preferred ret = %d", ret));
        return PJMEDIA_EAUD_SYSERR;
    }
#endif

    /* sample reads the capabilities of the capture */
    memset (&pi, 0, sizeof (pi));
    pi.channel = SND_PCM_CHANNEL_CAPTURE;
    if ((ret = snd_pcm_plugin_info (stream->ca_pcm, &pi)) < 0) {
        TRACE_((THIS_FILE, "snd_pcm_plugin_info ret = %d", ret));
        return PJMEDIA_EAUD_SYSERR;
    }

    /* Request the VoIP parameters
     * These parameters are different to waverec sample
     */
    memset (&pp, 0, sizeof (pp));
    /* Blocking read */
    pp.mode = SND_PCM_MODE_BLOCK;
    pp.channel = SND_PCM_CHANNEL_CAPTURE;
    pp.start_mode = SND_PCM_START_DATA;
    /* Auto-recover from errors */
    pp.stop_mode = SND_PCM_STOP_ROLLOVER;
    /* HARD CODE for the time being PJMEDIA expects 640 for 16khz */
    pp.buf.block.frag_size = PREFERRED_FRAME_SIZE*2;
    /* Not applicable for capture hence -1 */
    pp.buf.block.frags_max = -1;
    pp.buf.block.frags_min = 1;
    pp.format.interleave = 1;
    /* HARD CODE for the time being PJMEDIA expects 16khz */
    PJ_TODO(REMOVE_SAMPLE_RATE_HARD_CODE);
    pj_assert(param->clock_rate == VOIP_SAMPLE_RATE * 2);
    pp.format.rate = VOIP_SAMPLE_RATE*2;
    pp.format.voices = 1;
    pp.format.format = SND_PCM_SFMT_S16_LE;

    /* make the request */
    if ((ret = snd_pcm_plugin_params (stream->ca_pcm, &pp)) < 0) {
        TRACE_((THIS_FILE, "snd_pcm_plugin_params ret = %d", ret));
        return PJMEDIA_EAUD_SYSERR;
    }

    /* Again based on the sample */
    memset (&setup, 0, sizeof (setup));
    memset (&group, 0, sizeof (group));
    setup.channel = SND_PCM_CHANNEL_CAPTURE;
    setup.mixer_gid = &group.gid;
    if ((ret = snd_pcm_plugin_setup (stream->ca_pcm, &setup)) < 0) {
        TRACE_((THIS_FILE, "snd_pcm_plugin_setup ret = %d", ret));
        return PJMEDIA_EAUD_SYSERR;
    }

    frame_size = setup.buf.block.frag_size;

    if (group.gid.name[0] == 0) {
    } else {
    }

    /* frag_size should be 160 */
    frame_size = setup.buf.block.frag_size;

    /* END BB10 init */

    /* Set clock rate */
    rate = param->clock_rate;
    stream->ca_frames = (unsigned long) param->samples_per_frame /
			param->channel_count;

    /* Set the sound device buffer size and latency */
    if (param->flags & PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY) {
        tmp_buf_size = (rate / 1000) * param->input_latency_ms;
    } else {
        tmp_buf_size = (rate / 1000) * PJMEDIA_SND_DEFAULT_REC_LATENCY;
    }

    stream->param.input_latency_ms = tmp_buf_size / (rate / 1000);

    /* Set our buffer */
    stream->ca_buf_size = stream->ca_frames * param->channel_count *
			  (param->bits_per_sample/8);
    stream->ca_buf = (char *)pj_pool_alloc (stream->pool, stream->ca_buf_size);

    TRACE_((THIS_FILE, "bb10_open_capture: ca_frames = %d clock = %d",
                       stream->ca_frames, param->clock_rate));

    return PJ_SUCCESS;
}
Exemplo n.º 26
0
static int NTO_OpenAudio(_THIS, SDL_AudioSpec *spec)
{
	int rval;
	int format;
	Uint16 test_format;
	int twidth;
	int found;

#ifdef DEBUG_AUDIO
		fprintf(stderr, "NTO_OpenAudio\n");
#endif
	
	audio_handle = NULL;
	 this->enabled = 0;

	if ( pcm_buf != NULL ) {
		free((Uint8 *)pcm_buf); 
		pcm_buf = NULL;
	}
	 
	/* initialize channel transfer parameters to default */
	init_pcm_cparams(&cparams);

	/* Open the audio device */
	
	rval = snd_pcm_open_preferred(&audio_handle, &card_no, &device_no, OPEN_FLAGS);
	if ( rval < 0 ) {
		SDL_SetError("snd_pcm_open failed: %s\n", snd_strerror(rval));
		return(-1);
	}

    /* set to nonblocking mode */
    if ((rval = snd_pcm_nonblock_mode(audio_handle, 1))<0) //I assume 1 means on
    {
        SDL_SetError("snd_pcm_nonblock_mode failed: %s\n", snd_strerror(rval));
        return(-1);
    }

    /* enable count status parameter */
    if ((rval = snd_plugin_set_disable(audio_handle, PLUGIN_DISABLE_MMAP))<0)
    {
        SDL_SetError("snd_plugin_set_disable failed: %s\n", snd_strerror(rval));
        return(-1);
    }


	/* Try for a closest match on audio format */
	format = 0;
 	found = 0; // can't use format as SND_PCM_SFMT_U8 = 0 in nto
	for ( test_format = SDL_FirstAudioFormat(spec->format);	!found ; ) 

	{
#ifdef DEBUG_AUDIO
		fprintf(stderr, "Trying format 0x%4.4x spec->samples %d\n", test_format,spec->samples);
#endif
			/* if match found set format to equivalent ALSA format */
        switch ( test_format ) {
			case AUDIO_U8:
				format = SND_PCM_SFMT_U8;
				cparams.buf.block.frag_size = spec->samples * spec->channels;
				found = 1;
				break;
			case AUDIO_S8:
				format = SND_PCM_SFMT_S8;
				cparams.buf.block.frag_size = spec->samples * spec->channels;
				found = 1;
				break;
			case AUDIO_S16LSB:
				format = SND_PCM_SFMT_S16_LE;
				cparams.buf.block.frag_size = spec->samples*2 * spec->channels;
				found = 1;
				break;
			case AUDIO_S16MSB:
				format = SND_PCM_SFMT_S16_BE;
				cparams.buf.block.frag_size = spec->samples*2 * spec->channels;
				found = 1;
				break;
			case AUDIO_U16LSB:
				format = SND_PCM_SFMT_U16_LE;
				cparams.buf.block.frag_size = spec->samples*2 * spec->channels;
				found = 1;
				break;
			case AUDIO_U16MSB:
				format = SND_PCM_SFMT_U16_BE;
				cparams.buf.block.frag_size = spec->samples*2 * spec->channels;
				found = 1;
				break;
			default:
				break;
		}
		if ( ! found ) {
			test_format = SDL_NextAudioFormat();
		}
	}
	
	/* assumes test_format not 0 on success */
	if ( test_format == 0 ) {
		SDL_SetError("Couldn't find any hardware audio formats");
		return(-1);
	}
	
	spec->format = test_format;

	/* Set the audio format */
	cparams.format.format = format;

	/* Set mono or stereo audio (currently only two channels supported) */
	cparams.format.voices = spec->channels;
	
#ifdef DEBUG_AUDIO
	fprintf(stderr,"intializing channels %d\n", cparams.format.voices);
#endif

	
	/* Set rate */
	cparams.format.rate = spec->freq ;

	/* Setup the transfer parameters according to cparams */
	rval = snd_pcm_plugin_params(audio_handle, &cparams);
	if (rval < 0) {
		SDL_SetError("snd_pcm_channel_params failed: %s\n", snd_strerror (rval));
		return(-1);
	}

    /*  Make sure channel is setup right one last time */
    memset( &csetup, 0, sizeof( csetup ) );
    csetup.channel = SND_PCM_CHANNEL_PLAYBACK;
    if ( snd_pcm_plugin_setup( audio_handle, &csetup ) < 0 )
    {
        SDL_SetError("Unable to setup playback channel\n" );
        return(-1);
    }
    else
    {
#ifdef DEBUG_AUDIO
        fprintf(stderr,"requested format: %d\n",cparams.format.format);
        fprintf(stderr,"requested frag size: %d\n",cparams.buf.block.frag_size);
        fprintf(stderr,"requested max frags: %d\n\n",cparams.buf.block.frags_max);

        fprintf(stderr,"real format: %d\n", csetup.format.format );
        fprintf(stderr,"real frag size : %d\n", csetup.buf.block.frag_size );
		fprintf(stderr,"real max frags : %d\n", csetup.buf.block.frags_max );
#endif // DEBUG_AUDIO
    }


    /*  Allocate memory to the audio buffer and initialize with silence
        (Note that buffer size must be a multiple of fragment size, so find closest multiple)
    */
    
    twidth = snd_pcm_format_width(format);
    if (twidth < 0) {
        printf("snd_pcm_format_width failed\n");
        twidth = 0;
    }
    
#ifdef DEBUG_AUDIO
    fprintf(stderr,"format is %d bits wide\n",twidth);
#endif      
    
    pcm_len = spec->size ;
    
  
#ifdef DEBUG_AUDIO    
    fprintf(stderr,"pcm_len set to %d\n", pcm_len);
#endif
    
    if (pcm_len == 0)
    {
        pcm_len = csetup.buf.block.frag_size;
    }
    
    pcm_buf = (Uint8*)malloc(pcm_len);
    if (pcm_buf == NULL) {
        SDL_SetError("pcm_buf malloc failed\n");
        return(-1);
    }
    memset(pcm_buf,spec->silence,pcm_len);

#ifdef DEBUG_AUDIO
	fprintf(stderr,"pcm_buf malloced and silenced.\n");
#endif

    /* get the file descriptor */
    if( (audio_fd = snd_pcm_file_descriptor(audio_handle, SND_PCM_CHANNEL_PLAYBACK)) < 0)
    {
       fprintf(stderr, "snd_pcm_file_descriptor failed with error code: %d\n", audio_fd);
    }

	/* Trigger audio playback */
	rval = snd_pcm_plugin_prepare( audio_handle, SND_PCM_CHANNEL_PLAYBACK);
	if (rval < 0) {
       SDL_SetError("snd_pcm_plugin_prepare failed: %s\n", snd_strerror (rval));
       return(-1);
	}
	
	 this->enabled = 1;
	 
	/* Get the parent process id (we're the parent of the audio thread) */
	parent = getpid();

	/* We're ready to rock and roll. :-) */
	return(0);
}
Exemplo n.º 27
0
/*****************************************************************************
 * Open : creates a handle and opens an alsa device
 *****************************************************************************
 * This function opens an alsa device, through the alsa API
 *****************************************************************************/
int E_(OpenAudio)( vlc_object_t *p_this )
{
    aout_instance_t *p_aout = (aout_instance_t *)p_this;
    int i_ret;
    int i_bytes_per_sample;
    int i_nb_channels;
    snd_pcm_channel_info_t pi;
    snd_pcm_channel_params_t pp;
    aout_instance_t *p_aout = (aout_instance_t *)p_this;

    /* allocate structure */
    p_aout->output.p_sys = malloc( sizeof( aout_sys_t ) );
    if( p_aout->output.p_sys == NULL )
    {
        msg_Err( p_aout, "out of memory" );
        return -1;
    }

    /* open audio device */
    if( ( i_ret = snd_pcm_open_preferred( &p_aout->output.p_sys->p_pcm_handle,
                                          &p_aout->output.p_sys->i_card,
                                          &p_aout->output.p_sys->i_device,
                                          SND_PCM_OPEN_PLAYBACK ) ) < 0 )
    {
        msg_Err( p_aout, "unable to open audio device (%s)",
                         snd_strerror( i_ret ) );
        free( p_aout->output.p_sys );
        return -1;
    }

    /* disable mmap */
    if( ( i_ret = snd_pcm_plugin_set_disable( p_aout->output.p_sys->p_pcm_handle,
                                              PLUGIN_DISABLE_MMAP ) ) < 0 )
    {
        msg_Err( p_aout, "unable to disable mmap (%s)", snd_strerror(i_ret) );
        E_(CloseAudio)( p_this );
        free( p_aout->output.p_sys );
        return -1;
    }

    p_aout->output.p_sys->p_silent_buffer = malloc( DEFAULT_FRAME_SIZE * 4 );
    p_aout->output.pf_play = Play;
    aout_VolumeSoftInit( p_aout );

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

    pi.channel = SND_PCM_CHANNEL_PLAYBACK;
    if( ( i_ret = snd_pcm_plugin_info( p_aout->output.p_sys->p_pcm_handle,
                                       &pi ) ) < 0 )
    {
        msg_Err( p_aout, "unable to get plugin info (%s)",
                         snd_strerror( i_ret ) );
        E_(CloseAudio)( p_this );
        free( p_aout->output.p_sys );
        return -1;
    }

    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_STOP;

    pp.buf.block.frags_max   = 3;
    pp.buf.block.frags_min   = 1;

    pp.format.interleave     = 1;
    pp.format.rate           = p_aout->output.output.i_rate;

    i_nb_channels = aout_FormatNbChannels( &p_aout->output.output );
    if ( i_nb_channels > 2 )
    {
        /* I don't know if QNX supports more than two channels. */
        i_nb_channels = 2;
        p_aout->output.output.i_channels = AOUT_CHAN_STEREO;
    }
    pp.format.voices         = i_nb_channels;

    p_aout->output.output.i_format = AOUT_FMT_S16_NE;
    p_aout->output.i_nb_samples = DEFAULT_FRAME_SIZE;
    pp.format.format = SND_PCM_SFMT_S16;
    i_bytes_per_sample = 2;

    pp.buf.block.frag_size = p_aout->output.i_nb_samples *
                            p_aout->output.output.i_channels *
                            i_bytes_per_sample;

    /* set parameters */
    if( ( i_ret = snd_pcm_plugin_params( p_aout->output.p_sys->p_pcm_handle,
                                         &pp ) ) < 0 )
    {
        msg_Err( p_aout, "unable to set parameters (%s)", snd_strerror(i_ret) );
        E_(CloseAudio)( p_this );
        free( p_aout->output.p_sys );
        return -1;
    }

    /* prepare channel */
    if( ( i_ret = snd_pcm_plugin_prepare( p_aout->output.p_sys->p_pcm_handle,
                                          SND_PCM_CHANNEL_PLAYBACK ) ) < 0 )
    {
        msg_Err( p_aout, "unable to prepare channel (%s)",
                         snd_strerror( i_ret ) );
        E_(CloseAudio)( p_this );
        free( p_aout->output.p_sys );
        return -1;
    }

    /* Create audio thread and wait for its readiness. */
    if( vlc_thread_create( p_aout, "aout", QNXaoutThread,
                           VLC_THREAD_PRIORITY_OUTPUT, VLC_FALSE ) )
    {
        msg_Err( p_aout, "cannot create QNX audio thread (%s)", strerror(errno) );
        E_(CloseAudio)( p_this );
        free( p_aout->output.p_sys );
        return -1;
    }

    return( 0 );
}
static int voice_test()
{
    int rtn = 0;
    char* name;
    fd_set rfds, wfds;
    Audio_t hPcm_Mic;
    Audio_t hPcm_Spk;
    snd_pcm_channel_params_t params;
    bool bQuit = false;

    /************************ CAPTURE **************************/

    //  configuring capture (mic)
    name = "voice";

    //  get audioman handle
    rtn = audio_manager_get_handle(AUDIO_TYPE_VIDEO_CHAT, getpid(), (bool)false, &hPcm_Mic.hAudioman);
    if(rtn < 0) {
        cli_print("audio_manager_get_handle (mic) failed %s", strerror(-rtn));
        return -1;
     }

    cli_print("Opening %s - for capture", name);
    rtn = snd_pcm_open_name(&hPcm_Mic.pDs, name, SND_PCM_OPEN_CAPTURE);
    if (rtn < 0) {
        (void)audio_manager_free_handle(hPcm_Mic.hAudioman);
        cli_print("snd_pcm_open_name (mic) failed %s", snd_strerror(rtn));
        return -1; // snd_pcm calls return negative values; make positive
    }

    rtn = snd_pcm_set_audioman_handle(hPcm_Mic.pDs, hPcm_Mic.hAudioman);
    if (rtn < 0) {
        (void)snd_pcm_close(hPcm_Mic.pDs);
        (void)audio_manager_free_handle(hPcm_Mic.hAudioman);
        cli_print("snd_pcm_set_audioman_handle (mic) failed %s", snd_strerror(rtn));
        (void)snd_pcm_close(hPcm_Mic.pDs);
        return -1;
    }

    // disable mmap
    (void)snd_pcm_plugin_set_disable(hPcm_Mic.pDs, (unsigned int)PLUGIN_DISABLE_MMAP);

    // set parameters
    memset(&params, 0, sizeof(params));
    params.mode = SND_PCM_MODE_BLOCK;
    params.channel = SND_PCM_CHANNEL_CAPTURE;
    params.start_mode = SND_PCM_START_GO;
    params.stop_mode = SND_PCM_STOP_ROLLOVER;
    params.buf.block.frag_size = fragsize;
    params.buf.block.frags_max = 1;
    params.buf.block.frags_min = 1;
    params.format.rate = 8000; //samplerate;
    params.format.interleave = 1;
    params.format.voices = channels;
    params.format.format = SND_PCM_SFMT_S16_LE;

    rtn = snd_pcm_plugin_params(hPcm_Mic.pDs, &params);
    if (rtn < 0) {
        cli_print("snd_pcm_plugin_params (mic) failed %s", snd_strerror(rtn));
        (void)snd_pcm_close(hPcm_Mic.pDs);
        (void)audio_manager_free_handle(hPcm_Mic.hAudioman);
        return -1;
    }

    // get file descriptor for use with the select() call
    hPcm_Mic.hFD = snd_pcm_file_descriptor(hPcm_Mic.pDs, SND_PCM_CHANNEL_CAPTURE);
    if (hPcm_Mic.hFD < 0) {
        cli_print("snd_pcm_file_descriptor (mic) failed %s", snd_strerror(hPcm_Mic.hFD));
        (void)snd_pcm_close(hPcm_Mic.pDs);
        (void)audio_manager_free_handle(hPcm_Mic.hAudioman);
        return -1;
    }
    // Signal the driver to ready the capture channel
    rtn = snd_pcm_plugin_prepare(hPcm_Mic.pDs, SND_PCM_CHANNEL_CAPTURE);
    if (rtn < 0) {
        cli_print("snd_pcm_plugin_prepare (mic) failed %s", snd_strerror(errno));
        (void)snd_pcm_close(hPcm_Mic.pDs);
        (void)audio_manager_free_handle(hPcm_Mic.hAudioman);
        return -1;
    }
    fragsize = params.buf.block.frag_size;


    /************************ PLAYBACK **************************/

    name = "voice";

    // get and set audioman handle
    rtn = audio_manager_get_handle(AUDIO_TYPE_VIDEO_CHAT, getpid(), (bool)false, &hPcm_Spk.hAudioman);
    if (rtn < 0) {
        cli_print("audioman audio_manager_get_handle (spk) failed %s", strerror(-rtn) );
        (void)snd_pcm_close(hPcm_Mic.pDs);
        (void)audio_manager_free_handle(hPcm_Mic.hAudioman);
        return -1;
    }
#ifdef HANDSET
    // set audio manager handle type
    rtn = audio_manager_set_handle_type(hPcm_Spk.hAudioman, AUDIO_TYPE_VIDEO_CHAT, device_type, device_type);
    if (rtn < 0) {
        (void)snd_pcm_close(hPcm_Mic.pDs);
        (void)audio_manager_free_handle(hPcm_Mic.hAudioman);
        (void)audio_manager_free_handle(hPcm_Spk.hAudioman);
        cli_print("audio_manager_set_handle_type (spk) failed %s", strerror(-rtn));
        return -1;
    }
#endif
    // Create a handle and open a connection to an audio interface specified by name
    cli_print("Opening %s - for playback", name);
    rtn = snd_pcm_open_name(&hPcm_Spk.pDs, name, SND_PCM_OPEN_PLAYBACK);
    if (rtn < 0) {
        cli_print("snd_pcm_open_name (spk) failed %s", snd_strerror(rtn));
        (void)snd_pcm_close(hPcm_Mic.pDs);
        (void)audio_manager_free_handle(hPcm_Mic.hAudioman);
        (void)audio_manager_free_handle(hPcm_Spk.hAudioman);
        return -1;
    }
    rtn = snd_pcm_set_audioman_handle(hPcm_Spk.pDs, hPcm_Spk.hAudioman);
    if (rtn < 0) {
        cli_print("snd_pcm_set_audioman_handle (spk) failed %s", snd_strerror(rtn));
        (void)snd_pcm_close(hPcm_Mic.pDs);
        (void)snd_pcm_close(hPcm_Spk.pDs);
        (void)audio_manager_free_handle(hPcm_Mic.hAudioman);
        (void)audio_manager_free_handle(hPcm_Spk.hAudioman);
        return -1;
    }

    // disable mmap
    (void)snd_pcm_plugin_set_disable(hPcm_Spk.pDs, (unsigned int)PLUGIN_DISABLE_MMAP);

    // set parameters
    memset(&params, 0, sizeof(params));
    params.mode = SND_PCM_MODE_BLOCK;
    params.channel = SND_PCM_CHANNEL_PLAYBACK;
    params.start_mode = SND_PCM_START_GO;
    params.stop_mode = SND_PCM_STOP_ROLLOVER;
    params.buf.block.frag_size = fragsize;
    params.buf.block.frags_max = 1;
    params.buf.block.frags_min = 1;
    params.format.rate = samplerate;
    params.format.interleave = 1;
    params.format.voices = channels;
    params.format.format = SND_PCM_SFMT_S16_LE;

    // Set the configurable parameters for a PCM channel
    rtn = snd_pcm_plugin_params(hPcm_Spk.pDs, &params);
    if (rtn < 0) {
        cli_print("snd_pcm_plugin_params  (spk) failed %s", snd_strerror(rtn));
        (void)snd_pcm_close(hPcm_Mic.pDs);
        (void)snd_pcm_close(hPcm_Spk.pDs);
        (void)audio_manager_free_handle(hPcm_Mic.hAudioman);
        (void)audio_manager_free_handle(hPcm_Spk.hAudioman);
        return -1;
    }

    // get file descriptor for use with the select() call
    hPcm_Spk.hFD = snd_pcm_file_descriptor(hPcm_Spk.pDs, SND_PCM_CHANNEL_PLAYBACK);
    if (hPcm_Spk.hFD < 0) {
        cli_print("snd_pcm_file_descriptor (spk) failed %s", snd_strerror(hPcm_Spk.hFD));
        (void)snd_pcm_close(hPcm_Mic.pDs);
        (void)snd_pcm_close(hPcm_Spk.pDs);
        (void)audio_manager_free_handle(hPcm_Mic.hAudioman);
        (void)audio_manager_free_handle(hPcm_Spk.hAudioman);
        return -1;
    }
    // Signal the driver to ready the playback channel
    rtn = snd_pcm_plugin_prepare(hPcm_Spk.pDs, SND_PCM_CHANNEL_PLAYBACK);
    if (rtn < 0) {
        cli_print("snd_pcm_plugin_prepare  (spk) failed %s", snd_strerror(rtn));
        (void)snd_pcm_close(hPcm_Mic.pDs);
        (void)snd_pcm_close(hPcm_Spk.pDs);
        (void)audio_manager_free_handle(hPcm_Mic.hAudioman);
        (void)audio_manager_free_handle(hPcm_Spk.hAudioman);
        return -1;
    }
    fragsize = params.buf.block.frag_size;

    rtn = snd_pcm_capture_go(hPcm_Mic.pDs);
    if( rtn < 0) {
        cli_print("snd_pcm_capture_go (mic) failed %s", snd_strerror(rtn));
        (void)snd_pcm_close(hPcm_Mic.pDs);
        (void)snd_pcm_close(hPcm_Spk.pDs);
        (void)audio_manager_free_handle(hPcm_Mic.hAudioman);
        (void)audio_manager_free_handle(hPcm_Spk.hAudioman);
        return -1;
    }
    rtn = snd_pcm_playback_go(hPcm_Spk.pDs);
    if (rtn < 0) {
        cli_print("snd_pcm_playback_go (spk) failed %s", snd_strerror(rtn));
        (void)snd_pcm_close(hPcm_Mic.pDs);
        (void)snd_pcm_close(hPcm_Spk.pDs);
        (void)audio_manager_free_handle(hPcm_Mic.hAudioman);
        (void)audio_manager_free_handle(hPcm_Spk.hAudioman);
        return -1;
    }

    /******************* PLAYBACK/RECORD LOOP **************************/
    while(!bQuit)
    {
        int width;
        struct timeval timeout;
        timeout.tv_sec = 0;
        timeout.tv_usec = 350000; // 350 ms

        FD_ZERO(&rfds);
        FD_ZERO(&wfds);
        FD_SET(hPcm_Mic.hFD, &rfds);
        FD_SET(hPcm_Spk.hFD, &wfds);

        width = ((hPcm_Spk.hFD > hPcm_Mic.hFD) ? hPcm_Spk.hFD : hPcm_Mic.hFD) + 1;
        rtn = select(width, &rfds, &wfds, NULL, &timeout);
        if (rtn > 0) {
            if (FD_ISSET(hPcm_Spk.hFD, &wfds)) {
                bQuit = process_write(hPcm_Spk.pDs);
            }
            if (FD_ISSET(hPcm_Mic.hFD, &rfds)) {
                bQuit = process_read(hPcm_Mic.pDs);
            }
        }
        else if (rtn == 0){
            cli_print("select: timed out");
            bQuit = true;
        }
        else { // (rtn < 0)
            cli_print("select: %s", strerror(errno));
            bQuit = true;
        }
    }

    // Ensure audio processing is stopped
    if ((rtn = snd_pcm_plugin_playback_drain(hPcm_Spk.pDs)) < 0) {
        cli_print("snd_pcm_plugin_playback_drain (spk) failed %s", snd_strerror(rtn));
    }
    if ((rtn = snd_pcm_plugin_flush(hPcm_Mic.pDs, SND_PCM_CHANNEL_CAPTURE)) < 0) {
        cli_print("snd_pcm_plugin_flush (mic) failed %s", snd_strerror(rtn));
    }
    if ((rtn = snd_pcm_close(hPcm_Spk.pDs)) < 0) {
        cli_print("snd_pcm_close (spk) failed %s", snd_strerror(rtn));
    }
    if ((rtn = snd_pcm_close(hPcm_Mic.pDs)) < 0) {
        cli_print("snd_pcm_close (mic) failed %s", snd_strerror(rtn));
    }
    if (hPcm_Spk.hAudioman) {
        (void)audio_manager_free_handle(hPcm_Spk.hAudioman);
    }
    if (hPcm_Mic.hAudioman) {
        (void)audio_manager_free_handle(hPcm_Mic.hAudioman);
    }
    return 0;
}
// Initialize audio and report back a few parameters of the channel
int setupAudio( )
{
    int error;
    snd_pcm_channel_info_t pi;
    snd_pcm_channel_params_t pp;
    snd_pcm_channel_setup_t ps;

    //if ((error = snd_pcm_open_name (&playback_handle, "pcmPreferred", SND_PCM_OPEN_PLAYBACK)) < 0) {
    if ((error = snd_pcm_open_name (&playback_handle, "tones", SND_PCM_OPEN_PLAYBACK)) < 0) {
        slogf( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "Unable to open preferred audio driver\n");
        return -error;
    }

    sample_handle = snd_pcm_file_descriptor( playback_handle, SND_PCM_CHANNEL_PLAYBACK );

    if ((error = snd_pcm_plugin_set_disable (playback_handle, PLUGIN_DISABLE_MMAP)) < 0) {
        slogf( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "Unable to disable mmap\n");
        snd_pcm_close(playback_handle);
        return -error;
    }

    if ((error = snd_pcm_plugin_set_enable (playback_handle, PLUGIN_ROUTING)) < 0)
    {
        slogf ( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "snd_pcm_plugin_set_enable failed: %s\n", snd_strerror (error));
        snd_pcm_close(playback_handle);
        return -error;
    }

    // Find what sample rate and format to use
    memset( &pi, 0, sizeof(pi) );
    pi.channel = SND_PCM_CHANNEL_PLAYBACK;
    if ((error = snd_pcm_channel_info (playback_handle, &pi)) < 0) {
        slogf( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "Unable to get plugin info\n");
        snd_pcm_close(playback_handle);
        return -error;
    }

    // Initialize the playback channel
    memset(&pp, 0, sizeof(pp) );
    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_STOP;
    pp.buf.block.frag_size = pi.max_fragment_size;
    pp.buf.block.frags_max = 3;
    pp.buf.block.frags_min = 1;
    pp.format.interleave = 1;
    pp.format.format =  SND_PCM_SFMT_S16_LE;
    pp.format.rate = 48000;
    pp.format.voices = 2;

    memset( &ps, 0, sizeof( ps ) );
    memset( &group, 0, sizeof( group ) );
    ps.channel = SND_PCM_CHANNEL_PLAYBACK;
    ps.mixer_gid = &group.gid;
    //strcpy(pp.sw_mixer_subchn_name, "Wave playback channel");
    strcpy(pp.sw_mixer_subchn_name, "voice_ringtone");

    if ((error = snd_pcm_plugin_params( playback_handle, &pp)) < 0)
    {
        slogf( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "Unable to set plugin params\n");
        snd_pcm_close(playback_handle);
        return -error;
    }

    if ((error = snd_pcm_plugin_prepare (playback_handle, SND_PCM_CHANNEL_PLAYBACK)) < 0) {
        slogf( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "Unable to set prepare plugin\n");
        snd_pcm_close(playback_handle);
        return -error;
    }

    if ((error = snd_pcm_plugin_setup (playback_handle, &ps)) < 0) {
        slogf( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "Unable to setup plugin\n");
        snd_pcm_close(playback_handle);
        return -error;
    }

    card = ps.mixer_card;
    device = ps.mixer_device;

    if( audioman_handle ) {
        if ((error = snd_pcm_set_audioman_handle (playback_handle, audioman_handle)) < 0) {
            slogf( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "Unable to set audioman handle \n");
            snd_pcm_close(playback_handle);
            return -error;
        }
    }

    sample_frequency = ps.format.rate;
    frag_samples = ps.buf.block.frag_size / 4;
    frame_size = ps.buf.block.frag_size;
    format = pp.format.format;
/*
    // Only support 16-bit samples for now
    frag_buffer = malloc( ps.buf.block.frag_size * 2 );
    if( frag_buffer == NULL ) {
        slogf( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "Unable to alloc frag buffer\n");
        snd_pcm_close(playback_handle);
        return ENOMEM;
    }
*/
	fprintf (stderr,"Playback Format %s card = %d\n", snd_pcm_get_format_name (ps.format.format),card);
	fprintf (stderr,"Playback preferred frame_size %d \n", pi.max_fragment_size);
	fprintf (stderr,"Playback frame_size %d \n", ps.buf.block.frag_size);
	fprintf (stderr,"Playback frame_samples %d \n", frag_samples);
	fprintf (stderr,"Playback Rate %d \n", ps.format.rate);

	if (group.gid.name[0] == 0)
	{
		fprintf (stderr,"Playback Mixer Pcm Group [%s] Not Set \n", group.gid.name);
        return -1;
	}
	fprintf (stderr, "Playback Mixer Pcm Group [%s]\n", group.gid.name);

    return EOK;
}