//--------------------------------------------------------------------------------------
// wavのヘッダーを書き換えて指定音階のデータを作る
//--------------------------------------------------------------------------------------

#import "wavMusic.h"
#import "adpcm.h"	// storeWavHeader()
#include <math.h>
#include "mml.h"

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

// octave:scaleを喜寿運・・・ではなくて、基準にして音程作り出すためのサンプリングレート表
// WAVだけに許された強引な技のため
// ファイルのサンプリングレート : rate=44100,30000,...
// octave : ファイルのオクターブ
// scale  : ファイルの音階(SCALE_C〜SCALE_B)
void makeSamplingTable(int rate,int octave,int scale,ULong rateTable[MUSIC_OCTAVES][MUSIC_SCALES])
{
	printFunc();
	
	// 2の12乗根
	float bai=log10(2);	//printf("log(2)=%f\n",bai);
	bai=bai/12.0;	 	//printf("/12=%f\n",bai);
	bai=pow(10,bai); 	//printf("10^=%f\n",bai);
	
	// 累積演算誤差を避けるため1オクターブで1回基準を変える
	float baseRateOctave[MUSIC_OCTAVES];
	float rate0=(float)rate;
	int i;
	// 基準より低い方
	for (i=octave;i>=0;i--) {
		baseRateOctave[i]=rate0;
		rate0/=2.0;
	}
	// 基準より高い方
	for (i=octave+1;i<MUSIC_OCTAVES;i++) {
		rate*=2.0;
		baseRateOctave[i]=rate;
	}
	/* rate=44100,octave=3の時
	={
		5512.5,	// O0
		11025,
		22050,
		44100,	// O3
		88200,
		176400,
		352800,
		705600,
		1411200	// O8
	};
	 */
	
	// 基準サンプリングレート計算
	int oct;
	for (oct=0;oct<MUSIC_OCTAVES;oct++) {
		// 累積演算誤差を避けるためオクターブ別にリセットする
		float baseRate=baseRateOctave[oct];
		int i;
		for (i=scale;i>=0;i--) {
			rateTable[oct][i]=(ULong)baseRate;
			baseRate/=bai;
		}
		baseRate=baseRateOctave[oct];
		for (i=scale+1;i<MUSIC_SCALES;i++) {
			baseRate*=bai;
			rateTable[oct][i]=(ULong)baseRate;
		}
	}
}

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

// wavデータのヘッダーを指定note用にする
void remakeWaveHeaderForNote(UByte *wavBuff,int octave,int scale,ULong rateTable[MUSIC_OCTAVES][MUSIC_SCALES])
{
	printFunc();
	nslog(@"wavBuff=%p",wavBuff);
	
#ifdef DEBUG
	{
	UByte *p=wavBuff;
	for (int i=0;i<sizeof(RIFF_WAVE_Chunk);i++) {
		UByte c=*p++;
		if (isalnum(c)) fprintf(stdout,"'%c',",c);
		else fprintf(stdout,"%02x,",c);
	}
	fprintf(stdout,"\n");
	}
#endif
	nslog(@"オクターブ%d %s",octave,scale_string[scale]);
	
	// ヘッダー部を書き換える
	storeWavHeader(wavBuff,-1,rateTable[octave][scale]);
	

#ifdef DEBUG
	{
	UByte *p=wavBuff;
	for (int i=0;i<sizeof(RIFF_WAVE_Chunk);i++) {
		UByte c=*p++;
		if (isalnum(c)) fprintf(stdout,"'%c',",c);
		else fprintf(stdout,"%02x,",c);
	}
	fprintf(stdout,"\n");
	}
#endif

}

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

// 音声ファイルの種類を判別し、基本情報を取得する
int checkSoundType(NSString *path,
				   int *rate,		 // サンプリングレート;ADPCM/iOSファイルの時は予め設定しておくこと(この中では使わないけど)
				   int *multiple	 // 標準音声倍率
				   )
{
	printFunc();
	nslog(@"path=%@",path);

	*multiple=1; 	// 音声倍率
	int rateNo=NO_ADPCM; // X68系でない印

	if ([[path pathExtension]caseInsensitiveCompare:@"pcm"]==NSOrderedSame) { // 大文字小文字を無視して比較
		// .pcmならADPCMモードで初期設定
		// *rateは変更しない
		rateNo=FILE_ADPCM;
	}
	else
	if ([[path pathExtension]caseInsensitiveCompare:@"m44"]==NSOrderedSame) { // 大文字小文字を無視して比較
		*rate=44100;
		rateNo=FILE_M44;
	}
	else
	if ([[path pathExtension]caseInsensitiveCompare:@"p16"]==NSOrderedSame) { // 大文字小文字を無視して比較
		*rate=15625;
		*multiple=16; // P16は音量が小さいので大きくする;とりあえず固定しておく
		rateNo=FILE_P16;
	}
	else
	if ([[path pathExtension]caseInsensitiveCompare:@"m30"]==NSOrderedSame) { // 大文字小文字を無視して比較
		*rate=30000;
		*multiple=16;
		rateNo=FILE_M30;
	}
	nslog(@"rate=%d/multiple=%d/rateNo=%d",*rate,*multiple,rateNo);
	return rateNo;
}
				   
//--------------------------------------------------------------------------------------
