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 | } |