Locking TopBlock stops WavFile-Sink

It looks like there is an issue where locking/unlocking the TopBlock
causes WavFile-Sink to stop recording. A plain File-Sink does not have
this problem. This problem is new to 3.7 and didn’t exist in 3.6. Is
this the intended behavior? I am doing something wrong? Should I be
using Stop/Wait?

I have put together an even more simplified C++ program here:
https://github.com/robotastic/topblock-lock
https://github.com/robotastic/topblock-lock
When you run it, the wav file will stop growing after 5 secs when the
graph is locked/unlocked and the file sink raw file will keep growing.

To compile, do ‘cmake .’ then ‘make’ then ‘topblock-lock’

Here is the basic code:

time_t last_monkey;

gr::top_block_sptr tb;
gr::blocks::vector_source_f::sptr src;
gr::blocks::throttle::sptr throttle;
gr::blocks::wavfile_sink::sptr wav_sink;
gr::blocks::file_sink::sptr raw_sink;
char filename[160];
char raw_filename[160];

volatile sig_atomic_t exit_flag = 0;

void exit_interupt(int sig){ // can be called asynchronously
exit_flag = 1; // set flag
}

int main(int argc, char **argv)
{

std::string device_addr;
double samp_rate=32000;

signal(SIGINT, exit_interupt);

tb = gr::make_top_block("Main");

vector<float> floatVector;

srand((unsigned)time(NULL));

for (int i =0; i < 2000; i++){
float r = static_cast (rand()) / static_cast
(RAND_MAX);
floatVector.push_back®;
}
src = gr::blocks::vector_source_f::make(floatVector,true);
throttle = gr::blocks::throttle::make(sizeof(float), samp_rate);

std::stringstream path_stream;
path_stream << boost::filesystem::current_path().string() <<
“/recordings”;

boost::filesystem::create_directories(path_stream.str());
sprintf(filename, “%s/main-0.wav”, path_stream.str().c_str());
wav_sink = gr::blocks::wavfile_sink::make(filename,1,samp_rate,16);
sprintf(raw_filename, “%s/main-0.raw”, path_stream.str().c_str());
raw_sink = gr::blocks::file_sink::make(sizeof(float), raw_filename);

tb->connect(src,0,throttle,0);
tb->connect(throttle,0,wav_sink,0);
tb->connect(throttle,0,raw_sink,0);

last_monkey = time(NULL);

tb->start();

while (1) {
if(exit_flag){
printf("\n Signal caught!\n");
tb->stop();
return 0;
}
if ((time(NULL) - last_monkey) > 10) {
last_monkey = time(NULL);
tb->lock();
tb->unlock();
}
}
// Exit normally.
return 0;
}

Hi,

When there is a lock()/unlock() cycle, the ->stop() will end up being
called on all the flowgraph() blocks.

The wavsink block does implement stop() and that’s where it closes the
file and updates the wavheader.

But there is no implementation for start(), it actually opens the file
in the constructor, so it can’t resume.

Cheers,

Sylvain

Awesome! That is totally it.

I went back and checked and the 3.6 version of wavfile_sink_impl does
not
have a stop function. It only closes the file when close() is called or
the
destructor.

This is a pretty big change from 3.6 to 3.7 and I didn’t see it
documented
anywhere. Is this something I can add to the 3.6 -> 3.7 guide in the
wiki?
Is there a better place to capture some of the lower level changes?

Are there any good guides that walk through the flows for high level
functions? Like what calling lock() triggers in the blocks and the
scheduler? It would make it a lot easier to walk through the code.

In order to solve my problem, it looks like I should create a custom
version of wavfile_sink that doesn’t have stop().

Thanks again!

  • Luke

On Mon, Jan 5, 2015 at 9:45 AM, Luke B. [email protected] wrote:

Awesome! That is totally it.

I went back and checked and the 3.6 version of wavfile_sink_impl does not
have a stop function. It only closes the file when close() is called or the
destructor.

This is a pretty big change from 3.6 to 3.7 and I didn’t see it documented
anywhere. Is this something I can add to the 3.6 -> 3.7 guide in the wiki?
Is there a better place to capture some of the lower level changes?

That’s the best place to add this change.

You could try and modify the code to overload the start() function to
open/reopen the file again (can’t say for sure this will be safe with a
wav
file, though). Though probably easiest to create your own block as part
of
any oot module you’ve built for your projects.

Tom

On Mon, Jan 5, 2015 at 10:44 AM, Sylvain M. [email protected]
wrote:

apparently multiple start()/stop() calls by the scheduler is something

Sylvain

This sounds like a good idea.

Tom

I will give it a try and see if I can make a start() that does this.

One last question - does calling lock() in a HeirBlock2 just lock and
call
stop() on the internal blocks of the HeirBlock2 graph? or does it bubble
up
all the way to the TopBlock and cause a lock there?

I am trying to figure out why calling lock() on one instance of a
HeirBlock
cause all the other instances to lock().

Hi,

You could try and modify the code to overload the start() function to
open/reopen the file again (can’t say for sure this will be safe with a wav
file, though). Though probably easiest to create your own block as part of
any oot module you’ve built for your projects.

I’d tend to say that the included block should support that. Since
apparently multiple start()/stop() calls by the scheduler is something
blocks should handle gracefully.

I’d assume stop() was made to close the file to ensure the header is
properly written.
But it could just update the header and seek back to the end without
actually closing the file and let the destructor do the close on the
fd.

Cheers,

Sylvain


Discuss-gnuradio mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/discuss-gnuradio

Yes, a lock/unlock event affects the whole flowgraph, by necessity.

Reconfiguring flowgraphs should be considered a very big hammer, often
used in cases that can be solved some less invasive way.

Just in case anyone is looking for a less invasive way to dynamically
configure a graph

I just tried out Copy block and it seems to be a great way to turn on
and off segments of a flow graph. I was locking & unlocking a graph to
remove and add blocks.

This seems more elegant and prevents any problems with the WavFile-Sink.

http://gnuradio.org/doc/doxygen/classgr_1_1blocks_1_1copy.html
http://gnuradio.org/doc/doxygen/classgr_1_1blocks_1_1copy.html