static void handout_buf(void *_unused, Uint8 *stream, int length) { u16 requested_samples = length / (sys.sound_sample_size * 2); u16 available_samples; u16 served_samples; sys_lock_audiobuf(); if(!sys.sound_on || (~moo.state & MOO_ROM_RUNNING_BIT)) { memset(stream, 0x00, length); } else { #ifdef DEBUG if(get_available_samples() < requested_samples) { // printf("WARNING: Sound buffer underrun\n"); } #endif while((available_samples = get_available_samples()) < requested_samples) { sound_mix(); } if(sys.sound_buf_start > sys.sound_buf_end) { served_samples = sys.sound_buf_size - sys.sound_buf_start; if(served_samples >= requested_samples) { memcpy(stream, &sys.sound_buf[sys.sound_buf_start*2*2], length); } else { u16 bytes = served_samples * sys.sound_sample_size * 2; memcpy(&stream[0], &sys.sound_buf[sys.sound_buf_start*2*2], bytes); memcpy(&stream[bytes], &sys.sound_buf[0], (requested_samples - served_samples) * sys.sound_sample_size * 2); } } else { memcpy(stream, &sys.sound_buf[sys.sound_buf_start*2*2], length); } } sys.sound_buf_start += requested_samples; sys.sound_buf_start %= sys.sound_buf_size; sys_unlock_audiobuf(); }
static int request_frame(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; MixContext *s = ctx->priv; int ret; int wanted_samples, available_samples; ret = calc_active_inputs(s); if (ret < 0) return ret; if (s->input_state[0] == INPUT_OFF) { ret = request_samples(ctx, 1); if (ret < 0) return ret; ret = calc_active_inputs(s); if (ret < 0) return ret; available_samples = get_available_samples(s); if (!available_samples) return AVERROR(EAGAIN); return output_frame(outlink, available_samples); } if (s->frame_list->nb_frames == 0) { ret = ff_request_frame(ctx->inputs[0]); if (ret == AVERROR_EOF) { s->input_state[0] = INPUT_OFF; if (s->nb_inputs == 1) return AVERROR_EOF; else return AVERROR(EAGAIN); } else if (ret < 0) return ret; } av_assert0(s->frame_list->nb_frames > 0); wanted_samples = frame_list_next_frame_size(s->frame_list); if (s->active_inputs > 1) { ret = request_samples(ctx, wanted_samples); if (ret < 0) return ret; ret = calc_active_inputs(s); if (ret < 0) return ret; } if (s->active_inputs > 1) { available_samples = get_available_samples(s); if (!available_samples) return AVERROR(EAGAIN); available_samples = FFMIN(available_samples, wanted_samples); } else { available_samples = wanted_samples; } s->next_pts = frame_list_next_pts(s->frame_list); frame_list_remove_samples(s->frame_list, available_samples); return output_frame(outlink, available_samples); }