Data AcQuisition And Real-Time AnalysisScope - Spectrum - Spectrogram - Signal Generator
Software for Windows
Science with your Sound Card!
Contact us about
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.
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.
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.
;<Help=H490E 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." ELSE. 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." ELSE. 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 Buf3="<*(2^(16-UW))" 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 WEND. ELSE. Msg=FileName?n + "_x16.WAV already exists." _ +n +n +"Right-click here for Help." ENDIF. ENDIF. ENDIF.
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 - 2020 by Interstellar Research
All rights reserved