Skip to content

Commit

Permalink
Patchin 1.26.1 with AES57-2011 changes. Related pull request openpres…
Browse files Browse the repository at this point in the history
  • Loading branch information
ThomasEdvardsen committed Jan 6, 2023
1 parent 4b8ef10 commit 939b2ec
Show file tree
Hide file tree
Showing 6 changed files with 2,059 additions and 2,315 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public RepTreeRoot(RepInfo info, JhoveBase base) {
private static final String FILM_FRAMING = "FilmFraming";
private static final String FRAMING_NOT_APPLICABLE = "Framing: NOT_APPLICABLE";
private static final String NTSC_FILM_FRAMING_TYPE = "Type: ntscFilmFramingType";



/**
Expand Down Expand Up @@ -673,16 +673,15 @@ private DefaultMutableTreeNode aesToNode(AESAudioMetadata aes) {
region.add(timeline);
int nchan = aes.getNumChannels();
if (nchan != AESAudioMetadata.NULL) {
String[] locs = aes.getMapLocations();

region.add(new DefaultMutableTreeNode("NumChannels: "
+ Integer.toString(nchan), false));
for (String loc : locs) {
for (int ch = 0; ch < nchan; ch++) {
// write a stream element for each channel
DefaultMutableTreeNode stream = new DefaultMutableTreeNode(
"Stream", true);
region.add(stream);
stream.add(new DefaultMutableTreeNode("ChannelAssignment: "
+ loc, false));
stream.add(new DefaultMutableTreeNode("ChannelNum: " + Integer.toString (ch), false));
}
}
face.add(region);
Expand Down Expand Up @@ -749,83 +748,39 @@ private DefaultMutableTreeNode aesToNode(AESAudioMetadata aes) {
}

private void addAESTimeRange(DefaultMutableTreeNode parent,
AESAudioMetadata.TimeDesc start, AESAudioMetadata.TimeDesc duration) {
// Put the start time in
DefaultMutableTreeNode node = new DefaultMutableTreeNode("Start", true);
// Put in boilerplate to match the AES schema
node.add(new DefaultMutableTreeNode(FRAME_COUNT_30, false));
node.add(new DefaultMutableTreeNode(TIME_BASE_1000));
node.add(new DefaultMutableTreeNode(VIDEO_FIELD_FIELD_1));
node.add(new DefaultMutableTreeNode(
COUNTING_MODE_NTSC_NON_DROP_FRAME, false));
node.add(new DefaultMutableTreeNode(HOURS + start.getHours(), false));
node.add(new DefaultMutableTreeNode(MINUTES + start.getMinutes(),
false));
node.add(new DefaultMutableTreeNode(SECONDS + start.getSeconds(),
false));
node.add(new DefaultMutableTreeNode(FRAMES + start.getFrames(),
false));

// Do samples a bit more elaborately than is really necessary,
// to maintain parallelism with the xml schema.
DefaultMutableTreeNode snode = new DefaultMutableTreeNode(SAMPLES,
true);
double sr = start.getSampleRate();
if (sr == 1.0) {
sr = _sampleRate;
}
snode.add(new DefaultMutableTreeNode("SampleRate: S"
+ Integer.toString((int) sr), false));
snode.add(new DefaultMutableTreeNode(NUMBER_OF_SAMPLES
+ start.getSamples(), false));
node.add(snode);

snode = new DefaultMutableTreeNode(FILM_FRAMING, true);
snode.add(new DefaultMutableTreeNode(FRAMING_NOT_APPLICABLE, false));
snode.add(new DefaultMutableTreeNode(NTSC_FILM_FRAMING_TYPE, false));
node.add(snode);
parent.add(node);
AESAudioMetadata.TimeDesc start,
AESAudioMetadata.TimeDesc duration)
{
writeAESTimeRangePart(parent, "StartTime", start);

// Duration is optional.
if (duration != null) {
node = new DefaultMutableTreeNode("Duration", true);
// Put in boilerplate to match the AES schema
node.add(new DefaultMutableTreeNode(FRAME_COUNT_30, false));
node.add(new DefaultMutableTreeNode(TIME_BASE_1000));
node.add(new DefaultMutableTreeNode(VIDEO_FIELD_FIELD_1));
node.add(new DefaultMutableTreeNode(
COUNTING_MODE_NTSC_NON_DROP_FRAME, false));
node.add(new DefaultMutableTreeNode(
HOURS + duration.getHours(), false));
node.add(new DefaultMutableTreeNode(MINUTES
+ duration.getMinutes(), false));
node.add(new DefaultMutableTreeNode(SECONDS
+ duration.getSeconds(), false));
node.add(new DefaultMutableTreeNode(FRAMES
+ duration.getFrames(), false));

// Do samples a bit more elaborately than is really necessary,
// to maintain parallelism with the xml schema.
snode = new DefaultMutableTreeNode(SAMPLES, true);
sr = duration.getSampleRate();
if (sr == 1.0) {
sr = _sampleRate;
writeAESTimeRangePart(parent, "Duration", duration);
}
}


private void writeAESTimeRangePart(DefaultMutableTreeNode parent,
String name, AESAudioMetadata.TimeDesc timeDesc) {
double sampleRate = timeDesc.getSampleRate ();
if (sampleRate == 1.0) {
sampleRate = _sampleRate;
}
snode.add(new DefaultMutableTreeNode("SamplesRate S"
+ Integer.toString((int) sr), false));
snode.add(new DefaultMutableTreeNode(NUMBER_OF_SAMPLES
+ duration.getSamples(), false));
node.add(snode);

snode = new DefaultMutableTreeNode(FILM_FRAMING, true);
snode.add(new DefaultMutableTreeNode(FRAMING_NOT_APPLICABLE,
false));
snode.add(new DefaultMutableTreeNode(NTSC_FILM_FRAMING_TYPE,
false));
node.add(snode);

DefaultMutableTreeNode node =
new DefaultMutableTreeNode (name, true);
node.add(new DefaultMutableTreeNode(
"Value: " + String.valueOf(timeDesc.getSamples()), false));
node.add(new DefaultMutableTreeNode(
"EditRate: " + sampleRate, false));
node.add(new DefaultMutableTreeNode(
"FactorNumerator: 1", false));
node.add(new DefaultMutableTreeNode(
"FactorDenominator: 1", false));

parent.add(node);
}
}


/* Function for turning the textMD metadata into a subtree. */
private DefaultMutableTreeNode textMDToNode(TextMDMetadata textMD) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public class AESAudioMetadata
******************************************************************/

/** Constant value for the SchemaVersion field */
public static final String SCHEMA_VERSION = "1.02b";
public static final String SCHEMA_VERSION = "1.0.0";

/** Constant value for the disposition field */
private static final String DEFAULT_DISPOSITION = "validation";
Expand Down Expand Up @@ -160,20 +160,9 @@ public void setBitrateReduction (String codecName,
* accessed through the public methods of this interface.
*/
public static interface TimeDesc {
/** Returns the hours component. */
public long getHours ();
/** Returns the minutes component. */
public long getMinutes ();
/** Returns the seconds component. */
public long getSeconds ();
/** Returns the frames component of the fraction of a second.
* We always consider frames to be thirtieths of a second. */
public long getFrames ();
/** Returns the samples remaining after the frames part of
* the fractional second. */
/** Returns the number of samples. */
public long getSamples ();
/** Returns the sample rate on which the samples remainder
* is based. */
/** Returns the sample rate. */
public double getSampleRate ();
}

Expand Down Expand Up @@ -371,26 +360,13 @@ public void setWordSize (int wordSize)
*/
class TimeDescImpl implements TimeDesc
{
private long _hours;
private long _minutes;
private long _seconds;
private long _frames;

private long _samples;
private double _sampleRate;
private long _frameCount;

/* Constructor rewritten to avoid rounding errors when converting to
* TCF. Now uses integer remainder math instead of floating point.
* Changed the base unit from a double representing seconds to a long
* representing samples. Changed all existing calls (that I could find)
* to this method to accomodate this change.
*
* @author David Ackerman
*/

public TimeDescImpl (long samples)
{
long _sample_count = samples;
_frameCount = 30;
_samples = samples;
_sampleRate = _curFormatRegion.getSampleRate ();

/* It seems that this method is initially called before a valid
Expand All @@ -400,73 +376,15 @@ public TimeDescImpl (long samples)
if (_sampleRate < 0) {
_sampleRate = 44100.0; //reasonable default value
}

long sample_in_1_frame = (long)(_sampleRate/_frameCount);
long sample_in_1_second = sample_in_1_frame * _frameCount;
long sample_in_1_minute = sample_in_1_frame * _frameCount * 60;
long sample_in_1_hour = sample_in_1_frame * _frameCount * 60 * 60;
long sample_in_1_day = sample_in_1_frame * _frameCount * 60 * 60 * 24;

// BWF allows for a negative timestamp but tcf does not, so adjust
// time accordingly
// this might be a good place to report a warning during validation
if (_sample_count < 0) {
_sample_count += sample_in_1_day;
_sample_count = (_sample_count % sample_in_1_day);
}

_hours = _sample_count / sample_in_1_hour;
_sample_count -= _hours * sample_in_1_hour;
_minutes = _sample_count / sample_in_1_minute;
_sample_count -= _minutes * sample_in_1_minute;
_seconds = _sample_count / sample_in_1_second;
_sample_count -= _seconds * sample_in_1_second;
_frames = _sample_count / sample_in_1_frame;
_sample_count -= _frames * sample_in_1_frame;
_samples = _sample_count;

/* At present TCF does not have the ability to handle time stamps
* > midnight. Industry practice is to roll the clock forward to
* zero or back to 23:59:59:29... when crossing this boundary
* condition.
*/
_hours = _hours % 24;
}

/** Returns the hours component. */
@Override
public long getHours () {
return _hours;
}

/** Returns the minutes component. */
@Override
public long getMinutes () {
return _minutes;
}

/** Returns the seconds component. */
@Override
public long getSeconds () {
return _seconds;
}

/** Returns the frames component of the fraction of a second.
* We always consider frames to be thirtieths of a second. */
@Override
public long getFrames () {
return _frames;
}

/** Returns the samples remaining after the frames part of
* the fractional second. */
/** Returns the number of samples. */
@Override
public long getSamples () {
return _samples;
}

/** Returns the sample rate on which the samples remainder
* is based. */

/** Returns the sample rate. */
@Override
public double getSampleRate () {
return _sampleRate;
Expand Down
Loading

0 comments on commit 939b2ec

Please sign in to comment.