Tutorial – Project 5

Now, let’s modify the last project to add to recording file a background music. Since this is just a small addition to last tutorial project we won’t go through an in-depth explanation of all the code, we’ll concentrate instead on the differences between the two. Refer to previous project tutorial for more details if something isn’t clear enough.

The graphical interface is the same as that in recorder’s project, with 3 buttons, three mutually exclusive radio buttons and a text box where you have to put the SIP destination address.

screenshot

Here is the class constructor:

NewRecorder::NewRecorder(QWidget *parent, Qt::WFlags flags)
: QWidget(parent, flags), call_on(false), rec_on(false), filename("sound_example.wav")
{
	setupUi(this);

	vdk = new VDKQtEngine();
	vdk->init();
	vdk->setActiveSipAccount(1);

	micId = vdk->getDefaultAudioInputDevice();
	spkId = vdk->getDefaultAudioOutputDevice();

	connect(vdk,SIGNAL(sigCallEstablished(int)),
				this,SLOT(onCallEstablished(int)));
	connect(vdk,SIGNAL(sigCallFinished(int)),this,SLOT(onCallFinished(int)));
	connect(btnCall,SIGNAL(clicked()),this,SLOT(btnCallClicked()));
	connect(btnHangup,SIGNAL(clicked()),this,SLOT(btnHangupClicked()));
	connect(btnRec,SIGNAL(clicked()),this,SLOT(btnRecClicked()));

	btnCall->setEnabled(true);
	btnHangup->setEnabled(false);
	btnRec->setEnabled(false);
	rbtn_IN->setChecked(true);
}

It’s like last example except for the filename variable: this is a QString used to store the name of file that will be used as background music at record time. In fact, now we do not want to just record our audio flow, but also to add to the recorded audio an intentional music, that is held in sound_example.wav file (the value used to initialize the filename variable).

Among the member functions, only btnRecClicked() is different from previous tutorial: let’s see together just this one (you may go back(link) to third tutorial to check out the other methods).

void NewRecorder::btnRecClicked(){
if((!rec_on)){

	fileInId=vdk->getFileInputDevice(filename.toAscii().data(),true);
	fileOutId=vdk->getFileOutputDevice("rec_file.wav");

	if(rbtn_IN->isChecked()){
		vdk->connectLineToDevice(voipLineId,fileOutId);
		vdk->connectDevices(fileInId,fileOutId);
	}
	else if(rbtn_OUT->isChecked()){
		vdk->connectDevices(micId,fileOutId);
		vdk->connectDevices(fileInId,fileOutId);
	}
	else if(rbtn_BOTH->isChecked()){
		vdk->connectDevices(micId,fileOutId);
		vdk->connectLineToDevice(voipLineId,fileOutId);
		vdk->connectDevices(fileInId,fileOutId);
	}
	rbtn_IN->setEnabled(false);
	rbtn_OUT->setEnabled(false);
	rbtn_BOTH->setEnabled(false);

	btnRec->setText("Stop");
	rec_on=true;
}
else if(rec_on){
	vdk->disconnectDevices(fileInId,fileOutId);

	if(rbtn_IN->isChecked())
		vdk->disconnectLineFromDevice(voipLineId,fileOutId);

	else if(rbtn_OUT->isChecked())
		vdk->disconnectDevices(micId,fileOutId);
	else if (rbtn_BOTH->isChecked()){
		vdk->disconnectLineFromDevice(voipLineId,fileOutId);
		vdk->disconnectDevices(micId,fileOutId);
	}

	btnRec->setText("Record");

	rbtn_IN->setEnabled(true);
	rbtn_OUT->setEnabled(true);
	rbtn_BOTH->setEnabled(true);
	rbtn_IN->setChecked(true);
	rec_on=false;
}
}

Once again, we have two possible scenarios, since the user clicks on btnRec either to begin a new recording or to stop a recording previously started. We still refer to rec_on variable to discern between the two situations.

In the first case we are beginning a new recording; the first operation is to associate a deviceId_t to the sound_example.wav file, done via vdk’s getFileInputDevice method. We call the method with filename variable, and with a true flag: it indicates that the input file has to be read in a loop. Moreover we open the file where to record and we call it rec_file.wav. Then we have three possibilities:

  • if rbtn_IN is checked we add to recording the input from file and the audio from network line on which the call has been established;
  • if rbtn_OUT is checked we record the input from our microphone and the input from file;
  • if rbtn_BOTH is checked we record all inputs: from network connected line, from our microphone and from the input file too.

In the three cases, thanks to vdk feature, we do not have to worry about how to mix the different audio inputs, it is done automatically.

Before exiting, we also disable all radio buttons (that will enabled again in the second part of the method), ’cause we do not want that the user could accidentally check on them during a record.

In the second case instead we are stopping a recording. First of all we call disconnectDevices method with arguments fileInId and fileOutId, that are the devices associated to incidental music file and to the record file. After that, based on which radio button has been checked, we disconnect the necessary devices.

That’s all, we are ready!


Note:

if you try to run this application with the trial version of vdk, you will note that in case you start recording both audio inputs, from network line and from your microphone, you won’t hear any background music in your recorded file. This happens because you have already used the 4 connetions at your disposal (one to connect microphone to line, one to connect line to speakers, the other two to connect them to record file).