// Update to current position and compute the first sample to display.
Update to current position and compute the first sample to display.
Update to current position and compute the first sample to display .
fn update_first_visible_sample(&mut self, frame_time: u64) {
        self.first_visible_sample = if self.image.is_ready {
            self.refresh_position(frame_time);
            if self.cursor_sample >= self.image.lower {
                // current sample appears after first buffer sample
                if let Some((first_visible_sample_lock, lock_state)) =
                    self.first_visible_sample_lock.take()
                {
                    // There is a position lock constraint
                    match lock_state {
                        LockState::Playing => {
                            let offset_to_center = self.cursor_sample as i64
                                - self.half_req_sample_window as i64
                                - first_visible_sample_lock;
                            if offset_to_center < -(2 * self.image.sample_step as i64) {
                                // cursor in first half of the window
                                // keep origin on the first sample upon seek
                                self.first_visible_sample_lock =
                                    Some((first_visible_sample_lock, lock_state));
                                Some(first_visible_sample_lock as usize)
                            } else if (offset_to_center as usize) <= 2 * self.image.sample_step {
                                // reached the center => keep cursor there
                                self.sought_sample = None;
                                Some(
                                    self.image
                                        .lower
                                        .max(self.cursor_sample - self.half_req_sample_window),
                                )
                            } else if first_visible_sample_lock as usize + self.req_sample_window
                                < self.image.upper
                            {
                                // Cursor is on the right half of the window
                                // and the target sample window doesn't exceed the end
                                // of the rendered waveform yet
                                // => progressively get cursor back to center
                                let previous_offset =
                                    self.previous_sample as i64 - first_visible_sample_lock;
                                let delta_cursor =
                                    self.cursor_sample as i64 - self.previous_sample as i64;
                                let next_lower = (self.image.lower as i64).max(
                                    self.cursor_sample as i64 - previous_offset + delta_cursor,
                                );
                                self.first_visible_sample_lock =
                                    Some((next_lower, LockState::Playing));
                                Some(next_lower as usize)
                            } else {
                                // Not enough overhead to get cursor back to center
                                // Follow toward the last sample
                                let next_lower = if self.image.lower + self.req_sample_window
                                    < self.image.upper
                                {
                                    // buffer window is larger than req_sample_window
                                    // set last buffer to the right
                                    let next_lower = self.image.upper - self.req_sample_window;
                                    if !self.image.contains_eos {
                                        // but keep the constraint in case more samples
                                        // are added afterward
                                        self.first_visible_sample_lock =
                                            Some((next_lower as i64, LockState::Playing));
                                    } // else reached EOS => don't expect returning to center
                                    next_lower
                                } else {
                                    // buffer window is smaller than req_sample_window
                                    // set first sample to the left
                                    self.image.lower
                                };
                                Some(next_lower)
                            }
                        }
                        LockState::PlayingRange => {
                            // keep origin on the first sample upon seek
                            self.first_visible_sample_lock =
                                Some((first_visible_sample_lock, lock_state));
                            Some(first_visible_sample_lock as usize)
                        }
                        LockState::RestoringInitialPos => {
                            self.sought_sample = None;
                            Some(first_visible_sample_lock as usize)
                        }
                    }
                } else if self.cursor_sample + self.half_req_sample_window <= self.image.upper {
                    // cursor_sample fits in the first half of the window with last sample further
                    if self.cursor_sample > self.image.lower + self.half_req_sample_window {
                        // cursor_sample can be centered
                        Some(self.cursor_sample - self.half_req_sample_window)
                    } else {
                        // cursor_sample before half of displayable window
                        // set origin to the first sample in the buffer
                        // current sample will be displayed between the origin
                        // and the center
                        Some(self.image.lower)
                    }
                } else if self.cursor_sample >= self.image.upper {
                    // cursor_sample appears after image last sample
                    debug!(
                        concat!(
                            "{}_update_first_visible_sample ",
                            "cursor_sample {} appears above image upper bound {}",
                        ),
                        self.image.id,
                        self.cursor_sample,
                        self.image.upper,
                    );
                    if self.image.upper + self.req_sample_window >= self.cursor_sample {
                        // rebase image attempting to keep in range
                        // even if samples are not rendered yet
                        if self.cursor_sample > self.image.lower + self.req_sample_window {
                            Some(self.cursor_sample - self.req_sample_window)
                        } else {
                            Some(self.image.lower)
                        }
                    } else {
                        // cursor no longer in range, 2 cases:
                        // - seeking forward
                        // - zoomed-in too much to keep up with the audio stream
                        None
                    }
                } else if self.image.lower + self.req_sample_window < self.image.upper {
                    // buffer window is larger than req_sample_window
                    // set last buffer to the right
                    Some(self.image.upper - self.req_sample_window)
                } else {
                    // buffer window is smaller than req_sample_window
                    // set first sample to the left
                    Some(self.image.lower)
                }
            } else if self.cursor_sample + self.req_sample_window > self.image.lower {
                // cursor is close enough to the image
                // => render what can be rendered
                Some(self.image.lower)
            } else {
                // cursor_sample appears before image first sample
                // => wait until situation clarifies
                debug!(
                    concat!(
                        "{}_update_first_visible_sample cursor_sample {} ",
                        "appears before image first sample {}",
                    ),
                    self.image.id,
                    self.cursor_sample,
                    self.image.lower
                );
                None
            }
        } else {
            debug!(
                "{}_update_first_visible_sample image not ready",
                self.image.id
            );
            None
        };
    }
fn update_first_visible_sample ( & mut self , frame_time : u64 ) { self . first_visible_sample = if self . image . is_ready { self . refresh_position ( frame_time ) ; if self . cursor_sample >= self . image . lower { // current sample appears after first buffer sample if let Some ( ( first_visible_sample_lock , lock_state ) ) = self . first_visible_sample_lock . take ( ) { // There is a position lock constraint match lock_state { LockState :: Playing => { let offset_to_center = self . cursor_sample as i64 - self . half_req_sample_window as i64 - first_visible_sample_lock ; if offset_to_center < - ( 2 * self . image . sample_step as i64 ) { // cursor in first half of the window // keep origin on the first sample upon seek self . first_visible_sample_lock = Some ( ( first_visible_sample_lock , lock_state ) ) ; Some ( first_visible_sample_lock as usize ) } else if ( offset_to_center as usize ) <= 2 * self . image . sample_step { // reached the center => keep cursor there self . sought_sample = None ; Some ( self . image . lower . max ( self . cursor_sample - self . half_req_sample_window ) , ) } else if first_visible_sample_lock as usize + self . req_sample_window < self . image . upper { // Cursor is on the right half of the window // and the target sample window doesn't exceed the end // of the rendered waveform yet // => progressively get cursor back to center let previous_offset = self . previous_sample as i64 - first_visible_sample_lock ; let delta_cursor = self . cursor_sample as i64 - self . previous_sample as i64 ; let next_lower = ( self . image . lower as i64 ) . max ( self . cursor_sample as i64 - previous_offset + delta_cursor , ) ; self . first_visible_sample_lock = Some ( ( next_lower , LockState :: Playing ) ) ; Some ( next_lower as usize ) } else { // Not enough overhead to get cursor back to center // Follow toward the last sample let next_lower = if self . image . lower + self . req_sample_window < self . image . upper { // buffer window is larger than req_sample_window // set last buffer to the right let next_lower = self . image . upper - self . req_sample_window ; if ! self . image . contains_eos { // but keep the constraint in case more samples // are added afterward self . first_visible_sample_lock = Some ( ( next_lower as i64 , LockState :: Playing ) ) ; } // else reached EOS => don't expect returning to center next_lower } else { // buffer window is smaller than req_sample_window // set first sample to the left self . image . lower } ; Some ( next_lower ) } } LockState :: PlayingRange => { // keep origin on the first sample upon seek self . first_visible_sample_lock = Some ( ( first_visible_sample_lock , lock_state ) ) ; Some ( first_visible_sample_lock as usize ) } LockState :: RestoringInitialPos => { self . sought_sample = None ; Some ( first_visible_sample_lock as usize ) } } } else if self . cursor_sample + self . half_req_sample_window <= self . image . upper { // cursor_sample fits in the first half of the window with last sample further if self . cursor_sample > self . image . lower + self . half_req_sample_window { // cursor_sample can be centered Some ( self . cursor_sample - self . half_req_sample_window ) } else { // cursor_sample before half of displayable window // set origin to the first sample in the buffer // current sample will be displayed between the origin // and the center Some ( self . image . lower ) } } else if self . cursor_sample >= self . image . upper { // cursor_sample appears after image last sample debug ! ( concat ( " " " " ) self image id self cursor_sample self image upper ) ; if self . image . upper + self . req_sample_window >= self . cursor_sample { // rebase image attempting to keep in range // even if samples are not rendered yet if self . cursor_sample > self . image . lower + self . req_sample_window { Some ( self . cursor_sample - self . req_sample_window ) } else { Some ( self . image . lower ) } } else { // cursor no longer in range, 2 cases: // - seeking forward // - zoomed-in too much to keep up with the audio stream None } } else if self . image . lower + self . req_sample_window < self . image . upper { // buffer window is larger than req_sample_window // set last buffer to the right Some ( self . image . upper - self . req_sample_window ) } else { // buffer window is smaller than req_sample_window // set first sample to the left Some ( self . image . lower ) } } else if self . cursor_sample + self . req_sample_window > self . image . lower { // cursor is close enough to the image // => render what can be rendered Some ( self . image . lower ) } else { // cursor_sample appears before image first sample // => wait until situation clarifies debug ! ( concat ( " " " " ) self image id self cursor_sample self image lower ) ; None } } else { debug ! ( " " self image id ) ; None } ; }
Update to current position and compute the first sample to display.
Update to current position and compute the first sample to display .
&mut self
frame_time
u64