Rev 1 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1 | Rev 8 | ||
---|---|---|---|
Line 50... | Line 50... | ||
50 | smk_info_all(smk_handle, NULL, &smack->Frames, µsecs_per_frame); |
50 | smk_info_all(smk_handle, NULL, &smack->Frames, µsecs_per_frame); |
51 | fps = 1000000.0 / microsecs_per_frame; |
51 | fps = 1000000.0 / microsecs_per_frame; |
52 | smack->MSPerFrame = (unsigned long) ((1 / fps) * 1000); // Pierre-Marie Baty -- added type cast |
52 | smack->MSPerFrame = (unsigned long) ((1 / fps) * 1000); // Pierre-Marie Baty -- added type cast |
53 | smk_info_video(smk_handle, &smack->Width, &smack->Height, NULL); |
53 | smk_info_video(smk_handle, &smack->Width, &smack->Height, NULL); |
54 | smk_enable_video(smk_handle, 1); |
54 | smk_enable_video(smk_handle, 1); |
55 | - | ||
56 | if (smk_first(smk_handle) == SMK_ERROR) { |
- | |
57 | smk_close(smk_handle); |
- | |
58 | free(smack); |
- | |
59 | return NULL; |
- | |
60 | } |
- | |
61 | copy_palette(smack); |
- | |
62 | 55 | ||
63 | // initialize video sound if required and present |
56 | // initialize video sound if required and present |
64 | smack->audio_sample_rate = 0; |
57 | smack->audio_sample_rate = 0; |
65 | smack->audio_frame_size_in_bytes = 0; |
58 | smack->audio_frame_size_in_bytes = 0; |
66 | smack->audio_paged_buffer = NULL; |
59 | smack->audio_paged_buffer = NULL; |
67 | smack->audio_pages_accumulated_cnt = 0; |
- | |
68 | smack->audio_pages_accumulated_max = 0; |
- | |
69 | smack->audio_paged_buffer_data = NULL; |
60 | smack->audio_paged_buffer_data = NULL; |
70 | smack->audio_converter = NULL; |
61 | smack->audio_converter = NULL; |
71 | smack->audio_track = NULL; |
62 | smack->audio_track = NULL; |
72 | if (!gSound_enabled) { |
63 | if (!gSound_enabled) { |
73 |
|
64 | goto no_audio; |
74 | } |
65 | } |
75 | 66 | ||
76 | // get info about the audio tracks in this video |
67 | // get info about the audio tracks in this video |
77 | smk_info_audio(smk_handle, &track_mask_smk, channels_smk, bitdepth_smk, sample_rate_smk); |
68 | smk_info_audio(smk_handle, &track_mask_smk, channels_smk, bitdepth_smk, sample_rate_smk); |
78 | if (!(track_mask_smk & SMK_AUDIO_TRACK_0)) { |
69 | if (!(track_mask_smk & SMK_AUDIO_TRACK_0)) { |
79 | LOG_INFO("Smacker file does not contain audio"); |
70 | LOG_INFO("Smacker file does not contain audio"); |
80 |
|
71 | goto no_audio; |
81 | } |
72 | } |
82 | smack->audio_sample_rate = sample_rate_smk[0]; |
73 | smack->audio_sample_rate = sample_rate_smk[0]; |
83 | switch (bitdepth_smk[0]) { |
74 | switch (bitdepth_smk[0]) { |
84 | case 8: |
75 | case 8: |
85 | audioformat_ma = ma_format_u8; |
76 | audioformat_ma = ma_format_u8; |
Line 97... | Line 88... | ||
97 | audioformat_ma = ma_format_s32; |
88 | audioformat_ma = ma_format_s32; |
98 | smack->audio_frame_size_in_bytes = 4 * channels_smk[0]; |
89 | smack->audio_frame_size_in_bytes = 4 * channels_smk[0]; |
99 | break; |
90 | break; |
100 | default: |
91 | default: |
101 | LOG_WARN("Smacker audio stream has invalid bit depth: %d", bitdepth_smk[0]); |
92 | LOG_WARN("Smacker audio stream has invalid bit depth: %d", bitdepth_smk[0]); |
102 | goto |
93 | goto no_audio; |
103 | } |
94 | } |
104 | - | ||
105 | smack->audio_pages_accumulated_max = smack->Frames / 100; // divider discovered by trial and error. Syncs audio to video in all the intro and intermission videos without starving. |
- | |
106 | if (smack->audio_pages_accumulated_max < 1) |
- | |
107 | smack->audio_pages_accumulated_max = 1; |
- | |
108 | //LOG_INFO("Smacker audio: will accumulate %d pages", smack->audio_pages_accumulated_max); |
- | |
109 | 95 | ||
110 | // allocate and initialize paged buffer data |
96 | // allocate and initialize paged buffer data |
111 | smack->audio_paged_buffer_data = malloc(sizeof(ma_paged_audio_buffer_data)); |
97 | smack->audio_paged_buffer_data = malloc(sizeof(ma_paged_audio_buffer_data)); |
112 | 98 | ||
113 | if ((smack->audio_frame_size_in_bytes == 0) || (ma_paged_audio_buffer_data_init(audioformat_ma, channels_smk[0], smack->audio_paged_buffer_data) != MA_SUCCESS)) { |
99 | if ((smack->audio_frame_size_in_bytes == 0) || (ma_paged_audio_buffer_data_init(audioformat_ma, channels_smk[0], smack->audio_paged_buffer_data) != MA_SUCCESS)) { |
114 | LOG_WARN("Failed to create paged audio buffer data"); |
100 | LOG_WARN("Failed to create paged audio buffer data"); |
115 | goto |
101 | goto no_audio; |
116 | } |
102 | } |
117 | 103 | ||
118 | // allocate and initialize paged buffer |
104 | // allocate and initialize paged buffer |
119 | smack->audio_paged_buffer = malloc(sizeof(ma_paged_audio_buffer)); |
105 | smack->audio_paged_buffer = malloc(sizeof(ma_paged_audio_buffer)); |
120 | 106 | ||
121 | paged_audio_buffer_config = ma_paged_audio_buffer_config_init(smack->audio_paged_buffer_data); |
107 | paged_audio_buffer_config = ma_paged_audio_buffer_config_init(smack->audio_paged_buffer_data); |
122 | if (ma_paged_audio_buffer_init (&paged_audio_buffer_config, smack->audio_paged_buffer) != MA_SUCCESS) { |
108 | if (ma_paged_audio_buffer_init (&paged_audio_buffer_config, smack->audio_paged_buffer) != MA_SUCCESS) { |
123 | LOG_WARN("Failed to create paged audio buffer for smacker audio stream"); |
109 | LOG_WARN("Failed to create paged audio buffer for smacker audio stream"); |
124 | goto |
110 | goto no_audio; |
125 | } |
111 | } |
126 | 112 | ||
127 | // allocate and initialize sound |
113 | // allocate and initialize sound |
128 | smack->audio_track = malloc(sizeof(ma_sound)); |
114 | smack->audio_track = malloc(sizeof(ma_sound)); |
129 | 115 | ||
130 | if (ma_sound_init_from_data_source(&miniaudio_engine, smack->audio_paged_buffer, MA_SOUND_FLAG_NO_PITCH | MA_SOUND_FLAG_NO_SPATIALIZATION, NULL, smack->audio_track) != MA_SUCCESS) { |
116 | if (ma_sound_init_from_data_source(&miniaudio_engine, smack->audio_paged_buffer, MA_SOUND_FLAG_NO_PITCH | MA_SOUND_FLAG_NO_SPATIALIZATION, NULL, smack->audio_track) != MA_SUCCESS) { |
131 | LOG_WARN("Failed to create sound from data source"); |
117 | LOG_WARN("Failed to create sound from data source"); |
132 | goto |
118 | goto no_audio; |
133 | } |
119 | } |
134 | 120 | ||
135 | // allocate and initialize data converter |
121 | // allocate and initialize data converter if miniaudio engine and Smack file soundtrack sample rates differ |
- | 122 | if (ma_engine_get_sample_rate(&miniaudio_engine) != sample_rate_smk[0]) { |
|
136 | smack->audio_converter = malloc(sizeof(ma_data_converter)); |
123 | smack->audio_converter = malloc(sizeof(ma_data_converter)); |
137 | 124 | ||
138 | data_converter_config = ma_data_converter_config_init(audioformat_ma, audioformat_ma, channels_smk[0], channels_smk[0], smack->audio_sample_rate, ma_engine_get_sample_rate (&miniaudio_engine)); |
125 | data_converter_config = ma_data_converter_config_init(audioformat_ma, audioformat_ma, channels_smk[0], channels_smk[0], smack->audio_sample_rate, ma_engine_get_sample_rate (&miniaudio_engine)); |
139 | if (ma_data_converter_init(&data_converter_config, NULL, smack->audio_converter) != MA_SUCCESS) { |
126 | if (ma_data_converter_init(&data_converter_config, NULL, smack->audio_converter) != MA_SUCCESS) { |
140 | LOG_WARN("Failed to create sound data converter"); |
127 | LOG_WARN("Failed to create sound data converter"); |
141 | goto |
128 | goto no_audio; |
- | 129 | } |
|
142 | } |
130 | } |
143 | 131 | ||
144 | // tell libsmacker we can process audio now |
132 | // tell libsmacker we can process audio now |
145 | smk_enable_audio(smk_handle, 0, 1); |
133 | smk_enable_audio(smk_handle, 0, 1); |
- | 134 | ||
- | 135 | // load the first frame and return a handle to the Smack file |
|
- | 136 | if (smk_first(smk_handle) == SMK_ERROR) { |
|
- | 137 | smk_close(smk_handle); |
|
- | 138 | free(smack); |
|
- | 139 | return NULL; |
|
- | 140 | } |
|
- | 141 | copy_palette(smack); |
|
146 | return smack; |
142 | return smack; |
147 | 143 | ||
148 |
|
144 | no_audio: |
- | 145 | // no audio or failed to init audio, cleanup audio stuff |
|
149 | if (smack->audio_converter != NULL) { |
146 | if (smack->audio_converter != NULL) { |
150 | free(smack->audio_converter); |
147 | free(smack->audio_converter); |
151 | smack->audio_converter = NULL; |
148 | smack->audio_converter = NULL; |
152 | } |
149 | } |
153 | if (smack->audio_track != NULL) { |
150 | if (smack->audio_track != NULL) { |
Line 163... | Line 160... | ||
163 | if (smack->audio_paged_buffer_data != NULL) { |
160 | if (smack->audio_paged_buffer_data != NULL) { |
164 | ma_paged_audio_buffer_data_uninit (smack->audio_paged_buffer_data, NULL); |
161 | ma_paged_audio_buffer_data_uninit (smack->audio_paged_buffer_data, NULL); |
165 | free(smack->audio_paged_buffer_data); |
162 | free(smack->audio_paged_buffer_data); |
166 | smack->audio_paged_buffer_data = NULL; |
163 | smack->audio_paged_buffer_data = NULL; |
167 | } |
164 | } |
- | 165 | ||
- | 166 | // load the first frame and return a handle to the Smack file |
|
- | 167 | if (smk_first(smk_handle) == SMK_ERROR) { |
|
- | 168 | smk_close(smk_handle); |
|
- | 169 | free(smack); |
|
- | 170 | return NULL; |
|
- | 171 | } |
|
- | 172 | copy_palette(smack); |
|
168 | return smack; |
173 | return smack; |
169 | } |
174 | } |
170 | 175 | ||
171 | int SmackSoundUseDirectSound(void* dd) { |
176 | int SmackSoundUseDirectSound(void* dd) { |
172 | // TODO: do some miniaudio init |
177 | // TODO: do some miniaudio init |
Line 195... | Line 200... | ||
195 | unsigned long audio_data_size; |
200 | unsigned long audio_data_size; |
196 | ma_paged_audio_buffer_page *newPage; |
201 | ma_paged_audio_buffer_page *newPage; |
197 | ma_uint64 current_pos; |
202 | ma_uint64 current_pos; |
198 | ma_uint64 nb_frames_in; |
203 | ma_uint64 nb_frames_in; |
199 | ma_uint64 nb_frames_out; |
204 | ma_uint64 nb_frames_out; |
200 | ma_uint64 seek_pos; |
- | |
201 | 205 | ||
202 | // process audio if we have some |
206 | // process audio if we have some |
203 | if (smack-> |
207 | if (smack->audio_track != NULL) { |
204 | audio_data = smk_get_audio (smack->smk_handle, 0); |
208 | audio_data = smk_get_audio (smack->smk_handle, 0); |
205 | audio_data_size = smk_get_audio_size (smack->smk_handle, 0); |
209 | audio_data_size = smk_get_audio_size (smack->smk_handle, 0); |
206 | if ((audio_data == NULL) || (audio_data_size == 0)) { |
210 | if ((audio_data == NULL) || (audio_data_size == 0)) { |
207 | return 0; |
211 | return 0; |
208 | } |
212 | } |
209 | 213 | ||
210 | if (ma_paged_audio_buffer_get_length_in_pcm_frames (smack->audio_paged_buffer, ¤t_pos) != MA_SUCCESS) { |
214 | if (ma_paged_audio_buffer_get_length_in_pcm_frames (smack->audio_paged_buffer, ¤t_pos) != MA_SUCCESS) { |
211 | LOG_WARN("ma_paged_audio_buffer_get_length_in_pcm_frames failed"); |
215 | LOG_WARN("ma_paged_audio_buffer_get_length_in_pcm_frames failed"); |
212 | return 0; |
216 | return 0; |
213 | } |
217 | } |
214 | 218 | ||
- | 219 | // do we need to convert the sample frequency? |
|
- | 220 | if (smack->audio_converter != NULL) { |
|
215 | nb_frames_in = audio_data_size / smack->audio_frame_size_in_bytes; |
221 | nb_frames_in = audio_data_size / smack->audio_frame_size_in_bytes; |
216 | nb_frames_out = nb_frames_in * ma_engine_get_sample_rate (&miniaudio_engine) / smack->audio_sample_rate; |
222 | nb_frames_out = nb_frames_in * ma_engine_get_sample_rate (&miniaudio_engine) / smack->audio_sample_rate; |
217 | 223 | ||
218 | if (ma_paged_audio_buffer_data_allocate_page (smack->audio_paged_buffer_data, nb_frames_out, NULL, NULL, &newPage) != MA_SUCCESS) { |
224 | if (ma_paged_audio_buffer_data_allocate_page (smack->audio_paged_buffer_data, nb_frames_out, NULL, NULL, &newPage) != MA_SUCCESS) { |
219 | LOG_WARN("ma_paged_audio_buffer_data_allocate_page failed"); |
225 | LOG_WARN("ma_paged_audio_buffer_data_allocate_page failed"); |
220 | return 0; |
226 | return 0; |
221 | } |
227 | } |
222 | else if (ma_data_converter_process_pcm_frames (smack->audio_converter, audio_data, &nb_frames_in, newPage->pAudioData, &nb_frames_out) != MA_SUCCESS) { |
228 | else if (ma_data_converter_process_pcm_frames (smack->audio_converter, audio_data, &nb_frames_in, newPage->pAudioData, &nb_frames_out) != MA_SUCCESS) { |
223 | LOG_WARN("ma_data_converter_process_pcm_frames failed"); |
229 | LOG_WARN("ma_data_converter_process_pcm_frames failed"); |
- | 230 | return 0; |
|
- | 231 | } |
|
- | 232 | else if (ma_paged_audio_buffer_data_append_page (smack->audio_paged_buffer_data, newPage) != MA_SUCCESS) { |
|
- | 233 | LOG_WARN("ma_paged_audio_buffer_data_append_page failed"); |
|
- | 234 | return 0; |
|
- | 235 | } |
|
- | 236 | } else { // no sampling frequency conversion needed |
|
- | 237 | if (ma_paged_audio_buffer_data_allocate_and_append_page(smack->audio_paged_buffer_data, (ma_uint32) (audio_data_size / (ma_uint64) smack->audio_frame_size_in_bytes), audio_data, NULL) != MA_SUCCESS) { |
|
- | 238 | LOG_WARN ("ma_paged_audio_buffer_data_allocate_and_append_page failed"); |
|
224 | return 0; |
239 | return 0; |
- | 240 | } |
|
225 | } |
241 | } |
226 | else if (ma_paged_audio_buffer_data_append_page (smack->audio_paged_buffer_data, newPage) != MA_SUCCESS) { |
- | |
227 | LOG_WARN("ma_paged_audio_buffer_data_append_page failed"); |
- | |
228 | return 0; |
- | |
229 | } |
- | |
230 | smack->audio_pages_accumulated_cnt++; |
- | |
231 | 242 | ||
232 | if ( |
243 | if (!ma_sound_is_playing (smack->audio_track)) |
233 | { |
244 | { |
234 | if (!ma_sound_is_playing (smack->audio_track)) |
- | |
235 | { |
- | |
236 |
|
245 | // seek either at start, or where the accumulated value hasn't played yet |
237 | seek_pos = ((smack->audio_pages_accumulated_max - 1) * nb_frames_out < current_pos ? current_pos - (smack->audio_pages_accumulated_max - 1) * nb_frames_out : 0); |
- | |
238 |
|
246 | if (ma_sound_seek_to_pcm_frame (smack->audio_track, current_pos) != MA_SUCCESS) { |
239 |
|
247 | LOG_WARN("ma_sound_seek_to_pcm_frame failed"); |
240 | } |
- | |
241 | if (ma_sound_start (smack->audio_track) != MA_SUCCESS) { |
- | |
242 | LOG_WARN("ma_sound_start failed"); |
- | |
243 | } |
- | |
244 | } |
248 | } |
245 | if ( |
249 | if (ma_sound_start (smack->audio_track) != MA_SUCCESS) { |
246 | LOG_WARN |
250 | LOG_WARN("ma_sound_start failed"); |
247 | } |
251 | } |
- | 252 | } |
|
- | 253 | if (ma_sound_at_end (smack->audio_track)) { |
|
- | 254 | LOG_WARN ("video not playing fast enough: sound starved!"); |
|
248 | } |
255 | } |
249 | } |
256 | } |
250 | 257 | ||
251 | return 0; |
258 | return 0; |
252 | } |
259 | } |