3

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.

1

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.

  • this is basically what I ended up doing. – e7zkw9120 Aug 21 '09 at 15:57
0

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.

  • 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
0

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

  • 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
0

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.

0

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

  • i tried this but could not figure out how to configure things correctly in alsamixer. – e7zkw9120 Aug 21 '09 at 15:56
0

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.

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

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