为啥我的音频功能一直循环而不是一直运行?
Posted
技术标签:
【中文标题】为啥我的音频功能一直循环而不是一直运行?【英文标题】:Why does my audio function keep looping instead of running all the way through?为什么我的音频功能一直循环而不是一直运行? 【发布时间】:2015-03-17 18:45:22 【问题描述】:我的代码与我的“播放”功能不同。我试图让程序读取由“记录”功能创建的 .txt 文件并播放笔记。
不幸的是,当用户按下 P 来播放他们录制的音符时,它只是不断弹出相同的菜单,而不是前进到程序的下一步。
#include "aservelibs/aservelib.h"
#include <stdio.h>
#include <math.h>
#include <string.h>
float mtof(int note, float frequency);
FILE play(void);
FILE record(void);
FILE record2(void);
int main()
FILE *textFilePointer;
FILE *textFilePointer2;
int counter = 0;
char user;
do
printf("Press A to Record 1st Melody (A), B to Record 2nd Melody (B)\nP to Play Melodies (P):");
scanf(" %c", &user);
if (user == 'a' || user == 'A')
textFilePointer = fopen("/Users/Luke/Desktop/midinotes1.txt", "w");
*textFilePointer = record();
counter = 0;
else if (user == 'b' || user == 'B')
textFilePointer2 = fopen("/Users/Luke/Desktop/midinotes2.txt", "w");
*textFilePointer2 = record2();
counter = 0;
else if (user == 'p' || user == 'P')
textFilePointer = fopen("/Users/Luke/Desktop/midinotes1.txt", "r");
textFilePointer2 = fopen("/Users/Luke/Desktop/midinotes2.txt", "r");
counter = 0;
while(counter < 16);
float mtof(int note, float frequency)
frequency = 440.0 * pow(2, (note-69) / 12.0);
printf("%d\n", note);
return frequency;
FILE play(void)
FILE*file;
file = fopen("/Users/Luke/Desktop/midinotes1.txt", "r");
file = fopen("/Users/Luke/Desktop/midinotes1.txt", "r");
do
int note = aserveGetNote();
int velocity = aserveGetVelocity();
fscanf(file, "%d, %d\n", ¬e, &velocity);
int frequency = mtof(note, frequency);
aserveOscillator(0, frequency, 1.0, 0);
aserveSleep(500);
while (feof(file) == 0);
fclose(file);
return *file;
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);
counter++;
while (counter < 16);
fclose(file);
return *file;
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);
counter++;
while (counter < 16);
fclose(file);
return *file;
【问题讨论】:
【参考方案1】: fclose(file);
return *file;
如果您关闭它,您将无法再使用它。如果您希望以后仍然使用它(您会这样做),请不要关闭 file
。
【讨论】:
【参考方案2】:我在您的程序中看到的问题
当用户输入A
或a
时,你执行:
textFilePointer = fopen("/Users/Luke/Desktop/midinotes1.txt", "w");
*textFilePointer = record();
counter = 0;
录制到"/Users/Luke/Desktop/midinotes1.txt"
的代码已经硬编码在record()
中。这里不需要在同一个文件上使用fopen()
。
record()
不需要返回 FILE
。顺便说一句,使用FILE
作为返回类型似乎很奇怪。我认为该标准甚至不支持使用FILE
。使用FILE*
作为参数和返回值是我所看到的。
同样的事情也适用于record2()
。
当用户输入p
或P
时,你执行:
textFilePointer = fopen("/Users/Luke/Desktop/midinotes1.txt", "r");
textFilePointer2 = fopen("/Users/Luke/Desktop/midinotes2.txt", "r");
counter = 0;
这里没有给play()
的电话。当您将代码转录到此处发布时,可能会丢失。就算加一行
play();
那里,这里不需要使用fopen()
。 play()
已经打开文件进行播放。此外,您多次打开文件而不使用它们或关闭它们。
您在main
的所有三个if
块中将counter
设置为0
。 counter
的值何时为 16
以满足 do-while
循环的退出标准?这是疏忽吗?
在play()
的实现中,你有:
file = fopen("/Users/Luke/Desktop/midinotes1.txt", "r");
file = fopen("/Users/Luke/Desktop/midinotes1.txt", "r");
看起来不对。您在同一文件上调用 fopen
两次。当函数返回时,您将留下一个未使用并打开的FILE*
。
第二个文件永远不会播放。
我将建议创建一个辅助函数playFile()
,它可以播放给定文件的内容。然后,从play()
呼叫playFile()
两次。这是伪代码:
void playFile(char const* file)
FILE* file = fopen(file, "r);
if ( file == NULL )
// deal with error.
else
// Your code to play the contents.
// Close the file
fclose(file);
void play()
playFile("/Users/Luke/Desktop/midinotes1.txt");
playFile("/Users/Luke/Desktop/midinotes2.txt");
关注the DRY principle
我将建议创建一个函数recordToFile()
,它具有record()
和record2()
的公共代码,然后使用正确的参数从record()
和record2()
调用它。
void recordToFile(char const* file)
int counter;
FILE* file = fopen(file, "w");
if ( file == NULL )
// Deal with error
else
// Your code to record to the file.
// Close the file
fclose(file);
void record(void)
recordToFile("/Users/Luke/Desktop/midinotes1.txt");
void record2(void)
recordToFile("/Users/Luke/Desktop/midinotes2.txt");
【讨论】:
【参考方案3】:你永远不会像这样调用 play 函数:
else if (user == 'p' || user == 'P')
...
play ();
【讨论】:
【参考方案4】:可能在您第二次调用 fopen 之后:
file = fopen("/Users/Luke/Desktop/midinotes1.txt", "r");
file = fopen("/Users/Luke/Desktop/midinotes1.txt", "r");
FILE * file
将无效。至少,它们是多余的。
您应该删除其中一行。
另外,在使用之前检查file
是否有效:
file = fopen("/Users/Luke/Desktop/midinotes1.txt", "r");
if(file) //if fopen fails, file == NULL
do
...
【讨论】:
以上是关于为啥我的音频功能一直循环而不是一直运行?的主要内容,如果未能解决你的问题,请参考以下文章