Add channel assignment support for SMPTE DCPs.
authorCarl Hetherington <cth@carlh.net>
Thu, 8 Sep 2016 22:55:37 +0000 (23:55 +0100)
committerCarl Hetherington <cth@carlh.net>
Thu, 8 Sep 2016 22:55:37 +0000 (23:55 +0100)
examples/make_dcp.cc
src/rgb_xyz.cc
src/sound_asset.cc
src/sound_asset.h
src/sound_asset_writer.cc
src/sound_asset_writer.h
src/types.h
test/dcp_test.cc
test/encryption_test.cc

index 94eef710978643bdfb3805b19bcf060c3e870e6d..f0021e6bc08345ba22741b0078f95d815d908b9f 100644 (file)
@@ -48,7 +48,7 @@ main ()
 {
        /* Create a directory to put the DCP in */
        boost::filesystem::create_directory ("DCP");
-       
+
        /* Make a picture asset.  This is a file which combines JPEG2000 files together to make
           up the video of the DCP.  First, create the object, specifying a frame rate of 24 frames
           per second.
@@ -72,7 +72,7 @@ main ()
           When creating the object we specify the sampling rate (48kHz) and the number of channels (2).
        */
        boost::shared_ptr<dcp::SoundAsset> sound_asset (new dcp::SoundAsset (dcp::Fraction (24, 1), 48000, 2));
-       boost::shared_ptr<dcp::SoundAssetWriter> sound_writer = sound_asset->start_write ("DCP/sound.mxf", dcp::SMPTE);
+       boost::shared_ptr<dcp::SoundAssetWriter> sound_writer = sound_asset->start_write ("DCP/sound.mxf", dcp::SMPTE, dcp::CHANNEL_ASSIGNMENT_51);
 
        /* Write some sine waves */
        float* audio[2];
@@ -106,6 +106,6 @@ main ()
        dcp::DCP dcp ("DCP");
        dcp.add (cpl);
        dcp.write_xml (dcp::SMPTE);
-       
+
        return 0;
 }
index d299340ef7536ff5f0dfbaeb8b1cf17a7972bfd6..2eccb77a8aec0531af35c69688e3063097e4762e 100644 (file)
@@ -365,7 +365,9 @@ dcp::xyz_to_xyz (uint8_t const * xyz_16, dcp::Size size, int stride)
                uint16_t const * p = reinterpret_cast<uint16_t const *> (xyz_16 + y * stride);
                for (int x = 0; x < size.width; ++x) {
                        /* Truncate 16-bit to 12-bit */
+                       cout << *p << " ";
                        xyz_12->data(0)[jn] = *p++ >> 4;
+                       cout << xyz_12->data(0)[jn] << "\n";
                        xyz_12->data(1)[jn] = *p++ >> 4;
                        xyz_12->data(2)[jn] = *p++ >> 4;
                        ++jn;
index 11fd4b2fae685ec081f0221fe6ea35c98abcd134..2202311ac28f079cbef4ac6719f6af2d291ac392 100644 (file)
@@ -192,10 +192,10 @@ SoundAsset::equals (shared_ptr<const Asset> other, EqualityOptions opt, NoteHand
 }
 
 shared_ptr<SoundAssetWriter>
-SoundAsset::start_write (boost::filesystem::path file, Standard standard)
+SoundAsset::start_write (boost::filesystem::path file, Standard standard, ChannelAssignment assign)
 {
        /* XXX: can't we use a shared_ptr here? */
-       return shared_ptr<SoundAssetWriter> (new SoundAssetWriter (this, file, standard));
+       return shared_ptr<SoundAssetWriter> (new SoundAssetWriter (this, file, standard, assign));
 }
 
 shared_ptr<SoundAssetReader>
index a29eecd032746880c75cb51748ef4f8d8dd65061..b3e5fec3cf6f689afa13163b9d510a7f97e7ad6b 100644 (file)
@@ -58,7 +58,7 @@ public:
        explicit SoundAsset (boost::filesystem::path file);
        SoundAsset (Fraction edit_rate, int sampling_rate, int channels);
 
-       boost::shared_ptr<SoundAssetWriter> start_write (boost::filesystem::path file, Standard standard);
+       boost::shared_ptr<SoundAssetWriter> start_write (boost::filesystem::path file, Standard standard, ChannelAssignment assign);
        boost::shared_ptr<SoundAssetReader> start_read () const;
 
        bool equals (
index 84ed778756e44af2ad1719d0b7a95a3205048d4f..f7513d9171a4dee55b1f62cb419adfbd4ca8313a 100644 (file)
@@ -51,7 +51,7 @@ struct SoundAssetWriter::ASDCPState
        ASDCP::PCM::AudioDescriptor audio_desc;
 };
 
-SoundAssetWriter::SoundAssetWriter (SoundAsset* asset, boost::filesystem::path file, Standard standard)
+SoundAssetWriter::SoundAssetWriter (SoundAsset* asset, boost::filesystem::path file, Standard standard, ChannelAssignment assign)
        : AssetWriter (asset, file, standard)
        , _state (new SoundAssetWriter::ASDCPState)
        , _sound_asset (asset)
@@ -66,7 +66,27 @@ SoundAssetWriter::SoundAssetWriter (SoundAsset* asset, boost::filesystem::path f
        _state->audio_desc.BlockAlign = 3 * _sound_asset->channels();
        _state->audio_desc.AvgBps = _sound_asset->sampling_rate() * _state->audio_desc.BlockAlign;
        _state->audio_desc.LinkedTrackID = 0;
-       _state->audio_desc.ChannelFormat = ASDCP::PCM::CF_NONE;
+       if (standard == INTEROP) {
+               _state->audio_desc.ChannelFormat = ASDCP::PCM::CF_NONE;
+       } else {
+               switch (assign) {
+               case CHANNEL_ASSIGNMENT_51:
+                       _state->audio_desc.ChannelFormat = ASDCP::PCM::CF_CFG_1;
+                       break;
+               case CHANNEL_ASSIGNMENT_61:
+                       _state->audio_desc.ChannelFormat = ASDCP::PCM::CF_CFG_2;
+                       break;
+               case CHANNEL_ASSIGNMENT_71:
+                       _state->audio_desc.ChannelFormat = ASDCP::PCM::CF_CFG_3;
+                       break;
+               case CHANNEL_ASSIGNMENT_WTF:
+                       _state->audio_desc.ChannelFormat = ASDCP::PCM::CF_CFG_4;
+                       break;
+               case CHANNEL_ASSIGNMENT_71_DS:
+                       _state->audio_desc.ChannelFormat = ASDCP::PCM::CF_CFG_5;
+                       break;
+               }
+       }
 
        _state->frame_buffer.Capacity (ASDCP::PCM::CalcFrameBufferSize (_state->audio_desc));
        _state->frame_buffer.Size (ASDCP::PCM::CalcFrameBufferSize (_state->audio_desc));
index 0263942327687edb800fbe7b86411b4036909512..b13300c208653949f9c60c80165feb43b591ef5a 100644 (file)
@@ -63,7 +63,7 @@ public:
 private:
        friend class SoundAsset;
 
-       SoundAssetWriter (SoundAsset *, boost::filesystem::path, Standard standard);
+       SoundAssetWriter (SoundAsset *, boost::filesystem::path, Standard standard, ChannelAssignment);
 
        void write_current_frame ();
 
index dd2e10a6f4cc29d44d4421d166af2cd0d404dc56..c3aee26b25f0c4c7811366ad6022fb4001db5601 100644 (file)
@@ -232,6 +232,20 @@ enum Formulation {
        DCI_SPECIFIC
 };
 
+/** Possible channel assignments for SMPTE DCP audio */
+enum ChannelAssignment {
+       /** L/R/C/Lfe/Ls/Rs/HI/VI */
+       CHANNEL_ASSIGNMENT_51,
+       /** L/R/C/Lfe/Ls/Rs/Cs/unused/HI/VI */
+       CHANNEL_ASSIGNMENT_61,
+       /** L/R/C/Lfe/Ls/Rs/Lc/Rc/HI/VI */
+       CHANNEL_ASSIGNMENT_71,
+       /** "Wild track format"; no assignment */
+       CHANNEL_ASSIGNMENT_WTF,
+       /** L/R/C/Lfe/Ls/Rs/Lrs/Rrs/HI/VI */
+       CHANNEL_ASSIGNMENT_71_DS
+};
+
 /** @class Colour
  *  @brief An RGB colour.
  */
index ce10ee28b137b32622e2ec661042bbb526499ff1..bbc6ff832607fa11b0f2530525b13ca0ac2daa3d 100644 (file)
@@ -75,7 +75,7 @@ BOOST_AUTO_TEST_CASE (dcp_test1)
 
        shared_ptr<dcp::SoundAsset> ms (new dcp::SoundAsset (dcp::Fraction (24, 1), 48000, 1));
        ms->set_metadata (mxf_meta);
-       shared_ptr<dcp::SoundAssetWriter> sound_writer = ms->start_write ("build/test/DCP/dcp_test1/audio.mxf", dcp::SMPTE);
+       shared_ptr<dcp::SoundAssetWriter> sound_writer = ms->start_write ("build/test/DCP/dcp_test1/audio.mxf", dcp::SMPTE, dcp::CHANNEL_ASSIGNMENT_51);
 
        SF_INFO info;
        info.format = 0;
@@ -146,7 +146,7 @@ BOOST_AUTO_TEST_CASE (dcp_test2)
 
        shared_ptr<dcp::SoundAsset> ms (new dcp::SoundAsset (dcp::Fraction (24, 1), 48000, 1));
        ms->set_metadata (mxf_meta);
-       shared_ptr<dcp::SoundAssetWriter> sound_writer = ms->start_write ("build/test/DCP/dcp_test2/audio.mxf", dcp::SMPTE);
+       shared_ptr<dcp::SoundAssetWriter> sound_writer = ms->start_write ("build/test/DCP/dcp_test2/audio.mxf", dcp::SMPTE, dcp::CHANNEL_ASSIGNMENT_51);
 
        SF_INFO info;
        info.format = 0;
@@ -242,7 +242,7 @@ BOOST_AUTO_TEST_CASE (dcp_test5)
 
        shared_ptr<dcp::SoundAsset> ms (new dcp::SoundAsset (dcp::Fraction (24, 1), 48000, 1));
        ms->set_metadata (mxf_meta);
-       shared_ptr<dcp::SoundAssetWriter> sound_writer = ms->start_write ("build/test/DCP/dcp_test5/audio.mxf", dcp::SMPTE);
+       shared_ptr<dcp::SoundAssetWriter> sound_writer = ms->start_write ("build/test/DCP/dcp_test5/audio.mxf", dcp::SMPTE, dcp::CHANNEL_ASSIGNMENT_51);
 
        SF_INFO info;
        info.format = 0;
index a817d24606b0a04ae084e23c4a99823bd39ee882..665169d9a6ba453ea71d17ba1bc17db4f4275051 100644 (file)
@@ -91,7 +91,7 @@ BOOST_AUTO_TEST_CASE (encryption_test)
        shared_ptr<dcp::SoundAsset> ms (new dcp::SoundAsset (dcp::Fraction (24, 1), 48000, 1));
        ms->set_metadata (mxf_metadata);
        ms->set_key (key);
-       shared_ptr<dcp::SoundAssetWriter> sound_writer = ms->start_write ("build/test/DCP/encryption_test/audio.mxf", dcp::SMPTE);
+       shared_ptr<dcp::SoundAssetWriter> sound_writer = ms->start_write ("build/test/DCP/encryption_test/audio.mxf", dcp::SMPTE, dcp::CHANNEL_ASSIGNMENT_51);
 
        SF_INFO info;
        info.format = 0;