Record sound

Revision as of 10:21, 25 June 2022 by rosettacode>Roboticist-Tav (→‎{{header|Diego}}: syntax and added instruct version)

Record a monophonic 16-bit PCM sound into either memory space, a file or array.

Task
Record sound
You are encouraged to solve this task according to the task description, using any language you may know.

(This task neglects to specify the sample rate, and whether to use signed samples. The programs in this page might use signed 16-bit or unsigned 16-bit samples, at 8000 Hz, 44100 Hz, or any other sample rate. Therefore, these programs might not record sound in the same format.)

AutoHotkey

<lang autohotkey>name := "sample" waitsec := 5 Tooltip Recording %name%.wav MCI_SendString("close all wait") MCI_SendString("open new type waveaudio alias " . name) MCI_SendString("set " . name . " time format ms wait")

MCI_SendString("set " . name . " bitspersample 16 wait")
MCI_SendString("set " . name . " channels 1 wait")
MCI_SendString("set " . name . " samplespersec 16000 wait")
MCI_SendString("set " . name . " alignment 1 wait")
MCI_SendString("set " . name . " bytespersec 8000 wait")

MCI_SendString("record " . name) Sleep waitsec*1000 MCI_SendString("stop " . name . " wait") MCI_SendString("save " . name . " """ . name . ".wav""") Tooltip Finished ... Playing MCI_SendString("delete " . name) MCI_SendString("close " . name . " wait") MCI_SendString("open """ . name . ".wav"" type waveaudio alias " . name) MCI_SendString("play " . name . " wait") MCI_SendString("close " . name . " wait") Tooltip Return

MCI_SendString(p_lpszCommand,ByRef r_lpszReturnString="",p_hwndCallback=0) { VarSetCapacity(r_lpszReturnString,512,0) Return DllCall("winmm.dll\mciSendString" . (A_IsUnicode ? "W":"A") ,"Str",p_lpszCommand ;-- lpszCommand ,"Str",r_lpszReturnString ;-- lpszReturnString ,"UInt",512 ;-- cchReturn ,A_PtrSize ? "Ptr":"UInt",p_hwndCallback ;-- hwndCallback ,"Cdecl Int") ;-- Return type }

For more intuitive functions, see the MCI library by jballi.
doc
http://www.autohotkey.net/~jballi/MCI/v1.1/MCI.html
download
http://www.autohotkey.net/~jballi/MCI/v1.1/MCI.ahk</lang>

BBC BASIC

<lang bbcbasic> wavfile$ = @dir$ + "capture.wav"

     bitspersample% = 16
     channels% = 2
     samplespersec% = 44100

     alignment% = bitspersample% * channels% / 8
     bytespersec% = alignment% * samplespersec%

     params$ = " bitspersample " + STR$(bitspersample%) + \
     \         " channels " + STR$(channels%) + \
     \         " alignment " + STR$(alignment%) + \
     \         " samplespersec " + STR$(samplespersec%) + \
     \         " bytespersec " + STR$(bytespersec%)

     SYS "mciSendString", "close all", 0, 0, 0
     SYS "mciSendString", "open new type waveaudio alias capture", 0, 0, 0
     SYS "mciSendString", "set capture" + params$, 0, 0, 0 TO res%
     IF res% ERROR 100, "Couldn't set capture parameters: " + STR$(res% AND &FFFF)

     PRINT "Press SPACE to start recording..."
     REPEAT UNTIL INKEY(1) = 32

     SYS "mciSendString", "record capture", 0, 0, 0 TO res%
     IF res% ERROR 100, "Couldn't start audio capture: " + STR$(res% AND &FFFF)

     PRINT "Recording, press SPACE to stop..."
     REPEAT UNTIL INKEY(1) = 32

     SYS "mciSendString", "stop capture", 0, 0, 0
     SYS "mciSendString", "save capture " + wavfile$, 0, 0, 0 TO res%
     IF res% ERROR 100, "Couldn't save to WAV file: " + STR$(res% AND &FFFF)

     SYS "mciSendString", "delete capture", 0, 0, 0
     SYS "mciSendString", "close capture", 0, 0, 0

     PRINT "Captured audio is stored in " wavfile$</lang>

C

Read/write raw device /dev/dsp. On Linux you need access to said device, meaning probably you should be in audio user group.

<lang c>#include <stdlib.h>

  1. include <unistd.h>
  2. include <sys/types.h>
  3. include <fcntl.h>

void * record(size_t bytes) { int fd; if (-1 == (fd = open("/dev/dsp", O_RDONLY))) return 0; void *a = malloc(bytes); read(fd, a, bytes); close(fd); return a; }

int play(void *buf, size_t len) { int fd; if (-1 == (fd = open("/dev/dsp", O_WRONLY))) return 0; write(fd, buf, len); close(fd); return 1; }

int main() { void *p = record(65536); play(p, 65536); return 0; }</lang>

C++

Uses Windows MCI <lang cpp>

  1. include <iostream>
  2. include <string>
  3. include <windows.h>
  4. include <mmsystem.h>
  1. pragma comment ( lib, "winmm.lib" )

using namespace std;

class recorder { public:

   void start()
   {

paused = rec = false; action = "IDLE"; while( true ) { cout << endl << "==" << action << "==" << endl << endl; cout << "1) Record" << endl << "2) Play" << endl << "3) Pause" << endl << "4) Stop" << endl << "5) Quit" << endl; char c; cin >> c; if( c > '0' && c < '6' ) { switch( c ) { case '1': record(); break; case '2': play(); break; case '3': pause(); break; case '4': stop(); break; case '5': stop(); return; } } }

   }

private:

   void record()
   {

if( mciExecute( "open new type waveaudio alias my_sound") ) { mciExecute( "record my_sound" ); action = "RECORDING"; rec = true; }

   }
   void play()
   {

if( paused ) mciExecute( "play my_sound" ); else if( mciExecute( "open tmp.wav alias my_sound" ) ) mciExecute( "play my_sound" );

action = "PLAYING"; paused = false;

   }
   void pause()
   {

if( rec ) return; mciExecute( "pause my_sound" ); paused = true; action = "PAUSED";

   }
   void stop()
   {

if( rec ) { mciExecute( "stop my_sound" ); mciExecute( "save my_sound tmp.wav" ); mciExecute( "close my_sound" ); action = "IDLE"; rec = false; } else { mciExecute( "stop my_sound" ); mciExecute( "close my_sound" ); action = "IDLE"; }

   }
   bool mciExecute( string cmd )
   {

if( mciSendString( cmd.c_str(), NULL, 0, NULL ) ) { cout << "Can't do this: " << cmd << endl; return false; } return true;

   }
   bool paused, rec;
   string action;

};

int main( int argc, char* argv[] ) {

   recorder r; r.start();
   return 0;

} </lang>

ChucK

<lang c>// chuck this with other shreds to record to file // example> chuck foo.ck bar.ck rec

// arguments: rec:<filename>

// get name me.arg(0) => string filename; if( filename.length() == 0 ) "foo.wav" => filename;

// pull samples from the dac dac => Gain g => WvOut w => blackhole; // this is the output file name filename => w.wavFilename; <<<"writing to file:", "'" + w.filename() + "'">>>; // any gain you want for the output .5 => g.gain;

// temporary workaround to automatically close file on remove-shred null @=> w;

// infinite time loop... // ctrl-c will stop it, or modify to desired duration while( true ) 1::second => now;</lang>

Common Lisp

Translation of: C

<lang lisp> (defun record (n)

 (with-open-file (in "/dev/dsp" :element-type '(unsigned-byte 8))
   (loop repeat n collect (read-byte in))
   )
 )

(defun play (byte-list)

 (with-open-file (out "/dev/dsp" :direction :output :element-type '(unsigned-byte 8) :if-exists :append)
   (mapcar (lambda (b) (write-byte b out)) byte-list)
   )
 )

(play (record 65536)) </lang>

Go

Works with: Ubuntu 16.04


As Go does not have any audio support in its standard library, this invokes the 'arecord' command-line utility to record sound from the internal microphone (assuming there's no other audio input device present) and saves it to a monophonic, signed 16-bit .wav file. It then plays it back using the 'aplay' utility.

The file name, sampling rate and duration can all be set by the user. <lang go>package main

import (

   "bufio"
   "fmt"
   "log"
   "os"
   "os/exec"
   "strconv"

)

func check(err error) {

   if err != nil {
       log.Fatal(err)
   }

}

func main() {

   scanner := bufio.NewScanner(os.Stdin)
   name := ""
   for name == "" {
       fmt.Print("Enter output file name (without extension) : ")
       scanner.Scan()
       name = scanner.Text()
       check(scanner.Err())
   }
   name += ".wav"
   rate := 0
   for rate < 2000 || rate > 192000 {
       fmt.Print("Enter sampling rate in Hz (2000 to 192000) : ")
       scanner.Scan()
       input := scanner.Text()
       check(scanner.Err())
       rate, _ = strconv.Atoi(input)
   }
   rateS := strconv.Itoa(rate)
   dur := 0.0
   for dur < 5 || dur > 30 {
       fmt.Print("Enter duration in seconds (5 to 30)        : ")
       scanner.Scan()
       input := scanner.Text()
       check(scanner.Err())
       dur, _ = strconv.ParseFloat(input, 64)
   }
   durS := strconv.FormatFloat(dur, 'f', -1, 64)
   fmt.Println("OK, start speaking now...")
   // Default arguments: -c 1, -t wav. Note only signed 16 bit format supported.
   args := []string{"-r", rateS, "-f", "S16_LE", "-d", durS, name}
   cmd := exec.Command("arecord", args...)
   err := cmd.Run()
   check(err)
   fmt.Printf("'%s' created on disk and will now be played back...\n", name)
   cmd = exec.Command("aplay", name)
   err = cmd.Run()
   check(err)
   fmt.Println("Play-back completed.")

}</lang>

Diego

This function returns a {wav} variable recorded from a thing in the mist. It understands that the found thing has a microphone, so will have microphone knowledge. If the caller does not have microphone knowledge, the callee will train the caller on first request. <lang diego>begin_funct({wav}, Record sound);

   set_decision(linger);
   find_thing()_first()_microphone()_bitrate(16)_tech(PCM)_samplerate(signed16, unsigned16)_rangefrom(8000, Hz)_rangeto(44100, Hz)_export(.wav)
       ? with_found()_microphone()_label(mic);
       : err_funct[]_err(Sorry, no one has a microphone!);
         exit_funct[];
   ;
   with_microphone[mic]_record()_durat({secs}, 30)_var(recording);
   [Record sound]_ret([recording]);
   reset_decision();

end_funct[];

// Record a monophonic 16-bit PCM sound into memory space: exec_funct(Record sound)_var(PCMRecording)_me(); // The variable 'PCMRecording' is the sound in memory space

// Record a monophonic 16-bit PCM sound into a file or array: exec_funct(Record sound)_file(foo.wav)_me(); // The file 'foo.wav' is the sound in a file</lang>

This is the instruction version, where the thing keeps the reocording. <lang diego>begin_instruct(Record sound);

   set_decision(linger);
   find_thing()_first()_microphone()_bitrate(16)_tech(PCM)_samplerate(signed16, unsigned16)_rangefrom(8000, Hz)_rangeto(44100, Hz)_export(.wav)
       ? with_found()_label(recorder)_microphone()_label(mic);
       : err_instruct[]_err(Sorry, no one has a microphone!);
         exit_instruct[];
   ;
   with_microphone[mic]_record()_durat({secs}, 30)_var(recording);
   reset_decision();

end_instruct[];

// Record a monophonic 16-bit PCM sound into memory space: exec_instruct(Record sound)_me(); with_thing[recorder]_microphone[mic]_var[recording]_var(PCMRecording); // The variable 'PCMRecording' is the sound in memory space

// Record a monophonic 16-bit PCM sound into a file or array: exec_instruct(Record sound)_me(); with_thing[recorder]_microphone[mic]_var[recording]_file(foo.wav)_me(); // The file 'foo.wav' is the sound in a file</lang>

GUISS

Here we activate the Microsoft Windows '95 Sound Recorder:

<lang guiss>Start,Programs,Accessories,Sound Recorder,Button:Record</lang>

Julia

<lang Julia> using PortAudio, LibSndFile

stream = PortAudioStream("Microphone (USB Microphone)", 1, 0) # 44100 samples/sec buf = read(stream, 441000) save("recorded10sec.wav", buf) </lang>

Kotlin

Translation of: Scala

<lang scala>// version 1.1.3

import java.io.File import javax.sound.sampled.*

const val RECORD_TIME = 20000L // twenty seconds say

fun main(args: Array<String>) {

   val wavFile = File("RecordAudio.wav")
   val fileType = AudioFileFormat.Type.WAVE
   val format = AudioFormat(16000.0f, 16, 2, true, true)
   val info = DataLine.Info(TargetDataLine::class.java, format)
   val line = AudioSystem.getLine(info) as TargetDataLine
   // Creates a new thread that waits for 'RECORD_TIME' before stopping
   Thread(object: Runnable {
       override fun run() {
           try {
               Thread.sleep(RECORD_TIME)
           }
           catch (ie: InterruptedException) {
               println(ie.message)
           }
           finally {
               line.stop()
               line.close()
           }
           println("Finished")
        }
   }).start()
   // Captures the sound and saves it in a WAV file             
   try {
       if (AudioSystem.isLineSupported(info)) {
           line.open(format)
           line.start()
           println("Recording started")
           AudioSystem.write(AudioInputStream(line), fileType, wavFile)
       }
       else println("Line not supported")
   }
   catch (lue: LineUnavailableException) {
       println(lue.message)
   }

}</lang>

Liberty BASIC

LB can easily send a MCI string to the OS, or extra routines eg SOX, so a minimal solution could be <lang lb> run "sndrec32.exe" </lang> A more direct way is.. <lang lb>

   print "Starting 5 sec. recording..."
   r$ =mciSendString$( "open new type waveaudio alias capture")
   r$ =mciSendString$( "set capture time format ms bitspersample 16")
   r$ =mciSendString$( "set capture channels 1 samplespersec 8000")
   r$ =mciSendString$( "set capture alignment 1 bytespersec 8000")
   r$ =mciSendString$( "record capture")
   timer 5000, [on]
   wait
 [on]
   timer 0
   print "     .... now stopping the recording."
   r$ =mciSendString$( "stop capture")
   r$ =mciSendString$( "save capture " +chr$( 34) +"sample.wav" +chr$( 34))
   r$ =mciSendString$( "close capture")    
   print "Done recording."
   r$=mciSendString$( "open " +q$ +"sample.wav" +q$ +" type waveaudio alias sfx")
   r$=mciSendString$( "play sfx wait")
   r$=mciSendString$( "close sfx")
   print "Done playing back."
   end

function mciSendString$( s$)

   print s$
   buffer$ =space$( 1024) +chr$( 0)
   calldll #winmm, "mciSendStringA", s$ as ptr, buffer$ as ptr, 1028 as long, 0 as long, r as long
   buffer$ =left$( buffer$, instr( buffer$, chr$( 0)) -1)
   if r >0 then
       mciSendString$ ="error"
       print "returned "; mciSendString$
   else
       mciSendString$ =""'buffer$
       print "OK"
   end if

end function </lang>

LiveCode

This example sets some aspects of a sound recording individually and also shows use of the sound input dialog where a user can conveniently set them as well, either may be used.<lang LiveCode>command makeRecording

   set the dontUseQT to false -- on windows use true
   set the recordFormat to "wave" -- can be wav,aiff, au
   set the recordRate to 44.1 -- sample at 44100 Hz
   set the recordSampleSize to 16  --default is 8 bit
   ask file "Save recording as" 
   if it is not empty then
       answer record --show sound input dialog with presets above
       record sound file it  -- actual record command
       wait 10 seconds
       stop recording 
   end if

end makeRecording</lang>

Mathematica/Wolfram Language

<lang Mathematica>SystemDialogInput["RecordSound"]</lang>

Nim

Translation of: Go

This code is for Linux systems and uses “arecord” and “aplay”. Previous code which used “/dev/dsp” no longer works on modern OS. This code is a direct translation from Go version, but uses integers instead of floats for duration. <lang nim>import osproc, strutils

var name = "" while name.len == 0:

 stdout.write "Enter output file name (without extension): "
 name = stdin.readLine().strip()

name.add ".wav"

var rate = 0 while rate notin 2000..19_200:

 stdout.write "Enter sampling rate in Hz (2000 to 192000): "
 try: rate = parseInt(stdin.readLine().strip())
 except ValueError: discard

var duration = 0 while duration notin 5..30:

 stdout.write "Enter duration in seconds (5 to 30): "
 try: duration = parseInt(stdin.readLine().strip())
 except ValueError: discard

echo "OK, start speaking now..."

  1. Default arguments: -c 1, -t wav. Note that only signed 16 bit format is supported.

let args = ["-r", $rate, "-f", "S16_LE", "-d", $duration, name] echo execProcess("arecord", args = args, options = {poStdErrToStdOut, poUsePath})

echo "'$1' created on disk and will now be played back..." % name echo execProcess("aplay", args = [name], options = {poStdErrToStdOut, poUsePath}) echo "Playback completed"</lang>

OCaml

Translation of: C

<lang ocaml>#load "unix.cma"

let record bytes =

 let buf = String.make bytes '\000' in
 let ic = open_in "/dev/dsp" in
 let chunk = 4096 in
 for i = 0 to pred (bytes / chunk) do
   ignore (input ic buf (i * chunk) chunk)
 done;
 close_in ic;
 (buf)

let play buf len =

 let oc = open_out "/dev/dsp" in
 output_string oc buf;
 close_out oc

let () =

 let bytes = 65536 in
 let p = record bytes in
 play p bytes</lang>

Phix

Translation of: BBC_BASIC
Translation of: C
Translation of: Go
--
-- demo\rosetta\Record_sound.exw
-- =============================
--
without js -- (file i/o)
constant wavfile = "capture.wav",
         bitspersample = 16,
         channels = 2,
         samplespersec = 44100,
         alignment = bitspersample * channels / 8,
         bytespersec = alignment * samplespersec,
         params = sprintf(" bitspersample %d channels %d alignment %d samplespersec %d bytespersec %d",
                           {bitspersample,   channels,   alignment,   samplespersec,   bytespersec}),
         error_size = 2048
atom winmm = NULL, xmciSendString, pError

procedure mciSendString(string msg)
    if winmm=NULL then
         winmm = open_dll("winmm.dll")
         xmciSendString = define_c_func(winmm,"mciSendStringA",
            {C_PTR,     --  LPCTSTR lpszCommand
             C_PTR,     --  LPTSTR lpszReturnString
             C_INT,     --  UINT cchReturn
             C_PTR},    --  HANDLE hwndCallback
            C_INT)      -- MCIERROR
         pError = allocate(error_size)
    end if
    atom res = c_func(xmciSendString,{msg,pError,error_size,NULL})
    if res!=0 then crash("error %0x: %s",{res,peek_string(pError)}) end if
end procedure

include get.e   -- get_bytes()

function record(integer bytes)
    integer fn = open("/dev/dsp","rb")
    if fn=-1 then return "" end if
    string res = get_bytes(fn,bytes)
    close(fn)
    return res
end function
 
procedure play(string buf)
    if length(buf) then
        integer fn = open("/dev/dsp","wb")
        if fn!=-1 then
            puts(fn,buf)
            close(fn)
        end if
    end if
end procedure

if platform()=WINDOWS then
    mciSendString("close all")
    mciSendString("open new type waveaudio alias capture")
    mciSendString("set capture" & params)

    puts(1,"Press SPACE to start recording...")
    while wait_key()!=' ' do end while
 
    mciSendString("record capture")
    puts(1,"Recording, press SPACE to stop...")
    while wait_key()!=' ' do end while
 
    mciSendString("stop capture")
    mciSendString("save capture " & wavfile)
    mciSendString("delete capture")
    mciSendString("close capture")
 
    puts(1,"Captured audio is stored in "&wavfile)
elsif platform()=LINUX then
    -- warning: untested
    play(record(65536))
--  -- alternative, from Go (ditto)
--  string name = "test.wav",
--         rate = "2000", -- (2000..192000 Hz)
--         durn = "5" -- (5 to 30 seconds)
--  printf(1,"OK, start speaking now...\n")
--  -- Default arguments: -c 1, -t wav. Note only signed 16 bit format supported.
--  string cmd = sprintf("arecord -r %s -f S16_LE -d %s %s", {rate,durn,name})
--  {} = system_exec(cmd)
--  printf(1,"'%s' created on disk and will now be played back...\n", {name})
--  {} = system_exec("aplay "&name)
--  printf(1,"Play-back completed.\n")
end if

PicoLisp

<lang PicoLisp>(in '(rec -q -c1 -tu16 - trim 0 2) # Record 2 seconds

  (make
     (while (rd 2)
        (link @) ) ) )</lang>

Output:

-> (16767 19071 17279 ... 5503 9343 14719)  # 96000 numbers

Python

<lang python>import pyaudio

chunk = 1024 FORMAT = pyaudio.paInt16 CHANNELS = 1 RATE = 44100

p = pyaudio.PyAudio()

stream = p.open(format = FORMAT,

               channels = CHANNELS,
               rate = RATE,
               input = True,
               frames_per_buffer = chunk)

data = stream.read(chunk) print [ord(i) for i in data]</lang>

Racket

Translation of: C

<lang racket>

  1. lang racket

(define (record n) (with-input-from-file "/dev/dsp" ( () (read-bytes n)))) (define (play bs) (display-to-file bs "/dev/dsp" #:exists 'append)) (play (record 65536)) </lang>

Raku

(formerly Perl 6) Slightly modified from an example provided with the Audio::PortAudio module distribution. <lang perl6>use Audio::PortAudio; use Audio::Sndfile;

sub MAIN(Str $filename, Str :$source, Int :$buffer = 256) {

   my $pa = Audio::PortAudio.new;
   my $format = Audio::Sndfile::Info::Format::WAV +| Audio::Sndfile::Info::Subformat::PCM_16;
   my $out-file = Audio::Sndfile.new(:$filename, channels => 1, samplerate => 44100, :$format, :w);
   my $st;
   
   if $source.defined {
       my $index = 0;
       for $pa.devices -> $device {
           if $device.name eq $source {
               else {
                   my $la = $device.default-high-input-latency;
                   my $si = Audio::PortAudio::StreamParameters.new(device => $index,
                                                                   channel-count => 1,
                                                                   sample-format => Audio::PortAudio::StreamFormat::Float32,
                                                                   suggested-latency => ($la || 0.05e0 ));
                   $st = $pa.open-stream($si, Audio::PortAudio::StreamParameters, 44100, $buffer );
                   last;
               }
           }
           $index++;
       }
       die "Couldn't find a device for '$source'" if !$st.defined;
   }
   else {
       $st = $pa.open-default-stream(2,0, Audio::PortAudio::StreamFormat::Float32, 44100, $buffer);
   }
   $st.start;
   my $p = Promise.new;
   signal(SIGINT).act({
       say "stopping recording";
       $p.keep: "stopped";
       $out-file.close;
       $st.close;
       exit;
   });
   my Channel $write-channel = Channel.new;
   my $write-promise = start {
       react {
           whenever $write-channel -> $item {
               if $p.status ~~ Planned {
                   $out-file.write-float($item[0], $item[1]);
                   $out-file.sync;
               }
               else {
                   done;
               }
           }
       }
   };
   loop {
       if $p.status ~~ Planned {
           my $f = $buffer || $st.read-available;
           if $f > 0 {
               my $buff = $st.read($f,2, num32);
               $write-channel.send([$buff, $f]);
           }
       }
       else {
           last;
       }
   }

}</lang>

Scala

Library: Scala

<lang Scala>import java.io.{File, IOException} import javax.sound.sampled.{AudioFileFormat, AudioFormat, AudioInputStream} import javax.sound.sampled.{AudioSystem, DataLine, LineUnavailableException, TargetDataLine}

object SoundRecorder extends App {

 // record duration, in milliseconds
 final val RECORD_TIME = 60000 // 1 minute
 // path and format of the wav file
 val (wavFile, fileType) = (new File("RecordAudio.wav"), AudioFileFormat.Type.WAVE)
 val format = new AudioFormat(/*sampleRate =*/ 16000f,
   /*sampleSizeInBits =*/ 16,
   /*channels =*/ 2,
   /*signed =*/ true,
   /*bigEndian =*/ true)
 val info = new DataLine.Info(classOf[TargetDataLine], format)
 val line: TargetDataLine = AudioSystem.getLine(info).asInstanceOf[TargetDataLine]
 // Entry to run the program
 // Creates a new thread that waits for a specified of time before stopping
 new Thread(new Runnable() {
   def run() {
     try {
       Thread.sleep(RECORD_TIME)
     } catch {
       case ex: InterruptedException => ex.printStackTrace()
     }
     finally {
       line.stop()
       line.close()
     }
     println("Finished")
   }
 }).start()
 //Captures the sound and record into a WAV file
 try {
   // checks if system supports the data line
   if (AudioSystem.isLineSupported(info)) {
     line.open(format)
     line.start() // start capturing
     println("Recording started")
     AudioSystem.write(new AudioInputStream(line), fileType, wavFile)
   } else println("Line not supported")
 } catch {
   case ex: LineUnavailableException => ex.printStackTrace()
   case ioe: IOException => ioe.printStackTrace()
 }

}</lang>

Tcl

Library: Snack

<lang tcl>package require sound

  1. Helper to do a responsive wait

proc delay t {after $t {set ::doneDelay ok}; vwait ::doneDelay}

  1. Make an in-memory recording object

set recording [snack::sound -encoding "Lin16" -rate 44100 -channels 1]

  1. Set it doing the recording, wait for a second, and stop

$recording record -append true delay 1000 $recording stop

  1. Convert the internal buffer to viewable numbers, and print them out

binary scan [$recording data -byteorder littleEndian] s* words puts [join $words ", "]

  1. Destroy the recording object

$recording destroy</lang>

Wee Basic

<lang Wee Basic>print 1 "Recording..." micrec print 1 "Playing..." micpla end</lang>

Wren

Translation of: Go

The ability to call external processes such as arecord is expected to be added to Wren-cli in the next release. In the meantime, we embed the following Wren script in a C host to complete this task. <lang ecmascript>/* record_sound.wren */

class C {

   foreign static getInput(maxSize)
   foreign static arecord(args)
   foreign static aplay(name)

}

var name = "" while (name == "") {

   System.write("Enter output file name (without extension) : ")
   name = C.getInput(80)

} name = name + ".wav"

var rate = 0 while (!rate || !rate.isInteger || rate < 2000 || rate > 192000) {

   System.write("Enter sampling rate in Hz (2000 to 192000) : ")
   rate = Num.fromString(C.getInput(6))

} var rateS = rate.toString

var dur = 0 while (!dur || dur < 5 || dur > 30) {

   System.write("Enter duration in seconds (5 to 30)        : ")
   dur = Num.fromString(C.getInput(5))

} var durS = dur.toString

System.print("\nOK, start speaking now...") // Default arguments: -c 1, -t wav. Note only signed 16 bit format supported. var args = ["-r", rateS, "-f", "S16_LE", "-d", durS, name] C.arecord(args.join(" "))

System.print("\n'%(name)' created on disk and will now be played back...") C.aplay(name) System.print("\nPlay-back completed.")</lang>
We now embed this in the following C program, compile and run it. <lang c>#include <stdio.h>

  1. include <stdio_ext.h>
  2. include <stdlib.h>
  3. include <string.h>
  4. include "wren.h"

void C_getInput(WrenVM* vm) {

   int maxSize = (int)wrenGetSlotDouble(vm, 1) + 2;
   char input[maxSize];
   fgets(input, maxSize, stdin);
   __fpurge(stdin);
   input[strcspn(input, "\n")] = 0;
   wrenSetSlotString(vm, 0, (const char*)input);

}

void C_arecord(WrenVM* vm) {

   const char *args = wrenGetSlotString(vm, 1);
   char command[strlen(args) + 8];
   strcpy(command, "arecord ");
   strcat(command, args);
   system(command);

}

void C_aplay(WrenVM* vm) {

   const char *name = wrenGetSlotString(vm, 1);
   char command[strlen(name) + 6];
   strcpy(command, "aplay ");
   strcat(command, name);
   system(command);

}

WrenForeignMethodFn bindForeignMethod(

   WrenVM* vm,
   const char* module,
   const char* className,
   bool isStatic,
   const char* signature) {
   if (strcmp(module, "main") == 0) {
       if (strcmp(className, "C") == 0) {
           if (isStatic && strcmp(signature, "getInput(_)") == 0) return C_getInput;
           if (isStatic && strcmp(signature, "arecord(_)") == 0)  return C_arecord;
           if (isStatic && strcmp(signature, "aplay(_)") == 0)    return C_aplay;
       }
   }
   return NULL;

}

static void writeFn(WrenVM* vm, const char* text) {

   printf("%s", text);

}

void errorFn(WrenVM* vm, WrenErrorType errorType, const char* module, const int line, const char* msg) {

   switch (errorType) {
       case WREN_ERROR_COMPILE:
           printf("[%s line %d] [Error] %s\n", module, line, msg);
           break;
       case WREN_ERROR_STACK_TRACE:
           printf("[%s line %d] in %s\n", module, line, msg);
           break;
       case WREN_ERROR_RUNTIME:
           printf("[Runtime Error] %s\n", msg);
           break;
   }

}

char *readFile(const char *fileName) {

   FILE *f = fopen(fileName, "r");
   fseek(f, 0, SEEK_END);
   long fsize = ftell(f);
   rewind(f);
   char *script = malloc(fsize + 1);
   fread(script, 1, fsize, f);
   fclose(f);
   script[fsize] = 0;
   return script;

}

int main(int argc, char **argv) {

   WrenConfiguration config;
   wrenInitConfiguration(&config);
   config.writeFn = &writeFn;
   config.errorFn = &errorFn;
   config.bindForeignMethodFn = &bindForeignMethod;
   WrenVM* vm = wrenNewVM(&config);
   const char* module = "main";
   const char* fileName = "record_sound.wren";
   char *script = readFile(fileName);
   WrenInterpretResult result = wrenInterpret(vm, module, script);
   switch (result) {
       case WREN_RESULT_COMPILE_ERROR:
           printf("Compile Error!\n");
           break;
       case WREN_RESULT_RUNTIME_ERROR:
           printf("Runtime Error!\n");
           break;
       case WREN_RESULT_SUCCESS:
           break;
   }
   wrenFreeVM(vm);
   free(script);
   return 0;

}</lang>