So my Performance Scores are not very bad.
Accounting, yet another language?
https://en.wikipedia.org/wiki/Accounting
It is said that accounting is the language of business. I believe that understanding of a specific part of our universe (or world, or society), at least to some extent, requires mastering a particular language used in that field.
You can not fully enjoy works of Shakespeare if you do not understand (early modern?) English, and you can not fully enjoy your ham life if you do not QSO on CW.
Xilinx ISE Design Suite 14.7
Mutex (3)
Mutex (2)
Moved the place to start a thread for data capture.
void thread_for_read(Sound* s) { while(1) { usleep(200000); /* 0.2sec */ mtx.lock(); s->loop_count = s->asound_read(); mtx.unlock(); } } int Sound::asound_init() { // lots of stuff for sound device initialize std::thread t1{bind(thread_for_read, this)}; t1.detach(); return 0; }
% cat log.txt SoundIC7410::SoundIC7410() sound_device = hw:2,0, channels = 1, rate = 32000 Sound::asound_init(): starting a thread. SoundSoft66::SoundSoft66() sound_device = hw:1,0, channels = 2, rate = 48000 thread_for_read(): id = 139684893808384 <- this line is for IC7410. Sound::asound_init(): starting a thread. thread_for_read(): id = 139684877022976 <- this line is for Soft66.
The output lines are interleaved as usual.
% ps aux -L | egrep '(Sprig|USER)' USER PID LWP %CPU NLWP %MEM VSZ RSS TTY STAT START TIME COMMAND user1 5581 5581 52.3 5 0.6 474400 52532 pts/1 Sl+ 10:36 1:48 ./Sprigmm025 hw:2,0 hw:1,0 /dev/ttyUSB1 user1 5581 5585 0.0 5 0.6 474400 52532 pts/1 Sl+ 10:36 0:00 ./Sprigmm025 hw:2,0 hw:1,0 /dev/ttyUSB1 user1 5581 5586 0.0 5 0.6 474400 52532 pts/1 Sl+ 10:36 0:00 ./Sprigmm025 hw:2,0 hw:1,0 /dev/ttyUSB1 user1 5581 5587 0.0 5 0.6 474400 52532 pts/1 Sl+ 10:36 0:00 ./Sprigmm025 hw:2,0 hw:1,0 /dev/ttyUSB1 user1 5581 5588 0.0 5 0.6 474400 52532 pts/1 Sl+ 10:36 0:00 ./Sprigmm025 hw:2,0 hw:1,0 /dev/ttyUSB1
Mutex
A mutex is an object used for controlling access in a multi-threaded system.
#include <mutex> std::mutex mtx; /* global */ void thread_test(Sound* s) { while(1) { usleep(200000); /* 0.2sec */ mtx.lock(); s->loop_count = s->asound_read(); /* write pointer goes forward */ mtx.unlock(); } } bool MyDrawingAreaS::on_draw(const Cairo::RefPtr<Cairo::Context> &cr) { if(s->loop_count) { while(s->signal_end - s->signal_start >= nfft*channels) { mtx.lock(); s->asound_fftcopy(); /* write pointer sometimes goes back */ mtx.unlock(); // }
% ag locked log.txt | tail 58033:AAA locked in thread_test(); 58037:BBB locked in on_draw(); 58038:BBB locked in on_draw(); 58039:BBB locked in on_draw(); 58040:BBB locked in on_draw(); 58041:BBB locked in on_draw(); 58042:BBB locked in on_draw(); 58043:BBB locked in on_draw(); 58044:AAA locked in thread_test(); 58046:BBB locked in on_draw(); 58047:BBB locked in on_draw(); % ag AAA | wc; ag BBB | wc 4284 17136 183477 40219 160876 1561654
The lines AAA and BBB should appear 5 (=1/0.2) times per second, and 46.9 (=48000/1024) times per second, respectively. Note that 40219/4284 (= 9.39) is close to 46.9/5 (=9.37).
Threads in C++11 (3)
void thread_test(Sound* s) { while(1) { usleep(200000); /* 0.2sec */ s->loop_count = s->asound_read(); } }
So the function asound_read() is called 5 times per second. Since the function returns the number of blocks read, each containing 4k samples, the average value of loop_count should be 2.34 (= 0.2*(48000/4k)).
% ag --no-numbers loop_count log.txt | sort | uniq -c 3 loop_count = 0 2282 loop_count = 2 992 loop_count = 3
After a short run of the program, the average value obtained is 2.30 (= (3*0+2282*2+992*3)/(3+2282+992)), and no -EPIPE error (overrun for capture) was observed during the run.
Threads in C++11 (2)
Now sound capture is from another thread.
void thread_test(Sound* s) { while(1) { usleep(100000); s->loop_count = s->asound_read(); } } MyDrawingAreaS::MyDrawingAreaS(Sound* ss) : s {ss} { thread t1{bind(thread_test, s)}; t1.detach(); }
This is quite a dirty hack, but it seems to work. Note that the waveforms looks funny because of the inappropriate setting of the input level.
_set_near
I knew that before, but have forgotten.
SoundIC7410::SoundIC7410() sound_device = hw:2,0, channels = 1, rate = 32000, buffer_size = 131072, period_size = 4096 snd_pcm_hw_params_set_buffer_size_near: buffer_size_org = 131072 , buffer_size = 131072 snd_pcm_hw_params_set_period_size_near: period_size_org = 4096 , period_size = 4096
This is OK, but:
SoundSoft66::SoundSoft66() sound_device = hw:1,0, channels = 2, rate = 48000, buffer_size = 32768, period_size = 6144 snd_pcm_hw_params_set_buffer_size_near: buffer_size_org = 32768 , buffer_size = 16384 snd_pcm_hw_params_set_period_size_near: period_size_org = 6144 , period_size = 8192
So this is the cause of capture overrun (-EPIPE errors) with Soft66LC4 occurring with some set of parameters. They are not exactly set, but with other part of the program, they are assumed to be the original intended values.
Many CW signals on the band last night. A contest was going on?
The Silver Searcher
The Silver Serarcher is a code searching tool, something like grep or ack.
Looks nice? I hope this tool will help solve my problem that the sound system (ALSA) does not or only sometimes recover from -EPIPE errors (overrun for capture).