// External access to the chunks list SUBTITLE_REF GetNextTrackSubtitle (SUBTITLE_REF LastRef) { if (!LastRef) return NULL; // enumeration already ended return find_next_page (LastRef); }
void FastForward_Page (void) { TFB_SoundChunk *next; if (!sound_sample) return; // nothing is playing, so.. bye! LockMutex (soundSource[SPEECH_SOURCE].stream_mutex); next = find_next_page (cur_sub_chunk); if (next) { // Set the chunk to be played cur_chunk = next; cur_sub_chunk = next; // Decoder will be set in OnStreamStart() PlayStream (sound_sample, SPEECH_SOURCE, false, true, true); } else { // End of the tracks (pun intended) seek_track (tracks_length + 1); } UnlockMutex (soundSource[SPEECH_SOURCE].stream_mutex); }
// XXX: This code and the entire trackplayer are begging to be overhauled void SpliceTrack (UNICODE *TrackName, UNICODE *TrackText, UNICODE *TimeStamp, CallbackFunction cb) { static UNICODE last_track_name[128] = ""; static unsigned long dec_offset = 0; #define MAX_PAGES 50 UNICODE *pages[MAX_PAGES]; sint32 time_stamps[MAX_PAGES]; int num_pages; int page; if (!TrackText) return; if (!TrackName) { // Appending a piece of subtitles to the last track int slen1, slen2; if (track_count == 0) { log_add (log_Warning, "SpliceTrack(): Tried to append a subtitle," " but no current track"); return; } if (!last_sub || !last_sub->text) { log_add (log_Warning, "SpliceTrack(): Tried to append a subtitle" " to a NULL string"); return; } num_pages = SplitSubPages (TrackText, pages, time_stamps, MAX_PAGES); if (num_pages == 0) { log_add (log_Warning, "SpliceTrack(): Failed to parse subtitles"); return; } // The last page's stamp is a suggested value. The track should // actually play to the end. time_stamps[num_pages - 1] = -time_stamps[num_pages - 1]; // Add the first piece to the last subtitle page slen1 = strlen (last_sub->text); slen2 = strlen (pages[0]); last_sub->text = HRealloc (last_sub->text, slen1 + slen2 + 1); strcpy (last_sub->text + slen1, pages[0]); HFree (pages[0]); // Add the rest of the pages for (page = 1; page < num_pages; ++page) { TFB_SoundChunk *next_sub = find_next_page (last_sub); if (next_sub) { // nodes prepared by previous call, just fill in the subs next_sub->text = pages[page]; last_sub = next_sub; } else { // probably no timestamps were provided, so need more work TFB_SoundDecoder *decoder = SoundDecoder_Load (contentDir, last_track_name, 4096, dec_offset, time_stamps[page]); if (!decoder) { log_add (log_Warning, "SpliceTrack(): couldn't load %s", TrackName); break; } dec_offset += (unsigned long)(decoder->length * 1000); chunks_tail->next = create_SoundChunk (decoder, sound_sample->length); chunks_tail = chunks_tail->next; chunks_tail->tag_me = 1; chunks_tail->track_num = track_count - 1; chunks_tail->text = pages[page]; chunks_tail->callback = cb; // TODO: We may have to tag only one page with a callback //cb = NULL; last_sub = chunks_tail; sound_sample->length += decoder->length; } } } else { // Adding a new track int num_timestamps = 0; utf8StringCopy (last_track_name, sizeof (last_track_name), TrackName); num_pages = SplitSubPages (TrackText, pages, time_stamps, MAX_PAGES); if (num_pages == 0) { log_add (log_Warning, "SpliceTrack(): Failed to parse sutitles"); return; } // The last page's stamp is a suggested value. The track should // actually play to the end. time_stamps[num_pages - 1] = -time_stamps[num_pages - 1]; if (no_page_break && track_count) { int slen1, slen2; slen1 = strlen (last_sub->text); slen2 = strlen (pages[0]); last_sub->text = HRealloc (last_sub->text, slen1 + slen2 + 1); strcpy (last_sub->text + slen1, pages[0]); HFree (pages[0]); } else track_count++; log_add (log_Info, "SpliceTrack(): loading %s", TrackName); if (TimeStamp) { num_timestamps = GetTimeStamps (TimeStamp, time_stamps) + 1; if (num_timestamps < num_pages) { log_add (log_Warning, "SpliceTrack(): number of timestamps" " doesn't match number of pages!"); } else if (num_timestamps > num_pages) { // We most likely will get more subtitles appended later // Set the last page to the rest of the track time_stamps[num_timestamps - 1] = -100000; } } else { num_timestamps = num_pages; } // Reset the offset for the new track dec_offset = 0; for (page = 0; page < num_timestamps; ++page) { TFB_SoundDecoder *decoder = SoundDecoder_Load (contentDir, TrackName, 4096, dec_offset, time_stamps[page]); if (!decoder) { log_add (log_Warning, "SpliceTrack(): couldn't load %s", TrackName); break; } if (!sound_sample) { sound_sample = TFB_CreateSoundSample (NULL, 8, &trackCBs); chunks_head = create_SoundChunk (decoder, 0.0); chunks_tail = chunks_head; } else { chunks_tail->next = create_SoundChunk (decoder, sound_sample->length); chunks_tail = chunks_tail->next; } dec_offset += (unsigned long)(decoder->length * 1000); #if 0 log_add (log_Debug, "page (%d of %d): %d ts: %d", page, num_pages, dec_offset, time_stamps[page]); #endif sound_sample->length += decoder->length; chunks_tail->track_num = track_count - 1; if (!no_page_break) { chunks_tail->tag_me = 1; if (page < num_pages) { chunks_tail->text = pages[page]; last_sub = chunks_tail; } chunks_tail->callback = cb; // TODO: We may have to tag only one page with a callback //cb = NULL; } no_page_break = 0; } } }
static void gis_assistant_real_next_page (GisAssistant *assistant, GisPage *page) { gis_assistant_switch_to (assistant, find_next_page (page)); }