Search Results for

    Show / Hide Table of Contents

    DTMF Signalling

    LiveSwitch supports dual-tone multi-frequency signaling (DTMF) for peer connections. Per Mozilla:

    The primary purpose for WebRTC's DTMF support is to allow WebRTC-based communication clients to be connected to a public-switched telephone network (PSTN) or other legacy telephone service, including extant voice over IP (VoIP) services. For that reason, DTMF can't be used between two WebRTC-based devices, because there is no mechanism provided by WebRTC for receiving DTMF codes.

    Note

    About the code examples on this page:

    • For .NET MAUI and Unity, use the C# code.
    • For macOS, use the iOS code.

    Send DTMF Tones

    Sending a DTMF tone is simple.

    Note

    SFU upstreams are send only by definition, so they can send DTMF tones, but not receive them.

    • CSharp
    • Android
    • iOS
    • JavaScript
    audioStream.InsertDtmfTones(FM.LiveSwitch.Dtmf.Tone.FromToneString("..."));
    
    audioStream.insertDtmfTones(fm.liveswitch.dtmf.Tone.fromToneString("..."));
    
    audioStream?.insertDtmfTones(FMLiveSwitchDtmfTone.fromToneString("..."));
    
    audioStream.insertDtmfTones(fm.liveswitch.dtmf.Tone.fromToneString("..."));
    
    Note

    A DTMF tone string is made of up characters from the set "123456789*0#ABCD,". The special character "," indicates a pause.

    You can also hook into an event that is raised when the sending tone changes.

    • CSharp
    • Android
    • iOS
    • JavaScript
    audioStream.OnSendDtmfToneChange += (tone) =>
    {
        Log.Info("Sender's DTMF tone is changing: " + tone.ToString());
    };
    
    audioStream.addOnSendDtmfToneChange(new fm.liveswitch.IAction1<fm.liveswitch.dtmf.Tone>() {
        @Override
        public void invoke(fm.liveswitch.dtmf.Tone tone) {
            Log.info("Sender's DTMF tone is changing: " + tone.toString());
        }
    });
    
    audioStream?.addOnSendDtmfToneChange({ (t: Any!) in
        let tone = t as! FMLiveSwitchDtmfTone
        FMLiveSwitchLog.info(withMessage: "Sender's DTMF tone is changing: " + tone.description())
    })
    
    audioStream.addOnSendDtmfToneChange((tone: fm.liveswitch.dtmf.Tone) => {
        fm.liveswitch.Log.info("Sender's DTMF tone is changing: " + tone.toString());
    });
    

    The empty string "" indicates that the tone has stopped. For browsers, that's all there is to it.

    Additional DTMF Tone Features for Native Platforms

    We've taken it a few steps further on all other platforms (native desktop/mobile), where additional sending and receiving events are available.

    When the receiving tone changes, an event is raised:

    • CSharp
    • Android
    • iOS
    audioStream.OnReceiveDtmfToneChange += (tone) =>
    {
        Log.Info("Receiver's DTMF tone is changing: " + tone.ToString());
    };
    
    audioStream.addOnReceiveDtmfToneChange(new fm.liveswitch.IAction1<fm.liveswitch.dtmf.Tone>() {
        @Override
        public void invoke(fm.liveswitch.dtmf.Tone tone) {
            Log.info("Receiver's DTMF tone is changing: " + tone.toString());
        }
    });
    
    audioStream?.addOnReceiveDtmfToneChange({ (t: Any!) in
        let tone = t as! FMLiveSwitchDtmfTone
        FMLiveSwitchLog.info(withMessage: "Receiver's DTMF tone is changing: " + tone.description())
    })
    

    The empty string "" indicates that the tone has stopped.

    If you want to go lower-level, it's possible to handle the actual packet-level send/receive events which are tied to the clock-rate of the selected audio stream codec (Opus, PCMU, PCMA, etc.).

    Note

    SFU upstreams are send only by definition, so they can send DTMF tones, but not receive them. Similarly, SFU downstreams are receive only by definition. so they can receive DTMF tones but cannot send them.

    • CSharp
    • Android
    • iOS
    audioStream.OnSendDtmfTone += (tone) =>
    {
        Log.Info("Sending DTMF tone: " + tone.ToString());
    };
    audioStream.OnReceiveDtmfTone += (tone) =>
    {
        Log.Info("Received DTMF tone: " + tone.ToString());
    };
    
    audioStream.addOnSendDtmfTone(new fm.liveswitch.IAction1<fm.liveswitch.dtmf.Tone>() {
        @Override
        public void invoke(fm.liveswitch.dtmf.Tone tone) {
            Log.info("Sending DTMF tone: " + tone.toString());
        }
    });
    audioStream.addOnReceiveDtmfTone(new fm.liveswitch.IAction1<fm.liveswitch.dtmf.Tone>() {
        @Override
        public void invoke(fm.liveswitch.dtmf.Tone tone) {
            Log.info("Received DTMF tone: " + tone.toString());
        }
    });
    
    audioStream?.addOnSendDtmfTone({ (t: Any!) in
        let tone = t as! FMLiveSwitchDtmfTone
        FMLiveSwitchLog.info(withMessage: "Sending DTMF tone: " + tone.description())
    })
    audioStream?.addOnReceiveDtmfTone({ (t: Any!) in
        let tone = t as! FMLiveSwitchDtmfTone
        FMLiveSwitchLog.info(withMessage: "Received DTMF tone: " + tone.description())
    })
    
    In This Article
    Back to top Copyright © LiveSwitch Inc. All Rights Reserved.Documentation for LiveSwitch Version 1.24.6