//
//  Spectrogram.h
//  Capo
//
//  Created by Christopher Liscio on 11/6/09.
//  Copyright 2009 SuperMegaUltraGroovy. All rights reserved.
//

#import <Foundation/Foundation.h>

@protocol SpectrogramDelegate;
@protocol SpectrogramDisplay;
@class SpectrogramImageSegment;
@class SMUGRealMatrix;

@interface Spectrogram : NSObject <NSCoding>

/** Initializes a new Spectrogram object.
 
 @b Designated Initializer.
 
 @param inSampleRate Specifies the sample rate used when creating the spectrogram (and not the underlying audio file)
 @param inSkipLength Specifies the distance, in samples, between successive spectrogram slices
 @param binsPerNote Specifies the number of bins of data for each note. Expected to be @b odd.
 @param inStartNote Specifies the starting MIDI note of each spectrogram slice
 @param inEndNote Specifies the last MIDI note of each spectrogram slice
 
 */
- (instancetype)initWithSampleRate:(uint64_t)inSampleRate skipLength:(uint32_t)inSkipLength binsPerNote:(uint32_t)binsPerNote startNote:(uint8_t)inStartNote endNote:(uint8_t)inEndNote;

#pragma mark Spectrogram Note Range
@property(nonatomic, readonly, assign) uint8_t startNote;
@property(nonatomic, readonly, assign) uint8_t endNote;

#pragma mark Data Resolution
@property(nonatomic, readonly, assign) uint64_t sampleRate;
@property(nonatomic, readonly, assign) uint32_t skipLength;
@property(nonatomic, readonly, assign) uint32_t blockLength;
@property(nonatomic, readonly, assign) uint32_t binsPerNote;

#pragma mark Spectrogram Size
@property(nonatomic, readonly, assign) uint64_t frequencyBinCount;
@property(nonatomic, assign) uint64_t length;

#pragma mark Delegation
@property (nonatomic, readwrite,weak) id<SpectrogramDelegate> delegate;
@property (nonatomic, readwrite,weak) id<SpectrogramDisplay> display;

#pragma mark Spectrum data
@property(nonatomic, readonly, retain) SMUGRealMatrix *matrixRepresentation;

#pragma mark API
/** Adds a block of Constant Q data to the spectrogram
 
 @param inBlock The block of Constant Q data. Rows = # of slices, columns = # of frequency bins.
 @param inIndex The index (in slice space, not block space) where the block will be inserted.
 
 */
- (void)insertConstantQBlock:(SMUGRealMatrix *)inBlock atIndex:(uint64_t)inIndex;

@end

@protocol SpectrogramDelegate <NSObject>
// Notifies the delegate that a request for spectrogram image segments has been
// fulfilled.  The NSArray contains a list of SpectrogramImageSegment objects.
- (void)spectrogram:(Spectrogram*)spectrogram addedImageSegmentAtIndex:(uint64_t)index;
- (void)spectrogramDidFinishProcessing:(Spectrogram*)spectrogram;
@end

@protocol SpectrogramDisplay <NSObject>
// Notifies the delegate that a request for spectrogram image segments has been
// fulfilled.  The NSArray contains a list of SpectrogramImageSegment objects.
- (void)spectrogram:(Spectrogram*)spectrogram invalidateDisplayInSampleRange:(NSRange)range;
@end

extern NSString *SpectrogramDidProcessBlockNotification;
extern NSString *SpectrogramDidFinishProcessingNotification;