#include "aservelibs/aservelib.h"
#include <stdio.h>
#include <math.h>
#include <string.h>
FILE *textFilePointer;
FILE *textFilePointer2;
typedef struct
{
int notes;
int velocity;
}NoteData;
void notetofile (NoteData input, int seqlen, int reclayer);
int main()
{
int count, count2, note, vel = 0;
char choice = 'y';
struct layers;
int reclayer = 1;
int playlayer = 1;
char choice2 = 'y', choice3 = 'y';
int seqlen = 16;
NoteData input;
printf("Welcome To Jonny Maguire's Midi record and playback application. Please Select one of the following options...\n\n");
aserveSay("Welcome To Jonny Maguires Midi record and playback application. Please Select one of the following options");
aserveSleep(8000);
while(choice != 'x')
{
printf("r to Record\np to Playback\nx to exit the program\n");
aserveSay("choose r, to record a sequence, p, to playback your recording. Or select x, at any time to exit the program");
scanf(" %c", &choice);
if(choice == 'r')
{
while(choice2 != 'n')
{
aserveSay("you have chosen to record, enter the no. of notes you wish to record");
printf("You have chosen to record, enter the no. of notes you wish to record \n\n");
scanf(" %d", &seqlen);
printf("Please play %d notes", seqlen);
textFilePointer = fopen("recording1.txt", "w");
textFilePointer2 = fopen("recording2.txt", "w");
if(textFilePointer == NULL or textFilePointer2 == NULL)
{
printf("Error Opening File!");
}
else
{
//Recording 16 note data into txt file
notetofile(input, seqlen, reclayer);
printf("Would you like to record another layer?");
scanf(" %c", &choice2);
}
reclayer++;
}
}
else if (choice == 'p')
{
while(choice3 != 'n')
{
//If P is selected, playback of the txt file
printf("which sequence would like to playback? 1, 2 or both (3)?");
scanf(" %d", &playlayer);
textFilePointer = fopen("recording1.txt", "r");
// textFilePointer2 = fopen("recording2.txt", "r");
if(textFilePointer == NULL)
{
printf("Error Opening File!");
}
//read until end of file and convert frequency
if (playlayer == 1)
{
while(!feof(textFilePointer))
{
float frequency;
float amplitude = vel/127.0;
fscanf(textFilePointer, " %d %d\n", &input.notes, &input.velocity);
printf(" %d %d\n\n", input.notes, input.velocity);
frequency = 440 * pow(2, (note-69) /12.0);
aserveOscillator(0, frequency, amplitude, 0);
aserveSleep(500);
aserveOscillator(0, 0, 0, 0);
}
}
}
fclose(textFilePointer);
playlayer++;
}
}
return 0;
}
//function to write notes to file
void notetofile(NoteData input, int seqlen, int reclayer)
{
for (int count = 1; count <= seqlen;)
{
input.notes = aserveGetNote();
input.velocity = aserveGetVelocity();
//only note on messages are sent to file
if(input.velocity > 0)
{
printf("reclayer = %d\n", reclayer);
if(reclayer == 1)
{
printf("test");
fprintf(textFilePointer, " %d %d\n", input.notes, input.velocity);
fprintf(textFilePointer, "test");
}
else if(reclayer == 2)
{
fprintf(textFilePointer2, " %d %d\n", input.notes, input.velocity);
}
printf("%d %d\n", input.notes, input.velocity);
count++;
}
}
}
该程序用于读取midi音符,将它们写入txt文件,然后从文件读入振荡器。 fprintf没有在'notestofile'函数中写入文件。这可能是因为我有两个textFilePointers同时打开。
答案 0 :(得分:0)
当你写入2个文件recording1.txt和recording2.txt时,你不会追加,所以每次你想写时都会重置这些文件。如果你想追加你必须使用模式&#34; a&#34; (用于追加)而不是&#34; w&#34;。
当您正在编写这些文件时,文件描述符textFilePointer
和textFilePointer2
永远不会关闭,缓冲区也不会被明确刷新,因此您不会看到文件中的内容你的过程还活着。在这些文件描述符上调用fclose
会在代码中刷新这样的写缓冲区:
textFilePointer = fopen("recording1.txt", "w");
textFilePointer2 = fopen("recording2.txt", "w");
if(textFilePointer == NULL or textFilePointer2 == NULL)
{
printf("Error Opening File!");
}
else
{
//Recording 16 note data into txt file
notetofile(input, seqlen, reclayer);
printf("Would you like to record another layer?");
scanf(" %c", &choice2);
//Added fclose calls to opened files:
fclose( textFilePointer );
fclose( textFilePointer2 );
//TODO Check both fclose return values
}
如果你没有关闭文件,那就是文件描述符泄漏,在大多数Linux系统上,最大打开文件的限制设置为1024,输入ulimit -n
进行查看。
您可以在生命进程中查看已打开的描述符,以查看lsof
命令或列出/proc/<pid>/fd
目录的泄漏。