Data AcQuisition And Real-Time Analysis
Scope - Spectrum - Spectrogram - Signal Generator
Software for Windows
Science with your Sound Card!
The following is from the Daqarta Help system:



Spectrum Analyzer

Signal Generator

(Absolutely FREE!)


Pitch Tracker


DaqMusiq Generator
(Free Music... Forever!)

Engine Simulator

LCR Meter

Remote Operation

DC Measurements

True RMS Voltmeter

Sound Level Meter

Frequency Counter
    Spectral Event

    MHz Frequencies

Data Logger

Waveform Averager


Post-Stimulus Time
Histogram (PSTH)

THD Meter

IMD Meter

Precision Phase Meter

Pulse Meter

Macro System

Multi-Trace Arrays

Trigger Controls


Spectral Peak Track

Spectrum Limit Testing

Direct-to-Disk Recording



Frequency response

Distortion measurement

Speech and music

Microphone calibration

Loudspeaker test

Auditory phenomena

Musical instrument tuning

Animal sound

Evoked potentials

Rotating machinery


Product test

Contact us about
your application!

WAV File Convert-to-16bit Macro


The WAV_to_16bit macro is included with Daqarta. (See Macro Examples and Mini-Apps for the list.) It allows you to automatically convert .WAV files of 8, 20, 24, or 32 bits to 16 bits. Files may include 1, 2, or 4 channels. The converted file is saved to the original folder but with '_x16' appended to the original file name.

You may find this macro convenient because Daqarta itself currently only acquires and loads 16-bit files. If you have data obtained elsewhere that uses a different number of bits, this will enable you to analyze it with Daqarta.

This macro also demonstrates how to use Macro Arrays, including advanced File Operations as well as Math Operations, plus File Path and Name macros GetFilePath and FileName.

To run WAV_to_16bit, hit the F8 key followed by the unshifted 'w' key. Note that this macro ID is case-sensitive because the WAV_to_Mono macro uses an uppercase 'W' as its ID.

Alternatively, hit CTRL+F8 to open the Macro Dialog and then double-click on WAV_to_16bit in the Macro List.


WAV_to_16bit first clears any old Custom Messages using Msg=, then performs a "dummy" file load by first setting the number of channels to be loaded to 0 via Buf0#N=0, then invoking an Open dialog for file selection via Buf0="<LoadWAV:". It then saves the file path, reads the file sample rate via UR=Buf0?R, and reads the actual number of file channels via UN=Buf0?N. If there are no channels it means the specified file was not found, so the macro exits with an error message.

Otherwise, the data width (in bits) is read via UW=Buf0?W. If it is already a 16-bit file, the macro reports this and exits with an explanatory message.

Assuming it is not a 16-bit file, the macro performs a dummy open on the name of the target file, which is the orignal name with '_x16' appended. It does this without an Open dialog via A.Buf1="<LoadWAV:" + FileName?P + "_x16". (The leading A. forces an automatic open with no prompt.) If that file already exists, the returned number of channels will be non-zero and the macro exits with an error message.

If the target file doesn't already exist, the macro proceeds to a WHILE loop that reads it in 1024-sample blocks by first setting the read size with US=1024, reading a block, and then getting the samples actually loaded via US=Buf0?L. The loop is WHILE.US=1024, so if the actual load was less (due to encountering the end of the file) the next WHILE test will fail and the loop will exit.

In order to work through the entire file, the macro must keep advancing the file pointer. It uses variable UF for that, which it initializes to 0 before the loop, and uses to set the pointer via Buf0#L=UF before each load. At the end of each loop pass, the pointer is updated for the next pass via UF=UF+US, which adds the points read to the running total.

Each of the 1024 samples must be scaled to match 16-bit scaling, which involves scaling up 8-bit data, or scaling down 20, 24, or 32-bit data.

Note that 20-bit or 24-bit data can be stored as 3 bytes (24 bits) or 4 bytes (32 bits). Each sample is always high-justified in the data "container" width, so the scaling is related to the container size, not the 20-bit or 24-bit resolution.

Since the container width was set into UW on the initial dummy load, the scaling is done via Buf0="<*(2^(16-UW))". If the raw data width is 8 bits, then the factor is 2^(16-8) = 2^8 = 256. If the width is 24 bits the factor will be 2^(16-24) = 2^-8 = 1/256, and if it is 32 bits the factor will be 2^(16-32) = 2^-16 = 1/65536.

If the source file has 2 channels (UN=2), the original load to Buf0 actually loads Buf1 as well. If it has 4 channels, Buf0 through Buf3 are loaded. The additional buffers are scaled just like Buf0, even if they are not used.

The converted buffer(s) is/are appended to the _x16 target file via A.Buf0="<SAveWAV:" + FileName?P + "_x16". (Note the uppercase 'A' in SAveWAV, which means Append.) First, however, the number of samples to save (per buffer) is set via Buf0#S=US in case it is the final chunk of the file with less than 1024 samples. Also, the file sample rate is set to the original rate via Buf0#Rf=UR.

The source read position UF is then advanced by the number of samples US just processed, and WEND loops back to the WHILE statement.

As with the load command, if the source file has 2 or 4 channels, the append operation uses the adjacent buffers as needed.

Note, however, that this macro will not handle "multi-channel" files from 5.1 or 7.1 systems, which use a different structure, even if only 2 or 4 channels are in use.

WAV_to_16bit Macro Listing:

Msg=                   ;Clear any existing message
Buf0#N=0               ;Set 0 channels for dummy load
Buf0="<LoadWAV:"       ;Select and load file
GetFilePath=1          ;Save file name and path
UR=Buf0?R              ;Save file sample rate
UN=Buf0?N              ;Save actual file channels
IF.UN=0                ;Exit with message if no file
    Msg=FileName?n + ".WAV file not found." _
    +n +n +"Right-click here for Help."
    UW=Buf0?W              ;Else get data width for scaling
    IF.UW=16               ;Exit with message if already 16-bit
        Msg=FileName?n + ".WAV already 16 bits." _
        +n +n +"Right-click here for Help."
        Buf1#N=0           ;Else check for existing target
        A.Buf1="<LoadWAV:" + FileName?P + "_x16"
        IF.Buf1?N=0        ;OK if target does not yet exist
            US=1024        ;Load 1024 samples/chan at a time
            UF=0           ;Start at beginning of file
            WHILE.US=1024  ;Read as long as full blocks found
                Buf0#L=UF              ;Set file read position
                A.Buf0="<LoadWAV:" + FileName?P    ;Load the block
                US=Buf0?L              ;Save actual samples/chan
                Buf0="<*(2^(16-UW))"   ;Scale to 16-bit
                Buf1="<*(2^(16-UW))"   ;Scale stereo chan, if any
                Buf2="<*(2^(16-UW))"   ;Scale chans 3 and 4, if any
                Buf0#S=US              ;Set actual samples to save
                Buf0#Rf=UR             ;Set sample rate to save
                A.Buf0="<SAveWAV:" + FileName?P + "_x16"   ;Append data
                UF=UF+US               ;Next file read position
            Msg=FileName?n + "_x16.WAV already exists." _
            +n +n +"Right-click here for Help."

See also Macro Examples and Mini-Apps


Questions? Comments? Contact us!

We respond to ALL inquiries, typically within 24 hrs.
Over 30 Years of Innovative Instrumentation
© Copyright 2007 - 2017 by Interstellar Research
All rights reserved