|
29.02.2012, 09:23
|
#1
|
Нуждающийся
Регистрация: 19.11.2009
Сообщений: 64
Написано 4 полезных сообщений (для 6 пользователей)
|
Кто напишет функцию записи звука?
Добрый день всем!
Нужна функция записи звука с текущего источника воспроизведения
Пробовал использовать Bass dll- не смог разобраться (не работает функция BASS_StreamCreateFile)
Готов заплатить (в меру возможностей) - если будут написаны простые функции записи и сохранения сэмплов
Почта для контакта [email protected]
|
(Offline)
|
|
29.02.2012, 17:43
|
#2
|
[object Object]
Регистрация: 01.08.2008
Адрес: В России
Сообщений: 4,360
Написано 2,473 полезных сообщений (для 6,856 пользователей)
|
Ответ: Кто напишет функцию записи звука?
Squall бери и не парься. Его к блицу прикрутить не проблема.
__________________
Retry, Abort, Ignore? █
Intel Core i7-9700 4.70 Ghz; 64Gb; Nvidia RTX 3070
AMD Ryzen 7 3800X 4.3Ghz; 64Gb; Nvidia 1070Ti
AMD Ryzen 7 1700X 3.4Ghz; 8Gb; AMD RX 570
AMD Athlon II 2.6Ghz; 8Gb; Nvidia GTX 750 Ti
|
(Offline)
|
|
29.02.2012, 18:14
|
#3
|
Нуждающийся
Регистрация: 05.10.2011
Адрес: Россия, Южно-Сахалинск
Сообщений: 66
Написано 42 полезных сообщений (для 83 пользователей)
|
Ответ: Кто напишет функцию записи звука?
Сообщение от executer
не работает функция BASS_StreamCreateFile
|
Если я правильно понял справку, то Stream не предназначен для такого, нужно вручную писать файл, WAV, либо через функцию обратного вызова в BASS_RecordStart, либо через BASS_ChannelGetData.
ЗЫ
Гыгы, ради прикола попробовал
; Константы параметров записи
Const Frequency% = 44100
Const BitsPerSample% = 16
Const Channels% = 2
Const BlockAlign% = Channels * BitsPerSample / 8
; Инициализируем рекордер
BASS_RecordInit (-1 )
; Формируем банк с заголовком WAV файла
Local RecHeader% = CreateBank ( 44 )
; Сигнатура 'RIFF'
PokeInt ( RecHeader, 0, 1179011410 )
; Размер заголовка + размер данных, пока оставим нуль
PokeInt ( RecHeader, 4, 0 )
; Сигнатура 'WAVE'
PokeInt ( RecHeader, 8, 1163280727 )
; Сигнатура 'fmt '
PokeInt ( RecHeader, 12, 544501094 )
; Размер структуры WAVEFORMATEX
PokeInt ( RecHeader, 16, 16 )
; Поле WAVEFORMATEX\wFormatTag
PokeShort ( RecHeader, 20, 1 )
; Поле WAVEFORMATEX\nChannels
PokeShort ( RecHeader, 22, Channels )
; Поле WAVEFORMATEX\nSamplesPerSec
PokeInt ( RecHeader, 24, Frequency )
; Поле WAVEFORMATEX\nAvgBytesPerSec
PokeInt ( RecHeader, 28, Frequency * BlockAlign)
; Поле WAVEFORMATEX\nBlockAlign
PokeShort ( RecHeader, 32, BlockAlign)
; Поле WAVEFORMATEX\wBitsPerSample
PokeShort ( RecHeader, 34, BitsPerSample )
; Сигнатура 'data'
PokeInt ( RecHeader, 36, 1635017060 )
; Размер блока данных
PokeInt ( RecHeader, 40, 0 ); Data length
; Создаем файл для записи
Local RecFile% = WriteFile ( "output.wav" )
; Записываем заголовок
WriteBytes ( RecHeader, RecFile, 0, 44 )
;
; т.к. в Блиц-Бейсике нет возможности получить адрес функции (имею ввиду встроеной возможности),
; а один из механизмов записи данных в BASS это функции обратного вызова
; то можно записать бинарное представление этой функции в банк памяти и передать адрес на его данные
;
; исходя из заголовка функции (в справке):
; - она имеет stdcall соглашение вызова ( т.е. должна сама восстанавливать смещение стека )
; - предоставляет 4 параметра: хендл канала, адрес буфера с данными, длина данных и параметр указаный пользователем
; - должна возвращать True для продолжения записи
; для такой функции типично сразу передавать буфер с данными в файл
; блиц умеет передавать только банк памяти WriteBytes
; нижеописанный код получен путем дизассемблирования WriteBytes и небольшого анализа полученого кода
;
; да-да, я извращенец :)
;
; выделяем банк под код функции обратного вызова
Local RecProc% = CreateBank ( 27 )
; mov eax, [ esp + 12 ] "Length"
PokeByte ( RecProc, 0, $8B )
PokeByte ( RecProc, 1, $44 )
PokeByte ( RecProc, 2, $24 )
PokeByte ( RecProc, 3, $0C )
; push eax
PokeByte ( RecProc, 4, $50 )
; mov eax, [ esp + 12 ] "Buffer"
PokeByte ( RecProc, 5, $8B )
PokeByte ( RecProc, 6, $44 )
PokeByte ( RecProc, 7, $24 )
PokeByte ( RecProc, 8, $0C )
; push eax
PokeByte ( RecProc, 9, $50 )
; mov ecx, [ esp + 24 ] "File"
PokeByte ( RecProc, 10, $8B )
PokeByte ( RecProc, 11, $4C )
PokeByte ( RecProc, 12, $24 )
PokeByte ( RecProc, 13, $18 )
; mov eax, [ ecx ] "File -> This"
PokeByte ( RecProc, 14, $8B )
PokeByte ( RecProc, 15, $01 )
; call [ eax + 8 ] "This -> WriteData"
PokeByte ( RecProc, 16, $FF )
PokeByte ( RecProc, 17, $50 )
PokeByte ( RecProc, 18, $08 )
; mov eax, 1 "Return True"
PokeByte ( RecProc, 19, $B8 )
PokeByte ( RecProc, 20, $01 )
PokeByte ( RecProc, 21, $00 )
PokeByte ( RecProc, 22, $00 )
PokeByte ( RecProc, 23, $00 )
; ret 16
PokeByte ( RecProc, 24, $C2 )
PokeByte ( RecProc, 25, $10 )
PokeByte ( RecProc, 26, $00 )
; временный банк памяти для возвращения старого аттрибута памяти
Local RecTemp% = CreateBank ( 4 )
Const PAGE_EXECUTE_READWRITE% = 64
; для того чтобы DEP системы не дал по рукам за "выполнение данных"
; сменим атрибут памяти, указав что он предназначен для запуска
VirtualProtect ( RecProc, 27, PAGE_EXECUTE_READWRITE, RecTemp )
FreeBank ( RecTemp )
; запускаем рекордер, передаем параметры, банк с функцией обратного вызова
; и тот самый параметр пользователя - хендл файла, в который будет происходить запись
; в функции обратного вызова
Local RecChannel% = BASS_RecordStart ( Frequency, Channels, 0, RecProc, RecFile )
; ожидающий цикл
Repeat
Delay ( 100 )
Until KeyDown ( 1 )
; останавливаем рекордер
BASS_ChannelStop ( RecChannel )
; освобождаем ресурсы
BASS_RecordFree ( )
; получаем размер файла
Local RecLength% = FilePos ( RecFile )
; записываем размеры в заголовок
SeekFile ( RecFile, 4 )
WriteInt ( RecFile, RecLength - 8 )
SeekFile ( RecFile, 40 )
WriteInt ( RecFile, RecLength - ( 36 + 8 ) )
; закрываем файл
CloseFile ( RecFile )
End
и decls
.lib "kernel32.dll"
VirtualProtect%(Address*, Size%, NewProtect%, OldProtect*)
.lib "bass.dll"
BASS_RecordInit%(Device%)
BASS_RecordStart%(Frequency%, Mode%, Flags%, Func*, Context%)
BASS_ChannelStop%(Handle%)
BASS_RecordFree()
|
(Offline)
|
|
16.03.2012, 13:58
|
#4
|
Нуждающийся
Регистрация: 19.11.2009
Сообщений: 64
Написано 4 полезных сообщений (для 6 пользователей)
|
Ответ: Кто напишет функцию записи звука?
Платон Александрович-Огромное спасибо вам за помощь-простите что сразу не ответил!
Можно ваш сотовый?-хочу отблагодарить!
Думаю-наладим сотрудничество!
|
(Offline)
|
|
Ваши права в разделе
|
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 06:09.
|