Subversion Repositories Games.Carmageddon

Rev

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, &microsecs_per_frame);
50
    smk_info_all(smk_handle, NULL, &smack->Frames, &microsecs_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
        return smack;
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
        return smack;
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 audio_fail;
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 audio_fail;
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 audio_fail;
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 audio_fail;
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 audio_fail;
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
audio_fail:
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->audio_converter != NULL) {
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, &current_pos) != MA_SUCCESS) {
214
        if (ma_paged_audio_buffer_get_length_in_pcm_frames (smack->audio_paged_buffer, &current_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 (smack->audio_pages_accumulated_cnt > smack->audio_pages_accumulated_max)
243
        if (!ma_sound_is_playing (smack->audio_track))
233
        {
244
        {
234
            if (!ma_sound_is_playing (smack->audio_track))
-
 
235
            {
-
 
236
                // seek either at start, or where the accumulated value hasn't played yet
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
                if (ma_sound_seek_to_pcm_frame (smack->audio_track, seek_pos) != MA_SUCCESS) {
246
            if (ma_sound_seek_to_pcm_frame (smack->audio_track, current_pos) != MA_SUCCESS) {
239
                    LOG_WARN("ma_sound_seek_to_pcm_frame failed");
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 (ma_sound_at_end (smack->audio_track)) {
249
            if (ma_sound_start (smack->audio_track) != MA_SUCCESS) {
246
                LOG_WARN ("video not playing fast enough: sound starved!");
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
}