c - 如何让节拍器在程序录音的同时播放?

标签 c multithreading function

该程序旨在能够录制和存储用户输入的旋律,然后播放用户录制的序列。我正在尝试添加一个节拍器,以便在录音时您可以听到有节奏的脉冲。

我已经成功地制作了音调,并让该函数与 int length 函数一起及时工作。我的问题是我只能让节拍器在录制序列之前或之后播放,这使得节拍器毫无意义,因为你在录制音符时听不到它。

该函数包含 while 循环这一事实也会阻止程序继续执行程序的下一部分。我只想在录音时启用节拍器功能。

有谁知道我如何让它在录音时播放节拍器,而不是只能在启动录音功能之前或之后播放节拍器?

#include "aservelibs/aservelib.h"
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
//------------------------------------------------function declarations
float mtof(int note, float frequency);
FILE play(void);
FILE record(void);
FILE record2(void);
int length();
void metronome(void);
//------------------------------------------------main program
int main()
{
//------------------------------------------------variables
    FILE *textFilePointer;
    FILE *textFilePointer2;
    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')
        {

            textFilePointer = fopen("/Users/Luke/Desktop/midinotes1.txt", "w");
            *textFilePointer = record();
            metronome();


            if(textFilePointer == NULL);
            {
                printf("Recording Complete\n");
                aserveOscillator(3, 0, 0, 0);
            }
            counter = 0;
        }
//------------------------------------------------record 2nd melody
        else if (user == 'b' || user == 'B')
        {
            textFilePointer2 = fopen("/Users/Luke/Desktop/midinotes2.txt", "w");
            *textFilePointer2 = record2();
            metronome();


            if(textFilePointer == NULL);
            {
                printf("Recording Complete\n");
                aserveOscillator(3, 0, 0, 0);
            }
            counter = 0;
        }

//------------------------------------------------plays the melodies back
        else if (user == 'p' || user == 'P')
        {
            textFilePointer = fopen("/Users/Luke/Desktop/midinotes1.txt", "r");
            *textFilePointer = play();

            textFilePointer2 = fopen("/Users/Luke/Desktop/midinotes2.txt", "r");
            *textFilePointer2 = 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)
{
    while(true)
    {
    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);


    }
}
//--------------------------------------------------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", &note[0], &velocity);
        fscanf(file, "%d, %d\n", &note[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;
}

最佳答案

这里是一些创建线程的代码:

#include <pthread.h>

void* metronome(void* param);

int playMetronome;

int main(){
    pthread_t tid1;

    playMetronome = 1;
    pthread_create(&tid1,NULL,metronome,0);

    //the code to record and play something

    playMetronome = 0; //the loop in metronome() stops at this point


    return 0;
}

void* metronome(void* param){
    while(playMetronome){
        //code to play metronome
        //this code will run simultaneous with the code to play melodies
   }

}

关于c - 如何让节拍器在程序录音的同时播放?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29213594/

相关文章:

c - 合并两个 Makefile 以构建一个输出

c - 在哪里可以找到 ntohl

android - 如何在 Android 中的非 UI 线程上执行延迟

c++ - 有没有办法并行运行 C++ 单元测试测试?

python - python函数的参数列表

c - 为什么调用AddNode()函数后大小等于二叉树中添加的数据?

c - C 中的位移位

c - 使用位运算符拆分两个数字

java - 在 Java 中,更改对并发读取的 HashMap 的引用是否安全

javascript - 将变量重新输入到循环函数中