課題で出されたのですが…
-
eustia
課題で出されたのですが…
このままコンパイルすると、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;
}
同時に流れるようにするにはどうすればよいのでしょうか、教えてください。
(ファイル名や、音の打ち込みは途中ですが)
お願いします。
#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;
}
Re: 課題で出されたのですが…
#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;
}
Re: 課題で出されたのですが…
record関数で1曲再生する仕組みですか?
だとすると、複数の曲を同時に流すには、record関数が同時に動くようにしなければなりませんね。
大きく2つの方向性があると思います。
2の方法では、マルチスレッドの知識を要求されるのでpthreadなどを勉強する必要があります。
record関数で音が出る原理がわかってないので無駄な心配かもしれませんが、マルチスレッド化してrecord関数が同時に複数動いたとしても、出力するスピーカーが1つだったりすると、スピーカーに信号を送る前に音をミックスする必要があるかもしれません。
だとすると、複数の曲を同時に流すには、record関数が同時に動くようにしなければなりませんね。
大きく2つの方向性があると思います。
- record関数を改造して、複数の曲を扱えるようにする
- プログラムをマルチスレッド化して、record関数が複数のスレッドで動くようにする
2の方法では、マルチスレッドの知識を要求されるのでpthreadなどを勉強する必要があります。
record関数で音が出る原理がわかってないので無駄な心配かもしれませんが、マルチスレッド化してrecord関数が同時に複数動いたとしても、出力するスピーカーが1つだったりすると、スピーカーに信号を送る前に音をミックスする必要があるかもしれません。
Re: 課題で出されたのですが…
複数の曲を演奏と言うよりかは、和音を入れながらピアノ音で演奏するのが、
目的なのですか、結局は同じプログラムのいじり方でしょうか?
また、ここの関数をこういじるのような指摘がうれしいです。
如何せん初心者ですので。すみませんがよろしくお願いします。
目的なのですか、結局は同じプログラムのいじり方でしょうか?
また、ここの関数をこういじるのような指摘がうれしいです。
如何せん初心者ですので。すみませんがよろしくお願いします。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: 課題で出されたのですが…
これは波形を合成して一つのファイルにするって事ですよね。
PCM波形の合成方法は分かりますか?
PCM波形の合成方法は分かりますか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: 課題で出されたのですが…
そもそも物理の法則ですが、音と言うか音波は波であるという理解と音の波が音の大きさが周期的に変化することで出来ていると言う理解が必要です。
recode()関数が音の波形を作り出している部分は理解できていますか?
recode()関数が音の波形を作り出している部分は理解できていますか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: 課題で出されたのですが…
そこが分かるのであれば、波形の合成は時系列で音の大きさを合成=加算してやれば良いだけと分かるはずなのですが、何処でつまずいているのかよく分からなくなってきました。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 課題で出されたのですが…
プログラムはリアルタイム演奏ではなくて、WAVE形式ファイルを書き出していますよね。
p配列に追加しているのを、それぞれ別の配列に入れて、それらを合成すれば良いのでは?
p配列に追加しているのを、それぞれ別の配列に入れて、それらを合成すれば良いのでは?