def wav_header_unpack(data): ( riff, riffsize, wave, fmt, fmtsize, format, nchannels, samplespersecond, datarate, blockalign, bitspersample, data, datalength, ) = struct.unpack("<4sl4s4slhhllhh4sl", data) if riff != b"RIFF": raise ValueError("invalid wav header") if fmtsize != 16 or fmt != b"fmt " or data != b"data": # fmt chuck is not first chunk, directly followed by data chuck # It is nowhere required that they are, it is just very common raise ValueError("cannot understand wav header") wfx = pywintypes.WAVEFORMATEX() wfx.wFormatTag = format wfx.nChannels = nchannels wfx.nSamplesPerSec = samplespersecond wfx.nAvgBytesPerSec = datarate wfx.nBlockAlign = blockalign wfx.wBitsPerSample = bitspersample return wfx, datalength
def testRecord(self): d = ds.DirectSoundCaptureCreate(None, None) sdesc = ds.DSCBUFFERDESC() sdesc.dwBufferBytes = 352800 # 2 seconds sdesc.lpwfxFormat = pywintypes.WAVEFORMATEX() sdesc.lpwfxFormat.wFormatTag = pywintypes.WAVE_FORMAT_PCM sdesc.lpwfxFormat.nChannels = 2 sdesc.lpwfxFormat.nSamplesPerSec = 44100 sdesc.lpwfxFormat.nAvgBytesPerSec = 176400 sdesc.lpwfxFormat.nBlockAlign = 4 sdesc.lpwfxFormat.wBitsPerSample = 16 buffer = d.CreateCaptureBuffer(sdesc) event = win32event.CreateEvent(None, 0, 0, None) notify = buffer.QueryInterface(ds.IID_IDirectSoundNotify) notify.SetNotificationPositions((ds.DSBPN_OFFSETSTOP, event)) buffer.Start(0) win32event.WaitForSingleObject(event, -1) event.Close() data = buffer.Update(0, 352800) fname = os.path.join(win32api.GetTempPath(), 'test_directsound_record.wav') f = open(fname, 'wb') f.write(wav_header_pack(sdesc.lpwfxFormat, 352800)) f.write(data) f.close()
def __init__(self, nchnl=1, sps=16000, bps=16, t=0.1): dsc = directsound.DirectSoundCaptureCreate(None, None) #创建设备对象 cdesc = directsound.DSCBUFFERDESC() #创建DSCBUFFERDESC结构对象 self.bSize = int(sps * nchnl * bps / 8 * t) cdesc.dwBufferBytes = self.bSize #缓存大小 cdesc.lpwfxFormat = pywintypes.WAVEFORMATEX() #DirectSound数据块格式 cdesc.lpwfxFormat.wFormatTag = pywintypes.WAVE_FORMAT_PCM cdesc.lpwfxFormat.nChannels = nchnl cdesc.lpwfxFormat.nSamplesPerSec = sps cdesc.lpwfxFormat.nAvgBytesPerSec = int(sps * nchnl * bps / 8) cdesc.lpwfxFormat.nBlockAlign = int(nchnl * bps / 8) cdesc.lpwfxFormat.wBitsPerSample = bps self.buffer = dsc.CreateCaptureBuffer(cdesc) #创建缓冲区对象 self.evt = [] for i in range(2): self.evt.append(win32event.CreateEvent(None, 0, 0, None)) #创建两个事件通知 Notify = self.buffer.QueryInterface( directsound.IID_IDirectSoundNotify) #创建事件通知接口 Notify.SetNotificationPositions([ (int(self.bSize / 2) - 1, self.evt[0]), (self.bSize - 1, self.evt[1]) ]) #error #设置两个通知位置,缓冲区每填充bSize/2个样本即发送一个通知消息 self.data = b'' #用于实时存储捕获的音频数据 self.STATUS = False #录音状态标志 self.wfx = cdesc.lpwfxFormat #存储声音格式
def play(self): # 播放文件 f = open(self.file, 'rb') # 打开文件 header = f.read(WAV_HEADER_SIZE) # 读取WAV文件头 (riff, riffsize, wave, fmt, fmtsize, format, nchannels, samplespersecond, datarate, blockalign, bitspersample, data, size) =\ struct.unpack('<4sl4s4slhhllhh4sl', header) # 获取参数值 if riff != 'RIFF' or fmtsize != 16 or fmt != 'fmt ' or data != 'data': # 判断文件格式 raise 'Data Error' wfx = pywintypes.WAVEFORMATEX() # 创建WAVEFORMATEX结构 wfx.wFormatTag = format wfx.nChannels = nchannels wfx.nSamplesPerSec = samplespersecond wfx.nAvgBytesPerSec = datarate wfx.nBlockAlign = blockalign wfx.wBitsPerSample = bitspersample d = directsound.DirectSoundCreate(None, None) # 使用DirectSound播放声音 d.SetCooperativeLevel(None, directsound.DSSCL_PRIORITY) sdesc = directsound.DSBUFFERDESC() sdesc.dwFlags = (directsound.DSBCAPS_STICKYFOCUS | directsound.DSBCAPS_CTRLPOSITIONNOTIFY) sdesc.dwBufferBytes = size sdesc.lpwfxFormat = wfx self.buffer = buffer = d.CreateSoundBuffer(sdesc, None) buffer.Update(0, f.read(size)) buffer.Play(0)
def test_2_Attr(self): 'WAVEFORMATEX attribute access' # A wav header for a soundfile from a CD should look like this... w = pywintypes.WAVEFORMATEX() w.wFormatTag = pywintypes.WAVE_FORMAT_PCM w.nChannels = 2 w.nSamplesPerSec = 44100 w.nAvgBytesPerSec = 176400 w.nBlockAlign = 4 w.wBitsPerSample = 16 self.failUnless(w.wFormatTag == 1) self.failUnless(w.nChannels == 2) self.failUnless(w.nSamplesPerSec == 44100) self.failUnless(w.nAvgBytesPerSec == 176400) self.failUnless(w.nBlockAlign == 4) self.failUnless(w.wBitsPerSample == 16)
def test_2_Attr(self): 'DSCBUFFERDESC attribute access' c = ds.DSCBUFFERDESC() c.dwFlags = 1 c.dwBufferBytes = 2 c.lpwfxFormat = pywintypes.WAVEFORMATEX() c.lpwfxFormat.wFormatTag = pywintypes.WAVE_FORMAT_PCM c.lpwfxFormat.nChannels = 2 c.lpwfxFormat.nSamplesPerSec = 44100 c.lpwfxFormat.nAvgBytesPerSec = 176400 c.lpwfxFormat.nBlockAlign = 4 c.lpwfxFormat.wBitsPerSample = 16 self.failUnless(c.dwFlags == 1) self.failUnless(c.dwBufferBytes == 2) self.failUnless(c.lpwfxFormat.wFormatTag == 1) self.failUnless(c.lpwfxFormat.nChannels == 2) self.failUnless(c.lpwfxFormat.nSamplesPerSec == 44100) self.failUnless(c.lpwfxFormat.nAvgBytesPerSec == 176400) self.failUnless(c.lpwfxFormat.nBlockAlign == 4) self.failUnless(c.lpwfxFormat.wBitsPerSample == 16)
def wav_header_unpack(self, data): print("Start reading wave file.") #unpack wav header information (riff, riffsize, wave, fmt, fmtsize, format, nchannels, samplespersecond, \ datarate, blockalign, bitspersample, data, datalength) = struct.unpack('<4si4s4sihhiihh4si', data) if riff != b'RIFF' or fmtsize != 16 or fmt != b'fmt ' or data != b'data': print("Error! Please check your file!") exit(1) print("File size: " + str(riffsize)) wfx = pywintypes.WAVEFORMATEX() wfx.wFormatTag = format print("Audio format code: " + str(format)) wfx.nChannels = nchannels print("Number of channels: " + str(nchannels)) wfx.nSamplesPerSec = samplespersecond print("Sample rate: " + str(samplespersecond)) wfx.nAvgBytesPerSec = datarate print("Byte rate: " + str(datarate)) wfx.nBlockAlign = blockalign print("Block align: " + str(blockalign)) wfx.wBitsPerSample = bitspersample print("Bits per sample: " + str(bitspersample)) return wfx, datalength
def loadwav(wavefname): d = ds.DirectSoundCreate(None, None) d.SetCooperativeLevel(None, ds.DSSCL_PRIORITY) w = wave.open(wavefname, "rb") sdesc = ds.DSBUFFERDESC() sdesc.lpwfxFormat = pywintypes.WAVEFORMATEX() sdesc.lpwfxFormat.wFormatTag = pywintypes.WAVE_FORMAT_PCM sdesc.lpwfxFormat.nChannels = w.getnchannels() sdesc.lpwfxFormat.nSamplesPerSec = w.getframerate() sdesc.lpwfxFormat.nAvgBytesPerSec = w.getnchannels() * w.getsampwidth( ) * w.getframerate() sdesc.lpwfxFormat.nBlockAlign = w.getnchannels() * w.getsampwidth() sdesc.lpwfxFormat.wBitsPerSample = w.getsampwidth() * 8 sdesc.dwBufferBytes = w.getnframes() * w.getnchannels() * w.getsampwidth() sdesc.dwFlags = ds.DSBCAPS_STICKYFOCUS | ds.DSBCAPS_CTRLPOSITIONNOTIFY buffer = d.CreateSoundBuffer(sdesc, None) buffer.Update(0, w.readframes(w.getnframes())) w.close() return buffer
def wav_header_pack(wfx, datasize): return struct.pack('<4sl4s4slhhllhh4sl', 'RIFF', 36 + datasize, 'WAVE', 'fmt ', 16, wfx.wFormatTag, wfx.nChannels, wfx.nSamplesPerSec, wfx.nAvgBytesPerSec, wfx.nBlockAlign, wfx.wBitsPerSample, 'data', datasize) d = ds.DirectSoundCaptureCreate(None, None) sdesc = ds.DSCBUFFERDESC() sdesc.dwBufferBytes = 352800 # 2 seconds sdesc.lpwfxFormat = pywintypes.WAVEFORMATEX() sdesc.lpwfxFormat.wFormatTag = pywintypes.WAVE_FORMAT_PCM sdesc.lpwfxFormat.nChannels = 2 sdesc.lpwfxFormat.nSamplesPerSec = 44100 sdesc.lpwfxFormat.nAvgBytesPerSec = 176400 sdesc.lpwfxFormat.nBlockAlign = 4 sdesc.lpwfxFormat.wBitsPerSample = 16 buffer = d.CreateCaptureBuffer(sdesc)
def test_1_Type(self): 'WAVEFORMATEX type' w = pywintypes.WAVEFORMATEX() self.failUnless(type(w) == pywintypes.WAVEFORMATEXType)
def test_1_Type(self): "WAVEFORMATEX type" w = pywintypes.WAVEFORMATEX() self.assertTrue(type(w) == pywintypes.WAVEFORMATEXType)
def test_1_Type(self): 'WAVEFORMATEX type' w = pywintypes.WAVEFORMATEX() self.assertTrue(isinstance(w, pywintypes.WAVEFORMATEXType))