X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=examples%2Fmake_dcp.cc;h=fb17059a3dbfcc822615b498613164551adab36e;hb=4ee35138973188536d8b9dec2b06ff1e737b67c4;hp=6da9cf20f8499174f0eb8c5af499822ba503c419;hpb=5384418af0299194ecf3e27fd2e443e7d882a713;p=libdcp.git diff --git a/examples/make_dcp.cc b/examples/make_dcp.cc index 6da9cf20..fb17059a 100644 --- a/examples/make_dcp.cc +++ b/examples/make_dcp.cc @@ -1,115 +1,117 @@ /* - Copyright (C) 2012 Carl Hetherington + Copyright (C) 2012-2021 Carl Hetherington - This program is free software; you can redistribute it and/or modify + This file is part of libdcp. + + libdcp is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - This program is distributed in the hope that it will be useful, + libdcp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - + along with libdcp. If not, see . */ /** @file examples/make_dcp.cc - * @brief Shows how to make a DCP from some JPEG2000 and WAV files. + * @brief Shows how to make a DCP from some JPEG2000 and audio data. */ #include #include /* If you are using an installed libdcp, these #includes would need to be changed to -#include -#include -#include +#include +#include +#include ... etc. ... */ #include "dcp.h" #include "cpl.h" -#include "picture_asset.h" +#include "mono_picture_asset.h" +#include "mono_picture_asset_writer.h" #include "sound_asset.h" +#include "sound_asset_writer.h" #include "reel.h" - -/* This method returns the filename of the JPEG2000 file to use for a given frame. - In this example, we are using the same file for each frame, so we don't bother - looking at the frame parameter, but it will called with frame=0, frame=1, ... -*/ -std::string -video_frame (int /* frame */) -{ - return "examples/help.j2c"; -} +#include "reel_mono_picture_asset.h" +#include "reel_sound_asset.h" +#include int main () { - /* Make a DCP object. "My Film DCP" is the directory name for the DCP */ - libdcp::DCP dcp ("My Film DCP"); - - /* Now make a CPL object. + /* Set up libdcp */ + dcp::init(); - "My Film" is the title that will be shown on the projector / TMS when the DCP is ingested. - FEATURE is the type that the projector will list the DCP as. - 24 is the frame rate, and the DCP will be 48 frames long (ie 2 seconds at 24 fps). - */ - boost::shared_ptr cpl (new libdcp::CPL ("My Film DCP", "My Film", libdcp::FEATURE, 24, 48)); + /* Create a directory to put the DCP in */ + boost::filesystem::create_directory("DCP"); - /* And add the CPL to the DCP */ - dcp.add_cpl (cpl); + /* 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. + */ - /* Now make a `picture asset'. This is a collection of the JPEG2000 files that make up the picture, one per frame. - Here we're using a function (video_frame) to obtain the name of the JPEG2000 file for each frame. + auto picture_asset = std::make_shared(dcp::Fraction(24, 1), dcp::Standard::SMPTE); - The result will be an MXF file written to the directory "My Film DCP" (which should be the same as the DCP's - directory above) called "video.mxf". + /* Start off a write to it */ + auto picture_writer = picture_asset->start_write("DCP/picture.mxf", false); - The other parameters specify the entry_point (the frame at which the projector should start showing the picture), - the frame rate, the number of frames and the resolution of the frames; 1998x1080 is the DCI Flat specification - for 2K projectors. - */ - boost::shared_ptr picture_asset ( - new libdcp::MonoPictureAsset (video_frame, "My Film DCP", "video.mxf", 0, 24, 48, false, libdcp::Size (1998, 1080), false) - ); - - /* Now we will create a `sound asset', which is made up of a WAV file for each channel of audio. Here we're using - stereo, so we add two WAV files to a vector. - - We could add more files here to use more channels; the file order is: - Left - Right - Centre - LFE (sub) - Left surround - Right surround + /* Write 24 frames of the same JPEG2000 file */ + dcp::ArrayData picture("examples/help.j2c"); + for (int i = 0; i < 24; ++i) { + picture_writer->write (picture); + } + + /* And finish off */ + picture_writer->finalize(); + + /* Now create a sound MXF. As before, create an object and a writer. + When creating the object we specify the sampling rate (48kHz) and the number of channels (2). */ - std::vector sound_files; - sound_files.push_back ("examples/sine_440_-12dB.wav"); - sound_files.push_back ("examples/sine_880_-12dB.wav"); - - /* Now we can create the sound asset using these files */ - boost::shared_ptr sound_asset ( - new libdcp::SoundAsset (sound_files, "My Film DCP", "audio.mxf", 0, 24, 48, false, false) - ); - - /* Now that we have the assets, we can create a Reel to put them in and add it to the CPL */ - cpl->add_reel ( - boost::shared_ptr ( - new libdcp::Reel (picture_asset, sound_asset, boost::shared_ptr ()) - ) - ); - - /* Finally, we call this to write the XML description files to the DCP. After this, the DCP - is ready to ingest and play. + auto sound_asset = std::make_shared(dcp::Fraction(24, 1), 48000, 2, dcp::LanguageTag("en-GB"), dcp::Standard::SMPTE); + /* Here we must also say which of our channels will have "real" sound data in them */ + std::vector active_channels; + active_channels.push_back(dcp::Channel::LEFT); + active_channels.push_back(dcp::Channel::RIGHT); + auto sound_writer = sound_asset->start_write("DCP/sound.mxf", active_channels); + + /* Write some sine waves */ + float* audio[2]; + audio[0] = new float[48000]; + audio[1] = new float[48000]; + for (int i = 0; i < 48000; ++i) { + audio[0][i] = sin (2 * M_PI * i * 440 / 48000) * 0.25; + audio[1][i] = sin (2 * M_PI * i * 880 / 48000) * 0.25; + } + sound_writer->write (audio, 48000); + + /* And tidy up */ + delete[] audio[0]; + delete[] audio[1]; + sound_writer->finalize (); + + /* Now create a reel */ + auto reel = std::make_shared(); + + /* Add picture and sound to it. The zeros are the `entry points', i.e. the first + (video) frame from the assets that the reel should play. */ - libdcp::XMLMetadata metadata; - dcp.write_xml (false, metadata); + reel->add(std::make_shared(picture_asset, 0)); + reel->add(std::make_shared(sound_asset, 0)); + + /* Make a CPL with this reel */ + auto cpl = std::make_shared("My film", dcp::ContentKind::FEATURE); + cpl->add(reel); + + /* Write the DCP */ + dcp::DCP dcp ("DCP"); + dcp.add (cpl); + dcp.write_xml (dcp::Standard::SMPTE); return 0; }