int main(int argc, char *argv[]) { // print library versions (the actual loaded versions, if dynamically linked) printf("Versions:\n%s\n", LoadedVersions::Get().GetVersionsList().c_str()); if (argc < 2) { fprintf(stderr, "Usage: read-adm-bwf <bwf-file>\n"); exit(1); } // ADM aware WAV file ADMRIFFFile file; if (file.Open(argv[1])) { // a list of ADM object types to list static const char *types[] = { "audioProgramme", "audioContent", "audioObject", "audioChannelFormat", "audioTrackUID", }; // get access to ADM data object const ADMData *adm = file.GetADM(); uint_t j; printf("Opened '%s' okay, %u channels at %luHz (%u bytes per sample)\n", argv[1], file.GetChannels(), (ulong_t)file.GetSampleRate(), (uint_t)file.GetBytesPerSample()); // list ADM objects of different types for (j = 0; j < NUMBEROF(types); j++) { // list objects of a certain type std::vector<const ADMObject *>list; const char *type = types[j]; uint_t k; // get list of objects of specified type adm->GetObjects(type, list); if (list.size() > 0) { printf("Objects of type '%s':\n", type); for (k = 0; k < list.size(); k++) { const ADMObject *obj = list[k]; // print out information about the object printf(" %s\n", obj->ToString().c_str()); } printf("\n"); } else printf("No objects of type '%s'!\n", type); } // access the audio of an audio object { std::vector<const ADMObject *>list; // get a list of audioObjects adm->GetObjects("audioObject", list); if (list.size() > 0) { const ADMAudioObject *obj; // pick last object if ((obj = dynamic_cast<const ADMAudioObject *>(list.back())) != NULL) { // create audio samples handler for the audio object ADMAudioFileSamples handler(file.GetSamples(), obj); std::vector<Sample_t> samples; uint_t n, nsamples = 1024; printf("Reading audio from %s (%u channels)\n", obj->ToString().c_str(), handler.GetChannels()); // make buffer for 1024 frames worth of samples samples.resize(handler.GetChannels() * nsamples); // read samples (start channel and interleaving are handled by handler) while ((handler.GetSamplePosition() < 16384) && ((n = handler.ReadSamples(&samples[0], 0, handler.GetChannels(), nsamples)) > 0)) // arbitrary stop point of 16384! { printf("%u/%u sample frames read, sample position %s/%s\n", n, nsamples, StringFrom(handler.GetSamplePosition()).c_str(), StringFrom(handler.GetSampleLength()).c_str()); } } } else fprintf(stderr, "No audio objects in '%s'!\n", argv[1]); } // access raw audio data of entire file { // get audio samples handler for entire file SoundFileSamples *handler = file.GetSamples(); UNUSED_PARAMETER(handler); /* * handler->ReadSamples(...) works just like handler.ReadSamples(...) above but on the entire file instead of just a single audio object * */ } } else fprintf(stderr, "Failed to open file '%s' for reading!\n", argv[1]); return 0; }
int main(void) { // ensure libraries are set up bbcat_register_bbcat_fileio(); // ADM aware WAV file ADMRIFFFile file; const char *filename = "adm-4gb-bwf.wav"; // IMPORTANT: create basic ADM here - if this is not done, the file will be a plain WAV file! file.CreateADM(); // create file if (file.Create(filename, 48000, 32)) { ADMData *adm = file.GetADM(); if (adm) { ADMData::OBJECTNAMES names; printf("Created '%s' okay, %u channels at %luHz (%u bytes per sample)\n", filename, file.GetChannels(), (ulong_t)file.GetSampleRate(), (uint_t)file.GetBytesPerSample()); // set programme name // if an audioProgramme object of this name doesn't exist, one will be created names.programmeName = "ADM Test Programme"; // set content name // if an audioContent object of this name doesn't exist, one will be created names.contentName = "ADM Test Content"; // create tracks, channels and streams uint_t t; const ADMData::TRACKLIST& tracklist = adm->GetTrackList(); for (t = 0; t < tracklist.size(); t++) { std::string trackname; printf("------------- Track %2u -----------------\n", t + 1); // create default audioTrackFormat name (used for audioStreamFormat objects as well) Printf(trackname, "Track %u", t + 1); names.trackNumber = t; // derive channel and stream names from track name names.channelFormatName = trackname; names.streamFormatName = "PCM_" + trackname; names.trackFormatName = "PCM_" + trackname; // set object name // create 4 objects, each of 4 tracks names.objectName = ""; // need this because Printf() APPENDS! Printf(names.objectName, "Object %u", 1 + (t / 4)); // set pack name from object name // create 4 packs, each of 4 tracks names.packFormatName = ""; // need this because Printf() APPENDS! Printf(names.packFormatName, "Pack %u", 1 + (t / 4)); // set default typeLabel names.typeLabel = ADMObject::TypeLabel_Objects; adm->CreateObjects(names); // note how the programme and content names are left in place in 'names' // this is necessary to ensure that things are linked up properly } } else fprintf(stderr, "File does not have an ADM associated with it, did you forget to create one?\n"); // write audio const uint_t nchannels = file.GetChannels(); std::vector<sint32_t> audio; double fs = (double)file.GetSampleRate(); double level = dBToGain(-40.0); uint64_t i, nsamples = (uint64_t)1000 * (uint64_t)file.GetSampleRate(); uint_t step = file.GetSampleRate() * 10; uint_t j, pc = ~0; UNUSED_PARAMETER(fs); UNUSED_PARAMETER(level); audio.resize(step * nchannels); // write 1000s worth of samples for (i = 0; i < nsamples; i += step) { { uint_t index = (uint_t)(i / step); for (j = 0; j < nchannels; j++) { AudioObjectParameters params; Position pos; pos.polar = true; pos.pos.az = (double)(index + j) * 20.0; pos.pos.el = (double)j / (double)file.GetChannels() * 60.0; pos.pos.d = 1.0; params.SetPosition(pos); // set some extra parameters params.SetWidth((float)j * .2); params.SetDepth((float)j * .4); params.SetHeight((float)j * .3); if (j < 2) { params.SetScreenEdgeLock("azimuth", j ? "right" : "left"); params.SetScreenEdgeLock("elevation", j ? "bottom" : "top"); } else if (j == 2) { params.AddExcludedZone("left", -1, -1, -1, -.8, 1, 1); params.AddExcludedZone("right", .8, -1, -1, 1.0, 1, 1); } else { params.SetObjectImportance(5 + j - 3); params.SetChannelImportance(2 + j - 3); params.SetInteract(j != 3); params.SetDisableDucking(j == 3); } file.SetObjectParameters(j, params); } } // write a frame of audio file.WriteSamples(&audio[0], 0, nchannels, step); uint_t pc1 = (uint_t)((i * 100) / nsamples); if (pc1 != pc) { pc = pc1; printf("\rWriting... %u%% done", pc); fflush(stdout); } } printf("\n"); file.Close(); } else fprintf(stderr, "Failed to open file '%s' for writing!\n", filename); return 0; }