[Solved] Microphone won't start on Android

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
qwdqwqwffqw
Prole
Posts: 21
Joined: Sat Jan 25, 2020 4:11 pm

[Solved] Microphone won't start on Android

Post by qwdqwqwffqw »

Hello. I've been recently testing out new 11.3 features and having problem with using recording device on an android phone.

(Attachment below)

It's just a simple code that records and plays sound data, and this works just fine on desktop(windows). However on Android, it gets recording device normally yet recordingDevice:start() won't start.

On Windows, "Success!" , "recording : true" are printed, and rate goes up. Recorded sound is successfully played.
On Android, num goes up(which means mouse input and other things are working fine) , but device won't start recording.

* I'm using LOVE-for-Android app, and I made it sure to remove previous version, and installed 11.3 version with apk file on love2d.org front page, instead of one on Playstore as instructed. I also tried with a file on bitbuckets (https://bitbucket.org/rude/love/downloads/). I'm not sure they are different apks, but both of them didn't work anyway.

* I gave the permission to use the mircrophone, by two methods.
1) After installing love-for android, manually giving permission of microphone and storage for LOVE, on Setting - App info - Permission menu.
2) Adding "t.audio.mic = true" in conf.lua, which led app to ask permission with message box when app was ran.
Both did basically same, and neither worked out.

* I've also tried different values for parameters, but it always failed on android.

Am I missing something different on Android environment? ( I'm a layman and ignorant of elementary knowledges.)
Or maybe should I try making apk file with .love, instead of putting main.lua in sdcard/lovegame dir?

Thanks!
Attachments
mic.love
(1.68 KiB) Downloaded 225 times
Last edited by qwdqwqwffqw on Thu Jan 30, 2020 4:55 am, edited 1 time in total.
User avatar
AuahDark
Party member
Posts: 107
Joined: Mon Oct 23, 2017 2:34 pm
Location: Indonesia
Contact:

Re: Microphone won't start on Android

Post by AuahDark »

You have to try all possible combinations that works. This is the code exactly I used for testing while writing mic support for Android.

Code: Select all

local love = require("love")
local recDev = nil
local isRecording = -1
local soundDataTable = {}
local soundDataLen = 0
local audioSource = nil
local devicesString
local recordingFreq, recordingChan, recordingBitDepth

-- Possible combination testing
local sampleFmts = {48000, 44100, 32000, 22050, 16000, 8000}
local chanStereo = {2, 1}
local bitDepths = {16, 8}

function love.load()
	local devices = love.audio.getRecordingDevices()
	assert(#devices > 0, "no recording devices found")

	recDev = devices[1]

	local devStr = {}
	for i, v in ipairs(devices) do
		devStr[#devStr + 1] = string.format("%d. %s", i, v:getName())
	end
	devicesString = table.concat(devStr, "\n")
end

function love.update(dt)
	if isRecording > 0 then
		isRecording = isRecording - dt
		local data = recDev:getData()
		if data then
			soundDataLen = soundDataLen + data:getSampleCount()
			soundDataTable[#soundDataTable + 1] = data
		end

		if isRecording <= 0 then
			-- Stop recording
			isRecording = -math.huge
			recDev:stop()

			-- assemble soundData
			local soundData = love.sound.newSoundData(soundDataLen, recordingFreq, recordingBitDepth, recordingChan)
			local soundDataIdx = 0
			for _, v in ipairs(soundDataTable) do
				for i = 0, v:getSampleCount() - 1 do
					for j = 1, recordingChan do
						soundData:setSample(soundDataIdx, j, v:getSample(i, j))
					end
					soundDataIdx = soundDataIdx + 1
				end
				v:release()
			end

			audioSource = love.audio.newSource(soundData)
		end
	end
end

function love.mousereleased()
	if isRecording == -1 then
		-- start recording
		local success = false
		-- Test all possible combination
		for _, sampleFmt in ipairs(sampleFmts) do
			for _, bitDepth in ipairs(bitDepths) do
				for _, stereo in ipairs(chanStereo) do
					success = recDev:start(16384, sampleFmt, bitDepth, stereo)

					if success then
						recordingFreq = sampleFmt
						recordingBitDepth = bitDepth
						recordingChan = stereo
						isRecording = 5
						print("Recording", sampleFmt, bitDepth, stereo)
						return
					end

					print("Record parameter failed", sampleFmt, bitDepth, stereo)
				end
			end
		end

		assert(success, "cannot start capture")
	elseif isRecording == -math.huge and audioSource then
		if audioSource:isPlaying() then
			audioSource:pause()
		else
			audioSource:play()
		end
	end
end

function love.keyreleased(k)
	if k == "escape" then
		love.event.quit()
	end
end

function love.draw()
	if isRecording == -1 then
		love.graphics.print("Recording ready", 2, 2)
	elseif isRecording == -math.huge then
		love.graphics.print("Replay "..audioSource:tell(), 2, 2)
	else
		love.graphics.print("Recording at "..recordingFreq..", "..recordingBitDepth..", "..recordingChan..": "..isRecording, 2, 2)
	end

	love.graphics.print(devicesString, 2, 16)
end
In my phone (Mi A1, Android 9) it shows "Recording at 48000, 16, 2". I also noticed in your code that your buffer is too high. In my code above, I used 16384 as buffer size which is good enough to be able to record with such parameters. If I set the buffer size to 100000 as per your code, I can't record with 48000Hz but I can record in 32000Hz, possibly due to memory limitations.
Profile. Do you encounter crashes in LÖVE Android and wanna send me logcats? Please hit me up in LÖVE Discord and send the full logcat file!
qwdqwqwffqw
Prole
Posts: 21
Joined: Sat Jan 25, 2020 4:11 pm

Re: Microphone won't start on Android

Post by qwdqwqwffqw »

Your test code worked perfectly. While other sample rates didn't work at all, both 48000Hz and 22050Hz worked fine regardless of bit depth and channels(on Android 7.0) among suggested combinations.
So, like you said, it seems that setting buffer value too high was the problem.

Thanks for your kind reply!!
n0bleman
Prole
Posts: 10
Joined: Mon Sep 30, 2019 9:40 pm

Re: Microphone won't start on Android

Post by n0bleman »

AuahDark wrote: Tue Jan 28, 2020 12:24 pm You have to try all possible combinations that works. This is the code exactly I used for testing while writing mic support for Android.

Code: Select all

local love = require("love")
local recDev = nil
local isRecording = -1
local soundDataTable = {}
local soundDataLen = 0
local audioSource = nil
local devicesString
local recordingFreq, recordingChan, recordingBitDepth

-- Possible combination testing
local sampleFmts = {48000, 44100, 32000, 22050, 16000, 8000}
local chanStereo = {2, 1}
local bitDepths = {16, 8}

function love.load()
	local devices = love.audio.getRecordingDevices()
	assert(#devices > 0, "no recording devices found")

	recDev = devices[1]

	local devStr = {}
	for i, v in ipairs(devices) do
		devStr[#devStr + 1] = string.format("%d. %s", i, v:getName())
	end
	devicesString = table.concat(devStr, "\n")
end

function love.update(dt)
	if isRecording > 0 then
		isRecording = isRecording - dt
		local data = recDev:getData()
		if data then
			soundDataLen = soundDataLen + data:getSampleCount()
			soundDataTable[#soundDataTable + 1] = data
		end

		if isRecording <= 0 then
			-- Stop recording
			isRecording = -math.huge
			recDev:stop()

			-- assemble soundData
			local soundData = love.sound.newSoundData(soundDataLen, recordingFreq, recordingBitDepth, recordingChan)
			local soundDataIdx = 0
			for _, v in ipairs(soundDataTable) do
				for i = 0, v:getSampleCount() - 1 do
					for j = 1, recordingChan do
						soundData:setSample(soundDataIdx, j, v:getSample(i, j))
					end
					soundDataIdx = soundDataIdx + 1
				end
				v:release()
			end

			audioSource = love.audio.newSource(soundData)
		end
	end
end

function love.mousereleased()
	if isRecording == -1 then
		-- start recording
		local success = false
		-- Test all possible combination
		for _, sampleFmt in ipairs(sampleFmts) do
			for _, bitDepth in ipairs(bitDepths) do
				for _, stereo in ipairs(chanStereo) do
					success = recDev:start(16384, sampleFmt, bitDepth, stereo)

					if success then
						recordingFreq = sampleFmt
						recordingBitDepth = bitDepth
						recordingChan = stereo
						isRecording = 5
						print("Recording", sampleFmt, bitDepth, stereo)
						return
					end

					print("Record parameter failed", sampleFmt, bitDepth, stereo)
				end
			end
		end

		assert(success, "cannot start capture")
	elseif isRecording == -math.huge and audioSource then
		if audioSource:isPlaying() then
			audioSource:pause()
		else
			audioSource:play()
		end
	end
end

function love.keyreleased(k)
	if k == "escape" then
		love.event.quit()
	end
end

function love.draw()
	if isRecording == -1 then
		love.graphics.print("Recording ready", 2, 2)
	elseif isRecording == -math.huge then
		love.graphics.print("Replay "..audioSource:tell(), 2, 2)
	else
		love.graphics.print("Recording at "..recordingFreq..", "..recordingBitDepth..", "..recordingChan..": "..isRecording, 2, 2)
	end

	love.graphics.print(devicesString, 2, 16)
end
In my phone (Mi A1, Android 9) it shows "Recording at 48000, 16, 2". I also noticed in your code that your buffer is too high. In my code above, I used 16384 as buffer size which is good enough to be able to record with such parameters. If I set the buffer size to 100000 as per your code, I can't record with 48000Hz but I can record in 32000Hz, possibly due to memory limitations.
How I can play recorded file in realtime ??? And dont stop recording! I want to make multiplayer voice chat ? where data to send ? and
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 44 guests