Instructions for the utility programs "Sound Input" und "Sound Output" ========================================================================== File: soundutl\SoundUtilityInfo_01.txt Author: Wolfgang Buescher (DL4YHF) Revision Date: 2022-10-17 (ISO-8601 format: YYYY-MM-DD) This is just a preliminary description of the tools to read samples from a soundcard (etc) into a continuous "file stream" and vice versa. For a start, here the description of the "SndInput" utility which reads analog samples from the soundcard (A/D-converter). The program shall read a continuous stream of samples from the ADC, and put them in small "chunks" as temporary files to any other program which processes the audio data. The "Sound Input Utility" (SndInput.exe) will be called "producer" in the following, the program which processes the audio data further will be called "consumer". The "Sound Output Utility" (SndOutpt.exe) works the other way round, it "eats up" audio files and sends the samples to the D/A-converter of the soundcard. Other tools like "SerInput" work almost the same way, but they receive samples from other sources (like an external hardware connected to the PC's serial port, "COM1" or "COM2"). The firmware for such a converter using a cheap PIC microcontroller is available on the author's homepage. These utilities were originally written in Borland C++Builder V4, but most of them can also be compiled with Dev-C++ since 2006-07. Sourcecode are available from the author for non-commercial purposes. Principle (SndInput=Producer) -------------------------------------------------------------------------- 1.) Producer acquires audio samples in a RAM buffer [ under windows: in a high-priority Thread, so nothing gets lost ]. 2.) Whenever possible, the producer writes as many samples as possible from the RAM buffer into a temporary(!) file. 3.) As soon as the producer notices the "audio transport file" does not exist (because the "consumer" has eaten it), the producer renames the temporary file, for example from "audio.tmp" into "audio.dat". [ this happens in a single Win32-API-call, to avoid inconsistence. In the moment the file is being renamed, it is already CLOSED ]. 4.) As soon as the consumer notices there is a new audio file (new "feed"), he opens it, reads its contents, and closes it again. (during this time, the producer works in step 1 and 2) After closing the file, the consumer(!) erases(!) the file (here: "audio.dat"), which will cause the producer to jump to step 3, and the whole cycle begins from the start. Details: -------------------------------------------------------------------------- The producer polls every 100 milliseconds (or so), if he may produce a new audio file. The size of the file passed from producer to consumer depends on the "speed" of the consumer. To minimize (or even eliminate) hard disk accesses, a RAMDISK can be used. It is quite out of fashion these days, but it is still possible, even under Windoze XP. In many cases this is not required because the operating system often uses a disk cache without "write-through". Command Line Parameters: -------------------------------------------------------------------------- (N = single digit number, NNN=multi-digit integer number, the 'equal'-sign can [still?] be left away) /dev=N audio device name (since 2020 for both 'SndInput' and 'SndOutpt') If not specified, SndInput.exe uses the default 'Wave Audio' input device, which in the windows ecosystem is device "-1" . Beware, audio device names under windows can be very strange. For example, an Icom IC-7300 (SDR transceiver) appeared as "2- USB Audio CODEC" in the system control (classic control panel, 'Recording' devices). If a device names contain spaces, the device name itself must be double-quoted for the command line, e.g.: /dev="2- USB Audio CODEC" Note: If the device name starts with a NUMBER, the number may change when plugging in new USB audio devices, etc. To find out the *currently used* name, check the name of your audio input devices in the Windows 'classic' audio control (possibly somewhere under "Control Panel" / "Hardware and Sound", in german: "Systemsteuerung" / As often under Windows (10), it's much easier to get there through the command line: Press the Windows key + 'R' to open the 'Run' dialog, enter mmsys.cpl, press ENTER . On the classic 'Sound' control, switch to 'Recording' (to find device names suitable for "SndInput.exe") or to 'Playback'/'Wiedergabe'(?) for "SndOutpt.exe" . Each of the audio input devices has two names (in two lines) in the list displayed there. The first line shows some utterly useless name like "Microphone" / "Mikrofon" / "Stereomix" / etc, but you can rename them to a less ambiguous name like "IC-9700" (after discovering that the 'Microphone (USB Audio CODEC)' is actually your new rig). Then, after renaming the device, you can launch the sound input utility via e.g. SndInput.exe /dev="IC-9700" /sr=4800 /ch=1 instead of the confusing SndInput.exe /dev="2- USB Audio CODEC" /sr=4800 /ch=1 . The utility tries to find a matching device even if parts of device name are missing, e.g. it will find "IC-9700" even if the name return by waveInGetDevCaps() was "IC-9700 (2- USB Audio CODEC)" . BTW, the full names are also listed in the audio device selector (drop-down combo) in Spectrum Lab. The audio-input-utility doesn't have such a selector. Note to myself: A Behringer U-PHORIA UMC404HD presented its FOUR analog inputs as "IN 1-2" and "IN 3-4", thus unfortunately, with the standard windows "multimedia" API, it appeared to be impossible to open all four analog inputs simultaneously. Thus, the only possibilities (with SndInput.exe) were: /dev="IN 1-2" : opens the UMC404's "INPUT 1" and "INPUT 2", or /dev="IN 3-4" : opens the UMC404's "INPUT 3" and "INPUT 4". When clicking the "Info"-button, the SndInput-utility showed the UMC404 as current 'Input Device' like this: "Input Device: 4 IN 1-2 (wave-In)" or "Input Device: 4 IN 3-4 (wave-In)". Note the complete lack of the actual 'product name' (UMC404) in any of these device- or input channel names - almost as "intuitive" as "2- USB Audio CODEC" for an Icom IC-7300 or IC-9700. Ok, 'rant off'. /sr=NNN sample rate Defines the sampling rate for the ADC (before decimation). Usual values are 5512(5513?), 11025, 22050 or 44100; on some audio cards also 48000 or even 96000 samples/second. Default value: /sr=11025 /dec=NNN sample rate decimation Optional reduction of the sampling rate in den exported data. Some 'audiophiles' call this "downsampling", in the DAC out tool "Upsamling". Default value: /dec=1 (which means NO decimation). Internally, a cascaded design is used, every stage consists of a half band filter or "third- band-filter", which runs at 1/2 or 1/3 of the sampling rate of the preceding stage. A maximum number of 12 stages is possible, enough to reduce the (output) sample rate to 1/(2^12) or 1/(3^12) of the ADC sampling rate (of course, reducing also the usable bandwitdth). The shape factor (steepness) of the half-band filter is a bit better than the "1/3-band filter", for this reason -if possible- use only powers of two for the decimation factor: NNN=2,4,8,..4096. The theoretic bandwidth is sr / (2*dec), but practically - due to the filter slope - the usable bandwidth is less, so an accurate amplitude measurement is only possible for signals within a frequency up to f = 0.75 * sr/(2*dec), for example /sr=11025 /dec=256 -> usable bandwidth ~ 16 Hz . Note: For narrow-band signals it's a good idea to use floating point numbers for the export file, for integer numbers you need a kind of gain factor depending on input spectrum if you don't want to waste ADC resolution. Default value: /dec=1 (no decimation, input rate = output rate) /fc=NN.NNN center frequency for f-conversion with COMPLEX output /fr=NN.NNN center frequency for f-conversion with REAL output Optional multiplication of the input signal with a complex ("quadrature") sine wave. In technical terms, an "NCO" with two outputs, 90° phase lag. Default value: /fc=0 (which means no frequency shift, real-valued output). Only usable (and meaningful)in combination with the sample rate decimation ("/dec=NN", NN >= 4 ) . The result is either a complex (analytic) or real output signal. Use it if only a narrow spectrum around a center frequency (fc) in the INPUT SIGNAL are important (fc +- bw/2, with the bandwidth of the output signal dictated by the decimation ratio). With the "/fc" (complex) option, a monophone signal at the input will be converted into a signal with TWO components (I+Q), a "Stereo-signal" will be turned into a data stream with FOUR components per sample point: I "left", Q "left", I "right", Q "right". (I=in-phase channel, Q=quadrature channel) Example for frequency conversion with COMPLEX output: SndInput.exe /sr=11025 /fc=2000 /dec=4 Audio input = 11025 samples/second, Center frequency for 'real' frequency conversion = 2000 Hz Decimation ratio = 4 -> max possible Bandwidth = bw = 11025 / 4 = 2756 Hz (COMPLEX!) -> Input frequency band = fc +/- bw/2 = 622 Hz .. 3378 Hz The "/fr" option produces REAL output instead; for the same decimation ratio it has only half the bandwidth compared to "/fc" and only half the data output rate. Example for frequency conversion with REAL output: SndInput.exe /sr=11025 /fr=2000 /dec=4 Audio input = 11025 samples/second, Center frequency for 'real' frequency conversion = 2000 Hz Decimation ratio = 4 -> max possible Bandwidth = bw = 11025 / (4*2) = 1378 Hz -> Input frequency band = fr +/- bw/2 = 1310 Hz .. 2689 Hz To see these parameters in the utility, click the "Info" button. Note 1: You can modify the center frequency "on the fly" by typing it into an edit field of the utilitie's control window, but you cannot change the "conversion mode" this way ! Note 2: The "fr" command is only available for the INPUT tool, but not (yet) for SndOutput . /ch=N channels /ch1 = one channel, "mono" /ch2 = two channels, "stereo". Default value: /ch=1 (i.e. monophone input) /dt=N data type defines the basic data type of the exported audio samples 1= 8 bit integer (0..255, like in 8-bit-WAV-files ) 2= 16 bit integer (+-32767, like in 16-bit-WAV-files ) 3= 32 bit integer (only rarely supported...) 4= 64 bit integer (possibly never supported / "reserved for the future") 5= 32 bit float ("single precision") 6= 64 bit float ("double precision") Only the 'floating point' types make sense for decimated samples. Default value: /dt=2 (i.e. 16-bit integer values) /gain=NN.NNN gain (factor!! not a logarithmic scale) All samples can be multiplied with an optional "gain" factor before turning them into integer values and writing them into a file. (Only makes sense, if -for example- decimated samples shall be written to the file as integer values without using too many bits of "resulution".) Default value: /gain=1 (which means NO gain) Note: If the data are written as integer values, they may be "clipped" if the product (input * gain) gets too large. For example, if 8-bit-integers are written, values <0 and >255 will be limited to 0 or 255. /dc_reject=N Can be used to reject DC-components by software . (DC = "direct current" though we mostly use voltages) Some audio cards have a strong erroneous DC-component, for example output value from the ADC = -700 though the "Line-In" input of the soundcard is only AC-coupled). Default value: /dc_reject=1 (d.h. DC-rejection is ACTIVE) /of="" output filename (for all audio INPUT utilities) /fn="" in- or output filename (for ALL audio utilities) Example: /of="MyAudioStream.dat" The default name for the input-and output file is "audio.dat" . ( The name of the temporary file is derived from the name of the output file, using the extension ".tmp" ). If the file name is not chopped into pieces with SPACE characters.. ( which seems to be common bad practice under Windoze ) ..you can leave the double quotes away, like /of=MyAudioStream.dat . To be compatible with DOS and other operating system, DO NOT USE SPACE CHARACTERS IN FILENAMES ! Thanks. Location of the output file: If you specify a full path for the output file, there's no doubt: C:\CBproj\SoundUtl\SndInput.exe /of=C:\Spectrum\audio.dat /ch=1 If you don't specify a path (or no filename at all), the output file will be written into the CURRENT DIRECTORY which was active when the tool was launched. This is NOT NECESSARILY the directory where the input tool is located ! If you launch the tool from another location with a full directory path to the executable, like : C:\CBproj\SoundUtl\SndInput.exe /ch=1 while the CURRENT DIRECTORY is something else, for example : C:\Spectrum\ ...then the output file produced by SndInput will be : C:\Spectrum\audio.dat ...because the "current directory" will be used if no path is specified. /chunk=NNNN audio processing chunk size Defines the size of the "portions" which will be read from the A/D-converter (or sent to the D/A-converter). The smaller this value, the lower is the delay time between the analog input and the output to the file; but the risk of losing samples caused by task switching and other interruptions is increased. Default value: /chunk=2048 On fast PCs even /chunk=256 works at 11025 samples/sec, but this makes little sense because the server only check every 100 milliseconds if a new block from the buffer can be written into a file (or vice versa for the DAC tool). /minsize=NNNNN min size of output file Defines the minimum size of the output file. Default: /minsize=1K NNNN without a letter (suffix) means a size in BYTE, with appended letter "k" or "K" it's KBytes (1K = 1024 byte). See also: Notes on "/chunk" ! /maxsize=NNNNN max size of output file Sets the maximum allowed size of the output file in BYTE or KBYTE (1 KBYTE = 1024 Byte). Default: /maxsize=64K Warning: This default value may be a bit too low for 48000 samples/sec * 2 channels * 64-bit-floats because in this (quite academic) case about 768 KByte will be written per second ! /signed=N Defines if the A/D converter is connected to a SIGNED source (with negative and positive values) or not. N=0 means "unsigned values", output value range 0...32767. N=1 means "signed values", output range -32768...+32767. (Note: the A/D converter in the PIC12F675 microcontroller only accepts analog signals from 0...+5V, so it's "unsigned" by nature. But you may add an OPAMP circuit which adds a bias voltage to the input, in this case use the option /signed=1). Defaults: /signed=0 for SerInput.exe (ADC on serial interface) /signed=1 for SndInput.exe (soundcard) /show=N initial window 'show' state Defines how the window of the utility will be shown on program start, and who will be the new "active" window. /show=0 : Minimized window, will not be activated, which means the "calling program" will remain active and will keep the input focus. Win-API-function ShowWindow(SW_SHOWMINNOACTIVE). /show=1 : Normal window, will be activated. Win-API-function ShowWindow(SW_SHOWNORMAL). /show=2 : Normal window, but will NOT be activate . Win-API-function ShowWindow(SW_SHOWNA). Default: /show=0 (means the window of the utility will be MINIMIZED and NOT activated. It will run but you only see something in the task bar) /display=N Define what will be displayed in the Tool's window : /display=0 Show Time and Count of acquired samples /display=1 Show current Values of acquired samples Default: /display=0 /testsig=N.NNN produce test signal Generates a test signal (sine wave) with the given frequency in Hertz. This feature has been used to test the coninuous replay mode and to trace errors caused by too slow file exchange between "producer" and "consumer". For the "Sound Input Tool", the sine wave will be written into the produced file, for the "Sound Output Tool", it will be sent to the D/A- converter in real time. The amplitude of the test signal is 6 dB below the maximum level. The test signal will be ADDED to the audio samples from the A/D-converter, so be careful to avoid overload ! Note: The frequency of the test signal can be changed "on the fly" by typing it into an edit field of the utility. /port=XXXX define interface port name Defines the port used to receive samples from an external A/D converter. Only works for SerInput.exe and similar tools for external converters. No function for SndInput.exe (which uses the soundcard). Default: /port=COM1 /fs fool shell A special option to start the utility from a QuickBasic program (etc) with the SHELL-command, which seems to wait unter Windows XP (and ME, etc?) until the called program has terminated (!). With this option, the SHELL-command can be fooled. How it works and how it can be used: See below, "Program Start". Important: If you use the "/fs" option (for example, in a batchfile), specify it as the FIRST argument (after the program name) so the program can copy the rest of the command line, and pass it on to the 2nd launched instance. /quit Automatic closure of the program, useful if the utility has been started by another program before. Internally, the second started program instance packs the command line into a windows message (a WM_COPYDATA message) and sends this to the first started instance. Finally, both instances terminate themselves. Other command line parameters are still "under construction", like: - Using the programms as a "normal audio recorder" without time limit, Display Window --------------------------------------------------- The display window, aka "GUI", is only used for testing purposes, because the "main job" of this program is to work silently in the background. For this reason, the following displayed values may have been changed already, or don't exist any longer in the current version: "TimerTicks" should be incremented every 100ms, if there are no uncooperative other programs which steal too much CPU time. "Samples" shows how many audio sample points have been acquired since the start of the program, and how many of those have been passed (via file) to another program. "TempFile" shows the current size of the temporary file (which will be renamed to pass it to the "consumer") ________________________________ |A/D| SndInput __ [#] [ x ] | <- window "title bar" |--------------------------------| | Timer: 12.3 sec ,-, ,-, ,-, | | Samples: 6543210 | | | | | | | <- three bargraphs for | TempFile: 64 kByte | | | | | | | bu = "buffer usage", | Samples: 6543210 | | | | | | | vl = "volume left", | |_| |_| |_| | vr = "volume right". | ,-------, ,------,| | fr/Hz |0.0 | ft/Hz | 0.0 || <- edit fields | '-------' '------'| explained below | [Stop] [Info] [Gain] [Quit] | <- control buttons |________________________________| There are also a few edit-fields in the control window which CAN be used to modify certain parameters without stopping the process: "fr/Hz" or "fc/Hz": An edit field for the center frequency, if the optional frequency conversion is enabled. See explanation of the commands "/fc" or "/fr" . (fr=frequency conversion with REAL output, fc=frequency conversion with COMPLEX output) "ft/Hz" This edit field can be used to change the frequency of the "test signal" on the fly. See explanation of the "/testsig" command. At the right side of the window some vertical bars are displayed, among them a "buffer level indicator" and a simple level meter. The indicated audio level (in PERCENT of the clipping level) should be below 70 % . Otherwise you can start the program "sndvol32" (Windoze "sound volume control") with the "GAIN" button. Unfortunately Microsoft have the bad habit to change the names of these 'built-in utilities', so depending on the windows version, the name may be "sndvol.exe" instead of "sndvol32.exe", or whatever comes next in Windows 10, 11, etc. Thus, don't be surprised if clicking the "Gain"-button has no effect (in that case, try to find the right volume- or input-gain-control application yourself). Info-Window --------------------------------------------------- Shows the program version (and/or compilation date), contents of the command line when the program was started and a few other parameters. Installation --------------------------------------------------- Should not be required. The program does not require any "special" DLLs. Just copy it to any directory you like. On the author's PC, both utilities are kept in the folder c:\CBproj\SoundUtl\*.*, some links in HTML files point to this directory. Sourcecodes --------------------------------------------------- The sources were initially compiled with Borland C++ Builder Version 4, but most of them can be compiled (and linked) with DevCpp V4.9.9.2 too (which seems to be the last version of that nice freeware development system). The sources are available on the author's website, www.qsl.net/dl4yhf/snd_utl1.html at the time of this writing. Program start and termination --------------------------------------------------- You can start the program from your own application with a SHELL-command (in Basic), "WinExec", "ShellExecute" etc. Or you create a shortcut on the desktop which includes the full command line with all required arguments as described above. To terminate the program, restore the window to its normal size and click the "QUIT" button or the close symbol ("X") in the upper right corner. It is also possible to terminate the program from another ("user-")program by "calling" it again with the command line "/quit". For a very short time, two instances of the utility will run, but the second instance will detect the first program instance and pass the whole command line (with the "/quit"-instruction) to the first instance using a WM_COPYDATA-message. Finally, both instances will terminate themselves. The "Fool Shell"-option (/fs) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (ask me to translate this into english if you need it...) Beim Aufruf des Programmes aus QuickBasic unter Windoze XP zeigte sich das Problem, dass das Programm im SHELL-Kommando "hing", bis das SoundInput-Utility beendet war. Um dieses Problem zu umgehen, kann ALS ERSTER PARAMETER IN DER KOMMANDOZEILE der Schalter "/fs" stehen (fs wie "fool [the] shell"). Dieser bewirkt, dass das Utility sich selbst nochmal startet, wobei der Rest der Kommandozeile hinter dem "/fs" an die zweite Instanz weitergegeben wird. Unmittelbar danach beendet sich die erste Instanz selbst. Der SHELL-Befehl von QuickBasic kriegt von diesem Betrug nichts mit, und arbeitet wie gewünscht weiter. Beispiel (Aufruf aus QuickBasic-Programm) : SHELL "sndinput.exe /fs /dt=1 /sr=5512 /ch=2 /maxsize=32k" Das Utility analysiert die Kommandozeile von links nach rechts. Die "/fs"-Option wird erkannt, und automatisch eine neue Kommandozeile zusammengesetzt (mit dem kompletten Pfad zum EXE-File und dem Rest der Kommandozeile): c:\QuickBasic\SndInput.exe /dt=1 /sr=5512 /ch=2 Dieses Kommando wird mit Hilfe einer Win32-API-Funktion gestartet, die -im Gegensatz zum SHELL-Befehl- sofort zurückkehrt. Die zuerst gestartete Instanz terminiert sich danach sofort selbst, damit das aufrufende BASIC-Programm (o.ae.) weiterlaeuft. Mit einer leichten Modifikation konnte die "fool shell"-Option auch unter Windows 8.1 in der Windows-eigenen Shell ("Konsolenfenster") wieder 'zum Laufen' gebracht werden, so dass auch der Aufruf aus 'Batch-Dateien' nicht mehr dazu führt, dass Windows (8.1 & Co?) nicht mehr wartet, bis sich das aus dem Batch gestartete Programm (in diesem Fall SndInout.exe oder SndOutpt.exe) selbst beendet hat. Viel Erfolg bei eigenen Experimenten mit 'DSP per Soundkarte' / good luck, Wolfgang Buescher (DL4YHF@qsl.net) .