CTIMECOD.CPP

//=========================================================================== 
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1992 - 1997 Microsoft Corporation. All Rights Reserved.
//
//===========================================================================
//
// filename: ctimecod.cpp
//
// SMPTE Timecode support class
//
//---------------------------------------------------------
//
//This code is provided for reference purposes only
//
//NOTES:
// 1. Code is un-optimized for clarity
// 2. Minimal error checking.
// 3. Negative t/c values not supported
// 4. File logging functions are here for illustrative
//purposes but not used.
//
//---------------------------------------------------------


#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <vfw.h>
#include <streams.h>
#include "ctimecod.h"

// timecode conversion tables
#define TC_LENGTH 11*sizeof(TCHAR)// length of a t/c string
static long lNDFTable[] = {1080000L,108000L,18000L,1800L,300L,30L,10L,1L};
static long lDFTable[] = {1078920L,107892L,17982L,1798L,300L,30L,10L,1L};
static long l25Table[] = {900000L,90000L,15000L,1500L,250L,25L,10L,1L};
static long l24Table[] = {864000L,86400L,14400L,1440L,240L,24L,10L,1L};

//---------------------------------------------------------
//
//ConvertStringToTimecode
//
// Timecode sample passed in contains desired framerate for conversion
//
//---------------------------------------------------------
DWORD
CTimecode::ConvertStringToTimecode(TCHAR *lpszTimecode,
PTIMECODE_SAMPLE pTimecodeSample)
{
int i, j;
long *table;
TCHAR temp;

// select conversion table
switch (pTimecodeSample->timecode.wFrameRate)
{
case AM_TIMECODE_30DROP:
table = lDFTable;
break;
case AM_TIMECODE_30NONDROP:
table = lNDFTable;
break;
case AM_TIMECODE_25:
table = l25Table;
break;
case AM_TIMECODE_24:
table = l24Table;
break;
default:
table = lNDFTable;
}
pTimecodeSample->timecode.dwFrames = 0L;
j = 0;
for ( i = 0; lpszTimecode[i]!= 0; i++ )
{
if ( (lpszTimecode[i] > '9') || (lpszTimecode[i] < '0') )
continue;
temp = (lpszTimecode[i] - '0');
pTimecodeSample->timecode.dwFrames += (DWORD)temp * table[j];
j++;
}
return 0L;
}
//---------------------------------------------------------
//
//ConvertTimecodeToString
//
//---------------------------------------------------------
DWORD
CTimecode::ConvertTimecodeToString(PTIMECODE_SAMPLE pTimecodeSample,
TCHAR *lpszTimecode)
{
int i, j, temp;
long timecode;
long *table;
WORD wFCM;
int flag = 0;

// make local copies
wFCM = pTimecodeSample->timecode.wFrameRate;
timecode = pTimecodeSample->timecode.dwFrames;

// select conversion table
switch (wFCM)
{
case AM_TIMECODE_30DROP:
table = lDFTable;
break;
case AM_TIMECODE_30NONDROP:
table = lNDFTable;
break;
case AM_TIMECODE_25:
table = l25Table;
break;
case AM_TIMECODE_24:
table = l24Table;
break;
default:
table = lNDFTable;
}
for ( i=0, j=0; j<(TC_LENGTH); i++, j++ )
{
temp = (int)( timecode / table[i]);
lpszTimecode[j] = temp + '0';// ASCII conversion
timecode -= temp * table[i];
// if minutesx10, do the drop frame test
if ( i == 2 ) {
if ( timecode < 2)
flag = 1;// this means we are on a 10 minute
// boundary and 2 frames should be
// added later
else
timecode-=2L;
}
if ( i == 3 ) {
// this is where the 2 frames get added in
if ( !flag )
timecode+=2L;
}
// add punctuation
if ( 1 == j || 4 == j || 7 == j )
{
j++;
if ( 8 == j && wFCM == AM_TIMECODE_30DROP )
lpszTimecode[j] = ';';
else
lpszTimecode[j] = ':';
}
}
lpszTimecode[j] = 0;// null terminate
return 0L;
}

// eof ctimecod.c