예제 #1
0
/* This function needs to be modified to return some indication of how well
 * or not we are doing.                                                    
 */
int
audio_rw_process(session_t *spi, session_t *spo,  struct s_mixer *ms)
{
        uint32_t cushion_size, read_dur;
        struct s_cushion_struct *c;
	int	trailing_silence, new_cushion, cushion_step, diff;
        const audio_format* ofmt;
	sample	*bufp;

	session_validate(spi);
	session_validate(spo);

        c = spi->cushion;

	if ((read_dur = tx_read_audio(spi->tb)) <= 0) {
		return 0;
	} else {
                if (!spi->audio_device) {
                        /* no device means no cushion */
                        return read_dur;
                }
	}

        xmemchk();

	/* read_dur now reflects the amount of real time it took us to get
	 * through the last cycle of processing. 
         */

	if (spo->lecture == TRUE && spo->auto_lecture == 0) {
                cushion_update(c, read_dur, CUSHION_MODE_LECTURE);
	} else {
                cushion_update(c, read_dur, CUSHION_MODE_CONFERENCE);
	}

	/* Following code will try to achieve new cushion size without
	 * messing up the audio...
	 * First case is when we are in trouble and the output has gone dry.
	 * In this case we write out a complete new cushion with the desired
	 * size. We do not care how much of it is going to be real audio and
	 * how much silence so long as the silence is at the head of the new
	 * cushion. If the silence was at the end we would be creating
	 * another silence gap...
	 */
        cushion_size = cushion_get_size(c);
        ofmt         = audio_get_ofmt(spi->audio_device);

	if (cushion_size < read_dur) {
                debug_msg("catch up! read_dur(%d) > cushion_size(%d)\n",
                        read_dur,
                        cushion_size);
		/* Use a step for the cushion to keep things nicely rounded  */
                /* in the mixing. Round it up.                               */
                new_cushion = cushion_use_estimate(c);
                assert(new_cushion >= 0 && new_cushion < 100000);

                /* The mix routine also needs to know for how long the       */
                /* output went dry so that it can adjust the time.           */
                mix_new_cushion(ms, 
                                cushion_size, 
                                new_cushion, 
                                (read_dur - cushion_size), 
                                &bufp);
                audio_device_write(spo, bufp, new_cushion);
                /* We've blocked for this long for whatever reason           */
                cushion_size    = new_cushion;
        } else {
                trailing_silence = mix_get_audio(ms, read_dur * ofmt->channels, &bufp);
                cushion_step = cushion_get_step(c);
                diff  = 0;
                if (trailing_silence > cushion_step) {
                        /* Check whether we need to adjust the cushion */
                        diff = cushion_diff_estimate_size(c);
                        if (abs(diff) < cushion_step) {
                                diff = 0;
                        }
                } 
                
                /* If diff is less than zero then we must decrease the */
                /* cushion so loose some of the trailing silence.      */
                if (diff < 0 && 
                    mix_active(ms) == FALSE && 
                    source_list_source_count(spi->active_sources) == 0) {
                        /* Only decrease cushion if not playing anything out */
                        uint32_t old_cushion;
                        old_cushion = cushion_get_size(c);
                        if (read_dur > (unsigned)cushion_step) {
                                cushion_step_down(c);
                                if (cushion_get_size(c) != old_cushion) {
                                        debug_msg("Decreasing cushion\n");
                                        read_dur -= cushion_step;
                                }
                        }
                }
                assert(read_dur < 0x7fffffff);
                audio_device_write(spo, bufp, read_dur);
                /*
                 * If diff is greater than zero then we must increase the
                 * cushion so increase the amount of trailing silence.
                 */
                if (diff > 0) {
                        assert(cushion_step > 0);
                        audio_device_write(spo, zero_buf, cushion_step);
                        cushion_step_up(c);
                        debug_msg("Increasing cushion.\n");
                }
        }
        return (read_dur);
}
예제 #2
0
void wavplay_thread_entry(void *parameter)
{
    FILE *fp = NULL;
    uint16_t *buffer = NULL;
    struct wav_info *info = NULL;

    fp = fopen(file_name, "rb");
    if (!fp)
    {
        printf("open file failed!\n");
        goto __exit;
    }

    info = (struct wav_info *) malloc(sizeof(*info));
    if (!info) goto __exit;

    if (fread(&(info->header),     sizeof(struct RIFF_HEADER_DEF), 1, fp) != 1) goto __exit;
    if (fread(&(info->fmt_block),  sizeof(struct FMT_BLOCK_DEF),   1, fp) != 1) goto __exit;
    if (fread(&(info->data_block), sizeof(struct DATA_BLOCK_DEF),  1, fp) != 1) goto __exit;

    printf("wav information:\n");
    printf("samplerate %u\n", info->fmt_block.wav_format.SamplesPerSec);
    printf("channel %u\n", info->fmt_block.wav_format.Channels);

    audio_device_init();
    audio_device_open();
    audio_device_set_rate(info->fmt_block.wav_format.SamplesPerSec);

    while (!feof(fp))
    {
        int length;

        buffer = (uint16_t *)audio_device_get_buffer(RT_NULL);

        length = fread(buffer, 1, BUFSZ, fp);
        if (length)
        {
            if (info->fmt_block.wav_format.Channels == 1)
            {
                /* extend to stereo channels */
                int index;
                uint16_t *ptr;

                ptr = (uint16_t *)((uint8_t *)buffer + BUFSZ * 2);
                for (index = 1; index < BUFSZ / 2; index ++)
                {
                    *ptr = *(ptr - 1) = buffer[BUFSZ / 2 - index];
                    ptr -= 2;
                }

                length = length * 2;
            }

            audio_device_write((uint8_t *)buffer, length);
        }
        else
        {
            audio_device_put_buffer((uint8_t *)buffer);
            break;
        }
    }
    audio_device_close();

__exit:
    if (fp) fclose(fp);
    if (info) free(info);
}