Playing wav over modem

slavedogg 0 Tallied Votes 4K Views Share

This code will call a phone number and try to play a wav file. It sounds like a man on a CB that you cant understand. It should be a woman voice. I dont know if its the flo control or something else. Does anyone have any ideas?

System.IO.Ports.SerialPort comPort;
 comPort = new System.IO.Ports.SerialPort("Com2", 115200, System.IO.Ports.Parity.None, 8, StopBits.One);
 comPort.DtrEnable = true;

 //Switch to Voice Mode
 comPort.Write("AT+FCLASS=8" + System.Convert.ToChar(13).ToString());

 //Call Number
 comPort.Write("ATDT1231234" + System.Convert.ToChar(13).ToString());

//Enter Voice-Transmission Mode
 comPort.Write("AT+VTX" + System.Convert.ToChar(13).ToString());

 bool MSwitch = false;
 byte[] buffer = new byte[20000];
 FileStream strm = new FileStream(@"C:\Users\Master\Desktop\Prmpt445.wav", System.IO.FileMode.Open);
 MemoryStream ms = new MemoryStream();
 int count = ms.Read(buffer, 44, buffer.Length-44);
 BinaryReader rdr = new BinaryReader(strm);
         while (!MSwitch)
            {
                byte[] bt = new byte[1024];
                bt = rdr.ReadBytes(1024);
                if (bt.Length == 0)
                {
                    MSwitch = true;
                    break;
                }
                comPort.Write(bt, 0, bt.Length);               
            }
            strm.Close();
            strm.Dispose();
little.daffodil 0 Newbie Poster

I guess it has something to do with the audio rate? I quote this from http://bytes.com/topic/net/insights/703378-how-play-wave-file-phone-c-part-i

"In theory, most human voice frequency falls between 1kHz to 4kHz. Sampling theory (Nyquist) indicates that you will have to take at least 8kHz in order to reconstruct voice content up to 4kHz. Higher than 8kHz would be better to avoid anti-aliasing. However, higher sampling rates come with the price of heavier data load."

Just wondering, are you using internal or external voice modem?

slavedogg 0 Newbie Poster

Sorry I've been working on alternative solutions. I am using an internal pci Encore ENF656-ESW-MOPR Voice data fax modem w/ Motorola chipset. I've tried every possible combination pcm 8000Htz to 1125Hrz 8 and 16bit format @300to700bps I also tried ADPCM8-4-4 to APCM8-16-32 and IMA8-4-3 to IMA11-4-10. I thought the problem might have to do with windows7 so I tried it on a XP machine with no luck. I think the problem is the modem is cheap. I have done alot of reading and I think I need a Dialogic interface card. They are much more developer friendly and offer better support and events. The down side is the cost about $2000.(Ouch!). I found an api for $100 that will work for my current project.FYI VoiceElements.com

little.daffodil 0 Newbie Poster

Hi slavedogg. I'm doing a program similar like yours too, it's just that I'm using an external modem.

I notice that I need to put :

//check voice mode
            comPort.Write("AT+FCLASS=8" + System.Convert.ToChar(13).ToString());
                
            //start calling 
             comPort.Write("ATDT2374" + System.Convert.ToChar(13).ToString());
            System.Threading.Thread.Sleep(20000);

then only the phone will start ringing. Without that, the modem will just blink, but not dialing. But with that, I'm not able to pass my wav file.

If you have any idea on how to deal with this problem if I use external voice modem?

Thanks

slavedogg 0 Newbie Poster

I don't think it makes a difference as far as Internal -vs- External modems. If you can make it Dial your connecting to the device. I used the following code to send the wave to the modem.

byte[] buffer = new byte[20000];
FileStream strm = new FileStream(@"C:\Users\Master\Desktop\Prmpt445.wav", System.IO.FileMode.Open);
MemoryStream ms = new MemoryStream();
int count = ms.Read(buffer, 44, buffer.Length-44);
BinaryReader rdr = new BinaryReader(strm);
while (!MSwitch)
{
byte[] bt = new byte[1024];
bt = rdr.ReadBytes(1024);
if (bt.Length == 0)
{
MSwitch = true;
break;
}
comPort.Write(bt, 0, bt.Length);
}
strm.Close();
strm.Dispose();
little.daffodil 0 Newbie Poster

I don't know slavedogg. I really need to put System.Threading.Thread.Sleep(20000) after sending ATDT command. Otherwise, phone will not ring. Modem will just blink and nothing happen.

After the sleep, the phone will get disconnected. And my external modem is connected through USB port.. maybe that's the reason?

slavedogg 0 Newbie Poster

I dont think its the usb connection. Let me understand this you connect to the com port. Then you switch to voice mode

comPort.Write("AT+FCLASS=8)

You are able to dial the number..

comPort.Write("ATDT2374")

But if you don't put the wait in, it wont dial, and if you use a wait it still disconnects after the wait ends?

What code are you using to connect to the port? Are you sending any other commands?

little.daffodil 0 Newbie Poster

I tried the code given in the 1st post. The ReadLine is because I read the COMport and phone number from a text file.

while ((input = sr.ReadLine()) != null)
                    {

                        if ((input = sr.ReadLine()) != null)
                        {                     
                            //MessageBox.Show("COM Port is " + lines[0]);
                            //MessageBox.Show("Phone number is " + lines[1]);
                            System.IO.Ports.SerialPort comPort;
                            comPort = new System.IO.Ports.SerialPort(lines[0], 9600, Parity.None, 8, StopBits.One);
                            comPort.Open();
                            comPort.DtrEnable = true;

                            //check voice mode
                            comPort.Write("AT+FCLASS=8" + System.Convert.ToChar(13).ToString());
                         
                            //start calling 
                            comPort.Write("ATDT"+ lines[1] + System.Convert.ToChar(13).ToString());
                            System.Threading.Thread.Sleep(17000);
                                                        
                            //to enable voice-transmission mode @ send audio file
                            comPort.Write("AT+VTX" + System.Convert.ToChar(13).ToString());

                            
                            bool MSwitch = false;
                            byte[] buffer = new byte[500000];
                            FileStream strm = new FileStream(@"C:\HelpSound.wav", System.IO.FileMode.Open);
                            MemoryStream ms = new MemoryStream();
                            int count = ms.Read(buffer, 44, buffer.Length - 44);
                            BinaryReader rdr = new BinaryReader(strm);
                            while (!MSwitch)
                            {
                                byte[] bt = new byte[1024];
                                bt = rdr.ReadBytes(1024);
                                if (bt.Length == 0)
                                {
                                    MSwitch = true;
                                    break;
                                }
                                comPort.Write(bt, 0, bt.Length);
                            }
                            strm.Close();
                            strm.Dispose();
                            comPort.Close();
                            comPort.Write("ATH" + System.Convert.ToChar(13).ToString());
                        }

                       
                    }

Yes, you got it right. I need to put the sleep. Let say my sleep is 10000 (10secs), after 10secs, the modem will disconnect, and phone will stop ringing.

While the phone is ringing, and I pick up, nothing happen.

I'm really clueless :-(

slavedogg 0 Newbie Poster

Why is it in a while loop? Are you looping through a list of numbers or something? I would try removing the 1st 'While' and the 1st 'if' statement, that's why it keeps disconnecting. As for it not playing, How are you triggering the play? I used the 'pin changed' event to trigger the playing of the wave. It might be playing at the same time its ringing.

little.daffodil 0 Newbie Poster

The 1st while/if is to read the comport and phone number from a txt file.
Otherwise, the lines[] can't be concatenated :-(

little.daffodil 0 Newbie Poster

What is pin changed by the way? Is is SerialPinChanged?

slavedogg 0 Newbie Poster

I think I got it. You cant send the voice-transmission mode command until after the phone is answered, that's why it keeps dropping the line.

comPort.Write("AT+VTX" + System.Convert.ToChar(13).ToString());

Add 'Pin Change' event to detect an answer, then send the voice-transmission mode and play the wave.

comPort.PinChanged += new SerialPinChangedEventHandler(port_PinChanged);
bguyb 0 Newbie Poster

Hi guys,
I've tried this code and need some help...

The WAV file is playing really fast.
Do you have an idea on why or how to slow it down?

I've doubled check all parameters. they all look fine.
Tx

dwarvenassassin 0 Light Poster

little.daffodil:
You read a line and store it in 'input'

while ((input = sr.ReadLine()) != null)

Then you read another line which overwrites the value stored in 'input'.

if ((input = sr.ReadLine()) != null)

Then you use 'lines' (ie. NOT input) in your modem access code.

comPort = new System.IO.Ports.SerialPort(lines[0], 9600, Parity.None, 8, StopBits.One);

Your code doesn't make sense.

nmwendi_1 0 Newbie Poster

Hi Guys,
I am trying to play audio but all the modems i know here doesnt support voice mode AT+FCLASS=8. Which modem worked slavedogg?

dushi 0 Newbie Poster

hay can any one upload to gdrive your c# solutions which is working and shair a link hear, that helps lot thank you guys

mary r 0 Newbie Poster

Hi everyone
i wrote a code like you shared here but after calling, sound plays really fast and no one can understad what the sound says, would you guys help me here
thanks

eljainc 0 Newbie Poster

You need to change the speechRate variable, which is part of the TAPI SDK.

Umairg404 0 Newbie Poster

Please Upload C# code.

Reverend Jim 4,780 Hi, I'm Jim, one of DaniWeb's moderators. Moderator Featured Poster

Don't hold your breath. The OP hasnb't been on this site in 8 years.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.