int main(void) { // print library versions (the actual loaded versions, if dynamically linked) printf("Versions:\n%s\n", LoadedVersions::Get().GetVersionsList().c_str()); XMLADMData *adm; // create basic ADM if ((adm = XMLADMData::CreateADM()) != NULL) { ADMData::OBJECTNAMES names; // 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 16 tracks, channels and streams uint_t t, ntracks = 16; for (t = 0; t < ntracks; 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)); 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 // find channel format object for this track ADMAudioChannelFormat *cf; if ((cf = dynamic_cast<ADMAudioChannelFormat *>(adm->GetWritableObjectByName(names.channelFormatName, ADMAudioChannelFormat::Type))) != NULL) { // found channel format, generate block formats for it ADMAudioBlockFormat *bf; uint_t i; for (i = 0; i < 20; i++) { if ((bf = adm->CreateBlockFormat(cf)) != NULL) { AudioObjectParameters params; Position pos; // set start time to be index * 25ms bf->SetRTime(i * 25000000); // set duration to be 25ms bf->SetDuration(25000000); pos.polar = true; pos.pos.az = fmod((double)(t + i) * 20.0, 360.0); pos.pos.el = (double)i / (double)ntracks * 60.0; pos.pos.d = 1.0; params.SetPosition(pos); params.SetGain(2.0); params.SetWidth(5.0); params.SetHeight(10.0); params.SetDepth(15.0); params.SetDiffuseness(20.0); params.SetDelay(25.0); params.SetObjectImportance(5); params.SetChannelImportance(2); params.SetDialogue(1); params.SetChannelLock(true); params.SetInteract(true); params.SetInterpolate(true); params.SetInterpolationTimeS(5.2); params.SetOnScreen(true); ParameterSet othervalues = params.GetOtherValues(); params.SetOtherValues(othervalues.Set("other1", 1).Set("other2", "2")); // set object parameters bf->GetObjectParameters() = params; } else fprintf(stderr, "Failed to create audioBlockFormat (t: %u, i: %u)\n", t, i); } } else { // this will only occur in the case of an error fprintf(stderr, "Unable to find channel format '%s'\n", names.channelFormatName.c_str()); } } // finalise ADM adm->Finalise(); // output ADM printf("XML:\n%s", adm->GetAxml().c_str()); } return 0; }
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: write-separate-adm <filename>\n"); exit(1); } // create basic ADM XMLADMData *adm; if ((adm = XMLADMData::CreateADM()) != NULL) { ADMData::OBJECTNAMES names; // 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 16 tracks, channels and streams uint_t t, ntracks = 16; for (t = 0; t < ntracks; t++) { ADMAudioTrack *track; 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; // create audioTrackUID for chna chunk if ((track = adm->CreateTrack(names.trackNumber)) != NULL) { track->SetSampleRate(48000); track->SetBitDepth(24); } // 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)); 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 // find channel format object for this track ADMAudioChannelFormat *cf; if ((cf = dynamic_cast<ADMAudioChannelFormat *>(adm->GetWritableObjectByName(names.channelFormatName, ADMAudioChannelFormat::Type))) != NULL) { // found channel format, generate block formats for it ADMAudioBlockFormat *bf; uint_t i; for (i = 0; i < 20; i++) { if ((bf = adm->CreateBlockFormat(cf)) != NULL) { AudioObjectParameters params; Position pos; // set start time to be index * 25ms bf->SetRTime(i * 25000000); // set duration to be 25ms bf->SetDuration(25000000); pos.polar = true; pos.pos.az = fmod((double)(t + i) * 20.0, 360.0); pos.pos.el = (double)i / (double)ntracks * 60.0; pos.pos.d = 1.0; params.SetPosition(pos); params.SetGain(2.0); params.SetWidth(5.0); params.SetHeight(10.0); params.SetDepth(15.0); params.SetDiffuseness(20.0); params.SetDelay(25.0); params.SetObjectImportance(5); params.SetChannelImportance(2); params.SetDialogue(1); params.SetChannelLock(true); params.SetInteract(true); params.SetInterpolate(true); params.SetInterpolationTimeS(5.2); params.SetOnScreen(true); ParameterSet othervalues = params.GetOtherValues(); params.SetOtherValues(othervalues.Set("other1", 1).Set("other2", "2")); // set object parameters bf->GetObjectParameters() = params; } else fprintf(stderr, "Failed to create audioBlockFormat (t: %u, i: %u)\n", t, i); } } else { // this will only occur in the case of an error fprintf(stderr, "Unable to find channel format '%s'\n", names.channelFormatName.c_str()); } } // finalise ADM adm->Finalise(); // output ADM std::string axml = adm->GetAxml(); printf("XML:\n%s", axml.c_str()); // create simple WAV file RIFFFile file; if (file.Create(argv[1], 48000, 16)) { // add the chna and axml chunks from the ADM uint64_t len; const uint8_t *data; // add chna chunk if ((data = adm->GetChna(len)) != NULL) file.AddChunk("chna", data, len); else fprintf(stderr, "No chna chunk to add!\n"); // add axml chunk file.AddChunk("axml", (const uint8_t *)axml.c_str(), axml.size()); // write everything file.Close(); } else fprintf(stderr, "Failed to create file '%s'\n", argv[1]); } else fprintf(stderr, "Failed to create ADM - no provider available?\n"); 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; }