freetdm api - ftdm_channel_read()
Hi I'm prototyping an application which uses libfreetdm above the sangoma isdn stack and sangoma a104d card. I would like to ask for help about proper reading of voice from the particular channel. According to return value of sangoma_get_rx_queue_sz() the default rx queue size is 10. I did tests when application skipped several reads on given channel, then called ftdm_channel_read() w/ zero timeout in a loop while the return value of read was successfull - it was really 10 frames which were then possible to read. How can an application do this reading of a channel by the means of the freetdm api in more nice way? I did not find a better way yet, than to read it in the loop. Any way to explicitly read the number of available frames? Actually, why the ftdm_channel_read() does not read them ALL at once and sets the number of read bytes via *datalen output parameter? (assuming provided *data buffer is large enough) In my tests, always 160 bytes were returned in one particular read. thank you juraj
Hi Juraj, see your questions answered below ... On Wed, Jul 27, 2011 at 1:21 PM, Juraj Fabo <juraj.fabo@gmail.com> wrote:
According to return value of sangoma_get_rx_queue_sz() the default rx queue size is 10.
That is correct. And you can change that in the FreeTDM wanpipe.conf configuration to set a different default or by using FTDM_COMMAND_SET_RX/TX_QUEUE_SIZE
How can an application do this reading of a channel by the means of the freetdm api in more nice way? I did not find a better way yet, than to read it in the loop. Any way to explicitly read the number of available frames?
I just committed new code to allow access to the internal iostats structure (which contains the size of the queue and number of elements on it). See src/include/freetdm.h ftdm_channel_iostats_t, bear in mind you must enable the feature using FTDM_COMMAND_SWITCH_IOSTATS, then you can retrieve the stats with FTDM_COMMAND_GET_IOSTATS. I added an example of usage in mod_freetdm/mod_freetdm.c Do "git pull" to get it.
Actually, why the ftdm_channel_read() does not read them ALL at once and sets the number of read bytes via *datalen output parameter? (assuming provided *data buffer is large enough) In my tests, always 160 bytes were returned in one particular read.
Did you verify this by providing bigger buffer and datalen? The reason is that you typically want to handle voice as soon as is available, otherwise you add delay in your audio path, therefore you never leave your voice to accumulate in the driver's buffer's. FreeSWITCH and all other users of the FreeTDM API work this way. In the future you might want consider asking this questions in the freeswitch-dev mailing list to have better chances of a prompt response (as long as the question involves C development with FreeSWITCH/FreeTDM internal APIs). Moises Silva Senior Software Engineer, Software Development Manager Sangoma Technologies Inc. | 100 Renfrew Drive, Suite 100, Markham ON L3R 9R6 Canada t. 1 905 474 1990 x128 | e. moy@sangoma.com
Hi Moises, On Wed, Jul 27, 2011 at 1:21 PM, Juraj Fabo <juraj.fabo@gmail.com> wrote:
According to return value of sangoma_get_rx_queue_sz() the default rx queue size is 10.
That is correct. And you can change that in the FreeTDM wanpipe.conf configuration to set a different default or by using FTDM_COMMAND_SET_RX/TX_QUEUE_SIZE
My target platform is SLES 11. I installed wanpipe-3.5.20 but did not find the queue setting within wanpipe.conf (at least not explicitely as queue size) However, setting it via libfreetdm API was successful.
Actually, why the ftdm_channel_read() does not read them ALL at once and sets the number of read bytes via *datalen output parameter? (assuming provided *data buffer is large enough) In my tests, always 160 bytes were returned in one particular read.
Did you verify this by providing bigger buffer and datalen?
The reason is that you typically want to handle voice as soon as is available, otherwise you add delay in your audio path, therefore you never leave your voice to accumulate in the driver's buffer's. FreeSWITCH and all other users of the FreeTDM API work this way.
Yes, I just have different framing on the second network stack = 20ms, while on the E1 I have 10ms, that was why I asked about the reading method. Since read is done by polling, I would like to initiate it from the other network stack thread (here I use ACE framework and have all streams/mixers triggered from single Reactor/thread) My problem is that I'm experiencing unexpected latency in the test environment. I have two server, first with sangoma a104d and second with 2xa102de cards connected with E1 cables. First server is serving as a 'loopback', configured in telko mode and all it does is that in loop it reads all active channels and immediatelly writes read data to the same channel. My measurements show latency about 180ms from the write on the second server till read of the same speach on the second serve r in case of single call. I tried to reduce the queue size as described above, however it seems that some frames got lost then. My intention was to use single thread to handle read/write operations on all active channels, which is different than the approach described in freetdm/doc/locking.txt (where thread per call leg is mentioned). I worry most about calling the wait_channel() with timeout = -1 which afaik leads to blocking wait on single channel. As mentioned earlier, when this is called from single thread prio each particular ftdm_channel_write() it represents danger of blocking and latency. I measure time spent in each particular channel wait+write and the result was < 10us. Maybe rather a simple question, does the application which uses libfreetdm need to run thread per call/channel?
In the future you might want consider asking this questions in the freeswitch-dev mailing list to have better chances of a prompt response (as long as the question involves C development with FreeSWITCH/FreeTDM internal APIs).
should I repost also this? Thanks Juraj -- View this message in context: http://freeswitch-users.2379917.n2.nabble.com/freetdm-api-ftdm-channel-read-... Sent from the freeswitch-users mailing list archive at Nabble.com.
On Wed, Aug 24, 2011 at 8:47 AM, jfabo <juraj.fabo@gmail.com> wrote:
Hi Moises, My target platform is SLES 11. I installed wanpipe-3.5.20 but did not find the queue setting within wanpipe.conf (at least not explicitely as queue size) However, setting it via libfreetdm API was successful.
Do not confuse it with /etc/wanpipe/wanpipex.conf, the wanpipe.conf file I am talking about is the freetdm wanpipe.conf file, the sample file is found in conf/wanpipe.conf in the freetdm source code directory.
Yes, I just have different framing on the second network stack = 20ms, while on the E1 I have 10ms, that was why I asked about the reading method. Since read is done by polling, I would like to initiate it from the other network stack thread (here I use ACE framework and have all streams/mixers triggered from single Reactor/thread)
You are going to be better off by setting the timing to be the same as the network stack.
My intention was to use single thread to handle read/write operations on all active channels, which is different than the approach described in freetdm/doc/locking.txt (where thread per call leg is mentioned). I worry most about calling the wait_channel() with timeout = -1 which afaik leads to blocking wait on single channel. As mentioned earlier, when this is called from single thread prio each particular ftdm_channel_write() it represents danger of blocking and latency. I measure time spent in each particular channel wait+write and the result was < 10us.
If you're following this approach, you can safely assume all channels in a card are ready to read/write at the same time, so polling in just one channel is enough (just make sure the channel you poll on is not alarmed, ie, physical line disconnected). The card delivers data to the all the channels in the same card under the same hardware clock (either coming from the telco or the internal oscillator). The approach other applications follow is one thread per span, then you poll in a single channel and read/write for all of them when waken up.
Maybe rather a simple question, does the application which uses libfreetdm need to run thread per call/channel?
No, we have at least one application that even work in a completely different mode (span mode), where all the IO read/write is done for the whole span in a single operation in a single thread, unfortunately to do this you need to modify ftmod_wanpipe or code your own I/O module making use of libsangoma span mode. Probably not worth it yet.
should I repost also this?
You can move your future replies there. Moises Silva Senior Software Engineer, Software Development Manager Sangoma Technologies Inc. | 100 Renfrew Drive, Suite 100, Markham ON L3R 9R6 Canada t. 1 905 474 1990 x128 | e. moy@sangoma.com
participants (3)
-
jfabo
-
Juraj Fabo
-
Moises Silva