Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > VB6 > Запись звука с Line-inp


Автор: ProgramerForever 28.3.2007, 18:43
Здравствуйте.

Мне необходимо записать звук с линейного входа звуковой карты, а потом преобразовать его в массив громкостей.

Мне всё это необходимо для следующего:
Я хочу сделать пульт дистанционного управления для своего ноутбука.
Поискал в Интернете: есть описания самодельных ИК-приёмников только на COM, LPT и Irda (так вроде бы называется ИК-порт на матплате) порты, чего у меня на ноутбуке, естественно нет...
Я решил подключить фотодиод через 1-2 каскада усиления к линейному входу, а уже с него снимать "звук", а потом программкой его переделывать в команды.

Автор: JusTalionis 28.3.2007, 21:10
ProgramerForever:
Про алгоритм записи не знаю; надеюсь это подскажут другие.

А на счет фотодиода скажу хорошее решение: подключить его к микрофонному входу, а не к линейному.
На микрофонном входе уже есть подпитка +5V, так что уже есть, от чего запитать каскады. Но, если сам фотодиод качественный, его можно попробовать подключить без всяких каскадов, так как чувствительность микрофонного входа сама по себе значительно выше, чем линейного. В этом случае фотодиод включается в запертом направлении. Я всегда так поступаю для записи световых импульсов.

Автор: Akina 28.3.2007, 21:44
См. MSDN: Platform SDK: Windows Multimedia: Waveform Functions

Там такая развесистая клюква...

Автор: ProgramerForever 31.3.2007, 13:37
JusTalionis, в запёртом - это как??
У меня фотоэлемент от видеомагнитофона. Там 3 контакта: GND+5Out. И на микрофонном так же, как я понял...
Я подключил все ножки соответственно. Сигнал от пульта было слышно, но тихо и на расстоянии порядка 1 см.
Как всё-таки подключить?



И вопросик по теме:
Я тут нашёл, как писать в wav. С помощью MicroSoft MultiMedia Control.

А вот как из него получить массивчик уровней сигнала?

Автор: cardinal 31.3.2007, 16:21
Цитата(ProgramerForever @  31.3.2007,  11:37 Найти цитируемый пост)
А вот как из него получить массивчик уровней сигнала? 

Посмотри тут как устроены файлы .wav
http://ccrma.stanford.edu/CCRMA/Courses/422/projects/WaveFormat/

Автор: JusTalionis 1.4.2007, 11:41
ProgramerForever
Я пользовался простым фотодиодом ФД-26К. У него два вывода как у обычного диода, в одну сторону пропускает, в другую - нет.
А у тебя не фотоэлемент, а чип с фотоэлементом и усилителем вместе. 

На микрофонном входе два контакта если моно, три - если стерео. Один из них - общий, "земля" (GND), два других - входы  левого и правого каналов соответственно. Оба - совмещенные с питанием: на каждом присутствует слабенький +5V, и по тому же проводу одновременно принимается звуковой сигнал. В компьютерном микрофоне встроенный усилитель, который питается от этих +5V. Но для твоего чипа с фотодиодом эта подпитка оказалась по-видимому слаба.

Попробуй так: GND - общий, OUT - к любому из входов, а +5V взять например из гнезда USB. Огород, конечно, провод надо тянуть, но для пробы пойдет.

Может быть вообще лучше воспользоваться стандартным IRDA, вставляющимся в USB?

Автор: ProgramerForever 3.4.2007, 05:08
Цитата

Может быть вообще лучше воспользоваться стандартным IRDA, вставляющимся в USB?

Нет, я читал, что стандартный не пойдёт, да и его покупать надо, да исвоими руками что-то хочется сделать smile 
Буду пробовать...

Автор: ProgramerForever 16.4.2007, 06:38
Цитата

См. MSDN: Platform SDK: Windows Multimedia: Waveform Functions

Там такая развесистая клюква...

А на русском путёвое описание есть где-нибудь, у кого-нибудь. Я в инете нашёл, но там не очень то понятно...

Автор: cardinal 16.4.2007, 13:44
ProgramerForever, я бы на твоем месте начал с изучения английского (хотя бы на уровне, которого бы хватило чтобы читать техн. литературу).

Автор: ProgramerForever 18.4.2007, 19:11
cardinal, спасиБО за совет, всё так, но как-то перейдя в другую школу, где был ТОЛЬКО немецкий язык, изучаю его до сих пор.

Но английский я потихоньку учу, всё-таки...  smile моя девушка smile  мне помогает...

Автор: ProgramerForever 30.4.2007, 18:29
Добрый вечер!

Я тут с микрофоном разобрался кое-как, сигнал идёт.(Файлик я прикрепил)


Не подскажите алгоритм анализа сигнала и сравнения с эталоном, может кто чем-то подобным занимался...

Автор: JusTalionis 2.5.2007, 10:31
Судя по рисунку, у тебя сигнал типа амплитудно-модулированной высокочастотной несущей, да? (То есть зеленое - это заполнение мелкой синусоидой, как я понимаю). А тебе надо выделить прямоугольную огибающую?
Тогда надо усреднять по количеству отсчетов, соответствующему периоду несущей (причем брать их абсолютные величины).


ЗЫ Если не в лом,- хотя бы в двух словах, пожалуйста, как всё-таки подключил фотодетектор? Просто интересно.


Автор: ProgramerForever 7.5.2007, 05:23
Цитата

ЗЫ Если не в лом,- хотя бы в двух словах, пожалуйста, как всё-таки подключил фотодетектор? Просто интересно.


Я пока проводами подключил  smile , Как прогу доделаю, буду паять девайс. Думаю на радиоуправлении будет эротичнее...
К ДУшке - передатчик простецкий вместо ИК - светодиода, а к компу - приёмник на ту же частоту... Вот так пока.

Я о бо всех продвижениях буду тут писать, если время будет.. Тут месяц последний учиться остался, сессия на носу, а я, как всегда, весь семестр болты пинал.. Гы smile 

Автор: JusTalionis 7.5.2007, 16:39
Если я правильно понял что у тебя несущая, промодулированная полезным сигналом, то лично я ее продетектировал бы аппаратно. IMHO, гимору значительно меньше.

Автор: ProgramerForever 8.5.2007, 04:36
Частоту сканирования (в wav-функциях) буду ставить примерно 10000, должно хватить. А на рисунке просто сигнал с микрофона (на label - их значения (8ми битный сэмпл))

Цитата

...несущая, промодулированная полезным сигналом...

Ик-сигнал имеет НАМНОГО БОЛЬШУЮ частоту несущёй, чем какие-то 10кГц, поэтому и модулировать не надо. По-моему, так..
А может быть пульт выдаёт просто сигнал без модуляции, что тоже очень вероятно..

Автор: JusTalionis 8.5.2007, 11:17
Во-всяком случае те пульты, которые мне попадались, выдавали просто сигнал импульсами, без всякой модуляции. (Но тогда непонятно, почему на твоем рисунке зеленое заполнение? Может просто прога так кажет?)

А касательно передатчика по радио - это все-таки огород, и пульт модифицировать надо.
Не легче ли сделать простенький усилитель для фотодиода? Ну хотя бы как на прилагаемой схеме? Дополнительного питания не нужно, питается от микрофонного входа. Фотодиод - любой, какой найдется, но именно фотодиод, а не чип. (Я пользовал ФД26К, просто они у меня были smile ) Транзистор - в общем-то любой, но чем больше его коэфф передачи, тем больше и чувствительность будет.

Автор: cardinal 8.5.2007, 11:26
Возможно немного глупый вопрос: а как математически описать модель нарисованного?

Автор: ProgramerForever 8.5.2007, 12:33
Математически?? Что-то вроде F(t)?
А нарисованного у меня??
Если только функцией вроде 
при t=0, F=113;
при t=1, F=112;
при t=2, F=113;
при t=3, F=113;
при t=4, F=113;
при t=5, F=113;
..............
Другого способа я не вижу, да и не к чему это... smile 

Автор: Akina 8.5.2007, 12:52
Давайте, я это в железо перенесу, а? 

Автор: JusTalionis 8.5.2007, 13:09
Не надо, Акин, я больше не бууууудуууу!... smile 
Просто человек все еще ждет, кто ответит, как же все-таки читать сигнал со звуковухи в массив?  Никто ведь ничего конкретного до сих пор не сказал на этот начальный вопрос темы. Кста, и мне он тоже интересен... 
Так что - smile 


ЗЫ Испробовал http://forum.vingrad.ru/topic-45667.html# , который  прислал Voldemar2004. Пример не рабочий , (каких-то определений в нем не хватает, что ли).
Хочу пример!! Исправный!!! smile

Автор: ProgramerForever 10.5.2007, 04:53
Цитата

как же все-таки читать сигнал со звуковухи в массив

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

Вот код читалки:
Код


Dim WaveDataBool(1000) As Byte
Const Porog = 80
Dim Datnow As SYSTEMTIME
Dim Dat As SYSTEMTIME


Private Sub Form_Load()
F = FreeFile
Open "c:\1.txt" For Output As #F


Slider1_Change
    Dim Rv&
    Dim Msg$
    Dim WF As WAVEFORMATEX

    With WF
        .wFormatTag = WAVE_FORMAT_PCM
        .nChannels = 1
        .nBlockAlign = 1
        .nSamplesPerSec = 12000
        .wBitsPerSample = 8
        .nAvgBytesPerSec = (.nSamplesPerSec * .nBlockAlign) \ 8
        .cbSize = 0
    End With

    Rv = waveInOpen(hWaveIn, WAVE_MAPPER, WF, AddressOf waveInProc, 0, CALLBACK_FUNCTION)
    If Rv <> 0 Then
       MsgBox "Íå ìîãó îòêðûòü óñòðîéñòâî!", vbCritical, "Error"
       Exit Sub
    End If
    DoEvents
bBufferFull = True
End Sub

Private Sub Form_Unload(Cancel As Integer)
    waveInClose hWaveIn
    Close F

    End
End Sub

Private Sub Slider1_Change()
    With WH
        .lpData = VarPtr(WaveData(0))
        .dwBufferLength = Slider1.Value
        .dwFlags = 0
    End With
End Sub

Private Sub Slider1_KeyPress(KeyAscii As Integer)
    If KeyAscii = 27 Then
        waveInClose hWaveIn
        End
    End If
End Sub


Private Sub Timer1_Timer()

If bBufferFull Then
    If Check1.Value = 1 Then
        Picture1.Refresh
        aa = Int(Picture1.Width / (Slider1.Value * Screen.TwipsPerPixelX))
        If aa = 0 Then
            aa = 1
        End If
        Picture1.DrawWidth = aa
        Picture1.Line (0, Int(Picture1.Height * (WaveData(1) / 255)))-(1, Int(Picture1.Height * (WaveData(1) / 255)))
        For i = 0 To Slider1.Value - 1
            If Abs(WaveData(i) - 133) >= Porog Then
                    WaveDataBool(i) = 1
                    Picture1.Line (Int(Picture1.Width * i / Slider1.Value), 0)-(Int(Picture1.Width * i / Slider1.Value), Picture1.Height), vbRed
                Else
                    WaveDataBool(i) = 0
            End If
            If Check2.Value = 1 Then
                    Picture1.Line -(Picture1.Width * i \ Slider1.Value, Int(Picture1.Height * (WaveData(i) / 255)))
                Else
                    Picture1.Line (Int(Picture1.Width * i / Slider1.Value), Picture1.Height)-(Picture1.Width * i \ Slider1.Value, Int(Picture1.Height * (WaveData(i) / 255)))
            End If
        Next
        For i = 0 To Slider1.Value - 1
            s = s + Str(WaveData(i))
        Next
        Label1.Caption = s
    End If
        DoEvents
        waveInPrepareHeader hWaveIn, WH, Len(WH)
        bBufferFull = False
        waveInAddBuffer hWaveIn, WH, Len(WH)
        waveInStart hWaveIn
    End If
End Sub

И модуль:
Код

Public hWaveIn&
Public Const Buffer = 1000
Public bBufferFull As Boolean
Public WaveData(Buffer) As Byte
Public WH As WAVEHDR

Public Const MAXPNAMELEN = 20
Public Const CALLBACK_FUNCTION = &H30000
Public Const MM_WIM_DATA = &H3C0
Public Const WAVE_FORMAT_PCM = 1
Public Const WAVE_MAPPER = -1&

Public Const WAVE_FORMAT_1M08 = &H1     ' 11025 Hz, 8 Bit, Mono.
Public Const WAVE_FORMAT_2M08 = &H10    ' 22050 Hz, 8 Bit, Mono.
Public Const WAVE_FORMAT_4M08 = &H100   ' 44100 Hz, 8 Bit, Mono.
'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Public Type SYSTEMTIME
  wYear As Long
  wMonth As Long
  wDayOfWeek As Long
  wDay As Long
  wHour As Long
  wMinute As Long
  wSecond As Long
  wMilliseconds As Long
End Type

Public Declare Sub GetSystemTime Lib "kernel32" (lpSystemTime As SYSTEMTIME)
'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Public Type WAVEINCAPS
  wMid As Long
  wPid As Long
  vDriverVersion As Long
  szPname As String * MAXPNAMELEN
  dwFormats As Long
  wChannels As Long
End Type

Public Type WAVEHDR
     lpData As Long
     dwBufferLength As Long
     dwBytesRecorded As Long
     dwUser As Long
     dwFlags As Long
     dwLoops As Long
     lpNext As Long
     Reserved As Long
End Type

Public Type WAVEFORMATEX
     wFormatTag As Integer
     nChannels As Integer
     nSamplesPerSec As Long
     nAvgBytesPerSec As Long
     nBlockAlign As Integer
     wBitsPerSample As Integer
     cbSize As Integer
End Type

Public Declare Function waveInStart Lib "winmm.dll" (ByVal hWaveIn As Long) As Long
Public Declare Function waveInGetNumDevs Lib "winmm.dll" () As Long
Public Declare Function waveInGetDevCaps Lib "winmm.dll" Alias "waveInGetDevCapsA" (ByVal uDeviceID As Long, lpCaps As WAVEINCAPS, ByVal uSize As Long) As Long
Public Declare Function waveInClose Lib "winmm.dll" (ByVal hWaveIn As Long) As Long
Public Declare Function waveInOpen Lib "winmm.dll" (lphWaveIn As Long, ByVal uDeviceID As Long, lpFormat As WAVEFORMATEX, ByVal dwCallback As Long, ByVal dwInstance As Long, ByVal dwFlags As Long) As Long
Public Declare Function waveInPrepareHeader Lib "winmm.dll" (ByVal hWaveIn As Long, lpWaveInHdr As WAVEHDR, ByVal uSize As Long) As Long
Public Declare Function waveInAddBuffer Lib "winmm.dll" (ByVal hWaveIn As Long, lpWaveInHdr As WAVEHDR, ByVal uSize As Long) As Long
Public Declare Function waveInUnprepareHeader Lib "winmm.dll" (ByVal hWaveIn As Long, lpWaveInHdr As WAVEHDR, ByVal uSize As Long) As Long


Public Sub waveInProc(ByVal hwi&, ByVal uMsg&, ByVal dwInstance&, ByVal dwParam1&, ByVal dwParam2&)
    If uMsg = MM_WIM_DATA Then bBufferFull = True
End Sub

А если кому в лом разбираться, ниже архив с проектом: smile

Добавлено через 1 минуту и 34 секунды
Кыыыыыть! Извините, написать написал, а архив не бросил...

Автор: JusTalionis 10.5.2007, 17:46
Скачал архив; запустил проект. Скомпилировалось без ошибок. Но при запуске выдало: "Не могу открыть устройство". Капут. Форма разворачивается, но ничего не делает.

Звуковуха присутствует; под стандартными звуковыми редакторами пишет, играет. WIN98.
Вот еще попробую дома под ХР, отпишусь.

------------------------------
Попробовал. Заработало без ошибок. По-видимому, на работе у меня звуковуха мало совместимая (Gravis Ultrasound).
Посмотрел на твою прогу. Респект! smile Проделана значительная работа!..

По предыдущим вопросам: надо было рисунок прислать в режиме осциллографа. Я же не знал, что у тя столбчатой диаграммой рисуется. Так что никакой модуляции там нету, нормальный сигнал.
Кстати, я подключил фотодиод с транзистором, как здесь писал; проверил - чувствительность неодстаточна. Добавил второй каскад, подробно описывать не буду, Акине обещал; если хочешь - в личку, обсудим. Скажу только результат: с двумя каскадами чувствительность средняя (с 3х метров) но получились помехи от света лампочек. Короч, надо отстраиваться, делать фильтры, а они повлияют и на форму сигнала, так что огород получается - еще тот!.. Вынужден признать, что предложенный мною вариант мало перспективен для данной задачи.

За сим позвольте откланяться; если в чем-нибудь смогу помочь не столь мало, как теперь - не премину это сделать.

Юс Талионис

Автор: ProgramerForever 17.7.2007, 09:06
 smile  smile  smile А я прогу доделал... smile  smile  smile 

Прилагаю.
Чтобы добавить кнопку, 2 раза щёлкнуть по картинке.

Теперь надо сделать что-то вроде MKey. Чтобы было удобно...

Я тему по WMP создал, но другое тоже надо: WinAmp, окна и т.д.

Автор: cardinal 17.7.2007, 12:59
Ты только так двузначно файл в след. раз не называй... smile 

Автор: ProgramerForever 17.7.2007, 17:19
Скачал из-за названия??? smile Я так прикалываюсь... smile 

Автор: ProgramerForever 16.8.2007, 20:19
Добрый вечер!

Похвастаюсь: сделал пульт, но не на радиоуправлении, а на ИК, как положено. В качестве приёмника - приёмник от телека импортного. Работает на УРА!!! smile 

И вопрос. Немного не по теме, но из того же раздела.


Как мне можно уменьшать/увеличивать звук?

Автор: cardinal 16.8.2007, 21:39
Цитата(ProgramerForever @  16.8.2007,  19:19 Найти цитируемый пост)
Как мне можно уменьшать/увеличивать звук? 

Не совем понимаю вопрос.

Автор: ProgramerForever 16.8.2007, 21:53
Программно из VB устанавливать необходимый уровень громкости звука, который идёт на колонки, наушники и т.п.
Что-то вроде "Общая громкость"

Автор: cardinal 16.8.2007, 22:55
На это взгляни http://www.gssg.de/vbmume.htm

Автор: ProgramerForever 17.8.2007, 07:03
Спасибо, cardinal. Я посмотрел на ссылку, ".de", думаю, почему он частенько ответы даёт на немецкие ресурсы. Посмотрел профиль и всё встало на свои места... Спасибо ещё раз. Скачал, буду разбираться, благо сам совсем немного немецкий знаю, да и Promt у меня есть (что не можно глаз отвесть smile). Пока!

Автор: cardinal 17.8.2007, 10:28
Да можно и без профиля... smile 

Автор: ProgramerForever 19.8.2007, 11:34
Код

        Proz = 0.03
        If Button(ii).Name = "Track >" Then
            Vol.WaveVolume = Vol.WaveVolume + Vol.MaxWaveVolume * Proz
            Me.Caption = "ГишаSoft - Monitor - Громкость >>> (" + Str(Vol.WaveVolume * 100 \ Vol.MaxWaveVolume) + "%)"
        End If
        If Button(ii).Name = "Track <" Then
            Vol.WaveVolume = Vol.WaveVolume - Vol.MaxWaveVolume * Proz
            Me.Caption = "ГишаSoft - Monitor - Громкость <<< (" + Str(Vol.WaveVolume * 100 \ Vol.MaxWaveVolume) + "%)"
        End If


Так намного проще...
В том проекте была операция на гландах через ж...
Спасибо, работает! smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)