Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Compile: cc -o musicplayer sdl2-musicplayer.c -lSDL2 -lSDL2_mixer -lSDL2_ttf
- #include <stdio.h>
- #include <dirent.h> // for opendir(), readdir(), closedir(), struct dirent
- #include <libgen.h> // for basename()
- #include <sys/stat.h> // for stat() and S_ISDIR() macro
- #include <limits.h> // for PATH_MAX
- #ifndef PATH_MAX
- #define PATH_MAX 4096
- #endif
- #include <SDL2/SDL.h>
- #include <SDL2/SDL_ttf.h>
- #include <SDL2/SDL_image.h>
- #include <SDL2/SDL_mixer.h>
- #define TRUE 1
- #define FALSE 0
- SDL_Window *pWindow;
- SDL_Renderer *pRenderer;
- SDL_Event event;
- int playerIsRunning;
- static int playMusic(const char *file);
- static int init(const char *title, int xpos, int ypos, int height, int width, int flags);
- static void render(const char *text);
- static void close();
- static SDL_Texture *loadText(const char *text);
- static SDL_Texture *loadImage(const char *imgPath);
- int main(int argc, char **argv) {
- int path_exists(const char*);
- int path_is_directory(const char*);
- if ( init ("Hello SDL Player",
- SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
- 640, 480,
- SDL_WINDOW_SHOWN | SDL_WINDOW_BORDERLESS ) == FALSE )
- return EXIT_FAILURE;
- for ( int i = 1 ; i < argc && playerIsRunning ; i++ ) {
- const char *target_path = argv[i];
- // --- 1. Check if path exists ---
- if ( !path_exists(target_path) ) {
- fprintf(stderr, "SDL Player Error: %s not found.\n", target_path);
- continue;
- }
- // --- 2. Check if the path is a directory ---
- // --- If not, it is probably an audio file. Play it. ---
- if ( !path_is_directory(target_path) ) {
- playMusic(target_path);
- continue;
- }
- // --- 3. The path is a directory. Iterate through it. ---
- DIR *p_dir_stream; // Pointer to a directory stream
- struct dirent *p_dir_entry; // Pointer to a directory entry structure
- p_dir_stream = opendir(target_path);
- if ( p_dir_stream == NULL ) {
- fprintf(stderr, "opendir Error: %s not opened\n", target_path);
- perror(NULL);
- continue;
- }
- // readdir() reads the next entry in the directory stream
- // It returns NULL when there are no more entries or an error occurs.
- while ((p_dir_entry = readdir(p_dir_stream)) != NULL && playerIsRunning ) {
- // In POSIX systems, directories always contain "." (current directory)
- // and ".." (parent directory). We usually skip these.
- if ( strcmp(p_dir_entry->d_name, ".") == 0 || strcmp(p_dir_entry->d_name, "..") == 0 ) {
- continue;
- }
- char full_entry_path[PATH_MAX];
- snprintf(full_entry_path, sizeof(full_entry_path),
- "%s/%s", target_path, p_dir_entry->d_name);
- printf("%s\n", full_entry_path);
- playMusic(full_entry_path);
- }
- closedir(p_dir_stream);
- }
- close();
- return EXIT_SUCCESS;
- }
- static int init(const char *title, int xpos, int ypos, int height, int width, int flags) {
- if ( SDL_Init(SDL_INIT_EVERYTHING) < 0 ) {
- fprintf(stderr, "SDL_Init error: %s\n", SDL_GetError());
- return FALSE;
- }
- pWindow = SDL_CreateWindow(title, xpos, ypos, height, width, flags);
- if ( pWindow == NULL ) {
- fprintf(stderr, "SDL_CreateWindow error: %s\n", SDL_GetError());
- SDL_Quit();
- return FALSE;
- }
- pRenderer = SDL_CreateRenderer(pWindow, -1, 0);
- if ( pRenderer == NULL ) {
- fprintf(stderr, "SDL_CreateRenderer error: %s\n", SDL_GetError());
- SDL_DestroyWindow(pWindow);
- SDL_Quit();
- return FALSE;
- }
- SDL_SetRenderDrawColor(pRenderer, 255, 0, 0, 255);
- SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "2");
- if ( Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 4096) < 0 ) {
- fprintf(stderr, "Mix_OpenAudio error: %s\n", SDL_GetError());
- SDL_DestroyRenderer(pRenderer);
- SDL_DestroyWindow(pWindow);
- SDL_Quit();
- return FALSE;
- }
- playerIsRunning = TRUE;
- return TRUE;
- }
- static void close() {
- Mix_CloseAudio();
- SDL_DestroyRenderer(pRenderer);
- SDL_DestroyWindow(pWindow);
- SDL_Quit();
- }
- static int playMusic(const char *file) {
- Mix_Music *pMusic;
- fprintf(stdout, "Playing music: %s\n", file);
- render(basename(file));
- pMusic = Mix_LoadMUS(file);
- if ( pMusic == NULL ) {
- fprintf(stderr, "Mix_LoadMUS error: %s\n", Mix_GetError());
- return FALSE;
- }
- if ( Mix_PlayMusic(pMusic, 1) < 0 ) {
- fprintf(stderr, "Mix_PlayMusic error: %s\n", Mix_GetError());
- Mix_FreeMusic(pMusic);
- return FALSE;
- }
- while ( Mix_PlayingMusic() ) {
- while ( SDL_PollEvent(&event) ) {
- switch (event.type) {
- case SDL_QUIT:
- playerIsRunning = FALSE;
- Mix_FadeOutMusic(1000);
- break;
- }
- }
- }
- Mix_FreeMusic(pMusic);
- return TRUE;
- }
- static SDL_Texture* loadText(const char *text) {
- if ( TTF_Init() < 0 ) {
- fprintf(stderr, "TTF_Init error: %s\n", TTF_GetError());
- return NULL;
- }
- TTF_Font *pFont = TTF_OpenFont("/usr/share/fonts/truetype/msttcorefonts/Courier_New_Bold.ttf", 256);
- if ( pFont == NULL ) {
- fprintf(stderr, "TTF_OpenFont error: %s\n", TTF_GetError());
- return NULL;
- }
- SDL_Color color = {000, 255, 255};
- SDL_Surface *pSurface = TTF_RenderText_Solid(pFont, text, color);
- SDL_Texture *pTexture = SDL_CreateTextureFromSurface(pRenderer, pSurface);
- SDL_FreeSurface(pSurface);
- if ( pTexture == NULL ) {
- fprintf(stderr, "SDL_CreateTextureFromSurface error: %s\n", SDL_GetError());
- return NULL;
- }
- return pTexture;
- }
- static SDL_Texture *loadImage(const char *imgPath) {
- SDL_Surface *pImage = IMG_Load(imgPath);
- if ( pImage == NULL ) {
- fprintf(stderr, "IMG_Load error: %s\n", IMG_GetError());
- return NULL;
- }
- SDL_Texture *pTexture = SDL_CreateTextureFromSurface(pRenderer, pImage);
- SDL_FreeSurface(pImage);
- if ( pTexture == NULL ) {
- fprintf(stderr, "SDL_CreateTextureFromSurface error: %s\n", SDL_GetError());
- return NULL;
- }
- return pTexture;
- }
- static void render(const char *text) {
- int tw, th;
- int w, h;
- SDL_Rect dest;
- SDL_RenderClear(pRenderer);
- SDL_GetRendererOutputSize(pRenderer, &w, &h);
- /*
- // Image rendering
- SDL_Texture *pImageTexture = loadImage("/home/zuko/Pictures/life-universe-physics-martin-gardner.png");
- SDL_QueryTexture(pImageTexture, NULL, NULL, &tw, &th);
- dest.x = 0;
- dest.w = w;
- dest.h = th * w / tw;
- dest.y = (h - dest.h) / 2;
- SDL_RenderCopy(pRenderer, pImageTexture, NULL, &dest);
- */
- // Text rendering
- SDL_Texture *pTextTexture = loadText(text);
- SDL_QueryTexture(pTextTexture, NULL, NULL, &tw, &th);
- // Texts always have width much bigger than height
- dest.x = 0;
- dest.w = w;
- dest.h = th * w / tw;
- dest.y = (h - dest.h) / 2;
- SDL_RenderCopy(pRenderer, pTextTexture, NULL, &dest);
- SDL_RenderPresent(pRenderer);
- SDL_DestroyTexture(pTextTexture);
- /*SDL_DestroyTexture(pImageTexture);*/
- }
- int path_exists(const char *path) {
- struct stat st;
- // stat() attempts to get file status. Returns 0 on success, -1 on failure.
- return stat(path, &st) == 0;
- }
- int path_is_directory(const char *path) {
- struct stat st;
- if ( stat(path, &st) != 0 ) return FALSE;
- // S_ISDIR() is a POSIX macro to check if st_mode indicates a directory.
- return S_ISDIR(st.st_mode);
- }
Advertisement
Add Comment
Please, Sign In to add comment