Sound device stop working PJSUA - underflow error - c

I'm using pjsip 2.3 on Linux and I get some problems. The system work fine multiples days. But after a random time, there are no more sound from soundcard :
All the calls are handles/hangups normally
Sound from files is working
RTP is correctly send/receive
The log message indicate always this message :
Master/sound Underflow, buf_cnt=276, will generate 1 frame
According to this reference : https://trac.pjsip.org/repos/wiki/audio-check-sound-device-jitter
The PortAudio? audio abstraction in PJMEDIA prints the number of
underflow/overflow when the sound device is closed. With pjsua, you
need to set the log level to 5 (--app-log-level 5), and when the
application exits the underflow/overflow statistic will be printed to
console/log.
Apparently the sound device is closed, but I have no callback on_sdn_dev_operation.
How can I handle or avoid this state. Are they any callback ?
There is my config media :
//pjsua_media_config.ec_tail_len
pjsua_media_config configMedia;
pjsua_media_config_default(&configMedia);
configMedia.snd_play_latency = 100;
configMedia.snd_rec_latency = 100;
configMedia.max_media_ports = 100;
configMedia.snd_auto_close_time = -1;
configMedia.ec_tail_len = 0;
Thanks

The Master/sound Underflow log is not generated when closing the sound device. The log you will see when the sound device is closed will look something like this: pa_dev.c Closing <some device>: n underflow, n overflow.
The Master/sound Underflow log is printed when there are not enough samples in the delay buffer to fill a frame. I've also experienced these logs in connection with lost sound.

Related

ALSA ignores configuration

I have an audio box that can be connected via USB to my laptop.
I've written a C application that uses the ALSA API to open a communication channel with this audio box.
The communication should be established at 8kHz, running with a 10ms period size (that is 80 samples).
If I'm connecting the audio box to my laptop and then start the app, it seems that the min period size supported is 170 (e.g. snd_pcm_hw_params_get_period_size_min sets min period size to 170), while snd_pcm_hw_params_set_period_size_near sets the period size to 170.
Looking to /proc/asound/name-of-the-card/stream0, I can see Momentary freq = 48000 Hz (0x30.0000), but the sampling rate requested by me is 8kHz.
Also, snd_pcm_hw_params_set_rate_near call, is not changing the value that I've passed.
By starting the app first and then connecting the audio box to my laptop, snd_pcm_hw_params_get_period_size_min sets the min period size to 16 and when calling snd_pcm_hw_params_set_period_size_near, the period size is set to 80 (which represents what I want to achieve).
Checking again /proc/asound/name-of-the-card/stream0, I can see Momentary freq = 8000 Hz (0x8.0000), that is correct.
I have to mention that my app is trying to open the card associated with the audio box and if the operation doesn't succeed, is retrying the open it every 200ms until succeeds.
My feeling is that in the second case when the period size is set accordingly, my application sets the configuration before the system does (I'm not sure if the system does this).
I've tried to modify defaults.pcm.dmix.rate to 8000 in /usr/share/alsa/alsa.conf, but in this case the period size that is returned by acting as in the first scenario is 1024.
Below are some configurations from /usr/share/alsa/alsa.conf if this helps.
defaults.pcm.minperiodtime 5000 # in us
defaults.pcm.ipc_key 5678293
defaults.pcm.ipc_gid audio
defaults.pcm.ipc_perm 0666
defaults.pcm.dmix.max_periods 0
defaults.pcm.dmix.channels 2
defaults.pcm.dmix.rate 48000
Is there a config file that has a higher priority than what I want to configure via the API?

GSM Telit GL865-QUAD AT command, error: 314 (SIM card busy)

I'm trying to communicate with GSM click module (Telit GL865-QUAD module) via UART with AT command. First I want to read all received messages, but for some reason I got error 314, meaning that SIM card is busy. Other answers from GSM are ok.
So this is my config (sending few at commands in a row):
AT\r\n (check GSM)
ATE0\r\n (echo disable)
AT+CMGF=1\r\n (set SMS text mode)
AT+IPR?\r\n (query current baud rate)
AT+CMGL=\"ALL\"\r\n (finally read all messages)
All commands have 1 second delay after gsm get positive (OK) answer. For example: send AT\r\n wait for OK and then wait 1 second; after that delay send another AT command.
Result: I got fine response from GSM when I sent first 4 AT command. But after the fifth one the modem returns error 310 (sometimes) followed by error 314:
AT+CMGL="ALL"
+CMS ERROR: 310
AT+CMGL="ALL"
+CMS ERROR: 314\r\n
I tried it with 2 different SIM cards and got same result.
Any idea or comment are welcome.
First of all, GE865-QUAD is an old device, so I recommend that you at least update it to the latest FW version. You can query current FW version of any GSM modem by issuing AT+CGMR AT command.
Edit: since you have a really old version (10.00.144 is dated 2009/2010!) I STRONGLY recommend updating it, since many bugs could have been fixed since then. You will be able to get last version from Telit site, and to flash it via UART.
Errors explanation
You seem to obtain error 314 preceeded, sometimes by error 310.
+CMEE Error: 314 means SIM busy, as correctly stated by your question subject
+CMEE Error: 310 means SIM not inserted
Possible solutions
First of all, make sure that the SIM is correctly inserted. It has to be pushed all its way in. I suppose you correctly inserted it, but a check has to be done.
Then, since you state that
I try with 2 sim cards and got same result.
I suggest you to check the contacts of the SIM holder (because it is unlikely that both your SIMs have bad electric contacts). In fact the SIM busy status, usually reached when a SIM is actually read (e.g. full phonebook) could also mean that some unconsistent action happened (also SIM failure massage can be shown in those cases).
Make sure you wait enough for SIM ready. In fact, even if SIM initialization usually takes less than a second, in some old SIM models might happen that a longer time is needed.
Telit provides a command to query SIM status: AT#QSS. As descripted by the AT guide, it enables an unsolicited message for any SIM status change. But it also allows allows, through its read command to query the status asynchronously:
AT#QSS?
Read command reports whether the unsolicited indication #QSS is currently enabled or not, along with the SIM status, in the format:
#QSS: mode,status
mode - the verbosity level of #QSS URC, set with AT#QSS=mode. Default value is 0; 2 enables the maximum verbosity level.
status - current SIM status
0 - SIM NOT INSERTED
1 - SIM INSERTED
2 - SIM INSERTED and PIN UNLOCKED (Note: available only if mode=2!)
3 - SIM INSERTED and READY (SMS and Phonebook access are possible) (Note: available only if mode=2!)
So you have to wait until status 3 is reached. I suggest issuing read command every 1/2 seconds until the desired status is reached. Issuing commands that involve the SIM storage before that status is reached will lead to SIM Busy error.
Very important: since status=3 will be shown only with mode=2, issue the following concatenated AT command in order to discover if the SIM INSERTED and READY status has been actually received without enabling URCs:
AT#QSS=2;#QSS?;#QSS=0
In this way, mode=2 is set just before the read command so that the full status list is supported. Then mode is restored to value 0, avoiding URCs to appear.
Make sure that the PIN has been inserted!
The SIM could be locked with the PIN code. Verify it by querying AT+CPIN?. If the response is +CPIN: SIM Ready you are fine. Otherwise, If the response is +CPIN: SIM PIN, you have to insert the PIN code by issuing
AT+CPIN=<PIN>
I found what was problem. Power supply for GSM did not have enough Amps.. For GSM you must provide 3.3V and 3A from power supply unit. GSM don't have 6.5W power consumption if you think that GSM need 3A all the time. GSM have peaks of current up to 2A and thats why you need more Amps.

STM32 USB VCP (Virtual Com Port)

I generated a code for "stm32f103c8t6" with CubeMX for USB VCP, when I add "CDC_Transmit_FS" command to send data, the port isn't recognized by windows10!
what should I do? Here is the code which is compiled without error:
#include "stm32f1xx_hal.h"
#include "usb_device.h"
#include "usbd_cdc_if.h"
int main(void)
{
uint8_t Text[] = "Hello\r\n";
while (1)
{
CDC_Transmit_FS(Text,6); /*when commented the port is recognized*/
HAL_Delay(1000);
}
}
There are three things you need to check in my experience:
startup_stm32f405xx.s --> Increase the Heap size. I use heap size 800 and stack size 800 as well.
usbd_cdc_if.c --> APP_RX_DATA_SIZE 64 and APP_TX_DATA_SIZE 64
usbd_cdc_if.c --> add below code to the CDC_Control_FS() function
Code:
case CDC_SET_LINE_CODING:
tempbuf[0]=pbuf[0];
tempbuf[1]=pbuf[1];
tempbuf[2]=pbuf[2];
tempbuf[3]=pbuf[3];
tempbuf[4]=pbuf[4];
tempbuf[5]=pbuf[5];
tempbuf[6]=pbuf[6];
break;
case CDC_GET_LINE_CODING:
pbuf[0]=tempbuf[0];
pbuf[1]=tempbuf[1];
pbuf[2]=tempbuf[2];
pbuf[3]=tempbuf[3];
pbuf[4]=tempbuf[4];
pbuf[5]=tempbuf[5];
pbuf[6]=tempbuf[6];
break;
and define the uint8_t tempbuf[7]; in the user private_variables section.
Without the increased heap size, Windows does not react at all.
Without the point 3, Windows will send the baud rate information and then read the baud rate, expecting to get back the same values. Since you do not return any values, the virtual com port remains as driver-not-loaded.
If you do all of that, the Windows 10 out-of-the-box VCP driver can be used. No need to install the very old ST VCP driver on your system.
PS: I read somewhere turning on VSense makes problems, too. Don't know, I have not configured it and all works like a charm.
Put delay before CDC_Transmit_FS call - it will wait for the initiatialization. Your code should be like this
int main(void)
{
uint8_t Text[] = "Hello\r\n";
HAL_Delay(1000);
while (1)
{
CDC_Transmit_FS(Text,6); /*when commented the port is recognized*/
HAL_Delay(1000);
}
}
I had similar issue. I couldn't connect to a port and the port appears as just "virtual com port". I added while loop to wait for USBD_OK from CDC_Transmit_FS. Then it stars work even with out it or a delay after init function. I am not sure what the issue was.
while(CDC_Transmit_FS((uint8_t*)txBuf, strlen(txBuf))!=USBD_OK)
{
}
you may have to install driver to get device recognized as com port
you can get it from st site
if not installed the device is listed with question or exclamation mark on device manager
note that you cannot send until device get connected to host!
not sure that CubeMX CDC_Transmit_FS is checking for this
also instead of delay to resend you shall check the CDC class data "TXSstate"
is 0 mean tx is over.
I know it's a bit late, but I stumbled upon this post and it was extremely helpful.
Here is what I needed to do:
do the Line-Coding (I think only necessary on Windows-Systems)
increase Heap (Stack was left at default 0x200)
Here is what wasn't necessary for me (on a STM32F405RGT6 Chip):
change APP_RX_DATA_SIZE / APP_TX_DATA_SIZE (left it at 2048)
add a delay befor running CDC_Tranmit_FS()
Also some things to consider that happened to me in the past:
be sure to use a USB-Cable with data lines (most charging-cables don't have them)
double check the traces/connections if you use a custom board

TTF_OpenFont fails on Nth attempt

I'm trying to make a game in C using SDL_ttf to display the score every time the diplay is refreshed. The code looks like :
SDL_Surface *score = NULL;
TTF_Font *font;
SDL_Color color = { 255, 255, 255 };
font = TTF_OpenFont( "/home/sophie/Bureau/snake/data/ubuntu.ttf", 28 );
if (font == NULL) {
printf("%s\n", TTF_GetError());
}
score = TTF_RenderText_Solid( font, "score to display", color );
SDL_BlitSurface( score, NULL, screen, NULL );
SDL_Flip(screen);
When I launch the game, everything works properly, but after a while the game crashes and I get the following error :
Couldn't open /home/sophie/Bureau/snake/data/ubuntu.ttf
libgcc_s.so.1 must be installed for pthread_cancel to work
Abandon (core dumped)
I tried different fonts but I still have this problem.
Then I used a counter in the main loop of the game and found that the game always crashes after the 1008th time, regardless of the speed I wanted it to work at (in snake everything goes faster when you score points).
I don't know where does the problem comes from, nor what exactly does the error message mean.
Please tell me if you have any ideas, or if my question is poorly formulated. I looked on several forums and found nothing corresponding to my case, I could use any help now !
Thanks in advance
It looks like you're repeatedly opening the font every time you go through this function:
font = TTF_OpenFont( "/home/sophie/Bureau/snake/data/ubuntu.ttf", 28 );
While it may not be in the main game loop as Jongware suspected, you mentioned that after 1008 executions through this code path, the code crashes.
What is happening is that some resource is being leaked. Either the resource needs to be released by calling TTF_CloseFont() or (more efficient) hold onto the handle after the first time you open it and re-use it each time. Use a static declaration for the font and initialize to NULL:
static TTF_Font *font = NULL;
Then, if it hasn't been opened yet, open it:
if (!font) {
font = TTF_OpenFont( "/home/sophie/Bureau/snake/data/ubuntu.ttf", 28 );
}
This will initialize font the first time while subsequent iterations over the code will not unnecessarily re-do the process and leak the resource.
You mentioned that the code crashes after 1008 times through this function. That's pretty close to 1024. As memory serves, Linux has a limit of 1024 file handles per process (this is probably tunable in the kernel but I have run into this limitation in debugging resource leaks before). There are probably 16 other file handles open by your process and then 1 process being leaked by each invocation of TTF_OpenFont. Once you go above 1024, boom.
You can check the number of open file handles of a particular process (<pid>) by inspecting the number of file descriptors in /proc/<pid>/fd/.

Why does PortAudio not play nicely with other audio programs or how can I get it to?

I am trying to write an audio application using PortAudio, but if any other audio programs (usually Firefox) are running at the time which I try to run my program, I get the following error:
PaHost_OpenStream: could not open /dev/dsp for O_WRONLY
PaHost_OpenStream: ERROR - result = -10000
An error occured while using the portaudio stream
Error number: -10000
Error message: Host error.
Obviously, this makes my program pretty useless since it won't work if another program is using sound. Is there a way to get around this or should I just not use PortAudio?
You need to choose a device named "pulse" for PortAudio to work with PulseAudio, which is the sound server used for sound card sharing on the biggest Linux distros nowadays. The error message suggests that it is trying to use the OSS /dev/dsp interface, which does not support card sharing at all.
You can use code like this for listing the devices:
for (int i = 0, end = Pa_GetDeviceCount(); i != end; ++i) {
PaDeviceInfo const* info = Pa_GetDeviceInfo(i);
if (!info) continue;
printf("%d: %s\n", i, info->name);
}
Then supply the right number to OpenStream within stream parameter.
Notice that you need PortAudio v19. The older v18 only supported OSS.

Resources