22
R-C-D
6y

Hi android devs! 📱📱📱
I wanted to visualize a sound file using graphview.
But since the samplerate is high, it takes a long time .
To save the phone from freezing I tried using thread witch draws 2000 frames each 500 ms but it still takes a while to fully draw the graph .(lowering thread's repeat time also causes the system to freez)
What is the technical way of doing this?

Comments
  • 2
    First, determine the bottle neck. Read in the file data but don't do processing and draw random shit. Measure the time.

    Then read in say 1 MB of file data, do your calculations and drawing based on that buffer (with index wrap-around) and measure the time.

    Last, do file I/O and calculations but don't draw, also measuring the time.
  • 0
    @Fast-Nop isn't the time varient for different devices?
  • 1
    @R1100 Yes of course, but for getting a rough idea, it doesn't matter. The outcome also determines where to look next and what solutions are even worth considering.

    The idea is that you have three things here: reading stuff, processing it and drawing the results. The question is whether any of these three takes up the clear majority of the time. That's why you can do three tests with leaving out one of the things in each test and see how much faster things get without the omitted part.

    If the result is e.g. that you're file I/O bound, then splitting the calculation part into several threads won't be that beneficial.
  • 0
    @Fast-Nop drawing part seems to be the problem
  • 1
    @R1100 That's astonishing because in such an audio graph, all thats happening is drawing some hundred vertical lines. That shouldn't even depend on the file size because a longer file at the same window size is represented by fewer vertical lines. Each vertical lines represents more audio samples with increasing file size.

    The freezing happens because the GUI is busy during that time and won't deal with events until it is done. There are two options how to deal with that. Either you defer the heavy work to a worker thread, or you chop it into smaller slices and maintain a status counter where in the total work you are. Then you do a reasonable amount of work, good for let's say 10ms, leave the work and go back to your main event loop. If no events are there, you go back to your work and continue.
  • 1
    @Fast-Nop i think i sid not quite get it :/
    Can you please send an example code?
  • 1
    @R1100 unfortunately not, but the general thing with GUIs is, they have one loop where they process all their events. You can do small stuff directly in that loop. But heavy lifting means that the GUI cannot process other events until the calculation is done, which looks like GUI freezing. Therefore, you cannot do a big chunk of heavy work in that event loop.

    The cleanest solution is to have a worker thread, and the GUI thread tells the worker thread to do that stuff - while the GUI thread continues with its event loop. Of course, you'll need to synchronise these threads properly. The worker thread typically would send a "done" event to the GUI thread (and listen to a "cancel" event from the GUI).

    The easier, but less clean solution is to split the work in the GUI thread without second (worker) thread. Process say 128kB of data, store where in the work you are and return to the event processing. If no events are there, continue with the next 128kB and so on.
Add Comment