该程序旨在记录和存储用户输入的旋律,然后播放用户记录的序列。我有两个记录函数,其中函数扫描用户的输入,然后将音符编号和速度存储到两个单独的.txt
文件中。
该程序还具有节拍器功能(功能)和速度(长度)功能。
我的节目运行良好,除了我之前我意识到它没有播放同时录制的两个序列。事实上,它只播放存储在" midinotes2.txt"中的第二个序列,这让我感到困惑,我似乎找不到让两个序列一起回放的方法。任何人都可以看到我的代码可能出错或者我可以添加什么来使其工作?
#include "aservelibs/aservelib.h"
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
//------------------------------------------------function declarations
float mtof(int note, float frequency);
FILE play(void);
FILE record(void);
FILE record2(void);
int length();
void* metronome(void* param);
int playMetronome;
//------------------------------------------------main program
int main()
{
//------------------------------------------------variables
FILE *textFilePointer;
int counter = 0;
char user;
//------------------------------------------------main menu
do
{
printf("Press A to Record 1st Melody (A), B to Record 2nd Melody (B)\nP to Play Melodies (P) X to Exit (X):");
scanf(" %c", &user);
//------------------------------------------------record 1st melody
if (user == 'a' || user == 'A')
{
playMetronome = 1;
pthread_t tid1;
pthread_create(&tid1,NULL,metronome,0);
textFilePointer = fopen("/Users/Luke/Desktop/midinotes1.txt", "w");
*textFilePointer = record();
if(textFilePointer == NULL);
{
printf("Recording Complete\n");
playMetronome = 0;
}
counter = 0;
}
//------------------------------------------------record 2nd melody
else if (user == 'b' || user == 'B')
{
playMetronome = 1;
pthread_t tid1;
pthread_create(&tid1,NULL,metronome,0);
textFilePointer = fopen("/Users/Luke/Desktop/midinotes2.txt", "w");
*textFilePointer = record2();
if(textFilePointer == NULL);
{
printf("Recording Complete\n");
playMetronome = 0;
}
counter = 0;
}
//------------------------------------------------plays the melodies back
else if (user == 'p' || user == 'P')
{
textFilePointer = fopen("/Users/Luke/Desktop/midinotes1.txt", "r");
*textFilePointer = play();
textFilePointer = fopen("/Users/Luke/Desktop/midinotes2.txt", "r");
*textFilePointer = play();
if(textFilePointer == NULL);
{
printf("Playback Complete\n");
aserveOscillator(0, 0, 0, 0);
aserveOscillator(1, 0, 0, 0);
}
counter = 0;
}
//-------------------------------------------------exits program
else if (user == 'x' || user == 'X')
{
exit(0);
}
}
while(counter < 16);
}
//--------------------------------------------------function declarations
//--------------------------------------------------converts MIDI number to frequency
float mtof(int note, float frequency)
{
frequency = 440.0 * pow(2, (note-69) / 12.0);
printf("Playing Note:%d\n", note);
return frequency;
}
//--------------------------------------------------changes tempo of sequence playback
int length()
{
return (aserveGetControl(7)/((127.0 - 0) / (1000 - 100))) + 100;
}
//--------------------------------------------------metronome function
void* metronome(void* param)
{
while(playMetronome)
{
aserveOscillator(3, 1500, 0.8, 0);
aserveOscillator(3, 0, 0, 0);
aserveSleep(length()*2);
aserveOscillator(3, 0, 0, 0);
aserveOscillator(3, 1000, 0.8, 0);
aserveOscillator(3, 0, 0, 0);
aserveSleep(length()*2);
aserveOscillator(3, 0, 0, 0);
aserveOscillator(3, 1000, 0.8, 0);
aserveOscillator(3, 0, 0, 0);
aserveSleep(length()*2);
aserveOscillator(3, 0, 0, 0);
aserveOscillator(3, 1000, 0.8, 0);
aserveOscillator(3, 0, 0, 0);
aserveSleep(length()*2);
aserveOscillator(3, 0, 0, 0);
}
return 0;
}
//--------------------------------------------------playback function
FILE play(void)
{
FILE*file;
file = fopen("/Users/Luke/Desktop/midinotes1.txt", "r");
file = fopen("/Users/Luke/Desktop/midinotes2.txt", "r");
do {
int note[2];
int velocity;
float freq[2];
int frequency;
fscanf(file, "%d, %d\n", ¬e[0], &velocity);
fscanf(file, "%d, %d\n", ¬e[1], &velocity);
freq[0] = mtof(note[0], frequency);
freq[1] = mtof(note[1], frequency);
aserveOscillator(0, freq[0], 1.0, 0);
aserveOscillator(1, freq[1], 1.0, 0);
aserveSleep(length()*2);
} while (feof(file) == 0);
return *file;
}
//--------------------------------------------------layer 1 record function
FILE record(void)
{
int counter;
FILE*file;
file = fopen("/Users/Luke/Desktop/midinotes1.txt", "w");
do
{
int note = aserveGetNote();
int velocity = aserveGetVelocity();
if (velocity > 0)
{
fprintf(file, "%d, %d\n", note, velocity);
printf("Note: %d, Velocity: %d\n", note, velocity);
counter++;
}
} while (counter < 16);
fclose(file);
return *file;
}
//--------------------------------------------------layer 2 record function
FILE record2(void)
{
int counter;
FILE*file;
file = fopen("/Users/Luke/Desktop/midinotes2.txt", "w");
do
{
int note = aserveGetNote();
int velocity = aserveGetVelocity();
if (velocity > 0)
{
fprintf(file, "%d, %d\n", note, velocity);
printf("Note: %d, Velocity: %d\n", note, velocity);
counter++;
}
} while (counter < 16);
fclose(file);
return *file;
}
答案 0 :(得分:0)
在函数FILE play(void)
中,您首先将file
分配给第一个文件句柄,然后分配给第二个文件句柄。所以你基本上覆盖了变量。
file = fopen("/Users/Luke/Desktop/midinotes1.txt", "r");
file = fopen("/Users/Luke/Desktop/midinotes2.txt", "r");
所以我猜这是为什么它会play
第二个文件,而不是第一个文件。
我还可以告诉你,你的代码不是很容易阅读,并且做了许多似乎多余的事情(比如多次读取文件而不实际使用它们,在不使用它们的情况下分配变量)。 你有没有调试过这段代码?
如果没有,你真的应该这样做,以便更容易阅读,也更健壮。