From bcb704366cb5e333a626c18c308c7e0448a8e69f Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features. BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdenetwork@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- .../talk/third_party/mediastreamer/portaudiocard.c | 315 +++++++++++++++++++++ 1 file changed, 315 insertions(+) create mode 100644 kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/portaudiocard.c (limited to 'kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/portaudiocard.c') diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/portaudiocard.c b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/portaudiocard.c new file mode 100644 index 00000000..9570b905 --- /dev/null +++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/portaudiocard.c @@ -0,0 +1,315 @@ +/* + Copyright (C) 2005 Remko Troncon + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include + +#include "portaudiocard.h" +#include "msossread.h" +#include "msosswrite.h" + +// Settings +#define BUFFER_SIZE 2048 + +// PortAudio settings +#define FRAMES_PER_BUFFER 256 + + +// ----------------------------------------------------------------------------- + +int readBuffer(char* buffer, char** buffer_read_p, char*buffer_write, char* buffer_end, char* target_buffer, int target_len) +{ + char *end, *tmp, *buffer_read = *buffer_read_p; + size_t remaining, len; + int read = 0; + + // First phase + tmp = buffer_read + target_len; + if (buffer_write < buffer_read) { + if (tmp > buffer_end) { + end = buffer_end; + remaining = tmp - buffer_end; + } + else { + end = tmp; + remaining = 0; + } + } + else { + end = (tmp >= buffer_write ? buffer_write : tmp); + remaining = 0; + } + //printf("end: %p\n",end); + + // Copy the data + len = end - buffer_read; + memcpy(target_buffer, buffer_read, len); + buffer_read += len; + target_buffer += len; + read += len; + + // Second phase + if (remaining > 0) { + buffer_read = buffer; + tmp = buffer_read + remaining; + len = (tmp > buffer_write ? buffer_write : tmp) - buffer_read; + memcpy(target_buffer, buffer_read, len); + buffer_read += len; + read += len; + } + + // Finish up + *buffer_read_p = buffer_read; + + return read; +} + +int writeBuffer(char* buffer, char* buffer_read, char** buffer_write_p, char* buffer_end, char* source_buffer, int source_len) +{ + char *end, *tmp, *buffer_write = *buffer_write_p; + size_t remaining, len; + int written = 0; + + // First phase + tmp = buffer_write + source_len; + if (buffer_write >= buffer_read) { + if (tmp > buffer_end) { + end = buffer_end; + remaining = tmp - buffer_end; + } + else { + end = tmp; + remaining = 0; + } + } + else { + if (tmp > buffer_read) { + printf("Warning: Dropping frame(s) %p %p\n", tmp, buffer_read); + end = buffer_read; + remaining = 0; + } + else { + end = tmp; + remaining = 0; + } + } + + len = end - buffer_write; + memcpy(buffer_write, source_buffer, len); + buffer_write += len; + source_buffer += len; + written += len; + + // Second phase + if (remaining > 0) { + buffer_write = buffer; + tmp = buffer_write + remaining; + if (tmp > buffer_read) { + printf("Warning: Dropping frame(s) %p %p\n", tmp, buffer_read); + end = buffer_read; + } + else { + end = tmp; + } + + len = end - buffer_write; + memcpy(buffer_write, source_buffer, len); + buffer_write += len; + written += len; + } + + // Finish up + *buffer_write_p = buffer_write; + return written; +} + +// ----------------------------------------------------------------------------- + +static int portAudioCallback( void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, PaTimestamp outTime, void *card_p ) +{ + PortAudioCard* card = (PortAudioCard*) card_p; + + size_t len = framesPerBuffer * Pa_GetSampleSize(paInt16); + //printf("PA::readBuffer begin %p %p %p %p %d\n",card->out_buffer,card->out_buffer_read,card->out_buffer_write,card->out_buffer_end, len); + readBuffer(card->out_buffer,&card->out_buffer_read,card->out_buffer_write,card->out_buffer_end, outputBuffer, len); + //printf("PA::readBuffer end %p %p %p %p %d\n",card->out_buffer,card->out_buffer_read,card->out_buffer_write,card->out_buffer_end, len); + writeBuffer(card->in_buffer,card->in_buffer_read,&card->in_buffer_write,card->in_buffer_end, inputBuffer, len); + return 0; +} + +// ----------------------------------------------------------------------------- + +int portaudio_card_probe(PortAudioCard *obj, int bits, int stereo, int rate) +{ + return FRAMES_PER_BUFFER * (SND_CARD(obj)->stereo ? 2 : 1) * Pa_GetSampleSize(paInt16); +} + + +int portaudio_card_open_r(PortAudioCard *obj,int bits,int stereo,int rate) +{ + fprintf(stderr,"Opening PortAudio card\n"); + + int err; + err = Pa_OpenDefaultStream(&obj->stream, 1, 1, paInt16, rate, FRAMES_PER_BUFFER, 0, portAudioCallback, obj); + if (err != paNoError) { + fprintf(stderr, "Error creating a PortAudio stream: %s\n", Pa_GetErrorText(err)); + return -1; + } + + err = Pa_StartStream(obj->stream); + if (err != paNoError) { + fprintf(stderr, "Error starting PortAudio stream: %s\n", Pa_GetErrorText(err)); + Pa_CloseStream(obj->stream); + obj->stream = NULL; + return -1; + } + + SND_CARD(obj)->bits = 16; + SND_CARD(obj)->stereo = 0; + SND_CARD(obj)->rate = rate; + // Should this be multiplied by Pa_GetMinNumBuffers(FRAMES_PER_BUFFER,sampleRate) ? + SND_CARD(obj)->bsize = FRAMES_PER_BUFFER * (SND_CARD(obj)->stereo ? 2 : 1) * Pa_GetSampleSize(paInt16); + + return 0; + +} + +void portaudio_card_close_r(PortAudioCard *obj) +{ + fprintf(stderr, "Closing PortAudio card\n"); + if (obj->stream) { + Pa_StopStream(obj->stream); + Pa_CloseStream(obj->stream); + obj->stream = NULL; + } +} + +int portaudio_card_open_w(PortAudioCard *obj,int bits,int stereo,int rate) +{ +} + +void portaudio_card_close_w(PortAudioCard *obj) +{ +} + +void portaudio_card_destroy(PortAudioCard *obj) +{ + snd_card_uninit(SND_CARD(obj)); + free(obj->in_buffer); + free(obj->out_buffer); +} + +gboolean portaudio_card_can_read(PortAudioCard *obj) +{ + return obj->in_buffer_read != obj->in_buffer_write; +} + +int portaudio_card_read(PortAudioCard *obj,char *buf,int size) +{ + //printf("read begin %p %p %p %p %d\n",obj->in_buffer,obj->in_buffer_read,obj->in_buffer_write,obj->in_buffer_end, size); + return readBuffer(obj->in_buffer,&obj->in_buffer_read,obj->in_buffer_write,obj->in_buffer_end, buf, size); + //printf("read end %p %p %p %p %d\n",obj->in_buffer,obj->in_buffer_read,obj->in_buffer_write,obj->in_buffer_end, size); +} + +int portaudio_card_write(PortAudioCard *obj,char *buf,int size) +{ + //printf("writeBuffer begin %p %p %p %p %d\n",obj->out_buffer,obj->out_buffer_read,obj->out_buffer_write,obj->out_buffer_end, size); + return writeBuffer(obj->out_buffer,obj->out_buffer_read,&obj->out_buffer_write,obj->out_buffer_end, buf, size); + //printf("writeBuffer end %p %p %p %p %d\n",obj->out_buffer,obj->out_buffer_read,obj->out_buffer_write,obj->out_buffer_end, size); +} + +void portaudio_card_set_level(PortAudioCard *obj,gint way,gint a) +{ +} + +gint portaudio_card_get_level(PortAudioCard *obj,gint way) +{ + return 0; +} + +void portaudio_card_set_source(PortAudioCard *obj,int source) +{ +} + +MSFilter *portaudio_card_create_read_filter(PortAudioCard *card) +{ + MSFilter *f=ms_oss_read_new(); + ms_oss_read_set_device(MS_OSS_READ(f),SND_CARD(card)->index); + return f; +} + +MSFilter *portaudio_card_create_write_filter(PortAudioCard *card) +{ + MSFilter *f=ms_oss_write_new(); + ms_oss_write_set_device(MS_OSS_WRITE(f),SND_CARD(card)->index); + return f; +} + + +SndCard* portaudio_card_new() +{ + // Basic stuff + PortAudioCard* obj= g_new0(PortAudioCard,1); + SndCard* base= SND_CARD(obj); + snd_card_init(base); + base->card_name=g_strdup_printf("PortAudio Card"); + base->_probe=(SndCardOpenFunc)portaudio_card_probe; + base->_open_r=(SndCardOpenFunc)portaudio_card_open_r; + base->_open_w=(SndCardOpenFunc)portaudio_card_open_w; + base->_can_read=(SndCardPollFunc)portaudio_card_can_read; + base->_read=(SndCardIOFunc)portaudio_card_read; + base->_write=(SndCardIOFunc)portaudio_card_write; + base->_close_r=(SndCardCloseFunc)portaudio_card_close_r; + base->_close_w=(SndCardCloseFunc)portaudio_card_close_w; + base->_set_rec_source=(SndCardMixerSetRecSourceFunc)portaudio_card_set_source; + base->_set_level=(SndCardMixerSetLevelFunc)portaudio_card_set_level; + base->_get_level=(SndCardMixerGetLevelFunc)portaudio_card_get_level; + base->_destroy=(SndCardDestroyFunc)portaudio_card_destroy; + base->_create_read_filter=(SndCardCreateFilterFunc)portaudio_card_create_read_filter; + base->_create_write_filter=(SndCardCreateFilterFunc)portaudio_card_create_write_filter; + + // Initialize stream + obj->stream = NULL; + + // Initialize buffers + obj->out_buffer = (char*) malloc(sizeof(char)*BUFFER_SIZE); + obj->out_buffer_read = obj->out_buffer_write = obj->out_buffer; + obj->out_buffer_end = obj->out_buffer + BUFFER_SIZE; + obj->in_buffer = (char*) malloc(sizeof(char)*BUFFER_SIZE); + obj->in_buffer_read = obj->in_buffer_write = obj->in_buffer; + obj->in_buffer_end = obj->in_buffer + BUFFER_SIZE; + + return base; +} + +gint portaudio_card_manager_init(SndCardManager *manager, gint tabindex) +{ + // Initialize portaudio lib + int err = Pa_Initialize(); + if (err != paNoError) { + fprintf(stderr,"Error initializing PortAudio: %s\n",Pa_GetErrorText(err)); + return 0; + } + + // Create new card + manager->cards[0]=portaudio_card_new(); + manager->cards[0]->index=0; + + return 1; +} -- cgit v1.2.1