纵览Overview of this Document

介绍Introduction

更新What's New

功能Features

组件及安装Components and Installation

源码发布Source Code Distribution

二进制发布Binary Distribution

安装Installation

测试程序Test Program

接口描述/程序员指南Interface Description/Programmer’s Guide

WINRTP COM 接口WINRTP COM Interface

WINRTP接口详解(ICCNMedia)Details of WINRTP Interface (Interface ICCNMediaTerm)

COM的GUID COM GUIDs, etc

可选参数 Configurable Parameters

静态/动态 抖动缓冲器 Static/Dynamic Jitter Buffer

抖动缓冲区大小Jitter Buffer Length

接收的RTP音频流放大等级 Level of Auto-Amplification of incoming RTP audio streams

发送的RTP包的TOS值Type of Service Value (DiffServ Byte) of Outgoing RTP Packets

指定UDP传输端口Fixed Transmit Port for UDP Packets

发送音频的预加重Pre-emphasis of transmitted audio

接受音频的后加重Post-emphasis of received audio

音量限制Volume Limiting

示例代码Sample Code

未来的改进Future Improvements

This document describes the WinRTP for the Cisco IP SoftPhone from a programmer’s point of view. It discusses the COM interface it provides, installation, and configuration of the component.

此文档以程序员的视角描述了用于Cisco IP电话软件的WINRTP。它论述了WINRTP的COM接口、安装以及各组件的配置。

介绍

The WinRTP (WINRTP) was developed as part of the Cisco IP SoftPhone product. Cisco IP SoftPhone is a PC based telephone integrated with AVVID, and works with the Cisco Call Manager. The primary focus of the WINRTP is to ensure that it works well with other products in AVVID including desktop IP Phones, gateways, etc.It can also be used as an independent component.

·        It is written in C++

·        It is a COM component. (Not an ActiveX control). This makes it easy to use using any programming language like C/C++/Java (using J/Direct) etc.

开发WinRTP是作为Cisco IP SoftPhone产品的一部分。Cisco IP SoftPhone是基于个人电脑的集成AVVID的电话,它和Cisco Call Manager一起工作。WINRTP的主要目的是确保此产品同AVVID(语音、视频和集成数据体系架构)良好的工作,包括桌面IP电话、网关等等。当然,它也可以作为单独组件使用。

The basic job of the WINRTP is to source and sink audio streams to/from the network. So if an application needs the ability to do audio endpointing for real time voice (especially one that is integrated with Cisco’s AVVID), it can use this component.

WINRTP最基础的工作是发起和接收网络上的音频流。如果一个应用软件需要实时语音的支持(特别是当它集成了Cisco的AVVID),它可以使用WINRTP组件。

更新

Here are the improvements since the last version

这里是新版本的改进:

  • Completely standalone package – Compatible with all flavors of desktop Windows starting from Windows 95. Uses standard .DLL files that come with all Windows flavors 完全独立的包—兼容所有从windows95以来的版本,使用标准DLL适用所有windows。
  • Simple distribution: just two DLL's, no more .ax files. Also, the whole software is less than 300 Kbytes 简单的发布:只有两个DLL,再无.ax文件,整个软件小于300K字节
  • Support for multiple sound cards 支持多声卡
  • Dynamic jitter buffer algorithm option: it is very simple, but it works most of the time 动态抖动缓冲设置:简单而有效
  • Audio quality enhancements: including pre-emphasis and post-emphasis of audio to make it sound sharper, automatic amplification of the incoming RTP audio stream 声音质量改善:添加音频预增强和后增强,使声音清晰 。自动增大RTP音频流。
  • Others: Volume limiter algorithm in case you want to use it. 其它:需要时可以音量限制
  • Comes with pre-built binaries for your convenience  带有预先编译好的二进制文件,便于用户使用
  • Ability to play any wav file. Previous format restrictions removed. Also, now you can play as many files at the same time as you want  取消先前格式限制支持播放任何wav 文件。并且,可以同时播放多个文件。

功能

WINRTP consists of two independent parts. One part has the ability to capture the user’s voice (using the system’s microphone), encode it, and send the voice as an RTP (Real Time Protocol) stream to a configurable destination. The other part listens for an RTP stream from the network, extracts the audio from it, and plays it using the PC’s speaker. When both parts are used together, then WINRTP acts like an IP based voice endpoint. Here are the features in short

WINRTP 包含独立的两部分。其一提供捕捉用户声音、编码及以RTP流形式发送语音的功能,另一部分在网络上监听RTP流,从中解出音频并播放。当这两者在一起使用的时候,可以扮演一个基于IP的语音终端,下面是简要的功能介绍:

  • Support for multiple sound devices: This version of WinRTP supports multiple sound devices. This means you can independently choose which audio device to use for transmit and receive if there are multiple audio devices in your PC (for e.g. you have a sound card as well as an USB headset)

支持多个音频设备此版本WinRTP支持多音频设备。这样,如果你的PC上有多个音频设备,你可以自由地选择使用那个设备去发送和接收。

  • Number of streams: currently, only one incoming audio stream and one outgoing audio stream are supported. This is because WINRTP uses the sound card, and only one application can use the system’s speaker or microphone at a time.

流数量:现在只支持一个输入音频流和一个输出音频流。这是因为WINRTP声卡,同时只有一个应用程序可以使用系统扬声器或麦克风。

  • Codec Support: G.711 64kbps (both ALaw and ULaw). The version used in Cisco IP SoftPhone comes with support for G.723 and G.729. However, due to licensing restrictions, that support has been removed from the open source version of WinRTP. This explains some of the parameters (like G723BitRate) in some of the calls in the interface

Codec支持:G.711 64kbps(ALaw及ULaw)。在Cisco IP SoftPhone中使用的版本支持G.723 和 G.729。然而,由于许可限制,这些支持从开源版本的Winrtp中移除了。这说明了在接口调用中存在某些像G723BitRate这样参数的原因。

  • Support for Audio Mixing: WINRTP allows the mixing of other audio streams (from WAV files) to be mixed with the incoming and outgoing audio streams.

混音支持: WINRTP允许输入或输出音频流混合其它来自WAV文件的音频流。

  • Volume Control Support: WINRTP supports setting the volume level for the Microphone, Speaker, and each file that is being mixed in the audio streams.

音量调节支持:WINRTP支持设置麦克风、扬声器以及被混音的音频流的音量。

  • Silence Suppression: WINRTP supports silence suppression (Voice Activity Detection - VAD) of the outgoing streams. This means that if it detects silence (user is not speaking) then it stops sending outgoing RTP packets to conserve network bandwidth.

静音抑制:WINRTP支持输出流的静音抑制(声音活动性检查VAD)。这就是说,如果发现静音(用户没说话),它可以停止输出RTP包,以节省网络带宽。

  • QoS Support: WINRTP supports DiffServ (IP Type of Service-TOS) packet tagging for outgoing RTP packets.

Qos支持:WINRTP支持在输出RTP包中标示DiffServ 。

  • RTP Implementation: Encoding and decoding of RTP packets.

    • WINRTP does not support RTCP, but it does sink RTCP packets sent by the other end to prevent ICMP messages due to discarded packets.

RTP 实现:编码和解码RTP包。

            WINRTP不支持RTCP,但是它可以接收其它端发来的RTCP包,以免ICMP消息导致的丢包。

  • Independence of transmit/receive sides: The transmit and receive sides are independent, and that means

    • Different codecs may be used for transmit and receive
    • User can choose to do only one of the two operations

发送和接收端的独立性:发送和接收端是独立的,这就是说:

发送和接收可以使用不同的codecs(多媒体数字信号编解码器)。

用户可以选择只做其中某项操作。

  • Operating Systems Supported: All flavors of windows Windows95 and later, including Windows NT (Service Pack 3 onwards), Windows ME and Windows 2000/XP

操作系统支持:支持Windows95以后的版本,包括WindowsNT,WindowsME 及Windows2000/XP

  • Configurable/Dynamic Jitter Buffer: The depth of the jitter buffer can be specified, or a dynamic jitter buffer can also be used

可配置动态的抖动缓冲:可以设置抖动缓冲的深度值,也可以使用动态抖动。

  • DSP algorithms: like pre-emphasis and post-emphasis to make the audio sound sharper. Volume limiting to control the max volume, and auto-amplification of incoming RTP audio streams

DSP算法: 如预加重及后加重使声音更清晰,音量限制控制最大音量,自动放大输入的RTP音频流。

组件及安装

The distribution comes with both source code and binaries. Extract the ZIP file to obtain everything. It will create a directory calledWinRTP, which will contain everything.

发行版同时包含了源代码及二进制文件。解开ZIP文件,可以得到所有文件。

源代码发布

Build Order 编译 顺序

  1. TracerServer
  2. Tracer
  3. CCNMediaTerm

This will create TraceServer.dll and CCNSMT.dll. Build these projects either in Debug or Release mode.

这将建立TraceServer.dll 和CCNSMT.dll 两个文件,请在Debug和Release两个模式下都编译。

二进制发布

WINRTP binary distribution consists of two DLL files under the WinRTP directory. The main COM DLL (CCNSMT.dll) that exposes the WINRTP interface is about 200Kbytes while the other (TraceServer.dll) DLL (used for tracing) is 28Kbytes

WINRTP的二进制发布在WinRTP目录下包含了两个DLL文件。主要的COM 动态链接库(CCNSMT.dll)提供给我们WINRTOP的接口,大概200K字节大小。TraceServer.dll 28K字节。

安装

Third Party Dependencies 第三方依赖

None 无

Location of Distributed Files 文件位置:

  • TraceServer.dll: Put TraceServer.dll in the SYSTEM directory of windows (i.e. /WINDOWS/SYSTEM of win95/98/ME or /WINNT/SYSTEM32 on win nt/2000

TraceServer.dll: 将TraceServer.dll 放到windows的系统目录(如 win95/98/ME  下的/WINDOWS/SYSTEM  或winNT/200下的 /WINNT/SYSTEM32 )

  • CCNSMT.dll: This is a COM component, so its location is not important as long as it is registered with the system. It is recommended that it be kept all together in a separate directory or in the directory of the application that is using the WinRTP.

CCNSMT.dll: 这是一个COM组件,当它被系统注册以后它的位置已经不重要。推荐将它保存在一个单独的目录中或使用WINRTP的应用程序目录。

Final Install Steps 最后一步:

All COM objects must be registered before WINRTP can be used. For this, use the regsvr32 program that comes with windows (it may be found in the system directory)

所有COM对象在使用前必须进行注册,对于WINRTP,我们可以使用windows自带的regsvr32程序完成,命令如下:

  • Regsvr32 CCNSMT.dll

测试程序

There is also a test program (both source code and binary) that is available. It is a simple program that does not exercise all the features. It just connects your default microphone to your default speaker for 5 seconds so that you can hear yourself, and then exits. The source code is in the “WinRTP/TestWinRTP” folder and the binary is WinRTP/TestWinRTP.exe

这里还包含一个供测试用的程序(源代码及二进制)。它是一个简单的程序,并没有调用所有的功能,它只是连接你默认的麦克风到你默认的扬声器5秒钟时间,这期间,你可以从扬声器中听到你自己的声音。源代码在“WinRTP/TestWinRTP”目录下,二进制文件为“TestWinRTP.exe”。

’s Guide 接口描述及程序员指南

The WinRTP main DLL is CCNSMT.dll which exposes a COM interface that can be used to make calls to the WINRTP.

WinRTP主要的DLL是CCNSMT.dll,它提供了我们一个COM接口用于调用WINRTP。

WINRTP COM 接口

The interface of WINRTP (ICCNMediaTerm) consists of the following functions

WINRTP接口包含下面的函数:

  • HRESULT Initialize()
  • HRESULT UnInitialize()
  • HRESULT StartMicrophone() - not implemented/needed in this version.
  • HRESULT StopMicrophone() - not implemented/needed in this version.
  • HRESULT StartAudioReceive() - not implemented/needed in this version.
  • HRESULT StopAudioReceive() - not implemented/needed in this version.
  • HRESULT SetAudioCodecRX(
                                                     [in] long CompressionType,
                                                     [in] long MillisecPacketSize, 
                                                     [in] long EchoCancellationValue,
                                                     [in] long G723BitRate
                                                     )
  • HRESULT SetAudioCodecTX(
                                                    [in] long CompressionType,
                                                    [in] long MillisecPacketSize,
                                                    [in] long PrecedenceValue,
                                                    [in] long SilenceSuppression,
                                                    [in] unsigned short MaxFramesPerPacket,
                                                    [in] long G723BitRate
                                                    )
  • HRESULT SetAudioDestination(
                                                     [in] BSTR strHostName,
                                                     [in] long nUDPortNumber
                                                     )
  • HRESULT SetAudioReceivePort(
                                                       [in] long nUDPPortNumber
                                                       )
  • HRESULT StartPlayingFileTX(
                                                   [in] BSTR Filename,
                                                   [in] unsigned long Mode,
                                                   [in] unsigned long StartPosition,
                                                   [in] unsigned long StopPosition,
                                                   [in, out] long * Cookie
                                                   )
  • HRESULT StartPlayingFileRX(
                                                   [in] BSTR Filename,
                                                   [in] unsigned long Mode,
                                                   [in] unsigned long StartPosition,
                                                   [in] unsigned long StopPosition,
                                                   [in] unsigned long waveoutDeviceID,
                                                   [in, out] long * Cookie
                                                   )
  • HRESULT StopPlayingFileTX(
                                                   [in] unsigned long Cookie
                                                   )
  • HRESULT StopPlayingFileRX(
                                                   [in] unsigned long Cookie
                                                   )
  • HRESULT StartTX(unsigned long waveinDeviceID)
  • HRESULT StopTX()
  • HRESULT StartRX(unsigned long waveoutDeviceID)
  • HRESULT StopRX()
  • HRESULT SetSpeakerVolume(
                                                    [in] unsigned long volume
                                                    )
  • HRESULT SetMicrophoneVolume(
                                                         [in] unsigned long volume
                                                         )
  • HRESULT SetFilePlayVolume(
                                                   [in] unsigned long cookie,
                                                   [in] unsigned long volume
                                                   )

Events From WINRTP

WINRTP not only exposes a COM interface, it also has the ability to fire events to the component that using WINRTP. This is done through the standard Connection Point mechanism. For information on connection points read a book on COM and ATL (Active Template Library). The basic idea is that WINRTP describes a COM interface for receiving events. If a component implements that COM interface, then it can subscribe itself as a listener of events generated by the WINRTP.

WINRTP 不只提供给我们一个COM接口,它还具有发送事件给组件的功能。它从头至尾完成了标准的连接点机制(要了解关于connection points的信息,请查看关于COM和ATL的书籍)。基本的想法是WINRTP 给出一个COM 接口用于接收事件。如果一个组件实现了这个接口,则它可以把自己作为WINRTP事件的监听者。 PS:不太懂COM,瞎翻译的

The events interface (ICCNMediaTermEvents) is as follows

·        HRESULT EndOfFileEventRX(
                                                [in] long Cookie
                                                )

·        HRESULT EndOfFileEventTX(
                                                [in] long Cookie
                                                )

ICCNMediaTerm)  WINRTP接口详解

All methods in the interface return an HRESULT value. If the method succeeds, they return 0, otherwise a negative number for failure. The return values are changing L so the recommended way to debug any function  failures is to use the trace mechanism (i.e. turn on tracing for the WINRTP, and look at the trace file which includes a description of the error that caused the negative return value. If problems persist, contact the developer of WINRTP for details/help.In some cases, some of the important return values may be discussed for a function, but not for all functions

所有的方法都返回一个HRESULT值。如果方法成功,返回0,否则,返回一个负数表示失败。返回值是变化的,所以推荐的调试函数返回失败的方法是使用trace机制。(如,打开WINRTP的tracting,查看包含负值返回的错误描述的trace文件。如果问题无法解决请联系WINRTP开发者得到详细资料或帮助。有些情况下,函数的一些重要返回值可能需要讨论,但不是所有都这样)

HRESULT Initialize()

 

Description:

Initializes the WINRTP. Instantiates all components. Also sets up default codecs using the following calls

初始化WINRTP,初始化所有组件,并且使用下面调用设置默认codecs:

  • SetAudioCodecTX(Codec = G711 Ulaw 64kbps, 20, 0, 0, 1, 0)
  • SetAudioCodecRX(Codec = G711 Ulaw 64kbps, 20, 0, 0)

This function must be called before any other calls to WINRTP

调用所有其它WINRTP函数前必须调用该函数。

 

Parameters:

None 无参数

HRESULT UnInitialize()

Description:

Uninitializes the WINRTP and releases all allocated resources. This must be the last call made to the WINRTP

销毁WINRTP,释放所有分配的资源。这必须是WINRTP的最后一个调用。

Parameters:

None 无参数

HRESULT StartMicrophone()

Description:

No implemented/needed in this version

没有在此版本中实现

Parameters:

None

HRESULT StopMicrophone()

Description:

No implemented/needed in this version

没有在此版本中实现

Parameters:

None

HRESULT StartAudioReceive()

Description:

No implemented/needed in this version

没有在此版本中实现

Parameters:

None

HRESULT StopAudioReceive()

Description:

No implemented/needed in this version

没有在此版本中实现

Parameters:

None

HRESULT SetAudioCodecRX

Description:

Call this function to inform WINRTP of the audio codec used to encode the incoming RTP stream. This function may be called before StartRX is called. (so you may need to call StopRX before making this call). If called before StartRX is called, it sets the codec for the next invocation of StartRX. If it is called while receiving audio (i.e. after StartRX) it may return an error.

调用这个函数通知WINRTP对输入RTP流使用那个编码。此函数可能在StartRX之前调用(所以,你可能需要此函数前调用StopRX)。如果StartRX已经调用了,它将设置下一个StartRX,如果调用时正在接收数据,它返回一个错误。

Parameters:

[in] long CompressionType: The following values are supported

·        2 : G.711 Alaw 64kbps

·        4 : G.711 Ulaw 64kbps

[in] long MillisecPacketSize: Specifies the length of audio in each incoming RTP audio packets

[in] long EchoCancellationValue: Ignored. Put any value here. Echo cancellation is not supported in the WINRTP

[in] long G723BitRate: Ignored

HRESULT SetAudioCodecTX

Description:

Sets the audio codec for the transmit stream (outgoing stream). Should be called while NOT streaming (i.e. before StartTX/after StopTX)

设置输出流的codecs,需要在没有流传输时调用(如,StartTX之前,StopTX之后)

Parameters:

[in] long CompressionType: See SetAudioCodecRX

[in] long MillisecPacketSize: See SetAudioCodecRX

[in] long PrecedenceValue: Ignored

[in] long SilenceSuppression: Specifies whether to do silence suppression in the transmit stream

0 : Silence suppression is turned OFF

1 : Silence suppression is turned ON

[in] unsigned short MaxFramesPerPacket: Ignored

[in] long G723BitRate: See SetAudioCodecRX

HRESULT SetAudioDestination

Description:

Sets the destination [IP Address, UDP Port] where the send side audio stream should be transmitted. Must be called while not streaming (i.e. Before StartTX/after StopTX).

设置发送端传输音频流的目的地[IP地址,UDP端口] 。必须在无流传输时调用(如,StartTX之前,StopTX之后)。

 

Parameters:

[in] BSTR strHostName: IP address of the destination. E.g. “171.69.12.34”
[in] long nUDPortNumber: UDP port number where to send the stream

HRESULT SetAudioReceivePort

Description:

Informs the WINRTP of the UDP port number where it should listen for the incoming RTP audio stream. Note: StartAudioReceive must be called before any audio from the incoming stream is played to the speaker.

告知WINRTP用于监听输入RTP音频流的UDP地址。注:StartAudioReceive必须在输入流已经播放之前。

 

Parameters:

[in] long nUDPPortNumber: UDP port number

HRESULT StartPlayingFileTX

Description:

This method should be used when a WAV file needs to be transmitted. The audio from the file is mixed in with the outgoing audio stream (user’s voice). The WINRTP fires an event to let the caller know when the file has finished playing, so that another file may be played. If the file finished playing, the WINRTP automatically calls StopPlayingFileTX so the caller need not call it. Only one file may be playing at a time. If this function is called while another file is playing already, an error is returned and the original file keeps playing. The function returns an unique identifier (cookie) that may be used in later calls related to this file play (to set the volume, or stop it from playing any more). This method can also play the file in a loop continuously without stopping. By default, files start playing at 25% volume.

此方法用于WAV文件需要传输时。文件的音频将同输出流混音。WINRTP发送一个事件让调用者知道文件已经播放完毕,这时其它文件可以播放。当文件播放完毕,WINRTP自动调用StopPlayingFileTX ,调用者不必再调用。同一时刻只能播放一个文件。如果此函数调用时已经有文件在播放,此调用将返回一个错误,原来的文件将继续播放。函数返回一个唯一标示,可以被用于之后的函数调用(设置音量、停止播放等)。此方法也可以无间断地重复播放一个文件。默认情况下,文件以25%的音量大小播放。

 

Parameters:

[in] BSTR Filename: the location (path) of the file to be played  待播放文件的位置(路径)

[in] unsigned long Mode: specifies whether to play the file once or in a loop 制定播放一次或循环

·        0 : play the file continuously in a loop

·        1 : play the file once

[in] unsigned long StartPosition: unimplemented/ignored

[in] unsigned long StopPosition: unimplemented/ignored

[in, out] long * Cookie: WINRTP returns a unique ID for this instance of the file being played. This cookie should be used in later calls pertaining to the instance of the file playing

HRESULT StartPlayingFileRX

Description:

This function starts mixing audio from the specified file to the received audio stream, so that the user hears audio from both the incoming audio stream and the file. The only difference is that we can have two files playing simultaneously in the receive side instead of one. By default, files start playing at 25% volume.

此函数开始对接收音频流和制定的文件进行混音。用户将同时听到输入音频流和文件音频,唯一的不同点是我们可以在接收端同时播放两个文件。默认音量为25%。

 

Parameters:

Exactly the same as StartPlayingFileTX, but with another extra parameter

[in] unsigned long waveoutDeviceID: specifies which speaker device to play the file to. WinRTP now allows you to play the file using the wave/speaker device opened for audio (with StartRX) or to another wave/speaker device. sometimes it may be useful to play a file locally to another audio device (for e.g. if you are using a USB headset for speech, you may want to play ring tones for incoming calls through  the speakers connected to the sound card so that it is heard loudly). See StartRX for a discussion on waveoutDeviceID

HRESULT StartTX

Description:

Starts streaming on the transmit side. This method must be called before StartPlayingFileTX is called. Calling this method starts transmitting the user’s voice

在传输端开始流。此函数必须在StartPlayingFileTX函数调用前。调用此方法开发传输用户语音。

Parameters:

unsigned long waveinDeviceID: specifies which audio device to use for audio capture/recording. device ID's are numbered 0...(#of recording audio devices-1), and -1 means use default audio device for windows. Check out waveInOpen() and waveInGetDevCaps() in the windows API. If you are confused, -1 actually means (unsigned long) –1.

HRESULT StartRX

Description:

Sets up WINRTP to start the receive side. It also starts playing the received audio to the speaker.

设置接收端开始WINRTP,它也开始播放接收到的音频。

Parameters:

unsigned long waveoutDeviceID: specifies which audio device to use for playback/speaker. These device ID's are numbered 0 ... (# of playback devices - 1), and -1 means use the default playback device. Check out waveOutOpen() and waveOutGetDevCaps() functions in the windows API.. If you are confused, -1 actually means (unsigned long) –1.

HRESULT StopTX

Description:

Stops transmitting audio. Stops transmitting the user’s voice and files.

停止传输语音。停止传输用户语音及文件。

Parameters:

None

HRESULT StopRX

Description:

Stops receiving and playing audio. Stops playing the received audio stream and the files

停止接收和播放音频。停止播放接收的音频流及文件。

Parameters:

None

HRESULT SetSpeakerVolume

Description:

Sets the speaker volume on the PC. This setting sets the WAVEOUT volume of the system (not the master volume).

设置PC扬声器音量。此调用设置系统的WAVEOUT音量(不是主音量)。

Parameters:

[in] unsigned long volume: value between 0 and 100 where 0 = silence, and 100 = max volume. The scale is linear, so 50 = half volume

HRESULT SetMicrophoneVolume

Description:

Sets the microphone volume. This setting changes the PC’s microphone volume or audio capture volume.

设置麦克风音量。此调用改变麦克风音量或音频捕捉音量。

Parameters:

[in] unsigned long volume: value between 0 and 100 where 0 = silence, and 100 = max volume. The scale is linear, so 50 = half volume

HRESULT SetFilePlayVolume

Description:

Sets the volume of a file being played by the WINRTP.

设置WINRTP正在播放的文件的音量

Parameters:

[in] unsigned long cookie: the cookie that pertains to this instance of the file play. The cookie is obtained when StartPlayingFileTX(or RX) is called


[in] unsigned long volume: 
Volume setting. Starts from 0 (silence) to 100 (max volume)

HRESULT StopPlayingFileTX

Description:

Stops a file being played in the transmit side

在传输端停止当前文件播放

Parameters:

[in] unsigned long Cookie: Cookie that was returned when the file started playing.

HRESULT StopPlayingFileRX

Description:

Stops a file being played in the receive side

在接收端停止当前文件播放。

Parameters:

[in] unsigned long Cookie: Cookie that was returned when the file started playing.

GUIDs, etc

The important GUIDs are  最主要的GUID为:

  • WinRTP COM object (CCNMediaTerm class) : 94221C4E-00F1-11D4-9D59-0060B0FC246C
  • WinRTP COM Inteface (ICCNMediaTerm) : 94221C4D-00F1-11D4-9D59-0060B0FC246C
  • WinRTP Events Interface (_ICCNMediaTermEvents) : 94221C4F-00F1-11D4-9D59-0060B0FC246C

The following code snippet may be useful for more information 下面的小代码断可能会提供更多信息:

WINRTP Interface

// CCNSMT.idl : IDL source for CCNSMT.dll
//

// This file will be processed by the MIDL tool to
// produce the type library (CCNSMT.tlb) and marshalling code.

import "oaidl.idl";
import "ocidl.idl";
[
object,
uuid(94221C4D-00F1-11D4-9D59-0060B0FC246C),

helpstring("ICCNMediaTerm Interface"),
pointer_default(unique)
]
interface ICCNMediaTerm : IUnknown
{
[helpstring("method Initialize")]
HRESULT Initialize();
[helpstring("method UnInitialize")]
HRESULT UnInitialize();
[helpstring("method StartMicrophone")] 
HRESULT StartMicrophone();
[helpstring("method StopMicrophone")] 
HRESULT StopMicrophone();
[helpstring("method StartAudioReceive")] 
HRESULT StartAudioReceive();
[helpstring("method StopAudioReceive")] 
HRESULT StopAudioReceive();
[helpstring("method StopDtmfTone")] 
HRESULT StopDtmfTone();
[helpstring("method SetAudioCodecRX")] 
HRESULT SetAudioCodecRX([in] long CompressionType, [in] long MillisecPacketSize, [in] long EchoCancellationValue, [in] long G723BitRate);
[helpstring("method SetAudioCodecTX")] 
HRESULT SetAudioCodecTX([in] long CompressionType, [in] long MillisecPacketSize, [in] long PrecedenceValue, [in] long SilenceSuppression, [in] unsigned short MaxFramesPerPacket, [in] long G723BitRate);
[helpstring("method SetAudioDestination")] 
HRESULT SetAudioDestination([in] BSTR strHostName, [in] long nUDPortNumber);
[helpstring("method SetAudioReceivePort")] 
HRESULT SetAudioReceivePort([in] long nUDPPortNumber);
[helpstring("method StartDtmfTone")] 
HRESULT StartDtmfTone([in] long cToneAsChar, [in] long OnTime, [in] long OffTime);
[helpstring("method StartPlayingFileTX")] 
HRESULT StartPlayingFileTX([in] BSTR Filename, [in] unsigned long Mode, [in, out] long * Cookie);
[helpstring("method StartPlayingFileRX")] 
HRESULT StartPlayingFileRX([in] BSTR Filename, [in] unsigned long Mode, [in] unsigned long waveoutDeviceID, [in, out] long * Cookie);
[helpstring("method StopPlayingFileTX")] 
HRESULT StopPlayingFileTX([in] unsigned long Cookie);
[helpstring("method StopPlayingFileRX")] 
HRESULT StopPlayingFileRX([in] unsigned long Cookie);
[helpstring("method StartTX")] 
HRESULT StartTX([in] unsigned long waveinDeviceID);
[helpstring("method StopTX")] 
HRESULT StopTX();
[helpstring("method StartRX")] 
HRESULT StartRX([in] unsigned long waveoutDeviceID);
[helpstring("method StopRX")] 
HRESULT StopRX();
[helpstring("method SetSpeakerVolume")] 
HRESULT SetSpeakerVolume([in] unsigned long deviceID, [in] unsigned long volume);
[helpstring("method SetMicrophoneVolume")] 
HRESULT SetMicrophoneVolume([in] unsigned long deviceID, [in] unsigned long volume);
[helpstring("method SetFilePlayVolume")] 
HRESULT SetFilePlayVolume([in] unsigned long cookie, [in] unsigned long volume);
[helpstring("method NetworkMonitor")] 
HRESULT NetworkMonitor([in] unsigned long Enable, [in] unsigned long DurationMillisec);
};

[
uuid(94221C4F-00F1-11D4-9D59-0060B0FC246C),
helpstring("_ICCNMediaTermEvents Interface")
]
interface _ICCNMediaTermEvents : IUnknown
{
[helpstring("method EndOfFileEventRX")] 
HRESULT EndOfFileEventRX([in] long Cookie);
[helpstring("method EndOfFileEventTX")] 
HRESULT EndOfFileEventTX([in] long Cookie);
[helpstring("method NetworkMonitorEventRX")] 
HRESULT NetworkMonitorEventRX([in] double RXMean, [in] double RXVariance);
[helpstring("method NetworkMonitorEventTX")] 
HRESULT NetworkMonitorEventTX([in] double TXMean, [in] double TXVariance);
};

[
uuid(94221C40-00F1-11D4-9D59-0060B0FC246C),
version(1.0),
helpstring("CCNSMT 1.0 Type Library")
]
library CCNSMTLib
{
importlib("stdole32.tlb");
importlib("stdole2.tlb");

[
uuid(94221C4E-00F1-11D4-9D59-0060B0FC246C),
helpstring("CCNMediaTerm Class")
]
coclass CCNMediaTerm
{
[default] interface ICCNMediaTerm;
[default, source] interface _ICCNMediaTermEvents;
};
};

Type Library

[

uuid(94221C40-00F1-11D4-9D59-0060B0FC246C),

version(1.0),

helpstring("CCNSMT 1.0 Type Library")

]

library CCNSMTLib

{

importlib("stdole32.tlb");

importlib("stdole2.tlb");

[

uuid(94221C4E-00F1-11D4-9D59-0060B0FC246C),

helpstring("CCNMediaTerm Class")

]

coclass CCNMediaTerm

{

[default] interface ICCNMediaTerm;

[default, source] interface _ICCNMediaTermEvents;

};

};

Sample C++ Code 示例C++代码:

Using the type library generated while compiling WinRTP (CCNSMT.tlb) one can easily use WinRTP in code. Visual C++ 6.0 allows importing a type library in the #import command, as the following sample code shows. Note that you cannot import WinRTP as a COM object into your project because it is NOT and ActiveX control nor does it support IDispatch.

使用编译WINRTP时得到的类型库文件,可以在编码时很容易的使用WinRTP。就像下面代码显示的那样,VC 6.0 允许使用#import 命令导入一个类型库。注意,你不可以把WINRTP当作一个COM 对象导入你的工程,因为它不是。而且ActiveX 控件也不支持IDispatch。

#import "../CCNMediaTerm/CCNSMT/CCNSMT.tlb" no_namespace, raw_interfaces_only

int main()
{
HRESULT hr;

// Initialize COM
hr = CoInitialize(NULL);

// Get Interface ICCNMediaTerm from the WinRTP COM Object using smart pointer defined by the #import command above. 
// Automatically calls IUnknown::AddRef();
ICCNMediaTermPtr pICCNMediaTerm(__uuidof(CCNMediaTerm));

// Initialize WinRTP. Must be the first call
pICCNMediaTerm->Initialize();

// Set parameters for receive side
pICCNMediaTerm->SetAudioCodecRX(4, 20, 0, 0);
pICCNMediaTerm->SetAudioReceivePort(8500);

// Set parameters for transmit side
pICCNMediaTerm->SetAudioCodecTX(4, 20, 0, 0, 0, 0);
pICCNMediaTerm->SetAudioDestination(L"127.0.0.1", 8500);

// Start reception side. we will use the default (-1) playback device
pICCNMediaTerm->StartRX(-1);

// Start transmit side. we will use the default (-1) recording device
pICCNMediaTerm->StartTX(-1);

// Set the speaker volume to 50%
pICCNMediaTerm->SetSpeakerVolume(-1, 50);

// Set the microphone volume to 50%
pICCNMediaTerm->SetMicrophoneVolume(-1, 50);

// Hear yourself for 5 seconds
Sleep(5000);

// Stop reception & transmission
pICCNMediaTerm->StopRX();
pICCNMediaTerm->StopTX();

// Unitialize WinRTP. Must be the last call
pICCNMediaTerm->UnInitialize();
// Let go of the reference to the ICCNMediaTerm interface. Automatically calls IUnknown::Release()
pICCNMediaTerm = 0;

// Uninitialize COM
CoUninitialize();

return 0;
}

可选参数

The configurable parameters of WINRTP are mostly set using the registry. The registry key for these settings is HKEY_CURRENT_USER/Software/Cisco Systems/CCNMediaTerm/1.0. If these entries do not exist in the registry, then the WINRTP creates them automatically with the default values the first time it needs to use them.

大部分WINRTP的可选参数使用注册表。这些设置的键值为HKEY_CURRENT_USER/Software/Cisco Systems/CCNMediaTerm/1.0 。如果这个键值不存在,WINRTP将在第一次需要使用它们时建立它。

静态/动态 抖动缓冲

Set the UseDynamicJitterBuffer registry entry to “true” to use dynamic jitter buffer algorithm for audio reception. Set it to “false” to use static jitter buffer (like the old version of winrtp)

设置 UseDynamicJitterBuffer 条目为 “true” 则在音频接收时使用动态抖动缓冲算法。设置为“false” 则使用静态抖动缓冲(就像上的版本一样)

抖动缓冲长度

This value is relevant only if static jitter buffer is being used. The length of the jitter buffer can be specified using the JitterBufferTime registry setting. This setting is in milliseconds. The default value is 180, but lower values work on most computers. At the beginning of each talk spurt, the WINRTP fills x milliseconds of audio in the jitter buffer (where x is the value of the JitterBufferTime registry setting) before it starts playing it to the speaker. Higher jitter buffer length provides smoother audio and immunity to network problems, but increases the latency in a two-way conversation. But lowering this value too much can lead to bad quality audio (stuttering or jittery audio) in which case the user should try to increase this setting. The optimal value is very dependent on the configuration of the PC (sound card and drivers, operating system, etc.), so it should be set on a per-computer basis. The default value of 180 works on majority of computers (lower values may work too).

此值只有在使用静态抖动缓冲时才有效。使用JitterBufferTime 键值来设置抖动缓冲的长度。此设置单位为毫秒。默认值为180,但是大多数计算机使用更低的值。话音突发(talk spurt)开始时,WINRTP在播放之前填充 x 毫秒到抖动缓冲(x 为JitterBufferTime 键值)。更高的抖动缓冲长度提供了更平滑的音频及更好的网络故障免疫性,但是增加了双向交谈的反应时间。降低太多此值,会带来劣质的语音(间断的,抖动的声音),这时就需要增加这个值。最佳的值依赖于PC的配置(声卡、驱动及操作系统等),所以它对于每个电脑是不同的。默认的180,可以适用于大部分电脑。

Try the following (Windows 2000/XP : 60ms, WinNT 4.0 : 120ms, Win 95/98/ME : 180ms

按照操作系统不同,可尝试下面的设置:Windows 2000/XP : 60ms, WinNT 4.0 : 120ms, Win 95/98/ME : 180ms

接收的RTP音频流自动放大等级

WinRTP can automatically amplify the volume of the incoming audio streams. It is needed because frequently the volume level in the incoming packets is pretty low, so they sound much faint compared to other sounds on the PC. We could increase the volume sliders on the PC, but that would make every other sound extremely loud so it is not a satisfactory solution. The real fix is to amplify the incoming audio to a level that is comparable to other system sounds. WinRTP 2.1 onwards has that ability. Note that increasing the level of the incoming signal can cause distortion (due to clipping) so WinRTP employs a novel technique that gives the user complete control. It has amplification that is governed by two parameters, a max-gain (the maximum gain that will be applied if possible), and a distortion-free-percentile (percentage of audio samples that should not be distorted due to this amplification). It is best explained with an example. Say max gain is 5, and distortion-free-percentile is 95%. Then given an RTP packet with audio samples, WinRTP will calculate how much gain it can apply so the samples so that 95% of the samples will NOT be distorted. If this value (say x) is less than max-gain, then the packet will be amplified x times. If x is more that max-gain, then the packet will be amplified max-gain times. To ensure that no distortion occurs, set the percentile to 100% and max-gain to a high value. That way, WinRTP will always amplify the packet without distorting any sample. However, during quiet periods, x might be large which will increase the loudness of the background noise. This is where setting max-gain to a optimal value helps, because it is the max amplification that will ever be applied. I have seen that max-gain values between 5-10 and percentile of 95% produces a good balance. To turn off this feature altogether, set max-gain to 1, so that no amplification will be done. The following registry keys control this feature

WINRTP可以自动放大输入的音频流音量。这是很必要的,因为输入包的音量常常都很小,于PC的其它声音比起来很微弱。我们可以去增加PC的音量调节,但是它也将其它声音放的很大,这不是令人满意的解决办法。真正的解决办法是放大输入音频的等级和系统的其它声音相当。WINRTP2.1首先具有这个功能。注意,增大输入信号的等级可能会导致失真(由于clipping) ,所以WINRTP给用户完全的控制权。我们通过两个参数来进行设置,一个max-gain(可能的最大限度的增大)和一个distortion-free-percentile(最小保真率)。最好的阐述是通过一个例子:说,max gain设置为5 ,distortion-free-percentile设置为95% 。这时,给出一个RTP包,WINRTP将计算多大的增加可以保证原始包中95%的语音没有失真。如果这个值(x)小于 max-gain(5) ,这个包将放大x倍。如果这个值大于 max-gain(5),它将放大max-gain倍。要保证没有失真出现,设置百分点为100%, max-gain为一个很大值,这样,WINRTP将在不失真的情况下放大音频包。当静音阶段,x 可能会很大,这将导致环境杂音被放大。这就是为什么要设置max-gain为一个最佳值,因为这将是可以接收的最大放大倍数。我认为max-gain 在5到10之间,distortion-free-percentile为95% ,可以达到一个比较好的平衡。关闭此功能,设置max-gain 为1 ,这样不会有任何放大。下面的键值控制此功能:

VolumeMaximizeMaxGain (floating point number >= 1.0 e.g. 8.0 )

VolumeMaximizePercentile (floating point number between 0.0 and 100.0 )

DiffServ Byte) of Outgoing RTP Packets 输出RTP包的TOS

The WINRTP can stamp outgoing RTP packets with an IP TOS (type of service) value in the IP header. This is important for QoS purposes where packets of a certain TOS may be given priority in the network to reduce delay. To do this, you need to change the value in the RtpOut filter project (RtpOut.cpp)

WINRTP可以为输出RTP包在IP头标示IP TOS 值,对于Qos来说这很重要,不同的TOS将给与不同的优先级来减少延迟。你需要修改这个值在RtpOut filter 项目中(RtpOut.cpp)

指定UDP 传输端口

If you want to use a particular local UDP port to transmit RTP streams, set the UseFixedTransmitPort to “true” and set the TransmitPort registry entry to the port number you want to use. Otherwise, set UseFixedTransmitPort to “false”. Note the receive and transmit port cannot be the same. Make sure transmit port != receive port, and transmit port != (receive port + 1)

如果你想使用一个确定的本地UDP端口在传输RTP流,可以设置 UseFixedTransmitPort 键值为 “true” 并 设置 TransmitPort 键值为你想使用的端口。否则,设置UseFixedTransmitPort 为 “false” 。注意:接收和发送端口不能为一个,请确保transmit port != receive port, 并且 transmit port != (receive port + 1)

发送音频的预加重

To do pre-emphasis of transmitted audio to make it sound sharper, set the MicrophonePreprocess registry entry to “true” (“false” otherwise) and then set the TxFIRFilter registry entry to either “1” or “2”. This chooses between a set of parameters to set up an FIR filter to do pre-emphasis of the audio. Experiment to see which setting sounds best

预加重使声音 sharper。设置 MicrophonePreprocess 键值为“true” ,并设置 TxFIRFilter 键值为  “1” 或 “2” 。这些参数被FIR过滤器用来进行预加重(pre-emphasis),你可以自己实验得到最好的效果。

接收音频的后加重

To do post-emphasis of received audio to make it sound sharper, set the SpeakerPostprocess registry entry to “true” (“false” otherwise) and then set the RxFIRFilter registry entry to either “1” or “2”. This chooses between a set of parameters to set up an FIR filter to do post-emphasis of the audio. Experiment to see which setting sounds best

后加重使接收到的声音sharper。设置 SpeakerPostprocess 键值为“true” ,并设置 键值 RxFIRFilter 为“1” 或 “2” 。这些参数将传给FIR过滤器用来后加重(post-emphasis),你可以自己实验得到最好的效果。

音量限制

Sometimes the received audio may be too loud and you may want to do volume limiting to reduce the max volume. In that case, set the LimitVolume registry entry to “true” (“false” otherwise). This will turn on the volume limiting feature. To control the behavior of the limiter, there are three registry settings: LimiterThreshold (default –8.0), LimiterLossIncrement (default 0.075), LimiterLossDecrement (default –0.00075). Setting the threshold lower (for e.g. to –25.0 instead of –8.0) will limit audio to a lower volume. I recommend against playing around with the other parameters.

某些接收到的音频可能声音太大,你想限制音量的最大值。这时候,设置 LimitVolume 键值为  “true” 。这将打开音量限制功能,控制限制器的行为,有三个键值:LimiterThreshold (默认-8.0),LimiterLossIncrement (默认0.075), LimiterLossDecrement (默认–0.00075)。降低threshold 的值将会限制声音,另外的键值我建议大家不要修改。

示例代码

The following sections describes through an example how to use the Media Term component. Here are the basic steps

下面的段落叙述了一个使用Media Term组件的例子。下面是步骤:

  1. Initialize COM (CoInitializeEx)  初始化COM,使用(CoInitializeEx)
  2. Instantiate the Media Term Component and get the ICCNMediaTerm COM interface (Say the variable is CCNMediaTerm) using CoCreateInstance

初始化Media Term 组件,使用CoCreateInstance得到ICCNMediaTerm接口 (CCNMediaTerm)

  1. Initialize the WINRTP   初始化WINRTP

·        Initialize();

  1. Transmit Side  发送端:

·        Set the startup parameters for transmit: Use G.711 Ulaw Codec, 30ms packet size, No silence suppression. Transmit to localhost (127.0.0.1) to port 21243  设置传输的参数:

o       SetAudioCodecTX(4, 30, 0, 0, 1, 0);

o       SetAudioDestination(“127.0.0.1”, 21243);

·        Start transmission using the default audio capture device 开始发送音频流

o       StartTX(-1);

·        Mix the file “foo.wav” along with the transmitted stream. Play the file once. 混音文件“foo.wav”及传输流 ,并播放。

o       StartPlayingFileTX(“foo.wav”, 1, 0, 0, &sendFileCookie)

·        Set the volume of the “foo.wav” file to 50%  设置音量为50%

o       SetFilePlayVolume(sendFileCookie, 50)

·        Change the codec from G.711 Ulaw to G.723 at 5.3kbps and turn on silence suppression 改变codecs,打开静音抑制

o       SetAudioCodecTX(9, 30, 0, 1, 1, 0)

·        Stop Transmitting (everything, including voice and files) 停止传输

o       StopTX()

  1. Receive Side  接收端

·        Set the startup parameters for receive: Use G.711 Ulaw Codec, 30ms packet size. Receiving from local port 8000 设置接收参数

o       SetAudioCodecRX(4, 30, 0, 0);

o       SetAudioReceivePort(8000);

·        Start receive side using the default audio playback device 使用默认的回放设备开始接收

o       StartRX(-1);

·        Mix the file “foo.wav” along with the received stream. Play the file continuously in a loop. Also play another file “foobar.wav” just once. Mix both files along with the received audio 混音文件“foo.wav”及接收流 ,循环播放文件,播放另一个文件“foobar.wav”一次。混音所有输出。

o       StartPlayingFileRX(“foo.wav”, 0, 0, 0, -1, &receiveFileCookie1);

o       StartPlayingFileRX(“foobar.wav”, 1, 0, 0. –1, &receiveFileCookie2);

·        Set the volume of the “foobar.wav” file to 25%  设置音量25%

o       SetFilePlayVolume(receiveFileCookie2, 25)

·        Stop playing the “foo.wav” file that was playing in a loop 停止“foo.wav”播放

o       StopPlayingFileRX(receiveFileCookie1);

·        Change the codec from G.711 Ulaw to G.729 (30ms packet size), and also change the port to receive audio from 8000 to 9999 改变codecs和端口

o       SetAudioCodecRX(11, 30, 0, 0)

o       SetAudioReceivePort(9999)

·        Stop receiving (everything, including voice and files). This method releases the speaker停止接收

o       StopRX()

  1. Uninitialize the WINRTP and release all resources  销毁WINRTP ,释放所有资源

    • Uninitialize()
  2. Uninitialize COM if needed using CoUninitialize  销毁COM

I plan to release some sample C++ code to show how to use this component soon

我计划不久后发布一些C++代码来展示如何使用这些组件。

未来的改进

Some of the future improvements that are being considered are 一些未来需要做的改进:

  • Using the same local UDP port to do transmit and receive  使用相同的端口完成接受和传输

Cisco IP电话软件的WINRTP相关推荐

  1. 为Cisco IP电话添加自定义铃声

    Cisco IP电话,比如7960,默认只有两个铃声. 想必很多看过<24小时>的朋友,都对剧中CTU使用的电话铃声情有独钟.(其实那些电话都是Cisco的.) 下面,就介绍一种给Cisc ...

  2. 基于智能移动设备的IP电话软件的设计与实现

     摘  要 介绍了以Pocket PC2003为操作系统,带WiFi功能的智能移动设备平台下IP电话软件的设计方案与实现方法.实践证明,本软件具有实时性好.移植性强等优点.     关键字 智能移动设 ...

  3. cisco IP电话 qos

    auto qos voip cisco-phone 用于电话 auto qos voip trust 用于上联

  4. Cisco IP 电话 将它的voice mail 发送到手机

    功能一.将语音转成文字发送短信(有微软认知.百度认知.云片短信API) 功能二.直接将音频发送到微信 不废话,直接送个包 链接: https://github.com/JaviZhu/KLCN.Spe ...

  5. Network Experiance - Cisco IP 电话 通过防火墙后无法注册

    目前测试过通过juniper与hillstone防火墙后,本来可以正常注册的,但是经过墙后,哪怕是双向any any 的放行还是无法注册,是因为防火墙默认开启了sip协议的ALG防护功能,需要关闭,j ...

  6. Cisco新一代桌面IP 电话 7800 系列

    Cisco® IP 电话7800 系列是具有成本效益的高保真语音通信产品组合,旨在提高您组织以人为本的通信,同时降低运营成本. 它采用极具吸引力的全新人体工程学设计,提供"无间断" ...

  7. 网络电话显示服务器拒绝,云安全日报201223:思科IP电话发现拒绝服务漏洞,需要尽快升级...

    12月22日,思科发布了安全更新,主要修复了IP电话TCP数据包发现的拒绝服务漏洞.以下是漏洞详情: 漏洞详情 来源:https://tools.cisco.com/security/center/c ...

  8. 网络电话显示服务器拒绝,云安全日报201223:思科IP电话发现拒绝服务漏洞 需要尽快升级...

    12月22日,发布了安全更新,主要修复了IP电话TCP数据包发现的拒绝服务漏洞.以下是漏洞详情: 漏洞详情 来源:https://tools.cisco.com/security/center/con ...

  9. Cisco IP Communicator 企业Voip 解决方案

    思科IP电话提供了业界领先的集成业务功能和融合通信功能水平,远远超越了当前使用的传统语音系统和竞争对手产品.思科系统公司提供了无与伦比的端到端数据和IP电话解决方案,为各种规模的企业提供最为全面.功能 ...

最新文章

  1. 比特币挖矿——区块链技术
  2. 为何Google将几十亿行源代码放在一个仓库?| CSDN博文精选
  3. 如何将某个groupbox中的数据赋值到另一个groupbox_React中的数据和数据流
  4. numba.jit警告:Compilation is falling back to object mode WITH looplifting enabled because Function
  5. python函数大全和意思_python 之 内置函数大全
  6. 信息化基础建设 开发框架
  7. 《零基础》MySQL NULL 值处理(二十一)
  8. Netty 5用户指南
  9. 持续集成实践二之Jenkins与Sonar Qube集成
  10. unity3D与网页的交互
  11. staruml怎么画协作图_er图怎么画?轻松绘制专业er图的软件
  12. 完全免费的在线遥感影像下载器-转载
  13. 梦幻内存辅助制作教程
  14. 安川伺服驱动器软件SigmaWin
  15. 五色电阻在线计算机,色环电阻在线计算器
  16. 嗖嗖移动大厅JAVA(免费源码分享)
  17. 什么是stochastic regressor
  18. 《自适应机器人交互白皮书》
  19. 激活函数(Relu,sigmoid,Tanh,softmax)详解
  20. dialog出现Uncaught RangeError: Maximum call stack size exceeded错误

热门文章

  1. 七、Redis集群搭建
  2. OTB运行代码文件介绍
  3. 【嵌入式·单片机】老生常谈:学习单片机和嵌入式是否需要学习算法?
  4. 打卡哈利·波特吃饭的餐厅
  5. DNS域名和网络地址
  6. 合肥32中学2021高考成绩查询,2021年合肥高中录取分数线是多少及高中排名榜
  7. 微信jsapi支付获取code_微信JSAPI支付那点事
  8. windows无法启动windows update服务
  9. android qq三方登录授权失败,教大家qq第三方登陆授权失败110401怎么办的解决方法...
  10. Mac解决无法打开问题