Как программно синтезировать музыку?

Примечание: это НЕ вопрос "музыка для программирования".

Мой вопрос:

Я хочу написать компьютерную программу, которая может синтезировать повторяющиеся ритмы (которыми я могу управлять через командную строку), чтобы передавать музыку в мои уши.

Мне любопытно, существуют ли инструменты для этого (и если нет, то какие библиотеки использовать).

Общая идея такова:

1) компьютер знает, что я делаю (по командам, которые я запускаю - работаю ли я в Vim, компилируются ли мои программы и т. Д.)

2) компьютер знает мое общее настроение (подсчитать количество сбоев компилятора из-за 'make'; количество ошибок по умолчанию, ненулевых кодов выхода; количество коммитов git)

3) компьютер знает состояние моего мозга (в зависимости от скорости набора текста; я либо кодирую, либо думаю)

Я бы хотел использовать их для био-обратной связи для управления музыкой.

Это также, почему музыка должна быть синтезирована программно (а не только некоторые существующие треки).

8 ответов

Решение

Для фактической стороны музыки проверьте Чака. Это позволяет программно синтезировать звуки. Вот видео на YouTube, показывающее пример Чака на работе. Еще одно видео, рассказывающее о том, как работает Чак и как создавать основные звуки.

Ты должен:

  • Соберите входные данные, на которых вы будете основывать свою музыку.

  • решить, как эти входные переменные будут влиять на музыку

  • придумать алгоритмы для создания мелодий и ритмов

  • закодируйте все это в музыкальном синтезаторе

Ваши предметы "знайте свое настроение" и "знайте свое состояние мозга", вероятно, являются открытыми исследовательскими проблемами, заслуживающими докторской степени, если вы хотите добиться значительного прогресса в них!

Как только вы дойдете до этого последнего шага, я предлагаю Csound.

Csound - это система звукового дизайна, синтеза музыки и обработки сигналов, предоставляющая возможности для композиции и исполнения на широком спектре платформ. Он не ограничивается каким-либо стилем музыки, так как его много лет использовали для создания классической, поп, техно, эмбиентной, экспериментальной и (конечно) компьютерной музыки, а также музыки для кино и телевидения.

Кроме того, у меня когда-то было видение, что серверная комната должна отражать состояние серверов. Поэтому я настраиваю крикет крипов с частотой, основанной на средней загрузке, волчьих войх для событий входа в систему, наблюдаемых за системным журналом, и сововых криках для (в то время относительно редких) посещений веб-страниц...

В этом случае он был просто соединен в Python с некоторой базовой очисткой журнала....

археоптерикс, вероятно, довольно близок к тому, что касается генерации ритма.

Canon в D в C

Результат: https://www.youtube.com/watch?v=JISozfHATms

main.c:

#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

typedef uint16_t point_type_t;

double PI2;

void write_ampl(FILE *f, point_type_t ampl) {
    uint8_t bytes[2];
    bytes[0] = ampl >> 8;
    bytes[1] = ampl & 0xFF;
    fwrite(bytes, 2, sizeof(uint8_t), f);
}

/* https://en.wikipedia.org/wiki/Piano_key_frequencies */
double piano_freq(unsigned int i) {
    return 440.0 * pow(2, (i - 49.0) / 12.0);
}

/* Chord formed by the nth note of the piano. */
point_type_t piano_sum(unsigned int max_ampl, unsigned int time,
        double sample_freq, unsigned int nargs, unsigned int *notes) {
    unsigned int i;
    double sum = 0;
    for (i = 0 ; i < nargs; ++i)
        sum += sin(PI2 * time * piano_freq(notes[i]) / sample_freq);
    return max_ampl * 0.5 * (nargs + sum) / nargs;
}

enum notes {
    A0 = 1, AS0, B0,
    C1, C1S, D1, D1S, E1, F1, F1S, G1, G1S, A1, A1S, B1,
    C2, C2S, D2, D2S, E2, F2, F2S, G2, G2S, A2, A2S, B2,
    C3, C3S, D3, D3S, E3, F3, F3S, G3, G3S, A3, A3S, B3,
    C4, C4S, D4, D4S, E4, F4, F4S, G4, G4S, A4, A4S, B4,
    C5, C5S, D5, D5S, E5, F5, F5S, G5, G5S, A5, A5S, B5,
    C6, C6S, D6, D6S, E6, F6, F6S, G6, G6S, A6, A6S, B6,
    C7, C7S, D7, D7S, E7, F7, F7S, G7, G7S, A7, A7S, B7,
    C8,
};

int main(void) {
    FILE *f;
    PI2 = 2 * acos(-1.0);
    const double SAMPLE_FREQ = 44100;
    point_type_t ampl;
    point_type_t max_ampl = UINT16_MAX;
    unsigned int t, i;
    unsigned int samples_per_unit = SAMPLE_FREQ * 0.375;
    unsigned int *ip[] = {
        (unsigned int[]){4, 2, C3, E4},
        (unsigned int[]){4, 2, G3, D4},
        (unsigned int[]){4, 2, A3, C4},
        (unsigned int[]){4, 2, E3, B3},

        (unsigned int[]){4, 2, F3, A3},
        (unsigned int[]){4, 2, C3, G3},
        (unsigned int[]){4, 2, F3, A3},
        (unsigned int[]){4, 2, G3, B3},

        (unsigned int[]){4, 3, C3, G4, E5},
        (unsigned int[]){4, 3, G3, B4, D5},
        (unsigned int[]){4, 2, A3,     C5},
        (unsigned int[]){4, 3, E3, G4, B4},

        (unsigned int[]){4, 3, F3, C4, A4},
        (unsigned int[]){4, 3, C3, G4, G4},
        (unsigned int[]){4, 3, F3, F4, A4},
        (unsigned int[]){4, 3, G3, D4, B4},

        (unsigned int[]){2, 3, C4, E4, C5},
        (unsigned int[]){2, 3, C4, E4, C5},
        (unsigned int[]){2, 3, G3, D4, D5},
        (unsigned int[]){2, 3, G3, D4, B4},

        (unsigned int[]){2, 3, A3, C4, C5},
        (unsigned int[]){2, 3, A3, C4, E5},
        (unsigned int[]){2, 2, E3,     G5},
        (unsigned int[]){2, 2, E3,     G4},

        (unsigned int[]){2, 3, F3, A3, A4},
        (unsigned int[]){2, 3, F3, A3, F4},
        (unsigned int[]){2, 3, C3,     E4},
        (unsigned int[]){2, 3, C3,     G4},

        (unsigned int[]){2, 3, F3, A3, F4},
        (unsigned int[]){2, 3, F3, A3, C5},
        (unsigned int[]){2, 3, G3, B3, B4},
        (unsigned int[]){2, 3, G3, B3, G4},

        (unsigned int[]){2, 3, C4, E4, C5},
        (unsigned int[]){1, 3, C4, E4, E5},
        (unsigned int[]){1, 3, C4, E4, G5},
        (unsigned int[]){1, 2, G3,     G5},
        (unsigned int[]){1, 2, G3,     A5},
        (unsigned int[]){1, 2, G3,     G5},
        (unsigned int[]){1, 2, G3,     F5},

        (unsigned int[]){3, 3, A3, C4, E5},
        (unsigned int[]){1, 3, A3, C4, E5},
        (unsigned int[]){1, 3, E3, G3, E5},
        (unsigned int[]){1, 3, E3, G3, F5},
        (unsigned int[]){1, 3, E3, G3, E5},
        (unsigned int[]){1, 3, E3, G3, D5},
    };
    f = fopen("canon.raw", "wb");
    for (i = 0; i < sizeof(ip) / sizeof(int*); ++i) {
        unsigned int *cur = ip[i];
        unsigned int total = samples_per_unit * cur[0];
        for (t = 0; t < total; ++t) {
            ampl = piano_sum(max_ampl, t, SAMPLE_FREQ, cur[1], &cur[2]);
            write_ampl(f, ampl);
        }
    }
    fclose(f);
    return EXIT_SUCCESS;
}

генерировать canon.raw:

gcc -std=c99 -o main main.c -lm
./main

Играть canon.raw непосредственно:

sudo apt-get install ffmpeg
ffplay -autoexit -f u16be -ar 44100 -ac 1 canon.raw

или конвертируйте в более распространенный аудиоформат, а затем играйте с более распространенным аудиоплеером:

ffmpeg -f u16be -ar 44100 -ac 1 -i canon.raw canon.flac
vlc canon.flac

или конвертировать в видео для YouTube:

wget -O canon.png https://upload.wikimedia.org/wikipedia/commons/thumb/3/35/The_C_Programming_Language_logo.svg/564px-The_C_Programming_Language_logo.svg.png
ffmpeg -loop 1 -y -i canon.png -i canon.flac -shortest -acodec copy -vcodec vp9 canon.mkv

как объяснено: https://superuser.com/questions/1041816/combine-one-image-one-audio-file-to-make-one-video-using-ffmpeg/1041818

Вот более физически ориентированный взгляд на генерацию аудио: как звук представлен числами?

Проверено на Ubuntu 18.04. GitHub вверх по течению.

Music as Data - очень интересный проект, по-видимому, вдохновленный SuperCollider и Chuck.

Он специально разработан для того, чтобы его можно было легко взломать или поэкспериментировать с живыми инструментами - в основном это инструмент для создания музыкальных DSL.

Проверьте Boodler, "инструмент звукового пейзажа с открытым исходным кодом".

JFugue - это библиотека с открытым исходным кодом (Java/JVM) для "программирования музыки без сложностей MIDI". смотреть статью

Его легко начать, и он может послужить основой для вашей программы, как для ритма, так и для мелодии.

Я не знаю, как бы я это сделал, но я мог бы взглянуть на Bootchart, который выполняет кучу мониторинга процессов. Возможно, это поможет выяснить, что происходит сейчас.

Другие вопросы по тегам