I am trying to record a Phase 1 P25 Trunking systems. I have a bunch of OP25 records hooked up to the different channels that the system could use. I have a Valve in the flow graph that will allow samples to pass or dump them to a null_sink. This lets me turn P25 recorders on or off.
The problem is that the recorders using OP25 seem to using a ton of CPU even if they are not getting samples. I tracked it down to the p25_frame_assembler block. Whenever it is connected to a flow graph, it seems to be using a lot of CPU, even if it is not getting any samples.
Any ideas why the p25_frame_assembler block would be using CPU cycles even if it is not getting samples in?
I am running it with the following params: bool do_imbe = 1; bool do_output = 1; bool do_msgq = 0; bool do_audio_output = 1; bool do_tdma = 0;
So I don't fully understand it, but it looks like the problem is with forecast() in p25_frame_assembler.cc. My guess is that with the current forecast it would sometimes return that 0 Input samples are required because of the float to int conversion. The following code below makes a huge different for performance. What is the best way to submit a pull request?
void p25_frame_assembler_impl::forecast(int nof_output_items, gr_vector_int &nof_input_items_reqd) { // for do_imbe=false: we output packed bytes (4:1 ratio) // for do_imbe=true: input rate= 4800, output rate= 1600 = 32 * 50 (3:1) // for do_audio_output: output rate=8000 (ratio 0.6:1) const size_t nof_inputs = nof_input_items_reqd.size(); double samples_reqd = 4.0 * nof_output_items; int nof_samples_reqd; if (d_do_imbe) samples_reqd = 3.0 * nof_output_items; samples_reqd = nof_output_items; if (d_do_audio_output) samples_reqd = 0.6 * nof_output_items;
nof_samples_reqd = (int)ceil(samples_reqd); for(int i = 0; i < nof_inputs; i++) { nof_input_items_reqd[i] = nof_samples_reqd; }
}
Hi Luke,
That's a pretty significant find you have brought up. I concur on the dramatic performance increase seen on your end. This has a side effect on my end though. There are gaps in between each voice packet during the calls, which is causing constant audio underruns. So this isn't good for me. I'll have to play around with it more to find a cure.
However, when using the logfile workers, there are no gaps in the wav audio. This is kind of a big deal if this is how you use OP25. I can run 6 concurrent workers quite easily on an ancient Intel Q6600 "quad".
Thanks for bringing this up!
-Scott
This is how I modified the function:
void p25_frame_assembler_impl::forecast(int nof_output_items, gr_vector_int &nof_input_items_reqd) { // for do_imbe=false: we output packed bytes (4:1 ratio) // for do_imbe=true: input rate= 4800, output rate= 1600 = 32 * 50 (3:1) // for do_audio_output: output rate=8000 (ratio 0.6:1) const size_t nof_inputs = nof_input_items_reqd.size(); int nof_samples_reqd = nof_samples_reqd = (int)ceil(4.0f * float(nof_output_items)); if (d_do_imbe) nof_samples_reqd = (int)ceil(3.0f * float(nof_output_items)); if (d_do_audio_output) nof_samples_reqd = (int)ceil(0.6f * float(nof_output_items));
std::fill(&nof_input_items_reqd[0], &nof_input_items_reqd[nof_inputs], nof_samples_reqd); }
Awesome! It is good to hear that it wasn't just me that saw the performance improvements. Your good looks a bit cleaner. I am going to give that a try.
I think it could be played with a bit. I am using it like the logfile worker use case. I sometimes notice that the beginning or end of some transmissions are cut off. I think it could have something to do with the forecasting.... but it could also just be a bad transmission. Let me know if you manage to figure anything else out.
- Luke