iOS Question Beep particular frequency example

swabygw

Active Member
Licensed User
Longtime User
Is there an example available of how to make iOS generate a tone at a particular frequency and/or duration in B4I?

In B4A, it was simply (1) Dim b As Beeper, (2) b.Initialize(Duration, Frequency), (3) b.Beep.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
This code will create a wav file with the beep PCM data which you can then play with MediaPlayer:
B4X:
Sub Process_Globals
   Public App As Application
   Public NavControl As NavigationController
   Private Page1 As Page
   Private mp As MediaPlayer

End Sub

Private Sub Application_Start (Nav As NavigationController)
   NavControl = Nav
   Page1.Initialize("Page1")
   Page1.Title = "Page 1"
   Page1.RootPanel.Color = Colors.White
   NavControl.ShowPage(Page1)
   CreateBeepFile(File.DirLibrary, "1.wav", 1000, 500)
   mp.Initialize(File.DirLibrary, "1.wav", "mp")
   mp.Play
End Sub

Sub CreateBeepFile(Dir As String, FileName As String, Duration As Int, Frequency As Int)
   Dim sampleRate As Int = 8000
   Dim raf As RandomAccessFile = StartWaveFile(Dir, FileName, sampleRate, True, 16)
   Dim dur As Double = Duration / 1000
   Dim numSamples As Int = sampleRate * dur
   Dim generateSnd(2 * numSamples) As Byte
   Dim idx As Int = 0
   For i = 0 To numSamples - 1
     Dim d As Double = Sin(2 * cPI * i / (sampleRate / Frequency))
     Dim val As Short = d * 32767
     generateSnd(idx) = Bit.And(val, 0x00ff)
     generateSnd(idx + 1) = Bit.ShiftRight(Bit.And(val, 0xff00), 8)
     idx = idx + 2
   Next
   raf.WriteBytes(generateSnd, 0, generateSnd.Length, raf.CurrentPosition)
   'close
   raf.WriteInt(raf.Size - 8, 4)
   raf.WriteInt(raf.Size - 44, 40)
   raf.Close
End Sub

Sub StartWaveFile(Dir As String, FileName As String, SampleRate As Int, Mono As Boolean _
     , BitsPerSample As Int) As RandomAccessFile
   File.Delete(Dir, FileName)
   Dim raf As RandomAccessFile
   raf.Initialize2(Dir, FileName, False, True)
   raf.WriteBytes("RIFF".GetBytes("ASCII"), 0, 4, raf.CurrentPosition)
   raf.CurrentPosition = 8 'skip 4 bytes for the size
   raf.WriteBytes("WAVE".GetBytes("ASCII"),0, 4, raf.CurrentPosition)
   raf.WriteBytes("fmt ".GetBytes("ASCII"),0, 4, raf.CurrentPosition)
   raf.WriteInt(16, raf.CurrentPosition)
   raf.WriteShort(1, raf.CurrentPosition)
   Dim numberOfChannels As Int
   If Mono Then numberOfChannels = 1 Else numberOfChannels = 2
   raf.WriteShort(numberOfChannels, raf.CurrentPosition)
   raf.WriteInt(SampleRate, raf.CurrentPosition)
   raf.WriteInt(SampleRate * numberOfChannels * BitsPerSample / 8, raf.CurrentPosition)
   raf.WriteShort(numberOfChannels * BitsPerSample / 8, raf.CurrentPosition)
   raf.WriteShort(BitsPerSample, raf.CurrentPosition)
   raf.WriteBytes("data".GetBytes("ASCII"),0, 4, raf.CurrentPosition)
   raf.WriteInt(0, raf.CurrentPosition)
   Return raf
End Sub
 
Upvote 0

swabygw

Active Member
Licensed User
Longtime User
I've modified the Sub above to be able to play chords - hopefully useful to someone else.

B4X:
Sub CreateBeepFile(Dir As String, FileName As String, Duration As Int, Frequencies() As Double)
  'Dim Frequencies() As Int = Array As Int(440, 523, 659)
  Dim sampleRate As Int = 8000
  Dim raf As RandomAccessFile = StartWaveFile(Dir, FileName, sampleRate, True, 16)
  Dim dur As Double = Duration / 1000
  Dim numSamples As Int = sampleRate * dur
  Dim generateSnd(2 * numSamples) As Byte
  Dim idx As Int = 0
  Dim Amplitude As Double = (1 / Frequencies.Length)
  For i = 0 To numSamples - 1
    'Dim d As Double = Sin(2 * cPI * i / (sampleRate / Frequency))
    'Dim val As Short = d * 32767
    Dim val As Short
    val = 0
    For f = 0 To Frequencies.Length - 1
      val = val + (Sin(2 * cPI * i / (sampleRate / Frequencies(f))) * 32767 * Amplitude)
    Next
    generateSnd(idx) = Bit.And(val, 0x00ff)
    generateSnd(idx + 1) = Bit.ShiftRight(Bit.And(val, 0xff00), 8)
    idx = idx + 2
  Next
  raf.WriteBytes(generateSnd, 0, generateSnd.Length, raf.CurrentPosition)
  'close
  raf.WriteInt(raf.Size - 8, 4)
  raf.WriteInt(raf.Size - 44, 40)
  raf.Close
End Sub
 
Upvote 0

swabygw

Active Member
Licensed User
Longtime User
There's a physical, mechanical hammer inside the piano (piano is just one example) and it strikes a metallic wire (like strings on a guitar) when a particular note is pressed to produce a particular frequency. One tone/beep is one frequency, or one note. For example, the note A on the piano is 440.00 Hz. A chord is multiple frequencies played at once together, such as A minor chord, which is three tones (or beeps or notes) played together, 440.00 Hz, 523.25 Hz, 659.25 (the frequency is not random, it's physics - see link below).

The note A, in audio software programs like Cubase or ProTools, is transmitted via code called MIDI, where the note A in the middle of the piano would be 69 of 128 possible notes. A (western) musical instrument, like the piano, is just 12 notes repeated, with each repetition called an octave and assigned a number. The A in the middle of the piano, for example is A4 (below that A3, above that A5, etc.) - A4 is called its' "pitch".

Whatever the frequency is, it can be visually represented on a graph as a sine wave oscillating between -1 and +1, for example. In the case of multiple frequencies played at the same time, such as in a chord, it's like three sine waves layered on each other. Regardless of whether one frequency or multiple frequencies, they must sum to the same result. That is, they must oscillate within the same bounds (in my example, -1 or +1) - hence, the amplitude (the limiting sum) can be divided amongst the number of frequencies. Physically, the amplitude just raises or lowers the volume of each frequency: one note, 100% of the amplitude...three notes, each get 33% of the amplitude. The chord A minor 7 (notes: A, C, E, G or frequencies: 440, 523, 659, 784 or MIDI: 69, 72, 76, 79 or pitch: A4, C5, E5, G5), I would give each tone/beep 25% of the amplitude.

Frequencies: http://www.phy.mtu.edu/~suits/notefreqs.html

MIDI: https://www.midi.org/specifications/item/table-1-summary-of-midi-message

Frequency/MIDI determination: http://homes.soic.indiana.edu/donbyrd/INFO545Site-Spring07/MusicalPitchesTable.txt

Another Frequency/MIDI conversion chart: http://en.wikiaudio.org/MIDI_note_to_frequency_conversion_chart

Hope this helps (took me a long time to learn)!
 
Upvote 0
Top