From: Bill Kelly Date: 2003-07-02T23:01:06+09:00 Subject: Re: Question about streaming on Ruby Hi, "Rob" wrote: > At the moment I don't have to care about the voice recognition, I just have to > build something that can save a sound file in the server and something where > the user can press a button called "record my voice" and that as soon as the > server finishes recording the user's voice, the server will play the response file. > > My question is: how to start doing this with Ruby? > Can Ruby do this? > > I asked my friends at my lab, and one friend said I should better forget > Ruby and use active-X. > But my professor said I should try to develop it using Ruby. Since you mention active-X I'm assuming you might be under Windows. Here's a way to Play sounds in Ruby under Windows: http://www.ruby-talk.com/55423 As for recording... I haven't recorded under Windows, but there's a high-level API available for recording, that we should be able to call from Ruby. This page has examples using Windows' winmm.dll MCISendString function to both play and record sounds. The examples are in VB, but translate easily to Ruby using Ruby's Win32API module. http://www.geocities.com/smigman.geo/mci/wav.html (Hmm.. the page seems to be down at the moment... but it's still in Google's cache. If you search for "MCISendString record" [without the quotes] in Google, this site should come up as one of the first hits, called "Visual Basic WAV"... then click on the 'Cached' link :) Here's a Ruby example using MCISendString to play a sound: require 'Win32API' MCISendString = Win32API.new("winmm", "mciSendString", ['P', 'P', 'L', 'L'], 'L') MCISendString.call('open m:\download\snd\columbus.wav type waveaudio alias voice1', nil, 0, 0) MCISendString.call('play voice1', nil, 0, 0) ...I've tried the above on my system and it worked. I haven't tried the following, but the command lines are translated from the above web page: # prepare to record in buffer called "capture" MCISendString("open new type waveaudio alias capture", nil, 0, 0) # set bits-per-sample to 8 or 16 MCISendString("set capture bitspersample 8", nil, 0, 0) # set sample rate (11025, 22050, or 44100) MCISendString("set capture samplespersec 11025", nil, 0, 0) # set mono or stereo (1 or 2 channels) MCISendString("set capture channels 1", nil, 0, 0) # apparently this will record until the user presses "stop" MCISendString("record capture", nil, 0, 0) # alternately it seems you can specify a range in the buffer # in which to record: MCISendString("record capture from 2000 to 4000", nil, 0, 0) # ...so presumably this would allow you to record for a few # seconds and stop automatically without the user having to # click anything. # finally to save the buffer to a file: MCISendString("save capture c:\NewWave.wav", nil, 0, 0) .....Hmmm.... In your case, if you really need to do streaming, a lower-level API would probably be needed. Are you saying you'd need to record a sound (what the user speaks) locally, stream that to the server, have the server do (eventual) voice recognition, and respond with an audio stream back to the user? Since the phrases spoken are probably short, I wonder if you might be able to just use a non-streamed API like MCISendString? And then just transmit the recorded audio file to the server? If you really need streaming, you might want to look into this lower-level WAV API: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/mmfunc_1q5q.asp Here's some info on caling waveInOpen() from VB, which should be easy to translate to Ruby's Win32API like the MCISendString stuff above.. http://www.mentalis.org/apilist/waveInOpen.shtml Hope this helps, Bill