Record sound
Record a monophonic 16-bit PCM sound into either memory space, a file or array.
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
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.)
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>
- include <unistd.h>
- include <sys/types.h>
- 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>
GUISS
Here we activate the Microsoft Windows '95 Sound Recorder:
<lang guiss>Start,Programs,Accessories,Sound Recorder,Button:Record</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>
OCaml
<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>
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>
Tcl
<lang tcl>package require sound
- Helper to do a responsive wait
proc delay t {after $t {set ::doneDelay ok}; vwait ::doneDelay}
- Make an in-memory recording object
set recording [snack::sound -encoding "Lin16" -rate 44100 -channels 1]
- Set it doing the recording, wait for a second, and stop
$recording record -append true delay 1000 $recording stop
- Convert the internal buffer to viewable numbers, and print them out
binary scan [$recording data -byteorder littleEndian] s* words puts [join $words ", "]
- Destroy the recording object
$recording destroy</lang>