diff options
Diffstat (limited to 'src/audio')
-rw-r--r-- | src/audio/player.c | 88 | ||||
-rw-r--r-- | src/audio/player.h | 18 |
2 files changed, 103 insertions, 3 deletions
diff --git a/src/audio/player.c b/src/audio/player.c index b68d5ba5..aea2a998 100644 --- a/src/audio/player.c +++ b/src/audio/player.c | |||
@@ -25,14 +25,100 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
25 | #include <the_Foundation/thread.h> | 25 | #include <the_Foundation/thread.h> |
26 | #include <SDL_audio.h> | 26 | #include <SDL_audio.h> |
27 | 27 | ||
28 | iDeclareType(Decoder) | ||
29 | |||
30 | enum iDecoderType { | ||
31 | wav_DecoderType, | ||
32 | mpeg_DecoderType, | ||
33 | vorbis_DecoderType, | ||
34 | midi_DecoderType, | ||
35 | }; | ||
36 | |||
37 | struct Impl_Decoder { | ||
38 | enum iDecoderType type; | ||
39 | size_t inPos; | ||
40 | // iBlock samples; | ||
41 | }; | ||
42 | |||
28 | struct Impl_Player { | 43 | struct Impl_Player { |
44 | SDL_AudioSpec spec; | ||
29 | SDL_AudioDeviceID device; | 45 | SDL_AudioDeviceID device; |
46 | iMutex mtx; | ||
47 | iBlock data; | ||
48 | iBool isDataComplete; | ||
30 | }; | 49 | }; |
31 | 50 | ||
32 | void init_Player(iPlayer *d) { | 51 | void init_Player(iPlayer *d) { |
52 | iZap(d->spec); | ||
33 | d->device = 0; | 53 | d->device = 0; |
54 | init_Mutex(&d->mtx); | ||
55 | init_Block(&d->data, 0); | ||
56 | d->isDataComplete = iFalse; | ||
34 | } | 57 | } |
35 | 58 | ||
36 | void deinit_Player(iPlayer *d) { | 59 | void deinit_Player(iPlayer *d) { |
37 | SDL_CloseAudioDevice(d->device); | 60 | stop_Player(d); |
61 | deinit_Block(&d->data); | ||
62 | } | ||
63 | |||
64 | iBool isStarted_Player(const iPlayer *d) { | ||
65 | return d->device != 0; | ||
66 | } | ||
67 | |||
68 | void setFormatHint_Player(iPlayer *d, const char *hint) { | ||
69 | |||
70 | } | ||
71 | |||
72 | void updateSourceData_Player(iPlayer *d, const iBlock *data, enum iPlayerUpdate update) { | ||
73 | lock_Mutex(&d->mtx); | ||
74 | switch (update) { | ||
75 | case replace_PlayerUpdate: | ||
76 | set_Block(&d->data, data); | ||
77 | d->isDataComplete = iFalse; | ||
78 | break; | ||
79 | case append_PlayerUpdate: | ||
80 | append_Block(&d->data, data); | ||
81 | d->isDataComplete = iFalse; | ||
82 | break; | ||
83 | case complete_PlayerUpdate: | ||
84 | d->isDataComplete = iTrue; | ||
85 | break; | ||
86 | } | ||
87 | unlock_Mutex(&d->mtx); | ||
88 | } | ||
89 | |||
90 | static void writeOutputSamples_Player_(void *plr, Uint8 *stream, int len) { | ||
91 | iPlayer *d = plr; | ||
92 | memset(stream, 0, len); | ||
93 | /* TODO: Copy samples from the decoder's ring buffer. */ | ||
94 | } | ||
95 | |||
96 | iBool start_Player(iPlayer *d) { | ||
97 | if (isStarted_Player(d)) { | ||
98 | return iFalse; | ||
99 | } | ||
100 | SDL_AudioSpec conf; | ||
101 | iZap(conf); | ||
102 | conf.freq = 44100; /* TODO: from content */ | ||
103 | conf.format = AUDIO_S16; | ||
104 | conf.channels = 2; /* TODO: from content */ | ||
105 | conf.samples = 2048; | ||
106 | conf.callback = writeOutputSamples_Player_; | ||
107 | conf.userdata = d; | ||
108 | d->device = SDL_OpenAudioDevice(NULL, SDL_FALSE /* playback */, &conf, &d->spec, 0); | ||
109 | if (!d->device) { | ||
110 | return iFalse; | ||
111 | } | ||
112 | /* TODO: Start the stream/decoder thread. */ | ||
113 | /* TODO: Audio device is unpaused when there are samples ready to play. */ | ||
114 | return iTrue; | ||
115 | } | ||
116 | |||
117 | void stop_Player(iPlayer *d) { | ||
118 | if (isStarted_Player(d)) { | ||
119 | /* TODO: Stop the stream/decoder. */ | ||
120 | SDL_PauseAudioDevice(d->device, SDL_TRUE); | ||
121 | SDL_CloseAudioDevice(d->device); | ||
122 | d->device = 0; | ||
123 | } | ||
38 | } | 124 | } |
diff --git a/src/audio/player.h b/src/audio/player.h index 2786f619..121659f2 100644 --- a/src/audio/player.h +++ b/src/audio/player.h | |||
@@ -22,7 +22,21 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
22 | 22 | ||
23 | #pragma once | 23 | #pragma once |
24 | 24 | ||
25 | #include <the_Foundation/defs.h> | 25 | #include <the_Foundation/block.h> |
26 | 26 | ||
27 | iDeclareType(Player) | 27 | iDeclareType(Player) |
28 | iDeclareTypeConstruction(Player) | 28 | iDeclareTypeConstruction(Player) |
29 | |||
30 | enum iPlayerUpdate { | ||
31 | replace_PlayerUpdate, | ||
32 | append_PlayerUpdate, | ||
33 | complete_PlayerUpdate, | ||
34 | }; | ||
35 | |||
36 | void setFormatHint_Player (iPlayer *, const char *hint); | ||
37 | void updateSourceData_Player (iPlayer *, const iBlock *data, enum iPlayerUpdate update); | ||
38 | |||
39 | iBool start_Player (iPlayer *); | ||
40 | void stop_Player (iPlayer *); | ||
41 | |||
42 | iBool isStarted_Player (const iPlayer *); | ||