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:
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(){