2
* Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc.
3
* Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 3 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
* Additional permission under GNU GPL version 3 section 7:
21
* If you modify this program, or any covered work, by linking or
22
* combining it with the OpenSSL project's OpenSSL library (or a
23
* modified version of that library), containing parts covered by the
24
* terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
25
* grants you additional permission to convey the resulting work.
26
* Corresponding Source for a non-source form of such a combination
27
* shall include the source code for the parts of OpenSSL used as well
28
* as that of the covered work.
31
#include "audiorecord.h"
33
// structure for the wave header
36
char riff[4]; // "RIFF"
37
SINT32 file_size; // in bytes
38
char wave[4]; // "WAVE"
39
char fmt[4]; // "fmt "
40
SINT32 chunk_size; // in bytes (16 for PCM)
41
SINT16 format_tag; // 1=PCM, 2=ADPCM, 3=IEEE float, 6=A-Law, 7=Mu-Law
42
SINT16 num_chans; // 1=mono, 2=stereo
45
SINT16 bytes_per_samp; // 2=16-bit mono, 4=16-bit stereo
47
char data[4]; // "data"
48
SINT32 data_length; // in bytes
52
AudioRecord::AudioRecord()
58
recordingEnabled_ = false;
64
mixBuffer_ = new SFLDataFormat[nbSamplesMax_];
65
micBuffer_ = new SFLDataFormat[nbSamplesMax_];
66
spkBuffer_ = new SFLDataFormat[nbSamplesMax_];
69
AudioRecord::~AudioRecord()
77
void AudioRecord::setSndSamplingRate (int smplRate)
79
sndSmplRate_ = smplRate;
82
void AudioRecord::setRecordingOption (FILE_TYPE type, SOUND_FORMAT format, int sndSmplRate, std::string path)
89
sndSmplRate_ = sndSmplRate;
91
savePath_ = path + "/";
97
void AudioRecord::initFileName (std::string peerNumber)
103
fName.append ("-"+peerNumber);
105
if (fileType_ == FILE_RAW) {
106
if (strstr (fileName_, ".raw") == NULL) {
107
_debug("AudioRecord: concatenate .raw file extension: name : %s", fileName_);
108
fName.append (".raw");
110
} else if (fileType_ == FILE_WAV) {
111
if (strstr (fileName_, ".wav") == NULL) {
112
_debug("AudioRecord: concatenate .wav file extension: name : %s", fileName_);
113
fName.append (".wav");
117
savePath_.append (fName);
120
void AudioRecord::openFile()
123
_info ("AudioRecord: Open file()");
127
_debug ("AudioRecord: Open file()");
130
_debug ("AudioRecord: Filename does not exist, creating one");
133
if (fileType_ == FILE_RAW) {
134
result = setRawFile();
135
} else if (fileType_ == FILE_WAV) {
136
result = setWavFile();
139
_debug ("AudioRecord: Filename already exist opening it");
141
if (fileType_ == FILE_RAW) {
142
result = openExistingRawFile();
143
} else if (fileType_ == FILE_WAV) {
144
result = openExistingWavFile();
150
void AudioRecord::closeFile()
155
if (fileType_ == FILE_RAW)
157
else if (fileType_ == FILE_WAV)
158
this->closeWavFile();
165
bool AudioRecord::isOpenFile()
176
bool AudioRecord::isFileExist()
178
_info ("AudioRecord: Try to open name : %s ", fileName_);
180
if (fopen (fileName_,"rb") ==0) {
187
bool AudioRecord::isRecording()
190
if (recordingEnabled_)
197
bool AudioRecord::setRecording()
201
if (!recordingEnabled_) {
202
_info ("AudioRecording: Start recording");
203
recordingEnabled_ = true;
206
recordingEnabled_ = false;
207
_info ("AudioRecording: Stop recording");
213
recordingEnabled_ = true; // once opend file, start recording
216
// WARNING: Unused return value
221
void AudioRecord::stopRecording()
223
_info ("AudioRecording: Stop recording");
225
if (recordingEnabled_)
226
recordingEnabled_ = false;
230
void AudioRecord::createFilename()
235
struct tm * timeinfo;
237
rawtime = time (NULL);
238
timeinfo = localtime (&rawtime);
243
out << timeinfo->tm_year+1900;
245
if (timeinfo->tm_mon < 9) // january is 01, not 1
248
out << timeinfo->tm_mon+1;
250
if (timeinfo->tm_mday < 10) // 01 02 03, not 1 2 3
253
out << timeinfo->tm_mday;
258
if (timeinfo->tm_hour < 10) // 01 02 03, not 1 2 3
261
out << timeinfo->tm_hour;
265
if (timeinfo->tm_min < 10) // 01 02 03, not 1 2 3
268
out << timeinfo->tm_min;
272
if (timeinfo->tm_sec < 10) // 01 02 03, not 1 2 3
275
out << timeinfo->tm_sec;
277
// fileName_ = out.str();
278
strncpy (fileName_, out.str().c_str(), 8192);
280
_info("AudioRecord: create filename for this call %s ", fileName_);
283
bool AudioRecord::setRawFile()
286
fp = fopen (savePath_.c_str(), "wb");
289
_warn ("AudioRecord::setRawFile() : could not create RAW file!");
293
if (sndFormat_ != INT16) { // TODO need to change INT16 to SINT16
295
_debug ("AudioRecord::setRawFile() : using 16-bit signed integer data format for file.");
298
_debug ("AudioRecord:setRawFile() : created RAW file.");
304
bool AudioRecord::setWavFile()
307
fp = fopen (savePath_.c_str(), "wb");
310
_warn("AudioRecord: Error: could not create WAV file.");
314
struct wavhdr hdr = {"RIF", 44, "WAV", "fmt", 16, 1, 1,
315
sndSmplRate_, 0, 2, 16, "dat", 0
326
hdr.num_chans = channels_;
328
if (sndFormat_ == INT16) { // TODO need to write INT16 to SINT16
329
hdr.bits_per_samp = 16;
332
hdr.bytes_per_samp = (SINT16) (channels_ * hdr.bits_per_samp / 8);
334
hdr.bytes_per_sec = (SINT32) (hdr.sample_rate * hdr.bytes_per_samp);
337
if (fwrite (&hdr, 4, 11, fp) != 11) {
338
_warn("AudioRecord: Error: could not write WAV header for file. ");
342
_debug ("AudioRecord: created WAV file successfully.");
348
bool AudioRecord::openExistingRawFile()
350
fp = fopen (fileName_, "ab+");
353
_warn ("AudioRecord: could not create RAW file!");
361
bool AudioRecord::openExistingWavFile()
363
_info ("AudioRecord: Open existing wave file");
365
fp = fopen (fileName_, "rb+");
368
_warn("AudioRecord: Error: could not open WAV file!");
372
printf ("AudioRecord::openExistingWavFile()::Tried to open %s ",fileName_);
374
if (fseek (fp, 40, SEEK_SET) != 0) // jump to data length
375
_warn ("AudioRecord: Error: Couldn't seek offset 40 in the file ");
377
if (fread (&byteCounter_, 4, 1, fp))
378
_warn("AudioRecord: Error: bytecounter Read successfully ");
380
if (fseek (fp, 0 , SEEK_END) != 0)
381
_warn ("AudioRecord: Error: Couldn't seek at the en of the file ");
384
if (fclose (fp) != 0)
385
_warn ("AudioRecord: Error: Can't close file r+ ");
389
fp = fopen (fileName_, "ab+");
392
_warn ("AudioRecord: Error: Could not createopen WAV file ab+!");
396
if (fseek (fp, 4 , SEEK_END) != 0)
397
_warn ("AudioRecord: Error: Couldn't seek at the en of the file ");
404
void AudioRecord::closeWavFile()
407
_debug ("AudioRecord: Can't closeWavFile, a file has not yet been opened!");
412
SINT32 bytes = byteCounter_ * channels_;
414
fseek (fp, 40, SEEK_SET); // jump to data length
416
_warn ("AudioRecord: Error: can't reach offset 40 while closing");
418
fwrite (&bytes, sizeof (SINT32), 1, fp);
420
_warn ("AudioRecord: Error: can't write bytes for data length ");
423
bytes = byteCounter_ * channels_ + 44; // + 44 for the wave header
425
fseek (fp, 4, SEEK_SET); // jump to file size
427
_warn ("AudioRecord: Error: can't reach offset 4");
429
fwrite (&bytes, 4, 1, fp);
431
_warn("AudioRecord: Error: can't reach offset 4");
434
if (fclose (fp) != 0)
435
_warn ("AudioRecord: Error: can't close file");
440
void AudioRecord::recSpkrData (SFLDataFormat* buffer, int nSamples)
443
if (recordingEnabled_) {
445
nbSamplesMic_ = nSamples;
447
for (int i = 0; i < nbSamplesMic_; i++)
448
micBuffer_[i] = buffer[i];
455
void AudioRecord::recMicData (SFLDataFormat* buffer, int nSamples)
458
if (recordingEnabled_) {
460
nbSamplesSpk_ = nSamples;
462
for (int i = 0; i < nbSamplesSpk_; i++)
463
spkBuffer_[i] = buffer[i];
471
void AudioRecord::recData (SFLDataFormat* buffer, int nSamples)
474
if (recordingEnabled_) {
477
_debug ("AudioRecord: Can't record data, a file has not yet been opened!");
483
if (sndFormat_ == INT16) { // TODO change INT16 to SINT16
484
if (fwrite (buffer, sizeof (SFLDataFormat), nSamples, fp) != (unsigned int) nSamples)
485
_warn ("AudioRecord: Could not record data! ");
488
byteCounter_ += (unsigned long) (nSamples*sizeof (SFLDataFormat));
497
void AudioRecord::recData (SFLDataFormat* buffer_1, SFLDataFormat* buffer_2, int nSamples_1, int nSamples_2)
500
if (recordingEnabled_) {
503
_debug ("AudioRecord: Can't record data, a file has not yet been opened!");
508
if (sndFormat_ == INT16) { // TODO change INT16 to SINT16
509
for (int k=0; k<nSamples_1; k++) {
511
mixBuffer_[k] = (buffer_1[k]+buffer_2[k]);
514
if (fwrite (&mixBuffer_[k], 2, 1, fp) != 1)
515
_warn ("AudioRecord: Could not record data!");
522
byteCounter_ += (unsigned long) (nSamples_1*sizeof (SFLDataFormat));