playmus.c
author Vitaly Novichkov
Mon, 23 Dec 2019 14:01:02 +0300
changeset 1119 24ca9a03d51c
parent 1090 543b77a3c0eb
child 1121 71510d620652
permissions -rw-r--r--
introduce MetaTags api

In some games or players it would be possible to print a title and
some minor tags about playing music.

There are 5 added functions which can give meta-tags from music if
they are available or supported by a codec:
- Mix_GetMusicTitle() gives song title.
Unlike Mix_GetMusicTitleTag, returns filename if tag is blank.
- Mix_GetMusicTitleTag() gives song title
- Mix_GetMusicArtistTag() gives artist name
- Mix_GetMusicAlbumTag() gives album name
- Mix_GetMusicCopyrightTag() gives copyright tag
     1 /*
     2   PLAYMUS:  A test application for the SDL mixer library.
     3   Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
     4 
     5   This software is provided 'as-is', without any express or implied
     6   warranty.  In no event will the authors be held liable for any damages
     7   arising from the use of this software.
     8 
     9   Permission is granted to anyone to use this software for any purpose,
    10   including commercial applications, and to alter it and redistribute it
    11   freely, subject to the following restrictions:
    12 
    13   1. The origin of this software must not be misrepresented; you must not
    14      claim that you wrote the original software. If you use this software
    15      in a product, an acknowledgment in the product documentation would be
    16      appreciated but is not required.
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    21 
    22 /* Quiet windows compiler warnings */
    23 #define _CRT_SECURE_NO_WARNINGS
    24 
    25 /* $Id$ */
    26 
    27 #include <stdlib.h>
    28 #include <stdio.h>
    29 #include <string.h>
    30 
    31 #ifdef unix
    32 #include <unistd.h>
    33 #endif
    34 
    35 #include "SDL.h"
    36 #include "SDL_mixer.h"
    37 
    38 #ifdef HAVE_SIGNAL_H
    39 #include <signal.h>
    40 #endif
    41 
    42 
    43 static int audio_open = 0;
    44 static Mix_Music *music = NULL;
    45 static int next_track = 0;
    46 
    47 void CleanUp(int exitcode)
    48 {
    49     if(Mix_PlayingMusic()) {
    50         Mix_FadeOutMusic(1500);
    51         SDL_Delay(1500);
    52     }
    53     if (music) {
    54         Mix_FreeMusic(music);
    55         music = NULL;
    56     }
    57     if (audio_open) {
    58         Mix_CloseAudio();
    59         audio_open = 0;
    60     }
    61     SDL_Quit();
    62     exit(exitcode);
    63 }
    64 
    65 void Usage(char *argv0)
    66 {
    67     SDL_Log("Usage: %s [-i] [-l] [-8] [-f32] [-r rate] [-c channels] [-b buffers] [-v N] [-rwops] <musicfile>\n", argv0);
    68 }
    69 
    70 void Menu(void)
    71 {
    72     char buf[10];
    73 
    74     printf("Available commands: (p)ause (r)esume (h)alt volume(v#) > ");
    75     fflush(stdin);
    76     if (scanf("%s",buf) == 1) {
    77         switch(buf[0]){
    78         case 'p': case 'P':
    79             Mix_PauseMusic();
    80             break;
    81         case 'r': case 'R':
    82             Mix_ResumeMusic();
    83             break;
    84         case 'h': case 'H':
    85             Mix_HaltMusic();
    86             break;
    87         case 'v': case 'V':
    88             Mix_VolumeMusic(atoi(buf+1));
    89             break;
    90         }
    91     }
    92     printf("Music playing: %s Paused: %s\n", Mix_PlayingMusic() ? "yes" : "no",
    93            Mix_PausedMusic() ? "yes" : "no");
    94 }
    95 
    96 #ifdef HAVE_SIGNAL_H
    97 
    98 void IntHandler(int sig)
    99 {
   100     switch (sig) {
   101             case SIGINT:
   102             next_track++;
   103             break;
   104     }
   105 }
   106 
   107 #endif
   108 
   109 int main(int argc, char *argv[])
   110 {
   111     int audio_rate;
   112     Uint16 audio_format;
   113     int audio_channels;
   114     int audio_buffers;
   115     int audio_volume = MIX_MAX_VOLUME;
   116     int looping = 0;
   117     int interactive = 0;
   118     int rwops = 0;
   119     int i;
   120     const char *typ;
   121 
   122     /* Initialize variables */
   123     audio_rate = MIX_DEFAULT_FREQUENCY;
   124     audio_format = MIX_DEFAULT_FORMAT;
   125     audio_channels = MIX_DEFAULT_CHANNELS;
   126     audio_buffers = 4096;
   127 
   128     /* Check command line usage */
   129     for (i=1; argv[i] && (*argv[i] == '-'); ++i) {
   130         if ((strcmp(argv[i], "-r") == 0) && argv[i+1]) {
   131             ++i;
   132             audio_rate = atoi(argv[i]);
   133         } else
   134         if (strcmp(argv[i], "-m") == 0) {
   135             audio_channels = 1;
   136         } else
   137         if ((strcmp(argv[i], "-c") == 0) && argv[i+1]) {
   138             ++i;
   139             audio_channels = atoi(argv[i]);
   140         } else
   141         if ((strcmp(argv[i], "-b") == 0) && argv[i+1]) {
   142             ++i;
   143             audio_buffers = atoi(argv[i]);
   144         } else
   145         if ((strcmp(argv[i], "-v") == 0) && argv[i+1]) {
   146             ++i;
   147             audio_volume = atoi(argv[i]);
   148         } else
   149         if (strcmp(argv[i], "-l") == 0) {
   150             looping = -1;
   151         } else
   152         if (strcmp(argv[i], "-i") == 0) {
   153             interactive = 1;
   154         } else
   155         if (strcmp(argv[i], "-8") == 0) {
   156             audio_format = AUDIO_U8;
   157         } else
   158         if (strcmp(argv[i], "-f32") == 0) {
   159             audio_format = AUDIO_F32;
   160         } else
   161         if (strcmp(argv[i], "-rwops") == 0) {
   162             rwops = 1;
   163         } else {
   164             Usage(argv[0]);
   165             return(1);
   166         }
   167     }
   168     if (! argv[i]) {
   169         Usage(argv[0]);
   170         return(1);
   171     }
   172 
   173     /* Initialize the SDL library */
   174     if (SDL_Init(SDL_INIT_AUDIO) < 0) {
   175         SDL_Log("Couldn't initialize SDL: %s\n",SDL_GetError());
   176         return(255);
   177     }
   178 
   179 #ifdef HAVE_SIGNAL_H
   180     signal(SIGINT, IntHandler);
   181     signal(SIGTERM, CleanUp);
   182 #endif
   183 
   184     /* Open the audio device */
   185     if (Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers) < 0) {
   186         SDL_Log("Couldn't open audio: %s\n", SDL_GetError());
   187         return(2);
   188     } else {
   189         Mix_QuerySpec(&audio_rate, &audio_format, &audio_channels);
   190         SDL_Log("Opened audio at %d Hz %d bit%s %s %d bytes audio buffer\n", audio_rate,
   191             (audio_format&0xFF),
   192             (SDL_AUDIO_ISFLOAT(audio_format) ? " (float)" : ""),
   193             (audio_channels > 2) ? "surround" : (audio_channels > 1) ? "stereo" : "mono",
   194             audio_buffers);
   195     }
   196     audio_open = 1;
   197 
   198     /* Set the music volume */
   199     Mix_VolumeMusic(audio_volume);
   200 
   201     /* Set the external music player, if any */
   202     Mix_SetMusicCMD(SDL_getenv("MUSIC_CMD"));
   203 
   204     while (argv[i]) {
   205         next_track = 0;
   206 
   207         /* Load the requested music file */
   208         if (rwops) {
   209             music = Mix_LoadMUS_RW(SDL_RWFromFile(argv[i], "rb"), SDL_TRUE);
   210         } else {
   211             music = Mix_LoadMUS(argv[i]);
   212         }
   213         if (music == NULL) {
   214             SDL_Log("Couldn't load %s: %s\n",
   215                 argv[i], SDL_GetError());
   216             CleanUp(2);
   217         }
   218 
   219         switch (Mix_GetMusicType(music)) {
   220         case MUS_CMD:
   221             typ = "CMD";
   222             break;
   223         case MUS_WAV:
   224             typ = "WAV";
   225             break;
   226         case MUS_MOD:
   227         case MUS_MODPLUG_UNUSED:
   228             typ = "MOD";
   229             break;
   230         case MUS_FLAC:
   231             typ = "FLAC";
   232             break;
   233         case MUS_MID:
   234             typ = "MIDI";
   235             break;
   236         case MUS_OGG:
   237             typ = "OGG Vorbis";
   238             break;
   239         case MUS_MP3:
   240         case MUS_MP3_MAD_UNUSED:
   241             typ = "MP3";
   242             break;
   243         case MUS_OPUS:
   244             typ = "OPUS";
   245             break;
   246         case MUS_NONE:
   247         default:
   248             typ = "NONE";
   249             break;
   250         }
   251         SDL_Log("Detected music type: %s", typ);
   252 
   253         /* Play and then exit */
   254         SDL_Log("Playing %s, duration %f\n", argv[i], Mix_MusicDuration(music));
   255         Mix_FadeInMusic(music,looping,2000);
   256         while (!next_track && (Mix_PlayingMusic() || Mix_PausedMusic())) {
   257             if(interactive)
   258                 Menu();
   259             else
   260                 SDL_Delay(100);
   261         }
   262         Mix_FreeMusic(music);
   263         music = NULL;
   264 
   265         /* If the user presses Ctrl-C more than once, exit. */
   266         SDL_Delay(500);
   267         if (next_track > 1) break;
   268 
   269         i++;
   270     }
   271     CleanUp(0);
   272 
   273     /* Not reached, but fixes compiler warnings */
   274     return 0;
   275 }
   276 
   277 /* vi: set ts=4 sw=4 expandtab: */