00001
00002 #include "wavFile.h"
00003 #include "qtrec.h"
00004
00005
00006 #include <opie2/odebug.h>
00007 #include <qpe/config.h>
00008 using namespace Opie::Core;
00009
00010
00011 #include <qmessagebox.h>
00012 #include <qdir.h>
00013
00014
00015 #include <errno.h>
00016 #include <sys/time.h>
00017 #include <sys/types.h>
00018 #include <sys/vfs.h>
00019 #include <fcntl.h>
00020 #include <math.h>
00021 #include <mntent.h>
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <unistd.h>
00025
00026 WavFile::WavFile( QObject * parent,const QString &fileName, bool makeNwFile, int sampleRate,
00027 int channels, int resolution, int format )
00028 : QObject( parent)
00029 {
00030 owarn << "new wave file: " << fileName << oendl;
00031 bool b = makeNwFile;
00032 wavSampleRate=sampleRate;
00033 wavFormat=format;
00034 wavChannels=channels;
00035 wavResolution=resolution;
00036 useTmpFile=false;
00037 if( b) {
00038 newFile();
00039 } else {
00040 openFile(fileName);
00041 }
00042 }
00043
00044 bool WavFile::newFile() {
00045
00046
00047 Config cfg("OpieRec");
00048 cfg.setGroup("Settings");
00049
00050 currentFileName=cfg.readEntry("directory",QDir::homeDirPath());
00051 QString date;
00052 QDateTime dt = QDateTime::currentDateTime();
00053 date = dt.toString();
00054 date.replace(QRegExp("'"),"");
00055 date.replace(QRegExp(" "),"_");
00056 date.replace(QRegExp(":"),"-");
00057 date.replace(QRegExp(","),"");
00058
00059 QString currentFile=date;
00060 if(currentFileName.right(1).find("/",0,true) == -1)
00061 currentFileName += "/" + date;
00062 else
00063 currentFileName += date;
00064 currentFileName+=".wav";
00065
00066
00067 char pointer[] = "/tmp/opierec-XXXXXX";
00068 int fd = 0;
00069
00070 if( currentFileName.find("/mnt",0,true) == -1
00071 && currentFileName.find("/tmp",0,true) == -1 ) {
00072
00073
00074
00075 useTmpFile = true;
00076 if(( fd = mkstemp( pointer)) < 0 ) {
00077 perror("mkstemp failed");
00078 return false;
00079 }
00080
00081
00082 track.setName( pointer);
00083
00084 } else {
00085
00086 useTmpFile = false;
00087 track.setName( currentFileName);
00088 }
00089 if(!track.open( IO_ReadWrite | IO_Truncate)) {
00090 QString errorMsg=(QString)strerror(errno);
00091 odebug << errorMsg << oendl;
00092 QMessageBox::message("Note", "Error opening file.\n" +errorMsg);
00093
00094 return false;
00095 } else {
00096 setWavHeader( track.handle() , &hdr);
00097 }
00098 return true;
00099 }
00100
00101 WavFile::~WavFile() {
00102
00103 closeFile();
00104 }
00105
00106 void WavFile::closeFile() {
00107 if(track.isOpen())
00108 track.close();
00109 }
00110
00111 int WavFile::openFile(const QString ¤tFileName) {
00112 qWarning("open play file "+currentFileName);;
00113 closeFile();
00114
00115 track.setName(currentFileName);
00116
00117 if(!track.open(IO_ReadOnly)) {
00118 QString errorMsg=(QString)strerror(errno);
00119 odebug << "<<<<<<<<<<< "+errorMsg+currentFileName << oendl;
00120 QMessageBox::message("Note", "Error opening file.\n" +errorMsg);
00121 return -1;
00122 } else {
00123 parseWavHeader( track.handle());
00124 }
00125 return track.handle();
00126 }
00127
00128 bool WavFile::setWavHeader(int fd, wavhdr *hdr) {
00129
00130 strncpy((*hdr).riffID, "RIFF", 4);
00131 strncpy((*hdr).wavID, "WAVE", 4);
00132 strncpy((*hdr).fmtID, "fmt ", 4);
00133 (*hdr).fmtLen = 16;
00134
00135 if( wavFormat == WAVE_FORMAT_PCM) {
00136 (*hdr).fmtTag = 1;
00137
00138 }
00139 else {
00140 (*hdr).fmtTag = WAVE_FORMAT_DVI_ADPCM;
00141
00142 }
00143
00144
00145 (*hdr).nChannels = wavChannels;
00146
00147 (*hdr).sampleRate = wavSampleRate;
00148 (*hdr).avgBytesPerSec = (wavSampleRate)*( wavChannels*(wavResolution/8));
00149 (*hdr).nBlockAlign = wavChannels*( wavResolution/8);
00150 (*hdr).bitsPerSample = wavResolution;
00151
00152 strncpy((*hdr).dataID, "data", 4);
00153
00154 write( fd,hdr, sizeof(*hdr));
00155
00156 return true;
00157 }
00158
00159 bool WavFile::adjustHeaders(int fd, int total) {
00160 lseek(fd, 4, SEEK_SET);
00161 int i = total + 36;
00162 write( fd, &i, sizeof(i));
00163 lseek( fd, 40, SEEK_SET);
00164 write( fd, &total, sizeof(total));
00165
00166 return true;
00167 }
00168
00169 int WavFile::parseWavHeader(int fd) {
00170
00171 char string[4];
00172 int found;
00173 short fmt;
00174 unsigned short ch, bitrate;
00175 unsigned long samplerrate, longdata;
00176
00177 if (read(fd, string, 4) < 4) {
00178
00179 return -1;
00180 }
00181 if (strncmp(string, "RIFF", 4)) {
00182
00183 return -1;
00184 }
00185 lseek(fd, 4, SEEK_CUR);
00186 if (read(fd, string, 4) < 4) {
00187
00188 return -1;
00189 }
00190 if (strncmp(string, "WAVE", 4)) {
00191
00192 return -1;
00193 }
00194 found = 0;
00195
00196 while (!found) {
00197 if (read(fd, string, 4) < 4) {
00198
00199 return -1;
00200 }
00201 if (strncmp(string, "fmt ", 4)) {
00202 if (read(fd, &longdata, 4) < 4) {
00203
00204 return -1;
00205 }
00206 lseek(fd, longdata, SEEK_CUR);
00207 } else {
00208 lseek(fd, 4, SEEK_CUR);
00209 if (read(fd, &fmt, 2) < 2) {
00210
00211 return -1;
00212 }
00213 if (fmt != WAVE_FORMAT_PCM && fmt != WAVE_FORMAT_DVI_ADPCM) {
00214
00215 return -1;
00216 }
00217 wavFormat = fmt;
00218
00219
00220 if (read(fd, &ch, 2) < 2) {
00221
00222 return -1;
00223 } else {
00224 wavChannels = ch;
00225
00226 }
00227 if (read(fd, &samplerrate, 4) < 4) {
00228
00229 return -1;
00230 } else {
00231 wavSampleRate = samplerrate;
00232
00233
00234 }
00235 lseek(fd, 6, SEEK_CUR);
00236 if (read(fd, &bitrate, 2) < 2) {
00237
00238 return -1;
00239 } else {
00240 wavResolution=bitrate;
00241
00242
00243 }
00244 found++;
00245 }
00246 }
00247 found = 0;
00248 while (!found) {
00249 if (read(fd, string, 4) < 4) {
00250 odebug << "Could not read from sound file." << oendl;
00251 return -1;
00252 }
00253
00254 if (strncmp(string, "data", 4)) {
00255 if (read(fd, &longdata, 4)<4) {
00256 odebug << "Could not read from sound file." << oendl;
00257 return -1;
00258 }
00259
00260 lseek(fd, longdata, SEEK_CUR);
00261 } else {
00262 if (read(fd, &longdata, 4) < 4) {
00263 odebug << "Could not read from sound file." << oendl;
00264 return -1;
00265 } else {
00266 wavNumberSamples = longdata;
00267 odebug << "file hase length of " << (int)longdata << ""
00268 << "lasting "
00269 << (int)(( longdata / wavSampleRate) / wavChannels) / ( wavChannels*( wavResolution/8))
00270 << " seconds" << oendl;
00271
00272
00273 return longdata;
00274 }
00275 }
00276 }
00277
00278 lseek(fd, 0, SEEK_SET);
00279
00280 return 0;
00281 }
00282
00283 QString WavFile::trackName() {
00284 return track.name();
00285 }
00286
00287 int WavFile::wavHandle(){
00288 return track.handle();
00289 }
00290
00291 int WavFile::getFormat() {
00292 return wavFormat;
00293 }
00294
00295 int WavFile::getResolution() {
00296 return wavResolution;
00297 }
00298
00299 int WavFile::getSampleRate() {
00300 return wavSampleRate;
00301 }
00302
00303 int WavFile::getNumberSamples() {
00304 return wavNumberSamples;
00305 }
00306
00307 bool WavFile::isTempFile() {
00308 return useTmpFile;
00309 }
00310
00311 int WavFile::getChannels() {
00312
00313 return wavChannels;
00314 }