示例#1
0
/*--------------------------------------------------------------------------------*/
bool ADMRIFFFile::CreateExtraChunks()
{
  bool success = true;

  if (adm)
  {
    RIFFChunk *chunk;
    uint64_t  chnalen;
    uint8_t   *chna;
    uint_t i, nchannels = GetChannels();

    success = true;

    for (i = 0; i < nchannels; i++)
    {
      ADMAudioTrack *track;

      // create chna track data
      if ((track = adm->CreateTrack(i)) != NULL)
      {
        track->SetSampleRate(GetSampleRate());
        track->SetBitDepth(GetBitsPerSample());
      }
    }

    if (!admfile.empty())
    {
      // create ADM structure (content and objects from file)
      if (adm->CreateFromFile(admfile.c_str()))
      {
        // can prepare cursors now since all objects have been created
        PrepareCursors();
      }
      else
      {
        BBCERROR("Unable to create ADM structure from '%s'", admfile.c_str());
        success = false;
      }
    }

    // get ADM object to create chna chunk
    if ((chna = adm->GetChna(chnalen)) != NULL)
    {
      // and add it to the RIFF file
      if ((chunk = AddChunk(chna_ID)) != NULL)
      {
        success &= chunk->CreateChunkData(chna, chnalen);
      }
      else BBCERROR("Failed to add chna chunk");

      // don't need the raw data any more
      delete[] chna;
    }
    else BBCERROR("No chna data available");

    success &= (AddChunk(axml_ID) != NULL);
  }

  return success;
}
示例#2
0
/*--------------------------------------------------------------------------------*/
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;
  }
}