# Path: dunyadesktop_app/widgets/widgetutilities.py
# def downsample_plot(plot_array, ds_limit):
#     # Decide by how much we should downsample
#     """
#     Downsamples the given pitch array according to the given downsample limit.
# 
#     :param plot_array: (numpy array) A sequence of pitch values
#                        [440.4, 442.3, 440.0, ...]
#     :param ds_limit: (int) Maximum number of samples to be plotted.
# 
#     :return: (numpy array) A sequence of pitch values
#     """
#     size_array = np.size(plot_array)
#     ds = int(size_array / ds_limit) + 1
# 
#     if ds == 1:
#         # Small enough to display with no intervention.
#         return plot_array
#     else:
#         # Here convert data into a down-sampled array suitable for
#         # visualizing. Must do this piecewise to limit memory usage.
#         samples = 1 + (size_array // ds)
#         visible = np.zeros(samples * 2, dtype=plot_array.dtype)
#         source_ptr = 0
#         target_ptr = 0
# 
#         # read data in chunks of ~1M samples
#         chunk_size = (1000000 // ds) * ds
#         while source_ptr < size_array - 1:
#             chunk = plot_array[source_ptr:min(size_array,
#                                               source_ptr+chunk_size)]
#             size_chunk = np.size(chunk)
#             source_ptr += size_chunk
#             # reshape chunk to be integral multiple of ds
#             chunk = chunk[:(size_chunk // ds) * ds].reshape(size_chunk//ds, ds)
# 
#             # compute max and min
#             chunk_max = chunk.max(axis=1)
#             chunk_min = chunk.min(axis=1)
# 
#             # interleave min and max into plot data to preserve
#             # envelope shape
#             visible[target_ptr:target_ptr + chunk.shape[0] * 2:2] = chunk_min
#             visible[1+target_ptr:1+target_ptr+chunk.shape[0] * 2:2] = chunk_max
#             target_ptr += chunk.shape[0] * 2
#         plot_y = visible[:target_ptr]
#         plot_y[-1] = np.nan
#     return plot_y
# 
# def cursor_pos_sample(pos, samplerate, hopsize):
#     """
#     Returns the current index of sample.
# 
#     :param pos: (int or float) Playback position in seconds.
#     """
#     return np.int(pos * samplerate / hopsize)
# 
# def current_pitch(sample, pitch_plot):
#     """
#     Returns the current pitch value in Hz.
#     :param sample: (int) Index of sample.
# 
#     :return: (float) Pitch in Hz.
#     """
#     return pitch_plot[sample]


import pyqtgraph as pg
import numpy as np
from PyQt5.QtCore import pyqtSignal
from .widgetutilities import downsample_plot, cursor_pos_sample, current_pitch

    def add_tonic(self, values):
        """
        Adds tonic lines on the pitch plot.

        :param values: (list or numpy array) A sequence of tonic values in Hz.

        """
        # label options for the tonic values on the tonic line
        label_opts = {'position': 0.1, 'color': (200, 200, 100),
                      'fill': (200, 200, 200, 50), 'movable': True}

        if not hasattr(self, 'tonic_lines'):
            self.tonic_lines = []

        for value in values:
            # create infinite line
            t_line = pg.InfiniteLine(pos=value, movable=False, angle=0,
                                     label='Tonic=%.2f' % value,
                                     labelOpts=label_opts)
            # take tonic lines in a list to remove in the future
            self.tonic_lines.append(t_line)
            self.zoom_selection.addItem(t_line)  # add item to zoom selection

    def set_hist_cursor_pos(self, pos):
        """
        Sets the position of histogram in y-axis.

        :param pos: (int or float) Playback position in seconds.
        """

# Path: dunyadesktop_app/widgets/widgetutilities.py
# def downsample_plot(plot_array, ds_limit):
#     # Decide by how much we should downsample
#     """
#     Downsamples the given pitch array according to the given downsample limit.
# 
#     :param plot_array: (numpy array) A sequence of pitch values
#                        [440.4, 442.3, 440.0, ...]
#     :param ds_limit: (int) Maximum number of samples to be plotted.
# 
#     :return: (numpy array) A sequence of pitch values
#     """
#     size_array = np.size(plot_array)
#     ds = int(size_array / ds_limit) + 1
# 
#     if ds == 1:
#         # Small enough to display with no intervention.
#         return plot_array
#     else:
#         # Here convert data into a down-sampled array suitable for
#         # visualizing. Must do this piecewise to limit memory usage.
#         samples = 1 + (size_array // ds)
#         visible = np.zeros(samples * 2, dtype=plot_array.dtype)
#         source_ptr = 0
#         target_ptr = 0
# 
#         # read data in chunks of ~1M samples
#         chunk_size = (1000000 // ds) * ds
#         while source_ptr < size_array - 1:
#             chunk = plot_array[source_ptr:min(size_array,
#                                               source_ptr+chunk_size)]
#             size_chunk = np.size(chunk)
#             source_ptr += size_chunk
#             # reshape chunk to be integral multiple of ds
#             chunk = chunk[:(size_chunk // ds) * ds].reshape(size_chunk//ds, ds)
# 
#             # compute max and min
#             chunk_max = chunk.max(axis=1)
#             chunk_min = chunk.min(axis=1)
# 
#             # interleave min and max into plot data to preserve
#             # envelope shape
#             visible[target_ptr:target_ptr + chunk.shape[0] * 2:2] = chunk_min
#             visible[1+target_ptr:1+target_ptr+chunk.shape[0] * 2:2] = chunk_max
#             target_ptr += chunk.shape[0] * 2
#         plot_y = visible[:target_ptr]
#         plot_y[-1] = np.nan
#     return plot_y
# 
# def cursor_pos_sample(pos, samplerate, hopsize):
#     """
#     Returns the current index of sample.
# 
#     :param pos: (int or float) Playback position in seconds.
#     """
#     return np.int(pos * samplerate / hopsize)
# 
# def current_pitch(sample, pitch_plot):
#     """
#     Returns the current pitch value in Hz.
#     :param sample: (int) Index of sample.
# 
#     :return: (float) Pitch in Hz.
#     """
#     return pitch_plot[sample]


# Path: dunyadesktop_app/widgets/timeserieswidget.py
import pyqtgraph as pg
import numpy as np
from PyQt5.QtCore import pyqtSignal
from .widgetutilities import downsample_plot, cursor_pos_sample, current_pitch


    def add_tonic(self, values):
        """
        Adds tonic lines on the pitch plot.

        :param values: (list or numpy array) A sequence of tonic values in Hz.

        """
        # label options for the tonic values on the tonic line
        label_opts = {'position': 0.1, 'color': (200, 200, 100),
                      'fill': (200, 200, 200, 50), 'movable': True}

        if not hasattr(self, 'tonic_lines'):
            self.tonic_lines = []

        for value in values:
            # create infinite line
            t_line = pg.InfiniteLine(pos=value, movable=False, angle=0,
                                     label='Tonic=%.2f' % value,
                                     labelOpts=label_opts)
            # take tonic lines in a list to remove in the future
            self.tonic_lines.append(t_line)
            self.zoom_selection.addItem(t_line)  # add item to zoom selection

    def set_hist_cursor_pos(self, pos):
        """
        Sets the position of histogram in y-axis.

        :param pos: (int or float) Playback position in seconds.
        """

        pos_sample = cursor_pos_sample(pos, self.sample_rate, self.hopsize)