siproc

A primitive SIP client that spawns processes for each call
git clone git://xatko.vsos.ethz.ch/siproc.git
Log | Files | Refs | README | LICENSE

commit 3960b7e82a867e17a4e9e0de45991dd6e71544c1
parent 52827b890c7caa4c31d5fca81a5f8756c00702f7
Author: Dominik Schmidt <dominik@schm1dt.ch>
Date:   Sat, 16 Nov 2019 17:42:10 +0100

Implement alsa playback commands.

This commit introduces three new commands, namely:
* ARECORD: Write incoming audio to alsa stream
* APLAY: Write alsa stream to outgoing audio
* ASTOP: Stop writing from or to alsa stream

Diffstat:
Msiproc.1 | 13+++++++++++++
Msrc/siproc.cpp | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 72 insertions(+), 0 deletions(-)

diff --git a/siproc.1 b/siproc.1 @@ -119,6 +119,19 @@ Send a SIP message to the remote side .B RECORD [FILE] Record the conversation to the given file. If no file is given, the current recording is stopped. +.TP +.B APLAY [DEVICE] +Play the stream of the alsa-device +.B DEVICE +to the remote end. +.TP +.B ARECORD [DEVICE] +Play the audio stream from the remote end into the alsa device +.BR DEVICE . +.TP +.B ASTOP [DEVICE] +Stop both playing the remote end into and the local stream from +.BR DEVICE . . .SS SUBPROCESS EVENTS The following events can be read on stdin: diff --git a/src/siproc.cpp b/src/siproc.cpp @@ -118,6 +118,7 @@ class MyCall: public Call{ char *line; size_t line_length; std::vector<MyAudioMediaPlayer*> players; + std::map<int,ExtraAudioDevice*> audio_devs; AudioMediaRecorder* recorder=NULL; public: MyCall(Account &acc, int call_id = PJSUA_INVALID_ID) : Call(acc, call_id){ @@ -140,6 +141,12 @@ class MyCall: public Call{ for(unsigned int i=0; i<players.size(); i++){ delete players[i]; } + + for(auto it = audio_devs.begin(); it != audio_devs.end(); it++){ + delete it->second; + } + audio_devs.clear(); + if(recorder != NULL){ delete recorder; recorder = NULL; @@ -304,6 +311,49 @@ class MyCall: public Call{ xfer(std::string(number), prm); } + int get_dev_id(char *devname){ + AudDevManager &adm = ep.audDevManager(); + return adm.lookupDev("ALSA", string(devname)); + } + + ExtraAudioDevice* get_extra_audio(char *devname){ + int id = get_dev_id(devname); + ExtraAudioDevice *dev = NULL; + auto res = audio_devs.find(id); + if(res == audio_devs.end()){ + dev = new ExtraAudioDevice(id,id); + audio_devs[id] = dev; + dev->open(); + } + else{ + dev = res->second; + } + return dev; + } + + void cmd_aplay(char *source){ + ExtraAudioDevice *ea = get_extra_audio(source); + AudioMedia& play_dev_med = call_audio(); + ea->startTransmit(play_dev_med); + } + + void cmd_arecord(char *sink){ + ExtraAudioDevice *ea = get_extra_audio(sink); + AudioMedia& play_dev_med = call_audio(); + play_dev_med.startTransmit(*ea); + } + + void cmd_astop(char *sourcesink){ + int id = get_dev_id(sourcesink); + auto res = audio_devs.find(id); + if(res == audio_devs.end()){ + return; + } + ExtraAudioDevice *ea = res->second; + delete ea; + audio_devs.erase(res); + } + void command_machine(char *command){ char *args = strstr(command, " "); @@ -338,6 +388,15 @@ class MyCall: public Call{ else if(strcmp(command, "TRANSFER") == 0){ cmd_transfer(args); } + else if(strcmp(command, "APLAY") == 0){ + cmd_aplay(args); + } + else if(strcmp(command, "ARECORD") == 0){ + cmd_arecord(args); + } + else if(strcmp(command, "ASTOP") == 0){ + cmd_astop(args); + } } void handle_line(){