static SoundDeviceDescription *lookup_sound_device(const char *manufacturer, const char* model, const char *platform) { MSList *list = sound_device_descriptions; SoundDeviceDescription *d; for(; list != NULL; list = list->next) { d = (SoundDeviceDescription*) list->data; if (strcasecmp(d->manufacturer, manufacturer) == 0 && strcmp(d->model, model) == 0 && platform && d->platform && strcmp(d->platform, platform)==0) { return d; } } d = &devices[0]; while (d->manufacturer != NULL) { if (strcasecmp(d->manufacturer, manufacturer) == 0 && strcmp(d->model, model) == 0 && platform && d->platform && strcmp(d->platform, platform)==0) { return d; } d++; } if (platform){ /*retry without platform*/ return lookup_sound_device(manufacturer, model, NULL); } return NULL; }
SoundDeviceDescription * sound_device_description_get(void){ SoundDeviceDescription *d; char manufacturer[PROP_VALUE_MAX]={0}; char model[PROP_VALUE_MAX]={0}; char platform[PROP_VALUE_MAX]={0}; bool_t exact_match=FALSE; bool_t declares_builtin_aec=FALSE; #ifdef ANDROID if (__system_property_get("ro.product.manufacturer",manufacturer)<=0){ ms_warning("Could not get product manufacturer."); } if (__system_property_get("ro.product.model",model)<=0){ ms_warning("Could not get product model."); } if (__system_property_get("ro.board.platform",platform)<=0){ ms_warning("Could not get board platform."); } /* First ask android if the device has an hardware echo canceller (only >=4.2)*/ { JNIEnv *env=ms_get_jni_env(); jclass aecClass = (*env)->FindClass(env,"android/media/audiofx/AcousticEchoCanceler"); if (aecClass!=NULL){ jmethodID isAvailableID = (*env)->GetStaticMethodID(env,aecClass,"isAvailable","()Z"); if (isAvailableID!=NULL){ jboolean ret=(*env)->CallStaticBooleanMethod(env,aecClass,isAvailableID); if (ret){ ms_message("This device (%s/%s/%s) declares it has a built-in echo canceller.",manufacturer,model,platform); declares_builtin_aec=TRUE; }else ms_message("This device (%s/%s/%s) says it has no built-in echo canceller.",manufacturer,model,platform); }else{ ms_error("isAvailable() not found in class AcousticEchoCanceler !"); (*env)->ExceptionClear(env); //very important. } (*env)->DeleteLocalRef(env,aecClass); }else{ (*env)->ExceptionClear(env); //very important. } } #endif d=lookup_sound_device(manufacturer, model, platform); if (!d){ ms_message("No AEC information available for [%s/%s/%s],",manufacturer,model,platform); d=&genericSoundDeviceDescriptor; }else{ ms_message("Found AEC information for [%s/%s/%s] from internal table",manufacturer,model,platform); exact_match=TRUE; } if (declares_builtin_aec){ if (exact_match && (d->flags & DEVICE_HAS_BUILTIN_AEC_CRAPPY)){ ms_warning("This device declares a builtin AEC but according to internal tables it is known to be misfunctionning, so trusting tables."); }else{ d->flags=DEVICE_HAS_BUILTIN_AEC; d->delay=0; } } if (d->flags & DEVICE_HAS_CRAPPY_ANDROID_FASTTRACK) ms_warning("Fasttrack playback mode is crappy on this device, not using it."); if (d->flags & DEVICE_HAS_CRAPPY_ANDROID_FASTRECORD) ms_warning("Fasttrack record mode is crappy on this device, not using it."); if (d->flags & DEVICE_HAS_UNSTANDARD_LIBMEDIA) ms_warning("This device has unstandart libmedia."); ms_message("Sound device information for [%s/%s/%s] is: builtin=[%s], delay=[%i] ms", manufacturer,model,platform, (d->flags & DEVICE_HAS_BUILTIN_AEC) ? "yes" : "no", d->delay); return d; }