audiorecord.cpp 10.1 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 *  Copyright (C) 2008 Savoir-Faire Linux inc.
 *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include "audiorecord.h"

22
23


24
AudioRecord::AudioRecord(){
alexandresavard's avatar
alexandresavard committed
25
  
26
27
28
  sndSmplRate_ = 44100;
  channels_ = 1;
  byteCounter_ = 0;
alexandresavard's avatar
alexandresavard committed
29
  recordingEnabled_ = false;
30
  fp = 0;
31
32
33
34
35

}


void AudioRecord::setSndSamplingRate(int smplRate){
alexandresavard's avatar
alexandresavard committed
36
  sndSmplRate_ = smplRate;  
37
38
}

39
void AudioRecord::setRecordingOption(std::string name, FILE_TYPE type, SOUND_FORMAT format, int sndSmplRate){
40

41
42
43
44
45
46
  strncpy(fileName_, name.c_str(), 8192);
 
  fileType_ = type;
  sndFormat_ = format;
  channels_ = 1;
  sndSmplRate_ = sndSmplRate;
47
  
48
  if (fileType_ == FILE_RAW){
49
50
51
52
53
54
55
56
57
58
59
     if ( strstr(fileName_, ".raw") == NULL){
       printf("AudioRecord::openFile::concatenate .raw file extension: name : %s \n", fileName_); 
       strcat(fileName_, ".raw");
     }
   }
   else if (fileType_ == FILE_WAV){
     if ( strstr(fileName_, ".wav") == NULL){ 
       printf("AudioRecord::openFile::concatenate .wav file extension: name : %s \n", fileName_);
       strcat(fileName_, ".wav");
     }
   }
60
61
62
63
64
65
66
}

void AudioRecord::openFile(){
  
   _debug("AudioRecord::openFile()\n");  
  
   bool result = false;
67
68
   
   if(isFileExist()) {
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
     _debug("AudioRecord::Filename does not exist, creating one \n");
     byteCounter_ = 0;

     if(fileType_ == FILE_RAW){
       result = setRawFile();
     }
     else if (fileType_ == FILE_WAV){
       result = setWavFile();
     }
   }
   else {
     _debug("AudioRecord::Filename already exist opening it \n");
     if(fileType_ == FILE_RAW){
       result = openExistingRawFile();
     }   
     else if (fileType_ == FILE_WAV){
       result = openExistingWavFile();      
     }
   }  
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
}


void AudioRecord::closeFile() {

  if (fp == 0) return;

  if (fileType_ == FILE_RAW)
    fclose(fp);
  else if (fileType_ == FILE_WAV)
    this->closeWavFile();

}


bool AudioRecord::isOpenFile() {
  
105
106
  if(fp){
    _debug("AudioRecord::isOpenFile(): file already openend\n");
107
    return true;
108
109
110
  }
  else {
    _debug("AudioRecord::isOpenFIle(): file not openend \n");
111
    return false;
112
  }
113
114
115
}


116
117
118
119
120
121
122
123
124
125
bool AudioRecord::isFileExist() {
  
  printf("AudioRecord::isFileExist(): try to open name : %s \n", fileName_);
  if(fopen(fileName_,"rb")==0) {
    return true;
  }
  
  return false;  
}

126
127
128
129
130
131
132
133
134
bool AudioRecord::isRecording() {
  _debug("AudioRecording::setRecording() \n");
  
  if(recordingEnabled_)
    return true;
  else 
    return false;
}

135

alexandresavard's avatar
alexandresavard committed
136
bool AudioRecord::setRecording() {
137
  _debug("AudioRecord::setRecording()\n");
alexandresavard's avatar
alexandresavard committed
138
  
139
140
141
142
143
144
145
146
147
148
149
150
151
  if (isOpenFile()){
    _debug("AuioRecord::setRecording()::file already opened\n");
    if(!recordingEnabled_)
      recordingEnabled_ = true;
    else 
      recordingEnabled_ = false;
  }
  else {
    _debug("AudioRecord::setRecording():Opening the wave file in call during call instantiation\n");
    openFile();

    recordingEnabled_ = true; // once opend file, start recording
  }
alexandresavard's avatar
alexandresavard committed
152
153
154
  
}

155
156
157
158
159
160
161
void AudioRecord::stopRecording() {
  _debug("AudioRecording::stopRecording() \n");

  if(recordingEnabled_)
    recordingEnabled_ = false;
}

alexandresavard's avatar
alexandresavard committed
162

163
bool AudioRecord::setRawFile() {
164

165
  fp = fopen(fileName_, "wb");
166
  if ( !fp ) {
167
    _debug("AudioRecord::setRawFile() : could not create RAW file!\n");
168
169
170
171
172
    return false;
  }

  if ( sndFormat_ != INT16 ) { // TODO need to change INT16 to SINT16
    sndFormat_ = INT16;
173
    _debug("AudioRecord::setRawFile() : using 16-bit signed integer data format for file.\n");
174
175
  }

176
  _debug("AudioRecord:setRawFile() : created RAW file.\n");
177
178
179
180
  return true;
}


181
bool AudioRecord::setWavFile() {
182
  
183
  fp = fopen(fileName_, "wb");
184
  if ( !fp ) {
185
    _debug("AudioRecord::setWavFile() : could not create WAV file.\n");
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
    return false;
  }

  struct wavhdr hdr = {"RIF", 44, "WAV", "fmt", 16, 1, 1,
                        44100, 0, 2, 16, "dat", 0};
  hdr.riff[3] = 'F';
  hdr.wave[3] = 'E';
  hdr.fmt[3]  = ' ';
  hdr.data[3] = 'a';
  hdr.num_chans = channels_;
  if ( sndFormat_ == INT16 ) { //  TODO need to write INT16 to SINT16
    hdr.bits_per_samp = 16;
  }
  hdr.bytes_per_samp = (SINT16) (channels_ * hdr.bits_per_samp / 8);
  hdr.bytes_per_sec = (SINT32) (hdr.sample_rate * hdr.bytes_per_samp);

202
203
  
  if ( fwrite(&hdr, 4, 11, fp) != 11) {
204
    _debug("AudioRecord::setWavFile() : could not write WAV header for file. \n");
205
206
207
    return false;
  }

208
  _debug("AudioRecord::setWavFile() : created WAV file. \n");
209
210
211
212
  return true;
}


213
214
215
216
217
218
219
220
bool AudioRecord::openExistingRawFile()
{ 
  fp = fopen(fileName_, "ab+");
  if ( !fp ) {
    _debug("AudioRecord::openExistingRawFile() : could not create RAW file!\n");
    return false;
  }
}
221
222


223
224
225
bool AudioRecord::openExistingWavFile()
{ 
  _debug("AudioRecord::openExistingWavFile() \n");
226

227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
  fp = fopen(fileName_, "rb+");
  if ( !fp ) {
    _debug("AudioRecord::openExistingWavFile() : could not open WAV file rb+!\n");
    return false;
  }

  printf("AudioRecord::openExistingWavFile()::Tried to open %s \n",fileName_);
  
  if(fseek(fp, 40, SEEK_SET) != 0) // jump to data length
    _debug("AudioRecord::OpenExistingWavFile: 1.Couldn't seek offset 40 in the file \n");
  
  if(fread(&byteCounter_, 4, 1, fp))
    _debug("AudioRecord::OpenExistingWavFile : bytecounter Read successfully \n");
  
  if(fseek (fp, 0 , SEEK_END) != 0)
    _debug("AudioRecors::OpenExistingWavFile : 2.Couldn't seek at the en of the file \n");
243

244
  printf("AudioRecord::OpenExistingWavFile : Byte counter after oppening : %d \n",(int)byteCounter_);
245

246
247
  if ( fclose( fp ) != 0)
    _debug("AudioRecord::openExistingWavFile()::ERROR: can't close file r+ \n");
248

249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264

  
  fp = fopen(fileName_, "ab+");
  if ( !fp ) {
    _debug("AudioRecord::openExistingWavFile() : could not createopen WAV file ab+!\n");
    return false;
  }

  if(fseek (fp, 4 , SEEK_END) != 0)
    _debug("AudioRecors::OpenExistingWavFile : 2.Couldn't seek at the en of the file \n");
  
}


void AudioRecord::closeWavFile() 
{
265
  if (fp == 0){
266
    _debug("AudioRecord:: Can't closeWavFile, a file has not yet been opened!\n");
267
268
269
    return;
  }
 
270
271
272
273
274
275
276
277
278
279
280
  _debug("AudioRecord::closeWavFile() \n");

  if ( fclose( fp ) != 0)
    _debug("AudioRecord::closeWavFile()::ERROR: can't close file ab \n");

  

  fp = fopen(fileName_, "rb+");
  if ( !fp ) {
    _debug("AudioRecord::closeWavFile() : could not open WAV file rb+!\n");
    return;
281
282
  }

283
284
285
286
287
288
289
290
291
292
293
294
295
296
297

  SINT32 bytes = byteCounter_ * channels_;
  fseek(fp, 40, SEEK_SET); // jump to data length
  if (ferror(fp))perror("AudioRecord::closeWavFile()::ERROR: can't reach offset 40\n");
  
  fwrite(&bytes, sizeof(SINT32), 1, fp);
  if (ferror(fp))perror("AudioRecord::closeWavFile()::ERROR: can't write bytes for data length \n");
  printf("AudioRecord::closeWavFile : data bytes: %i \n",(int)bytes);

  bytes = byteCounter_ * channels_ + 44; // + 44 for the wave header 
  fseek(fp, 4, SEEK_SET);  // jump to file size
  if (ferror(fp))perror("AudioRecord::closeWavFile()::ERROR: can't reach offset 4\n");
  
  fwrite(&bytes, 4, 1, fp);
  if (ferror(fp))perror("AudioRecord::closeWavFile()::ERROR: can't reach offset 4\n");
298
  
299
300
301
302
303
304
305
306
307
308
  printf("AudioRecord::closeWavFile : bytes : %i \n",(int)bytes);
  
  if ( fclose( fp ) != 0)
    _debug("AudioRecord::closeWavFile()::ERROR: can't close file\n");
 
  // i = fclose(fp);
  // printf("AudioRecord::closeWavFile : indicator i : %i \n",i);

}

309

310
void AudioRecord::recData(SFLDataFormat* buffer, int nSamples) {
311

312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
  if (recordingEnabled_) {

    if (fp == 0){
      _debug("AudioRecord: Can't record data, a file has not yet been opened!\n");
      return;
    }
 
    // int size = nSamples * (sizeof(SFLDataFormat));
    // int size = sizeof(buffer);
    // int count = sizeof(buffer) / sizeof(SFLDataFormat);
  
    // printf("AudioRecord : sizeof(buffer) : %d \n",size); 
    // printf("AudioRecord : sizeof(buffer) / sizeof(SFLDataFormat) : %d \n",count);
    // printf("AudioRecord : nSamples : %d \n",nSamples);
    // printf("AudioRecord : buffer: %x : ", buffer);
 
    if ( sndFormat_ == INT16 ) { // TODO change INT16 to SINT16
      if ( fwrite(buffer, sizeof(SFLDataFormat), nSamples, fp) != nSamples)
        _debug("AudioRecord: Could not record data! \n");
      else {
        // printf("Buffer : %x \n",*buffer);
        fflush(fp);
        // _debug("Flushing!\n");
        byteCounter_ += (unsigned long)(nSamples*sizeof(SFLDataFormat));
      }
    } 
  }
339
340
341
342

  return;
}

343
344
345

void AudioRecord::recData(SFLDataFormat* buffer_1, SFLDataFormat* buffer_2, int nSamples_1, int nSamples_2) {

346
  if (recordingEnabled_) {
347

348
349
350
351
352
353
    if (fp == 0){
      _debug("AudioRecord: Can't record data, a file has not yet been opened!\n");
      return;
    }

    mixBuffer_ = new SFLDataFormat[nSamples_1]; 
354
 
355
356
357
358
359
360
361
362
    // int size = nSamples * (sizeof(SFLDataFormat));
    // int size = sizeof(buffer);
    // int count = sizeof(buffer) / sizeof(SFLDataFormat);
  
    // printf("AudioRecord : sizeof(buffer) : %d \n",size); 
    // printf("AudioRecord : sizeof(buffer) / sizeof(SFLDataFormat) : %d \n",count);
    // printf("AudioRecord : nSamples : %d \n",nSamples);
    // printf("AudioRecord : buffer: %x : ", buffer);
alexandresavard's avatar
alexandresavard committed
363
364
365

    if ( sndFormat_ == INT16 ) { // TODO change INT16 to SINT16
      for (int k=0; k<nSamples_1; k++){
366
      
alexandresavard's avatar
alexandresavard committed
367
        mixBuffer_[k] = (buffer_1[k]+buffer_2[k])/2;
368
      
alexandresavard's avatar
alexandresavard committed
369
370
371
372
373
374
375
        if ( fwrite(&buffer_1[k], 2, 1, fp) != 1)
          _debug("AudioRecord: Could not record data!\n");
        else {
          // printf("Buffer : %x \n",*buffer);
          fflush(fp);
          // _debug("Flushing!\n");
        }
376
377
      }
    }
378
   
379
    byteCounter_ += (unsigned long)(nSamples_1*sizeof(SFLDataFormat));
380

Emmanuel Milou's avatar
Emmanuel Milou committed
381
    //printf("AudioRecord::recData():: byteCounter_ : %i \n",(int)byteCounter_ );
382

383
384
    delete [] mixBuffer_;
  }
385
386
387

  return;
}