diff options
Diffstat (limited to 'src/libxineadec/pcm.c')
-rw-r--r-- | src/libxineadec/pcm.c | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/src/libxineadec/pcm.c b/src/libxineadec/pcm.c new file mode 100644 index 000000000..58b57bd57 --- /dev/null +++ b/src/libxineadec/pcm.c @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2003 J.Asselman <j.asselman@itsec.nl> + * ITsec Professional Services + * + * This file is part of xine, a free video player. + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * Dummy decoder for RAW Recorded PCM data + * Sample rate: 44100 + * Channels: 2 (Stereo) + * Resolution: 16 + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <unistd.h> + +#include "xine_internal.h" +#include "video_out.h" +#include "audio_out.h" +#include "buffer.h" +#include "xineutils.h" +#include "bswap.h" + +#define AUDIOBUFSIZE 128*1024 + +#define SAMPLERATE 44100 +#define CHANNELS 2 +#define BITS 16 +#define CAPMODE AO_CAP_MODE_STEREO + +typedef struct { + audio_decoder_class_t decoder_class; +} pcm_class_t; + +typedef struct pcm_decoder_s { + audio_decoder_t audio_decoder; + + xine_stream_t *stream; + + unsigned int buf_type; + + unsigned char *buf; + int bufsize; + int size; + char open; + int disc; +} pcm_decoder_t; + +static void pcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {\ + pcm_decoder_t *this = (pcm_decoder_t *) this_gen; + audio_buffer_t *aud; + char *offset; + int bytes_left = buf->decoder_info[1]; + int bits_per_frame = buf->decoder_info[1] / buf->decoder_info[0]; + +#ifdef LOG + printf(__FILE__ ": decode_data, flags=0x%08x , mem size: %d, frames: %d...\n", + buf->decoder_flags, buf->decoder_info[1], buf->decoder_info[0]); +#endif + + if (this->stream->stream_info[XINE_STREAM_INFO_AUDIO_MODE] == 0) { +#ifdef LOG + printf(__FILE__ ": Someone changed the audio mode. Closing device\r"); +#endif + this->stream->audio_out->close(this->stream->audio_out, this->stream); + this->open = 0; + } + + if (!this->open) + this->open = this->stream->audio_out->open(this->stream->audio_out, + this->stream, BITS, SAMPLERATE, CAPMODE); + + if (!this->open) + /* Snif :'( output still not open */ + return; + + offset = buf->content; + + while (bytes_left > 0 && (!this->disc || buf->pts)) { + int size; + + if (buf->pts) + this->disc = 0; + + aud = this->stream->audio_out->get_buffer(this->stream->audio_out); + + if (aud->mem_size == 0) { + printf(__FILE__ ": :( Got an audio buffer with size 0!\r\n"); + return; + } + + size = bytes_left > aud->mem_size ? aud->mem_size : bytes_left; + + aud->vpts = buf->pts; + aud->num_frames = size / bits_per_frame; + + xine_fast_memcpy(aud->mem, offset, size); + + this->stream->audio_out->put_buffer(this->stream->audio_out, aud, this->stream); + + bytes_left -= size; + offset += size; + + buf->pts = 0; + } +} + +static void pcm_reset (audio_decoder_t *this_gen) { + /* pcm_decoder_t *this = (pcm_decoder_t *) this_gen; */ +} + +static void pcm_discontinuity (audio_decoder_t *this_gen) +{ + pcm_decoder_t *this = (pcm_decoder_t *) this_gen; + + this->disc = 1; +} + +static void pcm_dispose (audio_decoder_t *this_gen) +{ + pcm_decoder_t *this = (pcm_decoder_t *) this_gen; + +#ifdef LOG + printf(__FILE__ ": Cleaning up\n"); +#endif + + if (this->open) + this->stream->audio_out->close (this->stream->audio_out, this->stream); + + this->open = 0; + + if (this->buf) + free(this->buf); + + free (this_gen); +} + +/* + * PCM decoder class code + */ + +static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { + + pcm_decoder_t *this; + + this = (pcm_decoder_t *) malloc (sizeof (pcm_decoder_t)); + memset(this, 0, sizeof (pcm_decoder_t)); + + this->audio_decoder.decode_data = pcm_decode_data; + this->audio_decoder.reset = pcm_reset; + this->audio_decoder.discontinuity = pcm_discontinuity; + this->audio_decoder.dispose = pcm_dispose; + + this->buf = NULL; + this->stream = stream; + this->open = 0; + + stream->audio_out->open (stream->audio_out, stream, + BITS, SAMPLERATE, CAPMODE); + + return &this->audio_decoder; +} + +static char *get_identifier (audio_decoder_class_t *this) { + return "PCM"; +} + +static char *get_description (audio_decoder_class_t *this) { + return "Dummy PCM stream decoder"; +} + +static void dispose_class (audio_decoder_class_t *this) { + free (this); +} + +static void *init_plugin (xine_t *xine, void *data) { + + pcm_class_t *this ; + + this = (pcm_class_t *) malloc (sizeof (pcm_class_t)); + + this->decoder_class.open_plugin = open_plugin; + this->decoder_class.get_identifier = get_identifier; + this->decoder_class.get_description = get_description; + this->decoder_class.dispose = dispose_class; + + return this; +} + +static uint32_t audio_types[] = { BUF_AUDIO_RAWPCM, 0 }; + +static decoder_info_t dec_info_audio = { + audio_types, /* supported types */ + 10 /* priority */ +}; + +plugin_info_t xine_plugin_info[] = { + /* type, API, "name", version, special_info, init_function */ + { PLUGIN_AUDIO_DECODER, 13, "pcm", XINE_VERSION_CODE, &dec_info_audio, init_plugin }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; +/* + * vim:sw=3:sts=3: + */ + |