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 | } |
| Line 210... | Line 214... | ||
| 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"); |
| - | 226 | return 0; |
|
| - | 227 | } |
|
| - | 228 | else if (ma_data_converter_process_pcm_frames (smack->audio_converter, audio_data, &nb_frames_in, newPage->pAudioData, &nb_frames_out) != MA_SUCCESS) { |
|
| - | 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"); |
|
| 220 | return 0; |
239 | return 0; |
| - | 240 | } |
|
| 221 | } |
241 | } |
| 222 | 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"); |
- | |
| 224 | return 0; |
- | |
| 225 | } |
- | |
| 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 | } |