X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Fsound_asset.cc;h=0cc7cdbae4e9ecfda4b15ffb09ab02ffc139cd91;hb=bf59c288798851808359575662f202d390032aa7;hp=6e29aadfe0f259b331617ff6806648ae4a071139;hpb=034abb6bb0f1d0382620bdcc43501ce0ba30b03a;p=libdcp.git diff --git a/src/sound_asset.cc b/src/sound_asset.cc index 6e29aadf..0cc7cdba 100644 --- a/src/sound_asset.cc +++ b/src/sound_asset.cc @@ -25,6 +25,7 @@ #include #include #include +#include #include "KM_fileio.h" #include "AS_DCP.h" #include "sound_asset.h" @@ -41,45 +42,27 @@ using boost::shared_ptr; using boost::lexical_cast; using namespace libdcp; -SoundAsset::SoundAsset ( - vector const & files, - string directory, - string mxf_name, - boost::signals2::signal* progress, - int fps, int intrinsic_duration - ) - : MXFAsset (directory, mxf_name, progress, fps, intrinsic_duration) - , _channels (files.size ()) +SoundAsset::SoundAsset (boost::filesystem::path directory, boost::filesystem::path mxf_name) + : MXFAsset (directory, mxf_name) + , _channels (0) , _sampling_rate (0) { - assert (_channels); - - construct (boost::bind (&SoundAsset::path_from_channel, this, _1, files)); + } -SoundAsset::SoundAsset ( - boost::function get_path, - string directory, - string mxf_name, - boost::signals2::signal* progress, - int fps, int intrinsic_duration, int channels - ) - : MXFAsset (directory, mxf_name, progress, fps, intrinsic_duration) - , _channels (channels) - , _sampling_rate (0) +void +SoundAsset::create (vector const & files) { - assert (_channels); - - construct (get_path); + create (boost::bind (&SoundAsset::path_from_channel, this, _1, files)); } -SoundAsset::SoundAsset (string directory, string mxf_name) - : MXFAsset (directory, mxf_name) - , _channels (0) +void +SoundAsset::read () { ASDCP::PCM::MXFReader reader; - if (ASDCP_FAILURE (reader.OpenRead (path().string().c_str()))) { - boost::throw_exception (MXFFileError ("could not open MXF file for reading", path().string())); + Kumu::Result_t r = reader.OpenRead (path().string().c_str()); + if (ASDCP_FAILURE (r)) { + boost::throw_exception (MXFFileError ("could not open MXF file for reading", path().string(), r)); } ASDCP::PCM::AudioDescriptor desc; @@ -94,16 +77,8 @@ SoundAsset::SoundAsset (string directory, string mxf_name) _intrinsic_duration = desc.ContainerDuration; } -SoundAsset::SoundAsset (string directory, string mxf_name, int fps, int channels, int sampling_rate) - : MXFAsset (directory, mxf_name, 0, fps, 0) - , _channels (channels) - , _sampling_rate (sampling_rate) -{ - -} - -string -SoundAsset::path_from_channel (Channel channel, vector const & files) +boost::filesystem::path +SoundAsset::path_from_channel (Channel channel, vector const & files) { unsigned int const c = int (channel); assert (c < files.size ()); @@ -111,17 +86,23 @@ SoundAsset::path_from_channel (Channel channel, vector const & files) } void -SoundAsset::construct (boost::function get_path) +SoundAsset::create (boost::function get_path) { ASDCP::Rational asdcp_edit_rate (_edit_rate, 1); - ASDCP::PCM::WAVParser pcm_parser_channel[_channels]; - if (pcm_parser_channel[0].OpenRead (get_path(LEFT).c_str(), asdcp_edit_rate)) { - boost::throw_exception (FileError ("could not open WAV file for reading", get_path(LEFT))); + assert (_channels > 0); + ASDCP::PCM::WAVParser* pcm_parser_channel[_channels]; + for (int i = 0; i < _channels; ++i) { + pcm_parser_channel[i] = new ASDCP::PCM::WAVParser (); + } + + Kumu::Result_t r = pcm_parser_channel[0]->OpenRead (get_path(LEFT).string().c_str(), asdcp_edit_rate); + if (ASDCP_FAILURE (r)) { + boost::throw_exception (FileError ("could not open WAV file for reading", get_path(LEFT), r)); } ASDCP::PCM::AudioDescriptor audio_desc; - pcm_parser_channel[0].FillAudioDescriptor (audio_desc); + pcm_parser_channel[0]->FillAudioDescriptor (audio_desc); audio_desc.ChannelCount = 0; audio_desc.BlockAlign = 0; audio_desc.EditRate = asdcp_edit_rate; @@ -141,22 +122,27 @@ SoundAsset::construct (boost::function get_path) assert (int(_channels) <= int(sizeof(channels) / sizeof(Channel))); - ASDCP::PCM::FrameBuffer frame_buffer_channel[_channels]; - ASDCP::PCM::AudioDescriptor audio_desc_channel[_channels]; + ASDCP::PCM::FrameBuffer* frame_buffer_channel[_channels]; + ASDCP::PCM::AudioDescriptor* audio_desc_channel[_channels]; + for (int i = 0; i < _channels; ++i) { + frame_buffer_channel[i] = new ASDCP::PCM::FrameBuffer (); + audio_desc_channel[i] = new ASDCP::PCM::AudioDescriptor (); + } for (int i = 0; i < _channels; ++i) { - string const path = get_path (channels[i]); + boost::filesystem::path const path = get_path (channels[i]); - if (ASDCP_FAILURE (pcm_parser_channel[i].OpenRead (path.c_str(), asdcp_edit_rate))) { - boost::throw_exception (FileError ("could not open WAV file for reading", path)); + Kumu::Result_t r = pcm_parser_channel[i]->OpenRead (path.string().c_str(), asdcp_edit_rate); + if (ASDCP_FAILURE (r)) { + boost::throw_exception (FileError ("could not open WAV file for reading", path, r)); } - pcm_parser_channel[i].FillAudioDescriptor (audio_desc_channel[i]); - frame_buffer_channel[i].Capacity (ASDCP::PCM::CalcFrameBufferSize (audio_desc_channel[i])); + pcm_parser_channel[i]->FillAudioDescriptor (*audio_desc_channel[i]); + frame_buffer_channel[i]->Capacity (ASDCP::PCM::CalcFrameBufferSize (*audio_desc_channel[i])); - audio_desc.ChannelCount += audio_desc_channel[i].ChannelCount; - audio_desc.BlockAlign += audio_desc_channel[i].BlockAlign; + audio_desc.ChannelCount += audio_desc_channel[i]->ChannelCount; + audio_desc.BlockAlign += audio_desc_channel[i]->BlockAlign; } ASDCP::PCM::FrameBuffer frame_buffer; @@ -164,37 +150,38 @@ SoundAsset::construct (boost::function get_path) frame_buffer.Size (ASDCP::PCM::CalcFrameBufferSize (audio_desc)); ASDCP::WriterInfo writer_info; - MXFAsset::fill_writer_info (&writer_info, _uuid); + MXFAsset::fill_writer_info (&writer_info, _uuid, _metadata); ASDCP::PCM::MXFWriter mxf_writer; - if (ASDCP_FAILURE (mxf_writer.OpenWrite (path().string().c_str(), writer_info, audio_desc))) { - boost::throw_exception (FileError ("could not open audio MXF for writing", path().string())); + r = mxf_writer.OpenWrite (path().string().c_str(), writer_info, audio_desc); + if (ASDCP_FAILURE (r)) { + boost::throw_exception (FileError ("could not open audio MXF for writing", path().string(), r)); } for (int i = 0; i < _intrinsic_duration; ++i) { for (int j = 0; j < _channels; ++j) { - memset (frame_buffer_channel[j].Data(), 0, frame_buffer_channel[j].Capacity()); - if (ASDCP_FAILURE (pcm_parser_channel[j].ReadFrame (frame_buffer_channel[j]))) { + memset (frame_buffer_channel[j]->Data(), 0, frame_buffer_channel[j]->Capacity()); + if (ASDCP_FAILURE (pcm_parser_channel[j]->ReadFrame (*frame_buffer_channel[j]))) { boost::throw_exception (MiscError ("could not read audio frame")); } } byte_t *data_s = frame_buffer.Data(); byte_t *data_e = data_s + frame_buffer.Capacity(); - byte_t sample_size = ASDCP::PCM::CalcSampleSize (audio_desc_channel[0]); + byte_t sample_size = ASDCP::PCM::CalcSampleSize (*audio_desc_channel[0]); int offset = 0; while (data_s < data_e) { for (int j = 0; j < _channels; ++j) { - byte_t* frame = frame_buffer_channel[j].Data() + offset; + byte_t* frame = frame_buffer_channel[j]->Data() + offset; memcpy (data_s, frame, sample_size); data_s += sample_size; } offset += sample_size; } - if (ASDCP_FAILURE (mxf_writer.WriteFrame (frame_buffer, 0, 0))) { + if (ASDCP_FAILURE (mxf_writer.WriteFrame (frame_buffer, _encryption_context, 0))) { boost::throw_exception (MiscError ("could not write audio MXF frame")); } @@ -203,22 +190,23 @@ SoundAsset::construct (boost::function get_path) } } - if (ASDCP_FAILURE (mxf_writer.Finalize())) { + bool const failed = ASDCP_FAILURE (mxf_writer.Finalize()); + + for (int i = 0; i < _channels; ++i) { + delete pcm_parser_channel[i]; + delete frame_buffer_channel[i]; + delete audio_desc_channel[i]; + } + + if (failed) { boost::throw_exception (MiscError ("could not finalise audio MXF")); } } -void -SoundAsset::write_to_cpl (ostream& s) const +string +SoundAsset::cpl_node_name () const { - s << " \n" - << " urn:uuid:" << _uuid << "\n" - << " " << _file_name << "\n" - << " " << _edit_rate << " 1\n" - << " " << _intrinsic_duration << "\n" - << " " << _entry_point << "\n" - << " " << _duration << "\n" - << " \n"; + return "MainSound"; } bool @@ -229,13 +217,15 @@ SoundAsset::equals (shared_ptr other, EqualityOptions opt, boost::f } ASDCP::PCM::MXFReader reader_A; - if (ASDCP_FAILURE (reader_A.OpenRead (path().string().c_str()))) { - boost::throw_exception (MXFFileError ("could not open MXF file for reading", path().string())); + Kumu::Result_t r = reader_A.OpenRead (path().string().c_str()); + if (ASDCP_FAILURE (r)) { + boost::throw_exception (MXFFileError ("could not open MXF file for reading", path().string(), r)); } ASDCP::PCM::MXFReader reader_B; - if (ASDCP_FAILURE (reader_B.OpenRead (other->path().string().c_str()))) { - boost::throw_exception (MXFFileError ("could not open MXF file for reading", path().string())); + r = reader_B.OpenRead (other->path().string().c_str()); + if (ASDCP_FAILURE (r)) { + boost::throw_exception (MXFFileError ("could not open MXF file for reading", path().string(), r)); } ASDCP::PCM::AudioDescriptor desc_A; @@ -299,7 +289,7 @@ shared_ptr SoundAsset::get_frame (int n) const { /* XXX: should add on entry point here? */ - return shared_ptr (new SoundFrame (path().string(), n)); + return shared_ptr (new SoundFrame (path().string(), n, _decryption_context)); } shared_ptr @@ -315,6 +305,7 @@ struct SoundAssetWriter::ASDCPState ASDCP::PCM::FrameBuffer frame_buffer; ASDCP::WriterInfo writer_info; ASDCP::PCM::AudioDescriptor audio_desc; + ASDCP::AESEncContext* encryption_context; }; SoundAssetWriter::SoundAssetWriter (SoundAsset* a) @@ -324,6 +315,8 @@ SoundAssetWriter::SoundAssetWriter (SoundAsset* a) , _frames_written (0) , _frame_buffer_offset (0) { + _state->encryption_context = a->encryption_context (); + /* Derived from ASDCP::Wav::SimpleWaveHeader::FillADesc */ _state->audio_desc.EditRate = ASDCP::Rational (_asset->edit_rate(), 1); _state->audio_desc.AudioSamplingRate = ASDCP::Rational (_asset->sampling_rate(), 1); @@ -339,10 +332,11 @@ SoundAssetWriter::SoundAssetWriter (SoundAsset* a) _state->frame_buffer.Size (ASDCP::PCM::CalcFrameBufferSize (_state->audio_desc)); memset (_state->frame_buffer.Data(), 0, _state->frame_buffer.Capacity()); - MXFAsset::fill_writer_info (&_state->writer_info, _asset->uuid ()); + _asset->fill_writer_info (&_state->writer_info, _asset->uuid (), _asset->metadata()); - if (ASDCP_FAILURE (_state->mxf_writer.OpenWrite (_asset->path().string().c_str(), _state->writer_info, _state->audio_desc))) { - boost::throw_exception (FileError ("could not open audio MXF for writing", _asset->path().string())); + Kumu::Result_t r = _state->mxf_writer.OpenWrite (_asset->path().string().c_str(), _state->writer_info, _state->audio_desc); + if (ASDCP_FAILURE (r)) { + boost::throw_exception (FileError ("could not open audio MXF for writing", _asset->path().string(), r)); } } @@ -376,8 +370,9 @@ SoundAssetWriter::write (float const * const * data, int frames) void SoundAssetWriter::write_current_frame () { - if (ASDCP_FAILURE (_state->mxf_writer.WriteFrame (_state->frame_buffer, 0, 0))) { - boost::throw_exception (MiscError ("could not write audio MXF frame")); + ASDCP::Result_t const r = _state->mxf_writer.WriteFrame (_state->frame_buffer, _state->encryption_context, 0); + if (ASDCP_FAILURE (r)) { + boost::throw_exception (MiscError ("could not write audio MXF frame (" + lexical_cast (int (r)) + ")")); } ++_frames_written; @@ -399,7 +394,8 @@ SoundAssetWriter::finalize () _asset->set_duration (_frames_written); } -SoundAssetWriter::~SoundAssetWriter () +string +SoundAsset::key_type () const { - assert (_finalized); + return "MDAK"; }