Android Question Reading data from microphone

Isa Paine

Member
Licensed User
Longtime User
I have a thermometer that is providing a frequency of 600Hz, room temperature, to my Samsung Galaxy S5 through the 3.5mm. With an oscilloscope I can see that a square wave is being provided to the phone but the data read in using the AudioStreamer library does not follow the pattern of a square wave. it goes from one extreme to the next with no square wave in the data.

What could be causing this? Why doesn't the data follow the flow of a square wave?

Am I some how not reading the external 3.5mm jack input?

Please help.

Here is the pertinent parts of the code:

B4X:
Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("Portrait")
    If FirstTime Then
        streamer.Initialize("streamer", SampleRate, True, 16, streamer.VOLUME_MUSIC)
        buffers.Initialize
        tmrTemp.Initialize("tmrTemp", 1)
        tmrTemp.Enabled = False
    End If
End Sub

Sub startRecording(duration As Int)
    buffers.Clear
    streamer.startRecording
    tmrTemp.Interval = duration * 1000
    tmrTemp.Enabled = True
End Sub

Sub stopRecording
    streamer.StopRecording
    AudioUtils.GetFrequency(buffers)
End Sub
 
Sub GetFrequency(buffers As List) As Double

    'Dim b_Array() As Byte
    Dim frequency As Double
    'Conv.LittleEndian = False
    Dim dataIndex As Int : dataIndex = 0
    Dim MyTextWriter As TextWriter
    MyTextWriter.Initialize(File.OpenOutput(File.DirRootExternal, "values.csv",False))
   
    For Each byteArray() As Byte In buffers
        Dim y_Voltage() As Short

        y_Voltage = Conv.ShortsFromBytes(byteArray)
        For index = 0 To y_Voltage.Length -1
            Dim y_VoltageString As String
            y_VoltageString = y_Voltage(index)
            MyTextWriter.WriteLine(y_VoltageString)
        Next
        dataIndex = dataIndex + 1
    Next
    MyTextWriter.Close
    Return frequency
End Sub
 

stevel05

Expert
Licensed User
Longtime User
As I explained in a previous post, you need to check the sample size and endieness (if more than 8 bits) of the sample to be able to get meaningful data from the stream. You are reading shorts and assuming 16 bits. Also whether it is a mono or stereo signal will make a difference to how you need to decode it.
 
Upvote 0

Isa Paine

Member
Licensed User
Longtime User
Sample Rate : 44100
Conv.LittleEndian = False
The thermometer is sending a mono signal.

I reran it with Conv.LittleEndian = False before converting the bytes to shorts and still the data is one extreme to the next.

What would you suggest?
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
If the incoming data still doesn't make sense, it's possible that the data is something other than 16bit. Do you know the expected range of input values? Is there a spec for the thermometer on the internet?, you could confirm these details.
 
Upvote 0

Isa Paine

Member
Licensed User
Longtime User
I have downloaded g-String, which is a guitar tuning app.
I have plugged the thermometer into the 3.5mm jack and g-String displays 600Hz in a sine wave.
But when I use the code i have written, as shown above, the data is high/low/high/low etc.
 
Upvote 0

Isa Paine

Member
Licensed User
Longtime User
Downloaded the Audio Scope app you recommended and it displays the same wave that my actual oscilloscope is showing.
So based on this what are your recommendations.

Am I using the Audio Stream object incorrectly? What am I doing wrong.

I thinking I might have to use Android Studio, which would not be fun since of the learning curve with Java.

What do you recommend?
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
Android Studio? It won't make any difference to the incoming signal. Can you post a recording of 10 seconds of the input?
 
Upvote 0

Isa Paine

Member
Licensed User
Longtime User
The code that produces the csv file is the
B4X:
GetFrequency(buffers As List) As Double
function as see below, and modified slightly from above.

I have attached a csv file of the data.

Android Studio is the IDE produced by Google. I was wondering if switching to straight java, would that help solve the problem. But I'd rather not at this point.

B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    Dim Conv As ByteConverter
    Dim VOLTAGE_THRESHOLD As Double : VOLTAGE_THRESHOLD = .5
    Dim index As Int  = 0
End Sub

Sub GetFrequency(buffers As List) As Double

    Dim frequency As Double
    Dim dataIndex As Int : dataIndex = 0
    Dim MyTextWriter As TextWriter
    MyTextWriter.Initialize(File.OpenOutput(File.DirRootExternal, "audioValues.csv",False))
    MyTextWriter.WriteLine("Time,Value")
  
    For Each byteArray() As Byte In buffers
        Dim y_Voltage() As Short
      
        Conv.LittleEndian = False
      
        y_Voltage = Conv.ShortsFromBytes(byteArray)

        For index = 0 To y_Voltage.Length -1
            Dim y_VoltageString As String
            y_VoltageString = y_Voltage(index)          
            time = (1/44100) * index
            MyTextWriter.WriteLine(time & "," & y_VoltageString)
            index = index + 1
        Next
        dataIndex = dataIndex + 1
    Next
    MyTextWriter.Close
    Return frequency
End Sub
 
Upvote 0

Isa Paine

Member
Licensed User
Longtime User
Here is the file: Because of the 512k limit I could give you 10 seconds of data. But this shows my problem.
 

Attachments

  • audioValueTesting.txt
    177.4 KB · Views: 492
Upvote 0

Isa Paine

Member
Licensed User
Longtime User
Can I suggest you open the txt file in Excel and use a line graph to see the pattern of the data. Just by looking at the numbers you can see to numbers go from one extreme to another. To create the wave file I'll have to wait for tomorrow.

Really do appreciate your help.

Do you see any problem in my code?
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
I'm afraid I don't have excel, Google Sheets won't support enough entries to display anything meaningful. I'll wait for the audio file.
 
Upvote 0

Isa Paine

Member
Licensed User
Longtime User
stevel05,

First I'd like to express gratitude for your continuing efforts to assist me.

Here is what I've done.

1) I used the resident Samsung Voice Recorder App to record 10 seconds of the 440 Hz that is being pumped into the 3.5mm jack mic.
The sound was saved in m4a format.
2) I converted the m4a file to mp3.
3) I ran the mp3 through Visualizer-WavForm. The result can be seen in the uploaded screenshot: Vizualizer-WavForm.png
4) I then ran PitchLab, which read the 440 Hz directly from the 3.5mm jack mic. The results can be seen in the screenshot: PitchLab.png
5) oscilloscope.png is a screen shot of the oscilloscope that I have hooked up to my phone showing that an excellent 440Hz wave signal is being send into the 440 Hz jack.

I don't understand the Vizualizer-WavForm screenshot, is that what a proper wave will look like? Why is it different from PitchLab?

What would you suggest I do now?
 

Attachments

  • Vizualizer-WavForm.png
    Vizualizer-WavForm.png
    231.4 KB · Views: 544
  • PitchLab.png
    PitchLab.png
    278.9 KB · Views: 523
  • oscilloscope.png
    oscilloscope.png
    181.1 KB · Views: 514
Upvote 0

stevel05

Expert
Licensed User
Longtime User
If you turn the gain down a little, you will see the peaks, it will be a little distorted as the Android visualizer only returns some samples of the signal, not every sample. But from the last two images it looks like you are getting a sine wave and not a square wave.

The problem could be that you are receiving a mono signal, but the capture is Stereo by default. You could try ignoring every other sample. This should give you a mono capture. Or you could try using the AudioRecord library which will allow to capture a mono signal.

Or you could post or send me the mp3 if it's too big, and I'll take a look tomorrow. I'm out for the rest of the day. Send it to steve@stevel05.com and I'll take a look.
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
Have you tried playing back the captured audio from the audio streamer example? Does it sound like the original?
 
Upvote 0

Isa Paine

Member
Licensed User
Longtime User
I have not played the sound back because it is not a song. It is a frequency that is piped into the 3.5mm jack.
The problem is converting it to a wave sine.

In my above code example am I properly converting the data from the byte stream to numbers?
If that conversion is correct, what could the problem be?

Oh and yes I have used the Audio Stream library and the same problem exists. The data goes from one extreme to the other.
 
Last edited:
Upvote 0

stevel05

Expert
Licensed User
Longtime User
The sine wave has a pure sound, I think you may be capturing the devices mic input and not the input from the audio jack, please try playing the recorded sound.
 
Upvote 0

Isa Paine

Member
Licensed User
Longtime User
I played the sound and to my ear it sounds like an A note.
At the time I was inputing 440Hz, which is the frequency of an A note.

How can I ensure I'm reading sound from the external mic?
I contacted PitchLab, and you can see from the screen shot their software displays a wave, and they said in their app they don't disable or enable either internal or external mic. They continued, that the external mic turned on automatically.
 
Last edited:
Upvote 0
Top