Solved

MCI Control, WaveAudio

Posted on 1997-07-22
13
635 Views
Last Modified: 2012-05-04
I can succesfully "Record" "Afile" and subsequently "Play" this file "Afile". The MCI Command "Save" doesn't work.
I want to use the MCI opened file with the Basic command:
Open "Afile" For Binary As #1
and then be able to analyse the content of this file with the usual file I/O coding.
The MCI generated file "Afile" is not recognised by VB4 with  this simple line of code; is there some other way ?
0
Comment
Question by:dand072297
  • 7
  • 6
13 Comments
 

Author Comment

by:dand072297
ID: 1428698
Adjusted points to 300
0
 

Author Comment

by:dand072297
ID: 1428699
I would settle for a solution with mci-api calls.
0
 
LVL 5

Expert Comment

by:y96andha
ID: 1428700
I do not understand your question. What do you want to do? Do you want to load the waveform data into memory so you can process the samples?
0
 

Author Comment

by:dand072297
ID: 1428701
y96andha,
Yes, I want to access waveform data which has just been recorded with mci-api calls (so there is a Filename for this buffer in memory ). The data would be a short burst (say 1 sec or less).
0
 
LVL 5

Expert Comment

by:y96andha
ID: 1428702
Does it have to be a file that you can read from? I am looking into the possibility of using the low-level functions to record directly into memory.
0
 
LVL 5

Accepted Solution

by:
y96andha earned 300 total points
ID: 1428703
Try this code. I currently don't have a mic connected to my computer, but it gives no errors in VB4. You will get the data into the buffer and can then process it as you like. Please comment if you have any questions.

Private 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
Private 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
Private Declare Function waveInAddBuffer Lib "winmm.dll" (ByVal hWaveIn As Long, lpWaveInHdr As WAVEHDR, ByVal uSize As Long) As Long
Private Declare Function waveInClose Lib "winmm.dll" (ByVal hWaveIn As Long) As Long
Private 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
Private Declare Function waveInPrepareHeader Lib "winmm.dll" (ByVal hWaveIn As Long, lpWaveInHdr As WAVEHDR, ByVal uSize As Long) As Long
Private Declare Function waveInStart Lib "winmm.dll" (ByVal hWaveIn As Long) As Long
Private Declare Function waveInStop Lib "winmm.dll" (ByVal hWaveIn As Long) As Long
Private Declare Function waveInUnprepareHeader Lib "winmm.dll" (ByVal hWaveIn As Long, lpWaveInHdr As WAVEHDR, ByVal uSize As Long) As Long
Private Declare Function waveInReset Lib "winmm.dll" (ByVal hWaveIn As Long) As Long
Private Declare Function VarPtr Lib "vb40032" (var As Any) As Long
Private Const WHDR_DONE = &H1         '  done bit
Private Const WAVE_FORMAT_PCM = 1  '  Needed in resource files so outside #ifndef RC_INVOKED
Private Const WAVE_MAPPER = -1&


Private Sub Command1_Click()
Dim wf As WAVEFORMATEX
Dim hWaveIn As Long
Dim error As Long
wf.wFormatTag = WAVE_FORMAT_PCM
wf.nChannels = 1
wf.nSamplesPerSec = 8000
wf.wBitsPerSample = 8
wf.nBlockAlign = wf.nChannels * wf.wBitsPerSample / 8
wf.cbSize = 0
error = waveInOpen(hWaveIn, WAVE_MAPPER, wf, 0, 0, 0)
If error <> 0 Then
    Print "Error "; error; " in waveInOpen"
    Exit Sub
End If

Dim wh As WAVEHDR
Dim data(8000) As Byte
wh.lpData = VarPtr(data(1))
wh.dwBufferLength = 8000
wh.dwUser = 0
wh.dwFlags = 0
wh.dwLoops = 0
wh.lpNext = 0
wh.Reserved = 0
error = waveInPrepareHeader(hWaveIn, wh, Len(wh))
If error <> 0 Then
    waveInClose hWaveIn
    Print "Error "; error; " in waveInPrepareHeader"
    Exit Sub
End If

error = waveInAddBuffer(hWaveIn, wh, Len(wh))
If error <> 0 Then
    waveInUnprepareHeader hWaveIn, wh, Len(wh)
    waveInClose hWaveIn
    Print "Error "; error; " in waveInAddBuffer"
    Exit Sub
End If

error = waveInStart(hWaveIn)
If error <> 0 Then
    waveInReset hWaveIn
    waveInUnprepareHeader hWaveIn, wh, Len(wh)
    waveInClose hWaveIn
    Print "Error "; error; " in waveInStart"
    Exit Sub
End If

Print "Recording"
While (wh.dwFlags And WHDR_DONE) <> WHDR_DONE
    DoEvents
Wend
Print "Finished"

error = waveInUnprepareHeader(hWaveIn, wh, Len(wh))
If error <> 0 Then
    waveInClose hWaveIn
    Print "Error "; error; "in waveInUnprepareHeader"
    Exit Sub
End If

waveInClose hWaveIn
Print "Recorded data successfully"

End Sub


0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Comment

by:dand072297
ID: 1428704
y96andha,
Thank you for your effort. There is a problem running your code.
Present spec. as follows:
Win 95 upgrade
VB4 32_bit
c:\windows\system\WINMM.DLL
Form created. It has 1 PushButton, Command1
Your code entered as Form code
Added "Debug" as object to your Print statements

Run,  Click on Command1:
error 32 waveInOpen

I note the code line wf.nSamplesPerSec=8000; this is not
the expected 11025, 22050 or 44100.

Regards, dand
0
 
LVL 5

Expert Comment

by:y96andha
ID: 1428705
You are probably right about that. The error code 32 means format not supported. It does work on my computer in that it generates no error messages, but it might be because of some special driver I have installed. You can try and change this to some value supported with your sound card.

You can use this piece of code to get the error text for a certain error code:
    Dim s As String
    dim errorcode as integer
    errorcode = 32 ' for example
    s = String(512, 0)
    waveInGetErrorText errorcode, s, 512
    s = Left(s, InStr(s, Chr(0)) - 1)
    Print s

0
 

Author Comment

by:dand072297
ID: 1428706
y96andha,
Added Decl.Function waveInGetErrorText and your code snippet within If Statement: If error<> 0 Then
            Debug.Print "error".............
>>>
             errorcode = 32 ' for example
             s = String(512, 0)
 XXX         waveInGetErrorText errorcode, s, 512
             s = Left(s, InStr(s, Chr(0)) - 1)
             Debug.Print s
>>>
 Exit Sub
      ......................
Result:            error 32 in waveInOpen

      MsgBox:Error in loading DLL  (highlighting line XXX as above)

I have tried conventional Sample rates,11025, 22050 but error 32 persists. My Sound is audio tone in Aux Input and I have matched the Sound Blaster settings of Chan/sampleRate/BitsperSample with the coded values but the error 32 remains.
I am interested in your solution to my question but if this "error" problem persists perhaps you may give some consideration to my original requirement. I shall re-state my objective:
      By utilizing the existing ocx, MMControl I can record my Sound to a Buffer (MMControl1.Filename) and I can play this sound with MMControl1.Command="Play". I want to process the contents of MMControl1.FileName (Which I call say,"Mysound") in some other way, eg a Waveform Display.
      How do I find the Address of the Buffer "Mysound" ?
Thank you for your interest,                  dand

0
 
LVL 5

Expert Comment

by:y96andha
ID: 1428707
There seems to be an other problem with the waveInGetErrorText function. Did you use this declaration?:

Private Declare Function waveInGetErrorText Lib "winmm.dll" Alias "waveInGetErrorTextA" (ByVal err As Long, ByVal lpText As String, ByVal uSize As Long) As Long

Could you send me your source file to andreas.hansson@mbox303.swipnet.se? I would like to try and load it in my VB4, to see if exactly the same code works on my machine.

About the MMControl way: You need to save it to a file on your hard disk, and then you would have the trouble of parsing the file format in order to load the sample data.
0
 

Author Comment

by:dand072297
ID: 1428708
Your latest .exe program works on 1 out of 3 systems that I have tried it on. I'm trying to find out what the difference is and am concentrating on Sound cards. I would like to know what Sound Card you and your friends have or any other info that might help identify the cause of the error message.
Thanks for your help so far. Cheers, Dan
0
 
LVL 5

Expert Comment

by:y96andha
ID: 1428709
Both I and my friends have SB32's. Maybe not such a good test after all :-)

I'll see if I can try it on some other sound cards. What cards have you tested, and with what results?


0
 

Author Comment

by:dand072297
ID: 1428710
My sound card and friend #1 card are sb16 generic and show the error message :-(  Friend #2 card is a SB Pro/16 Emulator (AD1812), this card (or some other factor) handles the WaveIn program OK.    

0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Suggested Solutions

When trying to find the cause of a problem in VBA or VB6 it's often valuable to know what procedures were executed prior to the error. You can use the Call Stack for that but it is often inadequate because it may show procedures you aren't intereste…
Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.  What are they? An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now