music_timidity.c
author Sam Lantinga <slouken@libsdl.org>
Fri, 20 Oct 2017 23:39:04 -0700
changeset 797 b4b6adff699a
parent 782 e7d3a8f73e88
child 812 d7396e517018
permissions -rw-r--r--
Switched to using SDL_AudioStream in SDL 2.0.7 for better streaming resampling support
Also made the following changes:
* Moved looping support into the music interfaces for better seamless looping when resampling
* Music interfaces always start play from the beginning of the song
* Implemented 24-bit and surround sound support for FLAC audio files
* Implemented sample dithering in MAD music interface using GPL code
* Improved error checking in music interfaces
slouken@777
     1
/*
slouken@777
     2
  SDL_mixer:  An audio mixer library based on the SDL library
slouken@777
     3
  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
slouken@777
     4
slouken@777
     5
  This software is provided 'as-is', without any express or implied
slouken@777
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@777
     7
  arising from the use of this software.
slouken@777
     8
slouken@777
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@777
    10
  including commercial applications, and to alter it and redistribute it
slouken@777
    11
  freely, subject to the following restrictions:
slouken@777
    12
slouken@777
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@777
    14
     claim that you wrote the original software. If you use this software
slouken@777
    15
     in a product, an acknowledgment in the product documentation would be
slouken@777
    16
     appreciated but is not required.
slouken@777
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@777
    18
     misrepresented as being the original software.
slouken@777
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@777
    20
*/
slouken@777
    21
slouken@777
    22
/* This file supports playing MIDI files with timidity */
slouken@777
    23
slouken@777
    24
#ifdef MUSIC_MID_TIMIDITY
slouken@777
    25
slouken@777
    26
#include "music_timidity.h"
slouken@777
    27
slouken@777
    28
#include "timidity/timidity.h"
slouken@777
    29
slouken@777
    30
slouken@797
    31
typedef struct
slouken@797
    32
{
slouken@797
    33
    int play_count;
slouken@797
    34
    MidiSong *song;
slouken@797
    35
} TIMIDITY_Music;
slouken@797
    36
slouken@797
    37
slouken@797
    38
static int TIMIDITY_Seek(void *context, double position);
slouken@797
    39
slouken@777
    40
static int TIMIDITY_Open(const SDL_AudioSpec *spec)
slouken@777
    41
{
slouken@782
    42
    return Timidity_Init();
slouken@777
    43
}
slouken@777
    44
slouken@777
    45
static void TIMIDITY_Close(void)
slouken@777
    46
{
slouken@782
    47
    Timidity_Exit();
slouken@777
    48
}
slouken@777
    49
slouken@777
    50
void *TIMIDITY_CreateFromRW(SDL_RWops *src, int freesrc)
slouken@777
    51
{
slouken@797
    52
    TIMIDITY_Music *music;
slouken@797
    53
slouken@797
    54
    music = (TIMIDITY_Music *)SDL_calloc(1, sizeof(*music));
slouken@797
    55
    if (!music) {
slouken@797
    56
        SDL_OutOfMemory();
slouken@797
    57
        return NULL;
slouken@797
    58
    }
slouken@797
    59
slouken@797
    60
    music->song = Timidity_LoadSong(src, &music_spec);
slouken@797
    61
    if (!music->song) {
slouken@797
    62
        SDL_free(music);
slouken@797
    63
        return NULL;
slouken@797
    64
    }
slouken@797
    65
slouken@797
    66
    if (freesrc) {
slouken@782
    67
        SDL_RWclose(src);
slouken@777
    68
    }
slouken@777
    69
    return music;
slouken@777
    70
}
slouken@777
    71
slouken@777
    72
static void TIMIDITY_SetVolume(void *context, int volume)
slouken@777
    73
{
slouken@797
    74
    TIMIDITY_Music *music = (TIMIDITY_Music *)context;
slouken@797
    75
    Timidity_SetVolume(music->song, volume);
slouken@777
    76
}
slouken@777
    77
slouken@797
    78
static int TIMIDITY_Play(void *context, int play_count)
slouken@777
    79
{
slouken@797
    80
    TIMIDITY_Music *music = (TIMIDITY_Music *)context;
slouken@797
    81
    music->play_count = play_count;
slouken@797
    82
    Timidity_Start(music->song);
slouken@797
    83
    return TIMIDITY_Seek(music, 0.0);
slouken@777
    84
}
slouken@777
    85
slouken@777
    86
static int TIMIDITY_GetAudio(void *context, void *data, int bytes)
slouken@777
    87
{
slouken@797
    88
    TIMIDITY_Music *music = (TIMIDITY_Music *)context;
slouken@797
    89
    if (!Timidity_PlaySome(music->song, data, bytes)) {
slouken@797
    90
        if (music->play_count == 1) {
slouken@797
    91
            /* We didn't consume anything and we're done */
slouken@797
    92
            music->play_count = 0;
slouken@797
    93
            return bytes;
slouken@797
    94
        } else {
slouken@797
    95
            int play_count = -1;
slouken@797
    96
            if (music->play_count > 0) {
slouken@797
    97
                play_count = (music->play_count - 1);
slouken@797
    98
            }
slouken@797
    99
            if (TIMIDITY_Play(music, play_count) < 0) {
slouken@797
   100
                return -1;
slouken@797
   101
            }
slouken@797
   102
        }
slouken@782
   103
    }
slouken@777
   104
    return 0;
slouken@777
   105
}
slouken@777
   106
slouken@782
   107
static int TIMIDITY_Seek(void *context, double position)
slouken@777
   108
{
slouken@797
   109
    TIMIDITY_Music *music = (TIMIDITY_Music *)context;
slouken@797
   110
    Timidity_Seek(music->song, (Uint32)(position * 1000));
slouken@782
   111
    return 0;
slouken@777
   112
}
slouken@777
   113
slouken@777
   114
static void TIMIDITY_Delete(void *context)
slouken@777
   115
{
slouken@797
   116
    TIMIDITY_Music *music = (TIMIDITY_Music *)context;
slouken@797
   117
    Timidity_FreeSong(music->song);
slouken@797
   118
    SDL_free(music);
slouken@777
   119
}
slouken@777
   120
slouken@777
   121
Mix_MusicInterface Mix_MusicInterface_TIMIDITY =
slouken@777
   122
{
slouken@777
   123
    "TIMIDITY",
slouken@777
   124
    MIX_MUSIC_TIMIDITY,
slouken@777
   125
    MUS_MID,
slouken@777
   126
    SDL_FALSE,
slouken@777
   127
    SDL_FALSE,
slouken@777
   128
slouken@777
   129
    NULL,   /* Load */
slouken@777
   130
    TIMIDITY_Open,
slouken@777
   131
    TIMIDITY_CreateFromRW,
slouken@777
   132
    NULL,   /* CreateFromFile */
slouken@777
   133
    TIMIDITY_SetVolume,
slouken@777
   134
    TIMIDITY_Play,
slouken@782
   135
    NULL,   /* IsPlaying */
slouken@777
   136
    TIMIDITY_GetAudio,
slouken@782
   137
    TIMIDITY_Seek,
slouken@777
   138
    NULL,   /* Pause */
slouken@777
   139
    NULL,   /* Resume */
slouken@777
   140
    NULL,   /* Stop */
slouken@777
   141
    TIMIDITY_Delete,
slouken@777
   142
    TIMIDITY_Close,
slouken@777
   143
    NULL,   /* Unload */
slouken@777
   144
};
slouken@777
   145
slouken@777
   146
#endif /* MUSIC_MID_TIMIDITY */
slouken@777
   147
slouken@777
   148
/* vi: set ts=4 sw=4 expandtab: */