mas01cr@239: #include "audioDB.h" mas01cr@239: mas01cr@239: #if defined(O2_DEBUG) mas01cr@239: void sigterm_action(int signal, siginfo_t *info, void *context) { mas01cr@239: exit(128+signal); mas01cr@239: } mas01cr@239: mas01cr@239: void sighup_action(int signal, siginfo_t *info, void *context) { mas01cr@239: // FIXME: reread any configuration files mas01cr@239: } mas01cr@239: #endif mas01cr@239: mas01cr@239: void audioDB::error(const char* a, const char* b, const char *sysFunc) { mas01ik@355: mas01ik@355: mas01ik@355: if(isServer) { mas01cr@370: /* FIXME: I think this is leaky -- we never delete err. mas01cr@370: actually deleting it is tricky, though; it gets placed into mas01cr@370: some soap-internal struct with uncertain extent... -- CSR, mas01cr@370: 2007-10-01 */ mas01cr@370: char *err = new char[256]; /* FIXME: overflows */ mas01cr@370: snprintf(err, 255, "%s: %s\n%s", a, b, sysFunc ? strerror(errno) : ""); mas01cr@370: /* FIXME: actually we could usefully do with a properly mas01cr@370: structured type, so that we can throw separate faultstring mas01cr@370: and details. -- CSR, 2007-10-01 */ mas01ik@355: throw(err); mas01ik@355: } else { mas01ik@355: std::cerr << a << ": " << b << std::endl; mas01ik@355: if (sysFunc) { mas01ik@355: perror(sysFunc); mas01ik@355: } mas01ik@355: exit(1); mas01cr@239: } mas01cr@239: } mas01cr@239: mas01cr@239: void audioDB::initDBHeader(const char* dbName) { mas01cr@498: if(!adb) { mas01cr@498: adb = audiodb_open(dbName, forWrite ? O_RDWR : O_RDONLY); mas01cr@498: if(!adb) { mas01cr@498: error("Failed to open database", dbName); mas01cr@498: } mas01cr@239: } mas01cr@498: dbfid = adb->fd; mas01cr@498: dbH = adb->header; mas01cr@239: mas01cr@239: // Make some handy tables with correct types mas01cr@239: if(forWrite || (dbH->length > 0)) { mas01cr@239: if(forWrite) { mas01cr@239: fileTableLength = dbH->trackTableOffset - dbH->fileTableOffset; mas01cr@239: trackTableLength = dbH->dataOffset - dbH->trackTableOffset; mas01cr@239: timesTableLength = dbH->powerTableOffset - dbH->timesTableOffset; mas01cr@239: powerTableLength = dbH->l2normTableOffset - dbH->powerTableOffset; mas01cr@239: l2normTableLength = dbH->dbSize - dbH->l2normTableOffset; mas01cr@239: } else { mas01cr@256: fileTableLength = ALIGN_PAGE_UP(dbH->numFiles * O2_FILETABLE_ENTRY_SIZE); mas01cr@256: trackTableLength = ALIGN_PAGE_UP(dbH->numFiles * O2_TRACKTABLE_ENTRY_SIZE); mas01mc@324: if( dbH->flags & O2_FLAG_LARGE_ADB ){ mas01mc@324: timesTableLength = ALIGN_PAGE_UP(dbH->numFiles * O2_FILETABLE_ENTRY_SIZE); mas01mc@324: powerTableLength = ALIGN_PAGE_UP(dbH->numFiles * O2_FILETABLE_ENTRY_SIZE); mas01mc@324: l2normTableLength = 0; mas01mc@324: } mas01mc@324: else{ mas01mc@324: timesTableLength = ALIGN_PAGE_UP(2*(dbH->length / dbH->dim)); mas01mc@324: powerTableLength = ALIGN_PAGE_UP(dbH->length / dbH->dim); mas01mc@324: l2normTableLength = ALIGN_PAGE_UP(dbH->length / dbH->dim); mas01mc@324: } mas01cr@239: } mas01cr@239: CHECKED_MMAP(char *, fileTable, dbH->fileTableOffset, fileTableLength); mas01cr@239: CHECKED_MMAP(unsigned *, trackTable, dbH->trackTableOffset, trackTableLength); mas01mc@324: if( dbH->flags & O2_FLAG_LARGE_ADB ){ mas01mc@324: CHECKED_MMAP(char *, featureFileNameTable, dbH->dataOffset, fileTableLength); mas01mc@324: if( dbH->flags & O2_FLAG_TIMES ) mas01mc@324: CHECKED_MMAP(char *, timesFileNameTable, dbH->timesTableOffset, fileTableLength); mas01mc@324: if( dbH->flags & O2_FLAG_POWER ) mas01mc@324: CHECKED_MMAP(char *, powerFileNameTable, dbH->powerTableOffset, fileTableLength); mas01mc@324: } mas01mc@324: else{ mas01mc@324: CHECKED_MMAP(double *, timesTable, dbH->timesTableOffset, timesTableLength); mas01mc@324: CHECKED_MMAP(double *, powerTable, dbH->powerTableOffset, powerTableLength); mas01mc@324: CHECKED_MMAP(double *, l2normTable, dbH->l2normTableOffset, l2normTableLength); mas01mc@324: } mas01cr@239: } mas01cr@239: } mas01cr@239: mas01cr@498: void audioDB::initInputFile (const char *inFile) { mas01cr@239: if (inFile) { mas01cr@239: if ((infid = open(inFile, O_RDONLY)) < 0) { mas01cr@239: error("can't open input file for reading", inFile, "open"); mas01cr@239: } mas01cr@239: mas01cr@239: if (fstat(infid, &statbuf) < 0) { mas01cr@239: error("fstat error finding size of input", inFile, "fstat"); mas01cr@239: } mas01cr@239: mas01cr@239: if(dbH->dim == 0 && dbH->length == 0) { // empty database mas01cr@239: // initialize with input dimensionality mas01cr@239: if(read(infid, &dbH->dim, sizeof(unsigned)) != sizeof(unsigned)) { mas01cr@239: error("short read of input file", inFile); mas01cr@239: } mas01cr@239: if(dbH->dim == 0) { mas01cr@239: error("dimensionality of zero in input file", inFile); mas01cr@239: } mas01cr@239: } else { mas01cr@239: unsigned test; mas01cr@239: if(read(infid, &test, sizeof(unsigned)) != sizeof(unsigned)) { mas01cr@239: error("short read of input file", inFile); mas01cr@239: } mas01cr@239: if(dbH->dim == 0) { mas01cr@239: error("dimensionality of zero in input file", inFile); mas01cr@239: } mas01cr@239: if(dbH->dim != test) { mas01cr@239: std::cerr << "error: expected dimension: " << dbH->dim << ", got : " << test < O2_MAXFILESTR) mas01mc@324: error("error: path prefix + filename too long",prefix); mas01mc@324: // Do not prefix absolute path+filename mas01mc@324: if(**name=='/') mas01mc@324: return; mas01mc@324: // OK to prefix relative path+filename mas01mc@324: char* prefixedName = (char*) malloc(O2_MAXFILESTR); mas01mc@324: sprintf(prefixedName, "%s/%s", prefix, *name); mas01mc@324: *name = prefixedName; // side effect new name to old name mas01mc@324: } mas01cr@498: mas01cr@498: void audioDB::insertTimeStamps(unsigned numVectors, std::ifstream *timesFile, double *timesdata) { mas01cr@498: assert(usingTimes); mas01cr@498: mas01cr@498: unsigned numtimes = 0; mas01cr@498: mas01cr@498: if(!timesFile->is_open()) { mas01cr@498: error("problem opening times file on timestamped database", timesFileName); mas01cr@498: } mas01cr@498: mas01cr@498: double timepoint, next; mas01cr@498: *timesFile >> timepoint; mas01cr@498: if (timesFile->eof()) { mas01cr@498: error("no entries in times file", timesFileName); mas01cr@498: } mas01cr@498: numtimes++; mas01cr@498: do { mas01cr@498: *timesFile >> next; mas01cr@498: if (timesFile->eof()) { mas01cr@498: break; mas01cr@498: } mas01cr@498: numtimes++; mas01cr@498: timesdata[0] = timepoint; mas01cr@498: timepoint = (timesdata[1] = next); mas01cr@498: timesdata += 2; mas01cr@498: } while (numtimes < numVectors + 1); mas01cr@498: mas01cr@498: if (numtimes < numVectors + 1) { mas01cr@498: error("too few timepoints in times file", timesFileName); mas01cr@498: } mas01cr@498: mas01cr@498: *timesFile >> next; mas01cr@498: if (!timesFile->eof()) { mas01cr@498: error("too many timepoints in times file", timesFileName); mas01cr@498: } mas01cr@498: }