/* * filemembers.cxx * * Various file-based Members for OpenMCU * * Copyright (C) 2003 Post Increment * * The contents of this file are subject to the Mozilla Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is Portable Windows Library. * * The Initial Developer of the Original Code is Post Increment * * Portions of this code were written by Post Increment (http://www.postincrement.com) * with the assistance of funding from Citron Networks (http://www.citron.com.tw) * * Portions are Copyright (C) 1993 Free Software Foundation, Inc. * All Rights Reserved. * * Contributor(s): Derek J Smithies (derek@indranet.co.nz) * * $Log: filemembers.cxx,v $ * Revision 2.2 2006/01/16 09:43:05 csoutheren * Fixed problem with crashes at end of playing files * * Revision 2.1 2004/05/26 06:54:31 csoutheren * Changed to be a PHTTPServiceProcess * Added ability to play WAV files on member entry and exit * Added additional documentation on all classes * Preparation for re-introducing video * */ #include #include "conference.h" #include "filemembers.h" ConferenceSoundCardMember::ConferenceSoundCardMember() #ifdef _WIN32 #pragma warning(push) #pragma warning(disable:4355) #endif : ConferenceMember(this) #ifdef _WIN32 #pragma warning(pop) #endif { // open the default audio device PString deviceName = PSoundChannel::GetDefaultDevice(PSoundChannel::Player); soundDevice.Open(deviceName, PSoundChannel::Player, 1, 8000, 16); // start a thread to read from the conference and write to default audio device if (!soundDevice.IsOpen()) { thread = NULL; } else { running = TRUE; thread = PThread::Create(PCREATE_NOTIFIER(Thread), 0, PThread::AutoDeleteThread); } } ConferenceSoundCardMember::~ConferenceSoundCardMember() { Unlisten(); } void ConferenceSoundCardMember::Unlisten() { if (conference->RemoveMember(this)) conference->GetManager().RemoveConference(conference->GetID()); if ((thread != NULL) && running) { running = FALSE; thread->WaitForTermination(); thread = NULL; } } void ConferenceSoundCardMember::Thread(PThread &, INT) { AudioDelay audioDelay; PBYTEArray pcmData(480); soundDevice.SetBuffers(480, 3); while (running) { // read a block of data ReadAudio(pcmData.GetPointer(), pcmData.GetSize()); // write the data to the sound card if (soundDevice.IsOpen()) soundDevice.Write(pcmData.GetPointer(), pcmData.GetSize()); audioDelay.Delay(pcmData.GetSize() / 16); } ConferenceManager & mgr = conference->GetManager(); mgr.RemoveMember(conference->GetID(), this); } /////////////////////////////////////////////////////////////////////////// ConferenceFileMember::ConferenceFileMember(const PFilePath & _fn, PFile::OpenMode _mode) #ifdef _WIN32 #pragma warning(push) #pragma warning(disable:4355) #endif : ConferenceMember((void *)this), filename(_fn), mode(_mode) #ifdef _WIN32 #pragma warning(pop) #endif { // open the default audio device if (!file.Open(filename, mode)) { PTRACE(1, "Cannot open WAV file " << filename); return; } PTRACE(1, "Playing WAV file " << filename); running = TRUE; if (mode == PFile::WriteOnly) thread = PThread::Create(PCREATE_NOTIFIER(WriteThread), 0, PThread::AutoDeleteThread); else thread = PThread::Create(PCREATE_NOTIFIER(ReadThread), 0, PThread::AutoDeleteThread); } ConferenceFileMember::~ConferenceFileMember() { Unlisten(); } void ConferenceFileMember::Unlisten() { if (conference->RemoveMember(this)) conference->GetManager().RemoveConference(conference->GetID()); if ((thread != NULL) && running) { running = FALSE; thread->WaitForTermination(); thread = NULL; } } void ConferenceFileMember::WriteThread(PThread &, INT) { PBYTEArray pcmData(480); AudioDelay audioDelay; while (running) { // read a block of data ReadAudio(pcmData.GetPointer(), pcmData.GetSize()); // write to the file if (file.IsOpen()) file.Write(pcmData.GetPointer(), pcmData.GetSize()); // and delay audioDelay.Delay(pcmData.GetSize() / 16); } ConferenceManager & mgr = conference->GetManager(); mgr.RemoveMember(conference->GetID(), this); } void ConferenceFileMember::ReadThread(PThread &, INT) { PBYTEArray pcmData(480); AudioDelay audioDelay; while (running) { if (!file.IsOpen()) break; // read a block of data from the file if (!file.Read(pcmData.GetPointer(), pcmData.GetSize())) break; // read a block of data WriteAudio(pcmData.GetPointer(), pcmData.GetSize()); // and delay audioDelay.Delay(pcmData.GetSize() / 16); } ConferenceManager & mgr = conference->GetManager(); mgr.RemoveMember(conference->GetID(), this); }