Audio frequency generator

Revision as of 17:28, 27 May 2013 by rosettacode>Dkf (→‎Tcl: Added implementation)

An audio frequency generator produces a continual audible monotone at a set frequency and level of volume. There are controls to adjust the frequency and the volume up and down as desired. Some also have a selector to switch the waveform type between sine wave, square wave and triangular sawtooth.

Audio frequency generator is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

The task is to emulate an audio frequency generator. It is permissible to use an inbuilt computer speaker if the system does not have the facility to utilize dedicated sound hardware.

The solution should include:

  • A demonstration of how to check for availability of sound hardware on the system (on systems where this is possible)
  • A demonstration of how to produce a continual audible monotone (on sound hardware this would typicvally be a sine wave)
  • A method of adjusting the frequency and volume of the monotone. (one way would be to use left and right arrow keys to increase or decrease frequency, and up and down keys to increase or decrease the volume)
  • A method to silence or reset the sound hardware on exit.

Optionally the solution can also include:

  • A demonstration of how to fall back to internal speaker, if sound hardware is not available
  • A facility to switch between sine wave, square wave and triangular sawtooth

Languages that provide no facilities for utilizing sound hardware of any kind should be omitted.

Tcl

Library: Snack

This does not work on Windows due the use of the external stty program. <lang tcl>package require sound

set baseFrequency 261.63 set baseAmplitude [expr {64000 / 100.0}] set halfSemis 0 set volSteps 10

  1. How to adjust the generator

proc adjustPitchVolume {changePitch changeVolume} {

   global filter baseFrequency baseAmplitude halfSemis volSteps
   incr halfSemis $changePitch
   incr volSteps $changeVolume
   # Clamp the volume range
   set volSteps [expr {$volSteps < 0 ? 0 : $volSteps > 10 ? 10 : $volSteps}]
   puts -nonewline " Pitch: [expr {$halfSemis / 2.0}]  Volume: $volSteps  \r"
   set freq [expr {$baseFrequency * 2**($halfSemis/24.0)}]
   set ampl [expr {$baseAmplitude * $volSteps**2}]
   # This is where we set the actual frequency of the generated sound
   $filter configure $freq $ampl

}

  1. Callback handler for pressed keys

proc keyPress {} {

   global done
   switch [string tolower [read stdin 1]] {

"q" { set done 1 } "u" { adjustPitchVolume 1 0 } "d" { adjustPitchVolume -1 0 } "s" { adjustPitchVolume 0 -1 } "l" { adjustPitchVolume 0 1 } default { if {[eof stdin]} { set done 1 } }

   }

}

  1. Instantiate the sound generation objects from the Snack library

set filter [snack::filter generator 1 32000 0.5 sine -1] set sound [snack::sound -rate 32050]

  1. Make things ready for a console application

exec stty raw -echo <@stdin >@stdout fconfigure stdout -buffering none fileevent stdin readable keyPress puts "'U' to raise pitch, 'D' to lower pitch, 'L' for louder, 'S' for softer" puts "'Q' to quit"

  1. Start the playing

$sound play -filter $filter adjustPitchVolume 0 0

  1. Wait until the user is finished

vwait done

  1. Clean up the console from its non-standard state

fileevent stdin readable {} puts "" exec stty -raw echo <@stdin >@stdout

  1. Stop the sound playing

$sound stop exit</lang>

ZX Spectrum Basic

The ZX Spectrum is not very good at making sound. Most applications in BASIC would just produce annoying beeps, and the following is no exception. To emulate the signal generator, we just produce repetative beeps using the inbuilt speaker. The left and right keys (5 and 8) change the tone. There is no volume control on the Spectrum.

<lang zxbasic>10 REM The crappest signal generator in the world 20 REM We do not check for boundary errors in this simple demo 30 LET n=1 40 LET k$=INKEY$ 50 IF k$="5" THEN LET n=n-0.5 60 IF k$="8" THEN LET n=n+0.5 70 PRINT AT 0,0;n," " 80 BEEP 0.1,n: REM beep for 0.1 second at n semitones relative to middle C 90 GO TO 40</lang>