- Altered many printf format codes to use the correct type for the given integer type
- Parenthesized some expressions to clarify previously ambiguous expectations of precedence
- Created macro KM_MACOSX for use in OS-specific code selection
- Removed last uses of the old C-language abs(), now using Kumu::xabs()
- Removed last uses of the old C-language atoi()
o Added platform-independent call Kumu::GetExecutablePath() (test with win32)
o Fixed a bug that was causing Array properties to be written without the (count, length) header (from PAL)
o Fixed Win32 build (from Crowe)
o Added imlementation of SMPTE ST 2092-1 pink noise generator
o Added pinkwave CLI utility
o Added font support to the IMF timed-text wrapper
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
/*! \file AS_02_PCM.cpp
\version $Id$
\brief AS-02 library, PCM essence reader and writer implementation
if ( DescObject->MIMEMediaType.find("application/x-font-opentype") != std::string::npos
|| DescObject->MIMEMediaType.find("application/x-opentype") != std::string::npos
|| DescObject->MIMEMediaType.find("font/opentype") != std::string::npos )
- TmpResource.Type = ASDCP::TimedText::MT_OPENTYPE;
-
+ {
+ TmpResource.Type = ASDCP::TimedText::MT_OPENTYPE;
+ }
else if ( DescObject->MIMEMediaType.find("image/png") != std::string::npos )
- TmpResource.Type = ASDCP::TimedText::MT_PNG;
-
+ {
+ TmpResource.Type = ASDCP::TimedText::MT_PNG;
+ }
else
- TmpResource.Type = ASDCP::TimedText::MT_BIN;
+ {
+ TmpResource.Type = ASDCP::TimedText::MT_BIN;
+ }
TDesc.ResourceList.push_back(TmpResource);
m_ResourceMap.insert(ResourceMap_t::value_type(DescObject->AncillaryResourceID, *sdi));
);
}
- fprintf(stream, " Scod: %hd\n", PDesc.CodingStyleDefault.Scod);
- fprintf(stream, " ProgressionOrder: %hd\n", PDesc.CodingStyleDefault.SGcod.ProgressionOrder);
+ fprintf(stream, " Scod: %hhu\n", PDesc.CodingStyleDefault.Scod);
+ fprintf(stream, " ProgressionOrder: %hhu\n", PDesc.CodingStyleDefault.SGcod.ProgressionOrder);
fprintf(stream, " NumberOfLayers: %hd\n",
KM_i16_BE(Kumu::cp2i<ui16_t>(PDesc.CodingStyleDefault.SGcod.NumberOfLayers)));
- fprintf(stream, " MultiCompTransform: %hd\n", PDesc.CodingStyleDefault.SGcod.MultiCompTransform);
- fprintf(stream, "DecompositionLevels: %hd\n", PDesc.CodingStyleDefault.SPcod.DecompositionLevels);
- fprintf(stream, " CodeblockWidth: %hd\n", PDesc.CodingStyleDefault.SPcod.CodeblockWidth);
- fprintf(stream, " CodeblockHeight: %hd\n", PDesc.CodingStyleDefault.SPcod.CodeblockHeight);
- fprintf(stream, " CodeblockStyle: %hd\n", PDesc.CodingStyleDefault.SPcod.CodeblockStyle);
- fprintf(stream, " Transformation: %hd\n", PDesc.CodingStyleDefault.SPcod.Transformation);
+ fprintf(stream, " MultiCompTransform: %hhu\n", PDesc.CodingStyleDefault.SGcod.MultiCompTransform);
+ fprintf(stream, "DecompositionLevels: %hhu\n", PDesc.CodingStyleDefault.SPcod.DecompositionLevels);
+ fprintf(stream, " CodeblockWidth: %hhu\n", PDesc.CodingStyleDefault.SPcod.CodeblockWidth);
+ fprintf(stream, " CodeblockHeight: %hhu\n", PDesc.CodingStyleDefault.SPcod.CodeblockHeight);
+ fprintf(stream, " CodeblockStyle: %hhu\n", PDesc.CodingStyleDefault.SPcod.CodeblockStyle);
+ fprintf(stream, " Transformation: %hhu\n", PDesc.CodingStyleDefault.SPcod.Transformation);
ui32_t precinct_set_size = 0;
for ( i = 0; PDesc.CodingStyleDefault.SPcod.PrecinctSize[i] != 0 && i < MaxPrecincts; ++i )
precinct_set_size++;
- fprintf(stream, " Precincts: %hd\n", precinct_set_size);
+ fprintf(stream, " Precincts: %u\n", precinct_set_size);
fprintf(stream, "precinct dimensions:\n");
for ( i = 0; i < precinct_set_size && i < MaxPrecincts; i++ )
s_exp_lookup[(PDesc.CodingStyleDefault.SPcod.PrecinctSize[i]>>4)&0x0f]
);
- fprintf(stream, " Sqcd: %hd\n", PDesc.QuantizationDefault.Sqcd);
+ fprintf(stream, " Sqcd: %hhu\n", PDesc.QuantizationDefault.Sqcd);
char tmp_buf[MaxDefaults*2];
fprintf(stream, " SPqcd: %s\n",
DefaultLogSink().Warn("EditRate and SampleRate do not match (%.03f, %.03f).\n",
m_EditRate.Quotient(), m_SampleRate.Quotient());
- if ( m_EditRate == EditRate_24 && m_SampleRate == EditRate_48 ||
- m_EditRate == EditRate_25 && m_SampleRate == EditRate_50 ||
- m_EditRate == EditRate_30 && m_SampleRate == EditRate_60 ||
- m_EditRate == EditRate_48 && m_SampleRate == EditRate_96 ||
- m_EditRate == EditRate_50 && m_SampleRate == EditRate_100 ||
- m_EditRate == EditRate_60 && m_SampleRate == EditRate_120 )
+ if ( ( m_EditRate == EditRate_24 && m_SampleRate == EditRate_48 )
+ || ( m_EditRate == EditRate_25 && m_SampleRate == EditRate_50 )
+ || ( m_EditRate == EditRate_30 && m_SampleRate == EditRate_60 )
+ || ( m_EditRate == EditRate_48 && m_SampleRate == EditRate_96 )
+ || ( m_EditRate == EditRate_50 && m_SampleRate == EditRate_100 )
+ || ( m_EditRate == EditRate_60 && m_SampleRate == EditRate_120 ) )
{
DefaultLogSink().Debug("File may contain JPEG Interop stereoscopic images.\n");
return RESULT_SFORMAT;
if ( stream == 0 )
stream = stderr;
- fprintf(stream, "Frame: %06u, %c%-2hu, %7u bytes",
+ fprintf(stream, "Frame: %06u, %c%-2hhu, %7u bytes",
m_FrameNumber, FrameTypeChar(m_FrameType), m_TemporalOffset, m_Size);
if ( m_GOPStart )
fprintf(stream, " EditUnitByteCount = %u\n", EditUnitByteCount);
fprintf(stream, " IndexSID = %u\n", IndexSID);
fprintf(stream, " BodySID = %u\n", BodySID);
- fprintf(stream, " SliceCount = %hu\n", SliceCount);
- fprintf(stream, " PosTableCount = %hu\n", PosTableCount);
+ fprintf(stream, " SliceCount = %hhu\n", SliceCount);
+ fprintf(stream, " PosTableCount = %hhu\n", PosTableCount);
fprintf(stream, " DeltaEntryArray:\n"); DeltaEntryArray.Dump(stream);
const char*
ASDCP::MXF::IndexTableSegment::DeltaEntry::EncodeString(char* str_buf, ui32_t buf_len) const
{
- snprintf(str_buf, buf_len, "%3d %-3hu %-3u", PosTableIndex, Slice, ElementData);
+ snprintf(str_buf, buf_len, "%3d %-3hhu %-3u", PosTableIndex, Slice, ElementData);
return str_buf;
}
txt_flags[4] = ( (Flags & 0x0f) == 3 ) ? 'B' : ( (Flags & 0x0f) == 2 ) ? 'P' : 'I';
txt_flags[5] = 0;
- snprintf(str_buf, buf_len, "%3i %-3hu %s %s",
+ snprintf(str_buf, buf_len, "%3i %-3hhu %s %s",
TemporalOffset, KeyFrameOffset, txt_flags,
i64sz(StreamOffset, intbuf));
fprintf(stream, " ProgOrder: %s\n", prog_order_str);
fprintf(stream, " Layers: %hu\n", Layers());
- fprintf(stream, " DecompLevels: %hu\n", DecompLevels());
+ fprintf(stream, " DecompLevels: %hhu\n", DecompLevels());
fprintf(stream, " CodeBlockWidth: %d\n", 1 << CodeBlockWidth());
fprintf(stream, "CodeBlockHeight: %d\n", 1 << CodeBlockHeight());
fprintf(stream, " CodeBlockStyle: %d\n", CodeBlockStyle());
fprintf(stream, "QCD: \n");
fprintf(stream, "QuantizationType: %s\n", GetQuantizationTypeString(QuantizationType()));
fprintf(stream, " GuardBits: %d\n", GuardBits());
- fprintf(stream, " SPqcd:\n", GuardBits());
+ fprintf(stream, " SPqcd: %d\n", GuardBits());
Kumu::hexdump(m_MarkerData, m_DataSize, stream);
}
{
public:
virtual ~PathMatchAny() {}
- inline bool Match(const std::string& s) const { return true; }
+ inline bool Match(const std::string&) const { return true; }
};
#ifndef KM_WIN32
PathList_t& FindInPaths(const IPathMatch& Pattern, const PathList_t& SearchPaths,
PathList_t& FoundPaths, bool one_shot = false, char separator = '/');
+ std::string GetExecutablePath(const std::string& default_path);
+
//------------------------------------------------------------------------------------------
// Directory Manipulation
//------------------------------------------------------------------------------------------
/*
-Copyright (c) 2004-2012, John Hurst
+Copyright (c) 2004-2015, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
#ifndef _KM_PLATFORM_H_
# define _KM_PLATFORM_H_
-# ifdef __APPLE__
+#if defined(__APPLE__) && defined(__MACH__)
+# define KM_MACOSX
# ifdef __BIG_ENDIAN__
# define KM_BIG_ENDIAN
# endif
//
template<class T>
inline T xclamp(T v, T l, T h) {
- if ( v < l ) return l;
- if ( v > h ) return h;
+ if ( v < l ) { return l; }
+ if ( v > h ) { return h; }
return v;
}
+ //
+ template<class T>
+ inline T xabs(T n) {
+ if ( n < 0 ) { return -n; }
+ return n;
+ }
// read an integer from byte-structured storage
template<class T>
template<class T>
inline void i2p(T i, byte_t* p) { *(T*)p = i; }
+
# ifdef KM_BIG_ENDIAN
# define KM_i16_LE(i) Kumu::Swap2(i)
# define KM_i32_LE(i) Kumu::Swap4(i)
tmp_t.AddMinutes(m_TZOffsetMinutes);
tmp_t.GetComponents(year, month, day, hour, minute, second);
- ofst_hours = abs(m_TZOffsetMinutes) / 60;
- ofst_minutes = abs(m_TZOffsetMinutes) % 60;
+ ofst_hours = Kumu::xabs(m_TZOffsetMinutes) / 60;
+ ofst_minutes = Kumu::xabs(m_TZOffsetMinutes) % 60;
if ( m_TZOffsetMinutes < 0 )
direction = '-';
// 2004-05-01T13:20:00+00:00
snprintf(str_buf, buf_len,
- "%04hu-%02hu-%02huT%02hu:%02hu:%02hu%c%02hu:%02hu",
+ "%04hu-%02hhu-%02hhuT%02hhu:%02hhu:%02hhu%c%02u:%02u",
year, month, day, hour, minute, second,
direction, ofst_hours, ofst_minutes);
r = strstr(pstr, separator.c_str());
}
- if ( strlen(pstr) >= 0 )
- {
- components.push_back(std::string(pstr));
- }
-
+ components.push_back(std::string(pstr));
return components;
}
};
inline void hexdump(const ByteString& buf, FILE* stream = 0) {
- hexdump(buf.RoData(), buf.Length());
+ hexdump(buf.RoData(), buf.Length(), stream);
}
// Locates the first occurrence of the null-terminated string s2 in the string s1, where not more
XERCES_CPP_NAMESPACE_USE
-namespace Kumu {
- void init_xml_dom();
- typedef std::basic_string<XMLCh> XercesString;
- bool UTF_8_to_XercesString(const std::string& in_str, XercesString& out_str);
- bool UTF_8_to_XercesString(const char* in_str, XercesString& out_str);
- bool XercesString_to_UTF_8(const XercesString& in_str, std::string& out_str);
- bool XercesString_to_UTF_8(const XMLCh* in_str, std::string& out_str);
+extern "C"
+{
+ void kumu_init_xml_dom();
+ bool kumu_UTF_8_to_XercesString(const std::string& in_str, std::basic_string<XMLCh>& out_str);
+ bool kumu_UTF_8_to_XercesString_p(const char* in_str, std::basic_string<XMLCh>& out_str);
+ bool kumu_XercesString_to_UTF_8(const std::basic_string<XMLCh>& in_str, std::string& out_str);
+ bool kumu_XercesString_to_UTF_8_p(const XMLCh* in_str, std::string& out_str);
}
#endif
//
void
-Kumu::init_xml_dom()
+kumu_init_xml_dom()
{
if ( ! sg_xml_init )
{
//
bool
-Kumu::XercesString_to_UTF_8(const Kumu::XercesString& in_str, std::string& out_str) {
- return XercesString_to_UTF_8(in_str.c_str(), out_str);
+kumu_XercesString_to_UTF_8(const std::basic_string<XMLCh>& in_str, std::string& out_str) {
+ return kumu_XercesString_to_UTF_8_p(in_str.c_str(), out_str);
}
//
bool
-Kumu::XercesString_to_UTF_8(const XMLCh* in_str, std::string& out_str)
+kumu_XercesString_to_UTF_8_p(const XMLCh* in_str, std::string& out_str)
{
assert(in_str);
assert(sg_xml_init);
//
bool
-Kumu::UTF_8_to_XercesString(const std::string& in_str, Kumu::XercesString& out_str) {
- return UTF_8_to_XercesString(in_str.c_str(), out_str);
+kumu_UTF_8_to_XercesString(const std::string& in_str, std::basic_string<XMLCh>& out_str) {
+ return kumu_UTF_8_to_XercesString_p(in_str.c_str(), out_str);
}
//
bool
-Kumu::UTF_8_to_XercesString(const char* in_str, Kumu::XercesString& out_str)
+kumu_UTF_8_to_XercesString_p(const char* in_str, std::basic_string<XMLCh>& out_str)
{
assert(in_str);
assert(sg_xml_init);
assert(x_name);
std::string tx_name;
- if ( ! XercesString_to_UTF_8(x_name, tx_name) )
+ if ( ! kumu_XercesString_to_UTF_8(x_name, tx_name) )
m_HasEncodeErrors = true;
const char* name = tx_name.c_str();
for ( ui32_t i = 0; i < a_len; i++)
{
std::string aname, value;
- if ( ! XercesString_to_UTF_8(attributes.getName(i), aname) )
+ if ( ! kumu_XercesString_to_UTF_8(attributes.getName(i), aname) )
m_HasEncodeErrors = true;
- if ( ! XercesString_to_UTF_8(attributes.getValue(i), value) )
+ if ( ! kumu_XercesString_to_UTF_8(attributes.getValue(i), value) )
m_HasEncodeErrors = true;
const char* x_aname = aname.c_str();
if ( length > 0 )
{
std::string tmp;
- if ( ! XercesString_to_UTF_8(chars, tmp) )
+ if ( ! kumu_XercesString_to_UTF_8(chars, tmp) )
m_HasEncodeErrors = true;
m_Scope.top()->AppendBody(tmp);
return false;
}
- init_xml_dom();
+ kumu_init_xml_dom();
int errorCount = 0;
SAXParser* parser = new SAXParser();
return false;
}
- init_xml_dom();
-
+ kumu_init_xml_dom();
+
int errorCount = 0;
SAXParser* parser = new SAXParser();
/*
-Copyright (c) 2005-2014, John Hurst
+Copyright (c) 2005-2015, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
};
const Dictionary*& m_Dict;
- Array<Pair> PairArray;
+ HeadlessArray<Pair> PairArray;
RIP(const Dictionary*& d) : m_Dict(d) {}
virtual ~RIP() {}
Batch() {}
virtual ~Batch() {}
+ inline virtual bool HasValue() const { return ! this->empty(); }
+
+ virtual ui32_t ArchiveLength() const {
+ ui32_t arch_size = sizeof(ui32_t) * 2;
+ typename std::vector<T>::const_iterator i;
+
+ for ( i = this->begin(); i != this->end(); ++i )
+ {
+ arch_size += i->ArchiveLength();
+ }
+
+ return arch_size;
+ }
+
+ //
+ virtual bool Archive(Kumu::MemIOWriter* Writer) const {
+ if ( ! Writer->WriteUi32BE(this->size()) ) return false;
+ byte_t* p = Writer->CurrentData();
+
+ if ( ! Writer->WriteUi32BE(0) ) return false;
+ if ( this->empty() ) return true;
+
+ typename std::vector<T>::const_iterator i = this->begin();
+ assert(i != this->end());
+
+ ui32_t ItemSize = Writer->Remainder();
+ if ( ! i->Archive(Writer) ) return false;
+ ItemSize -= Writer->Remainder();
+ Kumu::i2p<ui32_t>(KM_i32_BE(ItemSize), p);
+ ++i;
+
+ bool result = true;
+ for ( ; i != this->end() && result; ++i )
+ {
+ result = i->Archive(Writer);
+ }
+
+ return result;
+ }
+
//
virtual bool Unarchive(Kumu::MemIOReader* Reader) {
- ui32_t ItemCount, ItemSize;
- if ( ! Reader->ReadUi32BE(&ItemCount) ) return false;
- if ( ! Reader->ReadUi32BE(&ItemSize) ) return false;
+ ui32_t item_count, item_size;
+ if ( ! Reader->ReadUi32BE(&item_count) ) return false;
+ if ( ! Reader->ReadUi32BE(&item_size) ) return false;
- if ( ( ItemCount > 65536 ) || ( ItemSize > 1024 ) )
- return false;
+ if ( ( item_count > 65536 ) || ( item_size > 1024 ) )
+ {
+ return false;
+ }
bool result = true;
- for ( ui32_t i = 0; i < ItemCount && result; i++ )
+ for ( ui32_t i = 0; i < item_count && result; ++i )
{
T Tmp;
result = Tmp.Unarchive(Reader);
if ( result )
- this->push_back(Tmp);
+ {
+ this->push_back(Tmp);
+ }
}
return result;
}
+ //
+ void Dump(FILE* stream = 0, ui32_t depth = 0)
+ {
+ char identbuf[IdentBufferLen];
+
+ if ( stream == 0 )
+ stream = stderr;
+
+ typename std::vector<T>::iterator i = this->begin();
+ for ( ; i != this->end(); i++ )
+ fprintf(stream, " %s\n", (*i).EncodeString(identbuf, IdentBufferLen));
+ }
+ };
+
+ //
+ template <class T>
+ class Array : public std::list<T>, public Kumu::IArchive
+ {
+ public:
+ Array() {}
+ virtual ~Array() {}
+
inline virtual bool HasValue() const { return ! this->empty(); }
virtual ui32_t ArchiveLength() const {
- ui32_t arch_size = sizeof(ui32_t)*2;
+ ui32_t arch_size = sizeof(ui32_t) * 2;
+ typename std::list<T>::const_iterator i;
- typename std::vector<T>::const_iterator l_i = this->begin();
- assert(l_i != this->end());
+ for ( i = this->begin(); i != this->end(); ++i )
+ {
+ arch_size += i->ArchiveLength();
+ }
- for ( ; l_i != this->end(); l_i++ )
- arch_size += l_i->ArchiveLength();
-
return arch_size;
}
if ( ! Writer->WriteUi32BE(0) ) return false;
if ( this->empty() ) return true;
- typename std::vector<T>::const_iterator l_i = this->begin();
- assert(l_i != this->end());
+ typename std::list<T>::const_iterator i = this->begin();
+ assert(i != this->end());
ui32_t ItemSize = Writer->Remainder();
- if ( ! (*l_i).Archive(Writer) ) return false;
+ if ( ! i->Archive(Writer) ) return false;
ItemSize -= Writer->Remainder();
Kumu::i2p<ui32_t>(KM_i32_BE(ItemSize), p);
- l_i++;
+ ++i;
bool result = true;
- for ( ; l_i != this->end() && result; l_i++ )
- result = (*l_i).Archive(Writer);
+ for ( ; i != this->end() && result; ++i )
+ {
+ result = i->Archive(Writer);
+ }
+
+ return result;
+ }
+
+ //
+ virtual bool Unarchive(Kumu::MemIOReader* Reader) {
+ ui32_t item_count, item_size;
+ if ( ! Reader->ReadUi32BE(&item_count) ) return false;
+ if ( ! Reader->ReadUi32BE(&item_size) ) return false;
+
+ if ( ( item_count > 65536 ) || ( item_size > 1024 ) )
+ {
+ return false;
+ }
+
+ bool result = true;
+ for ( ui32_t i = 0; i < item_count && result; ++i )
+ {
+ T Tmp;
+ result = Tmp.Unarchive(Reader);
+
+ if ( result )
+ {
+ this->push_back(Tmp);
+ }
+ }
return result;
}
+
//
void Dump(FILE* stream = 0, ui32_t depth = 0)
if ( stream == 0 )
stream = stderr;
- typename std::vector<T>::iterator i = this->begin();
+ typename std::list<T>::iterator i = this->begin();
for ( ; i != this->end(); i++ )
fprintf(stream, " %s\n", (*i).EncodeString(identbuf, IdentBufferLen));
}
//
template <class T>
- class Array : public std::list<T>, public Kumu::IArchive
+ class HeadlessArray : public std::list<T>, public Kumu::IArchive
{
public:
- Array() {}
- virtual ~Array() {}
+ HeadlessArray() {}
+ virtual ~HeadlessArray() {}
//
virtual bool Unarchive(Kumu::MemIOReader* Reader)
if DEV_HEADERS
include_HEADERS += \
S12MTimecode.h \
+ ST2095_PinkNoise.h \
MDD.h \
Metadata.h \
KLV.h \
AtmosSyncChannel_Mixer.cpp AtmosSyncChannel_Mixer.h \
PCMDataProviders.cpp PCMDataProviders.h \
SyncEncoder.c SyncEncoder.h SyncCommon.h CRC16.c CRC16.h \
- UUIDInformation.c UUIDInformation.h
+ UUIDInformation.c UUIDInformation.h \
+ ST2095_PinkNoise.cpp
libasdcp_la_LDFLAGS = -release @VERSION@
# list of programs to be built and installed
bin_PROGRAMS = \
- asdcp-wrap asdcp-unwrap asdcp-util asdcp-info asdcp-test \
- j2c-test blackwave klvwalk wavesplit klvsplit \
- kmfilegen kmrandgen kmuuidgen
+ asdcp-wrap \
+ asdcp-unwrap \
+ asdcp-util \
+ asdcp-info \
+ asdcp-test \
+ j2c-test \
+ blackwave \
+ pinkwave \
+ klvwalk \
+ wavesplit \
+ klvsplit \
+ kmfilegen \
+ kmrandgen \
+ kmuuidgen
if USE_AS_02
bin_PROGRAMS += \
blackwave_SOURCES = blackwave.cpp
blackwave_LDADD = libasdcp.la libkumu.la
+pinkwave_SOURCES = pinkwave.cpp
+pinkwave_LDADD = libasdcp.la libkumu.la
+
klvwalk_SOURCES = klvwalk.cpp
klvwalk_LDADD = libasdcp.la libkumu.la
//------------------------------------------------------------------------------------------
//
+int const NS_ID_LENGTH = 16;
+
//
-static byte_t s_id_prefix[16] = {
+static byte_t s_png_id_prefix[NS_ID_LENGTH] = {
// RFC 4122 type 5
- // 2067-2 5.4.5
+ // 2067-2 5.4.5 / RFC4122 Appendix C
0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1,
0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8
};
//
-void
-gen_png_name_id(const std::string& image_name, UUID& asset_id)
+static byte_t s_font_id_prefix[NS_ID_LENGTH] = {
+ // RFC 4122 type 5
+ // 2067-2 5.4.6
+ 0xb6, 0xcc, 0x57, 0xa0, 0x87, 0xe7, 0x4e, 0x75,
+ 0xb1, 0xc3, 0x33, 0x59, 0xf3, 0xae, 0x88, 0x17
+};
+
+//
+static Kumu::UUID
+create_4122_type5_id(const std::string& subject_name, const byte_t* ns_id)
{
SHA_CTX ctx;
SHA1_Init(&ctx);
- SHA1_Update(&ctx, s_id_prefix, 16);
- SHA1_Update(&ctx, (byte_t*)image_name.c_str(), image_name.length());
+ SHA1_Update(&ctx, ns_id, NS_ID_LENGTH);
+ SHA1_Update(&ctx, (byte_t*)subject_name.c_str(), subject_name.size());
const ui32_t sha_len = 20;
byte_t bin_buf[sha_len];
buf[6] |= 0x50; // set UUID version 'digest'
buf[8] &= 0x3f; // clear bits 6&7
buf[8] |= 0x80; // set bit 7
- asset_id.Set(buf);
+ return Kumu::UUID(buf);
+}
+
+//
+static Kumu::UUID
+create_png_name_id(const std::string& image_name)
+{
+ return create_4122_type5_id(image_name, s_png_id_prefix);
+}
+
+//
+static Kumu::UUID
+create_font_name_id(const std::string& font_name)
+{
+ return create_4122_type5_id(font_name, s_font_id_prefix);
}
//------------------------------------------------------------------------------------------
abs_dirname = ".";
}
- if ( KM_SUCCESS(dir_reader.Open(abs_dirname.c_str())) )
+ Result_t result = dir_reader.Open(abs_dirname);
+
+ if ( KM_SUCCESS(result) )
{
while ( KM_SUCCESS(dir_reader.GetNext(next_item, ft)) )
{
if ( ft == DET_FILE )
{
FileReader reader;
- Result_t result = reader.OpenRead(tmp_path);
+ Result_t read_result = reader.OpenRead(tmp_path);
- if ( KM_SUCCESS(result) )
+ if ( KM_SUCCESS(read_result) )
{
- result = reader.Read(read_buffer, 16);
+ read_result = reader.Read(read_buffer, 16);
}
- if ( KM_SUCCESS(result) )
+ if ( KM_SUCCESS(read_result) )
{
// is it PNG?
if ( memcmp(read_buffer, PNGMagic, sizeof(PNGMagic)) == 0 )
{
- UUID asset_id;
- gen_png_name_id(next_item, asset_id);
+ UUID asset_id = create_png_name_id(next_item);
+ m_ResourceMap.insert(ResourceMap::value_type(asset_id, next_item));
+ }
+ // is it a font?
+ else if ( memcmp(read_buffer, OpenTypeMagic, sizeof(OpenTypeMagic)) == 0
+ || memcmp(read_buffer, TrueTypeMagic, sizeof(TrueTypeMagic)) == 0 )
+ {
+ fprintf(stderr, "wrap font!\n");
+ UUID asset_id = create_font_name_id(next_item);
m_ResourceMap.insert(ResourceMap::value_type(asset_id, next_item));
}
}
}
}
}
+
+ return result;
}
//
if ( i == m_ResourceMap.end() )
{
+ DefaultLogSink().Debug("Missing timed-text resource \"%s\"\n", tmp_id.EncodeHex(buf, 64));
return RESULT_NOT_FOUND;
}
for ( i = png_visitor.value_list.begin(); i != png_visitor.value_list.end(); ++i )
{
- UUID asset_id;
- gen_png_name_id(*i, asset_id);
- TimedTextResourceDescriptor TmpResource;
- memcpy(TmpResource.ResourceID, asset_id.Value(), UUIDlen);
- TmpResource.Type = ASDCP::TimedText::MT_PNG;
- m_TDesc.ResourceList.push_back(TmpResource);
- m_ResourceTypes.insert(ResourceTypeMap_t::value_type(UUID(TmpResource.ResourceID), ASDCP::TimedText::MT_PNG));
+ UUID asset_id = create_png_name_id(*i);
+ TimedTextResourceDescriptor png_resource;
+ memcpy(png_resource.ResourceID, asset_id.Value(), UUIDlen);
+ png_resource.Type = ASDCP::TimedText::MT_PNG;
+ m_TDesc.ResourceList.push_back(png_resource);
+ m_ResourceTypes.insert(ResourceTypeMap_t::value_type(UUID(png_resource.ResourceID),
+ ASDCP::TimedText::MT_PNG));
+ }
+
+ AttributeVisitor font_visitor("fontFamily");
+ apply_visitor(m_Root, font_visitor);
+
+ for ( i = font_visitor.value_list.begin(); i != font_visitor.value_list.end(); ++i )
+ {
+ UUID font_id = create_font_name_id(*i);
+ TimedTextResourceDescriptor font_resource;
+ memcpy(font_resource.ResourceID, font_id.Value(), UUIDlen);
+ font_resource.Type = ASDCP::TimedText::MT_OPENTYPE;
+ m_TDesc.ResourceList.push_back(font_resource);
+ m_ResourceTypes.insert(ResourceTypeMap_t::value_type(UUID(font_resource.ResourceID),
+ ASDCP::TimedText::MT_OPENTYPE));
}
return RESULT_OK;
case 'b':
TEST_EXTRA_ARG(i, 'b');
- fb_size = abs(atoi(argv[i]));
+ fb_size = Kumu::xabs(strtol(argv[i], 0, 10));
if ( verbose_flag )
fprintf(stderr, "Frame Buffer size: %u bytes.\n", fb_size);
case 'd':
TEST_EXTRA_ARG(i, 'd');
duration_flag = true;
- duration = abs(atoi(argv[i]));
+ duration = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'f':
TEST_EXTRA_ARG(i, 'f');
- start_frame = abs(atoi(argv[i]));
+ start_frame = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'h': help_flag = true; break;
case 'p':
TEST_EXTRA_ARG(i, 'p');
- picture_rate = abs(atoi(argv[i]));
+ picture_rate = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 's':
TEST_EXTRA_ARG(i, 's');
- fb_dump_size = abs(atoi(argv[i]));
+ fb_dump_size = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'V': version_flag = true; break;
case 'w':
TEST_EXTRA_ARG(i, 'w');
- number_width = abs(atoi(argv[i]));
+ number_width = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'Z': j2c_pedantic = false; break;
case 'b':
TEST_EXTRA_ARG(i, 'b');
- fb_size = abs(atoi(argv[i]));
+ fb_size = Kumu::xabs(strtol(argv[i], 0, 10));
if ( verbose_flag )
fprintf(stderr, "Frame Buffer size: %u bytes.\n", fb_size);
case 'D':
TEST_EXTRA_ARG(i, 'D');
- component_depth = abs(atoi(argv[i]));
+ component_depth = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'd':
TEST_EXTRA_ARG(i, 'd');
- duration = abs(atoi(argv[i]));
+ duration = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'E': encrypt_header_flag = false; break;
case 'F':
TEST_EXTRA_ARG(i, 'F');
- field_dominance = abs(atoi(argv[i]));
+ field_dominance = Kumu::xabs(strtol(argv[i], 0, 10));
if ( field_dominance > 1 )
{
fprintf(stderr, "Field dominance value must be \"0\" or \"1\"\n");
case 's':
TEST_EXTRA_ARG(i, 's');
- partition_space = abs(atoi(argv[i]));
+ partition_space = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 't':
TEST_EXTRA_ARG(i, 't');
- rgba_MinRef = abs(atoi(argv[i]));
+ rgba_MinRef = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'T':
TEST_EXTRA_ARG(i, 'T');
- rgba_MaxRef = abs(atoi(argv[i]));
+ rgba_MaxRef = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'u': show_ul_values_flag = true; break;
case 'x':
TEST_EXTRA_ARG(i, 'x');
- horizontal_subsampling = abs(atoi(argv[i]));
+ horizontal_subsampling = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'X':
TEST_EXTRA_ARG(i, 'X');
- vertical_subsampling = abs(atoi(argv[i]));
+ vertical_subsampling = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'Y':
case 't':
TEST_EXTRA_ARG(i, 't');
- max_bitrate = abs(atoi(argv[i]));
+ max_bitrate = Kumu::xabs(strtol(argv[i], 0, 10));
max_bitrate_flag = true;
break;
case 'b':
TEST_EXTRA_ARG(i, 'b');
- fb_size = abs(atoi(argv[i]));
+ fb_size = Kumu::xabs(strtol(argv[i], 0, 10));
if ( verbose_flag )
fprintf(stderr, "Frame Buffer size: %u bytes.\n", fb_size);
case 'd':
TEST_EXTRA_ARG(i, 'd');
duration_flag = true;
- duration = abs(atoi(argv[i]));
+ duration = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'E': encrypt_header_flag = false; break;
case 'f':
TEST_EXTRA_ARG(i, 'f');
- start_frame = abs(atoi(argv[i]));
+ start_frame = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'G': mode = MMT_GOP_START; break;
case 'p':
TEST_EXTRA_ARG(i, 'p');
- picture_rate = abs(atoi(argv[i]));
+ picture_rate = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'R': do_repeat = true; break;
case 's':
TEST_EXTRA_ARG(i, 's');
- fb_dump_size = abs(atoi(argv[i]));
+ fb_dump_size = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 't': mode = MMT_DIGEST; break;
case 'w':
TEST_EXTRA_ARG(i, 'w');
- number_width = abs(atoi(argv[i]));
+ number_width = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'x':
case 'b':
TEST_EXTRA_ARG(i, 'b');
- fb_size = abs(atoi(argv[i]));
+ fb_size = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'd':
TEST_EXTRA_ARG(i, 'd');
duration_flag = true;
- duration = abs(atoi(argv[i]));
+ duration = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'e':
case 'f':
TEST_EXTRA_ARG(i, 'f');
- start_frame = abs(atoi(argv[i]));
+ start_frame = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'G': mode = MMT_GOP_START; break;
case 'p':
TEST_EXTRA_ARG(i, 'p');
- picture_rate = abs(atoi(argv[i]));
+ picture_rate = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 's':
TEST_EXTRA_ARG(i, 's');
- fb_dump_size = abs(atoi(argv[i]));
+ fb_dump_size = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'V': version_flag = true; break;
case 'w':
TEST_EXTRA_ARG(i, 'w');
- number_width = abs(atoi(argv[i]));
+ number_width = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'Z': j2c_pedantic = false; break;
case 'b':
TEST_EXTRA_ARG(i, 'b');
- fb_size = abs(atoi(argv[i]));
+ fb_size = Kumu::xabs(strtol(argv[i], 0, 10));
if ( verbose_flag )
fprintf(stderr, "Frame Buffer size: %u bytes.\n", fb_size);
case 'd':
TEST_EXTRA_ARG(i, 'd');
- duration = abs(atoi(argv[i]));
+ duration = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'E': encrypt_header_flag = false; break;
case 'f':
TEST_EXTRA_ARG(i, 'f');
- start_frame = abs(atoi(argv[i]));
+ start_frame = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'g': write_partial_pcm_flag = true; break;
case 'p':
TEST_EXTRA_ARG(i, 'p');
- picture_rate = abs(atoi(argv[i]));
+ picture_rate = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 's': dolby_atmos_sync_flag = true; break;
if ( Options.verbose_flag )
{
- fprintf(stderr, "%s kHz PCM Audio, %s fps (%u spf)\n", "24",
+ fprintf(stderr, "%s kHz PCM Audio, 24 fps (%u spf)\n",
(Options.s96_flag?"96":"48"), PCM::CalcSamplesPerFrame(ADesc));
fputs("AudioDescriptor:\n", stderr);
PCM::AudioDescriptorDump(ADesc);
AS_02::MXF::AS02IndexReader::AS02IndexReader(const ASDCP::Dictionary*& d) :
m_Duration(0), m_BytesPerEditUnit(0),
- ASDCP::MXF::Partition(m_Dict), m_Dict(d) {}
+ ASDCP::MXF::Partition(d), m_Dict(d) {}
AS_02::MXF::AS02IndexReader::~AS02IndexReader() {}
case 'l':
TEST_EXTRA_ARG(i, 'l');
- extract_limit = abs(strtoll(argv[i], 0, 10));
+ extract_limit = Kumu::xabs(strtoll(argv[i], 0, 10));
break;
case 'p':
bool verbose_flag; // true if the verbose option was selected
bool version_flag; // true if the version display option was selected
bool help_flag; // true if the help display option was selected
- const char* filename; // filename to be processed
- const char* write_filename; // filename to write with val_write_flag
+ std::string filename; // filename to be processed
+ std::string write_filename; // filename to write with val_write_flag
ui32_t chunk_count;
MajorMode_t mode; // MajorMode selector
//
CommandOptions(int argc, const char** argv) :
- error_flag(true), order(""), verbose_flag(false), version_flag(false), help_flag(false),
- filename(""), write_filename(""), chunk_count(0), mode(MMT_VALIDATE)
+ error_flag(true), order(""), verbose_flag(false),
+ version_flag(false), help_flag(false),
+ chunk_count(0), mode(MMT_VALIDATE)
{
// order = "rand";
{
if (argv[i][0] != '-' )
{
- if ( filename != "" )
+ if ( ! filename.empty() )
{
fprintf(stderr, "Extra filename found: %s\n", argv[i]);
return;
if ( help_flag || version_flag )
return;
- if ( strlen ( filename ) == 0 )
+ if ( filename.empty() )
{
fprintf(stderr, "Filename required.\n");
return;
if ( strcmp(order, "") == 0 )
order = "rand";
- if ( strcmp ( filename, write_filename ) == 0 )
+ if ( filename == write_filename )
{
fprintf(stderr, "Output and input files must be different.\n");
return;
Result_t
ReadValidateWriteLargeFile(CommandOptions& Options)
{
- assert(Options.write_filename);
+ assert(!Options.write_filename.empty());
ui32_t check_total = 0;
ui32_t write_total = 0;
ui32_t read_count = 0;
case 's':
TEST_EXTRA_ARG(i, 's');
- request_size = abs(atoi(argv[i]));
+ request_size = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'v': verbose_flag = true; break;
{
case 'b':
TEST_EXTRA_ARG(i, 'b');
- fb_size = abs(atoi(argv[i]));
+ fb_size = Kumu::xabs(strtol(argv[i], 0, 10));
if ( verbose_flag )
fprintf(stderr, "Frame Buffer size: %u bytes.\n", fb_size);
case 'd':
TEST_EXTRA_ARG(i, 'd');
duration_flag = true;
- duration = abs(atoi(argv[i]));
+ duration = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'f':
TEST_EXTRA_ARG(i, 'f');
- start_frame = abs(atoi(argv[i]));
+ start_frame = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'h': help_flag = true; break;
case 's':
TEST_EXTRA_ARG(i, 's');
- fb_dump_size = abs(atoi(argv[i]));
+ fb_dump_size = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'V': version_flag = true; break;
case 'w':
TEST_EXTRA_ARG(i, 'w');
- number_width = abs(atoi(argv[i]));
+ number_width = Kumu::xabs(strtol(argv[i], 0, 10));
break;
default:
case 'b':
TEST_EXTRA_ARG(i, 'b');
- fb_size = abs(atoi(argv[i]));
+ fb_size = Kumu::xabs(strtol(argv[i], 0, 10));
if ( verbose_flag )
fprintf(stderr, "Frame Buffer size: %u bytes.\n", fb_size);
case 'D':
TEST_EXTRA_ARG(i, 'D');
- component_depth = abs(atoi(argv[i]));
+ component_depth = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'd':
TEST_EXTRA_ARG(i, 'd');
- duration = abs(atoi(argv[i]));
+ duration = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'E': encrypt_header_flag = false; break;
case 'F':
TEST_EXTRA_ARG(i, 'F');
- field_dominance = abs(atoi(argv[i]));
+ field_dominance = Kumu::xabs(strtol(argv[i], 0, 10));
if ( field_dominance > 1 )
{
fprintf(stderr, "Field dominance value must be \"0\" or \"1\"\n");
case 's':
TEST_EXTRA_ARG(i, 's');
- partition_space = abs(atoi(argv[i]));
+ partition_space = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 't':
TEST_EXTRA_ARG(i, 't');
- rgba_MinRef = abs(atoi(argv[i]));
+ rgba_MinRef = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'T':
TEST_EXTRA_ARG(i, 'T');
- rgba_MaxRef = abs(atoi(argv[i]));
+ rgba_MaxRef = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'u': show_ul_values_flag = true; break;
case 'x':
TEST_EXTRA_ARG(i, 'x');
- horizontal_subsampling = abs(atoi(argv[i]));
+ horizontal_subsampling = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'X':
TEST_EXTRA_ARG(i, 'X');
- vertical_subsampling = abs(atoi(argv[i]));
+ vertical_subsampling = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'Y':
--- /dev/null
+/*
+Copyright (c) 2015, John Hurst
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*! \file wavsplit.cpp
+ \version $Id$
+ \brief Black WAV file generator
+*/
+
+#include "Wav.h"
+#include "ST2095_PinkNoise.h"
+#include <assert.h>
+
+using namespace ASDCP;
+
+//------------------------------------------------------------------------------------------
+//
+// command line option parser class
+
+static const char* PROGRAM_NAME = "pinkwave"; // program name for messages
+
+// Macros used to test command option data state.
+
+// Increment the iterator, test for an additional non-option command line argument.
+// Causes the caller to return if there are no remaining arguments or if the next
+// argument begins with '-'.
+#define TEST_EXTRA_ARG(i,c) if ( ++i >= argc || argv[(i)][0] == '-' ) \
+ { \
+ fprintf(stderr, "Argument not found for option %c.\n", (c)); \
+ return; \
+ }
+//
+void
+banner(FILE* stream = stderr)
+{
+ fprintf(stream, "\n\
+%s (asdcplib %s)\n\n\
+Copyright (c) 2015 John Hurst\n\n\
+%s is part of asdcplib.\n\
+asdcplib may be copied only under the terms of the license found at\n\
+the top of every file in the asdcplib distribution kit.\n\n\
+Specify the -h (help) option for further information about %s\n\n",
+ PROGRAM_NAME, ASDCP::Version(), PROGRAM_NAME, PROGRAM_NAME);
+}
+
+//
+void
+usage(FILE* stream = stderr)
+{
+ fprintf(stream, "\
+USAGE: %s [-v|-h[-d]] <filename>\n\
+\n\
+ -V - Show version\n\
+ -h - Show help\n\
+ -d <duration> - Number of edit units to process, default 1440\n\
+ -9 - Make a 96 kHz file (default 48 kHz)\n\
+\n\
+Other Options:\n\
+ -v - Verbose, show extra detail during run\n\
+\n\
+ NOTES: o There is no option grouping, all options must be distinct arguments.\n\
+ o All option arguments must be separated from the option by whitespace.\n\
+\n", PROGRAM_NAME);
+}
+
+//
+//
+class CommandOptions
+{
+ CommandOptions();
+
+public:
+ bool error_flag; // true if the given options are in error or not complete
+ bool verbose_flag; // true if the verbose option was selected
+ bool version_flag; // true if the version display option was selected
+ bool help_flag; // true if the help display option was selected
+ bool s96_flag; // true if the samples should be at 96 kHz
+ ui32_t duration; // number of frames to be processed
+ float HpFc; // Highpass filter cutoff frequency in Hz
+ float LpFc; // Lowpass filter cutoff frequency in Hz
+ const char* filename; //
+
+ CommandOptions(int argc, const char** argv) :
+ error_flag(true), verbose_flag(false), version_flag(false), help_flag(false), s96_flag(false),
+ duration(1440), HpFc(PinkFilterHighPassConstant), LpFc(PinkFilterLowPassConstant), filename(0)
+ {
+ for ( int i = 1; i < argc; i++ )
+ {
+ if ( argv[i][0] == '-' && ( isalpha(argv[i][1]) || isdigit(argv[i][1]) ) && argv[i][2] == 0 )
+ {
+ switch ( argv[i][1] )
+ {
+ case 'V': version_flag = true; break;
+ case 'h': help_flag = true; break;
+ case 'v': verbose_flag = true; break;
+
+ case 'd':
+ TEST_EXTRA_ARG(i, 'd');
+ duration = Kumu::xabs(strtol(argv[i], 0, 10));
+ break;
+
+ case '9':
+ s96_flag = true;
+ break;
+
+ default:
+ fprintf(stderr, "Unrecognized option: %c\n", argv[i][1]);
+ return;
+ }
+ }
+ else
+ {
+ if ( filename )
+ {
+ fprintf(stderr, "Unexpected extra filename.\n");
+ return;
+ }
+
+ filename = argv[i];
+ }
+ }
+
+ if ( filename == 0 )
+ {
+ fputs("Output filename required.\n", stderr);
+ return;
+ }
+
+ error_flag = false;
+ }
+};
+
+//
+//
+Result_t
+make_pink_wav_file(CommandOptions& Options)
+{
+ PCM::FrameBuffer FrameBuffer;
+ PCM::AudioDescriptor ADesc;
+
+ ADesc.EditRate = Rational(24,1);
+ ADesc.AudioSamplingRate = Options.s96_flag ? ASDCP::SampleRate_96k : ASDCP::SampleRate_48k;
+ ADesc.Locked = 0;
+ ADesc.ChannelCount = 1;
+ ADesc.QuantizationBits = 24;
+ ADesc.BlockAlign = 3;
+ ADesc.AvgBps = ADesc.BlockAlign * ADesc.AudioSamplingRate.Quotient();
+ ADesc.LinkedTrackID = 1;
+ ADesc.ContainerDuration = Options.duration;
+
+ // set up LCG and pink filter
+ PinkFilter pink_filter(Options.s96_flag ? ASDCP::SampleRate_96k.Numerator : ASDCP::SampleRate_48k.Numerator,
+ Options.HpFc, Options.LpFc);
+
+ LinearCongruentialGenerator lcg(Options.s96_flag ? ASDCP::SampleRate_96k.Numerator : ASDCP::SampleRate_48k.Numerator);
+
+
+ FrameBuffer.Capacity(PCM::CalcFrameBufferSize(ADesc));
+ FrameBuffer.Size(FrameBuffer.Capacity());
+ ui32_t samples_per_frame = PCM::CalcSamplesPerFrame(ADesc);
+
+ if ( Options.verbose_flag )
+ {
+ fprintf(stderr, "%s kHz PCM Audio, 24 fps (%u spf)\n",
+ (Options.s96_flag?"96":"48"), samples_per_frame);
+ fputs("AudioDescriptor:\n", stderr);
+ PCM::AudioDescriptorDump(ADesc);
+ }
+
+ // set up output file
+ Kumu::FileWriter OutFile;
+ Result_t result = OutFile.OpenWrite(Options.filename);
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ RF64::SimpleRF64Header WavHeader(ADesc);
+ result = WavHeader.WriteToFile(OutFile);
+ }
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ ui32_t write_count = 0;
+ ui32_t duration = 0;
+ byte_t scaled_pink[sizeof(ui32_t)];
+
+ while ( ASDCP_SUCCESS(result) && (duration++ < Options.duration) )
+ {
+ // fill the frame buffer with a frame of pink noise
+ byte_t *p = FrameBuffer.Data();
+
+ for ( int i = 0; i < samples_per_frame; ++i )
+ {
+ float pink_sample = pink_filter.GetNextSample(lcg.GetNextSample());
+ ScalePackSample(pink_sample, p, ADesc.BlockAlign);
+ p += ADesc.BlockAlign;
+ }
+
+ result = OutFile.Write(FrameBuffer.RoData(), FrameBuffer.Size(), &write_count);
+ }
+ }
+
+ return result;
+}
+
+
+//
+int
+main(int argc, const char** argv)
+{
+ Result_t result = RESULT_OK;
+ CommandOptions Options(argc, argv);
+
+ if ( Options.help_flag )
+ {
+ usage();
+ return 0;
+ }
+
+ if ( Options.error_flag )
+ return 3;
+
+ if ( Options.version_flag )
+ banner();
+
+ else
+ result = make_pink_wav_file(Options);
+
+ if ( result != RESULT_OK )
+ {
+ fputs("Program stopped on error.\n", stderr);
+
+ if ( result != RESULT_FAIL )
+ {
+ fputs(result, stderr);
+ fputc('\n', stderr);
+ }
+
+ return 1;
+ }
+
+ return 0;
+}
+
+
+//
+// end pinkwave.cpp
+//
case 'd':
TEST_EXTRA_ARG(i, 'd');
- duration = abs(strtol(argv[i], 0, 10));
+ duration = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'f':
TEST_EXTRA_ARG(i, 'f');
- start_frame = abs(strtol(argv[i], 0, 10));
+ start_frame = Kumu::xabs(strtol(argv[i], 0, 10));
break;
case 'h': help_flag = true; break;