예제 #1
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: 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;
}
예제 #2
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;
}