示例#1
0
def calculateRMSForData(inputData, byteWidth):
    maxValueForInputData = 2**((byteWidth*8)-1)
    sampleData = []
    for i in range(0,len(inputData), byteWidth):
        try:
            sampleData.append(les24toles32Value(inputData[i:i+byteWidth]) * 1.0/maxValueForInputData)
        except Exception as e:
            print e.message

    signalPower = np.sum(np.power(sampleData,2))
    rms = math.sqrt(signalPower/(len(inputData)/byteWidth))
    return dbRepresentation(rms)
示例#2
0
def ultimateFreqAndPowerForData(inputData, byteWidth, sampleRate):
    ### this must be refactored for the appropiate type of data
    ### for signed data
    maxValueForInputData = 2**((byteWidth*8)-1)
    sampleData = []
    for i in range(0,len(inputData), byteWidth):
        try:
            sampleData.append(les24toles32Value(inputData[i:i+byteWidth]) * 1.0/maxValueForInputData)
        except Exception as e:
            print e.message

    signal = np.array(sampleData)

    signalPower = np.sum(np.power(signal,2))
    rms = math.sqrt(signalPower/(len(inputData)/byteWidth))
    highestdbRep = dbRepresentation(rms)

    # Compute Fourier transform of windowed signal
    windowed = signal * blackmanharris(len(signal))
    f = np.fft.rfft(windowed)
    # Find the peak and interpolate to get a more accurate peak
    i = np.argmax(abs(f)) # Just use this for less-accurate, naive version

    try:
        #defensive code around divide by zero issue, basically creating noise
        np.seterr(all='ignore')    
        a = np.arange(len(f), dtype=np.float)
        a.fill(10**-10)
        nf = np.where(f == 0., a, f)
        i = i if i != 0. else 10**-10
        if i > len(nf)-2:
            i = len(nf) -2
        true_i = parabolic(np.log(abs(nf)), i)[0]  
        # Convert to equivalent frequency
        freqHz =  (sampleRate * true_i / len(windowed))
    except ValueError:
        freqHz = 0.0

    return {"mainFreq":{"freqHz":freqHz, "dbRep":highestdbRep}, "nextFreq":{"freqHz":"0", "dbRep":"0"}}
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"}
示例#4
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()
示例#5
0
def highestAndNextHighestFreqAndPowerForData(inputData, byteWidth, sampleRate):
    ### this must be refactored for the appropiate type of data
    ### for signed data
    maxValueForInputData = 2**((byteWidth*8)-1)
    sampleData = []
    for i in range(0,len(inputData), byteWidth):
        try:
            sampleData.append(les24toles32Value(inputData[i:i+byteWidth]) * 1.0/maxValueForInputData)
        except Exception as e:
            print e.message

    ### take sample data and make numpy array from which we take the fft and keep the lower half of the data
    ### I am not applying a window
    data = np.array(sampleData)
    p = np.fft.fft(data)
    uniquePts = math.ceil(len(data)/2.0) + 1.0 
    p = p[0:uniquePts]
    freqs = np.fft.fftfreq(len(data))

    #### Find the peak in the coefficients
    idx = np.argmax(np.abs(p)**2)
    freq = freqs[idx]
    freqHz = abs(freq*sampleRate)

    ### Find the next highest peak which should exclude a nice band around the frequency of interest
    ### high end
    ### since we can be certain that each frequency band has a resolution of 1 Hz
    ### I can calculate the 1/3 octave frequency by using the idx
    upperBand = idx * pow(2,1.0/6)
    safeIdx = upperBand if upperBand < len(p) else idx
    pNext = p[safeIdx:len(p)-safeIdx]
    if len(pNext) > 0:
        idxNext = np.argmax(np.abs(pNext)**2)
        idxNext += safeIdx
        nextHighest = idxNext
    else:
        nextHighest = 0

    ### low end
    lowerBand = idx / pow(2,1.0/6)
    safeIdx = lowerBand if lowerBand > 1 else idx
    pNext = p[0:safeIdx]
    if len(pNext) > 0:
        idxNext = np.argmax(np.abs(pNext)**2)
    else:
        idxNext = 0

    if abs(p[idxNext]) > abs(p[nextHighest]):
        nextHighest = idxNext

    nextHighestFreq = freqs[nextHighest]
    nextHighestFreqHz = abs(nextHighestFreq*sampleRate)

    ### normalize fft length
    p = np.divide(p,float(len(data)))
    p = np.abs(p)
    p = np.power(p,2)

    ### make up for the power loss we deleted the the right side of the fft
    if len(data) % 2 > 0:
        p[1:len(p)] = np.multiply(p[1:len(p)], 2)
    else:
        p[1:len(p) - 1] = np.multiply(p[1:len(p) -1], 2)

    ### calculate the power of the highest frequency index
    rms = math.sqrt(p[idx])
    dataLength = (len(inputData)/byteWidth)
    hightestdbRep = dbRepresentation(rms)
    highestFreqDict = {"freqHz":freqHz, "dbRep":hightestdbRep}

    ### calculate the power of the next highest frequency index
    rmsNext = math.sqrt(p[nextHighest])
    dataLength = (len(inputData)/byteWidth)
    nextHighestdbRep = dbRepresentation(rmsNext)
    nextHighestFreqDict = {"freqHz":nextHighestFreqHz, "dbRep":nextHighestdbRep}

    return {"mainFreq":highestFreqDict, "nextFreq":nextHighestFreqDict}
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"}