Luat Demo | 給我十分鍾,教你實現Cat.1語音通話功能!


圖片

語音通話是Cat.1模組的重要應用功能之一,合宙官方提供了Luat Demo,便於廣大客戶在手機、對講機、電話手表等終端開發中參考運用。

合宙Cat.1系列中,Air720UH模組支持4G+2G,可直接使用語音通話功能;其他只支持4G制式的模組(如Air720UG、Air724UG),均需先打開VoLTE功能才能進行語音通話。

本文將以Air724UG開發板為例進行實操演示,Demo源碼可通過LuaTools或LuatIDE獲取。
 
 

前期主要准備工作


硬件准備:

EVB_Air724UG_A13開發板(本文操作適用於合宙Cat.1系列的開發板),以及天線、SIM卡、USB線。
圖片

軟件准備:

Windows電腦搭建Luat開發環境,可參考下文:

https://doc.openluat.com/wiki/21?wiki_page_id=1923
 

API說明:

https://doc.openluat.com/wiki/21?wiki_page_id=2267
 
 

通話功能Demo實操演示


例程參考:

CALL通話功能相關實例程序,在LuaTools/LuatIDE腳本庫的demo\call文件夾下。
 

最新版LuatIDE下載:

https://marketplace.visualstudio.com/items?itemName=luater.luatide

圖片
 

腳本邏輯:

 
1)訂閱信息函數

通話的相關事件是通過消息驅動的,首先通過sys.subscribe()注冊消息處理函數。我們通過訂閱來電、接通、結束消息的處理函數,來做不同場景的處理。

sys.subscribe("CALL_INCOMING",incoming)
sys.subscribe("CALL_CONNECTED",connected)
sys.subscribe("CALL_DISCONNECTED",disconnected)

 
2)播放來電鈴音

通過來電消息處理函數,當有電話打進來的時候,模塊會上報CALL_INCOMING來電的消息,我們在上面注冊的消息回調函數incoming()里去做處理。

此處主要是播放來電鈴音,也可以通過TTS方式播放一段語言,同時注冊了一個按鍵消息用於接通電話。

local function incoming(num)
    log.info("testCall.incoming:"..num)    
    if not coIncoming then
        coIncoming = sys.taskInit(function()
            while true do
                --audio.play(1,"TTS","來電話啦",4,function() sys.publish("PLAY_INCOMING_RING_IND") end,true)
                audio.play(1,"FILE","/lua/call.mp3",4,function() sys.publish("PLAY_INCOMING_RING_IND") end,true)
                sys.waitUntil("PLAY_INCOMING_RING_IND")       
               break                

            end
        end)
        sys.subscribe("POWER_KEY_IND",function() audio.stop(function() cc.accept(num) end) end) 
     end     
end

 
3)接通來電

通過注冊開機鍵的消息來接通電話,收到POWER_KEY_IND按鍵消息后,先停止之前的來電鈴聲,然后調用cc.accept()函數來接電話。

sys.subscribe("POWER_KEY_IND",function() audio.stop(function() cc.accept(num) end) end)

 
4)設置mic增益等級及相關操作

通話建立,電話接通后會上報CALL_CONNECTED消息。此時我們就可以在上面注冊的connected()函數里做想做的事情了。

比如:設置MIC增益,調用callVolTest()接口5秒鍾調節一次音量,通過TTS播放的方式向對面播放一段語音,最后啟動一個110S的定時器通過cc.hangUp()掛斷電話。

local function callVolTest()
    local curVol = audio.getCallVolume()
    curVol = (curVol>=7) and 1 or (curVol+1)  
    log.info("testCall.setCallVolume",curVol)

    audio.setCallVolume(curVol)
end

local function connected(num)

      log.info("testCall.connected")
      coIncoming = nil
      --通話中設置mic增益,必須在通話建立以后設置
      --audio.setMicGain("call",7)
      --通話中音量測試
      sys.timerLoopStart(callVolTest,5000)    
      --通話中向對方播放TTS測試

      audio.play(7,"TTS","通話中TTS測試",7,nil,true,2000)    
       --110秒之后主動結束通話

       sys.timerStart(cc.hangUp,110000,num)
end

 
5)掛斷電話

通話結束,電話掛斷之后會上報CALL_DISCONNECTED消息,用來通知通話結束。在disconnected()消息處理函數中,主要是置位一些變量,停止之前開啟的定時器、音頻播放等。

local function disconnected() 

           coIncoming = nil 

           log.info("testCall.disconnected")  

           sys.timerStopAll(cc.hangUp) 

           sys.timerStop(callVolTest)

           audio.stop()          

    end

 
6)撥打電話

這里是在收到網絡注冊NET_STATE_REGISTERED的消息后,啟動了一個定時器10秒后通過調用cc.dial()來撥打電話。

  --- “通話功能模塊准備就緒””消息處理函數
         -- @return 無
         local function ready()

                log.info("tesCall.ready")    --呼叫10086
                sys.timerStart(cc.dial,10000,"10086")
         end

 
7)通話過程中給對方播放音頻

添加demo/audio/testAudioStream.lua的testAudioStream.,在以下代碼中添加參數audiocore.PLAY_VOLTE:

curr_len = curr_len +
audiocore.streamplay(tStreamType,string.sub(data,curr_len,-1),audiocore.PLAY_VOLTE)

local function testAudioStream(streamType)
    sys.taskInit(      
         function()   
              while true do       
                       tStreamType = streamType           
                       log.info("AudioTest.AudioStreamTest", "AudioStreamPlay Start", streamType)                  
                     local tAudioFile =           
                     {
                 
                           [audiocore.AMR] = "tip.amr",  
                           [audiocore.SPX] = "record.spx",    
                           [audiocore.PCM] = "alarm_door.pcm",
             
                           [audiocore.MP3] = "sms.mp3"  
                       }              
                      local fileHandle = io.open("/lua/" .. tAudioFile[streamType], "rb")   
                     if not fileHandle then                        
                     log.error("AudioTest.AudioStreamTest", "Open file error")               
                           return     
                     end

        
       
                     while true do      
                           local data = fileHandle:read(streamType == audiocore.SPX and 1200 or 1024)        
                            if not data then                  
                                                   fileHandle:close() 
                                       while audiocore.streamremain() ~= 0 do   
                                       sys.wait(20)	
                
                                   end
               
                             sys.wait(1000)   
                             audiocore.stop()  --添加audiocore.stop()接口,否則再次播放會播放不出來 
                     log.warn("AudioTest.AudioStreamTest", "AudioStreamPlay Over")                      
                   return 
		    
                          end

                  

                    local data_len = string.len(data)   
                    local curr_len = 1    
                     while true do
               
                          curr_len = curr_len + audiocore.streamplay(tStreamType,string.sub(data,curr_len,-1),audiocore.PLAY_VOLTE)                  
                           if curr_len>=data_len then
   
                                break
                  
                           elseif curr_len == 0 then
                     log.error("AudioTest.AudioStreamTest", "AudioStreamPlay Error", streamType)                                                     return 
                          end    
                          sys.wait(10)         
                    end     
                    sys.wait(10)        
              end
         end    
    end
    )
end    

在connected添加一行testAudioStream(audiocore.AMR) ,添加tip.amr燒錄。調試電話接通后對方即有tip.amr的音頻播放。
 
 

通話功能常見問題


打不了電話,如何排查原因:

確認能不能正常注冊上網絡,有沒有欠費;

確認是否開通VoLTE功能,只有開通VoLTE功能才能進行語音通話;

確認固件是否支持VoLTE功能。

調試天線時,如何設置來電自動接聽:

ril.regUrc(“RING”,function()ril.request(“ATA”) end)

Cat.1是否支持視頻通話?

不支持

mic增益設置:

audio.setMicGain()通話中設置mic增益,必須在通話建立以后設置。

固件是否支持VoLTE:

可以通過固件名稱判斷,帶有NOVoLTE標志的,說明不支持VoLET。 也可以通過AT口發送AT+SETVOLTE?查詢,0
表示關閉VoLET,1表示打開VoLET功能。

上海合宙通信模塊 - 合宙Luat,讓萬物互聯更簡單


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM