aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/sfx/pcm_device/audiobuf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/sfx/pcm_device/audiobuf.cpp')
-rw-r--r--engines/sci/sfx/pcm_device/audiobuf.cpp339
1 files changed, 0 insertions, 339 deletions
diff --git a/engines/sci/sfx/pcm_device/audiobuf.cpp b/engines/sci/sfx/pcm_device/audiobuf.cpp
deleted file mode 100644
index 15c5bb765b..0000000000
--- a/engines/sci/sfx/pcm_device/audiobuf.cpp
+++ /dev/null
@@ -1,339 +0,0 @@
-/***************************************************************************
- audiobuf.c Copyright (C) 2003 Christoph Reichenbach
-
-
- This program may be modified and copied freely according to the terms of
- the GNU general public license (GPL), as long as the above copyright
- notice and the licensing information contained herein are preserved.
-
- Please refer to www.gnu.org for licensing details.
-
- This work is provided AS IS, without warranty of any kind, expressed or
- implied, including but not limited to the warranties of merchantibility,
- noninfringement, and fitness for a specific purpose. The author will not
- be held liable for any damage caused by this work or derivatives of it.
-
- By using this source code, you agree to the licensing terms as stated
- above.
-
-
- Please contact the maintainer for bug reports or inquiries.
-
- Current Maintainer:
-
- Christoph Reichenbach (CR) <jameson@linuxgames.com>
-
-***************************************************************************/
-
-#include "audiobuf.h"
-
-#define NO_BUFFER_UNDERRUN 0
-#define SAW_BUFFER_UNDERRUN 1
-#define REPORTED_BUFFER_UNDERRUN 2
-
-static int
-buffer_underrun_status = NO_BUFFER_UNDERRUN;
-
-
-static sfx_audio_buf_chunk_t *
-sfx_audbuf_alloc_chunk(void) {
- sfx_audio_buf_chunk_t *ch = (sfx_audio_buf_chunk_t*)sci_malloc(sizeof(sfx_audio_buf_chunk_t));
- ch->used = 0;
- ch->next = NULL;
- ch->prev = NULL;
-
- return ch;
-}
-
-void
-sfx_audbuf_init(sfx_audio_buf_t *buf, sfx_pcm_config_t pcm_conf) {
- int framesize = SFX_PCM_FRAME_SIZE(pcm_conf);
- byte silence[16];
- int silencew = pcm_conf.format & ~SFX_PCM_FORMAT_LMASK;
-
- /* Determine the correct 'silence' for the channel and install it */
- /* Conservatively assume stereo */
- if (pcm_conf.format & SFX_PCM_FORMAT_16) {
- if (pcm_conf.format & SFX_PCM_FORMAT_LE) {
- silence[0] = silencew & 0xff;
- silence[1] = (silencew >> 8) & 0xff;
- } else {
- silence[0] = (silencew >> 8) & 0xff;
- silence[1] = silencew & 0xff;
- }
- memcpy(silence + 2, silence, 2);
- } else {
- silence[0] = silencew;
- silence[1] = silencew;
- }
-
- buf->last = buf->first = sfx_audbuf_alloc_chunk();
- buf->unused = NULL;
- memcpy(buf->last_frame, silence, framesize); /* Initialise, in case we
- ** underrun before the
- ** first write */
- buf->read_offset = 0;
- buf->framesize = framesize;
- buf->read_timestamp.secs = -1; /* Mark as inactive */
- buf->frames_nr = 0;
-}
-
-static void
-sfx_audbuf_free_chain(sfx_audio_buf_chunk_t *b) {
- while (b) {
- sfx_audio_buf_chunk_t *n = b->next;
- sci_free(b);
- b = n;
- }
-}
-
-void
-sfx_audbuf_free(sfx_audio_buf_t *buf) {
- sfx_audbuf_free_chain(buf->first);
- sfx_audbuf_free_chain(buf->unused);
- buf->first = buf->last = buf->unused = NULL;
- buf->read_offset = (int) 0xdeadbeef;
-}
-
-void
-sfx_audbuf_write(sfx_audio_buf_t *buf, unsigned char *src, int frames) {
- /* In here, we compute PER BYTE */
- int data_left = buf->framesize * frames;
-
- if (!buf->last) {
- fprintf(stderr, "FATAL: Violation of audiobuf.h usage protocol: Must use 'init' before 'write'\n");
- exit(1);
- }
-
- if (buffer_underrun_status == SAW_BUFFER_UNDERRUN) {
- /* Print here to avoid threadsafeness issues */
- sciprintf("[audiobuf] Buffer underrun\n");
- buffer_underrun_status = REPORTED_BUFFER_UNDERRUN;
- }
-
- buf->frames_nr += frames;
-
- while (data_left) {
- int cpsize;
- int buf_free;
- buf_free = SFX_AUDIO_BUF_SIZE - buf->last->used;
-
-
- if (buf_free >= data_left)
- cpsize = data_left;
- else
- cpsize = buf_free;
-
- /* Copy and advance pointers */
- memcpy(buf->last->data + buf->last->used, src, cpsize);
- data_left -= cpsize;
- buf->last->used += cpsize;
- src += cpsize;
-
- if (buf->last->used == SFX_AUDIO_BUF_SIZE) {
- if (!buf->last->next) {
- sfx_audio_buf_chunk_t *old = buf->last;
- if (buf->unused) { /* Re-use old chunks */
- sfx_audio_buf_chunk_t *buf_next_unused = buf->unused->next;
- buf->unused->next = NULL;
- buf->unused->used = 0;
-
- buf->last->next = buf->unused;
- buf->unused = buf_next_unused;
- } else /* Allocate */
- buf->last->next =
- sfx_audbuf_alloc_chunk();
-
- buf->last->prev = old;
- }
-
- buf->last = buf->last->next;
- }
- }
-
-#ifdef TRACE_BUFFER
- {
- sfx_audio_buf_chunk_t *c = buf->first;
- int t = buf->read_offset;
-
- while (c) {
- fprintf(stderr, "-> [");
- for (; t < c->used; t++)
- fprintf(stderr, " %02x", c->data[t]);
- t = 0;
- fprintf(stderr, " ] ");
- c = c->next;
- }
- fprintf(stderr, "\n");
- }
-#endif
-
- if (frames && (src - buf->framesize) != buf->last_frame)
- /* Backup last frame, unless we're already filling from it */
- memcpy(buf->last_frame, src - buf->framesize, buf->framesize);
-}
-
-int
-sfx_audbuf_read(sfx_audio_buf_t *buf, unsigned char *dest, int frames) {
- int written = 0;
-
- if (frames <= 0)
- return 0;
-
- if (buf->read_timestamp.secs >= 0) {
- /* Have a timestamp? Must update it! */
- buf->read_timestamp =
- sfx_timestamp_add(buf->read_timestamp,
- frames);
-
- }
-
- buf->frames_nr -= frames;
- if (buf->frames_nr < 0)
- buf->frames_nr = 0;
-
-#ifdef TRACE_BUFFER
- {
- sfx_audio_buf_chunk_t *c = buf->first;
- int t = buf->read_offset;
-
- while (c) {
- fprintf(stderr, "-> [");
- for (; t < c->used; t++)
- fprintf(stderr, " %02x", c->data[t]);
- t = 0;
- fprintf(stderr, " ] ");
- c = c->next;
- }
- fprintf(stderr, "\n");
- }
-#endif
-
- while (frames) {
- int data_needed = frames * buf->framesize;
- int rdbytes = data_needed;
- int rdframes;
-
- if (rdbytes > buf->first->used - buf->read_offset)
- rdbytes = buf->first->used - buf->read_offset;
-
- memcpy(dest, buf->first->data + buf->read_offset, rdbytes);
-
- buf->read_offset += rdbytes;
- dest += rdbytes;
-
- if (buf->read_offset == SFX_AUDIO_BUF_SIZE) {
- /* Continue to next, enqueue the current chunk as
- ** being unused */
- sfx_audio_buf_chunk_t *lastfirst = buf->first;
-
- buf->first = buf->first->next;
- lastfirst->next = buf->unused;
- buf->unused = lastfirst;
-
- buf->read_offset = 0;
- }
-
- rdframes = (rdbytes / buf->framesize);
- frames -= rdframes;
- written += rdframes;
-
- if (frames &&
- (!buf->first || buf->read_offset == buf->first->used)) {
- fprintf(stderr, "Underrun by %d frames at %d\n", frames,
- buf->read_timestamp.frame_rate);
- /* Buffer underrun! */
- if (!buffer_underrun_status == NO_BUFFER_UNDERRUN) {
- buffer_underrun_status = SAW_BUFFER_UNDERRUN;
- }
- do {
- memcpy(dest, buf->last_frame, buf->framesize);
- dest += buf->framesize;
- } while (--frames);
- }
-
- }
-
- return written;
-}
-
-#if 0
-static void
-_sfx_audbuf_rewind_stream(sfx_audio_buf_t *buf, int delta) {
- if (delta > buf->frames_nr)
- delta = buf->frames_nr;
-
-
- fprintf(stderr, "Rewinding %d\n", delta);
- buf->frames_nr -= delta;
-
- /* From here on, 'delta' means the number of BYTES to remove */
- delta *= buf->framesize;
-
- while (delta) {
- if (buf->last->used >= delta) {
- fprintf(stderr, "Subtracting from %d %d\n", buf->last->used, delta);
- buf->last->used -= delta;
- delta = 0;
- } else {
- fprintf(stderr, "Must do block-unuse\n");
- delta -= buf->last->used;
- buf->last->used = 0;
- buf->last->next = buf->unused;
- buf->unused = buf->last;
- buf->last = buf->unused->prev;
- buf->unused->prev = NULL;
- }
- }
-}
-#endif
-
-void
-sfx_audbuf_write_timestamp(sfx_audio_buf_t *buf, sfx_timestamp_t ts) {
- sfx_timestamp_t newstamp;
-
- newstamp = sfx_timestamp_add(ts, -buf->frames_nr);
-
-
- if (buf->read_timestamp.secs <= 0)
- /* Initial stamp */
- buf->read_timestamp = newstamp;
- else {
- int delta = sfx_timestamp_frame_diff(newstamp, buf->read_timestamp);
- long s1, s2, s3, u1, u2, u3;
- sfx_timestamp_gettime(&(buf->read_timestamp), &s1, &u1);
- sfx_timestamp_gettime(&(newstamp), &s2, &u2);
- sfx_timestamp_gettime(&(ts), &s3, &u3);
-
- if (delta < 0) {
-#if 0
- /* fprintf(stderr, "[SFX-BUF] audiobuf.c: Timestamp delta %d at %d: Must rewind (not implemented yet)\n",
- delta, buf->read_timestamp.frame_rate);*/
- _sfx_audbuf_rewind_stream(buf, -delta);
- buf->read_timestamp = newstamp;
-#endif
- } else if (delta > 0) {
- fprintf(stderr, "[SFX-BUF] audiobuf.c: Timestamp delta %d at %d: Filling in as silence frames\n",
- delta, buf->read_timestamp.frame_rate);
- /* Fill up with silence */
- while (delta--) {
- sfx_audbuf_write(buf, buf->last_frame, 1);
- }
- buf->read_timestamp = newstamp;
- }
- }
-}
-
-int
-sfx_audbuf_read_timestamp(sfx_audio_buf_t *buf, sfx_timestamp_t *ts) {
- if (buf->read_timestamp.secs > 0) {
- *ts = buf->read_timestamp;
- return 0;
- } else {
- ts->secs = -1;
- ts->usecs = -1;
- ts->frame_offset = -1;
- ts->frame_rate = -1;
- return 1; /* No timestamp */
- }
-}