Example #1
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;
}
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));
	}
}
Example #3
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;
}
Example #4
0
/*
    open & setup audio device
    return: 1=success 0=fail
*/
static int init(int rate_hz, int channels, int format, int flags)
{
    int err;
    int cards = -1;
    snd_pcm_channel_params_t params;
    snd_pcm_channel_setup_t setup;
    snd_pcm_info_t info;
    snd_pcm_channel_info_t chninfo;

    mp_msg(MSGT_AO, MSGL_INFO, MSGTR_AO_ALSA5_InitInfo, rate_hz,
	channels, af_fmt2str_short(format));

    alsa_handler = NULL;

    mp_msg(MSGT_AO, MSGL_V, "alsa-init: compiled for ALSA-%s (%d)\n", SND_LIB_VERSION_STR,
        SND_LIB_VERSION);

    if ((cards = snd_cards()) < 0)
    {
	mp_msg(MSGT_AO, MSGL_ERR, MSGTR_AO_ALSA5_SoundCardNotFound);
	return 0;
    }

    ao_data.format = format;
    ao_data.channels = channels;
    ao_data.samplerate = rate_hz;
    ao_data.bps = ao_data.samplerate*ao_data.channels;
    ao_data.outburst = OUTBURST;
    ao_data.buffersize = 16384;

    memset(&alsa_format, 0, sizeof(alsa_format));
    switch (format)
    {
	case AF_FORMAT_S8:
	    alsa_format.format = SND_PCM_SFMT_S8;
	    break;
	case AF_FORMAT_U8:
	    alsa_format.format = SND_PCM_SFMT_U8;
	    break;
	case AF_FORMAT_U16_LE:
	    alsa_format.format = SND_PCM_SFMT_U16_LE;
	    break;
	case AF_FORMAT_U16_BE:
	    alsa_format.format = SND_PCM_SFMT_U16_BE;
	    break;
	case AF_FORMAT_AC3_LE:
	case AF_FORMAT_S16_LE:
	    alsa_format.format = SND_PCM_SFMT_S16_LE;
	    break;
	case AF_FORMAT_AC3_BE:
	case AF_FORMAT_S16_BE:
	    alsa_format.format = SND_PCM_SFMT_S16_BE;
	    break;
	default:
	    alsa_format.format = SND_PCM_SFMT_MPEG;
	    break;
    }

    switch(alsa_format.format)
    {
	case SND_PCM_SFMT_S16_LE:
	case SND_PCM_SFMT_U16_LE:
	    ao_data.bps *= 2;
	    break;
	case -1:
	    mp_msg(MSGT_AO, MSGL_ERR, MSGTR_AO_ALSA5_InvalidFormatReq,af_fmt2str_short(format));
	    return 0;
	default:
	    break;
    }

    switch(rate_hz)
    {
	case 8000:
	    alsa_rate = SND_PCM_RATE_8000;
	    break;
	case 11025:
	    alsa_rate = SND_PCM_RATE_11025;
	    break;
	case 16000:
	    alsa_rate = SND_PCM_RATE_16000;
	    break;
	case 22050:
	    alsa_rate = SND_PCM_RATE_22050;
	    break;
	case 32000:
	    alsa_rate = SND_PCM_RATE_32000;
	    break;
	case 44100:
	    alsa_rate = SND_PCM_RATE_44100;
	    break;
	case 48000:
	    alsa_rate = SND_PCM_RATE_48000;
	    break;
	case 88200:
	    alsa_rate = SND_PCM_RATE_88200;
	    break;
	case 96000:
	    alsa_rate = SND_PCM_RATE_96000;
	    break;
	case 176400:
	    alsa_rate = SND_PCM_RATE_176400;
	    break;
	case 192000:
	    alsa_rate = SND_PCM_RATE_192000;
	    break;
	default:
	    alsa_rate = SND_PCM_RATE_CONTINUOUS;
	    break;
    }

    alsa_format.rate = ao_data.samplerate;
    alsa_format.voices = ao_data.channels;
    alsa_format.interleave = 1;

    if ((err = snd_pcm_open(&alsa_handler, 0, 0, SND_PCM_OPEN_PLAYBACK)) < 0)
    {
	mp_msg(MSGT_AO, MSGL_ERR, MSGTR_AO_ALSA5_PlayBackError, snd_strerror(err));
	return 0;
    }

    if ((err = snd_pcm_info(alsa_handler, &info)) < 0)
    {
	mp_msg(MSGT_AO, MSGL_ERR, MSGTR_AO_ALSA5_PcmInfoError, snd_strerror(err));
	return 0;
    }

    mp_msg(MSGT_AO, MSGL_INFO, MSGTR_AO_ALSA5_SoundcardsFound,
	cards, info.name);

    if (info.flags & SND_PCM_INFO_PLAYBACK)
    {
	memset(&chninfo, 0, sizeof(chninfo));
	chninfo.channel = SND_PCM_CHANNEL_PLAYBACK;
	if ((err = snd_pcm_channel_info(alsa_handler, &chninfo)) < 0)
	{
	    mp_msg(MSGT_AO, MSGL_ERR, MSGTR_AO_ALSA5_PcmChanInfoError, snd_strerror(err));
	    return 0;
	}

#ifndef __QNX__
	if (chninfo.buffer_size)
	    ao_data.buffersize = chninfo.buffer_size;
#endif

	mp_msg(MSGT_AO, MSGL_V, "alsa-init: setting preferred buffer size from driver: %d bytes\n",
	    ao_data.buffersize);
    }

    memset(&params, 0, sizeof(params));
    params.channel = SND_PCM_CHANNEL_PLAYBACK;
    params.mode = SND_PCM_MODE_STREAM;
    params.format = alsa_format;
    params.start_mode = SND_PCM_START_DATA;
    params.stop_mode = SND_PCM_STOP_ROLLOVER;
    params.buf.stream.queue_size = ao_data.buffersize;
    params.buf.stream.fill = SND_PCM_FILL_NONE;

    if ((err = snd_pcm_channel_params(alsa_handler, &params)) < 0)
    {
	mp_msg(MSGT_AO, MSGL_ERR, MSGTR_AO_ALSA5_CantSetParms, snd_strerror(err));
	return 0;
    }

    memset(&setup, 0, sizeof(setup));
    setup.channel = SND_PCM_CHANNEL_PLAYBACK;
    setup.mode = SND_PCM_MODE_STREAM;
    setup.format = alsa_format;
    setup.buf.stream.queue_size = ao_data.buffersize;
    setup.msbits_per_sample = ao_data.bps;

    if ((err = snd_pcm_channel_setup(alsa_handler, &setup)) < 0)
    {
	mp_msg(MSGT_AO, MSGL_ERR, MSGTR_AO_ALSA5_CantSetChan, snd_strerror(err));
	return 0;
    }

    if ((err = snd_pcm_channel_prepare(alsa_handler, SND_PCM_CHANNEL_PLAYBACK)) < 0)
    {
	mp_msg(MSGT_AO, MSGL_ERR, MSGTR_AO_ALSA5_ChanPrepareError, snd_strerror(err));
	return 0;
    }

    mp_msg(MSGT_AO, MSGL_INFO, "AUDIO: %d Hz/%d channels/%d bps/%d bytes buffer/%s\n",
	ao_data.samplerate, ao_data.channels, ao_data.bps, ao_data.buffersize,
	snd_pcm_get_format_name(alsa_format.format));
    return 1;
}
// 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;
}