I'm getting a discrepancy between calculated versions of the timecode string based on wether the format is drop frame or non-drop frame (23.976 and 29.97 being 'drop' and 24 and 30 being non-drop.). I suspect the error is the result of 'user error' on part of the sound engineer doing the recording and failing to set the DF/NDF flag correctly even though a DF speed has been selected.
In this parsed SPEED subnode, we see that the speed is 23.976... (24000/1001) yet the file is also marked NDF. This is 'not possible' since 23.976 is a 'drop frame rate'. Calling it NDF is nonsensical. (I'm surprised the recorder doesn't actually just automatically set this.) My feeling is that this flag should be ignored and the speed be used directly for calculating the timecode string.
Code: Select all
[SPEED] => Array
(
[NOTE] => Array
(
)
[MASTER_SPEED] => 24000/1001
[CURRENT_SPEED] => 24000/1001
[TIMECODE_FLAG] => NDF
[TIMECODE_RATE] => 24000/1001
[FILE_SAMPLE_RATE] => 48000
[AUDIO_BIT_DEPTH] => 24
[DIGITIZER_SAMPLE_RATE] => 48000
[TIMESTAMP_SAMPLE_RATE] => 48000
[TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_HI] => 0000000000
[TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_LO] => 3180201025
)
I've created a secondary function and placed it in my audioinfo.class.php wrapper file it pulls both $this->info['riff']['WAVE']['iXML'][0]['timecode_rate'] and $this->info['riff']['WAVE']['iXML'][0]['timecode_string_round']. Get getID3 is correctly creating the SPEED, but not the timecode_string. Instead it is presenting the NDF calculation of the timecode rather than the DF version.
If you run my little snippet below, you get:
-- getID3 calculations --
timecode_rate = 23.976
ixml_timecode = 18:24:14:05
-- My code calculation --
tc = 18:23:08:00
speed = 23.976
I've opened the WAV file in Remetacator to confirm and my calculations are correct. At 24 fps, it calculates the TC as 18:24:14:04.1025 and at 23.976 it calculates the timecode as 18:23:08:00.1
Let me know what you think. If you like, I can PM you a link to the BWF file in question but I don't want to post it publicly. Thanks.
Code: Select all
private function parse_iXML() {
echo "<pre>";
if (@$this->info['riff']['WAVE']['iXML'][0]['timecode_string_round']) {
// see if there's an easily accessable frame rate and timecode string.
$this->result['ixml_speed'] = sprintf("%3.3f",$this->info['riff']['WAVE']['iXML'][0]['timecode_rate']);
$this->result['ixml_timecode'] = $this->info['riff']['WAVE']['iXML'][0]['timecode_string_round'];
echo "timecode_rate = " . sprintf("%3.3f",$this->info['riff']['WAVE']['iXML'][0]['timecode_rate']) . "\n";
echo "ixml_timecode = " . $this->info['riff']['WAVE']['iXML'][0]['timecode_string_round'] . "\n";
}
// manually calculate the timecode based purely on speed and samples, ignoring any DF/NDF flag.
if (@$this->info['riff']['WAVE']['iXML'][0]['parsed']['SPEED']) {
$iXML_ary = $this->info['riff']['WAVE']['iXML'][0]['parsed']['SPEED'];
$speed_ary = explode("/",$iXML_ary['MASTER_SPEED']);
$sample_rate = $iXML_ary['FILE_SAMPLE_RATE'];
$time_samples = $iXML_ary['TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_LO'];
// avoid divide by 0 errors in certain circumstances. Normally it should be 24/1
// or 24000/1001 for 23.976
isset ( $speed_ary[1] ) ? $divisor = $speed_ary[1]: $divisor = 1000;
if ($divisor == 1) {
$divisor *= 1000;
$speed_ary[0] *=1000;
}
$master_speed = round($speed_ary[0]/$divisor,4);
$num_seconds = (($time_samples / $sample_rate) * 1000)/$divisor;
$tc_hour = floor($num_seconds/3600);
$tc_minute = floor(($num_seconds % 3600)/60);
$tc_second = $num_seconds - $tc_hour * 3600 - $tc_minute * 60;
$decimal_frames = $tc_second - floor($tc_second);
$tc = str_pad($tc_hour,2,'0',STR_PAD_LEFT). ":" .
str_pad($tc_minute,2,'0',STR_PAD_LEFT) . ":" .
str_pad(floor($tc_second),2,'0',STR_PAD_LEFT). ":" .
str_pad(round($decimal_frames * $master_speed,0),2,'0',STR_PAD_LEFT);
echo "tc = $tc\n";
echo "speed = ". sprintf("%3.3f",$master_speed). "\n";
// $this->result['ixml_speed'] = sprintf("%3.3f",$master_speed);
// $this->result['ixml_timecode'] = $tc;
}
}
Code: Select all
[full_result] => Array
(
[GETID3_VERSION] => 1.9.7-20130705
[filesize] => 84762804
[filename] => iXML-23_976.wav
[filepath] => /home2/product/public_html/clientarea/ftp/RP/4916
[filenamepath] => /home2/product/public_html/clientarea/ftp/RP/4916/iXML-23_976.wav
[avdataoffset] => 6144
[avdataend] => 84762804
[fileformat] => riff
[audio] => Array
(
[dataformat] => wav
[bitrate_mode] => cbr
[wformattag] => 1
[streams] => Array
(
[0] => Array
(
[codec] => Pulse Code Modulation (PCM)
[channels] => 4
[sample_rate] => 48000
[bitrate] => 4608000
[bits_per_sample] => 24
[wformattag] => 1
[bitrate_mode] => cbr
[lossless] => 1
[dataformat] => wav
[compression_ratio] => 1
)
)
[codec] => Pulse Code Modulation (PCM)
[channels] => 4
[sample_rate] => 48000
[bitrate] => 4608000
[bits_per_sample] => 24
[lossless] => 1
[compression_ratio] => 1
)
[tags] => Array
(
[riff] => Array
(
[author] => Array
(
[0] => Sound Dev: Mix664 S#KA0513052004
)
[title] => Array
(
[0] => sSPEED=023.976-ND
sTAKE=36
sUBITS=$00000000
sSWVER=1.06.22
sSCENE=
sFILENAME=T36.WAV
sTAPE=131107
sCIRCLED=FALSE
sTRK1=MixL
sTRK2=MixR
sTRK3=Moderator
sTRK4=Engineer
sNOTE=TOYOTA
)
)
)
[encoding] => UTF-8
[mime_type] => audio/x-wave
[riff] => Array
(
[raw] => Array
(
[fmt ] => Array
(
[wFormatTag] => 1
[nChannels] => 4
[nSamplesPerSec] => 48000
[nAvgBytesPerSec] => 576000
[nBlockAlign] => 12
[wBitsPerSample] => 24
)
)
[audio] => Array
(
[0] => Array
(
[codec] => Pulse Code Modulation (PCM)
[channels] => 4
[sample_rate] => 48000
[bitrate] => 4608000
[bits_per_sample] => 24
)
)
[header_size] => 84762796
[WAVE] => Array
(
[bext] => Array
(
[0] => Array
(
[offset] => 12
[size] => 858
[data] => sSPEED=023.976-ND
sTAKE=36
sUBITS=$00000000
sSWVER=1.06.22
sSCENE=
sFILENAME=T36.WAV
sTAPE=131107
sCIRCLED=FALSE
sTRK1=MixL
sTRK2=MixR
sTRK3=Moderator
sTRK4=Engineer
sNOTE=TOYOTA
Sound Dev: Mix664 S#KA0513052004USSDVKA0513052004131107INJ1s 012013-11-0718:23:38A޽A=PCM,F=48000,W=24,M=multi,R=48000,T=4 Ch
[title] => sSPEED=023.976-ND
sTAKE=36
sUBITS=$00000000
sSWVER=1.06.22
sSCENE=
sFILENAME=T36.WAV
sTAPE=131107
sCIRCLED=FALSE
sTRK1=MixL
sTRK2=MixR
sTRK3=Moderator
sTRK4=Engineer
sNOTE=TOYOTA
[author] => Sound Dev: Mix664 S#KA0513052004
[reference] => USSDVKA0513052004131107INJ1s 01
[origin_date] => 2013-11-07
[origin_time] => 18:23:38
[time_reference] => 3180201025
[bwf_version] => 1
[reserved] =>
[coding_history] => Array
(
[0] => A=PCM,F=48000,W=24,M=multi,R=48000,T=4 Ch
)
[origin_date_unix] => 1383848618
)
)
[iXML] => Array
(
[0] => Array
(
[offset] => 878
[size] => 5226
[data] =>
1.5
SOUND
116
36
131107
FALSE
00000000
USSDVKA0513052004131107INJ1s 01
TOYOTA
24000/1001
24000/1001
NDF
24000/1001
48000
24
48000
48000
0000000000
3180201025
T36.WAV
T36.WAV
1
USSDVKA0513052004131107INJ1s 0
A
4
1
1
MixL
2
2
MixR
3
3
Moderator
4
4
Engineer
FALSE
[parsed] => Array
(
[IXML_VERSION] => 1.5
[PROJECT] => SOUND
[SCENE] => Array
(
)
[MEDIA_ID] => 116
[TAKE] => 36
[TAPE] => 131107
[CIRCLED] => FALSE
[UBITS] => 00000000
[FILE_UID] => USSDVKA0513052004131107INJ1s 01
[NOTE] => TOYOTA
[SPEED] => Array
(
[NOTE] => Array
(
)
[MASTER_SPEED] => 24000/1001
[CURRENT_SPEED] => 24000/1001
[TIMECODE_FLAG] => NDF
[TIMECODE_RATE] => 24000/1001
[FILE_SAMPLE_RATE] => 48000
[AUDIO_BIT_DEPTH] => 24
[DIGITIZER_SAMPLE_RATE] => 48000
[TIMESTAMP_SAMPLE_RATE] => 48000
[TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_HI] => 0000000000
[TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_LO] => 3180201025
)
[HISTORY] => Array
(
[ORIGINAL_FILENAME] => T36.WAV
[CURRENT_FILENAME] => T36.WAV
)
[FILE_SET] => Array
(
[TOTAL_FILES] => 1
[FAMILY_UID] => USSDVKA0513052004131107INJ1s 0
[FILE_SET_INDEX] => A
)
[TRACK_LIST] => Array
(
[TRACK_COUNT] => 4
[TRACK] => Array
(
[0] => Array
(
[CHANNEL_INDEX] => 1
[INTERLEAVE_INDEX] => 1
[NAME] => MixL
)
[1] => Array
(
[CHANNEL_INDEX] => 2
[INTERLEAVE_INDEX] => 2
[NAME] => MixR
)
[2] => Array
(
[CHANNEL_INDEX] => 3
[INTERLEAVE_INDEX] => 3
[NAME] => Moderator
)
[3] => Array
(
[CHANNEL_INDEX] => 4
[INTERLEAVE_INDEX] => 4
[NAME] => Engineer
)
)
)
[USER] => Array
(
[SOUND_DEVICES] => Array
(
[MIX664] => Array
(
[CL6_PRESENT] => FALSE
)
)
)
)
[master_speed] => 23.976023976024
[timecode_rate] => 23.976023976024
[timecode_seconds] => 66254.188020833
[timecode_string] => 18:24:14:04.51
[timecode_string_round] => 18:24:14:05
)
)
[fmt ] => Array
(
[0] => Array
(
[offset] => 6112
[size] => 16
[data] => €»Ê
)
)
[data] => Array
(
[0] => Array
(
[offset] => 6136
[size] => 84756660
)
)
)
[comments] => Array
(
[author] => Array
(
[0] => Sound Dev: Mix664 S#KA0513052004
)
[title] => Array
(
[0] => sSPEED=023.976-ND
sTAKE=36
sUBITS=$00000000
sSWVER=1.06.22
sSCENE=
sFILENAME=T36.WAV
sTAPE=131107
sCIRCLED=FALSE
sTRK1=MixL
sTRK2=MixR
sTRK3=Moderator
sTRK4=Engineer
sNOTE=TOYOTA
)
)
[encoding] => ISO-8859-1
)
[playtime_seconds] => 147.14697916667
[tags_html] => Array
(
[riff] => Array
(
[author] => Array
(
[0] => Sound Dev: Mix664 S#KA0513052004
)
[title] => Array
(
[0] => sSPEED=023.976-ND
sTAKE=36
sUBITS=$00000000
sSWVER=1.06.22
sSCENE=
sFILENAME=T36.WAV
sTAPE=131107
sCIRCLED=FALSE
sTRK1=MixL
sTRK2=MixR
sTRK3=Moderator
sTRK4=Engineer
sNOTE=TOYOTA
)
)
)
[bitrate] => 4608000
[playtime_string] => 2:27
)
[upload_date] => 1383960881
[doc_name] => iXML-23_976
[file_md5] => 944a0c383d2ae2957d1742c4413eae33
)