Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Video files in Allgro?

Credits go to Ariesnl, Arthur Kalliokoski, Derezo, Evert, gnolam, HoHo, Jonny Cook, Kitty Cat, Michael Faerber, Michael Jensen, Randal Stackpoole, ReyBrujo, Thomas Fjellstrom, Tobias Dammers, Victor Williams Stafusa da Silva, and Zaphos for helping out!
This thread is locked; no one can reply to it. rss feed Print
Video files in Allgro?
Kitty Cat
Member #2,815
October 2002
avatar

For Ogg music, you probably shouldn't load it all at once, anyway. I'll continue looking into this problem, but for now, you could try to do this to play the music:

APEG_STREAM *stream = apeg_open_stream("15.ogg");
if(!stream)
   error("couldn't open 15.ogg because: %s", apeg_error);
..
/* in main loop, regularly call: */
if(apeg_advance_stream(stream, TRUE) != APEG_OK)
   error("song stopped because: %s", apeg_error);
/* if you're not looping, that can return APEG_EOF, which is not an error */
..
/* when done: */
apeg_close_stream(stream);
stream = NULL;

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

Martano
Member #6,536
October 2005
avatar

I needed to change the error messages to:

if(!stream){
               set_gfx_mode(GFX_TEXT,0,0,0,0);
   allegro_message("couldn't open 15.ogg because: %s", apeg_error);
   exit(EXIT_FAILURE);
}

, because it didn't recognized "error".
It compiled and opened the program. But played no music and showed no error message.

Kitty Cat
Member #2,815
October 2002
avatar

You'd have to show more code. If the stream opened, and you regularly call that function, you should hear the music.

Quote:

it didn't recognized "error"

It was psuedo code, letting you know to handle it like an error if that happened. ;)

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

Martano
Member #6,536
October 2005
avatar

Here is the function where I am using the command:

1void novocarr(DATAFILE *data, BITMAP *tela)
2{
3 set_trans_blender(255, 255, 255, 128);
4
5 p = 0;
6
7 APEG_STREAM *stream = apeg_open_stream("15.ogg");
8 
9//------------
10 if(!stream)
11 {
12 set_gfx_mode(GFX_TEXT,0,0,0,0);
13 allegro_message("couldn't open 15.ogg because: %s", apeg_error);
14 exit(EXIT_FAILURE);
15 }
16//------------
17
18 while(!p == 1)
19 {
20 draw_sprite(tela,(BITMAP*)data[titulo].dat, 0, 0);
21 textprintf_ex(tela, font, 50, 240, makecol(255,255,255),-1,"%s, você deseja começar um novo jogo ou carregar outro?",the_name);
22 
23 botao0(data,tela,(BITMAP*)data[novo].dat);
24 botaoM(data,tela,(BITMAP*)data[carr].dat);
25// botao2(data,tela,(BITMAP*)data[novo].dat);
26 botaoS(data,tela,(BITMAP*)data[sair].dat);
27
28 show_mouse(tela);
29 blit(tela, screen, 0,0,0,0,640,480);
30 clear_bitmap(tela);
31
32//------------
33 if(!stream)
34 {
35 set_gfx_mode(GFX_TEXT,0,0,0,0);
36 allegro_message("song stopped because: %s", apeg_error);
37 exit(EXIT_FAILURE);
38 }
39//------------
40
41 }
42
43 /* when done: */
44apeg_close_stream(stream);
45stream = NULL;
46
47}

Evert
Member #794
November 2000
avatar

Call me slow, but I don't see any apeg_advance_stream() calls in that code...

Martano
Member #6,536
October 2005
avatar

There is no "apeg_advance_stream()". What is it?

I am only using:

APEG_STREAM *stream = apeg_open_stream("15.ogg");
apeg_close_stream(stream);
stream = NULL;

Evert
Member #794
November 2000
avatar

Quote:

There is no "apeg_advance_stream()". What is it?

Kitty cat said:

but for now, you could try to do this to play the music:

APEG_STREAM *stream = apeg_open_stream("15.ogg");
if(!stream)
error("couldn't open 15.ogg because: %s", apeg_error);
..
/* in main loop, regularly call: */
if(apeg_advance_stream(stream, TRUE) != APEG_OK)
error("song stopped because: %s", apeg_error);
/* if you're not looping, that can return APEG_EOF, which is not an error */
..
/* when done: */
apeg_close_stream(stream);
stream = NULL;

Be a bit more careful about reading other people's posts (especially if they wrote the thing you're using)! ;)

Right now, all you're doing is reading the file from disk. You're not playing it, so it stands to reason that you don't hear any music playing when you run your code!

Martano
Member #6,536
October 2005
avatar

Sorry. :-[

I don't know why I changed that part of the code. It is working now. Thanks again. :)

------------

How to set the volume of the song?
And is there a way to put an ogg file inside a datafile?

Kitty Cat
Member #2,815
October 2002
avatar

Quote:

How to set the volume of the song?

Use
int voice = apeg_get_stream_voice(stream);to get the voice number of a loaded stream, and then use
voice_set_volumeto set its volume.

Quote:

And is there a way to put an ogg file inside a datafile?

Yes. Just put it in as a binary chunk, then read with either:

/* Direct from disk: */
stream = apeg_open_stream("datafile.dat#object_name");
/* if loaded into memory: */
stream = apeg_open_memory_stream(datafile[object_name].dat, datafile[object_name].size);

Then use apeg_advance_stream and apeg_close_stream as normal.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

Martano
Member #6,536
October 2005
avatar

What is a binary chunk? Because I couldn't use grabber to load the ogg.

Kitty Cat
Member #2,815
October 2002
avatar

If you use dat, it should load it as binary automatically. Using the -t switch (-t VORB or -t VRBS) is probably a good idea, too.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

Martano
Member #6,536
October 2005
avatar

Thanks! ;D

Now I need to play a sound until the end and them continue the program.
Is there a command to do this or do I need "while" function?

I was trying this:

      while(t < 10)
      {
       t++;
       if(apeg_advance_stream(stream, TRUE) != APEG_OK)
       {
        set_gfx_mode(GFX_TEXT,0,0,0,0);
        allegro_message("Nao pode tocar o som, porque: %s", apeg_error);
        exit(EXIT_FAILURE);
       }
       rest(1000);
      }

But the "rest" cuts sound each second. It only works this way:

      while(t < 10000)
      {
       t++;
       if(apeg_advance_stream(stream, TRUE) != APEG_OK)
       {
        set_gfx_mode(GFX_TEXT,0,0,0,0);
        allegro_message("Nao pode tocar o som, porque: %s", apeg_error);
        exit(EXIT_FAILURE);
       }
      }

But this would make the time to be different in each computer.

Zaphos
Member #1,468
August 2001

How about:

while((ret = apeg_advance_stream(stream, FALSE)) == APEG_OK) {}
if (ret == APEG_ERROR) {
        set_gfx_mode(GFX_TEXT,0,0,0,0);
        allegro_message("Nao pode tocar o som, porque: %s", apeg_error);
        exit(EXIT_FAILURE);
}

So you keep calling the function until it returns with EOF or ERROR

Martano
Member #6,536
October 2005
avatar

Thanks!

Now it is working! :D

Well.... you all REALLY helped me! Look the size of this thread! ;D

--------
EDIT:

New problem :P

I need to play a song while it shows a image, wait, and shows another image, wait....

But when I use the wait function, it cuts the song.

1void esperar(int x) //esperar = to wait
2{
3 clock_t start_time, cur_time;
4 start_time = clock();
5 while((clock() - start_time) < x * CLOCKS_PER_SEC){}
6}
7 
8void apresentar(DATAFILE *data,BITMAP *tela)
9{
10 set_trans_blender(255, 255, 255, 128);
11 draw_gouraud_sprite(screen,tela, 0, 0, 0, 0, 0, 0);
12 esperar(1);
13 draw_gouraud_sprite(screen,tela, 0, 0, 255, 0, 0, 0);
14 esperar(1);
15 draw_gouraud_sprite(screen,tela, 0, 0, 255, 255, 0, 0);
16 esperar(1);
17 draw_gouraud_sprite(screen,tela, 0, 0, 255, 255, 255, 0);
18 esperar(1);
19 draw_gouraud_sprite(screen,tela, 0, 0, 255, 255, 255, 255);
20
21 set_trans_blender(0, 0, 0, 128);
22 
23 APEG_STREAM *stream = apeg_open_stream("musini.ogg");
24
25 pisca(data, tela, (BITMAP*)data[astro].dat, 4);
26 esperar(2);
27 pisca(data, tela, (BITMAP*)data[muri].dat, 4);
28 esperar(1);
29 while(co < 255)
30 {
31 esperar(1/30);
32 co++;
33 co++;
34 draw_gouraud_sprite(tela, (BITMAP*)data[apre].dat, 250, 225, co, co, co, co);
35 blit(tela, screen, 0, 0, 0, 0, 640, 480);
36 clear(tela);
37 }
38 esperar(1);
39 while(co > 0)
40 {
41 esperar(1/30);
42 co--;
43 co--;
44 draw_gouraud_sprite(tela, (BITMAP*)data[apre].dat, 250, 225, co, co, co, co);
45 blit(tela, screen, 0, 0, 0, 0, 640, 480);
46 clear(tela);
47 }
48 esperar(1);
49 while(co < 255)
50 {
51 esperar(1/30);
52 co++;
53 draw_gouraud_sprite(tela,(BITMAP*)data[abat].dat, 0, 0, co, co, co, co);
54 blit(tela, screen, 0,0,0,0,640,480);
55 clear(tela);
56 }
57 esperar(4);
58 while(co > 0)
59 {
60 int voice = apeg_get_stream_voice(stream);
61 voice_set_volume(voice, co);
62 adjust_sample((SAMPLE*)data[musini].dat, co, 128, 1000, 0);
63 esperar(1/30);
64 co--;
65 draw_gouraud_sprite(tela,(BITMAP*)data[abat].dat, 0, 0, co, co, co, co);
66 blit(tela, screen, 0,0,0,0,640,480);
67 clear(tela);
68 }
69 esperar(1);
70
71 apeg_close_stream(stream);
72 stream = NULL;
73}

The song must be played since the:

APEG_STREAM *stream = apeg_open_stream("musini.ogg");

until the last lines.

Kitty Cat
Member #2,815
October 2002
avatar

You're not calling apeg_advance_stream anywhere. You need to call it regularly or else it won't get a new batch of samples to the card in time.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

Martano
Member #6,536
October 2005
avatar

I know. But I don't know where I should use it. :-[
If I use in all the "while" functions, the wait function will cut the song.

Zaphos
Member #1,468
August 2001

options:
(1) You can call apeg_advance_stream in the wait function as well.
(2) You can use a separate thread to play the music.

Kitty Cat
Member #2,815
October 2002
avatar

or:
(3) redesign the loop so it allows for what you need to do.

Also, the esperar(1/30) call isn't going to do anything. 1/30 = 0 to an int, so you're waiting 0 seconds (call clock(), call clock() again, and see that enough time has passed, and return immediately).

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

Martano
Member #6,536
October 2005
avatar

Quote:

(2) You can use a separate thread to play the music.

How?

Quote:

(3) redesign the loop so it allows for what you need to do.

How?

vpenquerch
Member #233
April 2000

How to redesign the loop ?
You've got all the information in the previous posts, I think. You've just got to read it and understand it.
What you've done here is just copy code. You can do what you want by just modifying that code. The changes you need to make are unrelated to the apeg code, it's just adding your image drawing code, so you should have all the tools you need to do it yourself.

Start with the last loop that works for you, and think about where you can draw things without breaking the sound. If you know why the sound doesn't break with that particular loop, then you'll see how easy it is to add the draw code. But, for this, you need to understand why this loop works and some others you've tried do not. When you've understood this, if you don't already, you'll find it much easier to continue your program without breaking the sound play (or other things).

Martano
Member #6,536
October 2005
avatar

In real I didn't understand how you can play a song using the "if" function. You are not sending a command, but just checking it. The command should come in "{}", after the "if()".At least this is what I know about the "if" function.

But I liked the 2nd option, about a new thread, looks like very useful. But I have no idea about how to do it. :-[

Kitty Cat
Member #2,815
October 2002
avatar

if() isn't a function, it's something the compiler uses to branch code. You call apeg_advance_stream(stream, TRUE) in the if check, which the compiler knows to call that function and then check its return value against APEG_OK (and then gives the if() "command" a true or false value based on the comparison that's used to determine whether to execute the following code block or not).

It would be easy to rewrite your main loops to call apeg's polling function, however it's your code, and I don't know what your ultimate goal is. You're the one most qualified to modify it.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

Martano
Member #6,536
October 2005
avatar

Got it! Thanks! :D

(But I am still curious about the "2nd thread". :P Does anyone know a tutorial about it?)

--------------------------------

EDIT:

Errrrr. :-/

How to use the

if(apeg_advance_stream(stream, TRUE) != APEG_OK)

while showing this dialog:

     DIALOG dlg[] =
     {
     /* (proc)      (x)  (y)  (w)  (h) (fg) (bg)      (key) (flags) (d1) (d2) (dp)                        (dp2) (dp3) */
     { d_box_proc,  170, 215, 300, 50, 0,   16777215, 0,    0,      0,   0,   NULL,                       NULL, NULL },
     { d_text_proc, 180, 225, 250, 20, 0,   16777215, 0,    0,      0,   0,   (void*)"Escreva o código para carregar:", NULL, NULL },
     { d_edit_proc, 180, 245, 250, 20, 0,   16777215, 0,    D_EXIT,20,   0,   (void*)the_code,            NULL, NULL },
     { NULL,        0,   0,   0,   0,  0,   0,        0,    0,      0,   0,   NULL,                       NULL, NULL }
     };
     do_dialog(dlg, 2);

Zaphos
Member #1,468
August 2001

You could make it a gui item like clock proc in excustom.c (see your allegro examples folder), and then call apeg_advance_stream when your procedure recieves MSG_DRAW and/or MSG_IDLE messages.

As to the second thread stuff, for portable code you could use a pthreads library for windows, and for nonportable code you could use windows threads; pthreads has a tutorial here: [url http://www.cs.nmsu.edu/~jcook/Tools/pthreads/pthreads.html] and windows threads has a tutorial here: [url http://www.flipcode.com/articles/article_multithreading.shtml]

pthreads code might look like this:

void *playfunc(void *s)
{
   while (apeg_advance_stream((APEG_STREAM *)s, TRUE) == APEG_OK) {}
   return NULL;
}
// and later, in main, to start the music:
pthread_t music;
pthread_create (&music, NULL, playfunc, stream);

// and later if you want to wait for the music to end:
pthread_join(music, NULL);

Victor Williams Stafusa da Silva
Member #4,212
January 2004
avatar

I saw that:

void esperar(int x) //esperar = to wait
{
     clock_t start_time, cur_time;
         start_time = clock();
         while((clock() - start_time) < x * CLOCKS_PER_SEC){}
}

...

esperar(1/30);

This isn't good. It will pass zero to esperar() because the parameter is an int. You should do that:

void esperar(float x) //esperar = to wait
{
     clock_t start_time, cur_time;
         start_time = clock();
         while((clock() - start_time) < (int) (x * CLOCKS_PER_SEC)){}
}

...

esperar(1.0/30.0);

EDIT: Didn't read all the replies. Looks like Kitty Cat already said that.

[The attack of the space bugs - Speedhack 2005] [Rambananas - Speedhack 2006] [Make clean - Speedhack 2009] [The source god - TINS 2010]



Go to: