diff options
Diffstat (limited to 'mpeglib/lib/decoder/tplayPlugin.cpp')
-rw-r--r-- | mpeglib/lib/decoder/tplayPlugin.cpp | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/mpeglib/lib/decoder/tplayPlugin.cpp b/mpeglib/lib/decoder/tplayPlugin.cpp new file mode 100644 index 00000000..01c44cbc --- /dev/null +++ b/mpeglib/lib/decoder/tplayPlugin.cpp @@ -0,0 +1,264 @@ +/* + tplay player plugin + Copyright (C) 1999 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + +#include "tplayPlugin.h" + +#include "../tplay/tplayfunctions.h" + +#include <iostream> + +using namespace std; + +TplayPlugin::TplayPlugin() { + info=new info_struct(); + + info->progname = NULL; + info->loop = FALSE; + info->in_seconds = FALSE; + info->speed = DEFAULT_SPEED; + info->bits = DEFAULT_BITS; + info->channels = DEFAULT_CHANNELS; + info->buffer_size = BUFFER_SIZE; + info->show_usage = FALSE; + info->swap = FALSE; + info->forceraw = FALSE; + info->force = FALSE; + info->device = NULL; + info->verbose = FALSE; + info->optind = 0; + info->buffer = NULL; + info->firstblock = NULL; + info->number_of_blocks = 0; + info->readblock = 0; + info->writeblock = 0; + info->readcount = 0; + info->writecount = 0; + info->alldone = FALSE; + info->overflow = FALSE; + info->underflow = FALSE; + info->audioset = FALSE; + info->headerskip = 0; + info->blocksize = 4096; + info->bytes_on_last_block = 0; + + startStamp=new TimeStamp(); + endStamp=new TimeStamp(); +} + + +TplayPlugin::~TplayPlugin() { + delete startStamp; + delete endStamp; + delete info; +} + + + +void TplayPlugin::decoder_loop() { + int bytesread, count, stereo; + char *p, *bufferp; + + if (input == NULL) { + cout << "TplayPlugin::decoder_loop input is NULL"<<endl; + exit(0); + } + if (output == NULL) { + cout << "TplayPlugin::decoder_loop output is NULL"<<endl; + exit(0); + } + + TimeStamp* stamp; + long pos; + + info->buffer = (char*) malloc(info->buffer_size * sizeof(char)); + + while(runCheck()) { + switch(streamState) { + case _STREAM_STATE_FIRST_INIT : { + read_header(); + + if (info->channels == 1) + stereo = FALSE; + else + stereo = TRUE; + + info->number_of_blocks = 0; + bufferp = info->buffer; + pluginInfo->setLength(getTotalLength()); + output->writeInfo(pluginInfo); + lhasLength=true; + + setStreamState(_STREAM_STATE_INIT); + break; + } + case _STREAM_STATE_INIT : + setStreamState(_STREAM_STATE_PLAY); + cout << "audioSetup call"<<endl; + output->audioOpen(); + output->audioSetup(info->speed, stereo, 1, 0, info->bits); + break; + case _STREAM_STATE_PLAY : + bytesread = 0; + count = 0; + p = bufferp; + while ((bytesread < info->blocksize) && (count != -1) && + ((count = input->read(p,info->blocksize-bytesread))!=0)){ + p += count; + bytesread += count; + } + if (info->swap) { + swap_block(bufferp, bytesread); + } + + if (bytesread > 0) { + pos=input->getBytePosition(); + stamp=input->getTimeStamp(pos-bytesread); + output->audioPlay(stamp,endStamp,(char *) bufferp, bytesread); + } + + if (bytesread < info->blocksize) { + info->alldone = TRUE; + + } + break; + case _STREAM_STATE_WAIT_FOR_END: + // exit while loop + lDecoderLoop=false; + break; + default: + cout << "unknown stream state:"<<streamState<<endl; + } + } + cout << "tplay exit"<<endl; + free(info->buffer); + info->buffer = NULL; + output->audioFlush(); +} + + +int TplayPlugin::seek_impl(int second) { + int bytes_per_second; + int seconds; + int back; + + + bytes_per_second = info->speed * info->channels * (info->bits / 8); + + + + seconds = bytes_per_second * second; + back=input->seek(seconds); + + return back; +} + + +void TplayPlugin::config(const char* key,const char* value,void* user_data) { + DecoderPlugin::config(key,value,user_data); +} + + +void TplayPlugin::swap_block(char * buffer, int blocksize) { + register int i; + char c, *p; + + p = buffer; + for (i = 0; i < (blocksize / 2); i++) { + c = *p; + *p = *(p + 1); + *++p = c; + p++; + } +} + + +void TplayPlugin::read_header() { + int bytesread, count; + char *p, *bufferp; + + info->firstblock = (char*) malloc(info->blocksize * sizeof(char)); + bufferp = info->firstblock; + if (!info->forceraw) { + bytesread = 0; + count = 0; + p = bufferp; + while ((bytesread < info->blocksize) && (count != -1) && + ((count=input->read(p,info->blocksize-bytesread)) != 0)){ + p += count; + bytesread += count; + } + + if (bytesread < SUN_HDRSIZE) + cout << "Sample size is too small"<<endl; + + if (read_au(info,info->firstblock) && read_wav(info,info->firstblock)) { + if (info->verbose) + printf("Playing raw data: %ld samples/s, %d bits, %d channels.\n", + info->speed, info->bits, info->channels); + } + + if (info->swap) + swap_block(bufferp, bytesread); + + if (bytesread < info->blocksize) { + info->alldone = TRUE; + info->bytes_on_last_block = bytesread; + return; + } + + if (info->headerskip) { + count = 0; + bytesread = info->blocksize - info->headerskip; + p = info->firstblock + (info->blocksize - info->headerskip); + while ((bytesread < info->blocksize) && (count != -1) && + ((count = input->read(p,info->blocksize - bytesread)) != 0)) { + p += count; + bytesread += count; + } + } + + info->writeblock++; + info->writecount++; + } + else { + if (info->verbose) + printf("Playing raw data: %ld samples/s, %d bits, %d channels\n", + info->speed, info->bits, info->channels); + } +} + +/** + Nobody is perfect I'm too tired to fix this race +*/ + +int TplayPlugin::getTotalLength() { + float wavfilesize = input->getByteLength(); + int back=0; + + + float frequence=info->speed; + + int bits=info->bits; + + + if (bits == 16) { + wavfilesize=wavfilesize/2; + } + if (info->channels==2) { + wavfilesize=wavfilesize/2; + } + if (frequence != 0) { + back=(int)(wavfilesize/frequence); + } + return back; +} |