<?xml version='1.0' encoding='utf-8' standalone='yes'?>
<?xml-stylesheet href="./_c74_ref.xsl" type="text/xsl"?>

<c74object name='spectrogram~'>

	<digest>
		<o>buffer~</o> based spectrogram analyzer and viewer
	</digest>
	<description>
		Use the <o>spectrogram~</o> object to analyze and view the spectral contents of a <o>buffer~</o>.
		<br />
		<br />
		<a href="https://www.youtube.com/playlist?list=PLHc927eu2oKYhvWtMZ7XhzYrs3WBCVVWj">Tutorial Videos on YouTube</a>
	</description>


	<!--METADATA-->
	<metadatalist>
		<metadata name='author'>Zachary Seldess</metadata>
		<metadata name='tag'>MSP</metadata>
		<metadata name='tag'>MSP U/I</metadata>
	</metadatalist>


	<!--INLETS-->
	<inletlist>
		<inlet id="0" type="float">
			<digest>Display Start (ms)</digest>
		</inlet>
		<inlet id="1" type="float">
			<digest>Display Length (ms)</digest>
		</inlet>
		<inlet id="2" type="float">
			<digest>Display Low (Hz)</digest>
		</inlet>
		<inlet id="3" type="float">
			<digest>Display High (Hz)</digest>
		</inlet>
		<inlet id="4" type="float">
			<digest>Display Selection Start (ms)</digest>
		</inlet>
		<inlet id="5" type="float">
			<digest>Display Selection End (ms)</digest>
		</inlet>
		<inlet id="6" type="float">
			<digest>Display Selection Low (Hz)</digest>
		</inlet>
		<inlet id="7" type="float">
			<digest>Display Selection High (Hz)</digest>
		</inlet>
		<inlet id="8" type="message">
			<digest>Link In (for multi-channel viewing)</digest>
		</inlet>
	</inletlist>


	<!--OUTLETS-->
	<outletlist>
		<outlet id="0" type="float">
			<digest>Display Start (ms)</digest>
		</outlet>
		<outlet id="1" type="float">
			<digest>Display Length (ms)</digest>
		</outlet>
		<outlet id="2" type="float">
			<digest>Display Low (Hz)</digest>
		</outlet>
		<outlet id="3" type="float">
			<digest>Display High (Hz)</digest>
		</outlet>
		<outlet id="4" type="float">
			<digest>Display Selection Start (ms)</digest>
		</outlet>
		<outlet id="5" type="float">
			<digest>Display Selection End (ms)</digest>
		</outlet>
		<outlet id="6" type="float">
			<digest>Display Selection Low (Hz)</digest>
		</outlet>
		<outlet id="7" type="float">
			<digest>Display Selection High (Hz)</digest>
		</outlet>
		<outlet id="8" type="message">
			<digest>Link Out (for multi-channel viewing)</digest>
		</outlet>
		<outlet id="9" type="message">
			<digest>Data at mouse location (time freq mag)</digest>
		</outlet>
	</outletlist>


	<!--ARGUMENTS-->
	<objarglist>
	</objarglist>


	<!--MESSAGES-->
	<methodlist>
		<method name="write">
			<arglist />
			<digest>
				Save spectrogram as full or custom-resolution PNG file (full resolution = 1 pixel per bin).
			</digest>
			<description>
				Save spectrogram as full or custom-resolution PNG file (full resolution = 1 pixel per bin).
				<br />
				Optional arguments:
				<ul>
					<li>
						<b>Version 1</b> - Width Height DPI (will open file chooser)
					</li>
					<li>
						<b>Version 2</b> - Filename Width Height DPI
					</li>
					Defaults:
					<ul>
						- Width = number of FFT windows. Range 1 - 100000.
						<br />
						- Height = number of FFT bins per window. Range 1 - 100000.
						<br />
						- DPI = 72. Range 1 - 10000.
					</ul>
					Providing a Width or Height of &lt;= 0 will fall back to full resolution.
				</ul>
				<o>spectrogram~</o> will save to .png using its current display/color/etc. settings.
				<br />
				For example:
				<ul>
					<li>
						To save without time and frequency text, set @time_text and @freq_text to 0.
					</li>
					<li>
						To save using a specific magnitude scale or color scheme, set @mag_scale and @color_scheme accordingly.
					</li>
					<li>
						etc.
					</li>
				</ul>
			</description>
		</method>
		<method name="zoom_in">
			<arglist />
			<digest>
				Zoom in (time and frequency).
			</digest>
			<description>
				Zoom in (time and frequency).
			</description>
		</method>
		<method name="zoom_in_freq">
			<arglist />
			<digest>
				Zoom in (frequency).
			</digest>
			<description>
				Zoom in (frequency).
			</description>
		</method>
		<method name="zoom_in_time">
			<arglist />
			<digest>
				Zoom in (time).
			</digest>
			<description>
				Zoom in (time).
			</description>
		</method>

		<method name="zoom_out">
			<arglist />
			<digest>
				Zoom out (time and frequency).
			</digest>
			<description>
				Zoom out (time and frequency).
			</description>
		</method>
		<method name="zoom_out_freq">
			<arglist />
			<digest>
				Zoom out (frequency).
			</digest>
			<description>
				Zoom out (frequency).
			</description>
		</method>
		<method name="zoom_out_time">
			<arglist />
			<digest>
				Zoom out (time).
			</digest>
			<description>
				Zoom out (time).
			</description>
		</method>

		<method name="view_all">
			<arglist />
			<digest>
				Display entire buffer~ (time and frequency).
			</digest>
			<description>
				Display entire buffer~ (time and frequency).
			</description>
		</method>
		<method name="view_all_freq">
			<arglist />
			<digest>
				Display entire buffer~ (frequency).
			</digest>
			<description>
				Display entire buffer~ (frequency).
			</description>
		</method>
		<method name="view_all_time">
			<arglist />
			<digest>
				Display entire buffer~ (time).
			</digest>
			<description>
				Display entire buffer~ (time).
			</description>
		</method>
		<method name="view_selected">
			<arglist />
			<digest>
				Display selection (i.e. zoom to selection).
			</digest>
			<description>
				Display selection (i.e. zoom to selection).
			</description>
		</method>

		<method name="select_none">
			<arglist />
			<digest>
				Deselect all.
			</digest>
			<description>
				Deselect all.
			</description>
		</method>
		<method name="select_all">
			<arglist />
			<digest>
				Select entire buffer~ (time and frequency).
			</digest>
			<description>
				Select entire buffer~ (time and frequency).
			</description>
		</method>
		<method name="select_all_freq">
			<arglist />
			<digest>
				Select entire buffer~ (frequency).
			</digest>
			<description>
				Select entire buffer~ (frequency).
			</description>
		</method>
		<method name="select_all_time">
			<arglist />
			<digest>
				Select entire buffer~ (time).
			</digest>
			<description>
				Select entire buffer~ (time).
			</description>
		</method>
		<method name="select_window">
			<arglist />
			<digest>
				Select current window (time and frequency).
			</digest>
			<description>
				Select current window (time and frequency).
			</description>
		</method>
		<method name="select_window_freq">
			<arglist />
			<digest>
				Select current window (frequency).
			</digest>
			<description>
				Select current window (frequency).
			</description>
		</method>
		<method name="select_window_time">
			<arglist />
			<digest>
				Select current window (time).
			</digest>
			<description>
				Select current window (time).
			</description>
		</method>
	</methodlist>


	<!--ATTRIBUTES-->
	<attributelist>
		<!--Behavior Category-->
		<attribute name='buffer_name' get='1' set='1' type='symbol' size='1'>
			<digest>
				buffer~ name
			</digest>
			<description>
				buffer~ name.
			</description>
		</attribute>
		<attribute name='buffer_chan' get='1' set='1' type='int' size='1'>
			<digest>
				buffer~ channel to view.
			</digest>
			<description>
				buffer~ channel to view:
				<ul>
					<li>
						<b>0 = mixdown of all channels</b>
					</li>
					<li>
						<b>1 = 1st channel</b> (default)
					</li>
					<li>
						<b>2 = 2nd channel</b>
					</li>
					<li>
						<b>etc...</b>
					</li>
				</ul>
			</description>
		</attribute>
		<attribute name='win_size' get='1' set='1' type='int' size='1'>
			<digest>
				FFT window size (samples).
			</digest>
			<description>
				FFT window size. Range 8 - 32768. Must be a power of 2. (default 2048 samples)
			</description>
		</attribute>
		<attribute name='win_zero_pad' get='1' set='1' type='int' size='1'>
			<digest>
				FFT window zero padding.
			</digest>
			<description>
				FFT window zero padding. Range 1 - 64. (default 1)
				<br />
				<b>Note</b>: Window zero padding is clamped based on the FFT window size, keeping the applied window size (i.e. window size * window zero padding) to less than or equal to 32768 samples.
				<br />
				<b>Warning</b>: Setting window zero padding high with large buffers can considerably incease computation time. Use with care.
			</description>
		</attribute>
		<attribute name='win_overlap' get='1' set='1' type='int' size='1'>
			<digest>
				FFT window overlap.
			</digest>
			<description>
				FFT window overlap. Range 1 - 64. (default 2)
				<br />
				<b>Warning</b>: Setting window overlap high with large buffers can considerably incease computation time. Use with care.
			</description>
		</attribute>
		<attribute name='win_type' get='1' set='1' type='int' size='1'>
			<digest>
				FFT window type.
			</digest>
			<description>
				FFT window type: <a href="https://en.wikipedia.org/wiki/Window_function">about</a>
				<ul>
					<li>
						<b>Rect (0)</b> - Rectangular window
					</li>
					<li>
						<b>Tri (1)</b> - Triangular window
					</li>
					<li>
						<b>Bart (2)</b> - Bartlett window
					</li>
					<li>
						<b>Sine (3)</b> - Sine window
					</li>
					<li>
						<b>Hann (4)</b> - Hanning window (default)
					</li>
					<li>
						<b>Hamm (5)</b> - Hamming window
					</li>
					<li>
						<b>Bart-Hann (6)</b> - Bartlett-Hanning window
					</li>
					<li>
						<b>Black (7)</b> - Blackman window
					</li>
					<li>
						<b>Nutt (8)</b> - Nuttal window
					</li>
					<li>
						<b>Black-Nutt (9)</b> - Blackman-Nuttal window
					</li>
					<li>
						<b>Black-Harr (10)</b> - Blackman-Harris window
					</li>
					<li>
						<b>Gaus (11)</b> - Gaussian window
					</li>
					<li>
						<b>Sqrt (12)</b> - Square Root window
					</li>
				</ul>
			</description>
		</attribute>
		<attribute name='mag_scale' get='1' set='1' type='int' size='1'>
			<digest>
				FFT magnitude scale.
			</digest>
			<description>
				FFT magnitude scale:
				<ul>
					<li>
						<b>Lin (0)</b> - Linear scaling
					</li>
					<li>
						<b>Mel (1)</b> - Mel scaling (default) <a href="https://en.wikipedia.org/wiki/Mel_scale">about</a>
					</li>
					<li>
						<b>Log (2)</b> - Logarithmic scaling
					</li>
					<li>
						<b>Bark (3)</b> - Bark scaling <a href="https://en.wikipedia.org/wiki/Bark_scale">about</a>
					</li>
					<li>
						<b>ERB (4)</b> - Equivalent Rectangular Bandwidth scaling <a href="https://en.wikipedia.org/wiki/Equivalent_rectangular_bandwidth">about</a>
					</li>
				</ul>
			</description>
		</attribute>
		<attribute name='mouse_mode' get='1' set='1' type='int' size='1'>
			<digest>
				Mouse mode.
			</digest>
			<description>
				Mouse mode:
				<ul>
					<li>
						<b>Select (0)</b> (default)
						<ol>
							<li>
								Click-and-drag to create selection rectangle (click on unselected portion to deselect).
							</li>
							<li>
								Click-and-drag a side or corner of the selection rectangle to resize it.
							</li>
							<li>
								Click-and-drag inside the selection rectangle to move it.
							</li>
							<li>
								Shift-click-and-drag inside the selection rectangle to resize symmetrically from the center.
								<ul>
									<li>
										Dragging right/left resizes larger/smaller on the time axis (horizontally).
									</li>
									<li>
										Dragging up/down resizes larger/smaller on the frequency axis (vertically).
									</li>
								</ul>
							</li>
						</ol>
					</li>
					<li>
						<b>Move (1)</b>
						<ol>
							<li>
								Click-and-drag to adjust the displayed time window.
								<ul>
									<li>
										Dragging up/down zooms in/out on the time axis (horizontally).						
									</li>
									<li>
										Dragging left/right scrolls left/right on the time axis (horizontally).
									</li>
								</ul>
							</li>
							<li>
								Shift-click-and-drag to adjust the displayed frequency window.
								<ul>
									<li>
										Dragging right/left zooms in/out on the frequency axis (vertically).
									</li>
									<li>
										Dragging up/down scrolls up/down on the frequency axis (vertically).
									</li>
								</ul>
							</li>
						</ol>
					</li>
				</ul>
			</description>
		</attribute>

		<!--Display Category-->
		<attribute name='mag_min' get='1' set='1' type='float' size='1'>
			<digest>
				FFT minimum magnitude (dB).
			</digest>
			<description>
				FFT minimum magnitude sets the magnitude that maps to the coldest color in the active <b>color_scheme</b>. All magnitudes below this threshold will visually clamp to the coldest color. Range -120 - 120. (default -100 dB)
			</description>
		</attribute>
		<attribute name='mag_max' get='1' set='1' type='float' size='1'>
			<digest>
				FFT maximum magnitude (dB).
			</digest>
			<description>
				FFT maximum magnitude sets the magnitudes that maps to the hottest color in the active <b>color_scheme</b>. All magnitudes above this threshold will visually clamp to the hottest color. Range -120 - 120. (default 0 dB)
			</description>
		</attribute>
		<attribute name='freq_text' get='1' set='1' type='int' size='1'>
			<digest>
				Frequency text on/off.
			</digest>
			<description>
				Frequency text on/off. (default 1)
			</description>
		</attribute>
		<attribute name='time_text' get='1' set='1' type='int' size='1'>
			<digest>
				Time text on/off.
			</digest>
			<description>
				Time text on/off. (default 1)
			</description>
		</attribute>
		<attribute name='textsize' get='1' set='1' type='int' size='1'>
			<digest>
				Text size.
			</digest>
			<description>
				Text size. Range 1 - 72. (default 12)
			</description>
		</attribute>
		<attribute name='selection_linewidth' get='1' set='1' type='int' size='1'>
			<digest>
				Selection box line width.
			</digest>
			<description>
				Selection box line width. Range 1 - 20. (default 2)
			</description>
		</attribute>

		<!--Color Category-->
		<attribute name='color_scheme' get='1' set='1' type='int' size='1'>
			<digest>
				Color scheme
			</digest>
			<description>
				Color scheme:
				<ul>
					<li>
						<b>Custom (0)</b> (default)
					</li>
					<li>
						<b>Roseus (1)</b>
					</li>
					<li>
						<b>Classic (2)</b>
					</li>
					<li>
						<b>Greyscale (3)</b>
					</li>
					<li>
						<b>Custom - Inverted (4)</b>
					</li>
					<li>
						<b>Roseus - Inverted (5)</b>
					</li>
					<li>
						<b>Classic - Inverted (6)</b>
					</li>
					<li>
						<b>Greyscale - Inverted (7)</b>
					</li>
				</ul>
			</description>
		</attribute>
		<attribute name='custom_color1' get='1' set='1' type='rgba' size='1'>
			<digest>
				Custom color scheme: color 1 (lowest magnitude).
			</digest>
			<description>
				Custom color scheme: color 1 (lowest magnitude). (default 0. 0. 0. 1.)
			</description>
		</attribute>
		<attribute name='custom_color2' get='1' set='1' type='rgba' size='1'>
			<digest>
				Custom color scheme: color 2.
			</digest>
			<description>
				Custom color scheme: color 2. (default 0.361 0.039 0.706, 1.)
			</description>
		</attribute>
		<attribute name='custom_color3' get='1' set='1' type='rgba' size='1'>
			<digest>
				Custom color scheme: color 3.
			</digest>
			<description>
				Custom color scheme: color 3. (default 0.851 0.118 0.298 1.)
			</description>
		</attribute>
		<attribute name='custom_color4' get='1' set='1' type='rgba' size='1'>
			<digest>
				Custom color scheme: color 4.
			</digest>
			<description>
				Custom color scheme: color 4. (default 1. 0.486 0. 1.)
			</description>
		</attribute>
		<attribute name='custom_color5' get='1' set='1' type='rgba' size='1'>
			<digest>
				Custom color scheme: color 5 (highest magnitude).
			</digest>
			<description>
				Custom color scheme: color 5 (highest magnitude). (default 1. 1. 1. 1.)
			</description>
		</attribute>
		<attribute name='selection_linecolor' get='1' set='1' type='rgba' size='1'>
			<digest>
				Selection box line color.
			</digest>
			<description>
				Selection box line color. (default 0. 1. 0. 1.)
			</description>
		</attribute>
		<attribute name='textcolor' get='1' set='1' type='rgba' size='1'>
			<digest>
				Text color.
			</digest>
			<description>
				Text color. (default 0.4 0.6 0.4 1.)
			</description>
		</attribute>
	</attributelist>


	<!--RELATED-->
	<seealsolist>
		<seealso name="spectrogram.colorbar"/>
		<seealso name="buffer~"/>
		<seealso name="waveform~"/>
	</seealsolist>


	<misc name="Input">
		<entry name="float">
			<description>
				1st inlet: The display start time in milliseconds.
				<br />
				<br />
				2nd inlet: The display length in milliseconds.
				<br />
				<br />
				3rd inlet: The display low frequency in hertz.
				<br />
				<br />
				4th inlet: The display high frequency in hertz.
				<br />
				<br />
				5th inlet: The start time of the selection range in milliseconds.
				<br />
				<br />
				6th inlet: The end time of the selection range in milliseconds.
				<br />
				<br />
				7th inlet: The low frequency of the selection range in hertz.
				<br />
				<br />
				8th inlet: The high frequency of the selection range in hertz.
			</description>
		</entry>
		<entry name="list">
			<description>
				9th inlet: Link In. See description for 9th outlet.
			</description>
		</entry>
	</misc>

	<misc name="Output">
		<entry name="float">
			<description>
				1st outlet: The display start time in milliseconds.
				<br />
				<br />
				2nd outlet: The display length in milliseconds.
				<br />
				<br />
				3rd outlet: The display low frequency in hertz.
				<br />
				<br />
				4th outlet: The display high frequency in hertz.
				<br />
				<br />
				5th outlet: The start time of the selection range in milliseconds.
				<br />
				<br />
				6th outlet: The end time of the selection range in milliseconds.
				<br />
				<br />
				7th outlet: The low frequency of the selection range in hertz.
				<br />
				<br />
				8th outlet: The high frequency of the selection range in hertz.
			</description>
		</entry>
		<entry name="list">
			<description>
				9th outlet: This outlet sends a list that contains values from the 1st through 8th outlets, and is used for linking multiple <o>spectrogram~</o> objects together (i.e. each object displaying a different channel). Any update to an inlet or mouse interaction inside the body of the <o>spectrogram~</o> object results in a list being sent out of this outlet.
			</description>
		</entry>
		<entry name="list">
			<description>
				10th outlet: This outlet sends a list that contains the data at the mousedown/mousedrag point in the spectrogram. The list is formatted as: Time (ms) Frequency (Hz) Magnitude (dB).
			</description>
		</entry>
	</misc>
</c74object>
