Draw lines consecutively

Hello friends,

I am working in a application in which I read a line of data of the sound
card every 100 milliseconds and I need to draw this lines of data
consecutively on a SDL window in real time.

What I do is to write always in the first line of the window and then move all
the data of the window one line to seem that the image is scrolling. I do
this with a ‘memmove’ but this is too slow and some lines are lost.

Can anybody help me please? ThanQ.

  1. If you have a 3d card, use SDL-OpenGL instead (hardware acceleration)
  2. If you are willing to skip the scrolling, just draw one line
    for each 100ms event, and fill the screen up (somewhat like the
    heart-activity meter on a hospitel, sorry don’t know the correct
    lingua) that way you don’t need the costly memmove operation
  3. Try lowering the resolution

/Olof

Manuel D. Lago Reguera: “[SDL] Draw lines consecutively” (2004-07-21…

#Hello friends,#

I am working in a application in which I read a line of data of the sound

#card every 100 milliseconds and I need to draw this lines of data
#consecutively on a SDL window in real time.

#What I do is to write always in the first line of the window and then move all
#the data of the window one line to seem that the image is scrolling. I do
#this with a ‘memmove’ but this is too slow and some lines are lost.

#Can anybody help me please? ThanQ.

#_______________________________________________
#SDL mailing list
#SDL at libsdl.org
#http://www.libsdl.org/mailman/listinfo/sdl

A slightly different approach, but first, let me see that I have a good
idea of your current implementation, please reply making any
corrections that are necessary.

You are currently using a surface which contains the graphical
representation you are building of the sound data. You are using either
memmove, memcpy, or similar routines to create a scrolling effect.

Consider the following analogy to your scrolling effect. Imagine that
instead of scrolling graphics data, we have an array, and we wish to
insert some data at the beginning, so we must first move all of that
data to make room for it, sacrificing the last entry as in your
situation.

int Array[Size];

while (SomeCondition) {

for (int i=0; i < Size -1; i++) Array[i+1] = Array[i]; // Memmove type
of routine

Array[0] = GetData(); // Insert the value from the user (or from a
file, or a soundcard, whatever)

const int ScreenPosition = 0, DataPosition = 0; // Such descriptive
names! Read more below.
SomeDisplayRoutine( Array, DataPosition, ScreenPosition, Size );
}

In the above analog to your situation, we have to do an expensive
movement operation on all the memory we wish to represent! Also you may
wonder what the parameters are to SomeDisplayRoutine, they are, in
order:

  • the data to display
  • what row within the data , and how many rows to display. If you were
    to increment the ScreenPosition every frame without changing the data
    you were displaying, it should look like a static image just sliding
    down the screen (or in which ever direction you’d like.) If you were to
    increment DataPosition that way, and you incremented Size, it would
    look like your image was vanishing from its top.

The following pseudo code will explain the better method, which
resembles a strategy I use for creating queues in C that are fast and
simple. I hope the code with the comments is pretty self explanatory.
(Size, btw, is and has been the variable name I used to represent the
number of total rows on the screen, or wherever it is we’re displaying
the data.)

int Array[Size], CurrentRow = 0;

while (SomeCondition) {
Array [CurrentRow] = GetData();

SomeDisplayRoutine( Array, 0, CurrentRow -1, Size - CurrentRow );
SomeDisplayRoutine( Array, CurrentRow, 0, CurrentRow - Size -1 );

if (++CurrentRow == Size) CurrentRow = 0; // Here we make sure we don’t
overflow Array
}

There might be some OFF-BY-ONE bugs in that pseudo code… Some more
explanation: essentially the “DataPosition” (second) argument to
SomeDisplayRoutine is an analog to the Source Rectangle of blitting
operations in SDL (you can specify source rectangles in SDL right? I
know you can in pygame, I’ve been using OpenGL so much lately I’ve
forgotten!) And the “ScreenPosition” (third) argument to
SomeDisplayRoutine is like your destination rectangle.

This sort of algorithm is constantly updating a surface’s data, one row
at a time, and wrapping around when it hits the end. Then when it’s
time to update the screen’s contents, it draws the beginning part of
the data, and the end part of the data. Very simple, very efficient. It
should help your tremendously.

Also once you have this set in place, you may want to test it using
SDL_SWSURFACEs and SDL_HWSURFACEs (those are the flags you use to
choose between video memory and system memory right?) As a matter of
fact for a surface that gets changed so often, you may even want for
your program to test which is faster, since on some computers, one may
be faster than the other (many people will say that video memory is
ALWAYS slower, but I’ve heard convincing reasons why not.)

Hope this helps you on your project creating graphical “music
visualization” (which is what I assume you’re doing.)On Jul 21, 2004, at 6:53 AM, Manuel D. Lago Reguera wrote:

Hello friends,

I am working in a application in which I read a line of data of the
sound
card every 100 milliseconds and I need to draw this lines of data
consecutively on a SDL window in real time.

What I do is to write always in the first line of the window and then
move all
the data of the window one line to seem that the image is scrolling. I
do
this with a ‘memmove’ but this is too slow and some lines are lost.

Can anybody help me please? ThanQ.


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

Also you may wonder what the parameters are to SomeDisplayRoutine,
they are, in order:

  • the data to display
  • what row within the data , and how many rows to display. If you
    were to increment the ScreenPosition every frame without changing the
    data you were displaying, it should look like a static image just
    sliding down the screen (or in which ever direction you’d like.) If
    you were to increment DataPosition that way, and you incremented Size,
    it would look like your image was vanishing from its top.

Please allow me to reformat this paragraph and the following list.
Somehow, I only separated and bulleted the first two items. I also made
a few clarifications. I apologize that this took two emails to write.
Below are the changes:

Also you may wonder what the parameters are to SomeDisplayRoutine, they
are, in order:

  • the data to display
  • what row in our data to start drawing from
  • what row on our display to drawing to
  • how many rows to display.

If you were to increment the ScreenPosition every frame without
changing the data you were displaying, it should look like a static
image just sliding down the screen (or in which ever direction you’d
like.)

If you were to increment DataPosition that way, and you incremented
Size, it would look like your image was vanishing from its top.On Jul 21, 2004, at 12:50 PM, Donny Viszneki wrote:

A slightly different approach, but first, let me see that I have a good
idea of your current implementation, please reply making any
corrections that are necessary.

You are currently using a surface which contains the graphical
representation you are building of the sound data. You are using either
memmove, memcpy, or similar routines to create a scrolling effect.

Consider the following analogy to your scrolling effect. Imagine that
instead of scrolling graphics data, we have an array, and we wish to
insert some data at the beginning, so we must first move all of that
data to make room for it, sacrificing the last entry as in your
situation.

int Array[Size];

while (SomeCondition) {

for (int i=0; i < Size -1; i++) Array[i+1] = Array[i]; // Memmove type
of routine

Array[0] = GetData(); // Insert the value from the user (or from a
file, or a soundcard, whatever)

const int ScreenPosition = 0, DataPosition = 0; // Such descriptive
names! Read more below.
SomeDisplayRoutine( Array, DataPosition, ScreenPosition, Size );
}

In the above analog to your situation, we have to do an expensive
movement operation on all the memory we wish to represent! Also you may
wonder what the parameters are to SomeDisplayRoutine, they are, in
order:

  • the data to display
  • what row within the data , and how many rows to display. If you were

to increment the ScreenPosition every frame without changing the data
you were displaying, it should look like a static image just sliding
down the screen (or in which ever direction you’d like.) If you were to
increment DataPosition that way, and you incremented Size, it would
look like your image was vanishing from its top.

The following pseudo code will explain the better method, which
resembles a strategy I use for creating queues in C that are fast and
simple. I hope the code with the comments is pretty self explanatory.
(Size, btw, is and has been the variable name I used to represent the
number of total rows on the screen, or wherever it is we’re displaying
the data.)

int Array[Size], CurrentRow = 0;

while (SomeCondition) {
Array [CurrentRow] = GetData();

SomeDisplayRoutine( Array, 0, CurrentRow -1, Size - CurrentRow );
SomeDisplayRoutine( Array, CurrentRow, 0, CurrentRow - Size -1 );

if (++CurrentRow == Size) CurrentRow = 0; // Here we make sure we don’t
overflow Array
}

There might be some OFF-BY-ONE bugs in that pseudo code… Some more
explanation: essentially the “DataPosition” (second) argument to
SomeDisplayRoutine is an analog to the Source Rectangle of blitting
operations in SDL (you can specify source rectangles in SDL right? I
know you can in pygame, I’ve been using OpenGL so much lately I’ve
forgotten!) And the “ScreenPosition” (third) argument to
SomeDisplayRoutine is like your destination rectangle.

This sort of algorithm is constantly updating a surface’s data, one row
at a time, and wrapping around when it hits the end. Then when it’s
time to update the screen’s contents, it draws the beginning part of
the data, and the end part of the data. Very simple, very efficient. It
should help your tremendously.

Also once you have this set in place, you may want to test it using
SDL_SWSURFACEs and SDL_HWSURFACEs (those are the flags you use to
choose between video memory and system memory right?) As a matter of
fact for a surface that gets changed so often, you may even want for
your program to test which is faster, since on some computers, one may
be faster than the other (many people will say that video memory is
ALWAYS slower, but I’ve heard convincing reasons why not.)

Hope this helps you on your project creating graphical “music
visualization” (which is what I assume you’re doing.)

Hello friends,

I am working in a application in which I read a line of data of the
sound
card every 100 milliseconds and I need to draw this lines of data
consecutively on a SDL window in real time.

What I do is to write always in the first line of the window and then
move all
the data of the window one line to seem that the image is scrolling. I
do
this with a ‘memmove’ but this is too slow and some lines are lost.

Can anybody help me please? ThanQ.

Rather than doing a memmove every frame, consider keeping track of the
current line you are writing to and just write to that line and progress
the line number down. Then keep track of 2 rects, the top and the bottom
display rect; they will divide at where your line number variable is at.
Then all you do is display the top portion and the bottom portion and no
memmoves have been done. This is similar to the method that directSound
employs for streaming sound buffers to avoid doing excessive memmoves
while it updates the sound buffer and is called a Ring Buffer.

  • Will> On Jul 21, 2004, at 6:53 AM, Manuel D. Lago Reguera wrote: