//--------------------------------------------------------------------------------------
// music音色クラス : 1音の情報
//--------------------------------------------------------------------------------------

#import "MusicTone1.h"
#import "adpcm.h"
#import "FileControl2.h"
#import "libs.h"
#import "malloc2.h"
#import "AudioPlay.h"
#import "wavMusic.h"

@implementation MusicTone1

//--------------------------------------------------------------------------------------

-(void)initialize:(int)rate octave:(int)octave scale:(int)scale floop:(BOOL)floop
{
	// サンプリングレート表を作る
	makeSamplingTable(rate,octave,scale,rateTable);
	//
	_floopSound=floop;
	//
	_samplingRate=rate;
}

// 音色ファイルを設定する
// X68系ファイルもしくはWAVのみ指定可能(ヘッダーを書き換えるため)
// ファイルのサンプリングレート : rate=44100,30000,... ; ADPCMまたはWAVファイルで有効
// octave : ファイルのオクターブ
// scale  : ファイルの音階(SCALE_C〜SCALE_B)
// floop  : 連続音の時YES(ループして音を発生し続けるかどうか);基本的に管楽器や弓で弾く楽器はYES、弾く系（鍵盤・打・弦を弾く)はNO
// error  : エラーを返す
-(instancetype)initWithFile:(NSString *)fname rate:(int)rate octave:(int)octave scale:(int)scale floop:(BOOL)floop ferror:(BOOL *)ferror
{
	printSelf();
	nslog(@"ファイル名=%@/rate=%dHz",fname,rate);
	_toneName=fname;
	
	self=[super init];
	if (self!=nil) {
		BOOL ferr=NO;
		NSString *path=getResourceOrSavedataPath(fname);
		if (path==nil) {
			// ファイルが見つからない
			nslog2(@"ファイルが見つからない:path=%@",path);
			ferr=YES;
		} else {
			_data=nil; // 前のがあったら開放
			SLong bufsize;
			UByte *wavbuff;
			int multiple;	 // 標準音声倍率
			int rateNo=checkSoundType(fname,&rate,&multiple);
			switch (rateNo) {
				case NO_ADPCM: // WAVのみ
					if ([[fname pathExtension]caseInsensitiveCompare:@"WAV"]!=NSOrderedSame) {
						nslog2(@"WAVファイルでない:path=%@",path);
						ferr=YES;
					}
#ifdef USE_MUTABLEDATA
					_data=[NSMutableData dataWithContentsOfFile:path];
#else
					_data=[NSData dataWithContentsOfFile:path];
#endif
					break;
				
				default: // ADPCMのサンプリングレートはいろいろ
					// rateはrateNo(サンプリングレート番号)
					wavbuff=adpcmFile2WavMem(nsStringTocString(path),rate		    ,&bufsize);
					goto L1;
					
				case FILE_P16:
				case FILE_M30:
				case FILE_M44:
					// rate2はサンプリングレート(Hz)
					wavbuff=pcmFile2WavMem(  nsStringTocString(path),rate,0,multiple,&bufsize);
				L1:;
					if (wavbuff==NULL) {
						nslog2(@"変換できない");
						ferr=YES;
					} else {
#ifdef USE_MUTABLEDATA
						_data=[NSMutableData dataWithBytes:wavbuff length:bufsize];
#else
						_data=[NSData dataWithBytes:wavbuff length:bufsize];
#endif
						free2(wavbuff);
					}
					break;
			} // switch
			if (!ferr && _data==nil) {
				// ファイルが見つからない時もこちら
				nslog2(@"ファイルが見つからない(NSData)");
				ferr=YES;
			}
		}
		if (ferr) { // 内部でエラー発生時
			// selfの開放もしておく必要がある(そうしないとメモリリークを起こす)
			self=nil;
		} else {
			// 正常なときは音情報を初期化
			[self initialize:rate octave:octave scale:scale floop:floop];
		}
		if (ferror!=NULL) *ferror=ferr;
	} // if (self)
	return (self);
}

-(instancetype)initWithFile:(NSString *)fname rate:(int)rate octave:(int)octave scale:(int)scale floop:(BOOL)floop
{
	BOOL ferror;
	return [self initWithFile:fname rate:rate octave:octave scale:scale floop:floop ferror:&ferror];
}

//--------------------------------------------------------------------------------------

// wavデータのヘッダーを指定note用にする
-(void)remakeWaveHeaderForNote:(UByte *)wavBuff octave:(int)octave scale:(int)scale
{
	printSelf();
	remakeWaveHeaderForNote(wavBuff, octave, scale,rateTable);
}

//--------------------------------------------------------------------------------------

// デバッグ用
-(NSString *)description
{
	return [NSString stringWithFormat:@"ファイル名=%@,サンプリングレート=%d,ループ=%d",[_toneName lastPathComponent],_samplingRate,_floopSound];
}

//--------------------------------------------------------------------------------------

@end
