问题:
当不插usb声卡时,打开录像机,点录像键,几秒钟后系统提示错误,退出,再次点击录像键或照相机,均打不开
用录像机录像时,要打开音频输入设备
在AudioFlinger层
frameworks/base/services/audioflinger/AudioFlinger.cpp
[cpp] view plain copy print ?
- int AudioFlinger::openInput(uint32_t *pDevices,
- uint32_t *pSamplingRate,
- uint32_t *pFormat,
- uint32_t *pChannels,
- uint32_t acoustics)
- {
- status_t status;
- RecordThread *thread = NULL;
- uint32_t samplingRate = pSamplingRate ? *pSamplingRate : 0;
- uint32_t format = pFormat ? *pFormat : 0;
- uint32_t channels = pChannels ? *pChannels : 0;
- uint32_t reqSamplingRate = samplingRate;
- uint32_t reqFormat = format;
- uint32_t reqChannels = channels;
- audio_stream_in_t *inStream;
- audio_hw_device_t *inHwDev;
-
- if (pDevices == NULL || *pDevices == 0) {
- return 0;
- }
-
- Mutex::Autolock _l(mLock);
-
- inHwDev = findSuitableHwDev_l(*pDevices);
- if (inHwDev == NULL)
- return 0;
-
- status = inHwDev->open_input_stream(inHwDev, *pDevices, (int *)&format,
- &channels, &samplingRate,
- (audio_in_acoustics_t)acoustics,
- &inStream);
- LOGV("openInput() openInputStream returned input %p, SamplingRate %d, Format %d, Channels %x, acoustics %x, status %d",
- inStream,
- samplingRate,
- format,
- channels,
- acoustics,
- status);
-
-
-
-
- if (inStream == NULL && status == BAD_VALUE &&
- reqFormat == format && format == AUDIO_FORMAT_PCM_16_BIT &&
- (samplingRate <= 2 * reqSamplingRate) &&
- (getInputChannelCount(channels) < 3) && (getInputChannelCount(reqChannels) < 3)) {
- LOGV("openInput() reopening with proposed sampling rate and channels");
- status = inHwDev->open_input_stream(inHwDev, *pDevices, (int *)&format,
- &channels, &samplingRate,
- (audio_in_acoustics_t)acoustics,
- &inStream);
- }
-
- if (inStream != NULL) {
- AudioStreamIn *input = new AudioStreamIn(inHwDev, inStream);
-
- int id = nextUniqueId();
-
-
-
- uint32_t device = (*pDevices) | primaryOutputDevice_l();
- thread = new RecordThread(this,
- input,
- reqSamplingRate,
- reqChannels,
- id,
- device);
- mRecordThreads.add(id, thread);
- LOGV("openInput() created record thread: ID %d thread %p", id, thread);
- if (pSamplingRate) *pSamplingRate = reqSamplingRate;
- if (pFormat) *pFormat = format;
- if (pChannels) *pChannels = reqChannels;
-
- input->stream->common.standby(&input->stream->common);
-
-
- thread->audioConfigChanged_l(AudioSystem::INPUT_OPENED);
- return id;
- }
-
- return 0;
- }
int AudioFlinger::openInput(uint32_t *pDevices, uint32_t *pSamplingRate, uint32_t *pFormat, uint32_t *pChannels, uint32_t acoustics) { status_t status; RecordThread *thread = NULL; uint32_t samplingRate = pSamplingRate ? *pSamplingRate : 0; uint32_t format = pFormat ? *pFormat : 0; uint32_t channels = pChannels ? *pChannels : 0; uint32_t reqSamplingRate = samplingRate; uint32_t reqFormat = format; uint32_t reqChannels = channels; audio_stream_in_t *inStream; audio_hw_device_t *inHwDev; if (pDevices == NULL || *pDevices == 0) { return 0; } Mutex::Autolock _l(mLock); inHwDev = findSuitableHwDev_l(*pDevices); if (inHwDev == NULL) return 0; status = inHwDev->open_input_stream(inHwDev, *pDevices, (int *)&format, &channels, &samplingRate, (audio_in_acoustics_t)acoustics, &inStream); //问题出在这,当没有USB声卡时,这个函数没有返回。 LOGV("openInput() openInputStream returned input %p, SamplingRate %d, Format %d, Channels %x, acoustics %x, status %d", inStream, samplingRate, format, channels, acoustics, status); // If the input could not be opened with the requested parameters and we can handle the conversion internally, // try to open again with the proposed parameters. The AudioFlinger can resample the input and do mono to stereo // or stereo to mono conversions on 16 bit PCM inputs. if (inStream == NULL && status == BAD_VALUE && reqFormat == format && format == AUDIO_FORMAT_PCM_16_BIT && (samplingRate <= 2 * reqSamplingRate) && (getInputChannelCount(channels) < 3) && (getInputChannelCount(reqChannels) < 3)) { LOGV("openInput() reopening with proposed sampling rate and channels"); status = inHwDev->open_input_stream(inHwDev, *pDevices, (int *)&format, &channels, &samplingRate, (audio_in_acoustics_t)acoustics, &inStream); } if (inStream != NULL) { AudioStreamIn *input = new AudioStreamIn(inHwDev, inStream); int id = nextUniqueId(); // Start record thread // RecorThread require both input and output device indication to forward to audio // pre processing modules uint32_t device = (*pDevices) | primaryOutputDevice_l(); thread = new RecordThread(this, input, reqSamplingRate, reqChannels, id, device); mRecordThreads.add(id, thread); LOGV("openInput() created record thread: ID %d thread %p", id, thread); if (pSamplingRate) *pSamplingRate = reqSamplingRate; if (pFormat) *pFormat = format; if (pChannels) *pChannels = reqChannels; input->stream->common.standby(&input->stream->common); // notify client processes of the new input creation thread->audioConfigChanged_l(AudioSystem::INPUT_OPENED); return id; } return 0; }
在AudioHardware层
hardware/qcom/media/audio/msm8660/audio_hw_hal.cpp
[cpp] view plain copy print ?
- static int qcom_adev_open(const hw_module_t* module, const char* name,
- hw_device_t** device)
- {
- struct qcom_audio_device *qadev;
- int ret;
-
- if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0)
- return -EINVAL;
-
- qadev = (struct qcom_audio_device *)calloc(1, sizeof(*qadev));
- if (!qadev)
- return -ENOMEM;
-
- qadev->device.common.tag = HARDWARE_DEVICE_TAG;
- qadev->device.common.version = 0;
- qadev->device.common.module = const_cast<hw_module_t*>(module);
- qadev->device.common.close = qcom_adev_close;
-
- qadev->device.get_supported_devices = adev_get_supported_devices;
- qadev->device.init_check = adev_init_check;
- qadev->device.set_voice_volume = adev_set_voice_volume;
- qadev->device.set_master_volume = adev_set_master_volume;
- qadev->device.set_fm_volume = adev_set_fm_volume;
- qadev->device.set_mode = adev_set_mode;
- qadev->device.set_mic_mute = adev_set_mic_mute;
- qadev->device.get_mic_mute = adev_get_mic_mute;
- qadev->device.set_parameters = adev_set_parameters;
- qadev->device.get_parameters = adev_get_parameters;
- qadev->device.get_input_buffer_size = adev_get_input_buffer_size;
- qadev->device.open_output_stream = adev_open_output_stream;
- qadev->device.open_output_session = adev_open_output_session;
- qadev->device.close_output_stream = adev_close_output_stream;
- qadev->device.open_input_stream = adev_open_input_stream;
- qadev->device.close_input_stream = adev_close_input_stream;
- qadev->device.dump = adev_dump;
-
- qadev->hwif = createAudioHardware();
- if (!qadev->hwif) {
- ret = -EIO;
- goto err_create_audio_hw;
- }
-
- *device = &qadev->device.common;
-
- return 0;
-
- err_create_audio_hw:
- free(qadev);
- return ret;
- }
static int qcom_adev_open(const hw_module_t* module, const char* name, hw_device_t** device) { struct qcom_audio_device *qadev; int ret; if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) return -EINVAL; qadev = (struct qcom_audio_device *)calloc(1, sizeof(*qadev)); if (!qadev) return -ENOMEM; qadev->device.common.tag = HARDWARE_DEVICE_TAG; qadev->device.common.version = 0; qadev->device.common.module = const_cast<hw_module_t*>(module); qadev->device.common.close = qcom_adev_close; qadev->device.get_supported_devices = adev_get_supported_devices; qadev->device.init_check = adev_init_check; qadev->device.set_voice_volume = adev_set_voice_volume; qadev->device.set_master_volume = adev_set_master_volume; qadev->device.set_fm_volume = adev_set_fm_volume; qadev->device.set_mode = adev_set_mode; qadev->device.set_mic_mute = adev_set_mic_mute; qadev->device.get_mic_mute = adev_get_mic_mute; qadev->device.set_parameters = adev_set_parameters; qadev->device.get_parameters = adev_get_parameters; qadev->device.get_input_buffer_size = adev_get_input_buffer_size; qadev->device.open_output_stream = adev_open_output_stream; qadev->device.open_output_session = adev_open_output_session; qadev->device.close_output_stream = adev_close_output_stream; qadev->device.open_input_stream = adev_open_input_stream; //指向adev_open_input_stream() qadev->device.close_input_stream = adev_close_input_stream; qadev->device.dump = adev_dump; qadev->hwif = createAudioHardware(); if (!qadev->hwif) { ret = -EIO; goto err_create_audio_hw; } *device = &qadev->device.common; return 0; err_create_audio_hw: free(qadev); return ret; }
[cpp] view plain copy print ?
-
- static int adev_open_input_stream(struct audio_hw_device *dev,
- uint32_t devices, int *format,
- uint32_t *channels, uint32_t *sample_rate,
- audio_in_acoustics_t acoustics,
- struct audio_stream_in **stream_in)
- {
- struct legacy_audio_device *ladev = to_ladev(dev);
- status_t status;
- struct legacy_stream_in *in;
- int ret;
-
- in = (struct legacy_stream_in *)calloc(1, sizeof(*in));
- if (!in)
- return -ENOMEM;
-
- in->legacy_in = ladev->hwif->openInputStream(devices, format, channels,
- sample_rate, &status,
- (AudioSystem::audio_in_acoustics)acoustics);
- if (!in->legacy_in) {
- ret = status;
- goto err_open;
- }
-
- in->stream.common.get_sample_rate = in_get_sample_rate;
- in->stream.common.set_sample_rate = in_set_sample_rate;
- in->stream.common.get_buffer_size = in_get_buffer_size;
- in->stream.common.get_channels = in_get_channels;
- in->stream.common.get_format = in_get_format;
- in->stream.common.set_format = in_set_format;
- in->stream.common.standby = in_standby;
- in->stream.common.dump = in_dump;
- in->stream.common.set_parameters = in_set_parameters;
- in->stream.common.get_parameters = in_get_parameters;
- in->stream.common.add_audio_effect = in_add_audio_effect;
- in->stream.common.remove_audio_effect = in_remove_audio_effect;
- in->stream.set_gain = in_set_gain;
- in->stream.read = in_read;
- in->stream.get_input_frames_lost = in_get_input_frames_lost;
-
- *stream_in = &in->stream;
- return 0;
-
- err_open:
- free(in);
- *stream_in = NULL;
- return ret;
- }
/** This method creates and opens the audio hardware input stream */ static int adev_open_input_stream(struct audio_hw_device *dev, uint32_t devices, int *format, uint32_t *channels, uint32_t *sample_rate, audio_in_acoustics_t acoustics, struct audio_stream_in **stream_in) { struct legacy_audio_device *ladev = to_ladev(dev); status_t status; struct legacy_stream_in *in; int ret; in = (struct legacy_stream_in *)calloc(1, sizeof(*in)); if (!in) return -ENOMEM; in->legacy_in = ladev->hwif->openInputStream(devices, format, channels, sample_rate, &status, (AudioSystem::audio_in_acoustics)acoustics); //这里没有返回 if (!in->legacy_in) { ret = status; goto err_open; } in->stream.common.get_sample_rate = in_get_sample_rate; in->stream.common.set_sample_rate = in_set_sample_rate; in->stream.common.get_buffer_size = in_get_buffer_size; in->stream.common.get_channels = in_get_channels; in->stream.common.get_format = in_get_format; in->stream.common.set_format = in_set_format; in->stream.common.standby = in_standby; in->stream.common.dump = in_dump; in->stream.common.set_parameters = in_set_parameters; in->stream.common.get_parameters = in_get_parameters; in->stream.common.add_audio_effect = in_add_audio_effect; in->stream.common.remove_audio_effect = in_remove_audio_effect; in->stream.set_gain = in_set_gain; in->stream.read = in_read; in->stream.get_input_frames_lost = in_get_input_frames_lost; *stream_in = &in->stream; return 0; err_open: free(in); *stream_in = NULL; return ret; }
hardware/qcom/media/audio/msm8660/AudioHardware.cpp
[cpp] view plain copy print ?
- 887 AudioStreamIn* AudioHardware::openInputStream(
- 888 uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status,
- 889 AudioSystem::audio_in_acoustics acoustic_flags)
- 890 {
- 891
- 892 if (!AudioSystem::isInputDevice((AudioSystem::audio_devices)devices)) {
- 893 return 0;
- 894 }
- 895
- 896 #if 1
- 897 if (devices == AudioSystem::DEVICE_IN_USB_MIC)
- 898 {
- 899 Mutex::Autolock lock(mLock);
- 900
- 901 AudioStreamInUSBMic *in_usb = new AudioStreamInUSBMic();
- 902 status_t lStatus = in_usb->set(this, devices, format, channels, sampleRate, acoustic_flags);
- 903
- 904 if (status) {
- 906 *status = lStatus;
- 907 }
- 908 if (lStatus != NO_ERROR)
- 909 {
- 910 LOGE("before delete in_usb\n");
- 911 delete in_usb;
- 912 LOGE("delete in_usb\n");
- 913 }
- 914 else
- 915 {
- 916 mUsbInputs.add(in_usb);
- 917 return in_usb;
- 918 }
- 919 }
- 920 #endif
- 922 mLock.lock();
- 923 if(devices == AudioSystem::DEVICE_IN_COMMUNICATION) {
- 924 LOGE("Create Audio stream Voip \n");
- 925 AudioStreamInVoip* inVoip = new AudioStreamInVoip();
- 926 status_t lStatus = NO_ERROR;
- 927 lStatus = inVoip->set(this, devices, format, channels, sampleRate, acoustic_flags);
- 928 if (status) {
- 929 *status = lStatus;
- 930 }
- 931 if (lStatus != NO_ERROR) {
- 932 LOGE(" Error creating voip input \n");
- 933 mLock.unlock();
- 934 delete inVoip;
- 935 return 0;
- 936 }
- 937 mVoipInputs.add(inVoip);
- 938 mLock.unlock();
- 939 return inVoip;
- 940 } else {
- 941 AudioStreamInMSM72xx* in72xx = new AudioStreamInMSM72xx();
- 942 status_t lStatus = in72xx->set(this, devices, format, channels, sampleRate, acoustic_flags);
- 943 if (status) {
- 944 *status = lStatus;
- 945 }
- 946 if (lStatus != NO_ERROR) {
- 947 LOGE("Error creating Audio stream AudioStreamInMSM72xx \n");
- 948 mLock.unlock();
- 949 delete in72xx;
- 950 return 0;
- 951 }
- 952 mInputs.add(in72xx);
- 953 mLock.unlock();
- 954 return in72xx;
- 955 }
- 956 }
887 AudioStreamIn* AudioHardware::openInputStream( 888 uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status, 889 AudioSystem::audio_in_acoustics acoustic_flags) 890 { 891 // check for valid input source 892 if (!AudioSystem::isInputDevice((AudioSystem::audio_devices)devices)) { 893 return 0; 894 } 895 896 #if 1 //WNC:WJ Wang 20110719: Add USB-Mic path: BEGIN 897 if (devices == AudioSystem::DEVICE_IN_USB_MIC) 898 { 899 Mutex::Autolock lock(mLock); 900 901 AudioStreamInUSBMic *in_usb = new AudioStreamInUSBMic(); 902 status_t lStatus = in_usb->set(this, devices, format, channels, sampleRate, acoustic_flags); 903 904 if (status) { 906 *status = lStatus; 907 } 908 if (lStatus != NO_ERROR) //If open USB-Mic failed, continue to open the analog Mic 909 { 910 LOGE("before delete in_usb\n"); 911 delete in_usb; //这句之后的log没有打出来。delete in_usb对象时,进入AudioStreamInUSBMic的析构函数 912 LOGE("delete in_usb\n"); 913 } 914 else 915 { 916 mUsbInputs.add(in_usb); 917 return in_usb; 918 } 919 } 920 #endif //WNC:WJ Wang 20110719: Add USB-Mic path: END 922 mLock.lock(); 923 if(devices == AudioSystem::DEVICE_IN_COMMUNICATION) { 924 LOGE("Create Audio stream Voip \n"); 925 AudioStreamInVoip* inVoip = new AudioStreamInVoip(); 926 status_t lStatus = NO_ERROR; 927 lStatus = inVoip->set(this, devices, format, channels, sampleRate, acoustic_flags); 928 if (status) { 929 *status = lStatus; 930 } 931 if (lStatus != NO_ERROR) { 932 LOGE(" Error creating voip input \n"); 933 mLock.unlock(); 934 delete inVoip; 935 return 0; 936 } 937 mVoipInputs.add(inVoip); 938 mLock.unlock(); 939 return inVoip; 940 } else { 941 AudioStreamInMSM72xx* in72xx = new AudioStreamInMSM72xx(); 942 status_t lStatus = in72xx->set(this, devices, format, channels, sampleRate, acoustic_flags); 943 if (status) { 944 *status = lStatus; 945 } 946 if (lStatus != NO_ERROR) { 947 LOGE("Error creating Audio stream AudioStreamInMSM72xx \n"); 948 mLock.unlock(); 949 delete in72xx; 950 return 0; 951 } 952 mInputs.add(in72xx); 953 mLock.unlock(); 954 return in72xx; 955 } 956 }
[cpp] view plain copy print ?
- <pre class="cpp" name="code">AudioHardware::AudioStreamInUSBMic::~AudioStreamInUSBMic()
- {
- standby();
- }
<pre class="cpp" name="code">AudioHardware::AudioStreamInUSBMic::~AudioStreamInUSBMic() { standby(); }
[cpp] view plain copy print ?
- <pre class="html" name="code"><pre class="cpp" name="code"> status_t AudioHardware::AudioStreamInUSBMic::standby()
- {
- AudioHardware *hw = mHardware;
-
- if (!mHardware) return -1;
-
- hw->mLock.lock();
-
- if (mState > AUDIO_INPUT_CLOSED)
- {
- if (mHandle != 0)
- {
- snd_pcm_close(mHandle);
- mHandle = 0;
- if (mHardware != 0)
- {
- if(mHardware->mNumPcmRec > 0 && mFormat == AUDIO_HW_IN_FORMAT)
- mHardware->mNumPcmRec--;
- }
- }
-
- mState = AUDIO_INPUT_CLOSED;
- }
-
- hw->mLock.unlock();
- return NO_ERROR;
- }
<pre class="html" name="code"><pre class="cpp" name="code"> status_t AudioHardware::AudioStreamInUSBMic::standby() { AudioHardware *hw = mHardware; if (!mHardware) return -1; hw->mLock.lock(); if (mState > AUDIO_INPUT_CLOSED) { if (mHandle != 0) { snd_pcm_close(mHandle); mHandle = 0; if (mHardware != 0) { if(mHardware->mNumPcmRec > 0 && mFormat == AUDIO_HW_IN_FORMAT) mHardware->mNumPcmRec--; } } mState = AUDIO_INPUT_CLOSED; } hw->mLock.unlock(); return NO_ERROR; }
找到问题了:
在执行delete in_usb之前,执行了Mutex::Autolock lock(mLock); mLock被锁住了,所以在析构函数所调用的standby函数里,调用hw->mLock.lock();时,就获取不到锁,导致死锁!
AutoLock类是定义在Mutex内部的一个类,AutoLock的定义代码如下所示:
[-->Thread.h Mutex::Autolock声明和实现]
[cpp] view plain copy print ?
- class Autolock {
- public:
-
- inline Autolock(Mutex& mutex) : mLock(mutex) { mLock.lock(); }
- inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); }
-
- inline ~Autolock() { mLock.unlock(); }
- private:
- Mutex& mLock;
- };
class Autolock { public: //构造的时候调用lock。 inline Autolock(Mutex& mutex) : mLock(mutex) { mLock.lock(); } inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); } //析构的时候调用unlock。 inline ~Autolock() { mLock.unlock(); } private: Mutex& mLock; };
AutoLock的用法很简单: 先定义一个Mutex,如 Mutex xlock。 在使用xlock的地方,定义一个AutoLock,如 AutoLock autoLock(xlock)。由于C++对象的构造和析构函数都是自动被调用的,所以在AutoLock的生命周期内,xlock的lock和unlock也就自动被调用了,这样就省去了重复书写unlock的麻烦,而且lock和unlock的调用肯定是一一对应的,这样就绝对不会出错。
在作用域里加锁,脱离作用域就会自动解锁。作用域是指同级{}范围。
Mutex::Autolock lock(mLock)的mLock在class AudioHardware中定义,所以和hw->mLock.lock();中的mLock是同一个锁。
相关代码:
set函数由openInputStream()调用,没有usb声卡时返回BAD_VALUE,否则返回NO_ERROR。
[cpp] view plain copy print ?
- <pre class="cpp" name="code">status_t AudioHardware::AudioStreamInUSBMic::set(
- AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate,
- AudioSystem::audio_in_acoustics acoustic_flags)
- {
- char cap_pcm[16];
- LOGD("AudioHardware::AudioStreamInUSBMic::set(%d)...mState=%d", *pFormat, *pChannels);
-
- if (pFormat == 0 || pRate == 0 || pChannels == 0) {
- return BAD_VALUE;
- }
- uint32_t rate = hw->getInputSampleRate(*pRate);
- if (rate != *pRate) {
- *pRate = rate;
- return BAD_VALUE;
- }
-
- if (rate != 16000)
- rate = 16000;
-
- if ((*pChannels & (AudioSystem::CHANNEL_IN_MONO | AudioSystem::CHANNEL_IN_STEREO)) == 0) {
- *pChannels = AUDIO_HW_IN_CHANNELS;
- return BAD_VALUE;
- }
-
- if (mHandle != 0) {
- LOGE("Audio record already set");
- return NO_ERROR;
- }
-
- mHardware = hw;
- if(mHardware->mNumPcmRec > 0) {
-
- LOGE("Multiple PCM recordings is not allowed");
- return -1;
- }
-
- status_t status = NO_ERROR;
- int dir = 0;
- snd_pcm_t *handle = 0;
- snd_pcm_hw_params_t *params = 0;
-
- status = getCaptureDevice(cap_pcm);
- if (status < 0) {
- LOGE("No USB-Audio:");
- return BAD_VALUE;
- }
-
-
- status = snd_pcm_open(&handle, cap_pcm, SND_PCM_STREAM_CAPTURE, 0);
- if (status < 0) {
- LOGE("unable to open pcm device");
- return status;
- }
-
- mHandle = handle;
- mHardware->mNumPcmRec++;
- mDevices = devices;
- mFormat = AUDIO_HW_IN_FORMAT;
- mChannels = *pChannels;
- mChannelCount = AudioSystem::popCount(mChannels);
- mSampleRate = rate;
- mAcoustics = acoustic_flags;
- mBufferSize = mHardware->getInputBufferSize(mSampleRate, AUDIO_HW_IN_FORMAT, mChannelCount);
- mBufferSize <<= 1;
-
- LOGD("AudioStreamInUSBMic::set(%d)...(%d, %d, %d)", __LINE__, mChannelCount, mSampleRate, mBufferSize);
-
-
- snd_pcm_hw_params_alloca(¶ms);
- if (params == 0)
- {
- LOGE("unable to allocate parameter memory");
- goto Error;
- }
-
-
- snd_pcm_hw_params_any(handle, params);
-
-
-
- snd_pcm_hw_params_set_access(handle, params,
- SND_PCM_ACCESS_RW_INTERLEAVED);
-
-
- snd_pcm_hw_params_set_format(handle, params,
- SND_PCM_FORMAT_S16_LE);
-
-
- snd_pcm_hw_params_set_channels(handle, params, mChannelCount);
-
- snd_pcm_uframes_t lvFrames;
-
-
- lvFrames = 32;
- snd_pcm_hw_params_set_period_size_near(handle, params, &lvFrames, &dir);
-
-
- status = snd_pcm_hw_params(handle, params);
- if (status < 0) {
- LOGE("unable to set hw params");
- goto Error;
- }
-
- mState = AUDIO_INPUT_OPENED;
-
- return NO_ERROR;
-
- Error:
- if (mHandle != 0) {
- snd_pcm_close(mHandle);
- mHandle = 0;
- }
-
- return -1;
- }
<pre class="cpp" name="code">status_t AudioHardware::AudioStreamInUSBMic::set( AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate, AudioSystem::audio_in_acoustics acoustic_flags) { char cap_pcm[16]; LOGD("AudioHardware::AudioStreamInUSBMic::set(%d)...mState=%d", *pFormat, *pChannels); if (pFormat == 0 || pRate == 0 || pChannels == 0) { return BAD_VALUE; } uint32_t rate = hw->getInputSampleRate(*pRate); if (rate != *pRate) { *pRate = rate; return BAD_VALUE; } //Eaddy temp if (rate != 16000) rate = 16000; if ((*pChannels & (AudioSystem::CHANNEL_IN_MONO | AudioSystem::CHANNEL_IN_STEREO)) == 0) { *pChannels = AUDIO_HW_IN_CHANNELS; return BAD_VALUE; } if (mHandle != 0) { LOGE("Audio record already set"); return NO_ERROR; } mHardware = hw; if(mHardware->mNumPcmRec > 0) { /* Only one PCM recording is allowed at a time */ LOGE("Multiple PCM recordings is not allowed"); return -1; } status_t status = NO_ERROR; int dir = 0; snd_pcm_t *handle = 0; snd_pcm_hw_params_t *params = 0; status = getCaptureDevice(cap_pcm); if (status < 0) { LOGE("No USB-Audio:"); return BAD_VALUE; } /* Open PCM device for recording (capture). Old setting == "hw:2,0,0" */ status = snd_pcm_open(&handle, cap_pcm, SND_PCM_STREAM_CAPTURE, 0); if (status < 0) { LOGE("unable to open pcm device"); return status; } mHandle = handle; mHardware->mNumPcmRec++; mDevices = devices; mFormat = AUDIO_HW_IN_FORMAT; mChannels = *pChannels; mChannelCount = AudioSystem::popCount(mChannels); mSampleRate = rate; mAcoustics = acoustic_flags; mBufferSize = mHardware->getInputBufferSize(mSampleRate, AUDIO_HW_IN_FORMAT, mChannelCount); mBufferSize <<= 1; // We double the size of input buffer for ping pong use of record buffer. LOGD("AudioStreamInUSBMic::set(%d)...(%d, %d, %d)", __LINE__, mChannelCount, mSampleRate, mBufferSize); /* Allocate a hardware parameters object. */ snd_pcm_hw_params_alloca(¶ms); if (params == 0) { LOGE("unable to allocate parameter memory"); goto Error; } /* Fill it in with default values. */ snd_pcm_hw_params_any(handle, params); /* Set the desired hardware parameters. */ /* Interleaved mode */ snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); /* Signed 16-bit little-endian format */ snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); /* Two channels (stereo) */ snd_pcm_hw_params_set_channels(handle, params, mChannelCount); snd_pcm_uframes_t lvFrames; /* Set period size to frames. */ lvFrames = 32; snd_pcm_hw_params_set_period_size_near(handle, params, &lvFrames, &dir); /* Write the parameters to the driver */ status = snd_pcm_hw_params(handle, params); if (status < 0) { LOGE("unable to set hw params"); goto Error; } mState = AUDIO_INPUT_OPENED; return NO_ERROR; Error: if (mHandle != 0) { snd_pcm_close(mHandle); mHandle = 0; } return -1; }
getCaptureDevice,找到USB-Audio时,返回0,找不到时返回-1
[cpp] view plain copy print ?
- int AudioHardware::AudioStreamInUSBMic::getCaptureDevice(char * cap_pcm_str)
- {
- int rc,idx,dev;
- snd_ctl_t *handle;
- snd_pcm_hw_params_t *params;
- snd_ctl_card_info_t *info;
- snd_pcm_info_t *pcminfo;
- char str[16];
- char usb_card_str[16];
- int cap_pcm_dev;
- int cap_pcm_sub_dev;
-
- snd_ctl_card_info_alloca(&info);
- snd_pcm_info_alloca(&pcminfo);
-
- idx = -1;
- while (1)
- {
- if ((rc = snd_card_next(&idx)) < 0) {
- LOGE("Card next error ");
- break;
- }
- if (idx < 0)
- break;
-
-
- sprintf(str, "hw:CARD=%i", idx);
- if ((rc = snd_ctl_open(&handle, str, 0)) < 0) {
- LOGE("Open error: card = %s\n", str);
- continue;
- }
-
- if ((rc = snd_ctl_card_info(handle, info)) < 0) {
- LOGE("HW info error:");
- continue;
- }
-
-
- sprintf(usb_card_str, "%s", snd_ctl_card_info_get_driver(info));
- LOGI("Soundcard Driver = %s", usb_card_str);
-
- if ((rc = strncmp(usb_card_str, "USB-Audio", 9)) == 0)
- {
- LOGI("[--------------Got USB-Audio--------------]");
- dev = -1;
- while (1) {
- snd_pcm_sync_id_t sync;
- if ((rc = snd_ctl_pcm_next_device(handle, &dev)) < 0) {
- LOGE(" PCM next device error ");
- break;
- }
- if (dev < 0)
- break;
- snd_pcm_info_set_device(pcminfo, dev);
- snd_pcm_info_set_subdevice(pcminfo, 0);
- snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_CAPTURE);
- if ((rc = snd_ctl_pcm_info(handle, pcminfo)) < 0) {
- LOGE(" PCM info error");
- continue;
- }
-
-
- cap_pcm_dev = snd_pcm_info_get_device(pcminfo);
- cap_pcm_sub_dev = snd_pcm_info_get_subdevice(pcminfo);
- sprintf(cap_pcm_str, "hw:%i,%i,%i", idx, cap_pcm_dev, cap_pcm_sub_dev);
- LOGD("Open capture pcm device [%s]\n", cap_pcm_str);
-
- return 0;
- }
-
- }else{
- continue;
- }
- }
- return idx;
- }
-
-
int AudioHardware::AudioStreamInUSBMic::getCaptureDevice(char * cap_pcm_str) { int rc,idx,dev; snd_ctl_t *handle; snd_pcm_hw_params_t *params; snd_ctl_card_info_t *info; snd_pcm_info_t *pcminfo; char str[16]; char usb_card_str[16]; int cap_pcm_dev; int cap_pcm_sub_dev; snd_ctl_card_info_alloca(&info); snd_pcm_info_alloca(&pcminfo); idx = -1; while (1) { if ((rc = snd_card_next(&idx)) < 0) { LOGE("Card next error "); break; } if (idx < 0) break; /* Check sound card */ sprintf(str, "hw:CARD=%i", idx); if ((rc = snd_ctl_open(&handle, str, 0)) < 0) { LOGE("Open error: card = %s\n", str); continue; } if ((rc = snd_ctl_card_info(handle, info)) < 0) { LOGE("HW info error:"); continue; } /* Find "USB-Audio" */ sprintf(usb_card_str, "%s", snd_ctl_card_info_get_driver(info)); LOGI("Soundcard Driver = %s", usb_card_str); if ((rc = strncmp(usb_card_str, "USB-Audio", 9)) == 0) { LOGI("[--------------Got USB-Audio--------------]"); dev = -1; while (1) { snd_pcm_sync_id_t sync; if ((rc = snd_ctl_pcm_next_device(handle, &dev)) < 0) { LOGE(" PCM next device error "); break; } if (dev < 0) break; snd_pcm_info_set_device(pcminfo, dev); snd_pcm_info_set_subdevice(pcminfo, 0); snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_CAPTURE); if ((rc = snd_ctl_pcm_info(handle, pcminfo)) < 0) { LOGE(" PCM info error"); continue; } /* Find the PCM capture device */ cap_pcm_dev = snd_pcm_info_get_device(pcminfo); cap_pcm_sub_dev = snd_pcm_info_get_subdevice(pcminfo); sprintf(cap_pcm_str, "hw:%i,%i,%i", idx, cap_pcm_dev, cap_pcm_sub_dev); LOGD("Open capture pcm device [%s]\n", cap_pcm_str); return 0; } }else{ continue; } } return idx; }
class AudioHardware定义:
hardware/qcom/media/audio/msm8660/AudioHardware.h
[cpp] view plain copy print ?
-
-
- class AudioHardware : public AudioHardwareBase
- {
- class AudioStreamOutMSM72xx;
- class AudioStreamInMSM72xx;
-
- public:
- AudioHardware();
- virtual ~AudioHardware();
- virtual status_t initCheck();
-
- virtual status_t setVoiceVolume(float volume);
- virtual status_t setMasterVolume(float volume);
-
- virtual status_t setMode(int mode);
-
-
- virtual status_t setMicMute(bool state);
- virtual status_t getMicMute(bool* state);
-
- virtual status_t setParameters(const String8& keyValuePairs);
- virtual String8 getParameters(const String8& keys);
-
-
- virtual AudioStreamOut* openOutputStream(
- uint32_t devices,
- int *format=0,
- uint32_t *channels=0,
- uint32_t *sampleRate=0,
- status_t *status=0);
-
- virtual AudioStreamIn* openInputStream(
-
- uint32_t devices,
- int *format,
- uint32_t *channels,
- uint32_t *sampleRate,
- status_t *status,
- AudioSystem::audio_in_acoustics acoustics);
-
- virtual void closeOutputStream(AudioStreamOut* out);
- virtual void closeInputStream(AudioStreamIn* in);
-
- virtual size_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount);
- void clearCurDevice() { mCurSndDevice = -1; }
-
- protected:
- virtual status_t dump(int fd, const Vector<String16>& args);
-
- private:
-
- status_t doAudioRouteOrMute(uint32_t device);
- status_t setMicMute_nosync(bool state);
- status_t checkMicMute();
- status_t dumpInternals(int fd, const Vector<String16>& args);
- uint32_t getInputSampleRate(uint32_t sampleRate);
- bool checkOutputStandby();
- status_t doRouting(AudioStreamInMSM72xx *input);
- AudioStreamInMSM72xx* getActiveInput_l();
-
- class AudioStreamOutMSM72xx : public AudioStreamOut {
- public:
- AudioStreamOutMSM72xx();
- virtual ~AudioStreamOutMSM72xx();
- status_t set(AudioHardware* mHardware,
- uint32_t devices,
- int *pFormat,
- uint32_t *pChannels,
- uint32_t *pRate);
- virtual uint32_t sampleRate() const { return 44100; }
-
- virtual size_t bufferSize() const { return 4800; }
- virtual uint32_t channels() const { return AudioSystem::CHANNEL_OUT_STEREO; }
- virtual int format() const { return AudioSystem::PCM_16_BIT; }
- virtual uint32_t latency() const { return (1000*AUDIO_HW_NUM_OUT_BUF*(bufferSize()/frameSize()))/sampleRate()+AUDIO_HW_OUT_LATENCY_MS; }
- virtual status_t setVolume(float left, float right) { return INVALID_OPERATION; }
- virtual ssize_t write(const void* buffer, size_t bytes);
- virtual status_t standby();
- virtual status_t dump(int fd, const Vector<String16>& args);
- bool checkStandby();
- virtual status_t setParameters(const String8& keyValuePairs);
- virtual String8 getParameters(const String8& keys);
- uint32_t devices() { return mDevices; }
- virtual status_t getRenderPosition(uint32_t *dspFrames);
-
- private:
- AudioHardware* mHardware;
- int mFd;
- int mStartCount;
- int mRetryCount;
- bool mStandby;
- uint32_t mDevices;
- };
-
- class AudioStreamInMSM72xx : public AudioStreamIn {
- public:
- enum input_state {
- AUDIO_INPUT_CLOSED,
- AUDIO_INPUT_OPENED,
- AUDIO_INPUT_STARTED
- };
-
- AudioStreamInMSM72xx();
- virtual ~AudioStreamInMSM72xx();
- status_t set(AudioHardware* mHardware,
- uint32_t devices,
- int *pFormat,
- uint32_t *pChannels,
- uint32_t *pRate,
- AudioSystem::audio_in_acoustics acoustics);
- virtual size_t bufferSize() const { return mBufferSize; }
- virtual uint32_t channels() const { return mChannels; }
- virtual int format() const { return mFormat; }
- virtual uint32_t sampleRate() const { return mSampleRate; }
- virtual status_t setGain(float gain) { return INVALID_OPERATION; }
- virtual ssize_t read(void* buffer, ssize_t bytes);
- virtual status_t dump(int fd, const Vector<String16>& args);
- virtual status_t standby();
- virtual status_t setParameters(const String8& keyValuePairs);
- virtual String8 getParameters(const String8& keys);
- virtual unsigned int getInputFramesLost() const { return 0; }
- uint32_t devices() { return mDevices; }
- int state() const { return mState; }
- virtual status_t addAudioEffect(effect_interface_s**) { return 0;}
- virtual status_t removeAudioEffect(effect_interface_s**) { return 0;}
-
- private:
- AudioHardware* mHardware;
- int mFd;
- int mState;
- int mRetryCount;
- int mFormat;
- uint32_t mChannels;
- uint32_t mSampleRate;
- size_t mBufferSize;
- AudioSystem::audio_in_acoustics mAcoustics;
- uint32_t mDevices;
- bool mFirstread;
- };
-
- static const uint32_t inputSamplingRates[];
- bool mInit;
- bool mMicMute;
- bool mBluetoothNrec;
- uint32_t mBluetoothId;
- AudioStreamOutMSM72xx* mOutput;
- SortedVector <AudioStreamInMSM72xx*> mInputs;
-
- msm_snd_endpoint *mSndEndpoints;
- int mNumSndEndpoints;
- int mCurSndDevice;
- int m7xsnddriverfd;
- bool mDualMicEnabled;
- int mTtyMode;
-
- friend class AudioStreamInMSM72xx;
- Mutex mLock;
- };
-