mas01cr@498: extern "C" { mas01cr@498: #include "audioDB_API.h" mas01cr@498: } mas01cr@498: #include "audioDB-internals.h" mas01cr@239: mas01cr@239: /* Make a new database. mas01cr@239: mas01cr@509: (FIXME: this text, in particular the conditional, will not be true mas01cr@509: once we implement create flags rather than defaulting on format based mas01cr@509: on the requested size arguments) mas01cr@509: mas01cr@509: IF size(featuredata) < ADB_FIXME_LARGE_ADB_SIZE mas01cr@239: The database consists of: mas01cr@239: mas01cr@509: * a header (see adb_header_t definition); mas01cr@239: * keyTable: list of keys of tracks; mas01cr@239: * trackTable: Maps implicit feature index to a feature vector mas01cr@239: matrix (sizes of tracks) mas01cr@239: * featureTable: Lots of doubles; mas01cr@239: * timesTable: (start,end) time points for each feature vector; mas01cr@239: * powerTable: associated power for each feature vector; mas01cr@239: * l2normTable: squared l2norms for each feature vector. mas01cr@498: mas01mc@324: ELSE the database consists of: mas01cr@498: mas01cr@509: * a header (see adb_header_t definition); mas01mc@324: * keyTable: list of keys of tracks mas01mc@324: * trackTable: sizes of tracks mas01mc@324: * featureTable: list of feature file names mas01mc@324: * timesTable: list of times file names mas01mc@324: * powerTable: list of power file names mas01mc@324: mas01cr@239: */ mas01cr@239: mas01cr@498: adb_t *audiodb_create(const char *path, unsigned datasize, unsigned ntracks, unsigned datadim) { mas01cr@498: int fd; mas01cr@498: adb_header_t *header = 0; mas01cr@498: off_t databytes, auxbytes; mas01cr@498: if(datasize == 0) { mas01cr@509: datasize = ADB_DEFAULT_DATASIZE; mas01cr@498: } mas01cr@498: if(ntracks == 0) { mas01cr@509: ntracks = ADB_DEFAULT_NTRACKS; mas01cr@498: } mas01cr@498: if(datadim == 0) { mas01cr@509: datadim = ADB_DEFAULT_DATADIM; mas01cr@498: } mas01cr@239: mas01cr@595: if ((fd = open(path, O_RDWR|O_CREAT|O_EXCL, ADB_CREAT_PERMISSIONS)) < 0) { mas01cr@498: goto error; mas01cr@498: } mas01cr@239: mas01cr@498: header = (adb_header_t *) malloc(sizeof(adb_header_t)); mas01cr@498: if(!header) { mas01cr@498: goto error; mas01cr@498: } mas01cr@239: mas01cr@239: // Initialize header mas01cr@509: header->magic = ADB_MAGIC; mas01cr@509: header->version = ADB_FORMAT_VERSION; mas01cr@498: header->numFiles = 0; mas01cr@498: header->dim = 0; mas01cr@498: header->flags = 0; mas01cr@509: header->headerSize = ADB_HEADER_SIZE; mas01cr@498: header->length = 0; mas01cr@509: header->fileTableOffset = align_page_up(ADB_HEADER_SIZE); mas01cr@509: header->trackTableOffset = align_page_up(header->fileTableOffset + ADB_FILETABLE_ENTRY_SIZE*ntracks); // mas01cr@509: header->dataOffset = align_page_up(header->trackTableOffset + ADB_TRACKTABLE_ENTRY_SIZE*ntracks); mas01cr@256: mas01cr@498: databytes = ((off_t) datasize) * 1024 * 1024; mas01cr@498: auxbytes = databytes / datadim; mas01cr@498: mas01mc@324: // If database will fit in a single file the vectors are copied into the AudioDB instance mas01mc@324: // Else all the vectors are left on the FileSystem and we use the dataOffset as storage mas01mc@324: // for the location of the features, powers and times files (assuming that arbitrary keys are used for the fileTable) mas01cr@509: if(ntracks < ADB_FIXME_LARGE_ADB_NTRACKS && datasize < ADB_FIXME_LARGE_ADB_SIZE) { mas01cr@509: header->timesTableOffset = align_page_up(header->dataOffset + databytes); mas01cr@509: header->powerTableOffset = align_page_up(header->timesTableOffset + 2*auxbytes); mas01cr@509: header->l2normTableOffset = align_page_up(header->powerTableOffset + auxbytes); mas01cr@509: header->dbSize = align_page_up(header->l2normTableOffset + auxbytes); mas01cr@509: } else { // Create REFERENCES ADB, features and powers kept on filesystem mas01cr@509: header->flags |= ADB_HEADER_FLAG_REFERENCES; mas01cr@509: header->timesTableOffset = align_page_up(header->dataOffset + ADB_FILETABLE_ENTRY_SIZE*ntracks); mas01cr@509: header->powerTableOffset = align_page_up(header->timesTableOffset + ADB_FILETABLE_ENTRY_SIZE*ntracks); mas01cr@509: header->l2normTableOffset = align_page_up(header->powerTableOffset + ADB_FILETABLE_ENTRY_SIZE*ntracks); mas01cr@498: header->dbSize = header->l2normTableOffset; mas01mc@324: } mas01cr@239: mas01cr@509: write_or_goto_error(fd, header, ADB_HEADER_SIZE); mas01cr@239: mas01cr@596: // go to the location corresponding to the last byte of the database mas01cr@596: // file, and write a byte there. mas01cr@596: lseek_set_or_goto_error(fd, header->dbSize - 1); mas01cr@498: write_or_goto_error(fd, "", 1); mas01cr@239: mas01cr@498: free(header); mas01cr@498: return audiodb_open(path, O_RDWR); mas01cr@498: mas01cr@498: error: mas01cr@596: maybe_free(header); mas01cr@498: return NULL; mas01cr@239: }