/*--------------------------------------------------------------------------------*/ bool XMLADMData::ReadXMLFromFile(const std::string& filename, bool finalise) { EnhancedFile fp; bool success = false; if (fp.fopen(filename.c_str())) { fp.fseek(0, SEEK_END); off_t len = fp.ftell(); fp.rewind(); char *buffer; if ((buffer = new char[len + 1]) != NULL) { len = fp.fread(buffer, sizeof(char), len); buffer[len] = 0; success = SetAxml(buffer, finalise); delete[] buffer; } else BBCERROR("Failed to allocate %s chars for file '%s'", StringFrom(len + 1).c_str(), filename.c_str()); fp.fclose(); } else BBCERROR("Failed to open file '%s' for reading", filename.c_str()); return success; }
/*--------------------------------------------------------------------------------*/ bool XMLADMData::ReadChnaFromFile(const std::string& filename, bool finalise) { EnhancedFile fp; bool success = false; if (fp.fopen(filename.c_str())) { char buffer[1024]; int l; success = true; while (success && ((l = fp.readline(buffer, sizeof(buffer) - 1)) != EOF)) { if (l > 0) { std::vector<std::string> words; SplitString(std::string(buffer), words); if (words.size() == 4) { uint_t tracknum; if (Evaluate(words[0], tracknum)) { if (tracknum) { const std::string& trackuid = words[1]; const std::string& trackformat = words[2]; const std::string& packformat = words[3]; ADMAudioTrack *track; std::string id; if ((track = dynamic_cast<ADMAudioTrack *>(Create(ADMAudioTrack::Type, trackuid, ""))) != NULL) { XMLValue tvalue, pvalue; track->SetTrackNum(tracknum - 1); tvalue.name = ADMAudioTrackFormat::Reference; tvalue.value = trackformat; track->AddValue(tvalue); pvalue.name = ADMAudioPackFormat::Reference; pvalue.value = packformat; track->AddValue(pvalue); track->SetValues(); BBCDEBUG2(("Track %u: Index %u UID '%s' TrackFormatRef '%s' PackFormatRef '%s'", (uint_t)tracklist.size(), track->GetTrackNum() + 1, track->GetID().c_str(), tvalue.value.c_str(), pvalue.value.c_str())); } else { BBCERROR("Failed to create AudioTrack for UID %u", tracknum); success = false; } } } else { BBCERROR("CHNA line '%s' word 1 ('%s') should be a track number", buffer, words[0].c_str()); success = false; } } else { BBCERROR("CHNA line '%s' requires 4 words", buffer); success = false; } } } fp.fclose(); if (success && finalise) Finalise(); } return success; }
/*--------------------------------------------------------------------------------*/ void ADMRIFFFile::Close(bool abortwrite) { EnhancedFile *file = fileref; uint_t i; if (file && adm && writing && !abortwrite) { RIFFChunk *chunk; uint64_t endtime = filesamples ? filesamples->GetAbsolutePositionNS() : 0; uint64_t chnalen; uint8_t *chna; BBCDEBUG1(("Finalising ADM for '%s'...", file->getfilename().c_str())); BBCDEBUG1(("Finishing all blockformats")); // complete BlockFormats on all channels for (i = 0; i < cursors.size(); i++) { cursors[i]->Seek(endtime); cursors[i]->EndChanges(); } // finalise ADM adm->Finalise(); // update audio object time limits adm->UpdateAudioObjectLimits(); BBCDEBUG1(("Creating ADM RIFF chunks")); // get ADM object to create chna chunk if ((chna = adm->GetChna(chnalen)) != NULL) { // and add it to the RIFF file if ((chunk = GetChunk(chna_ID)) != NULL) { if (!chunk->UpdateChunkData(chna, chnalen)) BBCERROR("Failed to update chna data (possibly length has changed)"); } else BBCERROR("Failed to add chna chunk"); // don't need the raw data any more delete[] chna; } else BBCERROR("No chna data available"); // add axml chunk if ((chunk = GetChunk(axml_ID)) != NULL) { // first, calculate size of ADM (to save lots of memory allocations) uint64_t admlen = adm->GetAxmlBuffer(NULL, 0); BBCDEBUG1(("ADM size is %s bytes", StringFrom(admlen).c_str())); // allocate chunk data if (chunk->CreateChunkData(admlen)) { // finally, generate XML into buffer uint64_t admlen1 = adm->GetAxmlBuffer(chunk->GetDataWritable(), admlen); if (admlen1 != admlen) BBCERROR("Generating axml data for real resulted in different size (%s vs %s)", StringFrom(admlen1).c_str(), StringFrom(admlen).c_str()); } else BBCERROR("Failed to allocate %s bytes for axml data", StringFrom(admlen).c_str()); } else BBCERROR("Failed to add axml chunk"); } // write chunks and close file RIFFFile::Close(abortwrite); for (i = 0; i < cursors.size(); i++) { delete cursors[i]; } cursors.clear(); if (adm) { adm->Delete(); delete adm; adm = NULL; } }