示例#1
0
def infoTest():
	try:
		filename = sys.argv[1]
		if os.path.exists(filename):
			wavefile = PCWaveFile(filename)
			wavefile.info()
		else:
			print "The file",filename,"doesn't exist"
	except:
		print "No file was passed in as a variable"	
示例#2
0
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"
示例#3
0
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"
示例#4
0
def listOfTimeCodeValuesForFile(fullpath):
	wavefile = PCWaveFile(fullpath)
	if wavefile.isValidWaveFile() == False:
		print 'File is not valid'
		return

	tcList = []
	sampleRate = wavefile.fmtChunkInfoDict['nSamplesPerSec']
	tcList.append(wavefile.timestamp)
	tcList.append(pctimecode.convertUnsignedLongLongToTimeCode(wavefile.timestamp, sampleRate*1.001, 24)) 	#23976
	tcList.append(pctimecode.convertUnsignedLongLongToTimeCode(wavefile.timestamp, sampleRate, 24))			#24
	tcList.append(pctimecode.convertUnsignedLongLongToTimeCode(wavefile.timestamp, sampleRate, 25))			#25
	tcList.append(pctimecode.convertUnsignedLongLongToTimeCode(wavefile.timestamp, sampleRate*1.001, 30)) 	#2997
	tcList.append(pctimecode.convertUnsignedLongLongToTimeCode(wavefile.timestamp, sampleRate, 30))			#30	
	return tcList	
示例#5
0
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"
示例#6
0
def trackLayoutTest():

    parser = argparse.ArgumentParser(
        description="Set Timecode for a Broadcast Wave File")
    parser.add_argument("filename",
                        help="the file to process, represented as a path")
    parser.add_argument('-l',
                        '--tracklayout',
                        dest="tracklayout",
                        help="a tracklayout confirguration for the iXML file",
                        choices=tracklayouts.tracklayoutRepresentation())
    args = parser.parse_args()

    filename = args.filename
    layout = tracklayouts.tracklayouts

    if os.path.exists(filename):
        wavefile = PCWaveFile(filename)

        suggestedTrackLayoutDictionary = {}
        if args.tracklayout is not None:
            suggestedTrackLayoutDictionary = {
                "suggestedTrackNameLayoutArray":
                layout[args.tracklayout]["trackNames"],
                "suggestedTrackFunctionLayoutArray":
                layout[args.tracklayout]["trackFunctions"]
            }

        xmlstring = xmlStringForWaveFile(wavefile, True, "2997",
                                         suggestedTrackLayoutDictionary)
        # addiXMLToWaveFile(wavefile, xmlstring)
        print xmlstring
    else:
        print "file does not exist:", filename
示例#7
0
def examine():
	filePath = None
	try:
		filePath = sys.argv[1]
	except Exception:
		print "No file specified"
		return

	if os.path.isdir(filePath):
		for path, dirs, files in os.walk(filePath):
		    for name in files:
		    	fullpath = os.path.join(path, name)
		    	wavefile = PCWaveFile(fullpath)
		    	formatInformationForFile(wavefile)
	else:
		wavefile = PCWaveFile(filePath)
		formatInformationForFile(wavefile)	
示例#8
0
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"                
示例#9
0
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"         
示例#10
0
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"         
示例#11
0
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"     
示例#12
0
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)
示例#13
0
def clearChunkWithName(name):
	filePath = None
	try:
		filePath = sys.argv[1]
	except Exception:
		print "No file specified"
		return

	if os.path.isdir(filePath):
		for path, dirs, files in os.walk(filePath):
		    for name in files:
		    	fullpath = os.path.join(path, name)
		    	wavefile = PCWaveFile(fullpath)
		    	wavefile.clearChunk(name)
	else:
		wavefile = PCWaveFile(filePath)
		wavefile.clearChunk(name)
示例#14
0
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" 
示例#15
0
def timeCodeDisplayTest(sampleRate=48000):
	try:
		filename = sys.argv[1]
		if os.path.exists(filename):
			wavefile = PCWaveFile(filename)
			print wavefile.filePath
			print "23.976\t\t", pctimecode.convertUnsignedLongLongToTimeCode(wavefile.timestamp, sampleRate*1.001, 24)
			print "24\t\t", pctimecode.convertUnsignedLongLongToTimeCode(wavefile.timestamp, sampleRate, 24)
			print "25\t\t", pctimecode.convertUnsignedLongLongToTimeCode(wavefile.timestamp, sampleRate, 25)
			print "29.97\t\t", pctimecode.convertUnsignedLongLongToTimeCode(wavefile.timestamp, sampleRate*1.001, 30)
			print "30\t\t", pctimecode.convertUnsignedLongLongToTimeCode(wavefile.timestamp, sampleRate, 30)	
			print wavefile.regnChunkInfoDict
			print wavefile.timestamp

		else:
			print "The file",filename,"doesn't exist"
	except:
		print "No file was passed in as a variable"
示例#16
0
def test():

    try:
        filename = sys.argv[1]
    except:
        print "No file was specified"
        return

    if os.path.exists(filename):
        wavefile = PCWaveFile(filename)

        suggestedTrackLayoutDictionary = {}

        xmlstring = xmlStringForWaveFile(wavefile, True, "2997",
                                         suggestedTrackLayoutDictionary)
        # addiXMLToWaveFile(wavefile, xmlstring)
        print xmlstring
    else:
        print "file does not exist:", filename
示例#17
0
def main():
    filePath = None
    results = []
    try:
        filePath = sys.argv[1]
    except Exception:
        print "No file specified"
        return

    if os.path.isdir(filePath):
        for path, dirs, files in os.walk(filePath):
            for name in files:
                fullpath = os.path.join(path, name)
                results.append(formatInformationForFile(fullpath))
    else:
        wavefile = PCWaveFile(filePath)
        results.append(formatInformationForFile(filePath))

    #display the results to the screen in case of single file
    if os.path.isdir(filePath):
        resultFile = os.path.join(filePath, 'resultFile.json')
        writeDataToFile(resultFile, prettyPrintJSON({"results": results}))
    else:
        print prettyPrintJSON({"results": results})
示例#18
0
def showNonStandardChunks():
	filePath = None
	try:
		filePath = sys.argv[1]
	except Exception:
		print "No file specified"
		return

	if os.path.isdir(filePath):
		for path, dirs, files in os.walk(filePath):
		    for name in files:
		    	fullpath = os.path.join(path, name)
		    	wavefile = PCWaveFile(fullpath)
		    	for chunk in wavefile.allChunks():
		    		if chunk['chunkName'] in ['minf','elm1', 'regn','umid','DGDA']:
		    			print chunk
		    	print "\n"
	else:
		wavefile = PCWaveFile(filePath)
		for chunk in wavefile.allChunks():
			if chunk['chunkName'] in ['minf','elm1', 'regn','umid','DGDA']:
				print chunk				
示例#19
0
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":""} 
示例#20
0
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)
示例#21
0
def analyzeLevels(filePath):
	wavefile = None

	if os.path.exists(filePath):
		wavefile = PCWaveFile(filePath)
	else:
		return

	if wavefile == None or wavefile.isValidWaveFile() == False:
		return {"status":"fail", "resultString":"file is not a wavefile", "layout":"Unknown", "warningString":""} 

	sampleRate = wavefile.fmtChunkInfoDict['nSamplesPerSec']
	channelByteWidth = wavefile.fmtChunkInfoDict['wBitsPerSample'] / 8
	bitsPerSample = wavefile.fmtChunkInfoDict['wBitsPerSample']
	numberOfChannels = wavefile.fmtChunkInfoDict['nChannels']
	packetByteWidth = channelByteWidth * numberOfChannels

	for title in ['MEHELP']:
		if title.lower() in filePath.lower():
			layout = 'MONO' if numberOfChannels == 1 else 'MULTI-MONO'
			return {"status":"pass", "resultString":"The file contains {} in its file name and will not be analyzed.".format(title), "layout":layout, "warningString":""}

	if numberOfChannels != 6:
		if numberOfChannels == 2:
			return {"status":"pass", "resultString":"File contains {} audio channels".format(numberOfChannels), "layout":"STEREO", "warningString":""}
		else:
			return {"status":"pass", "resultString":"File contains {} audio channels".format(numberOfChannels), "layout":"Unknown", "warningString":""} 	 			

	isSigned = True
	if channelByteWidth == 1:
		isSigned = False

	chunkPosition = wavefile.getDataChunk()['chunkPosition']
	numberOfSamples = wavefile.getDataChunk()['chunkSize'] / packetByteWidth

	#open the file, read through the packets and do a running mean of each track in the file
	#what this does do is ASSUME that the input file is 24 bit signed data, otherwise 16 bit would be signed, but 8 bit wouldn't
	#not that 8 bit is an issue

	with open(filePath, 'rb') as f:
		f.seek(chunkPosition)

		blockWidthInSeconds = 4
		samplesToReadBlockSize = (sampleRate * blockWidthInSeconds)
		numberOfSamplesRemaining = numberOfSamples
		bufferAmount = samplesToReadBlockSize if numberOfSamples > samplesToReadBlockSize else numberOfSamples
		
		totalBlocksInFile = numberOfSamplesRemaining // samplesToReadBlockSize
		shouldReadEntireFile = False
		analysisSpacing = 0
		numberOfAnalyses = 34
		initialAnalyses = 0

		if totalBlocksInFile < (2 * numberOfAnalyses):
			shouldReadEntireFile = True
		else:
			analysisSpacing = totalBlocksInFile / numberOfAnalyses

		startTime = datetime.datetime.now()
		constantBitDepth16 = pow(2,15)
		constantBitDepth24 = pow(2,23)
		#totalsCounter = RunningTotalCounter(pow(2,(bitsPerSample-1)), samplesToReadBlockSize, numberOfChannels)
		totalsCounter = RunningTotalCounter(constantBitDepth16, samplesToReadBlockSize, numberOfChannels)
		# you need to constrain the size of the input as we will be calculating RMS values which require exponential math

		
		while numberOfSamplesRemaining > 0:
			#read a buffer's amount of samples
			if numberOfSamplesRemaining > bufferAmount:

				bytesToRead = packetByteWidth * bufferAmount 
				data = f.read(bytesToRead)
				numberOfSamplesRemaining -= (len(data)/packetByteWidth)

				if len(data) != bytesToRead:
					logging.error("IO Error: bytes returned do not match bytes asked for")

				#read a buffer's amount of samples
				analysis = totalsCounter.emptyAnalysisDictionary()

				# read the file or current analysis into memory and sum all of the samples and raise to the 2nd pow
				if shouldReadEntireFile == True or (initialAnalyses % analysisSpacing == 0):
					for i in range(0, bytesToRead, packetByteWidth):
						subdata = data[i:(i+packetByteWidth)]
						for chPos in range(0, numberOfChannels):
							trackoffset = chPos * channelByteWidth
							extendedValue = les24toles32Value(''.join(subdata[trackoffset:trackoffset+channelByteWidth]))
							extendedValue = int(((1.0 * extendedValue) / constantBitDepth24) * constantBitDepth16)
							analysis[str(chPos)] += (extendedValue**2)

					totalsCounter.addAnalysis(analysis)

				initialAnalyses += 1

			else:
				data = f.read(packetByteWidth * numberOfSamplesRemaining)
				numberOfSamplesRemaining = 0

		return totalsCounter.performAnalysis()
示例#22
0
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
示例#23
0
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 analyzeTrackCorrelations(filePath):
    wavefile = None

    if os.path.exists(filePath):
        wavefile = PCWaveFile(filePath)
    else:
        return

    if wavefile == None or wavefile.isValidWaveFile() == False:
        return {
            "status": "fail",
            "resultString": "file is not a wavefile",
            "layout": "Unknown"
        }

    sampleRate = wavefile.fmtChunkInfoDict['nSamplesPerSec']
    channelByteWidth = wavefile.fmtChunkInfoDict['wBitsPerSample'] / 8
    bitsPerSample = wavefile.fmtChunkInfoDict['wBitsPerSample']
    numberOfChannels = wavefile.fmtChunkInfoDict['nChannels']
    packetByteWidth = channelByteWidth * numberOfChannels

    if numberOfChannels != 6:
        if numberOfChannels == 2:
            return {
                "status":
                "pass",
                "resultString":
                "File contains {} audio channels".format(numberOfChannels),
                "layout":
                "STEREO"
            }
        else:
            return {
                "status":
                "pass",
                "resultString":
                "File contains {} audio channels".format(numberOfChannels),
                "layout":
                "Unknown"
            }

    isSigned = True
    if channelByteWidth == 1:
        isSigned = False

    chunkPosition = wavefile.getDataChunk()['chunkPosition']
    numberOfSamples = wavefile.getDataChunk()['chunkSize'] / packetByteWidth

    #open the file, read through the packets and do a running mean of each track in the file
    #what this does do is ASSUME that the input file is 24 bit signed data, otherwise 16 bit would be signed, but 8 bit wouldn't
    #not that 8 bit is an issue

    with open(filePath, 'rb') as f:
        f.seek(chunkPosition)

        blockWidthInSeconds = 1
        samplesToReadBlockSize = (sampleRate * blockWidthInSeconds) / 2
        numberOfSamplesRemaining = numberOfSamples
        bufferAmount = samplesToReadBlockSize if numberOfSamples > samplesToReadBlockSize else numberOfSamples

        totalBlocksInFile = numberOfSamplesRemaining // samplesToReadBlockSize
        shouldReadEntireFile = False
        analysisSpacing = 0
        numberOfAnalyses = 34
        initialAnalyses = 0

        if totalBlocksInFile < (2 * numberOfAnalyses):
            shouldReadEntireFile = True
        else:
            analysisSpacing = totalBlocksInFile / numberOfAnalyses

        startTime = datetime.datetime.now()
        constantBitDepth16 = pow(2, 15)
        constantBitDepth24 = pow(2, 23)
        #totalsCounter = RunningTotalCounter(pow(2,(bitsPerSample-1)), samplesToReadBlockSize, numberOfChannels)
        totalsCounter = RunningTotalCounter(constantBitDepth16,
                                            samplesToReadBlockSize,
                                            numberOfChannels)
        # you need to constrain the size of the input as we will be calculating RMS values which require exponential math

        while numberOfSamplesRemaining > 0:
            #read a buffer's amount of samples
            if numberOfSamplesRemaining > bufferAmount:

                bytesToRead = packetByteWidth * bufferAmount
                data = f.read(bytesToRead)
                numberOfSamplesRemaining -= (len(data) / packetByteWidth)

                if len(data) != bytesToRead:
                    logging.error(
                        "IO Error: bytes returned do not match bytes asked for"
                    )

                #read a buffer's amount of samples
                analysis = {}
                for i in range(0, numberOfChannels):
                    analysis[str(i)] = []

                # read the file or current analysis into memory and sum all of the samples and raise to the 2nd pow
                if shouldReadEntireFile == True or (initialAnalyses %
                                                    analysisSpacing == 0):
                    for i in range(0, bytesToRead, packetByteWidth):
                        subdata = data[i:(i + packetByteWidth)]
                        for chPos in range(0, numberOfChannels):
                            trackoffset = chPos * channelByteWidth
                            extendedValue = les24toles32Value(''.join(
                                subdata[trackoffset:trackoffset +
                                        channelByteWidth]))
                            extendedValue = int(
                                ((1.0 * extendedValue) / constantBitDepth24) *
                                constantBitDepth16)
                            analysis[str(chPos)].append(extendedValue)

                    maxValue = 0
                    track = 0
                    srcTrack = '0'
                    for i in [0, 1, 2, 3, 4, 5]:
                        if int(srcTrack) == i:
                            continue
                        result = np.cov(analysis[srcTrack],
                                        analysis[str(i)])[0, 1]
                        if result > maxValue:
                            maxValue = result
                            track = i

                    print srcTrack, "matches", track, "with", maxValue

                initialAnalyses += 1

            else:
                data = f.read(packetByteWidth * numberOfSamplesRemaining)
                numberOfSamplesRemaining = 0

        return {"OK": "OK"}
def analyzeTrackCorrelations(filePath):
	wavefile = None

	if os.path.exists(filePath):
		wavefile = PCWaveFile(filePath)
	else:
		return

	if wavefile == None or wavefile.isValidWaveFile() == False:
		return {"status":"fail", "resultString":"file is not a wavefile", "layout":"Unknown"} 

	sampleRate = wavefile.fmtChunkInfoDict['nSamplesPerSec']
	channelByteWidth = wavefile.fmtChunkInfoDict['wBitsPerSample'] / 8
	bitsPerSample = wavefile.fmtChunkInfoDict['wBitsPerSample']
	numberOfChannels = wavefile.fmtChunkInfoDict['nChannels']
	packetByteWidth = channelByteWidth * numberOfChannels

	if numberOfChannels != 6:
		if numberOfChannels == 2:
			return {"status":"pass", "resultString":"File contains {} audio channels".format(numberOfChannels), "layout":"STEREO"}
		else:
			return {"status":"pass", "resultString":"File contains {} audio channels".format(numberOfChannels), "layout":"Unknown"} 	 

	isSigned = True
	if channelByteWidth == 1:
		isSigned = False

	chunkPosition = wavefile.getDataChunk()['chunkPosition']
	numberOfSamples = wavefile.getDataChunk()['chunkSize'] / packetByteWidth

	#open the file, read through the packets and do a running mean of each track in the file
	#what this does do is ASSUME that the input file is 24 bit signed data, otherwise 16 bit would be signed, but 8 bit wouldn't
	#not that 8 bit is an issue

	with open(filePath, 'rb') as f:
		f.seek(chunkPosition)

		blockWidthInSeconds = 1
		samplesToReadBlockSize = (sampleRate * blockWidthInSeconds)/2
		numberOfSamplesRemaining = numberOfSamples
		bufferAmount = samplesToReadBlockSize if numberOfSamples > samplesToReadBlockSize else numberOfSamples
		
		totalBlocksInFile = numberOfSamplesRemaining // samplesToReadBlockSize
		shouldReadEntireFile = False
		analysisSpacing = 0
		numberOfAnalyses = 34
		initialAnalyses = 0

		if totalBlocksInFile < (2 * numberOfAnalyses):
			shouldReadEntireFile = True
		else:
			analysisSpacing = totalBlocksInFile / numberOfAnalyses

		startTime = datetime.datetime.now()
		constantBitDepth16 = pow(2,15)
		constantBitDepth24 = pow(2,23)
		#totalsCounter = RunningTotalCounter(pow(2,(bitsPerSample-1)), samplesToReadBlockSize, numberOfChannels)
		totalsCounter = RunningTotalCounter(constantBitDepth16, samplesToReadBlockSize, numberOfChannels)
		# you need to constrain the size of the input as we will be calculating RMS values which require exponential math

		
		while numberOfSamplesRemaining > 0:
			#read a buffer's amount of samples
			if numberOfSamplesRemaining > bufferAmount:

				bytesToRead = packetByteWidth * bufferAmount 
				data = f.read(bytesToRead)
				numberOfSamplesRemaining -= (len(data)/packetByteWidth)

				if len(data) != bytesToRead:
					logging.error("IO Error: bytes returned do not match bytes asked for")

				#read a buffer's amount of samples
				analysis = {}
				for i in range(0,numberOfChannels):
					analysis[str(i)] = []

				# read the file or current analysis into memory and sum all of the samples and raise to the 2nd pow
				if shouldReadEntireFile == True or (initialAnalyses % analysisSpacing == 0):
					for i in range(0, bytesToRead, packetByteWidth):
						subdata = data[i:(i+packetByteWidth)]
						for chPos in range(0, numberOfChannels):
							trackoffset = chPos * channelByteWidth
							extendedValue = les24toles32Value(''.join(subdata[trackoffset:trackoffset+channelByteWidth]))
							extendedValue = int(((1.0 * extendedValue) / constantBitDepth24) * constantBitDepth16)
							analysis[str(chPos)].append(extendedValue)

					maxValue = 0
					track = 0
					srcTrack = '0'
					for i in [0,1,2,3,4,5]:
						if int(srcTrack) == i:
							continue
						result = np.cov(analysis[srcTrack], analysis[str(i)])[0,1]
						if result > maxValue:
							maxValue = result
							track = i

					print srcTrack, "matches", track, "with", maxValue
					

				initialAnalyses += 1

			else:
				data = f.read(packetByteWidth * numberOfSamplesRemaining)
				numberOfSamplesRemaining = 0

		return {"OK":"OK"}
示例#26
0
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()