hi, plz can u help me with the code for python for this
views:
141answers:
3This would be extremely difficult, I don't believe it's been done in any language. It may be being investigated in the research departments of a university or two, but probably only in the most basic way (one instrument at a time, known instruments). Essentially, for now, not possible. (P.S., I'm not about to write the Python code for you).
Discriminating instruments from a waveform (as opposed to a MIDI) is a very challenging task. You would need to apply a Fourier transform to obtain frequency and phase data, then attempt to match that to the instrument characteristics.
If there are multiple instruments this becomes exponentially more difficult, but I bet with a little work you could determine what instruments are playing in solo pieces using numpy
and some sound libraries.
MIDIs, on the other hand, have the instrument data plainly available; if you grab any MIDI library you can scan the file for notes.
Here is some code to get you started.
:)
import sys, wave, audioop
class AudioAnalysis:
BITS_PER_BYTE = 8
FRAME_BUFFER_SIZE = 16384
FRAMES_PER_SECOND = 25
POWER_MAX = 32768
POWER_MIN = 0
__filename = ''
__powerMin = POWER_MAX
__powerMax = POWER_MIN
__samplePowerMin = POWER_MIN
__samplePowerMax = POWER_MAX
__frameInterval = 1.0 / FRAMES_PER_SECOND
__frameRate = 0
__samples = 0
__sampleWidth = 0
__channels = 0
__framePower = []
def __init__( self, filename ):
self.setFilename( filename )
def setFilename( self, filename ):
self.__filename = filename
def getFilename( self ):
return self.__filename
def getFileType( self ):
return str.split( self.getFilename(), '.' )[ -1 ].lower()
def setPowerMin( self, power ):
self.__powerMin = power
def getPowerMin( self ):
return self.__powerMin
def setPowerMax( self, power ):
self.__powerMax = power
def getPowerMax( self ):
return self.__powerMax
def setSamplePowerMax( self, power ):
self.__samplePowerMax = power
def getSamplePowerMax( self ):
return self.__samplePowerMax
def setSamplePowerMin( self, power ):
self.__samplePowerMin = power
def getSamplePowerMin( self ):
return self.__samplePowerMin
def setFrameRate( self, rate ):
self.__frameRate = rate
def getFrameRate( self ):
return self.__frameRate
def setSamples( self, samples ):
self.__samples = samples
def getSamples( self ):
return self.__samples
def setSampleWidth( self, sampleWidth ):
self.__sampleWidth = sampleWidth
def getSampleWidth( self ):
return self.__sampleWidth
def setFrameInterval( self, sfr ):
self.__frameInterval = sfr
def getFrameInterval( self ):
return self.__frameInterval
def setChannels( self, channels ):
self.__channels = channels
def getChannels( self ):
return self.__channels
def getFramePower( self ):
return self.__framePower
def __resetFramePower( self ):
self.__framePower = []
def getDuration( self ):
return float( self.getSamples() ) / float( self.getFrameRate() )
def aboveSampleMin( self, power ):
min = self.getSamplePowerMin()
if min == -1:
power = min
return power >= min
def belowSampleMax( self, power ):
max = self.getSamplePowerMax()
if max == -1:
max = power
return power <= max
def withinSamplePowerLimit( self, power ):
return self.aboveSampleMin( power ) and self.belowSampleMax( power )
def __setPowerLimits( self, power ):
if power < self.getPowerMin(): self.setPowerMin( power )
if power > self.getPowerMax(): self.setPowerMax( power )
def __calculateTime( self, frame ):
return float( frame ) / float( self.getSamples() ) * self.getDuration()
def __appendFramePower( self, frame, power ):
if self.withinSamplePowerLimit( power ):
t = self.__calculateTime( frame )
framePower = self.getFramePower()
if framePower:
tuple = framePower[-1]
if t - tuple[0] >= self.getFrameInterval():
framePower.append( (t, power) )
else:
framePower.append( (t, power) )
def analysePower( self, progress ):
self.__resetFramePower()
self.doPowerAnalysis( self.__appendFramePower, progress )
def doPowerAnalysis( self, doWork, progress ):
filename = self.getFilename()
try:
signal = wave.open( filename, 'rb' )
self.setFrameRate( signal.getframerate() )
self.setSamples( signal.getnframes() )
self.setSampleWidth( signal.getsampwidth() )
self.setChannels( signal.getnchannels() )
width = self.getSampleWidth()
frame = signal.readframes( 1 )
frameNumber = 0
while len( frame ):
if (frameNumber & 16383) == 0:
progress( (float( frameNumber ) / self.getSamples()) )
power = audioop.rms( frame, width )
doWork( frameNumber, power )
self.__setPowerLimits( power )
frame = signal.readframes( 1 )
frameNumber += 1
signal.close()
except IOError:
print 'File not found:', filename
except Exception, inst:
print inst