Summary: The telephone company's "Caller ID" service provides the calling party's directory information as well as the time and date of the call as an FSK (frequency shift keying) signal between the first and second rings of a telephone call. In this project, develop a complete Caller ID decoder that analyzes an audio recording of the FSK signal to extract the directory and date information for display.
![]() |
This module refers to LabVIEW, a software development environment that features a graphical programming language. Please see the LabVIEW QuickStart Guide module for tutorials and documentation that will help you: |
| • Apply LabVIEW to Audio Signal Processing | |
| • Get started with LabVIEW | |
| • Obtain a fully-functional evaluation edition of LabVIEW |
The telephone company's "Caller ID" service provides the calling party's directory information as well as the time and date of the call as an FSK (frequency shift keying) signal between the first and second rings of a telephone call. In this project, develop a complete Caller ID decoder that analyzes an audio recording of the FSK signal to extract the directory and date information for display.
Refer to the following textbooks for additional background on the project activities of this module; see the "References" section below for publication details:
If you are relatively new to LabVIEW, consider taking the course LabVIEW Techniques for Audio Signal Processing which provides the foundation you need to complete this project activity, including: block diagram editing techniques, essential programming structures, subVIs, arrays, and audio.
You are no doubt familiar with Caller ID, the telephone company service that provides the name and phone number of your incoming caller. The Caller ID service transmits the calling party's directory information (name and telephone number) as well as the date and time of the call between the first and second ring as a binary FSK (frequency shift keying) signal. Click CallerID_audio_example.mp3 to listen to a typical Caller ID FSK signal embedded between the first and second ringer pulses.
After successfully completing this project, your LabVIEW application will be able to read audio recordings such as CallerID_audio_example.mp3 and then extract the Caller ID message for display.
Figure 1 illustrates the Caller ID decoder system to be constructed in this project.
![]() |
The process begins with a call placed by the calling party. The telephone company's subscriber line interface card (SLIC) in the telephone company central office (CO) signals the customer premises equipment (CPE) -- telephone, modem, CallerID unit, etc. -- with a ringing pulse (90 VRMS, 20 Hz, 2 seconds on, 4 seconds off). The CO repeats the ringing pulse as long as the CPE is on hook, that is, the phone has not been answered. Answering the phone call places the CPE in the off hook state, and the CO connects the calling party to the CPE. The terms "on hook" and "off hook" refer to the position of the ear piece or handset in early telephone equipment. The SLIC detects the CPE hook state by the amount of DC current in the customer loop: zero current means on-hook, and non-zero current (about 10 to 20mA) indicates off-hook. The Caller ID FSK signal is transmitted between the first and second ringing pulses provided the CPE is on-hook. For this reason, the interface circuit indicated in Figure 1 must be AC-coupled to the SLIC to prevent drawing DC current.
Caller ID uses the Bell 202 modem standard:
The complete Caller ID message is less than eight tenths of a second in duration. Listen to reduced_tempo_FSK.wav, a reduced tempo version of just the FSK signal; the signal is stretched out in time by a factor of 4, but the original frequencies are preserved.
Hopefully you could discern three distinct regions of the signal:
The message consists of a sequence of 10-bit frames. A start bit of value 0 begins the frame, 8 bits of information follow, and the frame concludes with a stop bit of value 1. The 8 information bits begin with the LSB (least significant bit) and end with the MSB (most significant bit). The information bits form one byte.
The data block message bytes are organized as follows:
The phase-lock loop (PLL) can easily discern the change in frequencies of an FSK signal. The LabVIEW Modulation Toolkit provides a PLL component that serves as an FSK demodulator for this project. Refer to the theory-of-operation screencast video in cid_Demodulator.vi learn how to use this PLL.
The Caller ID message symbol rate is 1,200 symbols per second. The baseband output of the FSK demodulator must be compared to a threshold and sampled at the symbol rate to recover the serial bit stream. The timing recovery system ensures that the thresholded demodulator output is sampled near the midpoint of the symbol. In this project a "local oscillator" produces a squarewave at a nominal frequency of 1,200 Hz. The local oscillator phase is synchronized to the thresholded FSK demodulator output. That is, the local oscillator phase is reset each time a transition is detected on the FSK demodulator output.
Download the required project files contained in CID_Decoder_Project_Files.zip; unpack the files to the same folder in which you plan to build your LabVIEW subVIs and top-level application VIs.
The .zip archive contains the following files:
cid_ParseMessage.vi -- Accepts a text string containing the Caller ID data block bytes,
and parses the string to extract the Caller ID data fields, i.e., date, time, number, and name; also returns information about the data block itself,
namely, message type (SDMF or MDMF), message length, checksum value, and result of checksum calculation. All of the values are returned in a
single cluster.
cid_Display.ctl -- Custom front-panel control to display Caller ID data block information
contained in the cluster generated by cid_ParseMessage.vi. Follow these steps to place the control on
the front panel: Display the front panel, right-click and choose "Select a Control...", and then choose
cid_Display.ctl.
CallerID-N.wav -- Two audio recordings of Caller ID signal embedded between the first and second
ringer pulses. The recordings include three ringer pulses, are approximately 17 seconds in duration, and are sampled at 44.1 kHz.
CallerID-N_19.2kHz.wav -- The same audio recordings
downsampled to 19.2 kHz to produce 16 samples per symbol, the default value for many of the LabVIEW Modulation Toolkit subVIs. Either
audio file can be used for this project, although the downsampled versions shorten run times of the Caller ID decoder application.
cid_Recorder.vi -- LabVIEW VI to monitor the soundcard input for ringer activity;
when detected, record for a fixed time interval and save to a .wav file. Useful to collect several Caller ID signals automatically.
Requires a suitable interface circuit between the telephone wall jack and the computer sound card.
Open the CallerID-1.wav audio recording in Audacity
or an equivalent sound editor to view and listen to the signal. Use the zoom features to study the fine detail of the FSK signal,
especially at the transitions between frequencies.
Repeat for the other .wav audio files included in the download distribution.
Are you able to discern any obvious differences among the various audio recordings?
Possible approaches to analyze the signal generated by the telephone central office include: (1) process each sample as it arrives and generate the decoded message "on the fly," or (2) record the entire signal and then make repeated passes over the recording as needed to extract the message. Real-time implementation requires the former approach, while the latter "off-line" approach is easier to implement as a sequence of subVI calls, and is therefore the method of choice for this project.
Build the subVIs listed below. You may already have some of these available from previous projects.
Demonstrate that each of these subVIs works properly before continuing to the next part. The order in which you build the subVIs does not matter, however, the order presented roughly corresponds to the general processing flow that begins with the audio recording and ends with a collection of bytes.
Build a top-level VI that isolates and demodulates the FSK portion of the complete Caller ID audio signal.
util_GetAudio to load the .wav audio file, and then pass this signal to
cid_Demodulator.vi. Connect front-panel controls to the four parameter inputs
of cid_Demodulator.vi.
Create a mixed-signal waveform chart to display the four signals associated with cid_Demodulator.vi,
namely: FSK signal (the original audio signal applied to the demodulator input),
baseband signal (the demodulated output), phase error magnitude, and
PLL locked.
The Figure 2 screencast video describes how to set up a LabVIEW "Mixed Signal Graph" to plot the waveform data type and Boolean 1-D array on a common timescale, much like an oscilloscope display with multiple analog and digital signals.
![]() |
Set the demodulator VCO carrier frequency to the average value of the mark and space frequencies of the FSK signal.
Experiment with the remaining demodulator parameters VCO gain
(start with values in the range 0.05 to 0.20),
phase error LPF cutoff frequency, and
comparator threshold for PLL lock to satisfy the following goals:
PLL locked is active (T) only during
the FSK signal and is inactive during silence and ringer pulses.
Report your four demodulator parameter values and plot the mixed signal graph that demonstrates the ability of your system to identify the time region over which the FSK signal is active.
Use regen_Sampler.vi to extract the FSK signal region from the baseband signal produced by
cid_Demodulator.vi. Note that regen_Sampler.vi
is used like a "gating" circuit here: the PLL locked signal is active over the entire time that the
FSK signal is detected, therefore regen_Sampler.vi picks out every value from the original
audio recording over which PLL locked is active.
Add the bit sync system to your VI using a zero-crossing comparator, util_EdgeDetector.vi (two instances), regen_BitClock.vi set to 1,200 Hz, and another instance of regen_Sampler.vi. Use the zero-crossing comparator to convert the FSK signal to a Boolean 1-D array. This signal is not a bitstream yet, but rather serves to identify the beginning of bit intervals. Use one edge detector to produce indicator pulses for each zero crossing of the baseband signal (both rising edges and falling edges). These indicator pulses serve as the synchronization for the bit clock oscillator, which produces a square wave synchronized to the baseband signal. The square wave transitions low-to-high at the beginning of the symbol interval and transitions high-to-low at the midpoint of the signal interval. Use an edge detector to produce indicator pulses at the midpoint of the symbol interval which control when the sampler should take samples from the isolated FSK signal.
Create another mixed signal waveform graph to display the isolated FSK signal, the thresholded version of this signal, the indicator pulses that synchronize the bit clock, the bit clock output, and "actual sampling instants" produced by the sampler.
Study your results to ensure that the demodulated baseband signal is sampled properly.
The Figure 3 screencast video shows how you can conserve front-panel real estate by placing two waveform graphs inside a tabbed control.
Use a zero-crossing comparator (specifically of the "less than zero" type) to convert the sampled baseband signal to a bitstream. Process this bitstream with cid_DetectStartBit.vi to extract only the data block portion of the bitstream.
Use util_BitstreamToText.vi to convert the bitstream to a sequence of 8-bit
values ("string" data type), and then use cid_ParseMessage to convert
the text string into an information cluster to be displayed with the custom front-panel control
CID Display.
Include front panel indicators for the framing error and
text out outputs from util_BitstreamToText.vi.
The string indicator can be easily switched from ASCII display to hexadecimal display, as needed: right-click on the
front panel indicator and choose either "Normal Display" or "Hex Display."
The framing error indicator should be dark for the entire data block region; some "left over" bits are likely after the
data block ends due to the delay until the FSK demodulator's PLL locked output
returns to F, and the resulting framing errors may be safely ignored.
Choose one of the Caller ID signal recordings, and run your VI to decode the FSK signal. When all goes well,
the CID Display indicator will show "OK" for both the parsing process
and the checksum calculation.
Confirm that the data block values are correctly extracted by manually decoding the hex values in the text string front panel indicator. More specifically, copy the hex values to a piece of paper, and work through the interpretation of each byte. For example, the first byte of the data block is 0x80, which indicates the Caller ID message is of the MDMF (Multiple Data Message Format) type. The next byte is an 8-bit unsigned integer that indicates message length; convert the hexadecimal value to decimal and report this value. Continue in this way to demonstrate that you understand the significance of each byte in the data block.
Try your Caller ID decoder on other signal recordings. Report the CID Display
indicator values for each audio signal recording.
"The telephone company's "Caller ID" service provides the calling party's directory information as well as the time and date of the call as an FSK (frequency shift keying) signal between the first […]"