Add basic example; tweak bits and pieces.
[libdcp.git] / src / sound_asset.cc
index dae66f900659ff17346e2b7f90fe06920272767d..732bb61029f8282492972b4c6575ab74e31ba83c 100644 (file)
@@ -30,6 +30,7 @@
 #include "sound_asset.h"
 #include "util.h"
 #include "exceptions.h"
+#include "sound_frame.h"
 
 using namespace std;
 using namespace boost;
@@ -38,8 +39,9 @@ using namespace libdcp;
 SoundAsset::SoundAsset (
        vector<string> const & files, string directory, string mxf_name, sigc::signal1<void, float>* progress, int fps, int length
        )
-       : Asset (directory, mxf_name, progress, fps, length)
+       : MXFAsset (directory, mxf_name, progress, fps, 0, length)
        , _channels (files.size ())
+       , _sampling_rate (0)
 {
        construct (sigc::bind (sigc::mem_fun (*this, &SoundAsset::path_from_channel), files));
 }
@@ -47,17 +49,30 @@ SoundAsset::SoundAsset (
 SoundAsset::SoundAsset (
        sigc::slot<string, Channel> get_path, string directory, string mxf_name, sigc::signal1<void, float>* progress, int fps, int length, int channels
        )
-       : Asset (directory, mxf_name, progress, fps, length)
+       : MXFAsset (directory, mxf_name, progress, fps, 0, length)
        , _channels (channels)
+       , _sampling_rate (0)
 {
        construct (get_path);
 }
 
-SoundAsset::SoundAsset (string directory, string mxf_name, int fps, int length)
-       : Asset (directory, mxf_name, 0, fps, length)
+SoundAsset::SoundAsset (string directory, string mxf_name, int fps, int entry_point, int length)
+       : MXFAsset (directory, mxf_name, 0, fps, entry_point, length)
        , _channels (0)
 {
-       _digest = make_digest (mxf_path().string(), 0);
+       ASDCP::PCM::MXFReader reader;
+       if (ASDCP_FAILURE (reader.OpenRead (path().string().c_str()))) {
+               throw FileError ("could not open MXF file for reading", path().string());
+       }
+
+       
+       ASDCP::PCM::AudioDescriptor desc;
+       if (ASDCP_FAILURE (reader.FillAudioDescriptor (desc))) {
+               throw DCPReadError ("could not read audio MXF information");
+       }
+
+       _sampling_rate = desc.AudioSamplingRate.Numerator / desc.AudioSamplingRate.Denominator;
+       _channels = desc.ChannelCount;
 }
 
 string
@@ -120,8 +135,8 @@ SoundAsset::construct (sigc::slot<string, Channel> get_path)
        fill_writer_info (&writer_info);
 
        ASDCP::PCM::MXFWriter mxf_writer;
-       if (ASDCP_FAILURE (mxf_writer.OpenWrite (mxf_path().c_str(), writer_info, audio_desc))) {
-               throw FileError ("could not open audio MXF for writing", mxf_path().string());
+       if (ASDCP_FAILURE (mxf_writer.OpenWrite (path().string().c_str(), writer_info, audio_desc))) {
+               throw FileError ("could not open audio MXF for writing", path().string());
        }
 
        for (int i = 0; i < _length; ++i) {
@@ -155,14 +170,14 @@ SoundAsset::construct (sigc::slot<string, Channel> get_path)
                        throw MiscError ("could not write audio MXF frame");
                }
 
-               (*_progress) (0.5 * float (i) / _length);
+               if (_progress) {
+                       (*_progress) (0.5 * float (i) / _length);
+               }
        }
 
        if (ASDCP_FAILURE (mxf_writer.Finalize())) {
                throw MiscError ("could not finalise audio MXF");
        }
-
-       _digest = make_digest (mxf_path().string(), _progress);
 }
 
 void
@@ -170,7 +185,7 @@ SoundAsset::write_to_cpl (ostream& s) const
 {
        s << "        <MainSound>\n"
          << "          <Id>urn:uuid:" << _uuid << "</Id>\n"
-         << "          <AnnotationText>" << _mxf_name << "</AnnotationText>\n"
+         << "          <AnnotationText>" << _file_name << "</AnnotationText>\n"
          << "          <EditRate>" << _fps << " 1</EditRate>\n"
          << "          <IntrinsicDuration>" << _length << "</IntrinsicDuration>\n"
          << "          <EntryPoint>0</EntryPoint>\n"
@@ -179,21 +194,21 @@ SoundAsset::write_to_cpl (ostream& s) const
 }
 
 list<string>
-SoundAsset::equals (shared_ptr<const Asset> other, EqualityFlags flags) const
+SoundAsset::equals (shared_ptr<const Asset> other, EqualityOptions opt) const
 {
-       list<string> notes = Asset::equals (other, flags);
+       list<string> notes = MXFAsset::equals (other, opt);
                     
-       if (flags & MXF_INSPECT) {
+       if (opt.flags & MXF_INSPECT) {
                ASDCP::PCM::MXFReader reader_A;
-               if (ASDCP_FAILURE (reader_A.OpenRead (mxf_path().c_str()))) {
-                       cout << "failed " << mxf_path() << "\n";
-                       throw FileError ("could not open MXF file for reading", mxf_path().string());
+               if (ASDCP_FAILURE (reader_A.OpenRead (path().string().c_str()))) {
+                       cout << "failed " << path() << "\n";
+                       throw FileError ("could not open MXF file for reading", path().string());
                }
 
                ASDCP::PCM::MXFReader reader_B;
-               if (ASDCP_FAILURE (reader_B.OpenRead (other->mxf_path().c_str()))) {
-                       cout << "failed " << other->mxf_path() << "\n";
-                       throw FileError ("could not open MXF file for reading", mxf_path().string());
+               if (ASDCP_FAILURE (reader_B.OpenRead (other->path().string().c_str()))) {
+                       cout << "failed " << other->path() << "\n";
+                       throw FileError ("could not open MXF file for reading", path().string());
                }
 
                ASDCP::PCM::AudioDescriptor desc_A;
@@ -234,7 +249,7 @@ SoundAsset::equals (shared_ptr<const Asset> other, EqualityFlags flags) const
                        }
 
                        if (buffer_A.Size() != buffer_B.Size()) {
-                               notes.push_back ("sizes of video data for frame " + lexical_cast<string>(i) + " differ");
+                               notes.push_back ("sizes of audio data for frame " + lexical_cast<string>(i) + " differ");
                                continue;
                        }
 
@@ -247,3 +262,9 @@ SoundAsset::equals (shared_ptr<const Asset> other, EqualityFlags flags) const
 
        return notes;
 }
+
+shared_ptr<const SoundFrame>
+SoundAsset::get_frame (int n) const
+{
+       return shared_ptr<const SoundFrame> (new SoundFrame (path().string(), n + _entry_point));
+}