画像処理アプリのios6対応2012/10/03 20:14

数年前に マイナビの記事 を参考に作った 画像処理アプリ が、ios6になってクラッシュするようになったとのユーザーレビューがあったので、修正。
- (void)actionSheet:(UIActionSheet*)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex { . . . . . . . . . . . . . . . . . . . . . . . . //イメージピッカーを表示する //[self presentModalViewController:imagePicker animated:YES]; // 修正→  [self presentViewController:imagePicker animated:YES completion:^{ NSLog(@"complete"); }]; } // 選択完了 //- (void)imagePickerController:(UIImagePickerController*)picker // didFinishPickingImage:(UIImage*)image // editingInfo:(NSDictionary*)editingInfo // 修正→ - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)editingInfo { //イメージピッカーを隠す //[self dismissModalViewControllerAnimated:YES]; // 修正→ [self dismissViewControllerAnimated:YES completion:^ { NSLog(@"complete"); }];   // 画像処理など   . . . . . . . . . . . . . . . .   . . . . . . . . . . . . . . . . } // キャンセル - (void)imagePickerControllerDidCancel:(UIImagePickerController*)picker { //イメージピッカーを隠す //[self dismissModalViewControllerAnimated:YES]; // 修正→ [picker dismissViewControllerAnimated:YES completion:^{ NSLog(@"complete"); }]; }

ATmegaの読み方2012/04/02 11:24

ATmegaはどう発音するのが正しいのでしょうか?個人的に心のなかでは、「アルデュイーノ」風に「アトミーガ」な感じだったのですが、本当はどうなのかな?
調べたらAVRのファンサイトで投票が行われていました。(英語ネイティブの間でも意見が分かれているようです。)
日本人としてはどう読むべきなのか。。。

・エーティーメガ  41%
・アトメガ      36%
・メガ(ATは発音しない) 20%
・エム  1%
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=84575&view=previous

VS1053BでMIDIシンセサイザ2009/08/26 14:01

回路図
MIDIデコーダ機能のあるVS1053Bを使ってMIDIシンセサイザーを作り始めました。とりあえず音を出すだけなら、マイコン(PIC24F)のUART出力をVS1053BのRX端子につなげばOKです。
プログラムはごく基本的なもので、whileループで約1秒ごとにピアノの”ド”の音が鳴るようになっています。

#include 
#include 

_CONFIG1( JTAGEN_OFF & GCP_OFF & GWRP_OFF &	BKBUG_OFF
	 & COE_OFF & ICS_PGx1& FWDTEN_OFF ) 
_CONFIG2( IESO_OFF & FNOSC_FRCPLL & FCKSM_CSDCMD & OSCIOFNC_ON & IOL1WAY_OFF & POSCMOD_NONE )

//********************
// INIT_DATA
//********************
void init_data(void){
}

//**************************
// MAIN
//**************************
int main(void){
	int i,j;
	
	CLKDIV = 0;			// クロック1/1
	/* 入出力ポート設定  */
	AD1PCFG = 0xFFFE;	// すべてデジタル(AN0をのぞく)
	//TRISA = 0xffff;		//portA pa1 output
	TRISB = 0xfffe;		//portB all input pb0 output
	
	RPOR0bits.RP0R = 3;		//UART1 TX to RP0
	//UART1初期設定
	U1BRG = 31;
	U1MODE = 0b1000100000000000;
	U1STA = 0b0000010000000000;
	
	//init_data();
	while(U1STAbits.UTXBF==1);
	U1TXREG = 0xC0;
	while(U1STAbits.UTXBF==1);
	U1TXREG = 0x00;
	/**************** メインループ **********/
	while(1){
		while(U1STAbits.UTXBF==1);
		U1TXREG = 0x90;
		while(U1STAbits.UTXBF==1);
		U1TXREG = 0x3C;
		while(U1STAbits.UTXBF==1);
		U1TXREG = 0x40;
		for(i=0;i<30000;i++){for(j=0;j<100;j++){}}
	}
}

dsPICでボコーダ2009/08/17 12:08

以前PC用につくったボコーダプログラムをdsPIC用に書き直してみました。
固定小数点のプログラミングがなかなかうまくいかず非常に苦労しました。dsPIC(C30コンパイラ)にはfractionalという固定小数点型があって、これを利用すると積和演算などが高速に行えるということなのですが、計算途中でオーバフローを起こしているらしく、うまく使えませんでした。結局long int型を使ってなんとか動かすことができました。
計算速度の関係でサンプリング周波数は4kHz、フィルタのタップ数は4としています。そのためボコーダとしては最低の性能になっていると思います。何と発音しているかは識別できません。タップ数を増やせないのが致命的です。
#include 
#include "adc10.h"
#include "timer.h"
#include "dsp.h"

// Configuration bits--------------------------------------------------------
_FOSC(CSW_FSCM_OFF & FRC_PLL16);   //FRC with 16xPLL oscillator, Failsafe clock off
_FWDT(WDT_OFF);                  //Watchdog timer disabled
_FBORPOR(PBOR_OFF & MCLR_EN);    //Brown-out reset disabled, MCLR reset enabled
_FGS(CODE_PROT_OFF);             //Code protect disabled

//// Setup Data for 10bits A/D Converter
//// AN0のみサンプル Tad=200nsec@40MHz
//// タイマ3で自動スタート, 自動スキャン無し
unsigned int ValueADCON1 = ADC_MODULE_ON & ADC_IDLE_STOP & ADC_FORMAT_INTG &
			ADC_CLK_TMR & ADC_AUTO_SAMPLING_ON & ADC_SAMPLE_INDIVIDUAL & 
			ADC_SAMP_OFF;
unsigned int ValueADCON2 = ADC_VREF_AVDD_AVSS & ADC_SCAN_OFF & ADC_CONVERT_CH0
			 & ADC_SAMPLES_PER_INT_1 & ADC_ALT_BUF_OFF & ADC_ALT_INPUT_OFF;
unsigned int ValueADCON3 = ADC_SAMPLE_TIME_1 & ADC_CONV_CLK_SYSTEM 
			 & ADC_CONV_CLK_2Tcy;
unsigned int ValueADPCFG = ENABLE_AN0_ANA & ENABLE_AN1_ANA & ENABLE_AN2_ANA
			 & ENABLE_AN3_ANA;
unsigned int ValueADCSSL = 0;
unsigned int Channel0 = ADC_CH0_POS_SAMPLEA_AN0 & ADC_CH0_NEG_SAMPLEA_NVREF;

// Definitions---------------------------------------------------------------
#define BUF_LEN 256
#define LPC_ORDER 4

//グローバル変数-----------------------------------------------------------------
long int lpc[LPC_ORDER+1];
long int in_buf[BUF_LEN];
long int out_buf[LPC_ORDER+1];
int ix_buf = 0;
int ix_read = 0;
int ix_write = 0;
int ratio = 0;
int s_cnt = 0;		//音程用
int zero_cnt = 0;
unsigned char sound = 0;

//// タイマ1割り込み処理(16k/256/2Hz)
void _ISR _T1Interrupt(void)
{
	int n,m,k;
	int i,j;
	long int r[LPC_ORDER+1];
	long int a[LPC_ORDER+1];
	long int b[LPC_ORDER+1];
	long int alfa;
	long int km,alfam,t;
	
	IFS0bits.T1IF = 0;
	
	//AutoCorrelation
	for(i=0; i<=LPC_ORDER; i++){
		r[i] = 0;
		for(j=0; j<(BUF_LEN-i); j++){
			r[i] += ((in_buf[j] * in_buf[j+i])>>8);
		}
	}

	//Levinson-Durbin
	a[0] = 1<<8;
	alfam = r[0];
	for(m=1; m<=LPC_ORDER; m++){
		t = r[m];
		for(k=1; k<=m-1; k++){
			t = t + ((r[m-k]*a[k])>>8);
		}
		if(alfam==0)alfam=1;
		km = -((t<<8)/alfam);
		for(k=1; k<=m-1; k++){
			b[k] = a[m-k];
		}
		for(k=1; k<=m-1; k++){
			a[k] = a[k] + ((km*b[k])>>8);
		}
		a[m] = km;
		alfam = (alfam*((1<<8) - ((a[m]*a[m])>>8)))>>8;
	}
	alfa = alfam;
	for(i=0; i0; i--){
		out_buf[i-1] = 0;
	}
}

//// ADC割り込み処理(約16kHz)
void _ISRFAST _ADCInterrupt(void)
{
	long int tone;
	fractional SigIn;
	long int out;
	int d_out;
	int i;
	int on;
		
	IFS0bits.ADIF = 0;
	
	//音程生成
	s_cnt++;
	if(s_cnt==16){
		s_cnt = 0;
		tone=1<<7;
	}else{
		tone=0;
	}
	
	//AD input
	in_buf[ix_buf] = (long int)(ReadADC10(0)>>2)-128;
	if(in_buf[ix_buf]<32 && in_buf[ix_buf]>-32){
		in_buf[ix_buf]=0;
		zero_cnt++;
		//sound = 0;
	}else{
		sound = 1;
		zero_cnt = 0;
	}		
	if(zero_cnt>10){sound = 0;}
	if(sound==0){tone = 0;}
	ix_buf++;
	if(ix_buf>=BUF_LEN){
		ix_buf = 0;
	}	
	
	
	//合成フィルタ
	out = -(	((lpc[0] * out_buf[0])>>8)
					+ ((lpc[1] * out_buf[1])>>8)
					+ ((lpc[2] * out_buf[2])>>8)
					+ ((lpc[3] * out_buf[3])>>8)
					)
					+ tone;
	for(i=LPC_ORDER; i>0; i--){
		out_buf[i] = out_buf[i-1];
	}
	out_buf[0] = out;

	//出力処理
	d_out = 0x7000 | ((0x8000 + (out<<7))>>4);
	LATEbits.LATE0 = 0;  //CS=0
  	for(i=0; i<16; i++){
    	if(((d_out << i) & 0x8000) != 0){
      		LATEbits.LATE2 = 1;  //SDI=1
    	}else{
      		LATEbits.LATE2 = 0;  //SDI=0
    	}
    	LATEbits.LATE1 = 1;  //SCK=1
    	LATEbits.LATE1 = 0;  //SCK=0
  	}
  	LATEbits.LATE0 = 1;  //CS=1
  	LATEbits.LATE3 = 0;  //LDAC=0
  	LATEbits.LATE3 = 1;  //LDAC=0
}

//main-----------------------------------------------------------------------
int main(void)
{
	int i,j;
	int data;
	
//Initialize
	LATE = 0x0000;	//

// Setup Port
	TRISB = 0x01;	//AN0 input
	TRISE = 0x00;	//all output
	SRbits.IPL=4;	//Set CPU priority Set core priority level to 4

// Setup ADC10		
	OpenADC10(ValueADCON1, ValueADCON2, ValueADCON3, ValueADPCFG, ValueADCSSL);
	SetChanADC10(Channel0);
	ConfigIntADC10(ADC_INT_PRI_7 & ADC_INT_ENABLE);

// タイマ1設定 サンプリング周期 4/256/2kHz = (7.37MHz*16/4)/256/3684
	OpenTimer1(T1_ON & T1_GATE_OFF & T1_PS_1_256 & T1_SOURCE_INT,3684*2-1);
	IPC0bits.T1IP = 5;
	IFS0bits.T1IF = 0;
	IEC0bits.T1IE = 1;

// タイマ3設定 サンプリング周期 4kHz = (7.37MHz*16/4)/1842
	OpenTimer3(T3_ON & T3_GATE_OFF & T3_PS_1_1 & T3_SOURCE_INT,1842*4-1);

// init mcp4922
	LATEbits.LATE0 = 1;	//CS
	LATEbits.LATE1 = 0;	//SCK
	LATEbits.LATE2 = 0;	//SDI
	LATEbits.LATE3 = 1;	//LDAC
	
//Idle Loop
	while (1){};
}

c言語ではじめる音のプログラミング2009/07/21 23:09

● 読書記録
c言語ではじめる音のプログラミング 青木直史著
★★★★★
dsPICを使ってボイスチェンジャーを作ってみようと思い参考書として購入しました。いろいろなデジタルサウンドイフェクトの方法がサンプルプログラムとともに解説されています。いずれもPC上でwaveファイルを変換するかたちになっています。全部読んだわけではありませんが、説明もわかりやすくプログラムも著者のサイトからDLできるので難なく理解できました。windowsのサウンドレコーダを使って自分なりに試してみることもできると思います。
この著者は割とはずれがないですね。北大の先生のようですが、一般人の知りたいところのツボを押さえている感じです。
応用としてボコーダ(人の声と楽器音の合成?)を作ってみました。プログラムをのせておきます。線形予測+合成フィルタという構成です。フィルタ生成用の音源はニュース音声、楽音は250Hzのインパルス波形です。現状まだ無音部でも楽音が鳴ってしまっています。

#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include "wave.h"

#define BUF_LEN		320
#define LPC_ORDER	14

int main(void)
{
	MONO_PCM pcm0, pcm1, pcm2;
	int buf_cnt=0;
	int n,m,k;
	int i,j;
	int start;
	double in_buf[BUF_LEN];
	double m_buf;
	double out_buf[LPC_ORDER+1];
	double r[LPC_ORDER];
	double a[LPC_ORDER];
	double b[LPC_ORDER];
	double alfa;
	double km,alfam,t;
	double rnd;

	mono_wave_read(&pcm0, "speech.wav");
	
	pcm2.fs = pcm0.fs; /* 標本化周波数 */
	pcm2.bits = pcm0.bits; /* 量子化精度 */
	pcm2.length = pcm0.length; /* 音データの長さ */
	pcm2.s = calloc(pcm2.length, sizeof(double)); /* メモリの確保 */

	for(i=0; i=BUF_LEN)buf_cnt = 0;
		//機械音生成
		if(n%64==0){
			m_buf=1;
		}else{
			m_buf=0;
		}
		
		if(n%BUF_LEN==0 && n>0)
		{
			//LPC計算
			//自己相関関数( <- 8/5修正)
			for(i=0; i= BUF_LEN)
		{
			out_buf[0] = -(a[1] * out_buf[1]
					+ a[2] * out_buf[2]
					+ a[3] * out_buf[3]
					+ a[4] * out_buf[4]
					+ a[5] * out_buf[5]
					+ a[6] * out_buf[6]
					+ a[7] * out_buf[7]
					+ a[8] * out_buf[8]
					+ a[9] * out_buf[9]
					+ a[10] * out_buf[10]
					+ a[11] * out_buf[11]
					+ a[12] * out_buf[12]
					+ a[13] * out_buf[13]
					+ a[14] * out_buf[14])
					+m_buf;
			//出力の配列をプッシュする
			for(i=LPC_ORDER; i>0; i--){
				out_buf[i] = out_buf[i-1];
			}
			pcm2.s[n] = out_buf[0];
		}else{
			pcm2.s[n] = in_buf[0];
		}
	}
	mono_wave_write(&pcm2, "result.wav");
	free(pcm0.s);
	free(pcm2.s);
  
	return 0;
}