Author: derek Date: Mon Sep 18 19:46:52 2006 New Revision: 99 Modified: sofaswitch/trunk/sound/comms.cxx sofaswitch/trunk/sound/comms.h sofaswitch/trunk/sound/docs.cfg sofaswitch/trunk/sound/main.cxx sofaswitch/trunk/sound/main.h Log: Lots of fixes. Works correctly now. Remove local variable of currentController from comms. Modified: sofaswitch/trunk/sound/comms.cxx ============================================================================== --- sofaswitch/trunk/sound/comms.cxx (original) +++ sofaswitch/trunk/sound/comms.cxx Mon Sep 18 19:46:52 2006 @@ -39,100 +39,100 @@ //////////////////////////////////////////////////////////////////////////////// Comms::Comms(LaunchNewId & lid) - : MessageFrame(lid, 63000) + : MessageFrame(lid, 63000) { - stopByExit = FALSE; - stopByHangup = TRUE; - - tar = NULL; - taw = NULL; + stopByExit = FALSE; + stopByHangup = TRUE; + + tar = NULL; + taw = NULL; } Comms::~Comms() { - PTRACE(3, "Comms destructor "); - Terminate(); - WaitForTermination(); - PWaitAndSignal m(lockReaderWriter); - - if (tar != NULL) - delete tar; - - if (taw != NULL) - delete taw; + PTRACE(3, "Comms destructor "); + Terminate(); + WaitForTermination(); + PWaitAndSignal m(lockReaderWriter); + + if (tar != NULL) + delete tar; + + if (taw != NULL) + delete taw; } void Comms::OnTermination() { - PTRACE(3, "Comms sound thread has ended"); - - Terminate(); + PTRACE(3, "Comms sound thread has ended"); + + Terminate(); } - + void Comms::Terminate() { - PTRACE(3, "Terminate comms instance "); - PWaitAndSignal m(lockReaderWriter); - - if (tar != NULL) { - PTRACE(3, "Set tar to terminate"); - tar->Terminate(); - } else { - PTRACE(3, "NO tar to terminate"); - } - - if (taw != NULL) { - PTRACE(3, "Set taw to terminate"); - taw->Terminate(); - } else { - PTRACE(3, "NO taw to terminate"); - } + PTRACE(3, "Terminate comms instance "); + PWaitAndSignal m(lockReaderWriter); + + if (tar != NULL) { + PTRACE(3, "Set tar to terminate"); + tar->Terminate(); + } else { + PTRACE(3, "NO tar to terminate"); + } + + if (taw != NULL) { + PTRACE(3, "Set taw to terminate"); + taw->Terminate(); + } else { + PTRACE(3, "NO taw to terminate"); + } } void Comms::WaitForTermination() { - BOOL keepGoing = TRUE; - while (keepGoing) { - { - PTRACE(6, "Comms\tWaitForTermination"); - PWaitAndSignal m(lockReaderWriter); - if (tar != NULL) { - keepGoing = !tar->IsTerminated(); - } - if (taw != NULL) { - keepGoing = keepGoing || (!taw->IsTerminated()); - } - if ((taw == NULL) && (tar == NULL)) - keepGoing = !MessageFrame::IsTerminated(); + BOOL keepGoing = TRUE; + while (keepGoing) { + { + PTRACE(6, "Comms\tWaitForTermination"); + PWaitAndSignal m(lockReaderWriter); + if (tar != NULL) { + keepGoing = !tar->IsTerminated(); + } + if (taw != NULL) { + keepGoing = keepGoing || (!taw->IsTerminated()); + } + if ((taw == NULL) && (tar == NULL)) + keepGoing = !MessageFrame::IsTerminated(); + } + PThread::Sleep(100); } - PThread::Sleep(100); - } - - MessageFrame::WaitForTermination(); + + MessageFrame::WaitForTermination(); } void Comms::SendMessageToController(PString & message) { - SendThisMessageTo(message, currentController); + SendThisMessageTo(message, GetRemoteController()); } void Comms::SilentlyEndAll() { - + } BOOL Comms::SendDtmf(const PString & dtmfVals) { - cout << "Received DTMF from the controller of " << dtmfVals << " " << PTime(); + cerr << "At " << PTime() << " received DTMF from the controller of ---->>>|||" << dtmfVals << endl; return TRUE; } void Comms::ProcessRequestNewId(PStringArray &cmds, PString & sender) { - currentController = sender; + SetRemoteController(sender); PString answer = PString("REQUESTNEWID ") + Audio::Current().GetNodeId(); SendThisMessageTo(answer, sender); return; @@ -140,101 +140,108 @@ void Comms::ProcessHangup(PStringArray &cmds, PString & sender) { - stopByExit = TRUE; - SetRemoteController(sender); - Terminate(); + stopByExit = TRUE; + SetRemoteController(sender); + Terminate(); } void Comms::ProcessCallNode(PStringArray &cmds, PString & sender) { - SendThisMessageTo("Failed to do " + cmds[0] + " as we are a sound handler", "", sender); - return; + SendThisMessageTo("Failed to do " + cmds[0] + " as we are a sound handler", "", sender); + return; } -void Comms::ProcessStatusQuery(PStringArray &cmds, PString & sender) +void Comms::GetStatusInformation(PString & statusInfo) { - PStringStream countMessage; - countMessage << "sound card handler" << endl; - { - PWaitAndSignal m(lockReaderWriter); - if (tar != NULL) - countMessage << PString("Reader = ") << PString(tar->GetCountPackets()) - << PString(" packets"); - else - countMessage << PString(" no read count available"); - countMessage << endl << endl; + PStringStream countMessage; + countMessage << "sound card handler" << endl; + { + PWaitAndSignal m(lockReaderWriter); + if (tar != NULL) + countMessage << PString("Reader = ") << PString(tar->GetCountPackets()) + << PString(" packets"); + else + countMessage << PString(" no read count available"); + countMessage << endl << endl; + + if (taw != NULL) + countMessage << PString("writer = ") << PString(taw->GetCountPackets()) + << PString(" packets"); + else + countMessage << PString(" no write count available"); + countMessage << endl << endl; + } + PString partner = GetMediaPartner(); + countMessage << "other node is: " << (partner.IsEmpty() ? " not specified" : partner); + countMessage << endl << endl << "............................ "; - if (taw != NULL) - countMessage << PString("writer = ") << PString(taw->GetCountPackets()) - << PString(" packets"); - else - countMessage << PString(" no write count available"); - countMessage << endl << endl; - } - PString partner = GetMediaPartner(); - countMessage << "other node is: " << (partner.IsEmpty() ? " not specified" : partner); - countMessage << endl << endl << "............................ "; + statusInfo= countMessage; +} - SendThisMessageTo(countMessage, sender); +void Comms::ProcessStatusQuery(PStringArray &cmds, PString & sender) +{ + PString statusInfo; + GetStatusInformation(statusInfo); + SendThisMessageTo(statusInfo, sender); } void Comms::ProcessDuration(PStringArray &cmds, PString & sender) { - SendThisMessageTo(cmds[0] + PString(" sorry, duration not implemented "), "", sender); + SendThisMessageTo(cmds[0] + PString(" sorry, duration not implemented "), "", sender); } void Comms::ProcessIdentify(PStringArray &cmds, PString & sender) { - SendThisMessageTo(cmds[0] + PString(" node for handling sound port comms"), "", sender); + SendThisMessageTo(cmds[0] + PString(" node for handling sound port comms"), "", sender); } void Comms::ProcessDebug(PStringArray &cmds, PString & sender) { - SendThisMessageTo(cmds[0] + PString(" sorry, debug not implemented "), "", sender); + SendThisMessageTo(cmds[0] + PString(" sorry, debug not implemented "), "", sender); } void Comms::ProcessAnswer(PStringArray &cmds, PString & sender) { - SendThisMessageTo(cmds[0] + PString(" sorry, answer not implemented "), "", sender); + SendThisMessageTo(cmds[0] + PString(" sorry, answer not implemented "), "", sender); } void Comms::ProcessQuitNow(PStringArray &cmds, PString & sender) { - stopByExit = TRUE; - SetRemoteController(sender); - Terminate(); + stopByExit = TRUE; + SetRemoteController(sender); + Terminate(); } BOOL Comms::ConstructReader(PSoundChannel & sound) { - PWaitAndSignal m(lockReaderWriter); - - tar = new TestAudioRead(audioSocket, sound); - PThread::Sleep(100); - - if (tar->IsTerminated()) { - PTRACE(3, "OOPS TestAudioRead has finished real quick"); - return FALSE; - } - return TRUE; + PWaitAndSignal m(lockReaderWriter); + + tar = new TestAudioRead(audioSocket, sound); + PThread::Sleep(100); + + if (tar->IsTerminated()) { + PTRACE(3, "OOPS TestAudioRead has finished real quick"); + return FALSE; + } + return TRUE; } BOOL Comms::ConstructWriter(PSoundChannel & sound) { - PWaitAndSignal m(lockReaderWriter); - - taw = new TestAudioWrite(audioSocket, sound); - PThread::Sleep(100); - - if (taw->IsTerminated()) { - PTRACE(3, "OOPS TestAudioWrite has finished real quick"); - return FALSE; - } - - return TRUE; + PWaitAndSignal m(lockReaderWriter); + + taw = new TestAudioWrite(audioSocket, sound); + PThread::Sleep(100); + + if (taw->IsTerminated()) { + PTRACE(3, "OOPS TestAudioWrite has finished real quick"); + return FALSE; + } + + return TRUE; } Modified: sofaswitch/trunk/sound/comms.h ============================================================================== --- sofaswitch/trunk/sound/comms.h (original) +++ sofaswitch/trunk/sound/comms.h Mon Sep 18 19:46:52 2006 @@ -30,8 +30,8 @@ #ifdef P_USE_PRAGMA #pragma interface #endif - + #include <ptlib.h> #include <ptlib/sound.h> #include <sofa/messages.h> @@ -46,115 +46,116 @@ device */ class Comms : public MessageFrame { - + public: - /**Constuctor */ - Comms(LaunchNewId & lid); - - /**Terminate, wait for threads to exit, and destroy the tar & taw - threads */ - ~Comms(); - - /**Open the test audio read thread.. - Return TRUE if successfull, FALSE on failure */ - BOOL ConstructReader(PSoundChannel & sound); - - /**Open the test audio write thread. - Return TRUE if successfull, FALSE on failure */ - BOOL ConstructWriter(PSoundChannel & sound); - - /**Shut down the read and write methods */ - virtual void Terminate(); - - /**Block the calling process, and return when the threads have - terminated */ - virtual void WaitForTermination(); - - /**Send this message to the current controller. Typically, this will be a - * message stating that dtmf has been read from the keyboard. */ - void SendMessageToController(PString & message); - - /**Report if we were stopped by hangup */ - BOOL StoppedByHangup() { return stopByHangup; } - - /**Report if we were stopped by a shutdown request */ - BOOL StoppedByExit() { return stopByExit; } - + /**Constuctor */ + Comms(LaunchNewId & lid); + + /**Terminate, wait for threads to exit, and destroy the tar & taw + threads */ + ~Comms(); + + /**Open the test audio read thread.. + Return TRUE if successfull, FALSE on failure */ + BOOL ConstructReader(PSoundChannel & sound); + + /**Open the test audio write thread. + Return TRUE if successfull, FALSE on failure */ + BOOL ConstructWriter(PSoundChannel & sound); + + /**Shut down the read and write methods */ + virtual void Terminate(); + + /**Block the calling process, and return when the threads have + terminated */ + virtual void WaitForTermination(); + + /**Send this message to the current controller. Typically, this will be a + * message stating that dtmf has been read from the keyboard. */ + void SendMessageToController(PString & message); + + /**Report if we were stopped by hangup */ + BOOL StoppedByHangup() { return stopByHangup; } + + /**Report if we were stopped by a shutdown request */ + BOOL StoppedByExit() { return stopByExit; } + + /**Get the information that is replied when a status query happens. There + are two sources of a status query - the remote controller or the + keybaord */ + void GetStatusInformation(PString & statusInfo); + protected: - - /**We have a DTMF string from our current master. Display this DTMF on the console. - We always return TRUE, cause we can always do this right. */ + + /**We have a DTMF string from our current master. Display this DTMF on the console. + We always return TRUE, cause we can always do this right. */ virtual BOOL SendDtmf(const PString & dtmfVals); - - /**we have received a command asking us to provide the id of a new - communications nodes, that will be controlled only by the remote - node */ - virtual void ProcessRequestNewId(PStringArray &cmds, PString & sender); - - /**The supervisor has completed. This method is called when this - supervisor instance terminates. Since there is only one - Supervisor instance, this method is only every called once. */ - virtual void OnTermination(); - - /**we have received a hangup message, so end the call */ - virtual void ProcessHangup(PStringArray &cmds, PString & sender); - - /**we have received a Call other Node command, so do it and reply - accordingly*/ - virtual void ProcessCallNode(PStringArray &cmds, PString & sender); - - /**we have received a query status command, so do it and reply accordingly*/ - virtual void ProcessStatusQuery(PStringArray &cmds, PString & sender); - - /**we have received a command queryig the current call duration , - so extract information & answer */ - virtual void ProcessDuration(PStringArray &cmds, PString & sender); - - /**we have received a command requesting that we identify ourselves - so do it and reply accordingly*/ - virtual void ProcessIdentify(PStringArray &cmds, PString & sender); - - /**we have received a command which enables/disables debug - information so install as required and reply accordingly*/ - virtual void ProcessDebug(PStringArray &cmds, PString & sender); - - /**we have received a command advising us how to answer to the - incoming call, so we act as required and reply accordingly*/ - virtual void ProcessAnswer(PStringArray &cmds, PString & sender); - - /**we have received a command advising us that we are to end now */ - virtual void ProcessQuitNow(PStringArray &cmds, PString & sender); - - /**Some MessageFrame instances do not have the permission to quit - now. This virtual method determines if this instance is permitted to - exit the program. This supervisor has permision to end all. */ - virtual BOOL OkToQuitNow() { return TRUE; } - - /**We have a comms error, so just close everything right now. Send - no message to the remote node - just end end end. */ - virtual void SilentlyEndAll(); - - /**@name manage the audio streams of data to the sound device */ - //@{ - /**class that writes audio data to sound device */ - TestAudioWrite *taw; - - /**Class that reads audio from the sound device */ - TestAudioRead *tar; - - /**Mutex which protects access to the tar/taw variables */ - PMutex lockReaderWriter; - //@} - - /**The terminating condition was */ - BOOL stopByHangup; - - /**The terminating condition was */ - BOOL stopByExit; - - /**The id of the last node who has requested a sound worker. This node will - receive all dtmf messages. */ - PString currentController; + + /**we have received a command asking us to provide the id of a new + communications nodes, that will be controlled only by the remote + node */ + virtual void ProcessRequestNewId(PStringArray &cmds, PString & sender); + + /**The supervisor has completed. This method is called when this + supervisor instance terminates. Since there is only one + Supervisor instance, this method is only every called once. */ + virtual void OnTermination(); + + /**we have received a hangup message, so end the call */ + virtual void ProcessHangup(PStringArray &cmds, PString & sender); + + /**we have received a Call other Node command, so do it and reply + accordingly*/ + virtual void ProcessCallNode(PStringArray &cmds, PString & sender); + + /**we have received a query status command, so do it and reply accordingly*/ + virtual void ProcessStatusQuery(PStringArray &cmds, PString & sender); + + /**we have received a command queryig the current call duration , + so extract information & answer */ + virtual void ProcessDuration(PStringArray &cmds, PString & sender); + + /**we have received a command requesting that we identify ourselves + so do it and reply accordingly*/ + virtual void ProcessIdentify(PStringArray &cmds, PString & sender); + + /**we have received a command which enables/disables debug + information so install as required and reply accordingly*/ + virtual void ProcessDebug(PStringArray &cmds, PString & sender); + + /**we have received a command advising us how to answer to the + incoming call, so we act as required and reply accordingly*/ + virtual void ProcessAnswer(PStringArray &cmds, PString & sender); + + /**we have received a command advising us that we are to end now */ + virtual void ProcessQuitNow(PStringArray &cmds, PString & sender); + + /**Some MessageFrame instances do not have the permission to quit + now. This virtual method determines if this instance is permitted to + exit the program. This supervisor has permision to end all. */ + virtual BOOL OkToQuitNow() { return TRUE; } + + /**We have a comms error, so just close everything right now. Send + no message to the remote node - just end end end. */ + virtual void SilentlyEndAll(); + + /**@name manage the audio streams of data to the sound device */ + //@{ + /**class that writes audio data to sound device */ + TestAudioWrite *taw; + + /**Class that reads audio from the sound device */ + TestAudioRead *tar; + + /**Mutex which protects access to the tar/taw variables */ + PMutex lockReaderWriter; + //@} + + /**The terminating condition was */ + BOOL stopByHangup; + + /**The terminating condition was */ + BOOL stopByExit; }; #endif Modified: sofaswitch/trunk/sound/docs.cfg ============================================================================== --- sofaswitch/trunk/sound/docs.cfg (original) +++ sofaswitch/trunk/sound/docs.cfg Mon Sep 18 19:46:52 2006 @@ -190,7 +190,7 @@ #--------------------------------------------------------------------------- CLASS_DIAGRAMS = YES HIDE_UNDOC_RELATIONS = YES -HAVE_DOT = YES +HAVE_DOT = NO CLASS_GRAPH = YES COLLABORATION_GRAPH = YES UML_LOOK = YES Modified: sofaswitch/trunk/sound/main.cxx ============================================================================== --- sofaswitch/trunk/sound/main.cxx (original) +++ sofaswitch/trunk/sound/main.cxx Mon Sep 18 19:46:52 2006 @@ -24,56 +24,78 @@ #define new PNEW ///////////////////////////////////////////////////////////////////////////// +UserInterface::UserInterface(Comms & _comms, + PSoundChannel &_player, + PSoundChannel & _recorder) + : PThread(1000, NoAutoDeleteThread), + comms(_comms), + player(_player), + recorder(_recorder) +{ + endNow = FALSE; + Resume(); +} + void UserInterface::Main() { - - PConsoleChannel console(PConsoleChannel::StandardInput); - - cout << "This program will waits for user commands, and generates DTMF messages as required" << endl; - - - console.SetReadTimeout(500); - - PThread::Yield(); - - PStringStream help; - help << "Press : " << endl - << " H or ? help on this interface" << endl - << " D dtmf Send dtmf message text to the controller" - << " X or Q exit " << endl; - - - cout << endl << endl << help; - - for (;(!endNow) && (!comms.IsTerminated());) { - char ch = console.ReadChar(); - - if (endNow) - break; - - switch (tolower(ch)) { - case 'd' : - { - PString message; - console >> message; - comms.SendMessageToController(message); - cout << "Command ? " << flush; - } - break; - case 'x' : - case 'q' : - cout << "Exiting." << endl; - PTRACE(3, "End this program now "); - return; + + PConsoleChannel console(PConsoleChannel::StandardInput); + + cout << "This program will waits for user commands, and generates DTMF messages as required" << endl; + + + console.SetReadTimeout(500); + + PThread::Yield(); + + PStringStream help; + help << "Press : " << endl + << " H or ? help on this interface" << endl + << " D dtmf Send dtmf message text to the controller" << endl + << " S Report the status of this device" << endl + << " X or Q exit " << endl; + + + cout << endl << endl << help; + + for (;!endNow;) { + char ch = console.ReadChar(); + + if (endNow) break; - case '?' : - case 'h' : - cout << help << endl; - cout << "Command ? " << flush; - default: - break; - } // end switch - } // end for + + switch (tolower(ch)) { + case 'd' : { + PString message; + console >> message; + message = PString("SENDDTMF ") + message; + comms.SendMessageToController(message); + cout << "Command ? " << flush; + } + break; + case 'x' : + case 'q' : { + endNow = TRUE; + PTRACE(3, "End this program now "); + } + break; + case 's' : { + PString status; + comms.GetStatusInformation(status); + cout << status << endl; + } + break; + case '?' : + case 'h' : + cout << help << endl; + cout << "Command ? " << flush; + default: + break; + } // end switch + } // end for + + comms.Terminate(); + cerr << "Exiting." << endl; } void UserInterface::Terminate() @@ -83,174 +105,201 @@ ///////////////////////////////////////////////////////////////////////////// Audio::Audio() - : PProcess("Derek Smithies code factory", "audio", - MAJOR_VERSION, MINOR_VERSION, BUILD_TYPE, BUILD_NUMBER) + : PProcess("Derek Smithies code factory", "audio", + MAJOR_VERSION, MINOR_VERSION, BUILD_TYPE, BUILD_NUMBER) { - + } PCREATE_PROCESS(Audio) - -void Audio::Main() + + void Audio::Main() { - PArgList & args = GetArguments(); - args.Parse( - "d-sounddevice:" - "s-server:" - "i-id:" - "-password:" - "h. " + PArgList & args = GetArguments(); + args.Parse( + "d-sounddevice:" + "s-server: " + "i-id: " + "h. " + "l. " #if PTRACING - "o-output:" "-no-output." - "t-trace." "-no-trace." + "o-output: " + "t-trace. " #endif - "v. " - "s: "); - - if (args.HasOption('h')) { - cout << "usage: audio " - << endl - << " -d dev : use this device " << endl - << " -h : get help on usage " << endl - << " -v : report program version " << endl - << " -s --server srv : server to connect to\n" - << " -i --id ## : id we are labelled with \n" - << " --password pwd : password to use\n" + "v. " + "s: "); + + if (args.HasOption('h')) { + cout << "usage: audio " + << endl + << " -d dev : use this device " << endl + << " -h : get help on usage " << endl + << " -v : report program version " << endl + << " -s --server srv : server to connect to" << endl + << " -i --id ## : id we are labelled with" << endl + << " -l : list available sound devices" << endl #if PTRACING - << " -t --trace : Enable trace, use multiple times for more detail" << endl - << " -o --output : File for trace output, default is stderr" << endl + << " -t --trace : Enable trace, use multiple times for more detail" << endl + << " -o --output : File for trace output, default is stderr" << endl #endif - << endl; - return; - } - - - PTrace::Initialise(args.GetOptionCount('t'), - args.HasOption('o') ? (const char *)args.GetOptionString('o') : NULL, - PTrace::Blocks | PTrace::Timestamp | PTrace::Thread | PTrace::FileAndLine); - - if (args.HasOption('v')) { - cout << endl - << "Product Name: " << (const char *)GetName() << endl - << "Manufacturer: " << (const char *)GetManufacturer() << endl - << "Version : " << (const char *)GetVersion(TRUE) << endl - << "System : " << (const char *)GetOSName() << '-' - << (const char *)GetOSHardware() << ' ' - << (const char *)GetOSVersion() << endl << endl; return; - } - - - cout << "Audio Endpoint for SofaSwitch\n"; - - - devName = args.GetOptionString('d'); - if (devName.IsEmpty()) - devName = PSoundChannel::GetDefaultDevice(PSoundChannel::Player); - - PSoundChannel::Directions dir; - PStringArray namesPlay; - dir = PSoundChannel::Player; - namesPlay = PSoundChannel::GetDeviceNames(dir); - - - if (namesPlay.GetStringsIndex(devName) == P_MAX_INDEX) { - cout << "could not find " << devName << " in list of available play devices - abort program" << endl; - cout << "available device names are " << endl; - for(PINDEX i = 0; i < namesPlay.GetSize(); i++) - cout << namesPlay[i] << endl; - return; - } - - PStringArray namesRecord; - dir = PSoundChannel::Recorder; - namesRecord = PSoundChannel::GetDeviceNames(dir); - - if (namesRecord.GetStringsIndex(devName) == P_MAX_INDEX) { - cout << "could not find " << devName << " in list of available record devices - abort program" << endl; - cout << "available device names are " << endl; - for(PINDEX i = 0; i < namesRecord.GetSize(); i++) - cout << namesRecord[i] << endl; - return; - } - - PTRACE(3, "Audio\tTest device " << devName); - - PString server; - if (args.HasOption("server")) { - server = args.GetOptionString("server"); - PTRACE(3, "server is " << server); - } else { - server = "localhost"; - PTRACE(3, "Select a default server of localhost"); - } - - PString ourId; - if (args.HasOption("id")) { - nodeId = args.GetOptionString("id"); - PTRACE(3, "our ID is " << ourId); - } else { - nodeId = "sound"; - PTRACE(3, "Select a default ID of " << ourId); - } - - ourId = server + "/" + ourId; + } - PString ourPassword; - if (args.HasOption("password")) { - ourPassword = args.GetOptionString("password"); - PTRACE(3, "password is " << ourPassword); - } else { - ourPassword = "audio"; + + PTrace::Initialise(args.GetOptionCount('t'), + args.HasOption('o') ? (const char *)args.GetOptionString('o') : NULL, + PTrace::Blocks | PTrace::Timestamp | PTrace::Thread | PTrace::FileAndLine); + + if (args.HasOption('v')) { + cout << endl + << "Product Name: " << (const char *)GetName() << endl + << "Manufacturer: " << (const char *)GetManufacturer() << endl + << "Version : " << (const char *)GetVersion(TRUE) << endl + << "System : " << (const char *)GetOSName() << '-' + << (const char *)GetOSHardware() << ' ' + << (const char *)GetOSVersion() << endl + << endl; + return; + } + + + cout << "Audio Endpoint for SofaSwitch\n"; + + if (args.HasOption('l')) { + cout << "\n List of play devices\n"; + + PSoundChannel::Directions dir; + PStringArray namesPlay, namesRecord; + + dir = PSoundChannel::Player; + namesPlay = PSoundChannel::GetDeviceNames(dir); + for (PINDEX i = 0; i < namesPlay.GetSize(); i++) + cout << " \"" << namesPlay[i] << "\"\n"; + + cout << "The default play device is \"" << PSoundChannel::GetDefaultDevice(dir) << "\"\n"; + + cout << "\nList of Record devices\n"; + + dir = PSoundChannel::Recorder; + namesRecord = PSoundChannel::GetDeviceNames(dir); + for (PINDEX i = 0; i < namesRecord.GetSize(); i++) + cout << " \"" << namesRecord[i] << "\"\n"; + + cout << "The default record device is \"" << PSoundChannel::GetDefaultDevice(dir) << "\"\n\n"; + } + + + + devName = args.GetOptionString('d'); + if (devName.IsEmpty()) + devName = PSoundChannel::GetDefaultDevice(PSoundChannel::Player); + + PSoundChannel::Directions dir; + PStringArray namesPlay; + dir = PSoundChannel::Player; + namesPlay = PSoundChannel::GetDeviceNames(dir); + + + if (namesPlay.GetStringsIndex(devName) == P_MAX_INDEX) { + cout << "could not find " << devName << " in list of available play devices - abort program" << endl; + cout << "available device names are " << endl; + for(PINDEX i = 0; i < namesPlay.GetSize(); i++) + cout << namesPlay[i] << endl; + return; + } + + PStringArray namesRecord; + dir = PSoundChannel::Recorder; + namesRecord = PSoundChannel::GetDeviceNames(dir); + + if (namesRecord.GetStringsIndex(devName) == P_MAX_INDEX) { + cout << "could not find " << devName << " in list of available record devices - abort program" << endl; + cout << "available device names are " << endl; + for(PINDEX i = 0; i < namesRecord.GetSize(); i++) + cout << namesRecord[i] << endl; + return; + } + + PTRACE(3, "Audio\tTest device " << devName); + + PString server; + if (args.HasOption("server")) { + server = args.GetOptionString("server"); + PTRACE(3, "server is " << server); + } else { + server = "localhost"; + PTRACE(3, "Select a default server of localhost"); + } + + PString ourId; + if (args.HasOption("id")) { + nodeId = args.GetOptionString("id"); + PTRACE(3, "our ID is " << ourId); + } else { + nodeId = "sound"; + PTRACE(3, "Select a default ID of " << ourId); + } + + ourId = server + "/" + nodeId; + + PString ourPassword = "audio"; PTRACE(3, "Select a default password of audio"); - } - - LaunchNewId lid(ourId, ourPassword); - Comms c(lid); - c.Resume(); - - PTRACE(3, "Constructed the comms device "); - - - if (!OpenSoundDevice(soundRecorder, PSoundChannel::Recorder)) - return; - - if (!OpenSoundDevice(soundPlayer, PSoundChannel::Player)) - return; - - if (!c.ConstructReader(soundRecorder)) { - cerr << "Failed to consturct a reader for audio.... OOPs srry " << endl; - PTRACE(3, "Failed to construct a reader for the audio. Exit now "); - return; - } - - if (!c.ConstructWriter(soundPlayer)) { - cerr << "Failed to consturct a writer for audio.... OOPs srry " << endl; - PTRACE(3, "Failed to construct a writer for the audio. Exit now "); - return; - } - - UserInterface ui(c, soundPlayer, soundRecorder); - c.WaitForTermination(); - - PTRACE(3, "End of comms object, exit program "); - + + LaunchNewId lid(ourId, ourPassword); + Comms c(lid); + c.Resume(); + + PTRACE(3, "Constructed the comms device "); + + if (!OpenSoundDevice(soundRecorder, PSoundChannel::Recorder)) { + PStringStream msg; + msg << " Failed to open sound device " << soundRecorder << " to read from microphone"; + cerr << msg << " .... OOOPs Sorry. " << endl; + PTRACE(3, msg); + return; + } + + if (!OpenSoundDevice(soundPlayer, PSoundChannel::Player)){ + PStringStream msg; + msg << " Failed to open sound device " << soundPlayer << " to write to speaker"; + cerr << msg << " .... OOOPs Sorry. " << endl; + PTRACE(3, msg); + return; + } + + if (!c.ConstructReader(soundRecorder)) { + cerr << "Failed to consturct a reader for audio.... OOPs srry " << endl; + PTRACE(3, "Failed to construct a reader for the audio. Exit now "); + return; + } + + if (!c.ConstructWriter(soundPlayer)) { + cerr << "Failed to consturct a writer for audio.... OOPs srry " << endl; + PTRACE(3, "Failed to construct a writer for the audio. Exit now "); + return; + } + + UserInterface ui(c, soundPlayer, soundRecorder); + c.WaitForTermination(); + + PTRACE(3, "End of comms object, exit program "); + #if PTRACING - if (args.GetOptionCount('t') > 0) { - PTrace::ClearOptions(0); - PTrace::SetLevel(0); - } + if (args.GetOptionCount('t') > 0) { + PTrace::ClearOptions(0); + PTrace::SetLevel(0); + } #endif - + } BOOL Audio::OpenSoundDevice(PSoundChannel & sound, PSoundChannel::Directions dir) { - + PString name = (dir == PSoundChannel::Recorder ? "recorder" : "player"); - + PTRACE(3, "TestAudio\t open audio start for " << name << " and device name of " << devName); PTRACE(3, "Open audio device for " << name << " and device name of " << devName); @@ -274,7 +323,7 @@ if (!sound.IsOpen()) { PTRACE(3, "End of OpenAudio, but the sound device is closed"); } - + return TRUE; } Modified: sofaswitch/trunk/sound/main.h ============================================================================== --- sofaswitch/trunk/sound/main.h (original) +++ sofaswitch/trunk/sound/main.h Mon Sep 18 19:46:52 2006 @@ -15,7 +15,7 @@ * * */ - + #ifndef _MAIN_H #define _MAIN_H @@ -29,79 +29,74 @@ rudimentary status information */ class UserInterface: public PThread { - PCLASSINFO(UserInterface, PThread); - -public: - /**construct this class, to have access to the communications and sound modules */ - UserInterface(Comms & _comms, PSoundChannel &_player, PSoundChannel & _recorder) - : PThread(1000, NoAutoDeleteThread), - comms(_comms), - player(_player), - recorder(_recorder) - { endNow = FALSE; Resume(); } - - /**The main method where everything happens */ - void Main(); - - /**This method is used to shutdown the operation of this class */ - virtual void Terminate(); - + PCLASSINFO(UserInterface, PThread); + + public: + /**construct this class, to have access to the communications and sound modules */ + UserInterface(Comms & _comms, PSoundChannel &_player, PSoundChannel & _recorder); + + /**The main method where everything happens */ + void Main(); + + /**This method is used to shutdown the operation of this class */ + virtual void Terminate(); + protected: - /**Reference to the class that does all the communications */ - Comms & comms; - - /**Reference to the class that does all the playing of audio to the speaker */ - PSoundChannel & player; - - /**Reference to the class that does all of the recording of audio from the microphone */ - PSoundChannel & recorder; - - /**Variable used to indicate it is time to finish */ - BOOL endNow; + /**Reference to the class that does all the communications */ + Comms & comms; + + /**Reference to the class that does all the playing of audio to the speaker */ + PSoundChannel & player; + + /**Reference to the class that does all of the recording of audio from the microphone */ + PSoundChannel & recorder; + + /**Variable used to indicate it is time to finish */ + BOOL endNow; }; ///////////////////////////////////////////////////////////////////////////// /**The parent class, that hides the int main(int argc, char **argv). - + This handles all command line parsing, and creation of the relevant worker classes */ class Audio : public PProcess { - PCLASSINFO(Audio, PProcess); - -public: - /**Constructor */ - Audio(); - - /**The handling of the command line, generating classes etc */ - void Main(); - - /**Access function to return the selected audio device name */ - PString GetTestDeviceName() { return devName; } - - /**Access function, so that any code in this program can address - this class */ + PCLASSINFO(Audio, PProcess); + + public: + /**Constructor */ + Audio(); + + /**The handling of the command line, generating classes etc */ + void Main(); + + /**Access function to return the selected audio device name */ + PString GetTestDeviceName() { return devName; } + + /**Access function, so that any code in this program can address + this class */ static Audio & Current() { return (Audio &)PProcess::Current(); } - + /**Report the node id of this particular entity, as seen by the sofa switch server */ PString GetNodeId() { return nodeId; } protected: /**The selected audio device name */ - PString devName; - - /**Open the sound device before we use it, and leave it open */ - BOOL OpenSoundDevice(PSoundChannel &device, PSoundChannel::Directions dir); - - /**Device for recording audio */ - PSoundChannel soundRecorder; - - /**Device for playing audio */ - PSoundChannel soundPlayer; - - /**The id of this particular entity, as seen by the sofaswitch server */ - PString nodeId; + PString devName; + + /**Open the sound device before we use it, and leave it open */ + BOOL OpenSoundDevice(PSoundChannel &device, PSoundChannel::Directions dir); + + /**Device for recording audio */ + PSoundChannel soundRecorder; + + /**Device for playing audio */ + PSoundChannel soundPlayer; + + /**The id of this particular entity, as seen by the sofaswitch server */ + PString nodeId; };
participants (1)
-
SofaSWITCH SVN