In academic situation, preparing practical training for students in structural dynamics, willing to obtain the frequency response function of a mechanical system, both signals are necessary: one excitation and one acceleration. The second one can be got from an accelerometer connected to a DAQ board. The excitation (the force) is often obtained thanks an instrumented impact hammer. Impact hammer delivers a sharp signal, close to a Dirac impuls and therefore covers a wide range of frequency. But sometimes a more customized signal is useful so that a signal generator is required. Of course, the generator has to be synchronized with the measurement of the response of the tested frame and must be managed from the analysis software. Some NI devices enable signal generation in PCI/PXI/USB configurations but a less expensive option can be considered when the signal accuracy is not very important. Remember that, any way, the measurement of the signal is done thanks a force sensor. This article deals with appropriate techniques enabling signal generation from a computer sound card. Of course, the excitation of the structure is obtained by connecting a power suplier behind the sound device and before a shaker.
The method uses the library Windows SDK NI\...\CVI\sdk\lib\winmm.lib
Header: Mmsystem.h (include Windows.h)
DLL: Winmm.dll
See the site at address:
https://msdn.microsoft.com/en-us/library/windows/desktop/dd743834(v=vs.85).aspx
- waveOutGetNumDevs returns the number of sound boards
- waveOutGetDevCaps returns the abilities of the sound boards
- waveOutOpen opens a sound board
- waveOutSetVolume sets the sound volume
- waveOutPrepareHeader prepares a sound board for sounding
- waveOutWrite writes a wave and delivers a signal
- waveOutGetVolume gets the current sound volume
- waveOutUnprepareHeader releases the sound board
- waveOutReset clears the sound board (stop the signal)
- waveOutClose closes the sound board
1/ automatic scanning of the available soud devices (for output)
2/ manual selection of a device
3/ open a sound device and set some parameters, mainly the frequency of the outputs, the number of channels (mono/stereo), the bits per samples.
4/ form a wave (sinus, white noise or scanning sinus) with the wished frequency and duration
5/ prepare the device for playing
5/ play the wave (asynchroneously)
When the signal is played it becomes be possible for the user to:
- change the sound volume
- stop the signal generation
- change the signal type
The uir includes controls, mainly:
- a knob for the volume adjustment
- a knob for the signal duration, a button enables its continuous repetition
- a knob for the frequency (or the final frequency in case of a sweep sinus)
- a ring for choosing the output sound board
- a ring for choosing the signal type (sinus, sweep sinus, white noise, hammer)
- a traditional EXIT button
- a STOP button for stopping the running signal
- A GO button for launching the signal generation
- A graph for plotting the FFT modulus of the signal and including two buttons for the display frequency range and a linear/log switch.
DeviceCallback
Callback of the device ring. It stops the running signal, closes the current board and opens the new one.
RunCallback
Sets the signal and displays its FFT
Generates the signal on the output board
StopCallback
Resets the current board
ExitCallback
Exits the program
FreqCallback
The frequency can be adjusted thanks a knob and two button (UP and DOWN) connected to this callback. The output is reset (sound stops).
dBCallback
Changes the volume of the output. Signal goes on.
WtypeCallback
Callback of the signal type ring. Resets the output.
DurationCallback
Callback of the duration knob and the repetition button. Resets the output.
BodeCallback
Switchs between linear and Bode (log-log) FFT display. Acts on the graph
FreqRangeCallback
Set the FFT range frequency.
WaveOutCallback
Callback used by the output board when an event occurs among:
- WOM_DONE: the signal is terminated (or the board has been reset)
- WOM-CLOSE: the board is closed
- WOM_OPEN: the board is opened.
This callback manages two flags:
- openflag which indicates if a board is currently open or not
- runflag which indicates if a signal is currently running or not
PlotFFT
Plots the FFT of the signal either in linear coordinates either in a log-dB coordinates
LookForOutputDevices
This function scans the hardware and set the available device ring. It uses the library functions waveOutGetNumDevs and waveOutGetDevCaps for getting the device names.
CloseSignalChannel
Closes the current channel. Uses the library functions waveOutReset, waveOutSetVolume and waveOutClose. The intial board volume is restored before closing.
OpenSignalChannel
This function open a channel. It previously closes any other open channel. It keeps in mind the initial volume level. It uses the library functions waveOutOpen and waveOutGetVolume. waveOutOpen is called with the adequat parameters gathered in a structure WAVEFORMATEX : the format (PCM), the number of channels (we use 1 channel for driving a shaker), the output rate (here 44100 Hz), the bytes per second, the block alignment, the number of bits per signal sample. All these values come from constants or macros which are defined at the beginning of the source code.
SetSignal
Releases the memory already allocated, if any. Allocates an array of SIGWORD values (SIGWORD for 'signal word'). This type is currently defined as a signed 32-bit integer. The number of values constituting the array is equal to one plus the duration multiplied by the output rate.
- the white noise if generated thanks the CVI Analysis Library function WhiteNoise.
- the sinus is generated according the chosen frequency
- the sweep sinus is generated with a frequency increasing from 1Hz to the chosen frequency during the chosen duration
- the hammer impact is simulated thanks a sinus bulb risen at the power 0.4. The duration impact is on hundred shorter than the chosen duration.
GenerateSound
Prepares the channel, rises the runflag and switches on the according virtual led, launches the signal on the sound board. Uses the functions waveOutUnprepareHeader, waveOutPrepareHeader and waveOutWrite. The signal is asynchronus so that the uir remains available for the user.
Main
Displays the panel and manages the events.
#define NODEV 0xFFFF
#define MAXSIGWORD (~(DWORD)0>>1)
#define AMPLITUDE MAXSIGWORD
#define NCHAN 1
#define RATE 44100 // among 8.0-11.025-22.05-44.1 kHz
#define M_PI 3.1415926535897932384626433832795
#define M_2PI 6.283185307179586476925286766559
#define BITSPERSAMPLE (8*sizeof(SIGWORD))
#define BYTESPERSEC (RATE*NBLOCKALIGN)
#define NBLOCKALIGN (NCHAN*BITSPERSAMPLE/8)
#define FCT "EXIGEN ("__FUNCTION__")"
#define mmErrChk(fct) if (mmres=(fct)) goto mmstop;
#define mmErrDisp if (mmres) \
{ char txt[256]; \
sprintf(txt,"MMSYSERR %d",mmres); \
MessagePopup(FCT,txt); }
typedef int SIGWORD; // signed type mandatory
typedef enum _STYPE {S_WHITE, S_SINUS, S_SINSWEEP, S_HAMMER} STYPE;
typedef enum _LOGICAL { OFF, ON } LOGICAL;
hwo = handle for the sound board
whdr = header for a signal
dwVol = initial board volume
runflag = flag up is a signal is currently running
openflag = flag up is a board is currently open
N = number of values constituting the signal sampling
mySignal = signal sampling array
Example code from the Example Code Exchange in the NI Community is licensed with the MIT license.