課題で出されたのですが…

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
eustia

課題で出されたのですが…

#1

投稿記事 by eustia » 13年前

このままコンパイルすると、music6~musicの順番に音が流れるようになってしまうのです。
同時に流れるようにするにはどうすればよいのでしょうか、教えてください。
(ファイル名や、音の打ち込みは途中ですが)
お願いします。

#include <stdio.h>
#include <string.h>
#define _USE_MATH_DEFINES
#include <math.h>

#define CHANNEL 1
#define BIT 16
#define RATE 44100

char head[44];
double p[44100 * 300];
short data[44100 *300];
char onshoku[65536];
int onshokurate_table[4] = {44100, 33075, 22050, 11025};
int onshokusize, onshokuloopsize, onshokurate;

#define s0 0
#define g1 48.9994
#define g11 51.9131
#define a1 55
#define a11 58.2705
#define b1 61.7354
#define c2 65.4064
#define c21 69.2957
#define d2 73.4192
#define d21 77.7817
#define e2 82.4069
#define f2 87.3071
#define f21 92.4986
#define g2 97.9989
#define g21 103.8262
#define a2 110
#define a21 116.5409
#define b2 123.4708
#define c3 130.8128
#define c31 138.5913
#define d3 146.8324
#define d31 155.5635
#define e3 164.8138
#define f3 174.6141
#define f31 184.9972
#define g3 195.9977
#define g31 207.6523
#define a3 220
#define a31 233.0819
#define b3 246.9417
#define c4 261.6256
#define c41 277.1826
#define d4 293.6648
#define d41 311.1270
#define e4 329.6276
#define f4 349.2282
#define f41 369.9944
#define g4 391.9954
#define g41 415.3047
#define a4 440
#define a41 466.1638
#define b4 493.8833
#define c5 523.2511
#define c51 554.3653
#define d5 587.3295
#define d51 622.2540
#define e5 659.2551
#define f5 698.4565
#define f51 739.9888
#define g5 783.9909
#define g51 830.6094
#define a5 880
#define a51 932.3275
#define b5 987.7666
#define c6 1046.5023
#define c61 1108.7305
#define d6 1174.6591
#define d61 1244.5079
#define e6 1318.5102
#define f6 1396.9129
#define f61 1479.9777
#define g6 1567.9817
#define g61 1661.2188

#define WAVFILENAME ".wav"
#define ONSHOKUFILE "fpv/03PIANO1.FPV"
#define TEMPO 183
double music[]={e5,0.5, d51,1, b5,2, e5,0.5};

double music2[]={b4,0.5, s0,1, f51,2, s0,0.5};

double music3[]={g4,0.5, s0,1, d51,2, s0,0.5};

double music4[]={b3,4};

double music5[]={f3,4};

double music6[]={b2,4};



void set_wav_header(char head[], int cnt)
{
int blocksize=(BIT/8)*CHANNEL;
int size=blocksize*cnt;
memcpy(&head[0],"RIFF", 4);
*(long *)&head[4]=(long)(36+size);
memcpy(&head[8],"WAVEfmt ", 8);
*(long *)&head[16]=(long)16;
*(short *)&head[20]=(short)1;
*(short *)&head[22]=(short)CHANNEL;
*(long *)&head[24]=(long)RATE;
*(long *)&head[28]=(long)(blocksize * RATE);
*(short *)&head[32]=(short)blocksize;
*(short *)&head[34]=(short)BIT;
memcpy(&head[36], "data", 4);
*(long *)&head[40]=(long)size;
}

int record(double p[], double frq, double second)
{
int i, j;
double s = 0.0, hasuu;
double fadeout_time = RATE * second * 0.90;
double step = ((double)onshokurate / RATE) * (frq / c4);

if( onshokuloopsize ==0 ){
for(i = 0; i < RATE * second; i++){
if( s >= onshokusize ) p = 0.0;
else{
j = (int)s;
hasuu = s - (double)j;
p = onshoku[j] + (onshoku[j+1] - onshoku[j]) * hasuu;
s += step;
}
}
}else{
for(i = 0; i < RATE * second; i++){
j = (int)s;
hasuu = s - (double)j;
p = onshoku[j] + (onshoku[j+1] - onshoku[j]) * hasuu;
if( i > fadeout_time ){
p *= (RATE * second - i) / (RATE * second - fadeout_time);
}
s += step;
if( s >=onshokusize ) s -= onshokuloopsize;
}
}
return i;
}

void normalize(short data[], double p[], int size)
{
int i;
double max_v = 0.0, min_v = 0.0;
double scale;

for(i = 0; i < size; i++){
if( p > max_v ) max_v = p;
else if( p < min_v ) min_v =p;
}
if( max_v > -min_v ) scale = 32767.0 / max_v;
else scale = 32767.0 / min_v;
printf("max=%.3f min=%.3f 倍率=%.3f\n", max_v, min_v, scale);
for(i = 0; i < size; i++) data = p * scale;
}

int main(void)
{
int i, cnt = 0, ret;
FILE *f;

f = fopen("03PIANO1.FPV", "rb");
if( f == NULL ){
printf("File not found\n");
return 0;
}
fread(onshoku, 256, 1, f);
onshokusize = *(unsigned short *)&onshoku[6];
onshokuloopsize = *(unsigned short *)&onshoku[8];
if( onshokuloopsize > 0 ) {
onshokuloopsize = onshokusize - onshokuloopsize;
}
onshokurate = onshokurate_table[(int)(*(char *)&onshoku[11])];
fread(onshoku, onshokusize, 1, f);
fclose(f);
printf("音色ファイル=%s 周波数=%d 音色データサイズ=%d 音色ループサイズ=%d\n",
ONSHOKUFILE, onshokurate, onshokusize, onshokuloopsize);

f = fopen(WAVFILENAME, "wb");
if(f == NULL){printf("エラー"); return 0;}
fseek(f, 44, SEEK_SET);

for(i = 0; i <sizeof (music6) / 16; i++ ){
ret = record(&p[cnt], music6[i * 2], music6[i * 2 + 1] * 60.0 / TEMPO);
cnt += ret;
}
for(i = 0; i <sizeof (music5) / 16; i++ ){
ret = record(&p[cnt], music5[i * 2], music5[i * 2 + 1] * 60.0 / TEMPO);
cnt += ret;
}

for(i = 0; i <sizeof (music4) / 16; i++ ){
ret = record(&p[cnt], music4[i * 2], music4[i * 2 + 1] * 60.0 / TEMPO);
cnt += ret;
}
for(i = 0; i <sizeof (music3) / 16; i++ ){
ret = record(&p[cnt], music3[i * 2], music3[i * 2 + 1] * 60.0 / TEMPO);
cnt += ret;
}
for(i = 0; i <sizeof (music2) / 16; i++ ){
ret = record(&p[cnt], music2[i * 2], music2[i * 2 + 1] * 60.0 / TEMPO);
cnt += ret;
}
for(i = 0; i < sizeof(music) / 16; i++ ){
ret = record(&p[cnt], music[i * 2], music[i * 2 + 1] * 60.0 / TEMPO);
cnt += ret;
}
normalize(data, p, cnt);
fwrite(data, sizeof(short), cnt, f);
rewind(f);
set_wav_header(head, cnt);
fwrite(head, sizeof(head), 1, f);
fclose(f);
printf("成功");
return 0;
}

astraea
記事: 7
登録日時: 13年前

Re: 課題で出されたのですが…

#2

投稿記事 by astraea » 13年前

投稿者です、見難くてすみません。
ファーラムルールを知らずに投稿していまいました。

astraea
記事: 7
登録日時: 13年前

Re: 課題で出されたのですが…

#3

投稿記事 by astraea » 13年前

コード:

#include <stdio.h>
#include <string.h>
#define _USE_MATH_DEFINES
#include <math.h>

#define CHANNEL 1
#define BIT 16
#define RATE 44100

char head[44];
double p[44100 * 300];
short data[44100 *300];
char onshoku[65536];
int onshokurate_table[4] = {44100, 33075, 22050, 11025};
int onshokusize, onshokuloopsize, onshokurate;

#define s0	0
#define g1	48.9994
#define g11	51.9131
#define a1	55
#define a11	58.2705
#define b1	61.7354
#define c2	65.4064
#define c21	69.2957
#define d2	73.4192
#define d21	77.7817
#define e2	82.4069
#define f2	87.3071
#define f21	92.4986
#define g2	97.9989
#define g21	103.8262
#define a2	110
#define a21	116.5409
#define b2	123.4708
#define c3	130.8128
#define c31	138.5913
#define d3	146.8324
#define d31	155.5635
#define e3	164.8138
#define f3	174.6141
#define f31	184.9972
#define g3	195.9977
#define g31	207.6523
#define a3	220
#define a31	233.0819
#define b3	246.9417
#define c4	261.6256
#define c41	277.1826
#define d4	293.6648
#define d41	311.1270
#define e4	329.6276
#define f4	349.2282
#define f41	369.9944
#define g4	391.9954
#define g41	415.3047
#define a4	440
#define a41	466.1638
#define b4	493.8833
#define c5	523.2511
#define c51	554.3653
#define d5	587.3295
#define d51	622.2540
#define e5	659.2551
#define f5	698.4565
#define f51	739.9888
#define g5	783.9909
#define g51	830.6094
#define a5	880
#define a51	932.3275
#define b5	987.7666
#define c6	1046.5023
#define c61	1108.7305
#define d6	1174.6591
#define d61	1244.5079
#define e6	1318.5102
#define f6	1396.9129
#define f61	1479.9777
#define g6	1567.9817
#define g61	1661.2188

#define WAVFILENAME "INNOCENCE2.wav"
#define ONSHOKUFILE "fpv/03PIANO1.FPV"
#define TEMPO 183
double music[]={e5,0.5, d51,1, b5,2, e5,0.5};

double music2[]={b4,0.5, s0,1, f51,2, s0,0.5};

double music3[]={g4,0.5, s0,1, d51,2, s0,0.5};

double music4[]={b3,4};

double music5[]={f3,4};

double music6[]={b2,4};



void set_wav_header(char head[], int cnt)
{
	int blocksize=(BIT/8)*CHANNEL;
	int size=blocksize*cnt;
	memcpy(&head[0],"RIFF", 4);
	*(long *)&head[4]=(long)(36+size);
	memcpy(&head[8],"WAVEfmt ", 8);
	*(long *)&head[16]=(long)16;
	*(short *)&head[20]=(short)1;
	*(short *)&head[22]=(short)CHANNEL;
	*(long *)&head[24]=(long)RATE;
	*(long *)&head[28]=(long)(blocksize * RATE);
	*(short *)&head[32]=(short)blocksize;
	*(short *)&head[34]=(short)BIT;
	memcpy(&head[36], "data", 4);
	*(long *)&head[40]=(long)size;
}

int record(double p[], double frq, double second)
{
	int i, j;
	double s = 0.0, hasuu;
	double fadeout_time = RATE * second * 0.90;
	double step = ((double)onshokurate / RATE) * (frq / c4);

	if( onshokuloopsize ==0 ){
		for(i = 0; i < RATE * second; i++){
			if( s >= onshokusize ) p[i] = 0.0;
			else{
				j = (int)s;
				hasuu = s - (double)j;
				p[i] = onshoku[j] + (onshoku[j+1] - onshoku[j]) * hasuu;
				s += step;
			}
		}
	}else{
		for(i = 0; i < RATE * second; i++){
			j = (int)s;
			hasuu = s - (double)j;
			p[i] = onshoku[j] + (onshoku[j+1] - onshoku[j]) * hasuu;
			if( i > fadeout_time ){
				p[i] *= (RATE * second - i) / (RATE * second - fadeout_time);
			}
			s += step;
			if( s >=onshokusize ) s -= onshokuloopsize;
		}
	}
	return i;
}

void normalize(short data[], double p[], int size)
{
	int i;
	double max_v = 0.0, min_v = 0.0;
	double scale;

	for(i = 0; i < size; i++){
		if( p[i] > max_v ) max_v = p[i];
		else if( p[i] < min_v ) min_v =p[i];
	}
	if( max_v > -min_v ) scale = 32767.0 / max_v;
	else scale = 32767.0 /  min_v;
	printf("max=%.3f min=%.3f 倍率=%.3f\n", max_v, min_v, scale);
	for(i = 0; i < size; i++) data[i] = p[i] * scale;
}

int main(void)
{
	int i, cnt = 0, ret;
	FILE *f;

	f = fopen("03PIANO1.FPV", "rb");
	if( f == NULL ){
		printf("File not found\n");
		return 0;
	}
	fread(onshoku, 256, 1, f);
	onshokusize = *(unsigned short *)&onshoku[6];
	onshokuloopsize = *(unsigned short *)&onshoku[8];
	if( onshokuloopsize > 0 ) {
		onshokuloopsize = onshokusize - onshokuloopsize;
	}
	onshokurate = onshokurate_table[(int)(*(char *)&onshoku[11])];
	fread(onshoku, onshokusize, 1, f);
	fclose(f);
	printf("音色ファイル=%s 周波数=%d 音色データサイズ=%d 音色ループサイズ=%d\n",
		ONSHOKUFILE, onshokurate, onshokusize, onshokuloopsize);

	f = fopen(WAVFILENAME, "wb");
	if(f == NULL){printf("エラー"); return 0;}
	fseek(f, 44, SEEK_SET);

	for(i = 0; i <sizeof (music6) / 16; i++ ){
		ret = record(&p[cnt], music6[i * 2], music6[i * 2 + 1] * 60.0 / TEMPO);
		cnt += ret;
	}
	for(i = 0; i <sizeof (music5) / 16; i++ ){
		ret = record(&p[cnt], music5[i * 2], music5[i * 2 + 1] * 60.0 / TEMPO);
		cnt += ret;
	}

	for(i = 0; i <sizeof (music4) / 16; i++ ){
		ret = record(&p[cnt], music4[i * 2], music4[i * 2 + 1] * 60.0 / TEMPO);
		cnt += ret;
	}
	for(i = 0; i <sizeof (music3) / 16; i++ ){
		ret = record(&p[cnt], music3[i * 2], music3[i * 2 + 1] * 60.0 / TEMPO);
		cnt += ret;
	}
	for(i = 0; i <sizeof (music2) / 16; i++ ){
		ret = record(&p[cnt], music2[i * 2], music2[i * 2 + 1] * 60.0 / TEMPO);
		cnt += ret;
	}
	for(i = 0; i < sizeof(music) / 16; i++ ){
		ret = record(&p[cnt], music[i * 2], music[i * 2 + 1] * 60.0 / TEMPO);
		cnt += ret;
	}
	normalize(data, p, cnt);
	fwrite(data, sizeof(short), cnt, f);
	rewind(f);
	set_wav_header(head, cnt);
	fwrite(head, sizeof(head), 1, f);
	fclose(f);
	printf("成功");
	return 0;
}
すみません、こちらに移しました。

astraea
記事: 7
登録日時: 13年前

Re: 課題で出されたのですが…

#4

投稿記事 by astraea » 13年前

悪いとは思いますが、6/1提出の課題なのでわかるお方はお願いします。

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: 課題で出されたのですが…

#5

投稿記事 by beatle » 13年前

record関数で1曲再生する仕組みですか?
だとすると、複数の曲を同時に流すには、record関数が同時に動くようにしなければなりませんね。
大きく2つの方向性があると思います。
  1. record関数を改造して、複数の曲を扱えるようにする
  2. プログラムをマルチスレッド化して、record関数が複数のスレッドで動くようにする
1の方法では、record関数は結構複雑になるような気もしますね。複数の曲を指定した時間差で演奏する、などという機能を付けようとすると、さらに大変かも?
2の方法では、マルチスレッドの知識を要求されるのでpthreadなどを勉強する必要があります。
record関数で音が出る原理がわかってないので無駄な心配かもしれませんが、マルチスレッド化してrecord関数が同時に複数動いたとしても、出力するスピーカーが1つだったりすると、スピーカーに信号を送る前に音をミックスする必要があるかもしれません。

astraea
記事: 7
登録日時: 13年前

Re: 課題で出されたのですが…

#6

投稿記事 by astraea » 13年前

複数の曲を演奏と言うよりかは、和音を入れながらピアノ音で演奏するのが、
目的なのですか、結局は同じプログラムのいじり方でしょうか?
また、ここの関数をこういじるのような指摘がうれしいです。
如何せん初心者ですので。すみませんがよろしくお願いします。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 課題で出されたのですが…

#7

投稿記事 by softya(ソフト屋) » 13年前

これは波形を合成して一つのファイルにするって事ですよね。
PCM波形の合成方法は分かりますか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

astraea
記事: 7
登録日時: 13年前

Re: 課題で出されたのですが…

#8

投稿記事 by astraea » 13年前

分からないので、教えていただけるとありがたいです。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 課題で出されたのですが…

#9

投稿記事 by softya(ソフト屋) » 13年前

そもそも物理の法則ですが、音と言うか音波は波であるという理解と音の波が音の大きさが周期的に変化することで出来ていると言う理解が必要です。
recode()関数が音の波形を作り出している部分は理解できていますか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

astraea
記事: 7
登録日時: 13年前

Re: 課題で出されたのですが…

#10

投稿記事 by astraea » 13年前

はい、そこは大丈夫です。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 課題で出されたのですが…

#11

投稿記事 by softya(ソフト屋) » 13年前

そこが分かるのであれば、波形の合成は時系列で音の大きさを合成=加算してやれば良いだけと分かるはずなのですが、何処でつまずいているのかよく分からなくなってきました。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ISLe
記事: 2650
登録日時: 15年前
連絡を取る:

Re: 課題で出されたのですが…

#12

投稿記事 by ISLe » 13年前

プログラムはリアルタイム演奏ではなくて、WAVE形式ファイルを書き出していますよね。

p配列に追加しているのを、それぞれ別の配列に入れて、それらを合成すれば良いのでは?

astraea
記事: 7
登録日時: 13年前

Re: 課題で出されたのですが…

#13

投稿記事 by astraea » 13年前

なるほど、理解できました。
お答えしていただいた方々、ありがとうございます。

閉鎖

“C言語何でも質問掲示板” へ戻る