Capture input from the Mic with FMOD

Source-code only - please, don't post questions here.
mambazo
Posts: 650
Joined: Jul 17, 2005 13:02
Location: Ireland
Contact:

Capture input from the Mic with FMOD

Postby mambazo » Dec 19, 2005 0:47

This is part of my final year project research... Which btw will be done in FreeBASIC! ;)

Code: Select all

option explicit
#include once "fmod.bi"

CONST FALSE = 0

SCREENRES 640,480,8

IF( FSOUND_Init(44100, 32, 0) = FALSE ) THEN
      PRINT "Can't initialize FMOD"
                end 1
END IF

DIM Rec_Buffer, posR, posP AS INTEGER
Rec_Buffer = FSOUND_SAMPLE_Alloc (0,3000, FSOUND_NORMAL OR FSOUND_LOOP_NORMAL, 44100, 100, 0, 1)

FSOUND_Record_StartSample ( Rec_Buffer, 1)

WHILE FSOUND_Record_GetPosition < 1500:WEND
FSOUND_PlaySound(1, Rec_Buffer)
FSOUND_SetCurrentPosition ( 1 , 0 )

DIM s_ptr1 AS INTEGER PTR
DIM s_ptr2 AS INTEGER PTR
DIM offset AS INTEGER
DIM length AS INTEGER
DIM s_len1 AS UNSIGNED INTEGER
DIM s_len2 AS UNSIGNED INTEGER

DIM i AS INTEGER
offset = 0
DO
   
   SCREENLOCK
   LINE (0,0)-(639,479),0,bf
   
   IF (FSOUND_Sample_Lock (Rec_Buffer, offset,640,@s_ptr1,@s_ptr2,@s_len1,@s_len2)=FALSE) THEN PRINT "Can't do lock!"
   
   PSET (0,240),4
   FOR i = 0 TO 640
   LINE -(i,(*(s_ptr1+i)/10000000)+240),4
   NEXT i
    IF offset + 640 < 3000 THEN offset+=640 ELSE offset = 0
    FSOUND_Sample_UnLock (Rec_Buffer, @s_ptr1, s_ptr2, s_len1, @s_len2)
    SCREENUNLOCK
   SLEEP 5
LOOP WHILE INKEY$ = ""

FSOUND_Record_Stop

FSOUND_Close

END




This grabs input from the mic or whatever you have selected in your mixer record settings, and it displays the osciliscope. Enjoy!
Last edited by mambazo on Dec 22, 2005 13:01, edited 3 times in total.
mambazo
Posts: 650
Joined: Jul 17, 2005 13:02
Location: Ireland
Contact:

Postby mambazo » Dec 19, 2005 0:52

comment out...

Code: Select all

WHILE FSOUND_Record_GetPosition < 1500:WEND
FSOUND_PlaySound(1, Rec_Buffer)
FSOUND_SetCurrentPosition ( 1 , 0 )


if you don't want it to play what its recording. (those lines were included just while testing guitar input from the mic-in)
mambazo
Posts: 650
Joined: Jul 17, 2005 13:02
Location: Ireland
Contact:

Postby mambazo » Dec 19, 2005 3:29

Here's a use for it... Like a winamp visualisation. Stick on some music, set you mixer record settings to select mono mix and run this code. Enjoy the warmth of the fire too ;)

Code: Select all

OPTION EXPLICIT
#INCLUDE ONCE "fmod.bi"

CONST FALSE = 0

SCREENRES 640,480,8,1,&h1

IF( FSOUND_Init(44100, 32, 0) = FALSE ) THEN
      PRINT "Can't initialize FMOD"
                END 1
END IF

DIM buffersize AS INTEGER
DIM Rec_Buffer AS INTEGER
buffersize = 3000
Rec_Buffer = FSOUND_SAMPLE_Alloc (0,buffersize, FSOUND_NORMAL OR FSOUND_LOOP_NORMAL, 44100, 100, 0, 1)

FSOUND_Record_StartSample ( Rec_Buffer, 1)

DIM s_ptr1 AS INTEGER PTR
DIM s_ptr2 AS INTEGER PTR
DIM offset AS INTEGER
DIM length AS INTEGER
DIM s_len1 AS UNSIGNED INTEGER PTR
DIM s_len2 AS UNSIGNED INTEGER PTR

DIM i AS INTEGER
DIM c AS INTEGER
DIM c1 AS UBYTE
DIM c2 AS UBYTE
DIM c3 AS UBYTE
DIM c4 AS UBYTE
DIM c5 AS UBYTE

DIM framebuffer AS BYTE PTR
framebuffer = SCREENPTR

offset = 0

FOR i = 0 TO 255
IF i > 127 THEN c = i*2
IF i > 192 THEN c1 = i * 1.7
PALETTE i,i,c,c1
NEXT i

DIM By640(480) AS LONG
DIM Div5(256*5) AS UBYTE
DIM x AS INTEGER
DIM y AS INTEGER

FOR i = 0 TO 480
By640(i) = i * 640
NEXT i
FOR i =  0 TO 256*5
Div5(i) = INT(i/5)
NEXT i
SETMOUSE ,,0
c = 0
DO
   SCREENLOCK
   
   IF (FSOUND_Sample_Lock (Rec_Buffer, offset,640,@s_ptr1,@s_ptr2,@s_len1,@s_len2)=FALSE) THEN PRINT "Can't do lock!"
   
   c = INT(RND*128)+127
   PSET (0,440),c
   FOR i = 0 TO 640
   LINE -(i,(*(s_ptr1+i)/10000000)+440),c
   NEXT i
   IF offset + 640 <= buffersize THEN offset+=640 ELSE offset = 0
   FSOUND_Sample_UnLock (Rec_Buffer, @s_ptr1, @s_ptr2, @s_len1, @s_len2)
   
   LINE (0,475)-(639,479),0,bf
   
   FOR x = 0 TO 639
   FOR y = 3 TO 478
   'c = Div5(POINT(x,y+1) + POINT(x,y-1) + POINT(x+1,y) + POINT(x,y) + POINT(x-1,y)) -1
   'c = Div5(PEEK(framebuffer+((y+1)*640)+x) + PEEK(framebuffer+((y-1)*640)+x) + PEEK(framebuffer+((y)*640)+x+1) + POINT(x,y) + PEEK(framebuffer+((y+1)*640)+x-1)) -1
   c1 = PEEK(framebuffer+(by640(y+1))+x)
   c2 = PEEK(framebuffer+(by640(y-1))+x)
   c3 = PEEK(framebuffer+(by640(y))+x)
   c4 = PEEK(framebuffer+(by640(y))+x+1)
   IF x > 0 THEN c5 = PEEK(framebuffer+(by640(y))+x-1) ELSE c5 = 0
   c = Div5(c1+c2+c3+c4+c5) - 1
   IF c < 0 THEN c = 0
   POKE framebuffer+((y-3)*640)+x,c
   NEXT y
   NEXT x
   
   SCREENUNLOCK
   SLEEP 5
LOOP WHILE INKEY$ = ""

FSOUND_Record_Stop

FSOUND_Close
SLEEP
SETMOUSE ,,1
END
Ryan
Posts: 693
Joined: Jun 10, 2005 2:13
Location: Louisville, KY
Contact:

Postby Ryan » Dec 19, 2005 6:27

I'd love to go find a mic and test this out for you.. I'm sure I have one laying around somewhere. I'll let ya know if I find one. ^_^
blahboybang
Posts: 385
Joined: Oct 16, 2005 0:15
Location: USA
Contact:

Postby blahboybang » Dec 20, 2005 22:22

Is there a way to make it record to a sound file? also, would you mind if I put this on my website?
Sisophon2001
Posts: 1702
Joined: May 27, 2005 6:34
Location: Cambodia, Thailand, Lao, Ireland etc.
Contact:

Postby Sisophon2001 » Dec 22, 2005 11:07

Hi mambazo

I tried this code last night, and it looks very well.

I modified it to remove warnings during compile, and in the process I noticed what may be a bug. You defined s_len1 and s_len2 as unsigned integer pointers, but I needed to change them to unsigned integers, and also modify the final two parameters of the function FSOUND_Sample_UnLock().

Obviously it must have worked as you coded it, but from checking the function definitions, this looks correct, and it removes the warnings. Perhaps the fmod headerfiles changed?

Have fun.

Garvan

FreeBASIC 0.15

Code: Select all

option explicit
#include once "fmod.bi"

const FALSE = 0
const TRUE = not FALSE


   SCREENRES 640,480,8,1,&h1

   if( FSOUND_Init(44100, 32, 0) = FALSE ) then
      print "Can't initialize FMOD"
      end 1
   end if

   dim buffersize as integer
   dim Rec_Buffer as FSOUND_SAMPLE ptr 'integer
   buffersize = 3000
   Rec_Buffer = FSOUND_SAMPLE_Alloc (0,buffersize, FSOUND_NORMAL or FSOUND_LOOP_NORMAL, 44100, 100, 0, 1)

   FSOUND_Record_StartSample ( Rec_Buffer, 1)

   dim s_ptr1 as integer ptr
   dim s_ptr2 as integer ptr
   dim offset as integer
   dim length as integer
   dim s_len1 as unsigned integer
   dim s_len2 as unsigned integer

   dim i as integer
   dim c as integer
   dim c1 as ubyte
   dim c2 as ubyte
   dim c3 as ubyte
   dim c4 as ubyte
   dim c5 as ubyte

   dim framebuffer as byte ptr
   framebuffer = screenptr

   offset = 0

   for i = 0 to 255
      if i > 127 then c = i*2
      if i > 192 then c1 = i * 1.7
      palette i,i,c,c1
   next i

   dim By640(480) as long
   dim Div5(256*5) as ubyte
   dim x as integer
   dim y as integer

   for i = 0 to 480
      By640(i) = i * 640
   next i
   for i =  0 to 256*5
      Div5(i) = int(i/5)
   next i
   SETMOUSE ,,0
   c = 0
   do
      screenlock

      if (FSOUND_Sample_Lock (Rec_Buffer, offset,640,@s_ptr1,@s_ptr2,@s_len1,@s_len2)=FALSE)  then print "Can't do lock!"

      c = int(rnd*128)+127
      pset (0,440),c
      for i = 0 to 640
         line -(i,(*(s_ptr1+i)/10000000)+440),c
      next i
      if offset + 640 <= buffersize then offset+=640 else offset = 0
      FSOUND_Sample_UnLock (Rec_Buffer, @s_ptr1, @s_ptr2, s_len1, s_len2)

      line (0,475)-(639,479),0,bf

      for x = 0 to 639
         for y = 3 to 478
            'c = Div5(POINT(x,y+1) + POINT(x,y-1) + POINT(x+1,y) + POINT(x,y) + POINT(x-1,y)) -1
            'c = Div5(PEEK(framebuffer+((y+1)*640)+x) + PEEK(framebuffer+((y-1)*640)+x) + PEEK(framebuffer+((y)*640)+x+1) + POINT(x,y) + PEEK(framebuffer+((y+1)*640)+x-1)) -1
            c1 = peek(framebuffer+(by640(y+1))+x)
            c2 = peek(framebuffer+(by640(y-1))+x)
            c3 = peek(framebuffer+(by640(y))+x)
            c4 = peek(framebuffer+(by640(y))+x+1)
            if x > 0 then c5 = peek(framebuffer+(by640(y))+x-1) else c5 = 0
            c = Div5(c1+c2+c3+c4+c5) - 1
            if c < 0 then c = 0
            poke framebuffer+((y-3)*640)+x,c
         next y
      next x

      screenunlock
      sleep 5
   loop while inkey$ = ""

   FSOUND_Record_Stop

   FSOUND_Close
   sleep
   SETMOUSE ,,1
   end
mambazo
Posts: 650
Joined: Jul 17, 2005 13:02
Location: Ireland
Contact:

Postby mambazo » Dec 22, 2005 12:53

You're absolutely right!

Blahboyband, yes it is possible as far as i can see. You may want to alter the recording process such that you have a much larger buffer to record into. Then you can use FSOUND_Record_GetPosition to find out how far into the buffer the recording is taking place, and append all data up to that point into file. You will notice though, that as the record buffer is cyclic it is very difficult to piece the stream together properly.

You can also set the recording to not be cyclic. When it reaches the end of the sample buffer it stops. So you could wait for it to fill the buffer, then save that data to file, then fill the buffer again and so on.

This still produces some weird glitches though...
blahboybang
Posts: 385
Joined: Oct 16, 2005 0:15
Location: USA
Contact:

Postby blahboybang » Dec 22, 2005 19:04

Would you mind if I put this on my website?
blahboybang
Posts: 385
Joined: Oct 16, 2005 0:15
Location: USA
Contact:

Postby blahboybang » Jan 07, 2006 0:21

Mambazo, can I put this on my website?
mambazo
Posts: 650
Joined: Jul 17, 2005 13:02
Location: Ireland
Contact:

Postby mambazo » Jan 07, 2006 0:24

Certainly. I think I have a tidier version somewhere also, if you want that instead.
12val12
Posts: 13
Joined: Jun 06, 2006 12:32

Re: Capture input from the Mic with FMOD

Postby 12val12 » Jun 06, 2006 12:48

mambazo wrote:This is part of my final year project research... Which btw will be done in FreeBASIC! ;)

Code: Select all

option explicit
#include once "fmod.bi"

CONST FALSE = 0

SCREENRES 640,480,8

IF( FSOUND_Init(44100, 32, 0) = FALSE ) THEN
      PRINT "Can't initialize FMOD"
                end 1
END IF

DIM Rec_Buffer, posR, posP AS INTEGER
Rec_Buffer = FSOUND_SAMPLE_Alloc (0,3000, FSOUND_NORMAL OR FSOUND_LOOP_NORMAL, 44100, 100, 0, 1)

FSOUND_Record_StartSample ( Rec_Buffer, 1)

WHILE FSOUND_Record_GetPosition < 1500:WEND
FSOUND_PlaySound(1, Rec_Buffer)
FSOUND_SetCurrentPosition ( 1 , 0 )

DIM s_ptr1 AS INTEGER PTR
DIM s_ptr2 AS INTEGER PTR
DIM offset AS INTEGER
DIM length AS INTEGER
DIM s_len1 AS UNSIGNED INTEGER
DIM s_len2 AS UNSIGNED INTEGER

DIM i AS INTEGER
offset = 0
DO
   
   SCREENLOCK
   LINE (0,0)-(639,479),0,bf
   
   IF (FSOUND_Sample_Lock (Rec_Buffer, offset,640,@s_ptr1,@s_ptr2,@s_len1,@s_len2)=FALSE) THEN PRINT "Can't do lock!"
   
   PSET (0,240),4
   FOR i = 0 TO 640
   LINE -(i,(*(s_ptr1+i)/10000000)+240),4
   NEXT i
    IF offset + 640 < 3000 THEN offset+=640 ELSE offset = 0
    FSOUND_Sample_UnLock (Rec_Buffer, @s_ptr1, s_ptr2, s_len1, @s_len2)
    SCREENUNLOCK
   SLEEP 5
LOOP WHILE INKEY$ = ""

FSOUND_Record_Stop

FSOUND_Close

END




This grabs input from the mic or whatever you have selected in your mixer record settings, and it displays the Enjoy!


please !The same ,but stereo (two chanel ,96000 Hz ,16bit).
(osciliscope two different colors)
Thank you.!
relsoft
Posts: 1767
Joined: May 27, 2005 10:34
Location: Philippines
Contact:

Postby relsoft » Jun 06, 2006 13:03

Cool!!!!
mambazo
Posts: 650
Joined: Jul 17, 2005 13:02
Location: Ireland
Contact:

Postby mambazo » Jun 06, 2006 23:25

Woah, thats really old code. Its glitchy too. I have a much better example here...

Code: Select all

' Matthew Hart
' DNET4
' 02090201
' 10-01-06

OPTION EXPLICIT
#INCLUDE ONCE "fmod.bi"

' Init constants for FMOD
CONST FALSE = 0
CONST BUFFERSIZE = 2^14
CONST BUFFERBYTES = BUFFERSIZE * 2

IF( FSOUND_Init(44100, 32, 0) = FALSE ) THEN
   PRINT "Can't initialize FMOD"
   END 1
END IF

DIM AS INTEGER Rec_Buffer

' for sample lock
DIM s_ptr1 AS SHORT PTR
DIM s_ptr2 AS SHORT PTR
DIM offset AS INTEGER
DIM length AS INTEGER
DIM s_len1 AS UNSIGNED INTEGER
DIM s_len2 AS UNSIGNED INTEGER

DIM i AS INTEGER
DIM c AS INTEGER
DIM x AS INTEGER

DIM AS INTEGER itr,cycles
DIM AS DOUBLE t

DIM j AS DOUBLE
DIM y AS INTEGER


' This is the amount of bytes behind the
' record cursor that we want to lock.
' Each sample is 2 bytes, so we want
' to get twice the width of the screen
' in bytes.
length = 1280

' set screen resolution
SCREENRES 640,480,8,1

' create the palette
FOR i = 0 TO 255
IF i > 127 THEN c = i*2
IF i > 192 THEN x = i * 1.7
PALETTE i,i,c,x
NEXT i

' start the record buffer
Rec_Buffer = FSOUND_SAMPLE_Alloc (FSOUND_UNMANAGED, _
         BUFFERSIZE, FSOUND_NORMAL, 44100, 255, _
         128, 255)
FSOUND_Record_StartSample ( Rec_Buffer, 1)

t = TIMER
itr = 0

DO
      IF TIMER > (t + 1) THEN
         t = TIMER
         cycles = itr
         itr = 0
      END IF
      itr += 1
      
      offset = (FSOUND_Record_GetPosition() * 2) - length
      IF offset < 0 THEN offset += (BUFFERBYTES)
      
      IF FSOUND_Sample_Lock (Rec_Buffer, offset, _
            length, @s_ptr1, @s_ptr2, @s_len1, _
            @s_len2) = 1 THEN
         
         SCREENLOCK
         ' plot buffer contents

         LINE (0,0)-(639,479),0,bf
         PSET (-1,y),255
         x = 0
         y = 240
         
         FOR i = 0 TO (s_len1 SHR 1) -1
            j = ((s_ptr1[i])*.002)+y
            LINE -(x,j),255
            x+=1
            IF x > 640 THEN x = 0:y += 150: PSET (-1,y),200
         NEXT i
         
         ' if the buffer has wrapped then get the
         ' second chunk (at the start of the buffer)
         IF s_ptr2 THEN
            LOCATE 3,1: COLOR 200: PRINT "Wrapped!"
            FOR i = 0 TO (s_len2 SHR 1) -1
               j = ((s_ptr2[i])*.002)+y
               LINE -(x,j),200
               x+=1
               IF x > 640 THEN x = 0:y += 150: PSET (-1,y),200
            NEXT i
         END IF
         
         LOCATE 1,1: COLOR 255: PRINT "Real-Time Audio Data Capture - Matthew Hart - DNET4 - 02090201 - 12-01-06"
         PRINT "Cycles per second: = "; cycles
         SCREENUNLOCK
         
         FSOUND_Sample_UnLock (Rec_Buffer, @s_ptr1, @s_ptr2, s_len1, s_len2)
      ELSE
         PRINT "Something CRAZY just happened!"
      END IF
        SLEEP 1
LOOP WHILE INKEY$ = ""

FSOUND_Record_Stop
FSOUND_Sample_Free(Rec_Buffer)
FSOUND_Close
SLEEP

END
12val12
Posts: 13
Joined: Jun 06, 2006 12:32

Postby 12val12 » Jun 08, 2006 16:30

iTS NO RICHT BUT WORKS 96000 hZ (SOLO 1 ess1938)possible works with any 96 khz saund card.

Code: Select all

' Matthew Hart
' DNET4
' 02090201
' 10-01-06

OPTION EXPLICIT
#INCLUDE ONCE "fmod.bi"

' Init constants for FMOD
CONST FALSE = 0
CONST BUFFERSIZE = 2^14
CONST BUFFERBYTES = BUFFERSIZE * 2

IF( FSOUND_Init(44100, 32, 0) = FALSE ) THEN
   PRINT "Can't initialize FMOD"
   END 1
END IF

DIM AS INTEGER Rec_Buffer

' for sample lock
DIM s_ptr1 AS SHORT PTR
DIM s_ptr2 AS SHORT PTR
DIM offset AS INTEGER
DIM length AS INTEGER
DIM s_len1 AS UNSIGNED INTEGER
DIM s_len2 AS UNSIGNED INTEGER

DIM i AS INTEGER
DIM c AS INTEGER
DIM x AS INTEGER

DIM AS INTEGER itr,cycles
DIM AS DOUBLE t

DIM j AS DOUBLE
DIM y AS INTEGER


' This is the amount of bytes behind the
' record cursor that we want to lock.
' Each sample is 2 bytes, so we want
' to get twice the width of the screen
' in bytes.
length = 1280

' set screen resolution
SCREENRES 640,480,8,1

' create the palette
FOR i = 0 TO 255
IF i > 127 THEN c = i*2
IF i > 192 THEN x = i * 1.7
PALETTE i,i,c,x
NEXT i

' start the record buffer
Rec_Buffer = FSOUND_SAMPLE_Alloc (FSOUND_UNMANAGED, _
         BUFFERSIZE, FSOUND_NORMAL, 96000, 255, _
         128, 255)         '           44100 -->96000
FSOUND_Record_StartSample ( Rec_Buffer, 1)

t = TIMER
itr = 0

DO
      IF TIMER > (t + 1) THEN
         t = TIMER
         cycles = itr
         itr = 0
      END IF
      itr += 1
       
      offset = (FSOUND_Record_GetPosition() * 2) - length
      IF offset < 0 THEN offset += (BUFFERBYTES)
       
      IF FSOUND_Sample_Lock (Rec_Buffer, offset, _
            length, @s_ptr1, @s_ptr2, @s_len1, _
            @s_len2) = 1 THEN
         
         SCREENLOCK
         ' plot buffer contents

         LINE (0,0)-(639,479),0,bf
         PSET (-1,y),255
         x = 0
         y = 240
         
         FOR i = 0 TO (s_len1 SHR 1) -1
            j = ((s_ptr1[i])*.002)+y
            LINE -(x,j),255
            x+=1
            IF x > 640 THEN x = 0:y += 150: PSET (-1,y),200
         NEXT i
           
         ' if the buffer has wrapped then get the
         ' second chunk (at the start of the buffer)
      IF s_ptr2 THEN                               'will be del
       LOCATE 3,1                                  'will be del
      COLOR 200:PRINT "Wrapped!"'-not visible!!! 'will be del
           FOR i = 0 TO (s_len2 SHR 1) -1  'will be del
           j = ((s_ptr2[i])*.002)+y             'will be del
            LINE -(x,j),200                          'will be del
            x+=1                                       'will be del
         NEXT i                                           'will be del
      END IF                                              'will be del
         
         LOCATE 1,1: COLOR 255: PRINT "Real-Time Audio Data Capture - Matthew Hart - DNET4 - 02090201 - 12-01-06"
         PRINT "Cycles per second: = "; cycles
         SCREENUNLOCK
         
         FSOUND_Sample_UnLock (Rec_Buffer, @s_ptr1, @s_ptr2, s_len1, s_len2)
      ELSE
         PRINT "Something CRAZY just happened!"
      END IF
        SLEEP 1
LOOP WHILE INKEY$ = ""

FSOUND_Record_Stop
FSOUND_Sample_Free(Rec_Buffer)
FSOUND_Close
SLEEP

END
Jojo
Posts: 107
Joined: Jan 04, 2006 20:02
Contact:

Postby Jojo » Jun 09, 2006 19:51

I didn't read the whole thread... but is there a possibility to record the audio data which is played back? I need that for a programme.... i don't want to record something from the line-in but from the played audio...

Return to “Tips and Tricks”

Who is online

Users browsing this forum: No registered users and 3 guests