Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I need to simulate the process of recording an audio file, using an existing recording.

I'm running ubuntu 8.10 and had thought this would be quite simple but it seems now to be rather not so simple.

My 'concept' of what I want to do is,


$ cat myaudio.wav > /dev/mic

There is another program listening/waiting for the input.

Edit: Maybe it isn't clear from the way I explained this, but I want to basically spoof the microphone input by streaming a pre-recorded soundfile into the microphone device.
I can do


$ cat /dev/dsp > myfile.au 

to capture the raw input, and


$ cat myfile.au > /dev/dsp

to stream recorded input to my speakers, so I'm a bit confused as to why I can't do something analogous with the microphone/recording function? I still know next to nothing about low level sound stuff on linux but it seems odd that this isn't possible.

share|improve this question

6 Answers 6

Substitute the device node for something else

Move away the device node, or recompile the sound library to open something else. That way, you could put in your own fifo, or bogus loopback sound driver, or something.

share|improve this answer
    
this is basically what I ended up doing. –  e7zkw9120 Aug 21 '09 at 15:57

PulseAudio will allow you to do this, assuming your recording tool also uses PulseAudio. I'm sure that ALSA can be configured to use a different source for your audio. I'm guessing the answer really depends on what application you're using for recording and what stack they're using.

share|improve this answer
    
at present the recording application is just listening for microphone input. my understanding is that it is listening on /dev/dsp although pulseaudio is also running. i had hoped that there was a simple command line solution but it appears this is not the case. looks like im off for a crash course in sound programming with alsa. –  e7zkw9120 Aug 17 '09 at 14:53

Vsound will also help you do this. And the cool thing is you can loop the sound to anything. give it a try. vsound.org

share|improve this answer
    
this looks quite interesting, however as far as i can tell it seems to focus pretty heaviliy on realplayer. im not sure how id go about adapting it to my needs. –  e7zkw9120 Aug 17 '09 at 14:54

Record yourself playing it

Check if you can't set the recording source to the output, then play it. I think this is a common feature of soundcards, but it is something you'd have to persuade the hardware to do.

share|improve this answer

First step was installing the alsa-utilities package (assuming RHEL / CentOS and command line only): yum install alsa-utils

Then enable playback with the alsa mixer command line text user interface: alsamixer

To test the settings I used the speaker testing utility: speaker-test -c2

Got a bit carried away with what speaker test could actually do so here is a fun one that will annoy small animals: speaker-test -c2 -t sine -f 4400

Final part was to see if recording worked with this command: arecord -v -f cd > soundfile.sound

And play it back with: aplay soundfile.sound

share|improve this answer
    
i tried this but could not figure out how to configure things correctly in alsamixer. –  e7zkw9120 Aug 21 '09 at 15:56
up vote 0 down vote accepted

Thanks for all the responses. This turned out to be quite a learning experience. In particular I learned that linux still has some crufty areas and the sound setup is ( perhaps the largest ) one of them.

It's quite easy to cat the microphone input into a file ( or socket ), and intuitively it should be equally simple to cat a file into whatever the mic reads into - so that whatever reads from the mic can read said sound file. This however is, unfortunately not the case.

As a result I ended up modifying the listening program so that it could listen on a socket instead of the raw mic input. I then wrote a simple perl client to redirect the mic input to the socket,



#!/usr/bin/perl -w                                                                                                           
use strict;
use warnings;
use IO::Socket;

my $dspdev = '/dev/dsp';
my $port   = 8000;
my $host   = "127.0.0.1";

my $sock = new IO::Socket::INET(
    PeerAddr => $host,
    PeerPort => $port,
    Type     => SOCK_STREAM,
    Proto    => "tcp",
    ) || die "Couldn't open socket: $!\n";

open(DSP, "<", $dspdev)||die "can't open $dspdev: $!\n";

while( 1 ) {
    my $rbuf = "";
    sysread(DSP, $rbuf, 4096);
    syswrite($sock, $rbuf);
}

At this stage, this is all I needed, however it seems it required a bit more effort than it should have. I've come up with a solution, but I haven't actually answered my original question, so I'll leave this open.

edit: decided to close this as it doesn't seem to be attracting any more attention.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.