| 1008 | | static BOOL findCorrectDescriptionForStream(AudioStreamID streamID, int sampleRate) |
| 1009 | | { |
| 1010 | | OSStatus err; |
| 1011 | | UInt32 propertySize = 0; |
| 1012 | | err = AudioStreamGetPropertyInfo(streamID, 0, kAudioStreamPropertyPhysicalFormats, &propertySize, NULL); |
| 1013 | | |
| 1014 | | if(err != noErr || propertySize == 0) |
| 1015 | | return NO; |
| 1016 | | |
| 1017 | | AudioStreamBasicDescription *descs = malloc(propertySize); |
| 1018 | | if(descs == NULL) |
| 1019 | | return NO; |
| 1020 | | |
| 1021 | | int formatCount = propertySize / sizeof(AudioStreamBasicDescription); |
| 1022 | | err = AudioStreamGetProperty(streamID, 0, kAudioStreamPropertyPhysicalFormats, &propertySize, descs); |
| 1023 | | |
| 1024 | | if(err != noErr) |
| 1025 | | { |
| 1026 | | free(descs); |
| 1027 | | return NO; |
| 1028 | | } |
| 1029 | | |
| 1030 | | int i; |
| 1031 | | BOOL ret = NO; |
| 1032 | | for(i=0; i<formatCount; i++) |
| 1033 | | { |
| 1034 | | if (descs[i].mBitsPerChannel == 16 && descs[i].mFormatID == kAudioFormatLinearPCM) |
| 1035 | | { |
| 1036 | | if(descs[i].mSampleRate == sampleRate) |
| 1037 | | { |
| 1038 | | err = AudioStreamSetProperty(streamID, NULL, 0, kAudioStreamPropertyPhysicalFormat, sizeof(AudioStreamBasicDescription), descs + i); |
| 1039 | | if(err != noErr) |
| 1040 | | continue; |
| 1041 | | ret = YES; |
| 1042 | | break; |
| 1043 | | } |
| 1044 | | } |
| 1045 | | } |
| 1046 | | free(descs); |
| 1047 | | return ret; |
| 1048 | | } |
| 1049 | | |
| 1050 | | static BOOL setupDevice(AudioDeviceID devID, int sampleRate) |
| 1051 | | { |
| 1052 | | OSStatus err; |
| 1053 | | UInt32 propertySize = 0; |
| 1054 | | err = AudioDeviceGetPropertyInfo(devID, 0, FALSE, kAudioDevicePropertyStreams, &propertySize, NULL); |
| 1055 | | |
| 1056 | | if(err != noErr || propertySize == 0) |
| 1057 | | return NO; |
| 1058 | | |
| 1059 | | AudioStreamID *streams = malloc(propertySize); |
| 1060 | | if(streams == NULL) |
| 1061 | | return NO; |
| 1062 | | |
| 1063 | | int streamCount = propertySize / sizeof(AudioStreamID); |
| 1064 | | err = AudioDeviceGetProperty(devID, 0, FALSE, kAudioDevicePropertyStreams, &propertySize, streams); |
| 1065 | | if(err != noErr) |
| 1066 | | { |
| 1067 | | free(streams); |
| 1068 | | return NO; |
| 1069 | | } |
| 1070 | | |
| 1071 | | int i; |
| 1072 | | BOOL ret = NO; |
| 1073 | | for(i=0; i<streamCount; i++) |
| 1074 | | { |
| 1075 | | if(findCorrectDescriptionForStream(streams[i], sampleRate)) |
| 1076 | | { |
| 1077 | | ret = YES; |
| 1078 | | break; |
| 1079 | | } |
| 1080 | | } |
| 1081 | | free(streams); |
| 1082 | | return ret; |
| 1083 | | } |
| 1084 | | |
| 1085 | | static BOOL setupAudioOutput(int sampleRate) |
| 1086 | | { |
| 1087 | | OSErr err; |
| 1088 | | UInt32 propertySize = 0; |
| 1089 | | |
| 1090 | | err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &propertySize, NULL); |
| 1091 | | if(err != noErr || propertySize == 0) |
| 1092 | | return NO; |
| 1093 | | |
| 1094 | | AudioDeviceID *devs = malloc(propertySize); |
| 1095 | | if(devs == NULL) |
| 1096 | | return NO; |
| 1097 | | |
| 1098 | | err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &propertySize, devs); |
| 1099 | | if(err != noErr) |
| 1100 | | { |
| 1101 | | free(devs); |
| 1102 | | return NO; |
| 1103 | | } |
| 1104 | | |
| 1105 | | int i, devCount = propertySize/sizeof(AudioDeviceID); |
| 1106 | | BOOL ret = NO; |
| 1107 | | for(i=0; i<devCount; i++) |
| 1108 | | { |
| 1109 | | if(setupDevice(devs[i], sampleRate)) |
| 1110 | | { |
| 1111 | | err = AudioHardwareSetProperty(kAudioHardwarePropertyDefaultOutputDevice, sizeof(AudioDeviceID), devs + i); |
| 1112 | | if(err != noErr) |
| 1113 | | continue; |
| 1114 | | ret = YES; |
| 1115 | | break; |
| 1116 | | } |
| 1117 | | } |
| 1118 | | free(devs); |
| 1119 | | return ret; |
| 1120 | | } |
| 1121 | | |