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() : fp (NULL)
58
, nbSamplesMax_ (3000)
59
, recordingEnabled_ (false)
65
mixBuffer_ = new SFLDataFormat[nbSamplesMax_];
66
micBuffer_ = new SFLDataFormat[nbSamplesMax_];
67
spkBuffer_ = new SFLDataFormat[nbSamplesMax_];
72
AudioRecord::~AudioRecord()
80
void AudioRecord::setSndSamplingRate (int smplRate)
82
sndSmplRate_ = smplRate;
85
void AudioRecord::setRecordingOption (FILE_TYPE type, SOUND_FORMAT format, int sndSmplRate, std::string path)
91
sndSmplRate_ = sndSmplRate;
93
savePath_ = path + "/";
99
void AudioRecord::initFileName (std::string peerNumber)
105
fName.append ("-"+peerNumber);
107
if (fileType_ == FILE_RAW) {
108
if (strstr (fileName_, ".raw") == NULL) {
109
_debug ("AudioRecord: concatenate .raw file extension: name : %s", fileName_);
110
fName.append (".raw");
112
} else if (fileType_ == FILE_WAV) {
113
if (strstr (fileName_, ".wav") == NULL) {
114
_debug ("AudioRecord: concatenate .wav file extension: name : %s", fileName_);
115
fName.append (".wav");
119
savePath_.append (fName);
122
void AudioRecord::openFile()
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;
205
recordingEnabled_ = false;
206
_info ("AudioRecording: Stop recording");
211
recordingEnabled_ = true; // once opend file, start recording
214
// WARNING: Unused return value
219
void AudioRecord::stopRecording()
221
_info ("AudioRecording: Stop recording");
223
if (recordingEnabled_)
224
recordingEnabled_ = false;
228
void AudioRecord::createFilename()
233
struct tm * timeinfo;
235
rawtime = time (NULL);
236
timeinfo = localtime (&rawtime);
241
out << timeinfo->tm_year+1900;
243
if (timeinfo->tm_mon < 9) // january is 01, not 1
246
out << timeinfo->tm_mon+1;
248
if (timeinfo->tm_mday < 10) // 01 02 03, not 1 2 3
251
out << timeinfo->tm_mday;
256
if (timeinfo->tm_hour < 10) // 01 02 03, not 1 2 3
259
out << timeinfo->tm_hour;
263
if (timeinfo->tm_min < 10) // 01 02 03, not 1 2 3
266
out << timeinfo->tm_min;
270
if (timeinfo->tm_sec < 10) // 01 02 03, not 1 2 3
273
out << timeinfo->tm_sec;
275
// fileName_ = out.str();
276
strncpy (fileName_, out.str().c_str(), 8192);
278
_info ("AudioRecord: create filename for this call %s ", fileName_);
281
bool AudioRecord::setRawFile()
284
fp = fopen (savePath_.c_str(), "wb");
287
_warn ("AudioRecord::setRawFile() : could not create RAW file!");
291
if (sndFormat_ != INT16) { // TODO need to change INT16 to SINT16
293
_debug ("AudioRecord::setRawFile() : using 16-bit signed integer data format for file.");
296
_debug ("AudioRecord:setRawFile() : created RAW file.");
302
bool AudioRecord::setWavFile()
304
_debug ("AudioRecord: Create wave file %s", savePath_.c_str());
306
fp = fopen (savePath_.c_str(), "wb");
309
_warn ("AudioRecord: Error: could not create WAV file.");
313
struct wavhdr hdr = {"RIF", 44, "WAV", "fmt", 16, 1, 1,
314
sndSmplRate_, 0, 2, 16, "dat", 0
325
hdr.num_chans = channels_;
327
if (sndFormat_ == INT16) { // TODO need to write INT16 to SINT16
328
hdr.bits_per_samp = 16;
331
hdr.bytes_per_samp = (SINT16) (channels_ * hdr.bits_per_samp / 8);
333
hdr.bytes_per_sec = (SINT32) (hdr.sample_rate * hdr.bytes_per_samp);
336
if (fwrite (&hdr, 4, 11, fp) != 11) {
337
_warn ("AudioRecord: Error: could not write WAV header for file. ");
341
_debug ("AudioRecord: created WAV file successfully.");
347
bool AudioRecord::openExistingRawFile()
349
fp = fopen (fileName_, "ab+");
352
_warn ("AudioRecord: could not create RAW file!");
360
bool AudioRecord::openExistingWavFile()
362
_info ("AudioRecord: Open existing wave file");
364
fp = fopen (fileName_, "rb+");
367
_warn ("AudioRecord: Error: could not open WAV file!");
371
printf ("AudioRecord::openExistingWavFile()::Tried to open %s ",fileName_);
373
if (fseek (fp, 40, SEEK_SET) != 0) // jump to data length
374
_warn ("AudioRecord: Error: Couldn't seek offset 40 in the file ");
376
if (fread (&byteCounter_, 4, 1, fp))
377
_warn ("AudioRecord: Error: bytecounter Read successfully ");
379
if (fseek (fp, 0 , SEEK_END) != 0)
380
_warn ("AudioRecord: Error: Couldn't seek at the en of the file ");
383
if (fclose (fp) != 0)
384
_warn ("AudioRecord: Error: Can't close file r+ ");
388
fp = fopen (fileName_, "ab+");
391
_warn ("AudioRecord: Error: Could not createopen WAV file ab+!");
395
if (fseek (fp, 4 , SEEK_END) != 0)
396
_warn ("AudioRecord: Error: Couldn't seek at the en of the file ");
403
void AudioRecord::closeWavFile()
406
_debug ("AudioRecord: Can't closeWavFile, a file has not yet been opened!");
410
_debug ("AudioRecord: Close wave file");
413
SINT32 bytes = byteCounter_ * channels_;
415
fseek (fp, 40, SEEK_SET); // jump to data length
418
_warn ("AudioRecord: Error: can't reach offset 40 while closing");
420
fwrite (&bytes, sizeof (SINT32), 1, fp);
423
_warn ("AudioRecord: Error: can't write bytes for data length ");
426
bytes = byteCounter_ * channels_ + 44; // + 44 for the wave header
428
fseek (fp, 4, SEEK_SET); // jump to file size
431
_warn ("AudioRecord: Error: can't reach offset 4");
433
fwrite (&bytes, 4, 1, fp);
436
_warn ("AudioRecord: Error: can't reach offset 4");
439
if (fclose (fp) != 0)
440
_warn ("AudioRecord: Error: can't close file");
445
void AudioRecord::recSpkrData (SFLDataFormat* buffer, int nSamples)
448
if (recordingEnabled_) {
450
nbSamplesMic_ = nSamples;
452
for (int i = 0; i < nbSamplesMic_; i++)
453
micBuffer_[i] = buffer[i];
460
void AudioRecord::recMicData (SFLDataFormat* buffer, int nSamples)
463
if (recordingEnabled_) {
465
nbSamplesSpk_ = nSamples;
467
for (int i = 0; i < nbSamplesSpk_; i++)
468
spkBuffer_[i] = buffer[i];
476
void AudioRecord::recData (SFLDataFormat* buffer, int nSamples)
479
if (recordingEnabled_) {
482
_debug ("AudioRecord: Can't record data, a file has not yet been opened!");
488
if (sndFormat_ == INT16) { // TODO change INT16 to SINT16
489
if (fwrite (buffer, sizeof (SFLDataFormat), nSamples, fp) != (unsigned int) nSamples)
490
_warn ("AudioRecord: Could not record data! ");
493
byteCounter_ += (unsigned long) (nSamples*sizeof (SFLDataFormat));
502
void AudioRecord::recData (SFLDataFormat* buffer_1, SFLDataFormat* buffer_2, int nSamples_1, int nSamples_2 UNUSED)
505
if (recordingEnabled_) {
507
_debug ("Recording enabled");
510
_debug ("AudioRecord: Can't record data, a file has not yet been opened!");
515
if (sndFormat_ == INT16) { // TODO change INT16 to SINT16
516
for (int k=0; k<nSamples_1; k++) {
518
mixBuffer_[k] = (buffer_1[k]+buffer_2[k]);
521
if (fwrite (&mixBuffer_[k], 2, 1, fp) != 1)
522
_warn ("AudioRecord: Could not record data!");
529
byteCounter_ += (unsigned long) (nSamples_1*sizeof (SFLDataFormat));