def findTwoPop(): try: filePath = sys.argv[1] if os.path.exists(filePath): wavefile = PCWaveFile(filePath) if wavefile.isValidWaveFile() != True: print "File is not a wave file" return dataStartPos = wavefile.getDataChunk()["chunkPosition"] dataLength = wavefile.getDataChunk()["chunkSize"] sampleRate = wavefile.numberOfSamplesPerSecond() byteWidth = wavefile.numberOfBytesPerSample() numberOfChannels = wavefile.numberOfChannels() with open(filePath, 'rb') as f: startTime = datetime.datetime.now() #1 frame of audio at 23.98 or 48048 sample rate data_size = 2002 #position at which to examine startOffset = int(round( sampleRate * 1.001)) * 148 * byteWidth * numberOfChannels startOffset -= (data_size * byteWidth * numberOfChannels * 2) dataStartPos = dataStartPos + startOffset f.seek(dataStartPos) if dataStartPos > dataLength: print "file is too short to analyze" return dataToReadChunkSize = data_size * byteWidth * numberOfChannels dataRemaining = data_size * byteWidth * numberOfChannels * 6 while dataRemaining > 0: data = f.read(dataToReadChunkSize) print pcwave dataRemaining -= dataToReadChunkSize print "Next Sample" for channel in range(0, numberOfChannels): subdata = "" for x in range(channel * byteWidth, len(data), byteWidth * numberOfChannels): # subdata.extend(data[x:x+3]) subdata += (data[x] + data[x + 1] + data[x + 2]) # print anaylyzeDataWithZeroCrossing(subdata, byteWidth, sampleRate) result = ultimateFreqAndPowerForData( subdata, byteWidth, sampleRate) if math.isnan(result[0]) or result[1] < -65.0: print '\tDisregard', round(result[0]), result[1] elif result[0] < 1005 and result[0] > 995: print '\tMatch', round(result[0]), result[1] else: print '\tOops', round(result[0]), result[1] else: print "The file", filename, "doesn't exist" except IndexError as e: print "No file was passed in as a variable"
def smallSampleSize(): try: filePath = sys.argv[1] if os.path.exists(filePath): wavefile = PCWaveFile(filePath) if wavefile.isValidWaveFile() != True: print "File is not a wave file" return dataStartPos = wavefile.getDataChunk()["chunkPosition"] dataLength = wavefile.getDataChunk()["chunkSize"] sampleRate = wavefile.numberOfSamplesPerSecond() timeCodeSampleRate = int(sampleRate * 1.001) byteWidth = wavefile.numberOfBytesPerSample() numberOfChannels = wavefile.numberOfChannels() frameNumber = 0 print datetime.datetime.now() with open(filePath, 'rb') as f: startTime = datetime.datetime.now() f.seek(dataStartPos) data_size = int( (sampleRate * 1.001) / 24) #1 frame of audio at 23.98 or 48048 sample rate dataToReadChunkSize = data_size * byteWidth #examine 160 seconds of data dataRemaining = (160 * timeCodeSampleRate ) * byteWidth * numberOfChannels #dataLength while dataRemaining > 0: if dataRemaining > dataToReadChunkSize: data = f.read(dataToReadChunkSize) else: data = f.read(dataRemaining) dataRemaining -= len(data) print pctimecode.convertUnsignedLongLongToTimeCode( wavefile.timestamp + (frameNumber * data_size), timeCodeSampleRate, 24) frameNumber += 1 for channel in range(0, numberOfChannels): subdata = "" for x in range(channel * byteWidth, len(data), byteWidth * numberOfChannels): # subdata.extend(data[x:x+3]) subdata += (data[x] + data[x + 1] + data[x + 2]) print ultimateFreqAndPowerForData( subdata, byteWidth, sampleRate) print datetime.datetime.now() else: print "The file", filename, "doesn't exist" except IndexError as e: print "No file was passed in as a variable"
def multichannel(): try: filePath = sys.argv[1] if os.path.exists(filePath): wavefile = PCWaveFile(filePath) if wavefile.isValidWaveFile() != True: print "File is not a wave file" return dataStartPos = wavefile.getDataChunk()["chunkPosition"] dataLength = wavefile.getDataChunk()["chunkSize"] sampleRate = wavefile.numberOfSamplesPerSecond() timeCodeSampleRate = int(math.ceil(48000 * 1.001)) byteWidth = wavefile.numberOfBytesPerSample() numberOfChannels = wavefile.numberOfChannels() data_size = 48048 #1 second of audio print timeCodeSampleRate print pctimecode.convertUnsignedLongLongToTimeCode( wavefile.timestamp, timeCodeSampleRate, 24) second = 0 with open(filePath, 'rb') as f: startTime = datetime.datetime.now() f.seek(dataStartPos) dataToReadChunkSize = sampleRate * byteWidth * numberOfChannels dataRemaining = dataLength while dataRemaining > 0: if dataRemaining > dataToReadChunkSize: data = f.read(dataToReadChunkSize) else: data = f.read(dataRemaining) dataRemaining -= len(data) print wavefile.timestamp print pctimecode.convertUnsignedLongLongToTimeCode( wavefile.timestamp + (second * data_size), timeCodeSampleRate, 24) for channel in range(0, numberOfChannels): subdata = "" for x in range(channel * byteWidth, len(data), byteWidth * numberOfChannels): subdata += (data[x] + data[x + 1] + data[x + 2]) print highestAndNextHighestFreqAndPowerForData( subdata, byteWidth, sampleRate) second += 1 else: print "The file", filename, "doesn't exist" except IndexError as e: print "No file was passed in as a variable"
def findTwoPop(): try: filePath = sys.argv[1] if os.path.exists(filePath): wavefile = PCWaveFile(filePath) if wavefile.isValidWaveFile() != True: print "File is not a wave file" return dataStartPos = wavefile.getDataChunk()["chunkPosition"] dataLength = wavefile.getDataChunk()["chunkSize"] sampleRate = wavefile.numberOfSamplesPerSecond() byteWidth = wavefile.numberOfBytesPerSample() numberOfChannels = wavefile.numberOfChannels() with open(filePath, 'rb') as f: startTime = datetime.datetime.now() #1 frame of audio at 23.98 or 48048 sample rate data_size = 2002 #position at which to examine startOffset = int(round(sampleRate * 1.001)) * 148 * byteWidth * numberOfChannels startOffset -= (data_size * byteWidth * numberOfChannels * 2) dataStartPos = dataStartPos + startOffset f.seek(dataStartPos) if dataStartPos > dataLength: print "file is too short to analyze" return dataToReadChunkSize = data_size*byteWidth*numberOfChannels dataRemaining = data_size*byteWidth*numberOfChannels*6 while dataRemaining > 0: data = f.read(dataToReadChunkSize) print pcwave dataRemaining -= dataToReadChunkSize print "Next Sample" for channel in range(0, numberOfChannels): subdata = "" for x in range(channel*byteWidth,len(data),byteWidth*numberOfChannels): # subdata.extend(data[x:x+3]) subdata += (data[x] + data[x+1] + data[x+2]) # print anaylyzeDataWithZeroCrossing(subdata, byteWidth, sampleRate) result = ultimateFreqAndPowerForData(subdata, byteWidth, sampleRate) if math.isnan(result[0]) or result[1] < -65.0: print '\tDisregard', round(result[0]), result[1] elif result[0] < 1005 and result[0] > 995: print '\tMatch', round(result[0]), result[1] else: print '\tOops', round(result[0]), result[1] else: print "The file",filename,"doesn't exist" except IndexError as e: print "No file was passed in as a variable"
def smallSampleSize(): try: filePath = sys.argv[1] if os.path.exists(filePath): wavefile = PCWaveFile(filePath) if wavefile.isValidWaveFile() != True: print "File is not a wave file" return dataStartPos = wavefile.getDataChunk()["chunkPosition"] dataLength = wavefile.getDataChunk()["chunkSize"] sampleRate = wavefile.numberOfSamplesPerSecond() timeCodeSampleRate = int(sampleRate * 1.001) byteWidth = wavefile.numberOfBytesPerSample() numberOfChannels = wavefile.numberOfChannels() frameNumber = 0 print datetime.datetime.now() with open(filePath, 'rb') as f: startTime = datetime.datetime.now() f.seek(dataStartPos) data_size = int((sampleRate * 1.001) / 24) #1 frame of audio at 23.98 or 48048 sample rate dataToReadChunkSize = data_size*byteWidth #examine 160 seconds of data dataRemaining = (160*timeCodeSampleRate)*byteWidth*numberOfChannels #dataLength while dataRemaining > 0: if dataRemaining > dataToReadChunkSize: data = f.read(dataToReadChunkSize) else: data = f.read(dataRemaining) dataRemaining -= len(data) print pctimecode.convertUnsignedLongLongToTimeCode(wavefile.timestamp + (frameNumber * data_size), timeCodeSampleRate, 24) frameNumber += 1 for channel in range(0, numberOfChannels): subdata = "" for x in range(channel*byteWidth,len(data),byteWidth*numberOfChannels): # subdata.extend(data[x:x+3]) subdata += (data[x] + data[x+1] + data[x+2]) print ultimateFreqAndPowerForData(subdata, byteWidth, sampleRate) print datetime.datetime.now() else: print "The file",filename,"doesn't exist" except IndexError as e: print "No file was passed in as a variable"
def multichannel(): try: filePath = sys.argv[1] if os.path.exists(filePath): wavefile = PCWaveFile(filePath) if wavefile.isValidWaveFile() != True: print "File is not a wave file" return dataStartPos = wavefile.getDataChunk()["chunkPosition"] dataLength = wavefile.getDataChunk()["chunkSize"] sampleRate = wavefile.numberOfSamplesPerSecond() timeCodeSampleRate = int(math.ceil(48000 * 1.001)) byteWidth = wavefile.numberOfBytesPerSample() numberOfChannels = wavefile.numberOfChannels() data_size = 48048 #1 second of audio print timeCodeSampleRate print pctimecode.convertUnsignedLongLongToTimeCode(wavefile.timestamp, timeCodeSampleRate, 24) second = 0 with open(filePath, 'rb') as f: startTime = datetime.datetime.now() f.seek(dataStartPos) dataToReadChunkSize = sampleRate*byteWidth*numberOfChannels dataRemaining = dataLength while dataRemaining > 0: if dataRemaining > dataToReadChunkSize: data = f.read(dataToReadChunkSize) else: data = f.read(dataRemaining) dataRemaining -= len(data) print wavefile.timestamp print pctimecode.convertUnsignedLongLongToTimeCode(wavefile.timestamp + (second * data_size), timeCodeSampleRate, 24) for channel in range(0, numberOfChannels): subdata = "" for x in range(channel*byteWidth,len(data),byteWidth*numberOfChannels): subdata += (data[x] + data[x+1] + data[x+2]) print highestAndNextHighestFreqAndPowerForData(subdata, byteWidth, sampleRate) second += 1 else: print "The file",filename,"doesn't exist" except IndexError as e: print "No file was passed in as a variable"
def multichannel(): data_size = 48000 #1 second of audio frate = 48000.0 try: filePath = sys.argv[1] if os.path.exists(filePath): wavefile = PCWaveFile(filePath) if wavefile.isValidWaveFile() != True: print "File is not a wave file" return dataStartPos = wavefile.getDataChunk()["chunkPosition"] dataLength = wavefile.getDataChunk()["chunkSize"] sampleRate = wavefile.numberOfSamplesPerSecond() byteWidth = wavefile.numberOfBytesPerSample() numberOfChannels = wavefile.numberOfChannels() print byteWidth, numberOfChannels second = 0 with open(filePath, 'rb') as f: startTime = datetime.datetime.now() f.seek(dataStartPos) dataToReadChunkSize = sampleRate*byteWidth*numberOfChannels dataRemaining = dataLength while dataRemaining > 0: if dataRemaining > dataToReadChunkSize: data = f.read(dataToReadChunkSize) else: data = f.read(dataRemaining) dataRemaining -= len(data) print "Next second", second for channel in range(0, numberOfChannels): subdata = "" for x in range(channel*byteWidth,len(data),byteWidth*numberOfChannels): # subdata.extend(data[x:x+3]) subdata += (data[x] + data[x+1] + data[x+2]) print anaylyzeData(subdata, byteWidth, sampleRate) second += 1 else: print "The file",filename,"doesn't exist" except IndexError as e: print "No file was passed in as a variable"
def formatInformationForFile(filePath): wavefile = PCWaveFile(filePath) if wavefile == None or wavefile.isValidWaveFile() == False: badInfo = {} badInfo["fileName"] = os.path.basename(filePath) badInfo["fullPath"] = filePath badInfo["bitDepth"] = 0 badInfo["sampleRate"] = 0 badInfo["bextChunk"] = False badInfo["timeStamp"] = 0 badInfo["timeStampTC"] = "00:00:00:00" badInfo["regnChunk"] = False badInfo["channelCount"] = 0 badInfo["status"] = 'fail' badInfo["errors"] = ["{} is not a wave file.".format(os.path.basename(filePath)),] badInfo['fileLevels'] = {'status':'fail','layout':'unknown', "warningString":""} badInfo['headTones'] = {'status':'fail', 'resultString':'Unable to analyze head tones on account of invalid format.', "warningString":""} badInfo['pops'] = {'status':'fail', 'resultString':'Unable to analyze pops on account of invalid format.', "warningString":""} return badInfo info = {} info['fileName'] = os.path.basename(filePath) info['fullPath'] = filePath info['bitDepth'] = wavefile.numberOfBitsPerSample() info['sampleRate'] = wavefile.numberOfSamplesPerSecond() info['bextChunk'] = True if wavefile.hasBextChunk() else False info['timeStamp'] = wavefile.timestamp info['timeStampTC'] = prettyTimeCode2398(wavefile.timestamp, info['sampleRate']) info['regnChunk'] = True if wavefile.hasBextChunk() else False if wavefile.hasRegnChunk() == True: info['regnChunkUserTimeStamp'] = wavefile.regnChunkInfoDict['userTimeStamp'] info['regnChunkOriginalTimeStamp'] = wavefile.regnChunkInfoDict['originalTimeStamp'] info['channelCount'] = wavefile.numberOfChannels() if info['bitDepth'] != 24 or info['sampleRate'] != 48000: info['fileLevels'] = {'status':'fail','layout':'unknown', "warningString":""} info['headTones'] = {'status':'fail', 'resultString':'Unable to analyze head tones on account of invalid format.', "warningString":""} info['pops'] = {'status':'fail', 'resultString':'Unable to analyze pops on account of invalid format.', "warningString":""} else: info['fileLevels'] = analyzeLevels(filePath) info['headTones'] = analyzeHeadAlt(filePath) info['pops'] = analyzeTwoPopInEighths(filePath) return addStatusToInformation(info)
def examine2pop(): data_size = 48000/24 #1 second of audio frate = 48000.0 try: filePath = sys.argv[1] if os.path.exists(filePath): wavefile = PCWaveFile(filePath) if wavefile.isValidWaveFile() != True: print "File is not a wave file" return print wavefile.getFmtChunkDict() dataStartPos = wavefile.getDataChunk()["chunkPosition"] dataLength = wavefile.getDataChunk()["chunkSize"] sampleRate = wavefile.numberOfSamplesPerSecond() byteWidth = wavefile.numberOfBytesPerSample() with open(filePath, 'rb') as f: startTime = datetime.datetime.now() f.seek(dataStartPos) dataToReadChunkSize = data_size*byteWidth dataRemaining = dataLength while dataRemaining > 0: if dataRemaining > dataToReadChunkSize: data = f.read(dataToReadChunkSize) else: data = f.read(dataRemaining) print anaylyzeData(data, byteWidth, sampleRate) dataRemaining -= len(data) else: print "The file",filename,"doesn't exist" except: print "No file was passed in as a variable"
def updatebwftimecode(): parser = argparse.ArgumentParser(description="Set Timecode for a Broadcast Wave File, Optionally write metadata to iXML, and display file information") parser.add_argument( "filename", help="the file to process, represented as a path") parser.add_argument('-t','--timecode', required=True, dest="timecode", help="the timecode value, displayed as either drop or non drop, wrapped in quotes") parser.add_argument('-f', '--framerate', required=True, dest="framerate", help="an string representation of the framerate", choices=['2398', '24', '25', '2997', '2997DF', '30']) parser.add_argument('-l','--tracklayout', dest="tracklayout", help="a tracklayout confirguration for the iXML file", choices=tracklayouts.tracklayoutRepresentation()) parser.add_argument('-x', '--noixml', dest="noixml", help="do not write ixml into file", action="store_true") group = parser.add_mutually_exclusive_group() group.add_argument('-v', '--verbose', dest="verbose", help="display iXML to screen", action="store_true") group.add_argument('-o', '--outputfile', dest="outputfile", help="a path to a file to save information about the wav file you are updating") args = parser.parse_args() # bail if the timecode is not properly specified if pctimecode.isTimeCodeSafe(args.timecode, args.framerate) == False: print "-----------Timcode is invalid-----------" return useDropFrame = False if args.framerate.find("DF") is not -1: useDropFrame = True filename = args.filename layout = tracklayouts.tracklayouts if os.path.exists(filename): wavefile = PCWaveFile(filename) newTimeReference = 0 fileSampleRate = wavefile.numberOfSamplesPerSecond() # Calculate new timecode information if args.framerate == '2398': newTimeReference = pctimecode.convertTimeCodeToUnsignedLongLong2398(args.timecode, fileSampleRate) elif args.framerate == '24': newTimeReference = pctimecode.convertTimeCodeToUnsignedLongLong24(args.timecode, fileSampleRate) elif args.framerate == '25': newTimeReference = pctimecode.convertTimeCodeToUnsignedLongLong25(args.timecode, fileSampleRate) elif args.framerate == '2997': if useDropFrame == True: newTimeReference = pctimecode.convertTimeCodeToUnsignedLongLong2997DF(args.timecode, fileSampleRate) else: newTimeReference = pctimecode.convertTimeCodeToUnsignedLongLong2997(args.timecode, fileSampleRate) else: newTimeReference = pctimecode.convertTimeCodeToUnsignedLongLong30(args.timecode, fileSampleRate) wavefile.setTimeReference(newTimeReference) # Set the layout of the files for the iXML chunk suggestedTrackLayoutDictionary = {} if args.tracklayout is not None: suggestedTrackLayoutDictionary = {"suggestedTrackNameLayoutArray":layout[args.tracklayout]["trackNames"], "suggestedTrackFunctionLayoutArray":layout[args.tracklayout]["trackFunctions"]} xmlstring = xmlStringForWaveFile(wavefile, useDropFrame, args.framerate, suggestedTrackLayoutDictionary) # Check to see if we want to append the iXML to the file if args.noixml == False: wavefile.clearIXMLChunk() addiXMLToWaveFile(wavefile, xmlstring) # Write the iXML to stdout or file depending on the option if args.verbose == True: print "Sample Time Stamp:", newTimeReference prettyprintxml(xmlstring) elif args.outputfile is not None: with open(args.outputfile, 'w+') as f: f.write(xmlstring) else: print "file does not exist:", filename
def analyzeTwoPopInEighths(filePath): if not os.path.exists(filePath): return {"status":"fail", "resultString":"file doesn't exist", "warningString":""} wavefile = PCWaveFile(filePath) if wavefile.isValidWaveFile() != True: return {"status":"fail", "resultString":"file is not a wavefile"} dataStartPos = wavefile.getDataChunk()["chunkPosition"] dataLength = wavefile.getDataChunk()["chunkSize"] sampleRate = wavefile.numberOfSamplesPerSecond() timeCodeSampleRate = int(math.ceil(sampleRate * 1.001)) byteWidth = wavefile.numberOfBytesPerSample() numberOfChannels = wavefile.numberOfChannels() data_size = int(math.ceil(sampleRate * 1.001))/24 #1 second of audio dataStartPosOffset = 0 normalizedTimeStamp = wavefile.timestamp # currentPositionInFile = 0 dataLengthInSamples = dataLength / (numberOfChannels * byteWidth) # print "dataStartPosOffset",dataStartPosOffset toneStartTimeStamp = pctimecode.convertTimeCodeToUnsignedLongLong("00:57:30:00", timeCodeSampleRate, 24) popSafeStartTimeStamp = pctimecode.convertTimeCodeToUnsignedLongLong("00:59:57:00", timeCodeSampleRate, 24) hourOneTimeStamp = pctimecode.convertTimeCodeToUnsignedLongLong("01:00:00:00", timeCodeSampleRate, 24) # print "normalizedTimeStamp",normalizedTimeStamp # print "toneStartTimeStamp",toneStartTimeStamp #assume file starts at 00:57:30:00, in the case that the file doesn't have a bext extension #also gets into an issue of what to favor, bext over regn? I assume that the encoders user bext #as you couldn't reliably expect a regn chunk if normalizedTimeStamp == 0 or (normalizedTimeStamp % (timeCodeSampleRate * 60 * 60 * 24) == 0): normalizedTimeStamp = toneStartTimeStamp #we're going to read 3 seconds total secondsInSamplesToRead = 3 * timeCodeSampleRate # print "secondsInSamplesToRead",secondsInSamplesToRead #make sure that the timestamp starts on the second, otherwise normalize the timestamp normalizedTimestampOffset = wavefile.timestamp % timeCodeSampleRate if normalizedTimestampOffset > 0: dataStartPosOffset += (timeCodeSampleRate - normalizedTimestampOffset) * byteWidth * numberOfChannels normalizedTimeStamp = wavefile.timestamp + (timeCodeSampleRate - normalizedTimestampOffset) # print "(timeCodeSampleRate - normalizedTimestampOffset)", (timeCodeSampleRate - normalizedTimestampOffset) # print "normalizedTimestampOffset", normalizedTimestampOffset # print "dataStartPosOffset", dataStartPosOffset # print "normalizedTimeStamp", normalizedTimeStamp if normalizedTimeStamp > popSafeStartTimeStamp: # print 'if wavefile.timestamp > toneStartTimeStamp:' return {"status":"fail", "resultString":"timecode start exceeds pop location","warningString":""} if dataLengthInSamples < (hourOneTimeStamp - toneStartTimeStamp): return {"status":"fail", "resultString":"the file is too short", "warningString":""} if normalizedTimeStamp < popSafeStartTimeStamp: #seek to start time to analyze sampleDifference = (popSafeStartTimeStamp - normalizedTimeStamp) currentPositionInFile = sampleDifference + normalizedTimeStamp dataStartPosOffset += (sampleDifference * byteWidth * numberOfChannels) #lets only look at the 3 seconds of the file from 00:59:57:00 to 01:00:00:00 sizeToRead = secondsInSamplesToRead * byteWidth * numberOfChannels sizeToRead = sizeToRead if dataLength > sizeToRead else dataLength #this scans the head to make sure there is no signal in the head up to a sixteenth of frame before the pop headResult = preScanHead(filePath, data_size, dataStartPos, dataStartPosOffset, byteWidth, numberOfChannels, sampleRate) #this scans the tail to make sure there is no signal in the tail after an eighth of a frame after the pop nextByteOffset = (data_size * 25 * byteWidth * numberOfChannels) #seek 25 frames from the initial start which would be 59:58:01 tailResult = preScanTail(filePath, data_size, dataStartPos, (dataStartPosOffset + nextByteOffset), byteWidth, numberOfChannels, sampleRate) overallResult = {"status":"pass", "resultString":""} suppressSuperfluousWarnings = False if headResult['status'] == 'fail': overallResult['status'] = 'fail' overallResult["resultString"] += headResult["resultString"] if tailResult['status'] == 'fail': overallResult['status'] = 'fail' overallResult["resultString"] += tailResult["resultString"] if overallResult['status'] == 'pass': overallResult["resultString"] = "Pop area contains no discernable problems." twoPopCounter = TwoPopCounterAlt() twoPopCounter.timeCodeSampleRate = timeCodeSampleRate twoPopCounter.timeBase = 24 with open(filePath, 'rb') as f: f.seek(dataStartPos + dataStartPosOffset) dataToReadChunkSize = data_size*byteWidth*numberOfChannels dataRemaining = sizeToRead while dataRemaining > 0: if dataRemaining > dataToReadChunkSize: data = f.read(dataToReadChunkSize) else: data = f.read(dataRemaining) dataRemaining -= len(data) for channel in range(0, numberOfChannels): subdata = "" for x in range(channel*byteWidth,len(data),byteWidth*numberOfChannels): subdata += (data[x] + data[x+1] + data[x+2]) analysis = ultimateFreqAndPowerForData(subdata, byteWidth, sampleRate) twoPopCounter.addAnalysisForChannelAndTimeStamp(analysis, channel, currentPositionInFile) currentPositionInFile += data_size twoPopResult = twoPopCounter.result() #likely that the pop is off as we are checking an area of up to a sixteenth of frame prior to the pop and area an eighth of a frame #after the pop if overallResult['status'] == 'fail' and twoPopResult['status'] == 'pass': twoPopResult['status'] = 'fail' twoPopResult['resultString'] = "Check your pop as it is likely off. " + overallResult['resultString'] if overallResult['status'] == 'fail' and twoPopResult['status'] == 'fail' and twoPopResult['foundPop'] == 'pass': twoPopResult['status'] = 'fail' twoPopResult['resultString'] = "Check your pop as it is likely off. " + overallResult['resultString'] popIntegrityResult = {"status":"pass", "resultString":""} if overallResult['status'] == 'pass' and twoPopResult['status'] == 'pass' and twoPopResult['foundPop'] == 'pass': #lets make sure the pop actually starts consists of a frame nextByteOffset = (data_size * 23 * byteWidth * numberOfChannels) #seek 23 frames from the initial start which would be 59:57:23 popIntegrityResult = scanPop(filePath, data_size, dataStartPos, (dataStartPosOffset + nextByteOffset), byteWidth, numberOfChannels, sampleRate) if popIntegrityResult['status'] == 'fail': twoPopResult['status'] = 'fail' twoPopResult['resultString'] = popIntegrityResult['resultString'] return twoPopResult
def analyzeTwoPopAlt(filePath): if not os.path.exists(filePath): return {"status":"fail", "resultString":"file doesn't exist", "warningString":""} wavefile = PCWaveFile(filePath) if wavefile.isValidWaveFile() != True: return {"status":"fail", "resultString":"file is not a wavefile"} dataStartPos = wavefile.getDataChunk()["chunkPosition"] dataLength = wavefile.getDataChunk()["chunkSize"] sampleRate = wavefile.numberOfSamplesPerSecond() timeCodeSampleRate = int(math.ceil(sampleRate * 1.001)) byteWidth = wavefile.numberOfBytesPerSample() numberOfChannels = wavefile.numberOfChannels() data_size = int(math.ceil(sampleRate * 1.001))/24 #1 second of audio dataStartPosOffset = 0 normalizedTimeStamp = wavefile.timestamp # currentPositionInFile = 0 dataLengthInSamples = dataLength / (numberOfChannels * byteWidth) # print "dataStartPosOffset",dataStartPosOffset toneStartTimeStamp = pctimecode.convertTimeCodeToUnsignedLongLong("00:57:30:00", timeCodeSampleRate, 24) popSafeStartTimeStamp = pctimecode.convertTimeCodeToUnsignedLongLong("00:59:57:00", timeCodeSampleRate, 24) hourOneTimeStamp = pctimecode.convertTimeCodeToUnsignedLongLong("01:00:00:00", timeCodeSampleRate, 24) # print "normalizedTimeStamp",normalizedTimeStamp # print "toneStartTimeStamp",toneStartTimeStamp #assume file starts at 00:57:30:00, in the case that the file doesn't have a bext extension #also gets into an issue of what to favor, bext over regn? I assume that the encoders user bext #as you couldn't reliably expect a regn chunk if normalizedTimeStamp == 0: normalizedTimeStamp = toneStartTimeStamp #we're going to read 3 seconds total secondsInSamplesToRead = 3 * timeCodeSampleRate # print "secondsInSamplesToRead",secondsInSamplesToRead #make sure that the timestamp starts on the second, otherwise normalize the timestamp normalizedTimestampOffset = wavefile.timestamp % timeCodeSampleRate if normalizedTimestampOffset > 0: dataStartPosOffset += (timeCodeSampleRate - normalizedTimestampOffset) * byteWidth * numberOfChannels normalizedTimeStamp = wavefile.timestamp + (timeCodeSampleRate - normalizedTimestampOffset) # print "(timeCodeSampleRate - normalizedTimestampOffset)", (timeCodeSampleRate - normalizedTimestampOffset) # print "normalizedTimestampOffset", normalizedTimestampOffset # print "dataStartPosOffset", dataStartPosOffset # print "normalizedTimeStamp", normalizedTimeStamp if normalizedTimeStamp > popSafeStartTimeStamp: # print 'if wavefile.timestamp > toneStartTimeStamp:' return {"status":"fail", "resultString":"timecode start exceeds pop location","warningString":""} if dataLengthInSamples < (hourOneTimeStamp - toneStartTimeStamp): return {"status":"fail", "resultString":"the file is too short", "warningString":""} if normalizedTimeStamp < popSafeStartTimeStamp: # print 'if wavefile.timestamp < toneStartTimeStamp:' sampleDifference = (popSafeStartTimeStamp - normalizedTimeStamp) currentPositionInFile = sampleDifference + normalizedTimeStamp dataStartPosOffset += (sampleDifference * byteWidth * numberOfChannels) #lets only look at the 3 seconds of the file from 00:59:57:00 to 01:00:00:00 sizeToRead = secondsInSamplesToRead * byteWidth * numberOfChannels sizeToRead = sizeToRead if dataLength > sizeToRead else dataLength # print "sizeToRead",sizeToRead with open(filePath, 'rb') as f: f.seek(dataStartPos + dataStartPosOffset) dataToReadChunkSize = data_size*byteWidth*numberOfChannels dataRemaining = sizeToRead twoPopCounter = TwoPopCounterAlt() twoPopCounter.timeCodeSampleRate = timeCodeSampleRate twoPopCounter.timeBase = 24 while dataRemaining > 0: if dataRemaining > dataToReadChunkSize: data = f.read(dataToReadChunkSize) else: data = f.read(dataRemaining) dataRemaining -= len(data) for channel in range(0, numberOfChannels): subdata = "" for x in range(channel*byteWidth,len(data),byteWidth*numberOfChannels): subdata += (data[x] + data[x+1] + data[x+2]) analysis = ultimateFreqAndPowerForData(subdata, byteWidth, sampleRate) twoPopCounter.addAnalysisForChannelAndTimeStamp(analysis, channel, currentPositionInFile) currentPositionInFile += data_size return twoPopCounter.result()
def analyzeHeadAlt(filePath): if os.path.exists(filePath): wavefile = PCWaveFile(filePath) if wavefile.isValidWaveFile() != True: return {"status":"fail", "resultString":"file is not a wavefile"} dataStartPos = wavefile.getDataChunk()["chunkPosition"] dataLength = wavefile.getDataChunk()["chunkSize"] sampleRate = wavefile.numberOfSamplesPerSecond() timeCodeSampleRate = int(math.ceil(sampleRate * 1.001)) byteWidth = wavefile.numberOfBytesPerSample() numberOfChannels = wavefile.numberOfChannels() data_size = int(math.ceil(sampleRate * 1.001)) #1 second of audio dataLengthInSamples = dataLength / (numberOfChannels * byteWidth) dataStartPosOffset = 0 normalizedTimeStamp = wavefile.timestamp # # print "dataStartPosOffset",dataStartPosOffset toneStartTimeStamp = pctimecode.convertTimeCodeToUnsignedLongLong("00:57:30:00", timeCodeSampleRate, 24) # print "normalizedTimeStamp",normalizedTimeStamp # print "toneStartTimeStamp",toneStartTimeStamp #assume file starts at 00:57:30:00, in the case that the file doesn't have a bext extension #also gets into an issue of what to favor, bext over regn? I assume that the encoders user bext #as you couldn't reliably expect a regn chunk if normalizedTimeStamp == 0 or (normalizedTimeStamp % (timeCodeSampleRate * 60 * 60 * 24) == 0) : normalizedTimeStamp = toneStartTimeStamp #the head length should be 150 seconds secondsInSamplesToRead = 150 * timeCodeSampleRate # print "secondsInSamplesToRead",secondsInSamplesToRead if secondsInSamplesToRead > dataLengthInSamples: return {"status":"fail", "resultString":"the file is too short", "warningString":""} #make sure that the timestamp starts on the second, otherwise normalize the timestamp normalizedTimestampOffset = wavefile.timestamp % timeCodeSampleRate if normalizedTimestampOffset > 0: dataStartPosOffset += (timeCodeSampleRate - normalizedTimestampOffset) * byteWidth * numberOfChannels normalizedTimeStamp = wavefile.timestamp + (timeCodeSampleRate - normalizedTimestampOffset) # print "(timeCodeSampleRate - normalizedTimestampOffset)", (timeCodeSampleRate - normalizedTimestampOffset) # print "normalizedTimestampOffset", normalizedTimestampOffset # print "dataStartPosOffset", dataStartPosOffset # print "normalizedTimeStamp", normalizedTimeStamp if normalizedTimeStamp > toneStartTimeStamp: # print 'if wavefile.timestamp > toneStartTimeStamp:' secondsInSamplesToRead -= (normalizedTimeStamp - toneStartTimeStamp) if normalizedTimeStamp < toneStartTimeStamp: # print 'if wavefile.timestamp < toneStartTimeStamp:' secondsInSamplesToRead += (toneStartTimeStamp - normalizedTimeStamp) #lets only look at the first 150 seconds of the file sizeToRead = secondsInSamplesToRead * byteWidth * numberOfChannels sizeToRead = sizeToRead if dataLength > sizeToRead else dataLength second = 0 with open(filePath, 'rb') as f: startTime = datetime.datetime.now() dataStartPos += dataStartPosOffset f.seek(dataStartPos) dataToReadChunkSize = timeCodeSampleRate*byteWidth*numberOfChannels dataRemaining = sizeToRead counterDict = {} for channel in range(0, numberOfChannels): counterDict[str(channel)] = ToneCounterAlt() while dataRemaining > 0: if dataRemaining > dataToReadChunkSize: data = f.read(dataToReadChunkSize) else: data = f.read(dataRemaining) dataRemaining -= len(data) currentPositionInFile = normalizedTimeStamp + (second * data_size) # print currentPositionInFile, pctimecode.convertUnsignedLongLongToTimeCode(currentPositionInFile, 48048, 24) for channel in range(0, numberOfChannels): subdata = "" for x in range(channel*byteWidth,len(data),byteWidth*numberOfChannels): subdata += (data[x] + data[x+1] + data[x+2]) result = highestAndNextHighestFreqAndPowerForData(subdata, byteWidth, sampleRate) toneCounter = counterDict[str(channel)] toneCounter.addAnalysis({ "currentTimeStamp":currentPositionInFile, "timeCodeSampleRate":timeCodeSampleRate, "freqs":result, "RMSForInputData":calculateRMSForData(subdata, byteWidth)}) second += 1 #Questions to answer 1) Does it have at least 60 secs of tone 2) Does it start at head 3) Does it have a Pop 4) Does it have other tones? toneCounterResult = ToneCounterResultAlt(timeCodeSampleRate, 24) return toneCounterResult.result(counterDict) else: return {"status":"fail", "resultString":"file doesn't exist","warningString":""}
def formatInformationForFile(filePath): wavefile = PCWaveFile(filePath) if wavefile == None or wavefile.isValidWaveFile() == False: badInfo = {} badInfo["fileName"] = os.path.basename(filePath) badInfo["fullPath"] = filePath badInfo["bitDepth"] = 0 badInfo["sampleRate"] = 0 badInfo["bextChunk"] = False badInfo["timeStamp"] = 0 badInfo["timeStampTC"] = "00:00:00:00" badInfo["regnChunk"] = False badInfo["channelCount"] = 0 badInfo["status"] = 'fail' badInfo["errors"] = [ "{} is not a wave file.".format(os.path.basename(filePath)), ] badInfo['fileLevels'] = { 'status': 'fail', 'layout': 'unknown', "warningString": "" } badInfo['headTones'] = { 'status': 'fail', 'resultString': 'Unable to analyze head tones on account of invalid format.', "warningString": "" } badInfo['pops'] = { 'status': 'fail', 'resultString': 'Unable to analyze pops on account of invalid format.', "warningString": "" } return badInfo info = {} info['fileName'] = os.path.basename(filePath) info['fullPath'] = filePath info['bitDepth'] = wavefile.numberOfBitsPerSample() info['sampleRate'] = wavefile.numberOfSamplesPerSecond() info['bextChunk'] = True if wavefile.hasBextChunk() else False info['timeStamp'] = wavefile.timestamp info['timeStampTC'] = prettyTimeCode2398(wavefile.timestamp, info['sampleRate']) info['regnChunk'] = True if wavefile.hasBextChunk() else False if wavefile.hasRegnChunk() == True: info['regnChunkUserTimeStamp'] = wavefile.regnChunkInfoDict[ 'userTimeStamp'] info['regnChunkOriginalTimeStamp'] = wavefile.regnChunkInfoDict[ 'originalTimeStamp'] info['channelCount'] = wavefile.numberOfChannels() if info['bitDepth'] != 24 or info['sampleRate'] != 48000: info['fileLevels'] = { 'status': 'fail', 'layout': 'unknown', "warningString": "" } info['headTones'] = { 'status': 'fail', 'resultString': 'Unable to analyze head tones on account of invalid format.', "warningString": "" } info['pops'] = { 'status': 'fail', 'resultString': 'Unable to analyze pops on account of invalid format.', "warningString": "" } else: info['fileLevels'] = analyzeLevels(filePath) info['headTones'] = analyzeHeadAlt(filePath) info['pops'] = analyzeTwoPopInEighths(filePath) return addStatusToInformation(info)