• 0
Sign in to follow this  
don_

Analog Discovery output .wav file using python sdk

Question

I want to be able to output a .wav file. I can output a sine wave just fine from python, but I'm having trouble with this. I am loading the wav file. The array is populated. I've been looking for a funcPlay example, but I have not found any. I am able to import the file into waveforms and send it out using play.

Thanks.

 

import numpy as np
import scipy.io.wavfile
import matplotlib.pyplot as plt
import ctypes
import winsound

from ctypes import *
import time
from dwfconstants import *
import sys


rate, data = scipy.io.wavfile.read('/Users/don/1.wav')
plt.plot(data)
plt.show()

sin_data = np.sin(data)

if sys.platform.startswith("win"):
    dwf = cdll.dwf
elif sys.platform.startswith("darwin"):
    dwf = cdll.LoadLibrary("/Library/Frameworks/dwf.framework/dwf")
else:
    dwf = cdll.LoadLibrary("libdwf.so")

# declare ctype variables
hdwf = c_int()
channel = c_int(1)

# print DWF version
version = create_string_buffer(16)
dwf.FDwfGetVersion(version)
print("DWF Version: {}".format(version.value))

# open device
print("Opening first device...")
dwf.FDwfDeviceOpen(c_int(-1), byref(hdwf))

c_double_p = ctypes.POINTER(ctypes.c_double)
data_p = data.ctypes.data_as(c_double_p)

if hdwf.value == hdwfNone.value:
    print("failed to open device")
    quit()

print("Generating audio...")
print("Configure and start first analog out channel")
print("Generating custom waveform...")
dwf.FDwfAnalogOutNodeEnableSet(hdwf, channel, AnalogOutNodeCarrier, c_bool(True))
dwf.FDwfAnalogOutNodeFunctionSet(hdwf, channel, AnalogOutNodeCarrier, funcPlay)
dwf.FDwfAnalogOutNodeDataSet(hdwf, channel, AnalogOutNodeCarrier, data_p, data.size)
dwf.FDwfAnalogOutNodeFrequencySet(hdwf, channel, AnalogOutNodeCarrier, 44100)
dwf.FDwfAnalogOutNodeAmplitudeSet(hdwf, channel, AnalogOutNodeCarrier, c_double(2))
dwf.FDwfAnalogOutConfigure(hdwf, channel, c_bool(True))

dataLost = c_int(0)
dataFree = c_int(0)
dataCorrupted = c_int(0)
psts = c_int(0)
dwf.FDwfAnalogOutNodePlayStatus(hdwf, channel, AnalogOutNodeCarrier, dataFree, dataLost, dataCorrupted)
dwf.FDwfAnalogOutStatus(hdwf, channel, psts)
print("psts: {}".format(psts))
print("dataLost: {}".format(dataLost))
print("dataFree: {}".format(dataFree))
print("dataCorrupted: {}".format(dataCorrupted))
while psts != DwfStateDone:
    dwf.FDwfAnalogOutNodePlayStatus(hdwf, channel, AnalogOutNodeCarrier, dataFree, dataLost, dataCorrupted)
    dwf.FDwfAnalogOutStatus(hdwf, channel, psts)
    dwf.FDwfAnalogOutNodePlayData(hdwf, channel, AnalogOutNodeCarrier, data_p, data.size)

# if state == c_int(0):
#     print("state is 0")
# dwf.FDwfAnalogOutNodePlayData(hdwf, channel, AnalogOutNodeCarrier, data_p, data.size)


# print("Configure and start first analog out channel")
# dwf.FDwfAnalogOutEnableSet(hdwf, c_int(0), c_int(1))
# print("1 = Sine wave")
# dwf.FDwfAnalogOutFunctionSet(hdwf, c_int(0), c_int(1))
# dwf.FDwfAnalogOutFrequencySet(hdwf, c_int(0), c_double(3000))
# print("")
# dwf.FDwfAnalogOutConfigure(hdwf, c_int(0), c_int(1))


time.sleep(10)
print("done.")

dwf.FDwfDeviceClose(hdwf)

 

Edited by don_

Share this post


Link to post
Share on other sites

1 answer to this question

Recommended Posts

  • 0

Hi @don_

Here you have the AnalogOut_Play.py

"""
   DWF Python Example
   Author:  Digilent, Inc.
   Revision: 11/22/2017

   Requires:                       
       Python 2.7
"""

import numpy as np
import scipy.io.wavfile
import matplotlib.pyplot as plt
import ctypes
from ctypes import *
import sys

print "Load audio.WAV file"
rate, data = scipy.io.wavfile.read('audio.wav')
print "Rate: "+str(rate)
print "Size: "+str(data.size)
print "Type: " +str(np.dtype(data[0]))
# AnalogOut expects double normalized to +/-1 value
dataf = data.astype(np.float64)
if np.dtype(data[0]) == np.int8 or np.dtype(data[0]) == np.uint8 :
    print "Scaling: UINT8"
    dataf /= 128.0
    dataf -= 1.0
elif np.dtype(data[0]) == np.int16 :
    print "Scaling: INT16"
    dataf /= 32768.0
elif np.dtype(data[0]) == np.int32 :
    print "Scaling: INT32"
    dataf /= 2147483648.0
data_c = (ctypes.c_double * len(dataf))(*dataf)
plt.plot(data)
plt.show()

if sys.platform.startswith("win"):
    dwf = cdll.dwf
elif sys.platform.startswith("darwin"):
    dwf = cdll.LoadLibrary("/Library/Frameworks/dwf.framework/dwf")
else:
    dwf = cdll.LoadLibrary("libdwf.so")

# declare ctype variables
hdwf = c_int()
channel = c_int(0) # AWG 1

# print DWF version
version = create_string_buffer(16)
dwf.FDwfGetVersion(version)
print "DWF Version: "+version.value

# open device
print "Opening first device..."
dwf.FDwfDeviceOpen(c_int(-1), byref(hdwf))

if hdwf.value == 0:
    print "Failed to open device"
    szerr = create_string_buffer(512)
    dwf.FDwfGetLastErrorMsg(szerr)
    print szerr.value
    quit()

print "Playing audio..."
iPlay = 0
dwf.FDwfAnalogOutNodeEnableSet(hdwf, channel, 0, c_bool(True))
dwf.FDwfAnalogOutNodeFunctionSet(hdwf, channel, 0, c_int(31)) #funcPlay
dwf.FDwfAnalogOutRepeatSet(hdwf, channel, c_int(1))
sRun = 1.0*data.size/rate
print "Length: "+str(sRun)
dwf.FDwfAnalogOutRunSet(hdwf, channel, c_double(sRun))
dwf.FDwfAnalogOutNodeFrequencySet(hdwf, channel, 0, c_double(rate))
dwf.FDwfAnalogOutNodeAmplitudeSet(hdwf, channel, 0, c_double(1.0))
# prime the buffer with the first chunk of data
cBuffer = c_int(0)
dwf.FDwfAnalogOutNodeDataInfo(hdwf, channel, 0, 0, byref(cBuffer))
if cBuffer.value > data.size : cBuffer.value = data.size
dwf.FDwfAnalogOutNodeDataSet(hdwf, channel, 0, data_c, cBuffer)
iPlay += cBuffer.value
dwf.FDwfAnalogOutConfigure(hdwf, channel, c_bool(True))

dataLost = c_int(0)
dataFree = c_int(0)
dataCorrupted = c_int(0)
sts = c_ubyte(0)
totalLost = 0
totalCorrupted = 0

while True :
    # fetch analog in info for the channel
    if dwf.FDwfAnalogOutStatus(hdwf, channel, byref(sts)) != 1:
        print "Error"
        szerr = create_string_buffer(512)
        dwf.FDwfGetLastErrorMsg(szerr)
        print szerr.value
        break
    
    if sts.value != 3: break # not running !DwfStateRunning
    if iPlay >= data.size : continue # no more data to stream

    dwf.FDwfAnalogOutNodePlayStatus(hdwf, channel, 0, byref(dataFree), byref(dataLost), byref(dataCorrupted))
    totalLost += dataLost.value
    totalCorrupted += dataCorrupted.value

    if iPlay + dataFree.value > data.size : # last chunk might be less than the free buffer size
        dataFree.value = data.size - iPlay
    if dataFree.value == 0 : continue
    if dwf.FDwfAnalogOutNodePlayData(hdwf, channel, 0, byref(data_c, iPlay*8), dataFree) != 1: # offset for double is *8 (bytes) 
        print "Error"
        break
    iPlay += dataFree.value

print "Lost: "+str(totalLost)
print "Corrupted: "+str(totalCorrupted)

print "done"
dwf.FDwfDeviceClose(hdwf)

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this