Страница: 1 |
Страница: 1 |
Вопрос: Генерация звука
Добавлено: 21.08.06 02:59
Автор вопроса: Artyom
Вобщем, хочется сделать немного странного...
Наверное, все видели в своих медиаплеерах что-то типа такого:
http://artyom.soobcha.org/sound.gif
Мне хочется сделать следующее:
Я задаю такой график (не важно как, к примеру, функцией зависимости y=f(t)).
И на основании этой функции я хочу сгенерировать звук, понятное дело, программно, у кого есть идеи, как проще всего это реализовать?
Ответы
Всего ответов: 10
Номер ответа: 1
Автор ответа:
VβÐUηìt
Вопросов: 246
Ответов: 3333
Web-сайт:
Профиль | | #1
Добавлено: 21.08.06 07:14
Тоже када-то хотел такое. Два года хотел. Потом забил, потому что нигде такого ненашел
Номер ответа: 2
Автор ответа:
Серёга
ICQ: 262809473
Вопросов: 17
Ответов: 561
Web-сайт:
Профиль | | #2
Добавлено: 21.08.06 20:47
Если тебе нужно генерировать звук определенной частоты, то:
Private Sub Form_Activate()
Dim Cnt As Long
For Cnt = 0 To 5000 Step 10
Beep Cnt, 5
Me.Caption = Cnt
DoEvents
Next Cnt
End Sub
Правда, эта штука выдает звук на системный динамик, а не на колонки ))
Номер ответа: 3
Автор ответа:
Artyom
Разработчик
Вопросов: 130
Ответов: 6602
Профиль | | #3
Добавлено: 22.08.06 00:38
Возникла идея генерировать звуки по типу того, как рисуется фрактальная графика
Private Sub Form_Activate()
 im Cnt As Long
For Cnt = 0 To 5000 Step 10
Beep Cnt, 5
Me.Caption = Cnt
 oEvents
Next Cnt
End Sub
Не, это не то, это просто сигнал определенной частоты, это фактически будет синусоида, а мне надо не синусоида - я сам хочу задать форму сигнала!
Номер ответа: 4
Автор ответа:
Sharp
Лидер форума
ICQ: 216865379
Вопросов: 106
Ответов: 9979
Web-сайт:
Профиль | | #4
Добавлено: 22.08.06 12:22
Вообще, не f(t), а f(q, t), где q - частота, а f - громкость. Это основа цифрового звука. А для сабжа следует изучить формат wave.
Номер ответа: 5
Автор ответа:
Artyom
Разработчик
Вопросов: 130
Ответов: 6602
Профиль | | #5
Добавлено: 22.08.06 13:41
Могу и f(q,t), это в принципе роли не играет
Тяжко...
Все равно спасибо.
Номер ответа: 6
Автор ответа:
VβÐUηìt
Вопросов: 246
Ответов: 3333
Web-сайт:
Профиль | | #6
Добавлено: 24.08.06 18:15
Кстати кстати кстати кстати!
Как нутро WAV'а писать? Ну, всмысле, не заголовки и артисты, а непосредственно звук?
Номер ответа: 7
Автор ответа:
Sharp
Лидер форума
ICQ: 216865379
Вопросов: 106
Ответов: 9979
Web-сайт:
Профиль | | #7
Добавлено: 25.08.06 16:15
// Another fine solution from Sharp
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
#ifndef ANY_SIZE
#define ANY_SIZE 1
#endif
#define FOURCC(x) ((x[0] + (x[1] << 8) + (x[2] << 16) + (x[3] << 24)))
#define PI 3.14159265358979323
struct WAVEDATA {
DWORD dID; // "data"
DWORD dLen; // Length of data in the dData field
BYTE dData[ANY_SIZE]; // The actual waveform data
};
struct WAVE {
DWORD wID; // "WAVE"
// Format
DWORD fID; // "fmt "
DWORD fLen; // Length of data in the format chunk
WORD wFormatTag; // format type
WORD nChannels; // number of channels (i.e. mono, stereo, etc.)
 WORD nSamplesPerSec; // sample rate
 WORD nAvgBytesPerSec; // for buffer estimation
WORD nBlockAlign; // block size of data
WORD FormatSpecific; // Format specific data area
// Data
WAVEDATA wd;
};
struct RIFF {
DWORD rID; // "RIFF"
DWORD rLen; // The length of the data in the next chunk
WAVE rData; // The data chunk
};
int main(){
// Одна секунда звука 440 Hz, частота дискретизации 11025 Hz, 8-битный, несжатый
int freq = 440;
int discr = 11025;
int bits = 8;
int t = 1;
// Генерим звук
double currtime, ampl;
int a;
int datalen = t * discr * bits / 8;
BYTE *data = new BYTE [datalen];
for(int i = 0; i < t * discr; i++){
currtime = (double)i / (double)discr;
// Вычисление амплитуды
ampl = sin(currtime * freq * 2 * PI);
// Нормализация и запись
switch(bits){
case 8:
a = (int)((ampl + 1) / 2 * 255);
data[i] = a;
break;
case 16:
a = (int)(ampl * (2^15 - 1));
data[i*2] = a % 256;
data[i*2 + 1] = a / 256;
break;
}
}
RIFF riff;
riff.rID = FOURCC("RIFF"
riff.rLen = sizeof(WAVE) - 1 + datalen;
riff.rData.wID = FOURCC("WAVE"
riff.rData.fID = FOURCC("fmt "
riff.rData.nBlockAlign = bits / 8;
riff.rData.nChannels = 1;
riff.rData.nSamplesPerSec = discr;
riff.rData.FormatSpecific = 8; // hz
riff.rData.fLen = 16;
riff.rData.wFormatTag = 1;
riff.rData.nAvgBytesPerSec = discr * bits / 8;
riff.rData.wd.dID = FOURCC("data"
riff.rData.wd.dLen = t * discr * bits / 2;
// Запись
HANDLE hFile = CreateFile("my.wav", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL);
DWORD nBytes;
WriteFile(hFile, (void *)&riff, sizeof(RIFF) - 1, &nBytes, NULL);
WriteFile(hFile, (void *)data, datalen, &nBytes, NULL);
CloseHandle(hFile);
return 0;
}
Из исходника, в общем, все понятно. Полученный файл действительно работает и выдает что-то похожее на 440 Hz через колонки
Номер ответа: 8
Автор ответа:
Sharp
Лидер форума
ICQ: 216865379
Вопросов: 106
Ответов: 9979
Web-сайт:
Профиль | | #8
Добавлено: 25.08.06 17:09
Глюки, правда, какие-то с 16-битным звуком. Если не лень станет разбираться, запощу патч.
Номер ответа: 9
Автор ответа:
Artyom
Разработчик
Вопросов: 130
Ответов: 6602
Профиль | | #9
Добавлено: 25.08.06 17:33
ужость...
Попробую разобраться
Номер ответа: 10
Автор ответа:
Djon
Вопросов: 61
Ответов: 471
Web-сайт:
Профиль | | #10
Добавлено: 28.08.06 15:17
Private Sub Form_Activate()
 im Cnt As Long
For Cnt = 0 To 5000 Step 10
Beep Cnt, 5
Me.Caption = Cnt
 oEvents
Next Cnt
End Sub
Правда, эта штука выдает звук на системный динамик, а не на колонки ))
У меня и на колонки выдаёт!
Sharp а можно на VB а то с си у меня тяжеловато!