Platforms to show: All Mac Windows Linux Cross-Platform

/Audio/PortAudio Record and Play


Required plugins for this example: MBS Audio Plugin, MBS DataTypes Plugin

You find this example project in your Plugins Download as a Xojo project file within the examples folder: /Audio/PortAudio Record and Play

This example is the version from Tue, 28th Oct 2019.

Project "PortAudio Record and Play.xojo_binary_project"
Class App Inherits Application
Const kEditClear = "&Delete"
Const kFileQuit = "&Quit"
Const kFileQuitShortcut = ""
End Class
Class MainWindow Inherits Window
Control InfoLabel Inherits Label
ControlInstance InfoLabel Inherits Label
End Control
Control RecordButton Inherits PushButton
ControlInstance RecordButton Inherits PushButton
EventHandler Sub Action() StartRecording End EventHandler
End Control
Control PlayButton Inherits PushButton
ControlInstance PlayButton Inherits PushButton
EventHandler Sub Action() Play End EventHandler
End Control
Control SaveButton Inherits PushButton
ControlInstance SaveButton Inherits PushButton
EventHandler Sub Action() save End EventHandler
End Control
Control Output Inherits Canvas
ControlInstance Output Inherits Canvas
EventHandler Sub Paint(g As Graphics, areas() As REALbasic.Rect) #Pragma unused areas If out <> Nil Then g.DrawPicture out, 0, 0, g.Width, g.Height, 0, 0, out.Width, out.Height End If End EventHandler
End Control
Control StopButton Inherits PushButton
ControlInstance StopButton Inherits PushButton
EventHandler Sub Action() StopRecording End EventHandler
End Control
Control RecorderTimer Inherits Timer
ControlInstance RecorderTimer Inherits Timer
EventHandler Sub Action() // we ask for samples in the buffer Dim l As Integer = Recorder.ReadFrames(temp, temp.Size) If l > 0 Then RecordedData.Add temp, l*4 // 4 bytes per sample // process the l frames we got ProcessFrames temp, l end if End EventHandler
End Control
EventHandler Sub Open() po = New PortAudioMBS End EventHandler
Sub Play() If RecordedData = Nil Then Return // no data // get samples Dim audioBuffer As MemoryBlock = RecordedData.CopyMemory Dim c As New PortAudioStreamBufferedMBS Dim e As Integer = c.OpenDefaultStream(1, SampleRate) System.DebugLog "OpenDefaultStream: "+Str(e) If e = 0 Then Else MsgBox "Host Error: "+Str(c.HostError) Return End If If Not c.AddFloatAudio(audioBuffer) Then MsgBox "Failed to play audio!" Return Else System.DebugLog "AddFloatAudio ok" e=c.Start System.DebugLog "Start: "+Str(e) e=c.IsStreamActive System.DebugLog "Active: "+Str(e) PlayStream = c End If End Sub
Sub ProcessFrames(m as MemoryBlock, l as integer) // show In canvas dim c as integer = l-1 // just find min and max and display it here Dim b As Double = m.SingleValue(0) Dim mi As Double = b Dim ma As Double = b For i As Integer = 0 To c b = m.SingleValue(4*i) If b > ma Then ma = b End If If b < mi Then mi = b End If next // scale so we see more 'ma = ma * 2.0 'mi = mi * 2.0 ma = abs(ma) mi = abs(mi) // draw to the screen directly Dim w As Integer = Output.width Dim h As Integer = Output.Height Dim h2 As Double = h/2 If out = Nil Or out.Width <> w Or out.Height <> h Then out = New Picture(w, h, 32) End If Dim g As Graphics = out.Graphics g.ForeColor=&cFFFFFF g.DrawLine index, 0, index, h g.ForeColor=&cFF0000 g.DrawLine index, h2, index, h2 - ma * h2 g.ForeColor=&c00FF00 g.DrawLine index, h2, index, h2 + mi * h2 Output.Invalidate // move to the next line index = index + 1 If index = w Then index = 0 end if End Sub
Sub Save() // save as WAV // for more options, please use SoundFileMBS class Dim size As Integer=0 Dim f As FolderItem = GetSaveFolderItem(FileTypes1.AudioWav,"audio.wav") If f <> Nil Then Dim b As BinaryStream = f.CreateBinaryFile(FileTypes1.AudioWav) If b = Nil Then MsgBox "Failed to create file " + f.NativePath Else Dim buf As MemoryBlock = RecordedData.CopyMemory Dim samples As Integer = buf.size \ 4 // convert to 16-bit data Dim x As New MemoryBlock(samples*2) x.LittleEndian=True Dim p As Integer = 0 Dim q As Integer = 0 Dim c As Integer = samples-1 For i As Integer = 0 To c x.Short(q) = buf.SingleValue(p) * 32767.0 p = p + 4 q = q + 2 Next size = size + x.size b.LittleEndian=True b.Write "RIFF" b.WriteInt32 6+4+16+4+Size // size of file b.Write "WAVE" b.Write "fmt " b.WriteInt32 16 // size of following data b.WriteInt16 1 // format, uncompressed b.WriteInt16 1 // 1 Channel b.WriteInt32 SampleRate // Samples per Second b.WriteInt32 SampleRate * 2 // Bytes per Second b.WriteInt16 2 // Block align, Size of Sample in Bytes b.WriteInt16 16 // bits per sample b.Write "data" b.WriteInt32 Size b.Write x b.Close End If End If End Sub
Sub StartRecording() SampleRate = 48000 // Native Frequency of my Macbook Dim defaultInputDevice As Integer = po.DefaultInputDeviceID Dim deviceInfo As PortAudioDeviceInfoMBS = po.DeviceInfo(defaultInputDevice) If deviceInfo <> Nil Then SampleRate = deviceInfo.DefaultSampleRate System.DebugLog "SampleRate: "+Str(SampleRate) End If Recorder = New PortAudioStreamRecorderMBS(1024 * 1024) // read 1 second maximum per timer loop temp = New MemoryBlock(4 * SampleRate) RecordedData = New StringHandleMBS If Recorder.OpenDefaultStream(1, SampleRate) = 0 Then If Recorder.Start = 0 Then RecorderTimer.Mode = RecorderTimer.ModeMultiple PlayButton.Enabled = false StopButton.Enabled = True Else MsgBox "Failed to start recording." End If Else MsgBox "Failed to initialize." End If End Sub
Sub StopRecording() RecorderTimer.Mode = timer.ModeOff If Recorder <> Nil Then Call Recorder.Close Recorder = Nil End If temp = Nil StopButton.Enabled = False RecordButton.Enabled = True PlayButton.Enabled = True SaveButton.Enabled = True End Sub
Property PlayStream As PortAudioStreamBufferedMBS
Property RecordedData As StringHandleMBS
Property Recorder As PortAudioStreamRecorderMBS
Property SampleRate As Integer = 44100
Property index As Integer
Property out As Picture
Property po As PortAudioMBS
Property temp As MemoryBlock
End Class
MenuBar MainMenuBar
MenuItem FileMenu = "&File"
MenuItem FileQuit = "#App.kFileQuit"
MenuItem EditMenu = "&Edit"
MenuItem EditUndo = "&Undo"
MenuItem EditSeparator1 = "-"
MenuItem EditCut = "Cu&t"
MenuItem EditCopy = "&Copy"
MenuItem EditPaste = "&Paste"
MenuItem EditClear = "#App.kEditClear"
MenuItem EditSeparator2 = "-"
MenuItem EditSelectAll = "Select &All"
End MenuBar
ExternalFile info
End ExternalFile
FileTypes1
Filetype audio/wav
End FileTypes1
End Project

See also:

The items on this page are in the following plugins: MBS Audio Plugin.


The biggest plugin in space...