/* Handle STREAM_SEEK */
static void stream_on_seek(struct stream_seek_data *skd)
{
    uint32_t time = skd->time;
    int whence = skd->whence;

    switch (whence)
    {
    case SEEK_SET:
    case SEEK_CUR:
    case SEEK_END:
        if (stream_mgr.filename == NULL)
            break;

        /* Keep things spinning if already doing so */
        stream_keep_disk_active();

        /* Have data - reply in order to acquire lock */
        stream_mgr_reply_msg(STREAM_OK);

        stream_mgr_lock();

        /* Either seeking must be possible or a full rewind must be done */
        if (stream_can_seek() || time_from_whence(time, whence) == 0)
        {
            bool buffer;

            if (stream_mgr.status == STREAM_PLAYING)
            {
                /* Keep clock from advancing while seeking */
                pcm_output_play_pause(false);
            }

            time = stream_seek_intl(time, whence, stream_mgr.status, &buffer);
            stream_remember_resume_time();

            if (stream_mgr.status == STREAM_PLAYING)
            {
                /* Sync and restart - no force buffering */
                stream_start_playback(time, buffer);
            }
        }

        stream_mgr_unlock();
        return;
    }

    /* Invalid parameter or no file */
    stream_mgr_reply_msg(STREAM_ERROR);
}
/* Handle seeking details if playing or paused */
static uint32_t stream_seek_intl(uint32_t time, int whence,
                                 int status, bool *was_buffering)
{
    if (status != STREAM_STOPPED)
    {
        bool wb;

        /* Place streams in a non-running state - keep them on actl */
        actl_stream_broadcast(STREAM_STOP, 0);

        /* Stop all buffering or else risk clobbering random-access data */
        wb = disk_buf_send_msg(STREAM_STOP, 0);

        if (was_buffering != NULL)
            *was_buffering = wb;
    }

    time = time_from_whence(time, whence);

    stream_mgr.seeked = true;

    return parser_seek_time(time);
}