void libao_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv) { /* We need to be called rather often... */ if (o_device != NULL && !rdpsnd_queue_empty()) FD_SET(0, wfds); }
void sgi_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv) { /* We need to be called rather often... */ if (output_port != (ALport) 0 && !rdpsnd_queue_empty()) FD_SET(0, wfds); }
void libao_play(void) { struct audio_packet *packet; STREAM out; int len; static long prev_s, prev_us; unsigned int duration; struct timeval tv; int next_tick; if (reopened) { reopened = False; gettimeofday(&tv, NULL); prev_s = tv.tv_sec; prev_us = tv.tv_usec; } /* We shouldn't be called if the queue is empty, but still */ if (rdpsnd_queue_empty()) return; packet = rdpsnd_queue_current_packet(); out = &packet->s; next_tick = rdpsnd_queue_next_tick(); len = (WAVEOUTLEN > (out->end - out->p)) ? (out->end - out->p) : WAVEOUTLEN; ao_play(o_device, (char *) out->p, len); out->p += len; gettimeofday(&tv, NULL); duration = ((tv.tv_sec - prev_s) * 1000000 + (tv.tv_usec - prev_us)) / 1000; if (packet->tick > next_tick) next_tick += 65536; if ((out->p == out->end) || duration > next_tick - packet->tick + 500) { unsigned int delay_us; prev_s = tv.tv_sec; prev_us = tv.tv_usec; if (abs((next_tick - packet->tick) - duration) > 20) { DEBUG(("duration: %d, calc: %d, ", duration, next_tick - packet->tick)); DEBUG(("last: %d, is: %d, should: %d\n", packet->tick, (packet->tick + duration) % 65536, next_tick % 65536)); } delay_us = ((out->size / 4) * (1000000 / 44100)); rdpsnd_queue_next(delay_us); } }
void sgi_check_fds(fd_set * rfds, fd_set * wfds) { if (output_port == (ALport) 0) return; if (!rdpsnd_queue_empty()) sgi_play(); }
void libao_check_fds(fd_set * rfds, fd_set * wfds) { if (o_device == NULL) return; if (!rdpsnd_queue_empty()) libao_play(); }
void alsa_check_fds(fd_set * rfds, fd_set * wfds) { struct pollfd *f; int err; unsigned short revents; if (out_handle && !rdpsnd_queue_empty()) { for (f = pfds_out; f < &pfds_out[num_fds_out]; f++) { f->revents = 0; if (f->fd != -1) { /* Fixme: This doesn't properly deal with things like POLLHUP */ if (FD_ISSET(f->fd, rfds)) f->revents |= POLLIN; if (FD_ISSET(f->fd, wfds)) f->revents |= POLLOUT; } } err = snd_pcm_poll_descriptors_revents(out_handle, pfds_out, num_fds_out, &revents); if (err < 0) return; if (revents & POLLOUT) alsa_play(); } if (in_handle) { for (f = pfds_in; f < &pfds_in[num_fds_in]; f++) { f->revents = 0; if (f->fd != -1) { /* Fixme: This doesn't properly deal with things like POLLHUP */ if (FD_ISSET(f->fd, rfds)) f->revents |= POLLIN; if (FD_ISSET(f->fd, wfds)) f->revents |= POLLOUT; } } err = snd_pcm_poll_descriptors_revents(in_handle, pfds_in, num_fds_in, &revents); if (err < 0) return; if (revents & POLLIN) alsa_record(); } }
void alsa_close_out(void) { /* Ack all remaining packets */ while (!rdpsnd_queue_empty()) rdpsnd_queue_next(0); if (out_handle) { snd_pcm_close(out_handle); out_handle = NULL; } }
static void oss_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv) { if (dsp_fd == -1) return; if ((dsp_mode == O_WRONLY || dsp_mode == O_RDWR) && !rdpsnd_queue_empty()) FD_SET(dsp_fd, wfds); if (dsp_mode == O_RDONLY || dsp_mode == O_RDWR) FD_SET(dsp_fd, rfds); if (dsp_fd > *n) *n = dsp_fd; }
void alsa_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv) { int err; struct pollfd *f; if (out_handle && !rdpsnd_queue_empty()) { num_fds_out = snd_pcm_poll_descriptors_count(out_handle); if (num_fds_out > sizeof(pfds_out) / sizeof(*pfds_out)) return; err = snd_pcm_poll_descriptors(out_handle, pfds_out, num_fds_out); if (err < 0) return; for (f = pfds_out; f < &pfds_out[num_fds_out]; f++) { if (f->events & POLLIN) FD_SET(f->fd, rfds); if (f->events & POLLOUT) FD_SET(f->fd, wfds); if (f->fd > *n && (f->events & (POLLIN | POLLOUT))) *n = f->fd; } } if (in_handle) { num_fds_in = snd_pcm_poll_descriptors_count(in_handle); if (num_fds_in > sizeof(pfds_in) / sizeof(*pfds_in)) return; err = snd_pcm_poll_descriptors(in_handle, pfds_in, num_fds_in); if (err < 0) return; for (f = pfds_in; f < &pfds_in[num_fds_in]; f++) { if (f->events & POLLIN) FD_SET(f->fd, rfds); if (f->events & POLLOUT) FD_SET(f->fd, wfds); if (f->fd > *n && (f->events & (POLLIN | POLLOUT))) *n = f->fd; } } }
static void oss_close_out(void) { oss_close(); if (dsp_mode == O_RDWR) { if (oss_open(O_RDONLY)) oss_restore_format(); } /* Ack all remaining packets */ while (!rdpsnd_queue_empty()) rdpsnd_queue_next(0); }
void libao_close(void) { /* Ack all remaining packets */ while (!rdpsnd_queue_empty()) { rdpsnd_queue_next(0); } if (o_device != NULL) ao_close(o_device); o_device = NULL; ao_shutdown(); }
void rdpsnd_queue_next(unsigned long completed_in_us) { struct audio_packet *packet; assert(!rdpsnd_queue_empty()); packet = &packet_queue[queue_lo]; gettimeofday(&packet->completion_tv, NULL); packet->completion_tv.tv_usec += completed_in_us; packet->completion_tv.tv_sec += packet->completion_tv.tv_usec / 1000000; packet->completion_tv.tv_usec %= 1000000; queue_lo = (queue_lo + 1) % MAX_QUEUE; rdpsnd_queue_complete_pending(); }
void sgi_close(void) { /* Ack all remaining packets */ #if (defined(IRIX_DEBUG)) fprintf(stderr, "sgi_close: begin\n"); #endif while (!rdpsnd_queue_empty()) rdpsnd_queue_next(0); alDiscardFrames(output_port, 0); alClosePort(output_port); output_port = (ALport) 0; alFreeConfig(audioconfig); #if (defined(IRIX_DEBUG)) fprintf(stderr, "sgi_close: returning\n"); #endif }
void sgi_play(void) { struct audio_packet *packet; ssize_t len; unsigned int i; STREAM out; int gf; while (1) { if (rdpsnd_queue_empty()) return; packet = rdpsnd_queue_current_packet(); out = &packet->s; len = out->end - out->p; alWriteFrames(output_port, out->p, len / combinedFrameSize); out->p += len; if (out->p == out->end) { gf = alGetFilled(output_port); if (gf < (4 * maxFillable / 10)) { rdpsnd_queue_next(0); } else { #if (defined(IRIX_DEBUG)) /* fprintf(stderr,"Busy playing...\n"); */ #endif usleep(10); return; } } } }
void alsa_play(void) { struct audio_packet *packet; STREAM out; int len; static long prev_s, prev_us; unsigned int duration; struct timeval tv; int next_tick; if (reopened) { reopened = False; gettimeofday(&tv, NULL); prev_s = tv.tv_sec; prev_us = tv.tv_usec; } /* We shouldn't be called if the queue is empty, but still */ if (rdpsnd_queue_empty()) return; packet = rdpsnd_queue_current_packet(); out = &packet->s; next_tick = rdpsnd_queue_next_tick(); len = (out->end - out->p) / (samplewidth_out * audiochannels_out); if ((len = snd_pcm_writei(out_handle, out->p, ((MAX_FRAMES < len) ? MAX_FRAMES : len))) < 0) { printf("Fooo!\n"); snd_pcm_prepare(out_handle); len = 0; } out->p += (len * samplewidth_out * audiochannels_out); gettimeofday(&tv, NULL); duration = ((tv.tv_sec - prev_s) * 1000000 + (tv.tv_usec - prev_us)) / 1000; if (packet->tick > next_tick) next_tick += 65536; if ((out->p == out->end) || duration > next_tick - packet->tick + 500) { snd_pcm_sframes_t delay_frames; unsigned long delay_us; prev_s = tv.tv_sec; prev_us = tv.tv_usec; if (abs((next_tick - packet->tick) - duration) > 20) { DEBUG(("duration: %d, calc: %d, ", duration, next_tick - packet->tick)); DEBUG(("last: %d, is: %d, should: %d\n", packet->tick, (packet->tick + duration) % 65536, next_tick % 65536)); } if (snd_pcm_delay(out_handle, &delay_frames) < 0) delay_frames = out->size / (samplewidth_out * audiochannels_out); if (delay_frames < 0) delay_frames = 0; delay_us = delay_frames * (1000000 / rate_out); rdpsnd_queue_next(delay_us); } }
static void oss_play(void) { struct audio_packet *packet; ssize_t len; STREAM out; assert(dsp_fd != -1); /* We shouldn't be called if the queue is empty, but still */ if (rdpsnd_queue_empty()) return; packet = rdpsnd_queue_current_packet(); out = &packet->s; len = out->end - out->p; len = write(dsp_fd, out->p, (len > MAX_LEN) ? MAX_LEN : len); if (len == -1) { if (errno != EWOULDBLOCK) { if (!dsp_broken) perror("RDPSND: write()"); dsp_broken = True; rdpsnd_queue_next(0); } return; } dsp_broken = False; out->p += len; if (out->p == out->end) { int delay_bytes; unsigned long delay_us; audio_buf_info info; if (in_esddsp) { /* EsounD has no way of querying buffer status, so we have to * go with a fixed size. */ delay_bytes = out->size; } else { #ifdef SNDCTL_DSP_GETODELAY delay_bytes = 0; if (ioctl(dsp_fd, SNDCTL_DSP_GETODELAY, &delay_bytes) == -1) delay_bytes = -1; #else delay_bytes = -1; #endif if (delay_bytes == -1) { if (ioctl(dsp_fd, SNDCTL_DSP_GETOSPACE, &info) != -1) delay_bytes = info.fragstotal * info.fragsize - info.bytes; else delay_bytes = out->size; } } delay_us = delay_bytes * (1000000 / (samplewidth * snd_rate)); rdpsnd_queue_next(delay_us); } }