AW: How to play an mp3 file from a database
Dear all! It took me quite some time, but I'm moving forward. Here are some screens from my vocabulary trainer: https://picasaweb.google.com/104129024313554475104/Vokabeltrainer?authuser=0 authkey=Gv1sRgCKLyn6SSwIvCgwEfeat=directlink Now I want to play a vocable audio file (that is of course, stored in a database :)). I can't use SDL::Mixer::Music for that, because there is already some background music playing. AFAIK I need to use SDL::Mixer::Samples. I tried it, but there occurred an error when using mp3 files: Cannot load music file [music/terminal.mp3]: Unrecognized sound file type at play_effect.pl line 34 Here is the script: [code] #!perl use strict; use warnings; use utf8; use SDL; use SDL::Event; use SDL::Events; use SDLx::App; use SDLx::Controller; use SDL::Mixer; use SDL::Mixer::Music; use SDL::RWOps; use SDL::Mixer::Samples; use SDL::Mixer::Channels; SDL::init(SDL_INIT_AUDIO); SDL::Mixer::init( MIX_INIT_MP3 | MUS_MP3 ); my $app = SDLx::App-new( title = 'play mp3 effect', exit_on_quit = 1, ); unless( SDL::Mixer::open_audio( 44100, AUDIO_S16SYS, 2, 4096 ) == 0 ) { Carp::croak Cannot open audio: .SDL::get_error(); } my $file = 'music/terminal.mp3'; #my $file = 'music/br_crossing_bell_dop.r.wav'; #my $file = 'music/Windows Logon Sound.wav'; my $sample = SDL::Mixer::Samples::load_WAV( $file ); unless( $sample ) { Carp::croak Cannot load music file [$file]: . SDL::get_error(); } my $playing_channel = SDL::Mixer::Channels::play_channel( -1, $sample, 0 ); $app-run(); SDL::Mixer::Music::halt_music(); SDL::Mixer::close_audio; exit(0); [/code] There also occurred some other errors using .wav files: - Cannot load music file [music/br_crossing_bell_dop.r.wav]: Complex WAVE files not supported at play_effect.pl line 34 - Cannot load music file [music/Windows Logon Sound.wav]: MPEG Layer 3 data not supported play_effect.pl line 34 But, I only want to play mp3 files. Maybe you can hint me at the solution for this problem? How can I play an mp3 file once, e.g. on a button click event? Best regards, Alex -Ursprüngliche Nachricht- Von: breno [mailto:oainikus...@gmail.com] Gesendet: Dienstag, 29. November 2011 06:34 An: Alexander Becker Cc: sdl-devel@perl.org Betreff: Re: How to play an mp3 file from a database On Mon, Nov 28, 2011 at 8:13 PM, Alexander Becker alexanderbec...@gmx.net wrote: Dear all! Hi there! I just tried the example code of the SDL Manual where you play some music. By the SDL manual, I refer to the one that is hidden at the bottom of the sdl.perl.org page, so that you really have to search for it in order to find it - and even then you have to get along with an ugly github interface. There's a new project website under way, but we're missing people to work in it. Please join #sdl in irc.perl.org if you want to help us get it right :) So, in general: Is there a way to play mp3 files? Yup. If your libsdl was compiled with mp3 support, all you have to do (iirc) is set the MIX_INIT_MP3 (for effects) and MUS_MP3 (for audio) flags when you call SDL::Mixer::init(): SDL::Mixer::init( MIX_INIT_MP3 | MUS_MP3 ); then use load_MUS() and play_music() from SDL::Mixer::Music to play mp3 files as background music, or load_WAV() from SDL::Mixer::Samples to play mp3 effects (yes, the function is named load_WAV() but plays different formats too if they're available). The documentation in SDL::Mixer, SDL::Mixer::Music and SDL::Mixer::Samples should be helpful, as some of the test files (t/mixer_music.t comes to mind). And in particular: is there a way to play mp3 files that are in a variable? Or do I have to work with temporary files? Not sure. I *think* SDL::Mixer::quick_load_WAV( $buffer ) might do the right thing. You'll have to test it though. Cheers, breno
AW: How to play an mp3 file from a database
Hi! Ok, now I don't get any error when playing mp3 files from the database, but I don't get any sound either. I updated Alien::SDL to the latest version, that worked. However, SDL itself didn't pass the tests, it's the channels test that fails. So I installed with force, but no change. Is there anything in particular I could do to provide information about the error that occurs with the cannels test? Any information you need to fix this issue (in case it is one)? Best regards, Alex [snip] Test Summary Report --- t\core.t (Wstat: 0 Tests: 28 Failed: 0) TODO passed: 21-22 t\core_video.t(Wstat: 0 Tests: 110 Failed: 0) TODO passed: 57, 59 t\mixer_channels.t(Wstat: 65280 Tests: 35 Failed: 0) Non-zero exit status: 255 Parse errors: No plan found in TAP output Files=59, Tests=3942, 233 wallclock secs ( 0.94 usr + 0.23 sys = 1.17 CPU) Result: FAIL Failed 1/59 test programs. 0/3942 subtests failed. (C:\strawberry\perl\bin\perl.exe ./Build test exited with 65280) CPAN::Reporter: Test result is 'fail', One or more tests failed. CPAN::Reporter: preparing a CPAN Testers report for SDL-2.536 CPAN::Reporter: this appears to be a duplicate report for the test phase: FAIL SDL-2.536 MSWin32-x64-multi-thread 6.1 Test report will not be sent. FROGGS/SDL-2.536.tar.gz C:\strawberry\perl\bin\perl.exe ./Build test -- NOT OK //hint// to see the cpan-testers results for installing this module, try: reports FROGGS/SDL-2.536.tar.gz Running Build install make test had returned bad status, won't install without force Failed during this command: FROGGS/SDL-2.536.tar.gz : make_test NO [/snip] -Ursprüngliche Nachricht- Von: Tobias Leich [mailto:em...@froggs.de] Gesendet: Sonntag, 22. April 2012 19:31 An: Alex Betreff: Re: How to play an mp3 file from a database Hi Alex, At first, you are on windows and used the prebuklt libSDL binaries shipped with Alien::SDL? If yes, mp3 should be supported, but only files without VBR. So please try a few mp3 files and maybe check how it is encoded. Then, to play an mp3 file from a database, do somethind like: use DBI; use SDL; use SDL::Mixer; use SDL::Mixer::Channels; use SDL::Mixer::Samples; use SDL::RWOps; $dbh-prepare(SELECT music FROM ...); $sth = $dbh-execute(); if( $row = $sth-fetchrow_hashref ) { $rwops = SDL::RWOps-new_const_mem( $row-{music} ); $chunk = SDL::Mixer::Samples::load_WAV_RW( $rwops, 0 ); SDL::Mixer::Channels::play_channel( -1, $chunk, 1 ); } Cheers, FROGGS Am 22.04.2012 18:35, schrieb Alex: Dear all! It took me quite some time, but I'm moving forward. Here are some screens from my vocabulary trainer: https://picasaweb.google.com/104129024313554475104/Vokabeltrainer?auth user=0 authkey=Gv1sRgCKLyn6SSwIvCgwEfeat=directlink Now I want to play a vocable audio file (that is of course, stored in a database :)). I can't use SDL::Mixer::Music for that, because there is already some background music playing. AFAIK I need to use SDL::Mixer::Samples. I tried it, but there occurred an error when using mp3 files: Cannot load music file [music/terminal.mp3]: Unrecognized sound file type at play_effect.pl line 34 Here is the script: [code] #!perl use strict; use warnings; use utf8; use SDL; use SDL::Event; use SDL::Events; use SDLx::App; use SDLx::Controller; use SDL::Mixer; use SDL::Mixer::Music; use SDL::RWOps; use SDL::Mixer::Samples; use SDL::Mixer::Channels; SDL::init(SDL_INIT_AUDIO); SDL::Mixer::init( MIX_INIT_MP3 | MUS_MP3 ); my $app = SDLx::App-new( title = 'play mp3 effect', exit_on_quit = 1, ); unless( SDL::Mixer::open_audio( 44100, AUDIO_S16SYS, 2, 4096 ) == 0 ) { Carp::croak Cannot open audio: .SDL::get_error(); } my $file = 'music/terminal.mp3'; #my $file = 'music/br_crossing_bell_dop.r.wav'; #my $file = 'music/Windows Logon Sound.wav'; my $sample = SDL::Mixer::Samples::load_WAV( $file ); unless( $sample ) { Carp::croak Cannot load music file [$file]: . SDL::get_error(); } my $playing_channel = SDL::Mixer::Channels::play_channel( -1, $sample, 0 ); $app-run(); SDL::Mixer::Music::halt_music(); SDL::Mixer::close_audio; exit(0); [/code] There also occurred some other errors using .wav files: - Cannot load music file [music/br_crossing_bell_dop.r.wav]: Complex WAVE files not supported at play_effect.pl line 34 - Cannot load music file [music/Windows Logon Sound.wav]: MPEG Layer 3 data not supported play_effect.pl line 34 But, I only want to play mp3 files. Maybe you can hint me at the solution for this problem? How can I play an mp3 file once, e.g. on a button click event? Best regards, Alex -Ursprüngliche Nachricht- Von: breno [mailto:oainikus...@gmail.com] Gesendet: Dienstag, 29. November 2011 06:34 An: Alexander Becker Cc: sdl-devel@perl.org Betreff: Re: How to play an mp3 file from a database On Mon, Nov 28, 2011
AW: How to play an mp3 file from a database
Wohoo! Thats really great! Here is my current (OMG: its SDL + Tk) proof-of-concept-script. It plays a file via start and stop buttons. In case anyone has suggestions, please dont hesitate to drop me an email. [code] #!perl use strict; use warnings; use utf8; use Tk; use DBI; use SQL::Abstract::Limit; use SDL; use SDL::Audio; use SDL::Mixer; use SDL::Mixer::Samples; use SDL::Mixer::Channels; use SDL::Mixer::Music; use SDL::RWOps; SDL::init(SDL_INIT_AUDIO); SDL::Mixer::init( MIX_INIT_MP3 | MUS_MP3 ); my $mw = tkinit(); unless( SDL::Mixer::open_audio( 44100, AUDIO_S16SYS, 2, 4096 ) == 0 ) { Carp::croak Cannot open audio: .SDL::get_error(); } $mw-Button( -text = 'play', -command = sub{ my $buffer = get_audio_buffer(); my $rwops = SDL::RWOps-new_const_mem( $buffer ); my $background_music = SDL::Mixer::Music::load_MUS_RW( $rwops ); unless( $background_music ) { Carp::croak Cannot load music file [buffer from DB]: . SDL::get_error(); } SDL::Mixer::Music::play_music( $background_music, 20 ); }, )-pack(); $mw-Button( -text = 'stop', -command = sub{ SDL::Mixer::Music::halt_music(); }, )-pack(); $mw-MainLoop(); sub get_audio_buffer { my $sql = SQL::Abstract::Limit-new( limit_dialect = 'LimitXY' );; my $table = 'words'; my @fields = (qw/audio/); my %where = ( id = 2, ); my @order = (); my $limit = 1; my $offset = 0; my ( $stmt, @bind ) = $sql-select( $table, \@fields, \%where, \@order, $limit, $offset ); my $database = 'test'; my $db_host = '127.0.0.1'; my $db_port = '3306'; my $dsn = DBI:mysql:database=$database;host=$db_host;port=$db_port; my $username = 'test'; my $password = 'test'; my $dbh = DBI-connect($dsn, $username, $password) or die('Cannot connect to DB: ' . DBI-errstr()); my $sth = $dbh-prepare( $stmt ); $sth-execute( @bind ); my ($buffer) = $sth-fetchrow_array(); return $buffer; } # /get_audio_buffer [/code] Here is the output of perl Build.PL. There is an error for : execinfo.h, however, build, build test and build install runs fine. [snip] C:\zwischen\cpan\PerlGameDev-SDL-44c341fperl Build.PL *** !!!WARNING!!! This Release breaks back compatibility support with versions 2.4x and below ** Using 'My::Builder::Windows' class ... Detecting available libraries ... [Alien::SDL] Testing header(s): SDL.h [Alien::SDL] Testing header(s): SDL_mixer.h [Alien::SDL] Testing header(s): SDL_imageFilter.h [Alien::SDL] Testing header(s): SDL_image.h [Alien::SDL] Testing header(s): SDL_ttf.h [Alien::SDL] Testing header(s): SDL_framerate.h [Alien::SDL] Testing header(s): SDL_gfxBlitFunc.h [Alien::SDL] Testing header(s): SDL_gfxPrimitives.h [Alien::SDL] Testing header(s): SDL_rotozoom.h [Alien::SDL] Testing header(s): SDL_Pango.h Writing config_data ... Saving some info to 'notes' ... [Alien::SDL] Testing header(s): execinfo.h, signal.h NOK: (error: execinfo.h: No such file or directory) Can't find dist packages without a MANIFEST file Run 'Build manifest' to generate one WARNING: Possible missing or corrupt 'MANIFEST' file. Nothing to enter for 'provides' field in metafile. Created MYMETA.yml and MYMETA.json Creating new 'Build' script for 'SDL' version '2.535_01' C:\zwischen\cpan\PerlGameDev-SDL-44c341f [/snip] Will this be in an official release of SDL? Because this would be a really nice feature, that could be advertised, e.g. via blogs entries etc.. I could write a german one. Best regards thanks a lot, Alex Von: Tobias Leich [mailto:em...@froggs.de] Gesendet: Donnerstag, 1. Dezember 2011 18:37 An: Alexander Becker Betreff: Re: How to play an mp3 file from a database Hi Alex, You can checkout the c-sdl-rwops branch at github or download the zipfile if you are not experienced with git by using this link: https://github.com/PerlGameDev/SDL/zipball/c-sdl-rwops Usage: my $music = SDL::Mixer::Music::load_MUS_RW( $rwops ); load_MUS_RW does the same like load_MUS except that it accepts an SDL::RWOps http://search.cpan.org/perldoc?SDL%3A%3ARWOps -object rather than a filename. Example for loading music from a variable: use SDL; use SDL::Mixer; use SDL::Mixer::Music; use SDL::RWOps; [...] my $rwops = SDL::RWOps-new_const_mem( $scalar_holding_music ); my $music = SDL::Mixer::Music::load_MUS( $rwops
AW: How to play an mp3 file from a database
Hi breno, thank you for the quick response. It helped. I had a look into mixer_samples.t and line 106 states, that quick_load_WAV is not (yet? Who do I have to bribe with what to get it?) implemented. Here is a working piece of code using temporary files. Of course, you need a database containing audio files. Best regards, Alex [code] #!perl use strict; use warnings; use utf8; use DBI; use SQL::Abstract::Limit; use File::Temp; use SDL; use SDL::Audio; use SDL::Mixer; use SDL::Mixer::Samples; use SDL::Mixer::Channels; use SDL::Mixer::Music; SDL::init(SDL_INIT_AUDIO); SDL::Mixer::init( MIX_INIT_MP3 | MUS_MP3 ); unless( SDL::Mixer::open_audio( 44100, AUDIO_S16SYS, 2, 4096 ) == 0 ) { Carp::croak Cannot open audio: .SDL::get_error(); } my $buffer = get_audio_buffer(); # -- write audio buffer to temp file my $fh = File::Temp-new( UNLINK = 1, SUFFIX = '.mp3' ); $fh-unlink_on_destroy( 1 ); print $fh $buffer; my $fname = $fh-filename; # close the handle or the temfile will have some sort of lock on it and cannot be read $fh-close(); my $background_music = SDL::Mixer::Music::load_MUS( $fname ); unless( $background_music ) { Carp::croak Cannot load music file [buffer from DB]: . SDL::get_error(); } SDL::Mixer::Music::play_music( $background_music,0 ); sleep(6); SDL::Mixer::Music::halt_music(); SDL::Mixer::close_audio; exit(0); sub get_audio_buffer { my $sql = SQL::Abstract::Limit-new( limit_dialect = 'LimitXY' );; my $table = 'audio_files'; my @fields = (qw/audio/); my %where = ( id = 2, ); my @order = (); my $limit = 1; my $offset = 0; my ( $stmt, @bind ) = $sql-select( $table, \@fields, \%where, \@order, $limit, $offset ); my $database = 'database_name'; my $db_host = 'your_host'; my $db_port = '3306'; my $dsn = DBI:mysql:database=$database;host=$db_host;port=$db_port; my $username = 'username'; my $password = 'password'; my $dbh = DBI-connect($dsn, $username, $password) or die('Cannot connect to DB: ' . DBI-errstr()); my $sth = $dbh-prepare( $stmt ); $sth-execute( @bind ); my ($buffer) = $sth-fetchrow_array(); return $buffer; } # /get_audio_buffer [/code] -Ursprüngliche Nachricht- Von: breno [mailto:oainikus...@gmail.com] Gesendet: Dienstag, 29. November 2011 06:34 An: Alexander Becker Cc: sdl-devel@perl.org Betreff: Re: How to play an mp3 file from a database On Mon, Nov 28, 2011 at 8:13 PM, Alexander Becker wrote: Dear all! Hi there! I just tried the example code of the SDL Manual where you play some music. By the SDL manual, I refer to the one that is hidden at the bottom of the sdl.perl.org page, so that you really have to search for it in order to find it - and even then you have to get along with an ugly github interface. There's a new project website under way, but we're missing people to work in it. Please join #sdl in irc.perl.org if you want to help us get it right :) So, in general: Is there a way to play mp3 files? Yup. If your libsdl was compiled with mp3 support, all you have to do (iirc) is set the MIX_INIT_MP3 (for effects) and MUS_MP3 (for audio) flags when you call SDL::Mixer::init(): SDL::Mixer::init( MIX_INIT_MP3 | MUS_MP3 ); then use load_MUS() and play_music() from SDL::Mixer::Music to play mp3 files as background music, or load_WAV() from SDL::Mixer::Samples to play mp3 effects (yes, the function is named load_WAV() but plays different formats too if they're available). The documentation in SDL::Mixer, SDL::Mixer::Music and SDL::Mixer::Samples should be helpful, as some of the test files (t/mixer_music.t comes to mind). And in particular: is there a way to play mp3 files that are in a variable? Or do I have to work with temporary files? Not sure. I *think* SDL::Mixer::quick_load_WAV( $buffer ) might do the right thing. You'll have to test it though. Cheers, breno - eMail ist virenfrei. Von AVG überprüft - www.avg.de Version: 10.0.1411 / Virendatenbank: 2092/4046 - Ausgabedatum: 29.11.2011