Converting Prosody applications from Version 1 to Version 2 (TiNG)

There are some aspects of the API which are not entirely compatible between version 1 and version 2. This document explains what these are and suggests ways to modify an application originally designed for version 1 to work with version 2. Many applications will need only small changes to work satisfactorily.

Contents

Building applications

The required preprocessor definitions have changed. Prosody version 2 requires one symbol TiNGTYPE_xxx where xxx is the variant to be built. (Note the lower case i in that symbol). See Prosody Guide - how to build applications to use Prosody for details of how to build applications with Prosody version 2.

Forward compatibility

From time to time new features may be added to the API. This may require new fields to be added to structures. A mechanism is available to ensure that this does not cause any problems for code developed prior to the addition. This is achieved by defining all new fields such that the value zero selects backward compatible behaviour. To take advantage of this, applications should clear structures before use. For example,

	SM_CHANNEL_ALLOC_PLACED_PARMS ap;
	memset(&ap, 0, sizeof(ap));
	ap.type = kSMChannelTypeFullDuplex;
		... etc

This ensures that if a new field is ever added to this structure the new field is not left uninitialised and the application is forward compatible with all such future changes.

Conversion required

Downloading firmware

Version 1 Prosody used firmware builds. A build contained a fixed combination of features. Version 2 does not use builds. Instead the features are provided by firmware modules which can be downloaded individually. When a Prosody Processor is reset, the firmware kernel must be downloaded. This is done with the kload program. A shell script or batch file, called kl is provided which runs it with the appropriate parameters.

After the firmware kernel has been downloaded, the desired modules can be downloaded. This is done with the ELFload program. A shell script or batch file called lm is also provided to run this program. It is generally most convenient to write a shell script which downloads the desired combination of modules. An example, called sp30 is provided which includes a combination of modules which provides very similar functionality to the version 1 firmware builds called sp30a.smf and sp30u.smf.

The API guide indicates which firmware modules must be downloaded. This is done by stating the requirement for a firmware module in the description of each function which can start using a feature provided by that firmware module. The modules are also listed in the Software Module Index.

For debugging purposes it may be necessary to verify that the intended firmware is present on a Prosody Processor. The program fwinfo displays a list of currently downloaded firmware.

If an application wants to reconfigure a Prosody Processor while running, this can be done by using system() or equivalent to run a shell script or batch file which sets up the desired configuration. The test program fmwdnld shows how this can be done. The API function sm_download_fmw() which was used in version 1 to download a firmware build is not available in version 2. Generally it is better for an application to take responsibility for a Prosody Processor only after the appropriate firmware has already been downloaded.

Note, however, that the Resource Manager is available which provides backward compatibility with firmware downloading for existing applications.

Conversion required

Timeslot assignment

This will affect all applications unless they only use the S2 (ISA Prosody) card.

The S2 card provides only Prosody. Other cards, such as the P1 (PCI Prosody) card provide both Prosody and other resoures such as network ports and switching resources. All cards have an external connector for an industry standard bus which provides a way to carry channels between the card and other devices. The S2 card can connect to an MVIP bus, while the P1 card can use the newer H.100 bus.

When an application allocates a channel on an S2 card, that channel must be connected to an external timeslot on the external bus. This remains the same on version 2. For example, after allocating a recording channel on the first Prosody Processor, an application might use sm_switch_channel_input() to connect it to timeslot 3:7 which would be timeslot 7 within MVIP stream DSi3. This makes the channel ready to record anything put on DSi3:7 by any device.

When an application allocates a channel on a P1 card, version 1 Prosody assigns a timeslot which is local to the card. This timeslot can be switched to other devices on the same card, but not to devices on other cards. To connect to a device on another card, the application must connect the local timeslot to a timeslot on the external bus and then connect the external bus timeslot to the device on the other card. For example, a recording channel allocated on the first Prosody Processor might be assigned timeslot 8 on stream 48. This makes the channel ready to record anything put on 48:8, but this can only be referred to by other devices on the same card. To allow an external device to reach this timeslot, the switch matrix on the card must be instructed (with sw_set_output()) to connect an external timeslot to 48:8.

Version 2 Prosody does not allocate this local timeslot. Instead, the application must select a suitable timeslot and use sm_switch_channel_input() to assign it to the channel. The reason for this is that version 2 allows more than one channel to use the same local timeslot, so it cannot know whether or not a new timeslot is required when a channel is allocated. Normally the selection of a suitable timeslot is trivial because there is a simple way to select one based on a property already available. For example, if an application answers incoming calls on all four trunks on a P1 card, each call has a stream and timeslot, so the channel created to handle a call on network port N, timeslot T, could use local stream 48+N, timeslot T, so the channel allocated for a call arriving on timeslot 12 of port 2, would use local timeslot 50:12. This would be a suitable strategy for a P1 card which had four network ports and two Prosody Processors. If it had four Prosody Processors, you could dedicate one to each network port and use streams 48, 50, 52, 54 to handle channels for ports 1, 2, 3, and 4 respectively.

It is very easy to allow an application to support both version 1 and version 2 behaviour. Here is some example code for use with cards such as the P1 card:

	// we assume that:
	//	cp->channel is the newly allocated channel
	//	cp->local.stream is the number of a suitable local stream
	//	cp->local.timeslot is the number of a suitable local timeslot
	SM_CHANNEL_INFO_PARMS cip;
		// fetch channel type for later use
	int type = sm_get_channel_type(cp->channel);
		// find out current position
	memset(&cip, 0, sizeof(cip));
	cip.channel = cp->channel;
	e = sm_channel_info(&cip);
	if (e) {
		fprintf(stderr, "sm_channel_info failed: %d\n", e);
		return 1;
	}
		// Version 1 would have assigned local timeslots so
		// we check the timeslot details returned
		//
		// the channel needs an output timeslot unless
		// it can only be used for input
	if (type != kSMChannelTypeInput && cip.ost == -1) {
		SM_SWITCH_CHANNEL_PARMS swp;
		cip.ost = cp->local.stream;
		cip.ots = cp->local.timeslot;
		memset(&swp, 0, sizeof(swp));
		swp.channel = channel;
		swp.st = cip.ost;
		swp.ts = cip.ots;
		e = sm_switch_channel_output(&swp);
		if (e) {
			fprintf(stderr, "sm_switch_channel_output failed: %d\n", e);
			fprintf(stderr, "cannot assign local timeslot\n");
			return 1;
		}
	}
		// the channel needs an input timeslot unless
		// it can only be used for output
	if (type != kSMChannelTypeOutput && cip.ist == -1) {
		SM_SWITCH_CHANNEL_PARMS swp;
		cip.ist = cp->local.stream;
		cip.its = cp->local.timeslot;
		memset(&swp, 0, sizeof(swp));
		swp.channel = channel;
		swp.st = cip.ist;
		swp.ts = cip.its;
		e = sm_switch_channel_input(&swp);
		if (e) {
			fprintf(stderr, "sm_switch_channel_input failed: %d\n", e);
			fprintf(stderr, "cannot assign local timeslot\n");
			return 1;
		}
	}
		// at this point the channel always has a local timeslot
		// regardless of whether we are running version 1 or version 2
		// the SM_CHANNEL_INFO_PARMS structure has also been updated
		// making it convenient if we now want to connect to an
		// external bus

Note, however, that the Resource Manager is available which provides backward compatibility by automatically assigning timeslots.

Conversion required

Channel indices

Version 1 has a variety of API functions which can refer to a channel by an index number. This is a small integer which is an alternative to using a tSMChannelId to identify a channel. For performance and reliability reasons, there is no support for channel index numbers in version 2. In many cases it is quite straightforward to replace references to a channel which use a channel index with references using a tSMChannelId. For example, an array of tSMChannelIds could be used, indexed by the channel index number. However in a multithreaded program, locking and updating this array is very likely to be a performance bottleneck, so for best performance it is better to avoid the need for indices at all.

Note, however, that the Resource Manager is available which provides backward compatibility by providing some (but not all) of the support for channel indexes that was present in Prosody version 1.

Conversion required

A-law and mu-law

Note that this is considering the encoding of the data as it is sent or received by a channel - not the encoding of data stored in files.

Version 1 Prosody used different firmware builds for handling A-law and mu-law signals. Consequently, there was never any need for an application to indicate whether a channel would be processing one or the other - it was always implicitly specified by the firmware which was running.

Version 2, however, permits both to be used simultaneously. Obviously this means that there must be a mechanism for the application to declare which is required. This is done when the channel is assigned a timeslot with sm_switch_channel_input() or sm_switch_channel_output(). An extra field in the parameter struct specifies that the timeslot carries A-law, mu-law, or non-companded data.

Note that, although Prosody version 2 permits several channels to use the same timeslot as an input, all channels must specify the timeslot with the same type of companding. This is because the companding is performed with hardware support.

Note, however, that the Resource Manager, as part of the backward compatibility provided, forces timeslots to be either A-law or mu-law depending on the firmware downloaded.

Conversion required

sm_reset_channel()

The function sm_reset_channel() is not present in TiNG. This function performed two jobs: to stop operations in progress and to restore a channel to its initial state. In TiNG each operation must be stopped by the appropriate API function (for example, a detection started with sm_listen_for() must be stopped by another call to that function). This is described in the section When are the various operations on a channel complete? in the Prosody Overview. A special reset operation is not necessary to restore channel state since this always occurs when an operation is completed. For example, after performing a record operation on a channel, when sm_record_status() reports kSMReordStatusComplete, any new output operation will behave exactly as if the recording had not taken place. No state is retained which will influence future operations.

Conversion required

Starting and finishing operations

Prosody version 1 was quite permissive in its handling of operations such as replay, record, and playing tones. It allowed you to cancel some operations merely by starting another of the same kind. Version 2 does not permit this. For each operation which can be started, there is only one way permitted to finish it. For example, when sm_replay_start() is called to start a replay, this operation finishes when sm_replay_status() returns the status kSMReplayStatusComplete. While the replay is in progress, an attempt to start another output operation (i.e. a replay, play tone, play call progress tone, or play digits) will fail with the error ERR_SM_WRONG_CHANNEL_STATE. To stop an operation, the correct API function must be used (e.g. sm_replay_abort() for replays) and then the application must wait until the status changes to indicate completion.

Prosody version 1 also permitted functions such as sm_replay_status() to be called repeatedly after a replay had finished (which would repeatedly report completion). Version 2 does not permit this. After the completion has been reported, all resources relating to the operation are discarded, resulting in further attempts to read status returning an error (ERR_SM_WRONG_CHANNEL_STATE) just as any other inappropriate function also does.

Conversion required

Continuous background music

Sometimes it is desireable to have a continuous background signal, such as music, over which is played a sequence of messages. With Prosody version 1 this could be achieved by specifying a background channel when starting a replay (with sm_replay_start()) and then only doing replays on that channel. The background signal would persist uninterrupted while replays were started and stopped.

Prosody version 2 will stop the background signal if the replay completes. It will return the channel to emitting an idle pattern, which will sound perfectly silent. However, it is not necessary to stop and start the replay even if the application needs to play many different messages. Instead, the application can simply stop calling sm_put_replay_data() when it reaches the end of a message and call sm_put_replay_data() when it is time to start the next message. Of course, if there is a pause between messages, an underrun will be reported, but this can simply be ignored as it does not indicate a problem.

If it is necessary to play signals using different encoding types, then the replay must be stopped and a new one started. If the new one specifies the same background channel, and it is started immediately after the first one stops, the break in the background signal can be reduced to about 16 milliseconds.

If it is essential to avoid any break in the signal, it is possible to allocate a second channel, start a replay on it with the same background specified, but don't give it any data. Then use sm_switch_channel_output() to switch it to the same output timeslot as the original channel and use sm_switch_channel_output on the original to disconnect it (by specifying -1 as the stream number). Then the first channel can be reconfigured in any way as the output is being fed from the second. It can be released (to conserve resources) or the application can alternate between the two channels, with one always providing the output while the other is being reconfigured. This guarantees a totally uninterrupted signal. When handling many channels, it may be appropriate to have only one spare channel which is used when swapping over, and after performing a swap the old channel can become the new spare.

However, note that there can still be a discontinuity in one specific unusual circumstance: if you start replays in the order: first channel, background, second channel; then switching between first channel and second channel will skip forward or back by 8 milliseconds. Normally this circumstance does not arise because the background signal will be started before any channel which uses it.

Conversion required

Elimination of signals from recordings

Prosody version 1 provided a field called elimination in the parameters to sm_record_start() which controlled the elimination of signals from a recording. This field made the recording refer to the recognition which had been started on the same channel with sm_listen_for(). In version 2 elimination is controlled by several fields which, by themselves, configure the detection and do not use sm_listen_for().

Silence elimination is controlled by the field silence_elimination. This field contains the maximum duration (in milliseconds) of silence to be recorded. Any silences exceeding this duration cause recording to pause, truncating the silence to the maximum duration specified. In contrast to version 1, version 2 does not have any connection between the settings for grunt detection on a channel and those for silence elimination.

Elimination of tones is controlled by the field tone_elimination_mode, which is set to one of the kSMToneDetectionMinDuration* values as used with sm_listen_for() to detection tones. The tone set used is selected by the field tone_elimination_set_id.

In version 1, since tone elimination was a side-effect of using sm_listen_for(), items recognised and eliminated from the recording were reported through sm_get_recognised() and there was no way to determine exactly where in the recording that this had occurred. In version 2, tones and silences eliminated from a recording are reported through sm_record_status() so the position in the recording is known exactly.

Conversion required

Event states

Event objects (i.e. as implemented by tSMEventId) in Prosody version 1 marked the occurrence of events. In version 2 they indicate states. This is most easily explained with an example. Suppose tone detection is enabled and two DTMF digits "5" and "8" are detected. The associated event object is set (i.e. the event is signalled). The application must call sm_get_recognised() to find out what happened and the first such call reports that a digit "5" was detected. Another call reports the digit "8" was detected, and a third call reports that nothing was detected. The application can now use the event object again to wait for something else to happen. Both versions of Prosody behave the same in this respect. The difference is that version 1 clears the event as soon as it has woken the application, while version 2 only clears the event when there are no further digits to report. This allows the application to be simplified. Instead of repeatedly calling sm_get_recognised() until it reports that nothing more has been detected, the application can call it once and immediately wait on the event. If a second digit has been detected and not yet reported, then the wait will not sleep. This behaviour is normally compatible with applications written for Prosody version 1. In fact, it may fix a bug if the application fails to re-check until the status indicates that everything of interest has been reported (e.g. if an application fails to re-check DTMF detection then if digits appear fast enough, it will get behind and miss the last digit). It can only cause a problem if an application, having been woken while waiting for an event, deliberately ignores the event and tries to wait again. Prosody version 2 will not allow it to sleep until the circumstance which triggers the event has gone away. For detection events, this means that sm_get_recognised() has nothing more to report; for record, it means that there is insufficent data awaiting collection and there is nothing else to report (e.g. underrun); and for replay, it means that the channel is not ready for more data and nothing else to report.

For replay operations, if there is no more data to send, Prosody version 1 permitted the application to ignore the fact that the channel was ready for data because if the application tried waiting again on the channel's associated event object it would only be woken when something new happened. Version 2 does not permit this, because the situation of the channel being ready for data still applies, so the wait will not sleep. If an application wants to wait for a replay to finish, it must use sm_put_last_replay_data() to indicate that no more data is to follow. After this function is used, a channel can no longer be ready for more data, so the event object is only set when there is something else to report (such as completion of the replay).

Conversion required

Events before starting and after completing record, replay, and detection

In Prosody version 1 an event object was clear (inactive) before starting any operation. This meant that for replay and record, the first data transfer had to be handled differently to all others because it was not triggered by the event. Prosody version 2 makes the event be set (active) whenever the channel is not busy. This means that the application can start a replay or record operation and immediately wait on the associated event, which will be set, triggering data transfer. i.e. this code is suitable for version 2:

	sm_replay_start(...);
	for (;;) {
		smd_ev_wait(...);
		if (sm_replay_status(...) reports completion) {
			break;
		}
		if (more data to send) {
			sm_put_replay_data(...);
		} else {
			sm_put_last_replay_data(...);
		}
	}

whereas this is required for version 1:

	sm_replay_start(...);
	for (;;) {
		switch (sm_replay_status(...) status) {
		case completion: {
			goto done;
		case capacity:
			if (more data to send) {
				sm_put_replay_data(...);
			} else {
				sm_put_last_replay_data(...);
			}
			break;
		case no capacity:
			goto ready;
		}
	}
ready:
	for (;;) {
		smd_ev_wait(...);
		if (sm_replay_status(...) reports completion) {
			break;
		}
		if (more data to send) {
			sm_put_replay_data(...);
		} else {
			sm_put_last_replay_data(...);
		}
	}
done:

(actually, the version 1 code could be much simpler for one channel, and the initial loop which loads the first data only needs to be separate when the wait in the main loop must wait for one of many possible channels).

Similarly, when a channel completes a replay or record, the associated event remains permanently set. This is useful as a safety precaution to prevent an application waiting for something which can never happen.

The same rule applies to detection (as started by sm_listen_for()). The event is set (active) when there is no detection running or the detection has detected something of interest. This means that you can wait on an event and get woken if the detection is aborted.

Note that there is a version 1 compatibility event type (described in the next section) which emulates the version 1 behaviour.

Conversion required

Prosody 1 compatibility for events before starting and after completing record, replay, and detection

As described in the previous section, normal events are set except while an application might be waiting for a channel to do something. However if you specify an event type of kSMChannelSpecificEventNonIdle instead of kSMChannelSpecificEvent, that event is clear while no operation is in progress (but otherwise behaves normally). This makes it easier to use Prosody TiNG with applications which were written for Prosody version 1. Note that these compatibility events still reflect states (as described in Event states) so they're not exactly the same as version 1 events.

It is recommended that normal events be used where possible. Although the Prosody 1 compatibility events usually appear more convenient, they are not as good for exposing race conditions at the start or end of an operation.

Conversion required

Channel allocation

Prosody version 1 tried to ensure that resources were always available to a channel. This was done by specifying required capabilities when allocating the channel. In many cases this also allowed Prosody to choose the best location for a channel to optimise the use of resources.

Unfortunately, as the software becomes more powerful it gets increasingly difficult to specify exactly what resources are required. Any wholly automatic scheme either potentially wastes resources by assuming the worst case usage for every channel, or allows channels to fail by assuming an average or optimistic level of resource usage per channel. Prosody version 2 does not attempt automatic reservation of resources. Instead the application is expected to allocate and use channels appropriately and only the exhaustion of resources is reported. To assist the application designer, a sophisticated resource planner is provided. Even this does not cover all possible circumstances, as some are much easier to cover by simple documentation. For example, all channels used in a single primitive conference (controlled by the sm_conf_prim_*() functions) must be on the same Prosody Processor, so if the application handles only four-party conferences, when it is about to allocate a channel for a new conference it must ensure that not only are there currently resources for three more channels to complete the conference but that this also allows for any channels which it plans to allocate for adding to existing conferences. This sort of requirement is quite straightforward to handle in the application (by, for example, planning a fixed number of four-party conferences per Prosody Processor) but very diffcult to specify to an automatic allocator. The application may even be able to reorganise its channel usage. For example, if it has a five-party conference on a Prosody Processor and a sixth participant wants to join but there is no space on that Prosody Processor, if there is space on another Prosody Processor for a six-party conference it can create the six-party conference there and switch the timeslots around to move everyone onto the new conference.

Note, however, that the Resource Manager is available which provides backward compatibility by emulating the channel allocation behaviour of Prosody version 1.

Conversion required

Overrun notification

When performing recording, Prosody version 1 reported an overrun status out of sequence with the data. This meant that you could assume that when you got an overrun there was data available to be read (since, obviously, the buffer must be full when an overrun occurs). In version 2, the overrun is reported strictly in sequence with the data. This allows you to tell where the data was lost. It means that the overrun status is returned after you have read the data which was received before the overrun occurred which may mean that when you see the overrun indication there is no more data available. Consequently, if an application assumes that an overrun implies that there is data available, it will attempt to read data which may not yet have arrived, leading to a delay.

Conversion required

Shared resources

In Prosody version 1, many more resources were shared across all processes using a single Prosody processor module. This required all concurrent applications to use a common configuration and, since these resources were located on the Prosody processor itself, imposed strict limits on the number of items such as call-progress tones that could be defined. A complete classification of resources into shared and non-shared can be found in Prosody application note: simultaneous use of Prosody by multiple processes.

Conversion required

Recording echo cancelled signals

Prosody version 1 did not permit a channel to perform both echo cancellation (using sm_condition_input()) and recording. This meant that when you wanted to record the result of echo cancellation you had to allocate a second channel to perform the recording and direct the echo cancelled signal to it. This is not necessary in version 2 as it permits recording to be performed on the same channel as echo cancellation and such a recording records the signal after the echo cancellation has been performed on it.

sm_get_firmware_caps()

The function sm_get_firmware_caps() is not present in TiNG. This is both because TiNG does not have fixed firmware builds and because many of the limits described by the firmware capability details have been removed (e.g. size of tone generation table). If you have an application which uses this API call, you can either use fixed values or add a mechanism to configure them (for example, use a batch file or script to download firmware and make it leave capability information in an agreed place, such as a file, where the applicaton can find it).

Conversion required

sm_find_channel()

The function sm_find_channel() is not present in TiNG. If you have an application which requires this function, you can record the timeslot assignments used (when the channels are allocated) and use this record to determine which channel is using a timeslot. Here is a simple example which assumes you never have two channels connected to the same timeslot:

		// indexed by card, stream, in/out, timeslot
	tSMChannelId slot_to_chan[16][8][2][32];
	...
		// when channel allocated with timeslot assigned
	SM_CHANNEL_INFO_PARMS cip;
	memset(&cip, 0, sizeof(cip));
	r = sm_channel_info(&cip);
	cip.channel = chan;
	if (r) {
		... // handle error
	}
	slot_to_chan[cip.card][cip.ost-48][0][cip.ots] = chan;
	slot_to_chan[cip.card][cip.ist-48][1][cip.its] = chan;
	...
		// when releasing channel
	SM_CHANNEL_INFO_PARMS cip;
	memset(&cip, 0, sizeof(cip));
	r = sm_channel_info(&cip);
	cip.channel = chan;
	if (r) {
		... // handle error
	}
	slot_to_chan[cip.card][cip.ost-48][0][cip.ots] = kSMNullChannelId;
	slot_to_chan[cip.card][cip.ist-48][1][cip.its] = kSMNullChannelId;
	...
	int sm_find_channel(SM_FIND_CHANNEL_PARMS *fp)
	{
	 fp->channel = slot_to_chan[fp->card][fp->st-48][!fp->is_output][fp->ts];
	 if (fp->channel == kSMNullChannelId) return ERR_SM_NO_SUCH_CHANNEL;
	 fp->channel_ix = sm_get_channel_ix(fp->channel);
	 return 0;
	}

This example also assumes you are using PCI Prosody cards (where the streams used are 48 to 55). It also assumes that no locking is necessary, which is appropriate for both single-threaded applications as well as multi-threaded applications which already use a suitable lock.

Conversion required

sm_get_recorded_data() on any channel

In version 1 you can use sm_get_recorded_data() to retrieve data from any channel which has data available for collection. This functionality is not available in version 2 (TiNG). However the same effect can be easily achieved by invoking sm_record_status() to find a channel with status kSMRecordStatusData and fetching the data from that channel.

Conversion required

sm_record_how_terminated()

The function sm_record_how_terminated() is not present in TiNG. This is because when an operation is completed it leaves no state which can influence future operations. Instead, when the function sm_record_status() indicates that a record has completed, it always includes the reason for termination.

Conversion required

Isolated Word Recognition word models

Prosody version 1 permitted a process to use models which had been downloaded by a different process. It also permitted a process to delete all the models (using sm_reset_input_vocabs()). Version 2 (TiNG) makes the use of models local to each process, so the models to which sm_asr_listen_for() refers must have been downloaded by the process invoking sm_asr_listen_for(), and sm_reset_input_vocabs() only clears the list of models accessible to the process which invokes it. The models themselves are managed in such a way that only one copy of a model is stored even if many processes download it, and it is only deleted when it is no longer accessible from any process.

Conversion required

Isolated Word Recognition default word models

Prosody version 1 permitted the value zero for the field vocab_item_count for sm_asr_listen_for(), meaning that the vocabulary to be used for recognition was to be the same as that last used on the channel. Version 2 (TiNG) requires the vocabulary to be explicitly specified every time.

Conversion required

Isolated Word Recognition default parameters

Prosody version 1 provided the function sm_asr_module_parameters() which set the default parameters for future recognition on a given module. Version 2 (TiNG) requires that parameters be explicitly specified every time unless the built-in defaults are being used.

Conversion required

Isolated Word Recognition sidetone configuration

Prosody version 1 used sm_set_sidetone_channel() for both conferencing and Isolated Word Recognition. Version 2 (TiNG) uses it only for conferencing, and the sidetone used for Isolated Word Recognition is configured using the field called sidetone in the parameters to sm_asr_listen_for().

Conversion required

Isolated Word Recognition modes

Prosody version 1 implemented two modes of isolated word recognition: continuous and one-shot. Version 2 (TiNG) does not implement the one-shot mode.

Conversion required

sm_besp_(read|write)_status()

The function sm_besp_read_status() is not available in TiNG. However it is equivalent to using sm_record_status() with a channel ID of kSMNullChannelId.

The function sm_besp_write_status() is not available in TiNG. However it is equivalent to using the functions sm_replay_status(), sm_play_digits_status(), sm_play_cptone_status(), and sm_play_tone_status(), with a channel ID of kSMNullChannelId.

Conversion required

sm_adjust_agc_module_params()

This function is not available in version 2 (TiNG). If you need this functionality, please contact Aculab to discuss your requirements.


Document reference: AN 1382