ALSA ignores configuration - c

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?

Related

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.

Rpi wheezy duplicate capture on usb & dummy cards

I am trying to create an application that will stream audio with Darkice as well as provide a LED VU meter indication of the audio stream.
I have created a virtual card with . This card is recognized by alsamixer, aplay, and arecord but I can not transfer the line-in signal from the usb card (hw:0,0) to the dummy card (hw:2,0).
I have tried several .asoundrc scripts that I found both in your Q&A as well as Google using alsa dmix, dsnoop, and multi but nothing has worked so far.
I am presently using one python program (LED_VU.py) that autostarts in one terminal, and the second python program containing Darkice (streamer.diDual.py) in a second terminal. The configuration portion of the LED program is:
### LED VU Meter on RPI ###
#!/usr/bin/env python
import alsaaudio as AA
import audioop
from time import sleep
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
#Define physical header pin numbers for 10 LEDs
RPiPins=[11,12,13,15,16,18,22,7,3,5]
#set all pins as output
for pin in RPiPins:
GPIO.setup(pin, GPIO.OUT)
#Set up audio
card = 'hw:0,0'
The configuation portion of darkiceDual.cfg is:
# Darkice Configuration File - Generated by Streamer
[general]
duration = 0 # duration of encoding, in seconds. 0 means forever
bufferSecs = 5 # size of internal slip buffer in seconds
reconnect = yes # reconnect to server if disconnected
[input]
device = hw:2,0 # alsa usb soundcard device for audio input
sampleRate = 44100 # sample rate in Hz
bitsPerSample = 16 # bits per sample
channel = 2 # channels. 1 = mono, 2 = stereo
My .asoundrc file is:
pcm.!default {
type plug
slave.pcm "mdev"
route_policy "duplicate"
}
pcm.mdev {
type multi
slaves.a.pcm "hw:0,0"
slaves.a.channels 2
slaves.b.pcm "dmixer"
slaves.b.channels 2
bindings.0.slave a
bindings.0.channel 0
bindings.1.slave a
bindings.1.channel 1
bindings.2.slave b
bindings.2.channel 0
bindings.3.slave b
bindings.3.channel 1
}
pcm.dmixer {
type dmix
ipc_key 1024
slave {
pcm "hw:2,0"
period_time 0
period_size 1024
buffer_size 4096
rate 44100
channels 2
format S16_LE
}
}
What am I doing wrong?
The streamer will have no audio if I use hw:2,0 and have the 'Can not connect' error if I use hw:0,0 (LED_VU.py is using this). If I change the card setting of the LED program to hw:2,0 the LEDs will lockup with all of them lit.
Any help is appreciated!
Thank you for the help. The two programs both use the usb line-in as expected.
I am not able to use alsamixer or amixer now. Pulseaudio is causing the problem now. If it is installed, the LED_VU.py program will not run. When it is uninstalled, the python programs will run but not alsamixer.
Apparently, you want to run the VU meter and DarkIce from the same audio data, i.e., you need to allow two programs to share one recording device.
This can be done with the dsnoop plugin. Which is enabled by default for USB devices.
Tell both programs to record from the device default. If that was redefined, try dsnoop:0 instead.

Sound device stop working PJSUA - underflow error

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.

write custom timestamp into syslog using syslog.h

my program get events from remote systems, every event contains an timestamp.
I want to log this events to syslog using the event timestamp instead of systemtime.
Is there any way to send a custom header to syslog deamon ?
I'm using rsyslog on debian
EDIT:
The "events" are generated by some "bare-metal" devices.
My application is a gateway between a realtime-ethernet (EthernetPOWERLINK) and a normal network.
I want to save them in micro-second precision, because its important to know in wich sequence they are occoured.
So i need the exact timestamp created by the bare-metal devices.
I'like to put this events into syslog.
I did not found any lib (except syslog.h) to write into syslog).
I really need to build the packages myself and send them to rsyslog deamon ?
No, don't open that can of worms.
If you allow the sender to specify the timestamp, you allow an attacker to spoof the timestamps of events they wish to hide. That kind of defeats the entire purpose (security-wise) of using a separate machine for logging.
What you can do, however, is compare the current time and the timestamp, and include that at the start of every logged message, using something like
struct timespec now;
struct timespec timestamp;
double delta;
int priority = facility | level;
const char *const message;
delta = difftime(timestamp.tv_sec, now.tv_sec)
+ ((double)timestamp.tv_nsec - now.tv_nsec) / 1000000000.0;
syslog(priority, "[%+.0fs] %s\n", delta, message);
On a typically configured Linux machine, that should produce something similar to
Jan 18 08:01:02 hostname service: [-1s] Original message
assuming the message took at least half a second to arrive. If hostname has its clock running fast, the delta would be positive. Normally, the delta is zero. In the case of a very slow network, the delta is negative, since the original event happened in the past relative to the timestamp shown.
If you already have infrastructure in place to monitor the logged messages, you can have a daemon or a cron script read the log files, and generate new log files (not via syslog(), but simply with string and file operations) with the timestamps adjusted by the specified delta. However, that must be done with extreme care, recognizing unacceptable or unexpectedly changing deltas, or maybe flagging them somehow.
If you write your log file monitoring/display widgets, then you can very easily let the user switch between "actual" (syslog) or "derived" (syslog + delta) timestamps, as the delta is trivial to extract from the logged lines if always present; even then, you must be careful to let the user know if a delta is out of bounds or changes unexpectedly, as such a change is most always informative to the user. (If it is not nefarious, it does mean there is something iffy with the machine timekeeping; time should not just jump around. Even NTP adjustments should be quite smooth.)
If you insist on opening that can of worms, just produce your own log files. Many applications do. It's not like syslog() was a magic bullet or a strict requirement for reliable logging, after all.
If your log-receiving application runs as a specific user and group, you can create /var/log/yourlogs/ owned by root user and that group, and save your log files there. Set the directory mode to 02770 (drwxrws--- or u=rwx,g=rwxs,o=), and all files created in that directory will automatically be owned by the same group (that's what the setgid bit, s, does for directories). You just need to make sure your service sets umask to 002 (and uses 0666 or 0660 mode flags when creating log files), so that they stay group-readable and group-writable.
Log rotation (archiving and/or deleting old log files, mailing logs) is usually a separate service, provided by the logrotate package, and configured by dropping a service-specific configuration file in /etc/logrotate.d/ at installation time. In other words, even if you write your own log files, do not rotate them; use the existing service for this. It makes life much easier for your users, us system administrators. (Note: Setting umask 002 at the start of the log rotate scripts is very useful in the above directory case; created files will then be group-writable. umask 022 will make them group-read-only.)
Ok've solved this, by enabling networking support (TCP) and micro seconds timer in rsyslog configuration.
Accroding to RFC 5424 my application build raw syslog messages and sends them via TCP (port 514) to the deamon.
Thanks to Nominal Animal, but i've no choice...
You can write a raw log message to the /dev/log file. This is a Unix domain socket from where the syslog server reads the messages, as they are written with the syslog() function.
I'm not sure about portability since the message format written by syslog() does not seem to follow the RFC 5424. I can only share my findings with busybox and its syslogd and nc utilities.
syslog() function writes messages as datagrams in the form <PRI>Mon DD HH:MM:SS message, where PRI is a priority, i.e. a decimal number computed as facility | severity, followed by a timestamp and a message.
With nc -u local:/dev/log, you can write UDP datagrams to the domain socket directly. For example, writing <84>Apr 3 07:27:20 hello world results in a Apr 3 07:27:20 hostname authpriv.warn hello world line in /var/log/messages.
Then you are free to extend the timestamp with the microseconds precision. Anyway, you need to make sure your syslog server implementation accepts such form. In case of busybox, I had to modify the source code.
Note: Busybox needs to be configured with enabled CONFIG_NC_EXTRA, CONFIG_NC_110_COMPAT and CONFIG_FEATURE_UNIX_LOCAL options to allow for opening /dev/log with nc.

Remux MPEG TS -> RTP MPEG ES

Please guide me to achieve the following result in my program (written in C):
I have a stream source as HTTP MPEG TS stream (codecs h264 & aac), It has 1 video and 1 audio substream.
I need to get MPEG ES frames (of same codecs), to send them via RTP to
RTSP clients. It'll be best if libavformat give frames with RTP
header.
MPEG ES is needed, because, as i know, media players on Blackberry
phones do not play TS (i tried it).
Although, i appreciate if anyone point me some another format, easier to get
in this situation, that can hold h264 & aac, and plays well on
blackberry and other phones.
I've already succeed with other task to open the stream and remux to
FLV container.
Tried to open two output format contexts with "rtp" formats, also got
frames. Sent to client. No success.
I've also tried writing frames to "m4v" AVFormatContext, have got
frames, have cut them by NAL, added RTP header before each frame, and sent to client. Client displays 1st frame and hangs, or plays a second of video+audio (faster than needed) each 10 seconds or more.
In VLC player log i have this: http://pastebin.com/NQ3htvFi
I've scaled timestamps to make them start with 0 for simplicity.
I compared it with what VLC (or Wowza, sorry i dont remember) incremented audio TS by 1024, not 1920, so i did additional linear scaling to be similar to other streamers.
Packet dump of playback of bigbuckbunny_450.mp4 is here:
ftp://rtb.org.ua/tmp/output_my_bbb_450.log
BTW in both cases i've hardly copied SDP from Wowza or VLC.
What is the right way to get what i need?
I'm also interested if there's some library similar to
libavformat? Maybe even in embryo state.

Resources