Permalink
Browse files

Finished the 2nd example of the music stuff

  • Loading branch information...
1 parent b7fa6f4 commit 1c38b7082b4343740035e8505f397c264f31a99f @kthakore kthakore committed Dec 24, 2010
Showing with 272 additions and 1 deletion.
  1. +1 −1 code_listings/sound_event.pl
  2. +271 −0 src/08-music_and_sound.pod
@@ -20,7 +20,7 @@
);
# Initialize the Audio
-unless ( SDL::Mixer::open_audio( 44100, AUDIO_S16SYS, 1, 4096 ) == 0 ) {
+unless ( SDL::Mixer::open_audio( 44100, AUDIO_S16SYS, 2, 4096 ) == 0 ) {
Carp::croak "Cannot open audio: " . SDL::get_error();
}
@@ -158,6 +158,277 @@ Volumes can be set at anytime and range from C<1-100>.
Now that we know how to prepare and play simple sounds we will apply it to an C<SDLx::App>.
+=head2 SDLx::App Audio Initialization
+
+C<SDLx::App> will initialize everything normally for us. However for a stream line application it is recommend to initialize only the things we need. In this case that is C<SDL_INIT_VIDEO> and C<SDL_INIT_AUDIO>.
+
+ use strict;
+ use warnings;
+ use SDL;
+ use Carp;
+ use SDLx::App;
+ use SDL::Audio;
+ use SDL::Mixer;
+ use SDL::Event;
+ use SDL::Events;
+ use SDL::Mixer::Music;
+ use SDL::Mixer::Samples;
+ use SDL::Mixer::Channels;
+
+ my $app = SDLx::App->new(
+ init => SDL_INIT_AUDIO | SDL_INIT_VIDEO,
+ width => 250,
+ height => 75,
+ title => "Sound Event Demo",
+ eoq => 1
+
+ );
+
+=head2 Loading Resources
+
+It is highly recommended to perform all resource allocations before a C<SDLx::App::run()> method is called.
+
+
+ # Initialize the Audio
+ unless ( SDL::Mixer::open_audio( 44100, AUDIO_S16SYS, 2, 4096 ) == 0 ) {
+ Carp::croak "Cannot open audio: " . SDL::get_error();
+ }
+
+ #Something to show while we play music and sounds
+ my $channel_volume = 100;
+ my $music_volume = 100;
+ my $laser_status = 'none';
+ my $music_status = 'not playing';
+
+ # Load our sound resources
+ my $laser = SDL::Mixer::Samples::load_WAV('data/sample.wav');
+ unless ($laser) {
+ Carp::croak "Cannot load sound: " . SDL::get_error();
+ }
+
+ my $background_music =
+ SDL::Mixer::Music::load_MUS('data/music/01-PC-Speaker-Sorrow.ogg');
+ unless ($background_music) {
+ Carp::croak "Cannot load music: " . SDL::get_error();
+ }
+
+
+=head2 The Show Handler
+
+For the purposes of describing the current state of the music lets draw text to the screen in a C<show_handler>.
+
+ $app->add_show_handler(
+ sub {
+
+ $app->draw_rect([0,0,$app->w,$app->h], 0 );
+
+ $app->draw_gfx_text( [10,10], [255,0,0,255], "Channel Volume : $channel_volume" );
+ $app->draw_gfx_text( [10,25], [255,0,0,255], "Music Volume : $music_volume" );
+ $app->draw_gfx_text( [10,40], [255,0,0,255], "Laser Status : $laser_status" );
+ $app->draw_gfx_text( [10,55], [255,0,0,255], "Music Status : $music_status" );
+
+ $app->update();
+
+ }
+ );
+
+This will draw the channel volume of our samples, and the volume of the music. It will also print the status of our two sounds in the application.
+
+=head2 The Event Handler
+
+Finally our event handler will do the actual leg work and trigger the music and sound as we need it.
+
+ $app->add_event_handler(
+ sub {
+ my $event = shift;
+
+ if ( $event->type == SDL_KEYDOWN ) {
+ my $keysym = $event->key_sym;
+ my $keyname = SDL::Events::get_key_name($keysym);
+
+ if ( $keyname eq 'space' ) {
+
+ $laser_status = 'PEW!';
+ #fire lasers!
+ SDL::Mixer::Channels::play_channel( -1, $laser, 0 );
+
+ }
+ elsif ( $keyname eq 'up' ) {
+ $channel_volume += 5 unless $channel_volume == 100;
+ }
+ elsif ( $keyname eq 'down' ) {
+ $channel_volume -= 5 unless $channel_volume == 0;
+ }
+ elsif ( $keyname eq 'right' ) {
+ $music_volume += 5 unless $music_volume == 100;
+ }
+ elsif ( $keyname eq 'left' ) {
+ $music_volume -= 5 unless $music_volume == 0;
+ }
+ elsif ( $keyname eq 'return' ) {
+ my $playing = SDL::Mixer::Music::playing_music();
+ my $paused = SDL::Mixer::Music::paused_music();
+
+ if ( $playing == 0 && $paused == 0 ) {
+ SDL::Mixer::Music::play_music( $background_music, 1 );
+ $music_status = 'playing';
+ }
+ elsif ( $playing && !$paused ) {
+ SDL::Mixer::Music::pause_music();
+ $music_status = 'paused'
+ }
+ elsif ( $playing && $paused ) {
+ SDL::Mixer::Music::resume_music();
+ $music_status = 'resumed playing';
+ }
+
+ }
+
+ SDL::Mixer::Channels::volume( -1, $channel_volume );
+ SDL::Mixer::Music::volume_music($music_volume);
+
+ }
+
+ }
+
+ );
+
+The above event handler fires the laser on pressing the 'Space' key. Go ahead and press it multiple times as if you are firing a gun in a game! You will notice that depending on how fast you fire the laser the application will still manage to overlap the sounds as needed. The sample overlapping is accomplished by requiring multiple channels in the C<open_audio> call. If your game has lots of samples that may play at the same time you may need more channels allocated.
+Additionally you can see that the volume control is easily managed both on the channels and the music with just incrementing or decrementing a value and calling the appropriate function.
+
+Finally it is worth noticing the various state the background music can be in.
+
+Lets run this application and the make sure to clean up the audio on the way out.
+ $app->run();
+ SDL::Mixer::Music::halt_music();
+ SDL::Mixer::close_audio;
+
+
+=head2 Completed Code
+
+=begin programlisting
+ use strict;
+ use warnings;
+ use SDL;
+ use Carp;
+ use SDLx::App;
+ use SDL::Audio;
+ use SDL::Mixer;
+ use SDL::Event;
+ use SDL::Events;
+ use SDL::Mixer::Music;
+ use SDL::Mixer::Samples;
+ use SDL::Mixer::Channels;
+
+
+ my $app = SDLx::App->new(
+ init => SDL_INIT_AUDIO | SDL_INIT_VIDEO,
+ width => 250,
+ height => 75,
+ title => "Sound Event Demo",
+ eoq => 1
+ );
+
+ # Initialize the Audio
+ unless ( SDL::Mixer::open_audio( 44100, AUDIO_S16SYS, 2, 4096 ) == 0 ) {
+ Carp::croak "Cannot open audio: " . SDL::get_error();
+ }
+
+ my $channel_volume = 100;
+ my $music_volume = 100;
+ my $laser_status = 'none';
+ my $music_status = 'not playing';
+
+ # Load our sound resources
+ my $laser = SDL::Mixer::Samples::load_WAV('data/sample.wav');
+ unless ($laser) {
+ Carp::croak "Cannot load sound: " . SDL::get_error();
+ }
+
+ my $background_music =
+ SDL::Mixer::Music::load_MUS('data/music/01-PC-Speaker-Sorrow.ogg');
+ unless ($background_music) {
+ Carp::croak "Cannot load music: " . SDL::get_error();
+ }
+
+
+ $app->add_show_handler(
+ sub {
+
+ $app->draw_rect([0,0,$app->w,$app->h], 0 );
+
+ $app->draw_gfx_text( [10,10], [255,0,0,255], "Channel Volume : $channel_volume" );
+ $app->draw_gfx_text( [10,25], [255,0,0,255], "Music Volume : $music_volume" );
+ $app->draw_gfx_text( [10,40], [255,0,0,255], "Laser Status : $laser_status" );
+ $app->draw_gfx_text( [10,55], [255,0,0,255], "Music Status : $music_status" );
+
+ $app->update();
+
+ }
+ );
+
+ $app->add_event_handler(
+ sub {
+ my $event = shift;
+
+ if ( $event->type == SDL_KEYDOWN ) {
+ my $keysym = $event->key_sym;
+ my $keyname = SDL::Events::get_key_name($keysym);
+
+ if ( $keyname eq 'space' ) {
+
+ $laser_status = 'PEW!';
+ #fire lasers!
+ SDL::Mixer::Channels::play_channel( -1, $laser, 0 );
+
+ }
+ elsif ( $keyname eq 'up' ) {
+ $channel_volume += 5 unless $channel_volume == 100;
+ }
+ elsif ( $keyname eq 'down' ) {
+ $channel_volume -= 5 unless $channel_volume == 0;
+ }
+ elsif ( $keyname eq 'right' ) {
+ $music_volume += 5 unless $music_volume == 100;
+ }
+ elsif ( $keyname eq 'left' ) {
+ $music_volume -= 5 unless $music_volume == 0;
+ }
+ elsif ( $keyname eq 'return' ) {
+ my $playing = SDL::Mixer::Music::playing_music();
+ my $paused = SDL::Mixer::Music::paused_music();
+
+ if ( $playing == 0 && $paused == 0 ) {
+ SDL::Mixer::Music::play_music( $background_music, 1 );
+ $music_status = 'playing';
+ }
+ elsif ( $playing && !$paused ) {
+ SDL::Mixer::Music::pause_music();
+ $music_status = 'paused'
+ }
+ elsif ( $playing && $paused ) {
+ SDL::Mixer::Music::resume_music();
+ $music_status = 'resumed playing';
+ }
+
+ }
+
+ SDL::Mixer::Channels::volume( -1, $channel_volume );
+ SDL::Mixer::Music::volume_music($music_volume);
+
+ }
+
+ }
+
+ );
+
+ $app->run();
+
+ SDL::Mixer::Music::halt_music();
+ SDL::Mixer::close_audio;
+
+=end programlisting
+
=head1 Mixer Effects
Making a dynamic spectrograph.

0 comments on commit 1c38b70

Please sign in to comment.