Android AudioRecord 部分機型無法採集音頻

來源:互聯網
上載者:User

第一次安卓開發,初次體會到如此深刻的版本差異。

 

我的AudioRecord代碼在三星S5670測試成功。

 

小米,朵唯D210T測試失敗。錯誤資訊如下:

 

04-01 12:58:44.368: E/AudioRecord(19808): Could not get audio input for record source 1

04-01 12:58:44.368: E/AudioRecord-JNI(19808): Error creating AudioRecord instance: initialization check failed.

04-01 12:58:44.368: E/AudioRecord-Java(19808): [ android.media.AudioRecord ] Error code -20 when initializing native AudioRecord object.

 

 

 

網上的相關資料整理在此:

You problem here is probably actually twofold. First, you have to get all of the parameters just right for the AudioRecord, ie, I can see that you tried all the various sampling rates and channel configurations, but did you try different bit depths? If you don't get it all just right, it doesn't work. Furthermore, it would appear that some android devices seem to report the wrong minBufferSize.

 

After using audio recorder, you must stop and release it. Then when you init the audio recorder the next time, it's ok.

 

Had the same error, till I restarted the device.

It seems that on my Galaxy S the native impl is buggy: several times acquiring and releasing anAudioRecorder (during whole phone uptime) causes that error.

 

For me, the cause was failure to call AudioRecord.release() for a previous instance of AudioRecord; it tied up native resources in AudioFlinger and interfered with subsequent AudioRecord instances. Saw it on a Samsung Fascinate (Galaxy S) Android 2.1 (Eclair); either the Eclair or the Samsung implementation may be particularly intolerant.

 

 

 

 

×

You are now talking to an expert. The transcript of your session will be available online.

Expert: Hi, are also trying to handle the buffer?

You: no,

Expert: Noted.

You: I faced the problem of AudioRecord

Expert: Well said.

You: 04-01 12:58:44.368: E/AudioRecord(19808): Could not get audio input for record source 1 04-01 12:58:44.368: E/AudioRecord-JNI(19808): Error creating AudioRecord instance: initialization check failed.

Expert: I wonder if people who want to process of microphone input have similar problems.

You: yeah

Expert: Okay.

You: the strange thing is,

Expert: We're talking past each other here.

You: it just happens on some phones

Expert: What is "it" in that case?

You: the error

Expert: O... kay...

Expert: Maybe you could attempt to create tuner.

Expert: Why do you want to know?

You: i am trying to work out a tuner

Expert: You're not the only one who is trying to work out a tuner.

You: i see

Expert: Whatever you say.

You: i will google and have a try

Expert: Are you trolling me?

You: just now, i searched in chinese, with nothing useful

Expert: I once tried to instantiate activity componentinfo, it worked remarkably well.

You: my program works well on my phone, but fails on my classmates'

Expert:

You: could u tell your email to me?

Expert: Can you rephrase that?

You: sorry, what is "rephase"? record?

Expert: Why do you want to know?

You: I am working on a tunner

Expert: Oh really? I'm kind of working on a tunner myself.

You: and i want to get the main f of the input sound

Expert: Do you know anyone who could help you get the main f of the input sound?

You: i have already finished it with matlab

Expert: Well, then you know who to ask.

You: i just can not get the sound from microphone with some cellphones

Expert: Hey, would you like to be recording in android instead?

You: i want to work on realtime

Expert: It takes a lot of resources to work on realtime. Just sayin'.

You: yeah

Expert: No matter what?

You: in my mind, when tuning an instrument, it will be more convinent if it is realtime

Expert: I thought so.

You: r u in the US?

Expert: So we've given up on getting the main f of the input sound?

You: absolutely not

Expert: If you really want to get the sound with some cellphones from microphone, you have to start working now.

You: ok, i'v got someone that has the same question with me

Expert: About working on realtime -- what have you tried so far?

You: fft

Expert: While we're on the topic, recording with audiorecord on android speeds is a pretty interesting challenge.

You: my program has the f delay for about 1s

Expert: You don't say.

 

The trick with using AudioRecord is that each device may have different initialization settings, so you will have to create a method that loops over all possible combinations of bit rates, encoding, etc.

 

Since the buffer size for recording is limited, once your "analyzing process" is slower than the rate of recording, the data in the buffer will be stuck, but the recording bytes are always coming thus buffer overflows.

 

As we discussed in the chat room, decoding the audio data and displaying it on the screen should be straightforward. You mentioned that the audio buffer has 8000 samples per second, each sample is 16 bit, and it's mono audio.

Displaying this should be straightforward. Treat each sample as a vertical offset in your view. You need to scale the range -32k to +32k to the vertical height of your view. Starting at the left edge of the view, draw one sample per column. When you reach the right edge, wrap around again (erasing the previous line as necessary).

This will end up drawing each sample as a single pixel, which may not look very nice. You can also draw a line between adjacent samples. You can play around with line widths, colors and so on to get the best effect.

One last note: You'll be drawing 8000 times per second, plus more to blank out the previous samples. You may need to take some shortcuts to make sure the framerate can keep up with the audio. You may need to skip samples.

 

Well, after spending my free time for the last 5 days working on theAudioRecord class I´m here again to post my findings.

But first let me make myself clear:

 

- What I´m about to write is the result of my tests and findings after having a lot of trouble to use the basic routines of the class. I found a lot of forums posts over the internet about the same problems so my idea here is to help people so they don´t face the same problems I´ve faced.

 

- It may be beginner´s stuff, but a lot of people have faced or are

facing the same problems.

 

- If something here is wrong please don´t come here just to say it,

share your knowledge with us and post not only what´s wrong but how to

do it right.

 

- I´ve done all tests on the EMULATOR provided by google. Also I´m

using the sdk 2.1 (build 7)

 

Ok, let´s go.

 

Creating an AudioRecord object:

 

When you create a new instance of AudioRecord there are two ways of

finding out if it was created properly (the device can handle the

audio parameters and resources were trully allocated to your object):

by catching an exception or by verifying the return of the getState()

method.

 

- Handling the IllegalArgumentException : Well, tricky is what I can

say. Exceptions will only be thrown if any of the parameters you have

used are NOT acceptable by the CLASS (not if the device can´t handle

it). For example, a sample rate = 12345 is not a standard value and

then the class will throw an exception. If SR = 44100 is not supported

by the DEVICE, the object will be created and no exception will be

launched.

* An interesting thing is that the official documentation says:

"sampleRateInHz  the sample rate expressed in Hertz. Examples of rates

are (but not limited to) 44100, 22050 and 11025."

If you try SR = 11025 the system will throw an exception as it

considers this an illegal parameter. Strange, huh?

 

- Then ok, you have created an instance of AudioRecord but you don´t

know if the parameters you have set are available in an specific

device. What you do? Verify AudioRecord.getState(), right?

Ok then, it works. But if you find out your instance is not ok and

then you have to create a new AudioRecord object you will be in

trouble. Why? Even after running AudioRecord.release() the resources

for the audio input you are interested in will keep being in use and

you won´t be abble to recreate your object in a way it would work.

To verify this create an instace of AudioRecord with parameters that

are known not to work on the emulator (ex. SR = 44100). Then verify

the errors on logcat. After that call release() and then try to create

another instance of AudioRecorder with the parameters that work (sr =

8000, mono channel, pcm 16 bits) and check the first error line.

 

Then how should you find out which parameters the device will allow

you to use? Say with me: AudioRecord.getMinBufferSize() is my

solution!

Loop checking from the best combination of parameters to the worst. If

it returns -2, you should try another combination, if it returns -1

the audio input source is already being in use or isn´t even available

for the specific device. If it returns something > 0 then you´re ok

and can proceed creating a new AudioRecord object.

 

AudioRecord notification:

 

YES, IT WORKS! Believe me. The trick is: the notification will only be

called AFTER you call read() for the first time! And not only one time

(Oo). After a periodic notification you need to read from the audio

buffer again to receive another notification. A marker notification

will be called only once: if you need it to be called again, set the

marker again!

 

I guess it covers the basics.

 

Good luck and believe me, android is great!

Gabriel Simões

 

 

解決方案:

朵唯D210T的解決方案為修改AudioRecord建構函式的sample rate。當使用4000的sample rate時,無法構造成功。而當我採用8000的sample rate時即可採集成功。

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.