Please login or register.

Login with username, password and session length

Author Topic: HomeZIX calls you on the phone  (Read 19491 times)

homevista

  • Full Member
  • ***
  • Helpful Post Rating: 1
  • Posts: 40
  • It is your home, control it your way
    • http://www.automationvista.com
HomeZIX calls you on the phone
« on: August 27, 2007, 07:08:49 AM »

Our goal here: We want HomeZIX to call a designated phone number when something happens, and report it in easy-to-understand spoken audio snippets which are saved in the form of pre-recorded wave files.

PART I: Find out about your modem's capability.

Most modems can be classified with these characteristics:

        * Data/fax
        * Data/fax/voice
        * Data/fax/voice/speakerphone

In our case here, the modem at least has to support the voice feature. The easiest way to find out if your modem supports voice is to run the HyperTerminal to use AT commands.

Run HyperTerminal and use the following commands:

ATZ

The modem should respond with "OK"

AT+FCLASS=8

If your modem supports voice, it should come back with "OK". Otherwise, "ERROR".

If you are interested, you can type AT+FCLASS=?

The modem should respond with something like: 0,1, 2, 8.

    0:       Data

    1,2:    Fax

    8:       Voice

If it turns out you don't have a voice modem, then we're stuck. If you want to go further with this approach, you'll need to install a modem with voice capability.

Now, if you do have a voice modem, you need to find out about its capabilities regarding the voice data formats it can handle. Use the following AT command to find out:

AT+VSM=? (Remember that AT+FCLASS=8 must be sent prior to sending this command.)

Our modem here comes back with the following:

AT+VSM=?
128,"8-BIT LINEAR",(7200,8000,11025)
129,"16-BIT LINEAR",(7200,8000,11025)
130,"8-BIT ALAW",(8000)
131,"8-BIT ULAW",(8000)
132,"IMA ADPCM",(7200,8000,11025)


OK

We interpret this as: Our modem supports 5 different methods of encoding voice data. If you are interested in learning more about these methods, just Google them. In this example, we will focus on the first method (the simplest one). This method uses 8-bit linear (signed numbers) and supports the following sampling rates:

7200, 8000, or 11025 samples per second.

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.

Now, come back to our example, we will choose: 8000 samples per second which is 8kHz. We tell the modem our selection by typing the command:

AT+VSM=128, 8000 (Should get "OK" back.)

Following the above procedure, you should now know if your modem supports voice, and if so, what voice data format it uses. You have to choose the data format now in order to prepare the wave file which will be the topic in PART II.

Tuicemen

  • Administrator
  • Hero Member
  • ****
  • Helpful Post Rating: 282
  • Posts: 10497
  • I don't work for X10, I use it successfuly!
Re: HomeZIX calls you on the phone
« Reply #1 on: August 27, 2007, 05:04:32 PM »

Quote
AT+FCLASS=8

If your modem supports voice, it should come back with "OK". Otherwise, "ERROR".
 

Actually this only works if your modem uses the chip set that uses the AT+ commands!
If you no your modem supports voice but the AT+FCLASS=8
reports an error then try AT#CLS=8!
If you get an OK responce with this then your modem does indeed support voice!
Not knowing what part 2 of this article will contain the commands for sending sounds will differ depending on the chipsets your modems use!
Actualy there is a better way to see what your modem supports!
    [li]go to your control pannel[/li]
    [li]then click on phone and modem connections[/li]
    [li]click on modem [/li]
    [li] then choose your modem from the list which appear[/li]
    [li]click properties [/li]
    [li]click diagnostics [/li]
    [li]the quiry modem a screen will appear stating it is atempting to commumicate with the modem, if successful  the AT commands which your modem suports wil be displayed [/li]
    [/color][/list]
    I look forward to reading the second part perhaps HomeZIX will be able to do every thing AlertDialer can! Voice Modem communication can get tricky, what may work for one persons modem may not work for the next! ;) :D
    Logged
    Please Read Topic:
    General Forum Etiquette
    Before you post!

    homevista

    • Full Member
    • ***
    • Helpful Post Rating: 1
    • Posts: 40
    • It is your home, control it your way
      • http://www.automationvista.com
    Re: HomeZIX calls you on the phone
    « Reply #2 on: August 28, 2007, 03:23:23 AM »

    You're absolutely right about the AT+ and AT#. However, we are not aiming at providing a solution for every modem. Instead, we are trying to show the general guideline from programming prospective. In PARTII we will show you how to read a wave file to a buffer. Then show you how to communicate with the modem via COM port to send the buffer out in PARTIII. Actually, we have all 3 parts available on our website already: http://www.automationvista.com
    Best regards,

    homevista

    • Full Member
    • ***
    • Helpful Post Rating: 1
    • Posts: 40
    • It is your home, control it your way
      • http://www.automationvista.com
    Re: HomeZIX calls you on the phone
    « Reply #3 on: August 28, 2007, 09:11:54 PM »

    Part II: Wave file - How to read to a buffer

    Let's revisit our goal here: We want HomeZIX to call a designated phone number when something happens, and report it in easy-to-understand spoken audio. Until the next release of VoiceZIX when it will be possible for the machine to generate computerized voice, audio snippets are saved in the form of pre-recorded wave files.

    Wave (or Wav) is the standard format for storing audio data on the PC. As software developers, we are interested in the internal structure of the file so that we can open and read data correctly before transmitting it over the phone line.

    Fortunately, there are plenty of good articles on the internet addressing the wave file format. Here is one of them: http://www.sonicspot.com/guide/wavefiles.html

    We show a small except from that article (thanks to sonicspot) to show the typical layout of a wave file:



    We attach here 2 files: (Please click here to go to this topic in our forum to download the files.)
    "houston 8kHz Mono 8.wav" is the WAV file with the famous phrase: "Houston we've got a problem."

    The second attachment is the C# script to (be imported to HomeZIX) which reads the WAV file. Please download and save the wave file to your C:\ drive, and then load the script into HomeZIX (by dropping an Advanced C# block into your workspace, going to the C# source code window, right clicking on the editor, and selecting File->Open.) The implementation is pretty straightforward. If you don't care about the details, just focus on the Initialize() function where we open and read wave data into the buffer.

    As we pointed out in the Part I, we just want to work with a PCM uncompressed Wave file, Mono, 8 bits per sample and 8kHz sample rate. That's why our C# script checks to see if we are reading an appropriate file. You may change the file type-checking functionality to accommodate different formats that your voice modem supports.

    Put HomeZIX in RUN mode (by selecting Manage->Run.) and click on the Advanced Script block. You should then see debug output, similar to what we are seeing here:



    Now, the voice data has been loaded into the buffer. We will send it over the phone line so that whoever answers the phone will hear: "Houston, We've got a problem.".

    * The last part: Putting things together

    homevista

    • Full Member
    • ***
    • Helpful Post Rating: 1
    • Posts: 40
    • It is your home, control it your way
      • http://www.automationvista.com
    Re: HomeZIX calls you on the phone
    « Reply #4 on: August 29, 2007, 09:50:54 PM »

    PART III: Putting things together

    In part I we examined the modem to verify that it supported voice. If so, we took a note about the voice data format that we would use. In the second part, we prepared a wave file and implemented a piece of code in C# to be used by HomeZIX to read the wave file into a buffer. Now, it's time to put things together to send out that buffer as an audio stream over the phone line to a designated phone number.

    In our example here, we are connecting to a voice modem via COM10. It is an old one we got from a local store. We have prepared a wave file: "Houston 8 bit Mono 8kHz.wav" which has the formats: PCM/uncompressed, 8 bits per sample, single channel (mono), 8000 samples per second. We dropped into the HomeZIX's workplace a virtual switch to control when to start calling the number and playing the wave file. Of course, it's only for demonstration purposes. In real use, it should call the number and choose appropriate wave file to play according to particular events such as: motion detected, temperature too high, door open, etc…

    Download the attached script
    to import the C# script to HomeZIX and take a moment to go through the implementation:

    Initialize

    public void Initialize()

    {   // Required function. DO NOT remove or change the name.
        // Called once when the script start executing.
        string fileName = "C:\\houston 8kHz Mono 8.wav";
        if (!System.IO.File.Exists(fileName))
     {
      Debug("Wave file not found.");
      return;
     }
     
        System.IO.FileStream strm = new System.IO.FileStream(fileName, System.IO.FileMode.Open);
        System.IO.BinaryReader rdr = new System.IO.BinaryReader(strm);
        Wave.WAVEFORMATEX wfmt = new Wave.WAVEFORMATEX();
        wfmt.SeekTo(strm);

        // Read in the WAVEFORMATEX structure and attempt to open the
        // device for playback.
        wfmt.Read(rdr);
     Debug("Wave file information:");
     Debug("Wave file encoding: " + wfmt.wFormatTag.ToString());
     Debug("Channels: " + wfmt.nChannels.ToString());
     Debug("Bits per Sample: " + wfmt.wBitsPerSample.ToString());
     Debug("Sampling rate: " + wfmt.nSamplesPerSec.ToString());
     
     if ((wfmt.wFormatTag == 1)&&(wfmt.nChannels == 1) && (wfmt.wBitsPerSample == 8) && (wfmt.nSamplesPerSec == 8000))
     {
         uint dataLength = (uint)(rdr.BaseStream.Length - Wave.WAVEFORMATEX.WF_OFFSET_DATA);
         m_whdr = new Wave.WAVEHDR();
         m_whdr.Read(rdr, dataLength, wfmt.nBlockAlign);
      Debug("Wave file data has been read successfully.");
     } else
     {
      Debug("Unsupported wave file.");
      Debug("This example supports only [PCM/Uncompressed], [Mono], [8 bits per sample], [8kHz samples per second] wave files.");
     }

        rdr.BaseStream.Close();
        rdr.Close();
        rdr = null;
     
     //Initializing COM port
     m_serialPort = new System.IO.Ports.SerialPort();
     m_serialPort.PortName = "COM10";
     m_serialPort.BaudRate = 115200;
     m_serialPort.DataBits = 8;
     m_serialPort.StopBits = System.IO.Ports.StopBits .One;
     m_serialPort.Parity = System.IO.Ports.Parity.None;
     m_serialPort.Handshake = System.IO.Ports.Handshake.None;
     m_serialPort.DtrEnable = true;
     try
     {
      m_serialPort.Open();
      Debug("COM port is ready.");
     } catch
     {
      Debug("Error opening the COM port.");
     }

     m_talking = false;
    }

    We have seen this function in Part II. This time we added initialization for the COM port. In our case here: serial COM10 is connected to our external voice modem. Most modems have an auto detect feature for a serial connection. So the settings here: 115200bps, 8 data bits, 1 stop bit, no parity, no handshaking would likely work. However, check the modem's manual to make sure you set them correctly. Hyper Terminal is a handy tool to test your setup approach.

    Execute
    This function detects if the virtual switch has been turned on. If so, it starts the calling process. Because this function is called every second, we don't want to monopolize the processing time of the main program by processing the modem connection here. Instead, we spawn another thread to do that job.

    public void Execute()
    {   // Required function. DO NOT remove or change the name.
        // Called every second.
     int status = GetStatus("Virtual switch..0.0");
     if ((m_virtualSwitchPreviousState == 0) &&(status > 0))
     {
      if (!m_talking)
      {
       m_talking = true;
       m_phoneThread = new System.Threading.Thread(new System.Threading.ThreadStart(WaveToPhone));
                m_phoneThread.Start();
      }
      m_virtualSwitchPreviousState = status;
     }
     if ((m_virtualSwitchPreviousState > 0) &&(status == 0))
     {
      m_talking = false;
      m_virtualSwitchPreviousState = status;
     }
    }

    This thread has 3 parts: preparing the modem, sending wave data, and finally terminating the session.
    Preparing the modem: These are commands to put the modem in voice mode with our selected voice data encoding format. When a command has been sent to the modem, the script waits for the response. We didn't check the response here since we know it works (from going through Part I.) We simply print out the debug string. The last steps of this phase is to call the number ("ATDT number") and switch the modem to the sending voice data mode ("AT+VTX")


    private void WaveToPhone()
    {
     if ((m_serialPort != null)&&(m_serialPort.IsOpen))
     {
      SendCommand("ATZ");
      GetResponse(1, true);
      SendCommand("AT+FCLASS=8");
      GetResponse(1, true);
      SendCommand("AT+VSM=128,8000");
      GetResponse(1, true);
      SendCommand("ATDT" + m_phoneNumber);
      GetResponse(60, false);
     
      SendCommand("AT+VTX");
     
      System.Threading.Thread.Sleep(500);
      SendVoiceData();
      System.Threading.Thread.Sleep(1000);
      SendVoiceData();
      System.Threading.Thread.Sleep(1000);
      SendVoiceData();
      System.Threading.Thread.Sleep(1000);
     
      byte [] terminator = new byte [2];
      terminator[0] = 0x10;
      terminator[1] = 0x03;
      m_serialPort.Write(terminator, 0, 2);
     
      SendCommand("ATH");
     }
     m_talking = false;
    }

    Sending the wave data.
    In the Initialize function, we already read the data into the buffer from a wave file. It's time now to transfer that buffer as an audio stream to the modem. However, because the modem likely cannot handle large amount of data at once, we send data in chunks of 1024 bytes each. This greatly improves the total throughput ensuring smooth voice on the other end. In our example there, we also repeat the same data buffer 3 times.

    private void SendVoiceData()
    {
     if ((m_whdr == null)||(!m_serialPort.IsOpen)) return;
     int offset = 0;
     int blockSize = 1024;
     int dataLength = m_whdr.data.Length;
     if (dataLength == 0) return;
     try
     {
      Debug("Start sending WAVE data...");
      while (true)
      {
       m_serialPort.Write(m_whdr.data, offset, blockSize);
       if (blockSize < 1024) break;
       offset += blockSize;
       if (dataLength - offset < 1024) blockSize = dataLength - offset;
      }
      Debug("Done sending WAVE data.");
     } catch
     {
      Debug("Error sending WAVE data.");
     }
    }

    Terminating the call.
    Once the wave data has been sent, we terminate the connection by: sending 0x10 0x03 to the modem to switch off the sending mode, and then hang up the phone by sending "ATH". Note that if you plan to have multiple scripts handling different wave files for different events, you will have to close the COM port here as well.

    Closing

    This function is called when the user stops or closes HomeZIX. We simply close the COM port here to release the resource.


    As you can see, the implementation is relatively simple and straightforward. If you are an experience software developer, you shouldn't have any problem following and customizing the code. However, if you have difficulty reading the code (or you don't want to dig in) here are the steps to follow to make it work:

    1. Verify that your modem supports voice. Take a note about the encoding (recommended PCM, 8 bits per sample, Mono, 8KHz sampling rate.)
    2. Prepare wave file(s). Use other software to create and edit your wave file(s) and make sure to save the file(s) to the format selected in step 1.
    3. Drop an Advanced Script block into your HomeZIX workspace, and load the attached C# script.
    4. Change the phone number in the C# script to your choice.
    5. Change the location of the wave file in the C# script, to the location on your computer.
    6. Set up the correct COM settings for your modem.
    7. Change the default "AT+VSM=128,8000" to spcify your encoding method, if different from the default.
    8. Decide if you want to send the wave data one or multiple times.
    9. Decide which event will trigger the calling process. (Replace our logic here to detect when the virtual switch is on by your logic.)
    10. Enjoy.

    It works perfectly here for us, even with the old and cheap voice modem. How does it work for you?

    Houston, we've got no problem at all.

    Tuicemen

    • Administrator
    • Hero Member
    • ****
    • Helpful Post Rating: 282
    • Posts: 10497
    • I don't work for X10, I use it successfuly!
    Re: HomeZIX calls you on the phone
    « Reply #5 on: September 06, 2007, 01:47:06 PM »

    A tidbit of useful info for those with modems that don't respond to the AT+Fclass=8 command but do reply to the AT#CLS=8 command with success!
    Change the AT commands to AT# instead of AT+ and FClass to CLS and you should get voice over the phone with your modem.
    The other settings homevista posted are the same !
    This should get modems with the most common chipsets to work! ;) :D ;D
    Logged
    Please Read Topic:
    General Forum Etiquette
    Before you post!

    Dan Lawrence

    • Hero Member
    • *****
    • Helpful Post Rating: 68
    • Posts: 3991
    Re: HomeZIX calls you on the phone
    « Reply #6 on: September 06, 2007, 06:14:06 PM »

    The only future problem I can foresee is as dial-up service goes away as cable & fiber progress in speed to the customer, the modem will be a piece of hardware that cannot be bought new.

    All modems are 56K at the chips, but throughput is capped by the FTC at 53K.   Anti-virus program updates take hours to download on a dial-up modem, compared in minutes on broadband. 
    Logged
    I don't SELL this stuff... BUT I sure do ENJOY using it!!!

    Tuicemen

    • Administrator
    • Hero Member
    • ****
    • Helpful Post Rating: 282
    • Posts: 10497
    • I don't work for X10, I use it successfuly!
    Re: HomeZIX calls you on the phone
    « Reply #7 on: September 06, 2007, 10:40:27 PM »

    I actually can't see the modem disappearing any time soon as the internet isn't the only thing they are used for! New Voice modems can be picked up dirt cheep right now! I had 2 in my PC along with my eithernet card for broadband when creating the early versions of AlertDialer one of each chip set! Basically HomeZIX's is doing what AlertDialer did in the beginning! ;) :D ;D

    Logged
    Please Read Topic:
    General Forum Etiquette
    Before you post!
     

    X10.com | About X10 | X10 Security Systems | Cameras| Package Deals
    © Copyright 2014-2016 X10.com All rights reserved.