A simple variable frequency sinewave audio generator.


Login or Register for Dates, Times and to Reply

 
Thread Tools Search this Thread
# 1  
A simple variable frequency sinewave audio generator.

Hi all...

Well I have not been inactive but working out how to make OSX 10.14.x command line audio player have a variable sample rate.
This is a back door as afplay does not have a sample rate flag unlike aplay for ALSA, in Linux flavours.
This is a DEMO only but a derivative of it will be used in a kids level, variable, AUDIO Function Generator from around 50HZ to 20KHz for pure audio use.

The other limitation is that the shell script must adhere to full POSIX compliance.
I use dash in the script but it should work on the majority of shells.

How does it work?
Well it creates the file everytime you run the script in the following order:
First the frequency '$1' is converted to the big endian word, hex, sample rate.
Next the bytes are extracted and converted to octal.
Finally these octal bytes are reversed and a string created in the correct order.

Now the 'WAV' header is built up using octal values with the 'RATE' placed in the middle.
After that the 'DATA' is added which makes the whole file 65580 bytes in size.

Although this was designed purely for OSX's command line audio player it also works with the ALSA's one too.

USAGE: [./]VFO.sh <Integer FREQUENCY value from 250 to 6000>
As it is a DEMO there is only limited error detection!
Code:
#/usr/local/bin/dash
# #!/bin/sh
#
# USAGE" [./]VFO.sh <Integer FREQUENCY value from 250 to 6000>

FREQ=$1
if [ "${FREQ}" = "" ]
then
    FREQ=1000
fi

if [ ${FREQ} -lt 250 ] || [ ${FREQ} -gt 6000 ]
then
    FREQ=1000
fi

# Get individual little endian words, convert to bytes, reverse and convert to octal.
RATE=$( printf "%04x" $(( FREQ * 8 )) )
BYTE2='\'$( printf "%03o" "0x${RATE%??}" )
BYTE1='\'$( printf "%03o" "0x${RATE#??}" )
# The RATE string to be inserted into the header.
RATE="${BYTE1}${BYTE2}"'\000\000'"${BYTE1}${BYTE2}"

# Create the wav header, 44 bytes in size.
: > /tmp/sine.wav
printf "%b" "\122\111\106\106\044\000\001\000\127\101\126\105\146\155\164\040\020\000\000\000\001\000\001\000" >> /tmp/sine.wav
printf "%b" "${RATE}" >> /tmp/sine.wav
printf "%b" "\000\000\001\000\010\000\144\141\164\141\000\000\001\000" >> /tmp/sine.wav

# Add the sinewave data, 65536 bytes in size.
DATA="Oq~qO- -"
COUNTER=0
while [ ${COUNTER} -le 12 ]
do
    DATA=${DATA}${DATA}
    COUNTER=$(( COUNTER + 1 ))
done
# Entire filesize 65580 bytes, 8+ seconds long for 1000[Hz].
printf "%b" "${DATA}" >> /tmp/sine.wav

# OSX command line player.
afplay /tmp/sine.wav > /dev/null 2>&1

# ALSA command line player.
aplay /tmp/sine.wav > /dev/null 2>&1

Enjoy...


Bazza.

Last edited by wisecracker; 06-06-2019 at 06:01 PM.. Reason: Correct copy and paste error.
These 2 Users Gave Thanks to wisecracker For This Post:
# 2  
A suggestion for more efficiency:
Code:
# Open the file for writing via descriptor 4
exec 4> /tmp/sine.wav
{
printf "%b" "\122\111\106\106\044\000\001\000\127\101\126\105\146\155\164\040\020\000\000\000\001\000\001\000"
printf "%b" "${RATE}"
printf "%b" "\000\000\001\000\010\000\144\141\164\141\000\000\001\000"
} >&4
# Add the sinewave data, 65536 bytes in size.
DATA="Oq~qO- -"
COUNTER=0
while [ ${COUNTER} -le 12 ]
do
    printf "%b" "${DATA}"
    COUNTER=$(( COUNTER + 1 ))
done >&4
# Entire filesize 65580 bytes, 8+ seconds long for 1000[Hz]

These 2 Users Gave Thanks to MadeInGermany For This Post:
# 3  
Thanks MadeInGermany, I will try this out on my main code.

I limited the DEMO to 6000Hz because it kept the BYTE manipulation easy to understand using only one little endian word per sample and byterate instead of the two little endian words for both. Also 8 bits unsigned per sample, and mono eliminates the need for other sections to be altered.

As an addendum the WAV file format:

Microsoft WAVE soundfile format
Login or Register for Dates, Times and to Reply

Previous Thread | Next Thread
Thread Tools Search this Thread
Search this Thread:
Advanced Search

8 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

The Start Of A Simple Audio Scope Shell Script...

This is a DEMO shell script to generate a simple graticule and plot inside it... Apologies for any typos... it is another building block along with my other two shell uploads recently to start a semi_serious project of an Terminal_AudioScope... The fist upload I posted recently was to show... (83 Replies)
Discussion started by: wisecracker
83 Replies

2. OS X (Apple)

Variable frequency audio generator...

Hi all... I intend to do an Audio Function Generator using Awk, (already started thanks to Don), but the biggest thing I have struggled with was variable frequency. I was going to generate differing sized waveforms on the fly but that would that would mean the frequencies are dependent on any... (2 Replies)
Discussion started by: wisecracker
2 Replies

3. OS X (Apple)

An Audio Function Generator...

Ok guys, gals and geeks... As from today I am starting to learn awk in earnest doing something totally different. I am going to create a pseudo-Audio_Function Generator centred around OSX 10.11.x minimum. The code below is a tester to see what the possibilities are. All waveforms will be... (11 Replies)
Discussion started by: wisecracker
11 Replies

4. OS X (Apple)

Python script to do simple audio capture...

This site is the first to get this snippet. It will capture an audio recording of any time length within the limits of OSX's QuickTime Player's capablility... A shell script derivative of this will be used as a further capture for CygWin's AudioScope.sh. Thoroughly read ALL the comments in... (0 Replies)
Discussion started by: wisecracker
0 Replies

5. OS X (Apple)

A Bash Audio Sweep Generator...

This is a small program as a tester for a basic sweep generator for bandwidth testing of AudioScope.sh. This DEMO is only capable of 4KHz down to about 85Hz and back due to the low bit rate, but it is proof of concept for a much wider variant using a much higher bit rate. The file generated... (4 Replies)
Discussion started by: wisecracker
4 Replies

6. Windows & DOS: Issues & Discussions

A SOX 1KHz Sinewave Generator Using A Batch File...

Hi all... I don't think this has been done before but I am open to being corrected... This batch file generates a 65536 byte binary file to give 8 seconds of pure sinewave at the earphone/speaker output(s)... It uses ONLY a default Windows 32 bit installation, to Windows 7, except for the... (0 Replies)
Discussion started by: wisecracker
0 Replies

7. Shell Programming and Scripting

A Crude 1KHz Audio Sinewave Generator Demo...

A very simple crude sinewave generator. The file required is generated inside the code, is linear interpolated and requires /dev/audio to work. Ensure you have this device, if not the download oss-compat from your OS's repository... It lasts for about 8 seconds before exiting and saves a... (5 Replies)
Discussion started by: wisecracker
5 Replies

8. Programming

Python, Platform Independent, Pure Audio Sinewave Generator...

IKHz_SW_OSX.py A DEMO mono _pure_ sinewave generator using standard text mode Python 2.6.7 to at least 2.7.3. This code is EASILY modifyable to Python version 3.x.x... This DEMO kids level 1KHz generator is mainly for a MacBook Pro, (13 inch in my case), OSX 10.7.5 and above. See below...... (0 Replies)
Discussion started by: wisecracker
0 Replies

Featured Tech Videos