forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Blitz3D (http://forum.boolean.name/forumdisplay.php?f=45)
-   -   Кто напишет функцию записи звука? (http://forum.boolean.name/showthread.php?t=16413)

executer 29.02.2012 09:23

Кто напишет функцию записи звука?
 
Добрый день всем!
Нужна функция записи звука с текущего источника воспроизведения
Пробовал использовать Bass dll- не смог разобраться (не работает функция BASS_StreamCreateFile)
Готов заплатить (в меру возможностей) - если будут написаны простые функции записи и сохранения сэмплов
Почта для контакта [email protected]

Randomize 29.02.2012 17:43

Ответ: Кто напишет функцию записи звука?
 
Squall бери и не парься. Его к блицу прикрутить не проблема.

Платон Александрович 29.02.2012 18:14

Ответ: Кто напишет функцию записи звука?
 
Цитата:

Сообщение от executer (Сообщение 220971)
не работает функция 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()


executer 16.03.2012 13:58

Ответ: Кто напишет функцию записи звука?
 
Платон Александрович-Огромное спасибо вам за помощь-простите что сразу не ответил!
Можно ваш сотовый?-хочу отблагодарить!
Думаю-наладим сотрудничество!


Часовой пояс GMT +4, время: 10:47.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Перевод: zCarot