├── ExtAudioConverter ├── .DS_Store ├── ExtAudioConverter.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── ExtAudioConverter.xccheckout │ │ └── xcuserdata │ │ │ ├── lixing.xcuserdatad │ │ │ ├── UserInterfaceState.xcuserstate │ │ │ └── WorkspaceSettings.xcsettings │ │ │ └── xingli.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ ├── lixing.xcuserdatad │ │ ├── xcdebugger │ │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ │ ├── ExtAudioConverter.xcscheme │ │ │ └── xcschememanagement.plist │ │ └── xingli.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ ├── ExtAudioConverter.xcscheme │ │ └── xcschememanagement.plist ├── ExtAudioConverter │ ├── ExtAudioConverter.h │ ├── ExtAudioConverter.m │ ├── input.wav │ └── main.m ├── lame.h └── libmp3lame.a └── README.md /ExtAudioConverter/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixing123/ExtAudioFileConverter/1f8f5ad927937d62b97e2a00b7687cde74ce5ec3/ExtAudioConverter/.DS_Store -------------------------------------------------------------------------------- /ExtAudioConverter/ExtAudioConverter.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 8E1086F41AE8C2AC0088E699 /* libmp3lame.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E1086F31AE8C2AC0088E699 /* libmp3lame.a */; }; 11 | 8EE9B5531AD67A5B0009BD0A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EE9B5521AD67A5B0009BD0A /* main.m */; }; 12 | 8EE9B55B1AD67A730009BD0A /* ExtAudioConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EE9B55A1AD67A730009BD0A /* ExtAudioConverter.m */; }; 13 | 8EE9B55D1AD67E460009BD0A /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8EE9B55C1AD67E460009BD0A /* AudioToolbox.framework */; }; 14 | /* End PBXBuildFile section */ 15 | 16 | /* Begin PBXCopyFilesBuildPhase section */ 17 | 8EE9B54D1AD67A5B0009BD0A /* CopyFiles */ = { 18 | isa = PBXCopyFilesBuildPhase; 19 | buildActionMask = 2147483647; 20 | dstPath = /usr/share/man/man1/; 21 | dstSubfolderSpec = 0; 22 | files = ( 23 | ); 24 | runOnlyForDeploymentPostprocessing = 1; 25 | }; 26 | /* End PBXCopyFilesBuildPhase section */ 27 | 28 | /* Begin PBXFileReference section */ 29 | 8E1086F21AE8C2A10088E699 /* lame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lame.h; sourceTree = ""; }; 30 | 8E1086F31AE8C2AC0088E699 /* libmp3lame.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libmp3lame.a; sourceTree = ""; }; 31 | 8EA190671B5E3B42005EB05B /* input.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = input.wav; sourceTree = ""; }; 32 | 8EE9B54F1AD67A5B0009BD0A /* ExtAudioConverter */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ExtAudioConverter; sourceTree = BUILT_PRODUCTS_DIR; }; 33 | 8EE9B5521AD67A5B0009BD0A /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 34 | 8EE9B5591AD67A730009BD0A /* ExtAudioConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExtAudioConverter.h; sourceTree = ""; }; 35 | 8EE9B55A1AD67A730009BD0A /* ExtAudioConverter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExtAudioConverter.m; sourceTree = ""; }; 36 | 8EE9B55C1AD67E460009BD0A /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; 37 | /* End PBXFileReference section */ 38 | 39 | /* Begin PBXFrameworksBuildPhase section */ 40 | 8EE9B54C1AD67A5B0009BD0A /* Frameworks */ = { 41 | isa = PBXFrameworksBuildPhase; 42 | buildActionMask = 2147483647; 43 | files = ( 44 | 8EE9B55D1AD67E460009BD0A /* AudioToolbox.framework in Frameworks */, 45 | 8E1086F41AE8C2AC0088E699 /* libmp3lame.a in Frameworks */, 46 | ); 47 | runOnlyForDeploymentPostprocessing = 0; 48 | }; 49 | /* End PBXFrameworksBuildPhase section */ 50 | 51 | /* Begin PBXGroup section */ 52 | 8EE9B5461AD67A5B0009BD0A = { 53 | isa = PBXGroup; 54 | children = ( 55 | 8EFA3FD21AE8A09800B8CFDA /* lame */, 56 | 8EE9B55C1AD67E460009BD0A /* AudioToolbox.framework */, 57 | 8EE9B5511AD67A5B0009BD0A /* ExtAudioConverter */, 58 | 8EE9B5501AD67A5B0009BD0A /* Products */, 59 | ); 60 | sourceTree = ""; 61 | }; 62 | 8EE9B5501AD67A5B0009BD0A /* Products */ = { 63 | isa = PBXGroup; 64 | children = ( 65 | 8EE9B54F1AD67A5B0009BD0A /* ExtAudioConverter */, 66 | ); 67 | name = Products; 68 | sourceTree = ""; 69 | }; 70 | 8EE9B5511AD67A5B0009BD0A /* ExtAudioConverter */ = { 71 | isa = PBXGroup; 72 | children = ( 73 | 8EE9B5521AD67A5B0009BD0A /* main.m */, 74 | 8EE9B5591AD67A730009BD0A /* ExtAudioConverter.h */, 75 | 8EE9B55A1AD67A730009BD0A /* ExtAudioConverter.m */, 76 | 8EA190671B5E3B42005EB05B /* input.wav */, 77 | ); 78 | path = ExtAudioConverter; 79 | sourceTree = ""; 80 | }; 81 | 8EFA3FD21AE8A09800B8CFDA /* lame */ = { 82 | isa = PBXGroup; 83 | children = ( 84 | 8E1086F21AE8C2A10088E699 /* lame.h */, 85 | 8E1086F31AE8C2AC0088E699 /* libmp3lame.a */, 86 | ); 87 | name = lame; 88 | sourceTree = ""; 89 | }; 90 | /* End PBXGroup section */ 91 | 92 | /* Begin PBXNativeTarget section */ 93 | 8EE9B54E1AD67A5B0009BD0A /* ExtAudioConverter */ = { 94 | isa = PBXNativeTarget; 95 | buildConfigurationList = 8EE9B5561AD67A5B0009BD0A /* Build configuration list for PBXNativeTarget "ExtAudioConverter" */; 96 | buildPhases = ( 97 | 8EE9B54B1AD67A5B0009BD0A /* Sources */, 98 | 8EE9B54C1AD67A5B0009BD0A /* Frameworks */, 99 | 8EE9B54D1AD67A5B0009BD0A /* CopyFiles */, 100 | ); 101 | buildRules = ( 102 | ); 103 | dependencies = ( 104 | ); 105 | name = ExtAudioConverter; 106 | productName = ExtAudioConverter; 107 | productReference = 8EE9B54F1AD67A5B0009BD0A /* ExtAudioConverter */; 108 | productType = "com.apple.product-type.tool"; 109 | }; 110 | /* End PBXNativeTarget section */ 111 | 112 | /* Begin PBXProject section */ 113 | 8EE9B5471AD67A5B0009BD0A /* Project object */ = { 114 | isa = PBXProject; 115 | attributes = { 116 | LastUpgradeCheck = 0620; 117 | ORGANIZATIONNAME = lixing123.com; 118 | TargetAttributes = { 119 | 8EE9B54E1AD67A5B0009BD0A = { 120 | CreatedOnToolsVersion = 6.2; 121 | }; 122 | }; 123 | }; 124 | buildConfigurationList = 8EE9B54A1AD67A5B0009BD0A /* Build configuration list for PBXProject "ExtAudioConverter" */; 125 | compatibilityVersion = "Xcode 3.2"; 126 | developmentRegion = English; 127 | hasScannedForEncodings = 0; 128 | knownRegions = ( 129 | en, 130 | ); 131 | mainGroup = 8EE9B5461AD67A5B0009BD0A; 132 | productRefGroup = 8EE9B5501AD67A5B0009BD0A /* Products */; 133 | projectDirPath = ""; 134 | projectRoot = ""; 135 | targets = ( 136 | 8EE9B54E1AD67A5B0009BD0A /* ExtAudioConverter */, 137 | ); 138 | }; 139 | /* End PBXProject section */ 140 | 141 | /* Begin PBXSourcesBuildPhase section */ 142 | 8EE9B54B1AD67A5B0009BD0A /* Sources */ = { 143 | isa = PBXSourcesBuildPhase; 144 | buildActionMask = 2147483647; 145 | files = ( 146 | 8EE9B5531AD67A5B0009BD0A /* main.m in Sources */, 147 | 8EE9B55B1AD67A730009BD0A /* ExtAudioConverter.m in Sources */, 148 | ); 149 | runOnlyForDeploymentPostprocessing = 0; 150 | }; 151 | /* End PBXSourcesBuildPhase section */ 152 | 153 | /* Begin XCBuildConfiguration section */ 154 | 8EE9B5541AD67A5B0009BD0A /* Debug */ = { 155 | isa = XCBuildConfiguration; 156 | buildSettings = { 157 | ALWAYS_SEARCH_USER_PATHS = NO; 158 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 159 | CLANG_CXX_LIBRARY = "libc++"; 160 | CLANG_ENABLE_MODULES = YES; 161 | CLANG_ENABLE_OBJC_ARC = YES; 162 | CLANG_WARN_BOOL_CONVERSION = YES; 163 | CLANG_WARN_CONSTANT_CONVERSION = YES; 164 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 165 | CLANG_WARN_EMPTY_BODY = YES; 166 | CLANG_WARN_ENUM_CONVERSION = YES; 167 | CLANG_WARN_INT_CONVERSION = YES; 168 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 169 | CLANG_WARN_UNREACHABLE_CODE = YES; 170 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 171 | COPY_PHASE_STRIP = NO; 172 | ENABLE_STRICT_OBJC_MSGSEND = YES; 173 | GCC_C_LANGUAGE_STANDARD = gnu99; 174 | GCC_DYNAMIC_NO_PIC = NO; 175 | GCC_OPTIMIZATION_LEVEL = 0; 176 | GCC_PREPROCESSOR_DEFINITIONS = ( 177 | "DEBUG=1", 178 | "$(inherited)", 179 | ); 180 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 181 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 182 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 183 | GCC_WARN_UNDECLARED_SELECTOR = YES; 184 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 185 | GCC_WARN_UNUSED_FUNCTION = YES; 186 | GCC_WARN_UNUSED_VARIABLE = YES; 187 | MACOSX_DEPLOYMENT_TARGET = 10.10; 188 | MTL_ENABLE_DEBUG_INFO = YES; 189 | ONLY_ACTIVE_ARCH = YES; 190 | SDKROOT = macosx; 191 | }; 192 | name = Debug; 193 | }; 194 | 8EE9B5551AD67A5B0009BD0A /* Release */ = { 195 | isa = XCBuildConfiguration; 196 | buildSettings = { 197 | ALWAYS_SEARCH_USER_PATHS = NO; 198 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 199 | CLANG_CXX_LIBRARY = "libc++"; 200 | CLANG_ENABLE_MODULES = YES; 201 | CLANG_ENABLE_OBJC_ARC = YES; 202 | CLANG_WARN_BOOL_CONVERSION = YES; 203 | CLANG_WARN_CONSTANT_CONVERSION = YES; 204 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 205 | CLANG_WARN_EMPTY_BODY = YES; 206 | CLANG_WARN_ENUM_CONVERSION = YES; 207 | CLANG_WARN_INT_CONVERSION = YES; 208 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 209 | CLANG_WARN_UNREACHABLE_CODE = YES; 210 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 211 | COPY_PHASE_STRIP = NO; 212 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 213 | ENABLE_NS_ASSERTIONS = NO; 214 | ENABLE_STRICT_OBJC_MSGSEND = YES; 215 | GCC_C_LANGUAGE_STANDARD = gnu99; 216 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 217 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 218 | GCC_WARN_UNDECLARED_SELECTOR = YES; 219 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 220 | GCC_WARN_UNUSED_FUNCTION = YES; 221 | GCC_WARN_UNUSED_VARIABLE = YES; 222 | MACOSX_DEPLOYMENT_TARGET = 10.10; 223 | MTL_ENABLE_DEBUG_INFO = NO; 224 | SDKROOT = macosx; 225 | }; 226 | name = Release; 227 | }; 228 | 8EE9B5571AD67A5B0009BD0A /* Debug */ = { 229 | isa = XCBuildConfiguration; 230 | buildSettings = { 231 | LIBRARY_SEARCH_PATHS = ( 232 | "$(inherited)", 233 | "$(PROJECT_DIR)", 234 | ); 235 | PRODUCT_NAME = "$(TARGET_NAME)"; 236 | }; 237 | name = Debug; 238 | }; 239 | 8EE9B5581AD67A5B0009BD0A /* Release */ = { 240 | isa = XCBuildConfiguration; 241 | buildSettings = { 242 | LIBRARY_SEARCH_PATHS = ( 243 | "$(inherited)", 244 | "$(PROJECT_DIR)", 245 | ); 246 | PRODUCT_NAME = "$(TARGET_NAME)"; 247 | }; 248 | name = Release; 249 | }; 250 | /* End XCBuildConfiguration section */ 251 | 252 | /* Begin XCConfigurationList section */ 253 | 8EE9B54A1AD67A5B0009BD0A /* Build configuration list for PBXProject "ExtAudioConverter" */ = { 254 | isa = XCConfigurationList; 255 | buildConfigurations = ( 256 | 8EE9B5541AD67A5B0009BD0A /* Debug */, 257 | 8EE9B5551AD67A5B0009BD0A /* Release */, 258 | ); 259 | defaultConfigurationIsVisible = 0; 260 | defaultConfigurationName = Release; 261 | }; 262 | 8EE9B5561AD67A5B0009BD0A /* Build configuration list for PBXNativeTarget "ExtAudioConverter" */ = { 263 | isa = XCConfigurationList; 264 | buildConfigurations = ( 265 | 8EE9B5571AD67A5B0009BD0A /* Debug */, 266 | 8EE9B5581AD67A5B0009BD0A /* Release */, 267 | ); 268 | defaultConfigurationIsVisible = 0; 269 | defaultConfigurationName = Release; 270 | }; 271 | /* End XCConfigurationList section */ 272 | }; 273 | rootObject = 8EE9B5471AD67A5B0009BD0A /* Project object */; 274 | } 275 | -------------------------------------------------------------------------------- /ExtAudioConverter/ExtAudioConverter.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ExtAudioConverter/ExtAudioConverter.xcodeproj/project.xcworkspace/xcshareddata/ExtAudioConverter.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 6B6A641C-84B2-4F4C-AF9D-819CEB0DD1E7 9 | IDESourceControlProjectName 10 | ExtAudioConverter 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 7D4FE7030989B0042BC950B2FF664B4F5A4A7948 14 | https://github.com/lixing123/ExtAudioConverter.git 15 | 16 | IDESourceControlProjectPath 17 | ExtAudioConverter/ExtAudioConverter.xcodeproj 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 7D4FE7030989B0042BC950B2FF664B4F5A4A7948 21 | ../../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/lixing123/ExtAudioConverter.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | 7D4FE7030989B0042BC950B2FF664B4F5A4A7948 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 7D4FE7030989B0042BC950B2FF664B4F5A4A7948 36 | IDESourceControlWCCName 37 | ExtAudioConverter 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /ExtAudioConverter/ExtAudioConverter.xcodeproj/project.xcworkspace/xcuserdata/lixing.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixing123/ExtAudioFileConverter/1f8f5ad927937d62b97e2a00b7687cde74ce5ec3/ExtAudioConverter/ExtAudioConverter.xcodeproj/project.xcworkspace/xcuserdata/lixing.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /ExtAudioConverter/ExtAudioConverter.xcodeproj/project.xcworkspace/xcuserdata/lixing.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges 6 | 7 | SnapshotAutomaticallyBeforeSignificantChanges 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ExtAudioConverter/ExtAudioConverter.xcodeproj/project.xcworkspace/xcuserdata/xingli.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixing123/ExtAudioFileConverter/1f8f5ad927937d62b97e2a00b7687cde74ce5ec3/ExtAudioConverter/ExtAudioConverter.xcodeproj/project.xcworkspace/xcuserdata/xingli.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /ExtAudioConverter/ExtAudioConverter.xcodeproj/xcuserdata/lixing.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /ExtAudioConverter/ExtAudioConverter.xcodeproj/xcuserdata/lixing.xcuserdatad/xcschemes/ExtAudioConverter.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 70 | 72 | 78 | 79 | 80 | 81 | 83 | 84 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /ExtAudioConverter/ExtAudioConverter.xcodeproj/xcuserdata/lixing.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | ExtAudioConverter.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 8EE9B54E1AD67A5B0009BD0A 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /ExtAudioConverter/ExtAudioConverter.xcodeproj/xcuserdata/xingli.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /ExtAudioConverter/ExtAudioConverter.xcodeproj/xcuserdata/xingli.xcuserdatad/xcschemes/ExtAudioConverter.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 52 | 58 | 59 | 60 | 61 | 62 | 63 | 69 | 70 | 76 | 77 | 78 | 79 | 81 | 82 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /ExtAudioConverter/ExtAudioConverter.xcodeproj/xcuserdata/xingli.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | ExtAudioConverter.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 8EE9B54E1AD67A5B0009BD0A 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /ExtAudioConverter/ExtAudioConverter/ExtAudioConverter.h: -------------------------------------------------------------------------------- 1 | // 2 | // ExtAudioConverter.h 3 | // ExtAudioConverter 4 | // 5 | // Created by 李 行 on 15/4/9. 6 | // Copyright (c) 2015年 lixing123.com. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | enum BitDepth{ 13 | BitDepth_8 = 8, 14 | BitDepth_16 = 16, 15 | BitDepth_24 = 24, 16 | BitDepth_32 = 32 17 | }; 18 | 19 | //TODO:Add delegate 20 | 21 | @interface ExtAudioConverter : NSObject 22 | 23 | //Must set 24 | @property(nonatomic,retain)NSString* inputFile;//Absolute path 25 | @property(nonatomic,retain)NSString* outputFile;//Absolute path 26 | 27 | //optional 28 | @property(nonatomic,assign)int outputSampleRate;//Default 44100.0 29 | @property(nonatomic,assign)int outputNumberChannels;//Default 2 30 | @property(nonatomic,assign)enum BitDepth outputBitDepth;//Default BitDepth_16 31 | @property(nonatomic,assign)AudioFormatID outputFormatID;//Default Linear PCM 32 | @property(nonatomic,assign)AudioFileTypeID outputFileType;//Default kAudioFileCAFType 33 | //TODO:add bit rate parameter 34 | 35 | -(BOOL)convert; 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /ExtAudioConverter/ExtAudioConverter/ExtAudioConverter.m: -------------------------------------------------------------------------------- 1 | // 2 | // ExtAudioConverter.m 3 | // ExtAudioConverter 4 | // 5 | // Created by 李 行 on 15/4/9. 6 | // Copyright (c) 2015年 lixing123.com. All rights reserved. 7 | // 8 | 9 | #import "ExtAudioConverter.h" 10 | #import "lame.h" 11 | 12 | typedef struct ExtAudioConverterSettings{ 13 | AudioStreamBasicDescription inputPCMFormat; 14 | AudioStreamBasicDescription outputFormat; 15 | 16 | ExtAudioFileRef inputFile; 17 | CFStringRef outputFilePath; 18 | ExtAudioFileRef outputFile; 19 | 20 | AudioStreamPacketDescription* inputPacketDescriptions; 21 | }ExtAudioConverterSettings; 22 | 23 | static void CheckError(OSStatus error, const char *operation) 24 | { 25 | if (error == noErr) return; 26 | char errorString[20]; 27 | // See if it appears to be a 4-char-code 28 | *(UInt32 *)(errorString + 1) = CFSwapInt32HostToBig(error); 29 | if (isprint(errorString[1]) && isprint(errorString[2]) && 30 | isprint(errorString[3]) && isprint(errorString[4])) { 31 | errorString[0] = errorString[5] = '\''; 32 | errorString[6] = '\0'; 33 | } else 34 | // No, format it as an integer 35 | sprintf(errorString, "%d", (int)error); 36 | fprintf(stderr, "Error: %s (%s)\n", operation, errorString); 37 | exit(1); 38 | } 39 | 40 | void startConvert(ExtAudioConverterSettings* settings){ 41 | //Determine the proper buffer size and calculate number of packets per buffer 42 | //for CBR and VBR format 43 | UInt32 sizePerBuffer = 32*1024;//32KB is a good starting point 44 | UInt32 framesPerBuffer = sizePerBuffer/sizeof(SInt16); 45 | 46 | // allocate destination buffer 47 | SInt16 *outputBuffer = (SInt16 *)malloc(sizeof(SInt16) * sizePerBuffer); 48 | 49 | while (1) { 50 | AudioBufferList outputBufferList; 51 | outputBufferList.mNumberBuffers = 1; 52 | outputBufferList.mBuffers[0].mNumberChannels = settings->outputFormat.mChannelsPerFrame; 53 | outputBufferList.mBuffers[0].mDataByteSize = sizePerBuffer; 54 | outputBufferList.mBuffers[0].mData = outputBuffer; 55 | 56 | UInt32 framesCount = framesPerBuffer; 57 | 58 | CheckError(ExtAudioFileRead(settings->inputFile, 59 | &framesCount, 60 | &outputBufferList), 61 | "ExtAudioFileRead failed"); 62 | 63 | if (framesCount==0) { 64 | printf("Done reading from input file\n"); 65 | return; 66 | } 67 | 68 | CheckError(ExtAudioFileWrite(settings->outputFile, 69 | framesCount, 70 | &outputBufferList), 71 | "ExtAudioFileWrite failed"); 72 | } 73 | } 74 | 75 | void startConvertMP3(ExtAudioConverterSettings* settings){ 76 | //Init lame and set parameters 77 | lame_t lame = lame_init(); 78 | lame_set_in_samplerate(lame, settings->inputPCMFormat.mSampleRate); 79 | lame_set_num_channels(lame, settings->inputPCMFormat.mChannelsPerFrame); 80 | lame_set_VBR(lame, vbr_default); 81 | lame_init_params(lame); 82 | 83 | NSString* outputFilePath = (__bridge NSString*)settings->outputFilePath; 84 | FILE* outputFile = fopen([outputFilePath cStringUsingEncoding:1], "wb"); 85 | 86 | UInt32 sizePerBuffer = 32*1024; 87 | UInt32 framesPerBuffer = sizePerBuffer/sizeof(SInt16); 88 | 89 | int write; 90 | 91 | // allocate destination buffer 92 | SInt16 *outputBuffer = (SInt16 *)malloc(sizeof(SInt16) * sizePerBuffer); 93 | 94 | while (1) { 95 | AudioBufferList outputBufferList; 96 | outputBufferList.mNumberBuffers = 1; 97 | outputBufferList.mBuffers[0].mNumberChannels = settings->outputFormat.mChannelsPerFrame; 98 | outputBufferList.mBuffers[0].mDataByteSize = sizePerBuffer; 99 | outputBufferList.mBuffers[0].mData = outputBuffer; 100 | 101 | UInt32 framesCount = framesPerBuffer; 102 | 103 | CheckError(ExtAudioFileRead(settings->inputFile, 104 | &framesCount, 105 | &outputBufferList), 106 | "ExtAudioFileRead failed"); 107 | 108 | SInt16 pcm_buffer[framesCount]; 109 | unsigned char mp3_buffer[framesCount]; 110 | memcpy(pcm_buffer, 111 | outputBufferList.mBuffers[0].mData, 112 | framesCount); 113 | if (framesCount==0) { 114 | printf("Done reading from input file\n"); 115 | //TODO:Add lame_encode_flush for end of file 116 | return; 117 | } 118 | 119 | //the 3rd parameter means number of samples per channel, not number of sample in pcm_buffer 120 | write = lame_encode_buffer_interleaved(lame, 121 | outputBufferList.mBuffers[0].mData, 122 | framesCount, 123 | mp3_buffer, 124 | 0); 125 | size_t result = fwrite(mp3_buffer, 126 | 1, 127 | write, 128 | outputFile); 129 | } 130 | } 131 | 132 | @implementation ExtAudioConverter 133 | 134 | @synthesize inputFile; 135 | @synthesize outputFile; 136 | @synthesize outputSampleRate; 137 | @synthesize outputNumberChannels; 138 | @synthesize outputBitDepth; 139 | 140 | 141 | -(BOOL)convert{ 142 | ExtAudioConverterSettings settings = {0}; 143 | 144 | //Check if source file or output file is null 145 | if (self.inputFile==NULL) { 146 | NSLog(@"Source file is not set"); 147 | return NO; 148 | } 149 | 150 | if (self.outputFile==NULL) { 151 | NSLog(@"Output file is no set"); 152 | return NO; 153 | } 154 | 155 | //Create ExtAudioFileRef 156 | NSURL* sourceURL = [NSURL fileURLWithPath:self.inputFile]; 157 | CheckError(ExtAudioFileOpenURL((__bridge CFURLRef)sourceURL, 158 | &settings.inputFile), 159 | "ExtAudioFileOpenURL failed"); 160 | 161 | [self validateInput:&settings]; 162 | 163 | settings.outputFormat.mSampleRate = self.outputSampleRate; 164 | settings.outputFormat.mBitsPerChannel = self.outputBitDepth; 165 | if (self.outputFormatID==kAudioFormatMPEG4AAC) { 166 | settings.outputFormat.mBitsPerChannel = 0; 167 | } 168 | settings.outputFormat.mChannelsPerFrame = self.outputNumberChannels; 169 | settings.outputFormat.mFormatID = self.outputFormatID; 170 | 171 | if (self.outputFormatID==kAudioFormatLinearPCM) { 172 | settings.outputFormat.mBytesPerFrame = settings.outputFormat.mChannelsPerFrame * settings.outputFormat.mBitsPerChannel/8; 173 | settings.outputFormat.mBytesPerPacket = settings.outputFormat.mBytesPerFrame; 174 | settings.outputFormat.mFramesPerPacket = 1; 175 | settings.outputFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; 176 | //some file type only support big-endian 177 | if (self.outputFileType==kAudioFileAIFFType || self.outputFileType==kAudioFileSoundDesigner2Type || self.outputFileType==kAudioFileAIFCType || self.outputFileType==kAudioFileNextType) { 178 | settings.outputFormat.mFormatFlags |= kAudioFormatFlagIsBigEndian; 179 | } 180 | }else{ 181 | UInt32 size = sizeof(settings.outputFormat); 182 | CheckError(AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, 183 | 0, 184 | NULL, 185 | &size, 186 | &settings.outputFormat), 187 | "AudioFormatGetProperty kAudioFormatProperty_FormatInfo failed"); 188 | } 189 | NSLog(@"output format:%@",[self descriptionForAudioFormat:settings.outputFormat]); 190 | 191 | //Create output file 192 | //if output file path is invalid, this returns an error with 'wht?' 193 | NSURL* outputURL = [NSURL fileURLWithPath:self.outputFile]; 194 | 195 | //create output file 196 | settings.outputFilePath = (__bridge CFStringRef)(self.outputFile); 197 | if (settings.outputFormat.mFormatID!=kAudioFormatMPEGLayer3) { 198 | CheckError(ExtAudioFileCreateWithURL((__bridge CFURLRef)outputURL, 199 | self.outputFileType, 200 | &settings.outputFormat, 201 | NULL, 202 | kAudioFileFlags_EraseFile, 203 | &settings.outputFile), 204 | "Create output file failed, the output file type and output format pair may not match"); 205 | } 206 | 207 | //Set input file's client data format 208 | //Must be PCM, thus as we say, "when you convert data, I want to receive PCM format" 209 | if (settings.outputFormat.mFormatID==kAudioFormatLinearPCM) { 210 | settings.inputPCMFormat = settings.outputFormat; 211 | }else{ 212 | settings.inputPCMFormat.mFormatID = kAudioFormatLinearPCM; 213 | settings.inputPCMFormat.mSampleRate = settings.outputFormat.mSampleRate; 214 | //TODO:set format flags for both OS X and iOS, for all versions 215 | settings.inputPCMFormat.mFormatFlags = kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger; 216 | //TODO:check if size of SInt16 is always suitable 217 | settings.inputPCMFormat.mBitsPerChannel = 8 * sizeof(SInt16); 218 | settings.inputPCMFormat.mChannelsPerFrame = settings.outputFormat.mChannelsPerFrame; 219 | //TODO:check if this is suitable for both interleaved/noninterleaved 220 | settings.inputPCMFormat.mBytesPerPacket = settings.inputPCMFormat.mBytesPerFrame = settings.inputPCMFormat.mChannelsPerFrame*sizeof(SInt16); 221 | settings.inputPCMFormat.mFramesPerPacket = 1; 222 | } 223 | NSLog(@"Client data format:%@",[self descriptionForAudioFormat:settings.inputPCMFormat]); 224 | 225 | CheckError(ExtAudioFileSetProperty(settings.inputFile, 226 | kExtAudioFileProperty_ClientDataFormat, 227 | sizeof(settings.inputPCMFormat), 228 | &settings.inputPCMFormat), 229 | "Setting client data format of input file failed"); 230 | 231 | //If the file has a client data format, then the audio data in ioData is translated from the client format to the file data format, via theExtAudioFile's internal AudioConverter. 232 | if (settings.outputFormat.mFormatID!=kAudioFormatMPEGLayer3) { 233 | CheckError(ExtAudioFileSetProperty(settings.outputFile, 234 | kExtAudioFileProperty_ClientDataFormat, 235 | sizeof(settings.inputPCMFormat), 236 | &settings.inputPCMFormat), 237 | "Setting client data format of output file failed"); 238 | } 239 | 240 | 241 | printf("Start converting...\n"); 242 | if (settings.outputFormat.mFormatID==kAudioFormatMPEGLayer3) { 243 | startConvertMP3(&settings); 244 | }else{ 245 | startConvert(&settings); 246 | } 247 | 248 | 249 | ExtAudioFileDispose(settings.inputFile); 250 | //AudioFileClose/ExtAudioFileDispose function is needed, or else for .wav output file the duration will be 0 251 | ExtAudioFileDispose(settings.outputFile); 252 | return YES; 253 | } 254 | 255 | //Check if the input combination is valid 256 | -(void)validateInput:(ExtAudioConverterSettings*)settigs{ 257 | //Set default output format 258 | if (self.outputSampleRate==0) { 259 | self.outputSampleRate = 44100; 260 | } 261 | 262 | if (self.outputNumberChannels==0) { 263 | self.outputNumberChannels = 2; 264 | } 265 | 266 | if (self.outputBitDepth==0) { 267 | self.outputBitDepth = 16; 268 | } 269 | 270 | if (self.outputFormatID==0) { 271 | self.outputFormatID = kAudioFormatLinearPCM; 272 | } 273 | 274 | if (self.outputFileType==0) { 275 | //caf type is the most powerful file format 276 | self.outputFileType = kAudioFileCAFType; 277 | } 278 | 279 | BOOL valid = YES; 280 | //The file format and data format match documentatin is at: https://developer.apple.com/library/ios/documentation/MusicAudio/Conceptual/CoreAudioOverview/SupportedAudioFormatsMacOSX/SupportedAudioFormatsMacOSX.html 281 | switch (self.outputFileType) { 282 | case kAudioFileWAVEType:{//for wave file format 283 | //WAVE file type only support PCM, alaw and ulaw 284 | valid = self.outputFormatID==kAudioFormatLinearPCM || self.outputFormatID==kAudioFormatALaw || self.outputFormatID==kAudioFormatULaw; 285 | break; 286 | } 287 | case kAudioFileAIFFType:{ 288 | //AIFF only support PCM format 289 | valid = self.outputFormatID==kAudioFormatLinearPCM; 290 | break; 291 | } 292 | case kAudioFileAAC_ADTSType:{ 293 | //aac only support aac data format 294 | valid = self.outputFormatID==kAudioFormatMPEG4AAC; 295 | break; 296 | } 297 | case kAudioFileAC3Type:{ 298 | //convert from PCM to ac3 format is not supported 299 | valid = NO; 300 | break; 301 | } 302 | case kAudioFileAIFCType:{ 303 | //TODO:kAudioFileAIFCType together with kAudioFormatMACE3/kAudioFormatMACE6/kAudioFormatQDesign2/kAudioFormatQUALCOMM pair failed 304 | //Since MACE3:1/MACE6:1 is obsolete, they're not supported yet 305 | valid = self.outputFormatID==kAudioFormatLinearPCM || self.outputFormatID==kAudioFormatULaw || self.outputFormatID==kAudioFormatALaw || self.outputFormatID==kAudioFormatAppleIMA4 || self.outputFormatID==kAudioFormatQDesign2 || self.outputFormatID==kAudioFormatQUALCOMM; 306 | break; 307 | } 308 | case kAudioFileCAFType:{ 309 | //caf file type support almost all data format 310 | //TODO:not all foramt are supported, check them out 311 | valid = YES; 312 | break; 313 | } 314 | case kAudioFileMP3Type:{ 315 | //TODO:support mp3 type 316 | valid = self.outputFormatID==kAudioFormatMPEGLayer3; 317 | break; 318 | } 319 | case kAudioFileMPEG4Type:{ 320 | valid = self.outputFormatID==kAudioFormatMPEG4AAC; 321 | break; 322 | } 323 | case kAudioFileM4AType:{ 324 | valid = self.outputFormatID==kAudioFormatMPEG4AAC || self.outputFormatID==kAudioFormatAppleLossless; 325 | break; 326 | } 327 | case kAudioFileNextType:{ 328 | valid = self.outputFormatID==kAudioFormatLinearPCM || self.outputFormatID==kAudioFormatULaw; 329 | break; 330 | } 331 | case kAudioFileSoundDesigner2Type:{ 332 | valid = self.outputFormatID==kAudioFormatLinearPCM; 333 | break; 334 | } 335 | //TODO:check iLBC format 336 | default: 337 | break; 338 | } 339 | 340 | if (!valid) { 341 | NSLog(@"the file format and data format pair is not valid"); 342 | exit(-1); 343 | } 344 | 345 | } 346 | 347 | -(NSString*)descriptionForAudioFormat:(AudioStreamBasicDescription) audioFormat 348 | { 349 | NSMutableString *description = [NSMutableString new]; 350 | 351 | // From https://developer.apple.com/library/ios/documentation/MusicAudio/Conceptual/AudioUnitHostingGuide_iOS/ConstructingAudioUnitApps/ConstructingAudioUnitApps.html (Listing 2-8) 352 | char formatIDString[5]; 353 | UInt32 formatID = CFSwapInt32HostToBig (audioFormat.mFormatID); 354 | bcopy (&formatID, formatIDString, 4); 355 | formatIDString[4] = '\0'; 356 | 357 | [description appendString:@"\n"]; 358 | [description appendFormat:@"Sample Rate: %10.0f \n", audioFormat.mSampleRate]; 359 | [description appendFormat:@"Format ID: %10s \n", formatIDString]; 360 | [description appendFormat:@"Format Flags: %10d \n", (unsigned int)audioFormat.mFormatFlags]; 361 | [description appendFormat:@"Bytes per Packet: %10d \n", (unsigned int)audioFormat.mBytesPerPacket]; 362 | [description appendFormat:@"Frames per Packet: %10d \n", (unsigned int)audioFormat.mFramesPerPacket]; 363 | [description appendFormat:@"Bytes per Frame: %10d \n", (unsigned int)audioFormat.mBytesPerFrame]; 364 | [description appendFormat:@"Channels per Frame: %10d \n", (unsigned int)audioFormat.mChannelsPerFrame]; 365 | [description appendFormat:@"Bits per Channel: %10d \n", (unsigned int)audioFormat.mBitsPerChannel]; 366 | 367 | // Add flags (supposing standard flags). 368 | [description appendString:[self descriptionForStandardFlags:audioFormat.mFormatFlags]]; 369 | 370 | return [NSString stringWithString:description]; 371 | } 372 | 373 | -(NSString*)descriptionForStandardFlags:(UInt32) mFormatFlags 374 | { 375 | NSMutableString *description = [NSMutableString new]; 376 | 377 | if (mFormatFlags & kAudioFormatFlagIsFloat) 378 | { [description appendString:@"kAudioFormatFlagIsFloat \n"]; } 379 | if (mFormatFlags & kAudioFormatFlagIsBigEndian) 380 | { [description appendString:@"kAudioFormatFlagIsBigEndian \n"]; } 381 | if (mFormatFlags & kAudioFormatFlagIsSignedInteger) 382 | { [description appendString:@"kAudioFormatFlagIsSignedInteger \n"]; } 383 | if (mFormatFlags & kAudioFormatFlagIsPacked) 384 | { [description appendString:@"kAudioFormatFlagIsPacked \n"]; } 385 | if (mFormatFlags & kAudioFormatFlagIsAlignedHigh) 386 | { [description appendString:@"kAudioFormatFlagIsAlignedHigh \n"]; } 387 | if (mFormatFlags & kAudioFormatFlagIsNonInterleaved) 388 | { [description appendString:@"kAudioFormatFlagIsNonInterleaved \n"]; } 389 | if (mFormatFlags & kAudioFormatFlagIsNonMixable) 390 | { [description appendString:@"kAudioFormatFlagIsNonMixable \n"]; } 391 | if (mFormatFlags & kAudioFormatFlagsAreAllClear) 392 | { [description appendString:@"kAudioFormatFlagsAreAllClear \n"]; } 393 | if (mFormatFlags & kLinearPCMFormatFlagIsFloat) 394 | { [description appendString:@"kLinearPCMFormatFlagIsFloat \n"]; } 395 | if (mFormatFlags & kLinearPCMFormatFlagIsBigEndian) 396 | { [description appendString:@"kLinearPCMFormatFlagIsBigEndian \n"]; } 397 | if (mFormatFlags & kLinearPCMFormatFlagIsSignedInteger) 398 | { [description appendString:@"kLinearPCMFormatFlagIsSignedInteger \n"]; } 399 | if (mFormatFlags & kLinearPCMFormatFlagIsPacked) 400 | { [description appendString:@"kLinearPCMFormatFlagIsPacked \n"]; } 401 | if (mFormatFlags & kLinearPCMFormatFlagIsAlignedHigh) 402 | { [description appendString:@"kLinearPCMFormatFlagIsAlignedHigh \n"]; } 403 | if (mFormatFlags & kLinearPCMFormatFlagIsNonInterleaved) 404 | { [description appendString:@"kLinearPCMFormatFlagIsNonInterleaved \n"]; } 405 | if (mFormatFlags & kLinearPCMFormatFlagIsNonMixable) 406 | { [description appendString:@"kLinearPCMFormatFlagIsNonMixable \n"]; } 407 | if (mFormatFlags & kLinearPCMFormatFlagsSampleFractionShift) 408 | { [description appendString:@"kLinearPCMFormatFlagsSampleFractionShift \n"]; } 409 | if (mFormatFlags & kLinearPCMFormatFlagsSampleFractionMask) 410 | { [description appendString:@"kLinearPCMFormatFlagsSampleFractionMask \n"]; } 411 | if (mFormatFlags & kLinearPCMFormatFlagsAreAllClear) 412 | { [description appendString:@"kLinearPCMFormatFlagsAreAllClear \n"]; } 413 | if (mFormatFlags & kAppleLosslessFormatFlag_16BitSourceData) 414 | { [description appendString:@"kAppleLosslessFormatFlag_16BitSourceData \n"]; } 415 | if (mFormatFlags & kAppleLosslessFormatFlag_20BitSourceData) 416 | { [description appendString:@"kAppleLosslessFormatFlag_20BitSourceData \n"]; } 417 | if (mFormatFlags & kAppleLosslessFormatFlag_24BitSourceData) 418 | { [description appendString:@"kAppleLosslessFormatFlag_24BitSourceData \n"]; } 419 | if (mFormatFlags & kAppleLosslessFormatFlag_32BitSourceData) 420 | { [description appendString:@"kAppleLosslessFormatFlag_32BitSourceData \n"]; } 421 | 422 | return [NSString stringWithString:description]; 423 | } 424 | 425 | 426 | @end 427 | -------------------------------------------------------------------------------- /ExtAudioConverter/ExtAudioConverter/input.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixing123/ExtAudioFileConverter/1f8f5ad927937d62b97e2a00b7687cde74ce5ec3/ExtAudioConverter/ExtAudioConverter/input.wav -------------------------------------------------------------------------------- /ExtAudioConverter/ExtAudioConverter/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // ExtAudioConverter 4 | // 5 | // Created by 李 行 on 15/4/9. 6 | // Copyright (c) 2015年 lixing123.com. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ExtAudioConverter.h" 11 | 12 | int main(int argc, const char * argv[]) { 13 | @autoreleasepool { 14 | ExtAudioConverter* converter = [[ExtAudioConverter alloc] init]; 15 | //converter.inputFile = @"/Users/lixing/Desktop/playAndRecord.caf"; 16 | converter.inputFile = @"/Users/lixing/Desktop/input.wav"; 17 | //output file extension is for your convenience 18 | converter.outputFile = @"/Users/lixing/Desktop/output.mp3"; 19 | 20 | //TODO:some option combinations are not valid. 21 | //Check them out 22 | converter.outputSampleRate = 8000; 23 | converter.outputNumberChannels = 1; 24 | converter.outputBitDepth = BitDepth_16; 25 | converter.outputFormatID = kAudioFormatMPEGLayer3; 26 | converter.outputFileType = kAudioFileMP3Type; 27 | [converter convert]; 28 | } 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /ExtAudioConverter/lame.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Interface to MP3 LAME encoding engine 3 | * 4 | * Copyright (c) 1999 Mark Taylor 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Library General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Library General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Library General Public 17 | * License along with this library; if not, write to the 18 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 | * Boston, MA 02111-1307, USA. 20 | */ 21 | 22 | /* $Id: lame.h,v 1.189.2.1 2012/01/08 23:49:58 robert Exp $ */ 23 | 24 | #ifndef LAME_LAME_H 25 | #define LAME_LAME_H 26 | 27 | /* for size_t typedef */ 28 | #include 29 | /* for va_list typedef */ 30 | #include 31 | /* for FILE typedef, TODO: remove when removing lame_mp3_tags_fid */ 32 | #include 33 | 34 | #if defined(__cplusplus) 35 | extern "C" { 36 | #endif 37 | 38 | typedef void (*lame_report_function)(const char *format, va_list ap); 39 | 40 | #if defined(WIN32) || defined(_WIN32) 41 | #undef CDECL 42 | #define CDECL __cdecl 43 | #else 44 | #define CDECL 45 | #endif 46 | 47 | #define DEPRECATED_OR_OBSOLETE_CODE_REMOVED 1 48 | 49 | typedef enum vbr_mode_e { 50 | vbr_off=0, 51 | vbr_mt, /* obsolete, same as vbr_mtrh */ 52 | vbr_rh, 53 | vbr_abr, 54 | vbr_mtrh, 55 | vbr_max_indicator, /* Don't use this! It's used for sanity checks. */ 56 | vbr_default=vbr_mtrh /* change this to change the default VBR mode of LAME */ 57 | } vbr_mode; 58 | 59 | 60 | /* MPEG modes */ 61 | typedef enum MPEG_mode_e { 62 | STEREO = 0, 63 | JOINT_STEREO, 64 | DUAL_CHANNEL, /* LAME doesn't supports this! */ 65 | MONO, 66 | NOT_SET, 67 | MAX_INDICATOR /* Don't use this! It's used for sanity checks. */ 68 | } MPEG_mode; 69 | 70 | /* Padding types */ 71 | typedef enum Padding_type_e { 72 | PAD_NO = 0, 73 | PAD_ALL, 74 | PAD_ADJUST, 75 | PAD_MAX_INDICATOR /* Don't use this! It's used for sanity checks. */ 76 | } Padding_type; 77 | 78 | 79 | 80 | /*presets*/ 81 | typedef enum preset_mode_e { 82 | /*values from 8 to 320 should be reserved for abr bitrates*/ 83 | /*for abr I'd suggest to directly use the targeted bitrate as a value*/ 84 | ABR_8 = 8, 85 | ABR_320 = 320, 86 | 87 | V9 = 410, /*Vx to match Lame and VBR_xx to match FhG*/ 88 | VBR_10 = 410, 89 | V8 = 420, 90 | VBR_20 = 420, 91 | V7 = 430, 92 | VBR_30 = 430, 93 | V6 = 440, 94 | VBR_40 = 440, 95 | V5 = 450, 96 | VBR_50 = 450, 97 | V4 = 460, 98 | VBR_60 = 460, 99 | V3 = 470, 100 | VBR_70 = 470, 101 | V2 = 480, 102 | VBR_80 = 480, 103 | V1 = 490, 104 | VBR_90 = 490, 105 | V0 = 500, 106 | VBR_100 = 500, 107 | 108 | 109 | 110 | /*still there for compatibility*/ 111 | R3MIX = 1000, 112 | STANDARD = 1001, 113 | EXTREME = 1002, 114 | INSANE = 1003, 115 | STANDARD_FAST = 1004, 116 | EXTREME_FAST = 1005, 117 | MEDIUM = 1006, 118 | MEDIUM_FAST = 1007 119 | } preset_mode; 120 | 121 | 122 | /*asm optimizations*/ 123 | typedef enum asm_optimizations_e { 124 | MMX = 1, 125 | AMD_3DNOW = 2, 126 | SSE = 3 127 | } asm_optimizations; 128 | 129 | 130 | /* psychoacoustic model */ 131 | typedef enum Psy_model_e { 132 | PSY_GPSYCHO = 1, 133 | PSY_NSPSYTUNE = 2 134 | } Psy_model; 135 | 136 | 137 | /* buffer considerations */ 138 | typedef enum buffer_constraint_e { 139 | MDB_DEFAULT=0, 140 | MDB_STRICT_ISO=1, 141 | MDB_MAXIMUM=2 142 | } buffer_constraint; 143 | 144 | 145 | struct lame_global_struct; 146 | typedef struct lame_global_struct lame_global_flags; 147 | typedef lame_global_flags *lame_t; 148 | 149 | 150 | 151 | 152 | /*********************************************************************** 153 | * 154 | * The LAME API 155 | * These functions should be called, in this order, for each 156 | * MP3 file to be encoded. See the file "API" for more documentation 157 | * 158 | ***********************************************************************/ 159 | 160 | 161 | /* 162 | * REQUIRED: 163 | * initialize the encoder. sets default for all encoder parameters, 164 | * returns NULL if some malloc()'s failed 165 | * otherwise returns pointer to structure needed for all future 166 | * API calls. 167 | */ 168 | lame_global_flags * CDECL lame_init(void); 169 | #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED 170 | #else 171 | /* obsolete version */ 172 | int CDECL lame_init_old(lame_global_flags *); 173 | #endif 174 | 175 | /* 176 | * OPTIONAL: 177 | * set as needed to override defaults 178 | */ 179 | 180 | /******************************************************************** 181 | * input stream description 182 | ***********************************************************************/ 183 | /* number of samples. default = 2^32-1 */ 184 | int CDECL lame_set_num_samples(lame_global_flags *, unsigned long); 185 | unsigned long CDECL lame_get_num_samples(const lame_global_flags *); 186 | 187 | /* input sample rate in Hz. default = 44100hz */ 188 | int CDECL lame_set_in_samplerate(lame_global_flags *, int); 189 | int CDECL lame_get_in_samplerate(const lame_global_flags *); 190 | 191 | /* number of channels in input stream. default=2 */ 192 | int CDECL lame_set_num_channels(lame_global_flags *, int); 193 | int CDECL lame_get_num_channels(const lame_global_flags *); 194 | 195 | /* 196 | scale the input by this amount before encoding. default=1 197 | (not used by decoding routines) 198 | */ 199 | int CDECL lame_set_scale(lame_global_flags *, float); 200 | float CDECL lame_get_scale(const lame_global_flags *); 201 | 202 | /* 203 | scale the channel 0 (left) input by this amount before encoding. default=1 204 | (not used by decoding routines) 205 | */ 206 | int CDECL lame_set_scale_left(lame_global_flags *, float); 207 | float CDECL lame_get_scale_left(const lame_global_flags *); 208 | 209 | /* 210 | scale the channel 1 (right) input by this amount before encoding. default=1 211 | (not used by decoding routines) 212 | */ 213 | int CDECL lame_set_scale_right(lame_global_flags *, float); 214 | float CDECL lame_get_scale_right(const lame_global_flags *); 215 | 216 | /* 217 | output sample rate in Hz. default = 0, which means LAME picks best value 218 | based on the amount of compression. MPEG only allows: 219 | MPEG1 32, 44.1, 48khz 220 | MPEG2 16, 22.05, 24 221 | MPEG2.5 8, 11.025, 12 222 | (not used by decoding routines) 223 | */ 224 | int CDECL lame_set_out_samplerate(lame_global_flags *, int); 225 | int CDECL lame_get_out_samplerate(const lame_global_flags *); 226 | 227 | 228 | /******************************************************************** 229 | * general control parameters 230 | ***********************************************************************/ 231 | /* 1=cause LAME to collect data for an MP3 frame analyzer. default=0 */ 232 | int CDECL lame_set_analysis(lame_global_flags *, int); 233 | int CDECL lame_get_analysis(const lame_global_flags *); 234 | 235 | /* 236 | 1 = write a Xing VBR header frame. 237 | default = 1 238 | this variable must have been added by a Hungarian notation Windows programmer :-) 239 | */ 240 | int CDECL lame_set_bWriteVbrTag(lame_global_flags *, int); 241 | int CDECL lame_get_bWriteVbrTag(const lame_global_flags *); 242 | 243 | /* 1=decode only. use lame/mpglib to convert mp3/ogg to wav. default=0 */ 244 | int CDECL lame_set_decode_only(lame_global_flags *, int); 245 | int CDECL lame_get_decode_only(const lame_global_flags *); 246 | 247 | #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED 248 | #else 249 | /* 1=encode a Vorbis .ogg file. default=0 */ 250 | /* DEPRECATED */ 251 | int CDECL lame_set_ogg(lame_global_flags *, int); 252 | int CDECL lame_get_ogg(const lame_global_flags *); 253 | #endif 254 | 255 | /* 256 | internal algorithm selection. True quality is determined by the bitrate 257 | but this variable will effect quality by selecting expensive or cheap algorithms. 258 | quality=0..9. 0=best (very slow). 9=worst. 259 | recommended: 2 near-best quality, not too slow 260 | 5 good quality, fast 261 | 7 ok quality, really fast 262 | */ 263 | int CDECL lame_set_quality(lame_global_flags *, int); 264 | int CDECL lame_get_quality(const lame_global_flags *); 265 | 266 | /* 267 | mode = 0,1,2,3 = stereo, jstereo, dual channel (not supported), mono 268 | default: lame picks based on compression ration and input channels 269 | */ 270 | int CDECL lame_set_mode(lame_global_flags *, MPEG_mode); 271 | MPEG_mode CDECL lame_get_mode(const lame_global_flags *); 272 | 273 | #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED 274 | #else 275 | /* 276 | mode_automs. Use a M/S mode with a switching threshold based on 277 | compression ratio 278 | DEPRECATED 279 | */ 280 | int CDECL lame_set_mode_automs(lame_global_flags *, int); 281 | int CDECL lame_get_mode_automs(const lame_global_flags *); 282 | #endif 283 | 284 | /* 285 | force_ms. Force M/S for all frames. For testing only. 286 | default = 0 (disabled) 287 | */ 288 | int CDECL lame_set_force_ms(lame_global_flags *, int); 289 | int CDECL lame_get_force_ms(const lame_global_flags *); 290 | 291 | /* use free_format? default = 0 (disabled) */ 292 | int CDECL lame_set_free_format(lame_global_flags *, int); 293 | int CDECL lame_get_free_format(const lame_global_flags *); 294 | 295 | /* perform ReplayGain analysis? default = 0 (disabled) */ 296 | int CDECL lame_set_findReplayGain(lame_global_flags *, int); 297 | int CDECL lame_get_findReplayGain(const lame_global_flags *); 298 | 299 | /* decode on the fly. Search for the peak sample. If the ReplayGain 300 | * analysis is enabled then perform the analysis on the decoded data 301 | * stream. default = 0 (disabled) 302 | * NOTE: if this option is set the build-in decoder should not be used */ 303 | int CDECL lame_set_decode_on_the_fly(lame_global_flags *, int); 304 | int CDECL lame_get_decode_on_the_fly(const lame_global_flags *); 305 | 306 | #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED 307 | #else 308 | /* DEPRECATED: now does the same as lame_set_findReplayGain() 309 | default = 0 (disabled) */ 310 | int CDECL lame_set_ReplayGain_input(lame_global_flags *, int); 311 | int CDECL lame_get_ReplayGain_input(const lame_global_flags *); 312 | 313 | /* DEPRECATED: now does the same as 314 | lame_set_decode_on_the_fly() && lame_set_findReplayGain() 315 | default = 0 (disabled) */ 316 | int CDECL lame_set_ReplayGain_decode(lame_global_flags *, int); 317 | int CDECL lame_get_ReplayGain_decode(const lame_global_flags *); 318 | 319 | /* DEPRECATED: now does the same as lame_set_decode_on_the_fly() 320 | default = 0 (disabled) */ 321 | int CDECL lame_set_findPeakSample(lame_global_flags *, int); 322 | int CDECL lame_get_findPeakSample(const lame_global_flags *); 323 | #endif 324 | 325 | /* counters for gapless encoding */ 326 | int CDECL lame_set_nogap_total(lame_global_flags*, int); 327 | int CDECL lame_get_nogap_total(const lame_global_flags*); 328 | 329 | int CDECL lame_set_nogap_currentindex(lame_global_flags* , int); 330 | int CDECL lame_get_nogap_currentindex(const lame_global_flags*); 331 | 332 | 333 | /* 334 | * OPTIONAL: 335 | * Set printf like error/debug/message reporting functions. 336 | * The second argument has to be a pointer to a function which looks like 337 | * void my_debugf(const char *format, va_list ap) 338 | * { 339 | * (void) vfprintf(stdout, format, ap); 340 | * } 341 | * If you use NULL as the value of the pointer in the set function, the 342 | * lame buildin function will be used (prints to stderr). 343 | * To quiet any output you have to replace the body of the example function 344 | * with just "return;" and use it in the set function. 345 | */ 346 | int CDECL lame_set_errorf(lame_global_flags *, lame_report_function); 347 | int CDECL lame_set_debugf(lame_global_flags *, lame_report_function); 348 | int CDECL lame_set_msgf (lame_global_flags *, lame_report_function); 349 | 350 | 351 | 352 | /* set one of brate compression ratio. default is compression ratio of 11. */ 353 | int CDECL lame_set_brate(lame_global_flags *, int); 354 | int CDECL lame_get_brate(const lame_global_flags *); 355 | int CDECL lame_set_compression_ratio(lame_global_flags *, float); 356 | float CDECL lame_get_compression_ratio(const lame_global_flags *); 357 | 358 | 359 | int CDECL lame_set_preset( lame_global_flags* gfp, int ); 360 | int CDECL lame_set_asm_optimizations( lame_global_flags* gfp, int, int ); 361 | 362 | 363 | 364 | /******************************************************************** 365 | * frame params 366 | ***********************************************************************/ 367 | /* mark as copyright. default=0 */ 368 | int CDECL lame_set_copyright(lame_global_flags *, int); 369 | int CDECL lame_get_copyright(const lame_global_flags *); 370 | 371 | /* mark as original. default=1 */ 372 | int CDECL lame_set_original(lame_global_flags *, int); 373 | int CDECL lame_get_original(const lame_global_flags *); 374 | 375 | /* error_protection. Use 2 bytes from each frame for CRC checksum. default=0 */ 376 | int CDECL lame_set_error_protection(lame_global_flags *, int); 377 | int CDECL lame_get_error_protection(const lame_global_flags *); 378 | 379 | #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED 380 | #else 381 | /* padding_type. 0=pad no frames 1=pad all frames 2=adjust padding(default) */ 382 | int CDECL lame_set_padding_type(lame_global_flags *, Padding_type); 383 | Padding_type CDECL lame_get_padding_type(const lame_global_flags *); 384 | #endif 385 | 386 | /* MP3 'private extension' bit Meaningless. default=0 */ 387 | int CDECL lame_set_extension(lame_global_flags *, int); 388 | int CDECL lame_get_extension(const lame_global_flags *); 389 | 390 | /* enforce strict ISO compliance. default=0 */ 391 | int CDECL lame_set_strict_ISO(lame_global_flags *, int); 392 | int CDECL lame_get_strict_ISO(const lame_global_flags *); 393 | 394 | 395 | /******************************************************************** 396 | * quantization/noise shaping 397 | ***********************************************************************/ 398 | 399 | /* disable the bit reservoir. For testing only. default=0 */ 400 | int CDECL lame_set_disable_reservoir(lame_global_flags *, int); 401 | int CDECL lame_get_disable_reservoir(const lame_global_flags *); 402 | 403 | /* select a different "best quantization" function. default=0 */ 404 | int CDECL lame_set_quant_comp(lame_global_flags *, int); 405 | int CDECL lame_get_quant_comp(const lame_global_flags *); 406 | int CDECL lame_set_quant_comp_short(lame_global_flags *, int); 407 | int CDECL lame_get_quant_comp_short(const lame_global_flags *); 408 | 409 | int CDECL lame_set_experimentalX(lame_global_flags *, int); /* compatibility*/ 410 | int CDECL lame_get_experimentalX(const lame_global_flags *); 411 | 412 | /* another experimental option. for testing only */ 413 | int CDECL lame_set_experimentalY(lame_global_flags *, int); 414 | int CDECL lame_get_experimentalY(const lame_global_flags *); 415 | 416 | /* another experimental option. for testing only */ 417 | int CDECL lame_set_experimentalZ(lame_global_flags *, int); 418 | int CDECL lame_get_experimentalZ(const lame_global_flags *); 419 | 420 | /* Naoki's psycho acoustic model. default=0 */ 421 | int CDECL lame_set_exp_nspsytune(lame_global_flags *, int); 422 | int CDECL lame_get_exp_nspsytune(const lame_global_flags *); 423 | 424 | void CDECL lame_set_msfix(lame_global_flags *, double); 425 | float CDECL lame_get_msfix(const lame_global_flags *); 426 | 427 | 428 | /******************************************************************** 429 | * VBR control 430 | ***********************************************************************/ 431 | /* Types of VBR. default = vbr_off = CBR */ 432 | int CDECL lame_set_VBR(lame_global_flags *, vbr_mode); 433 | vbr_mode CDECL lame_get_VBR(const lame_global_flags *); 434 | 435 | /* VBR quality level. 0=highest 9=lowest */ 436 | int CDECL lame_set_VBR_q(lame_global_flags *, int); 437 | int CDECL lame_get_VBR_q(const lame_global_flags *); 438 | 439 | /* VBR quality level. 0=highest 9=lowest, Range [0,...,10[ */ 440 | int CDECL lame_set_VBR_quality(lame_global_flags *, float); 441 | float CDECL lame_get_VBR_quality(const lame_global_flags *); 442 | 443 | /* Ignored except for VBR=vbr_abr (ABR mode) */ 444 | int CDECL lame_set_VBR_mean_bitrate_kbps(lame_global_flags *, int); 445 | int CDECL lame_get_VBR_mean_bitrate_kbps(const lame_global_flags *); 446 | 447 | int CDECL lame_set_VBR_min_bitrate_kbps(lame_global_flags *, int); 448 | int CDECL lame_get_VBR_min_bitrate_kbps(const lame_global_flags *); 449 | 450 | int CDECL lame_set_VBR_max_bitrate_kbps(lame_global_flags *, int); 451 | int CDECL lame_get_VBR_max_bitrate_kbps(const lame_global_flags *); 452 | 453 | /* 454 | 1=strictly enforce VBR_min_bitrate. Normally it will be violated for 455 | analog silence 456 | */ 457 | int CDECL lame_set_VBR_hard_min(lame_global_flags *, int); 458 | int CDECL lame_get_VBR_hard_min(const lame_global_flags *); 459 | 460 | /* for preset */ 461 | #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED 462 | #else 463 | int CDECL lame_set_preset_expopts(lame_global_flags *, int); 464 | #endif 465 | 466 | /******************************************************************** 467 | * Filtering control 468 | ***********************************************************************/ 469 | /* freq in Hz to apply lowpass. Default = 0 = lame chooses. -1 = disabled */ 470 | int CDECL lame_set_lowpassfreq(lame_global_flags *, int); 471 | int CDECL lame_get_lowpassfreq(const lame_global_flags *); 472 | /* width of transition band, in Hz. Default = one polyphase filter band */ 473 | int CDECL lame_set_lowpasswidth(lame_global_flags *, int); 474 | int CDECL lame_get_lowpasswidth(const lame_global_flags *); 475 | 476 | /* freq in Hz to apply highpass. Default = 0 = lame chooses. -1 = disabled */ 477 | int CDECL lame_set_highpassfreq(lame_global_flags *, int); 478 | int CDECL lame_get_highpassfreq(const lame_global_flags *); 479 | /* width of transition band, in Hz. Default = one polyphase filter band */ 480 | int CDECL lame_set_highpasswidth(lame_global_flags *, int); 481 | int CDECL lame_get_highpasswidth(const lame_global_flags *); 482 | 483 | 484 | /******************************************************************** 485 | * psycho acoustics and other arguments which you should not change 486 | * unless you know what you are doing 487 | ***********************************************************************/ 488 | 489 | /* only use ATH for masking */ 490 | int CDECL lame_set_ATHonly(lame_global_flags *, int); 491 | int CDECL lame_get_ATHonly(const lame_global_flags *); 492 | 493 | /* only use ATH for short blocks */ 494 | int CDECL lame_set_ATHshort(lame_global_flags *, int); 495 | int CDECL lame_get_ATHshort(const lame_global_flags *); 496 | 497 | /* disable ATH */ 498 | int CDECL lame_set_noATH(lame_global_flags *, int); 499 | int CDECL lame_get_noATH(const lame_global_flags *); 500 | 501 | /* select ATH formula */ 502 | int CDECL lame_set_ATHtype(lame_global_flags *, int); 503 | int CDECL lame_get_ATHtype(const lame_global_flags *); 504 | 505 | /* lower ATH by this many db */ 506 | int CDECL lame_set_ATHlower(lame_global_flags *, float); 507 | float CDECL lame_get_ATHlower(const lame_global_flags *); 508 | 509 | /* select ATH adaptive adjustment type */ 510 | int CDECL lame_set_athaa_type( lame_global_flags *, int); 511 | int CDECL lame_get_athaa_type( const lame_global_flags *); 512 | 513 | #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED 514 | #else 515 | /* select the loudness approximation used by the ATH adaptive auto-leveling */ 516 | int CDECL lame_set_athaa_loudapprox( lame_global_flags *, int); 517 | int CDECL lame_get_athaa_loudapprox( const lame_global_flags *); 518 | #endif 519 | 520 | /* adjust (in dB) the point below which adaptive ATH level adjustment occurs */ 521 | int CDECL lame_set_athaa_sensitivity( lame_global_flags *, float); 522 | float CDECL lame_get_athaa_sensitivity( const lame_global_flags* ); 523 | 524 | #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED 525 | #else 526 | /* OBSOLETE: predictability limit (ISO tonality formula) */ 527 | int CDECL lame_set_cwlimit(lame_global_flags *, int); 528 | int CDECL lame_get_cwlimit(const lame_global_flags *); 529 | #endif 530 | 531 | /* 532 | allow blocktypes to differ between channels? 533 | default: 0 for jstereo, 1 for stereo 534 | */ 535 | int CDECL lame_set_allow_diff_short(lame_global_flags *, int); 536 | int CDECL lame_get_allow_diff_short(const lame_global_flags *); 537 | 538 | /* use temporal masking effect (default = 1) */ 539 | int CDECL lame_set_useTemporal(lame_global_flags *, int); 540 | int CDECL lame_get_useTemporal(const lame_global_flags *); 541 | 542 | /* use temporal masking effect (default = 1) */ 543 | int CDECL lame_set_interChRatio(lame_global_flags *, float); 544 | float CDECL lame_get_interChRatio(const lame_global_flags *); 545 | 546 | /* disable short blocks */ 547 | int CDECL lame_set_no_short_blocks(lame_global_flags *, int); 548 | int CDECL lame_get_no_short_blocks(const lame_global_flags *); 549 | 550 | /* force short blocks */ 551 | int CDECL lame_set_force_short_blocks(lame_global_flags *, int); 552 | int CDECL lame_get_force_short_blocks(const lame_global_flags *); 553 | 554 | /* Input PCM is emphased PCM (for instance from one of the rarely 555 | emphased CDs), it is STRONGLY not recommended to use this, because 556 | psycho does not take it into account, and last but not least many decoders 557 | ignore these bits */ 558 | int CDECL lame_set_emphasis(lame_global_flags *, int); 559 | int CDECL lame_get_emphasis(const lame_global_flags *); 560 | 561 | 562 | 563 | /************************************************************************/ 564 | /* internal variables, cannot be set... */ 565 | /* provided because they may be of use to calling application */ 566 | /************************************************************************/ 567 | /* version 0=MPEG-2 1=MPEG-1 (2=MPEG-2.5) */ 568 | int CDECL lame_get_version(const lame_global_flags *); 569 | 570 | /* encoder delay */ 571 | int CDECL lame_get_encoder_delay(const lame_global_flags *); 572 | 573 | /* 574 | padding appended to the input to make sure decoder can fully decode 575 | all input. Note that this value can only be calculated during the 576 | call to lame_encoder_flush(). Before lame_encoder_flush() has 577 | been called, the value of encoder_padding = 0. 578 | */ 579 | int CDECL lame_get_encoder_padding(const lame_global_flags *); 580 | 581 | /* size of MPEG frame */ 582 | int CDECL lame_get_framesize(const lame_global_flags *); 583 | 584 | /* number of PCM samples buffered, but not yet encoded to mp3 data. */ 585 | int CDECL lame_get_mf_samples_to_encode( const lame_global_flags* gfp ); 586 | 587 | /* 588 | size (bytes) of mp3 data buffered, but not yet encoded. 589 | this is the number of bytes which would be output by a call to 590 | lame_encode_flush_nogap. NOTE: lame_encode_flush() will return 591 | more bytes than this because it will encode the reamining buffered 592 | PCM samples before flushing the mp3 buffers. 593 | */ 594 | int CDECL lame_get_size_mp3buffer( const lame_global_flags* gfp ); 595 | 596 | /* number of frames encoded so far */ 597 | int CDECL lame_get_frameNum(const lame_global_flags *); 598 | 599 | /* 600 | lame's estimate of the total number of frames to be encoded 601 | only valid if calling program set num_samples 602 | */ 603 | int CDECL lame_get_totalframes(const lame_global_flags *); 604 | 605 | /* RadioGain value. Multiplied by 10 and rounded to the nearest. */ 606 | int CDECL lame_get_RadioGain(const lame_global_flags *); 607 | 608 | /* AudiophileGain value. Multipled by 10 and rounded to the nearest. */ 609 | int CDECL lame_get_AudiophileGain(const lame_global_flags *); 610 | 611 | /* the peak sample */ 612 | float CDECL lame_get_PeakSample(const lame_global_flags *); 613 | 614 | /* Gain change required for preventing clipping. The value is correct only if 615 | peak sample searching was enabled. If negative then the waveform 616 | already does not clip. The value is multiplied by 10 and rounded up. */ 617 | int CDECL lame_get_noclipGainChange(const lame_global_flags *); 618 | 619 | /* user-specified scale factor required for preventing clipping. Value is 620 | correct only if peak sample searching was enabled and no user-specified 621 | scaling was performed. If negative then either the waveform already does 622 | not clip or the value cannot be determined */ 623 | float CDECL lame_get_noclipScale(const lame_global_flags *); 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | /* 632 | * REQUIRED: 633 | * sets more internal configuration based on data provided above. 634 | * returns -1 if something failed. 635 | */ 636 | int CDECL lame_init_params(lame_global_flags *); 637 | 638 | 639 | /* 640 | * OPTIONAL: 641 | * get the version number, in a string. of the form: 642 | * "3.63 (beta)" or just "3.63". 643 | */ 644 | const char* CDECL get_lame_version ( void ); 645 | const char* CDECL get_lame_short_version ( void ); 646 | const char* CDECL get_lame_very_short_version ( void ); 647 | const char* CDECL get_psy_version ( void ); 648 | const char* CDECL get_lame_url ( void ); 649 | const char* CDECL get_lame_os_bitness ( void ); 650 | 651 | /* 652 | * OPTIONAL: 653 | * get the version numbers in numerical form. 654 | */ 655 | typedef struct { 656 | /* generic LAME version */ 657 | int major; 658 | int minor; 659 | int alpha; /* 0 if not an alpha version */ 660 | int beta; /* 0 if not a beta version */ 661 | 662 | /* version of the psy model */ 663 | int psy_major; 664 | int psy_minor; 665 | int psy_alpha; /* 0 if not an alpha version */ 666 | int psy_beta; /* 0 if not a beta version */ 667 | 668 | /* compile time features */ 669 | const char *features; /* Don't make assumptions about the contents! */ 670 | } lame_version_t; 671 | void CDECL get_lame_version_numerical(lame_version_t *); 672 | 673 | 674 | /* 675 | * OPTIONAL: 676 | * print internal lame configuration to message handler 677 | */ 678 | void CDECL lame_print_config(const lame_global_flags* gfp); 679 | 680 | void CDECL lame_print_internals( const lame_global_flags *gfp); 681 | 682 | 683 | /* 684 | * input pcm data, output (maybe) mp3 frames. 685 | * This routine handles all buffering, resampling and filtering for you. 686 | * 687 | * return code number of bytes output in mp3buf. Can be 0 688 | * -1: mp3buf was too small 689 | * -2: malloc() problem 690 | * -3: lame_init_params() not called 691 | * -4: psycho acoustic problems 692 | * 693 | * The required mp3buf_size can be computed from num_samples, 694 | * samplerate and encoding rate, but here is a worst case estimate: 695 | * 696 | * mp3buf_size in bytes = 1.25*num_samples + 7200 697 | * 698 | * I think a tighter bound could be: (mt, March 2000) 699 | * MPEG1: 700 | * num_samples*(bitrate/8)/samplerate + 4*1152*(bitrate/8)/samplerate + 512 701 | * MPEG2: 702 | * num_samples*(bitrate/8)/samplerate + 4*576*(bitrate/8)/samplerate + 256 703 | * 704 | * but test first if you use that! 705 | * 706 | * set mp3buf_size = 0 and LAME will not check if mp3buf_size is 707 | * large enough. 708 | * 709 | * NOTE: 710 | * if gfp->num_channels=2, but gfp->mode = 3 (mono), the L & R channels 711 | * will be averaged into the L channel before encoding only the L channel 712 | * This will overwrite the data in buffer_l[] and buffer_r[]. 713 | * 714 | */ 715 | int CDECL lame_encode_buffer ( 716 | lame_global_flags* gfp, /* global context handle */ 717 | const short int buffer_l [], /* PCM data for left channel */ 718 | const short int buffer_r [], /* PCM data for right channel */ 719 | const int nsamples, /* number of samples per channel */ 720 | unsigned char* mp3buf, /* pointer to encoded MP3 stream */ 721 | const int mp3buf_size ); /* number of valid octets in this 722 | stream */ 723 | 724 | /* 725 | * as above, but input has L & R channel data interleaved. 726 | * NOTE: 727 | * num_samples = number of samples in the L (or R) 728 | * channel, not the total number of samples in pcm[] 729 | */ 730 | int CDECL lame_encode_buffer_interleaved( 731 | lame_global_flags* gfp, /* global context handlei */ 732 | short int pcm[], /* PCM data for left and right 733 | channel, interleaved */ 734 | int num_samples, /* number of samples per channel, 735 | _not_ number of samples in 736 | pcm[] */ 737 | unsigned char* mp3buf, /* pointer to encoded MP3 stream */ 738 | int mp3buf_size ); /* number of valid octets in this 739 | stream */ 740 | 741 | 742 | /* as lame_encode_buffer, but for 'float's. 743 | * !! NOTE: !! data must still be scaled to be in the same range as 744 | * short int, +/- 32768 745 | */ 746 | int CDECL lame_encode_buffer_float( 747 | lame_global_flags* gfp, /* global context handle */ 748 | const float pcm_l [], /* PCM data for left channel */ 749 | const float pcm_r [], /* PCM data for right channel */ 750 | const int nsamples, /* number of samples per channel */ 751 | unsigned char* mp3buf, /* pointer to encoded MP3 stream */ 752 | const int mp3buf_size ); /* number of valid octets in this 753 | stream */ 754 | 755 | /* as lame_encode_buffer, but for 'float's. 756 | * !! NOTE: !! data must be scaled to +/- 1 full scale 757 | */ 758 | int CDECL lame_encode_buffer_ieee_float( 759 | lame_t gfp, 760 | const float pcm_l [], /* PCM data for left channel */ 761 | const float pcm_r [], /* PCM data for right channel */ 762 | const int nsamples, 763 | unsigned char * mp3buf, 764 | const int mp3buf_size); 765 | int CDECL lame_encode_buffer_interleaved_ieee_float( 766 | lame_t gfp, 767 | const float pcm[], /* PCM data for left and right 768 | channel, interleaved */ 769 | const int nsamples, 770 | unsigned char * mp3buf, 771 | const int mp3buf_size); 772 | 773 | /* as lame_encode_buffer, but for 'double's. 774 | * !! NOTE: !! data must be scaled to +/- 1 full scale 775 | */ 776 | int CDECL lame_encode_buffer_ieee_double( 777 | lame_t gfp, 778 | const double pcm_l [], /* PCM data for left channel */ 779 | const double pcm_r [], /* PCM data for right channel */ 780 | const int nsamples, 781 | unsigned char * mp3buf, 782 | const int mp3buf_size); 783 | int CDECL lame_encode_buffer_interleaved_ieee_double( 784 | lame_t gfp, 785 | const double pcm[], /* PCM data for left and right 786 | channel, interleaved */ 787 | const int nsamples, 788 | unsigned char * mp3buf, 789 | const int mp3buf_size); 790 | 791 | /* as lame_encode_buffer, but for long's 792 | * !! NOTE: !! data must still be scaled to be in the same range as 793 | * short int, +/- 32768 794 | * 795 | * This scaling was a mistake (doesn't allow one to exploit full 796 | * precision of type 'long'. Use lame_encode_buffer_long2() instead. 797 | * 798 | */ 799 | int CDECL lame_encode_buffer_long( 800 | lame_global_flags* gfp, /* global context handle */ 801 | const long buffer_l [], /* PCM data for left channel */ 802 | const long buffer_r [], /* PCM data for right channel */ 803 | const int nsamples, /* number of samples per channel */ 804 | unsigned char* mp3buf, /* pointer to encoded MP3 stream */ 805 | const int mp3buf_size ); /* number of valid octets in this 806 | stream */ 807 | 808 | /* Same as lame_encode_buffer_long(), but with correct scaling. 809 | * !! NOTE: !! data must still be scaled to be in the same range as 810 | * type 'long'. Data should be in the range: +/- 2^(8*size(long)-1) 811 | * 812 | */ 813 | int CDECL lame_encode_buffer_long2( 814 | lame_global_flags* gfp, /* global context handle */ 815 | const long buffer_l [], /* PCM data for left channel */ 816 | const long buffer_r [], /* PCM data for right channel */ 817 | const int nsamples, /* number of samples per channel */ 818 | unsigned char* mp3buf, /* pointer to encoded MP3 stream */ 819 | const int mp3buf_size ); /* number of valid octets in this 820 | stream */ 821 | 822 | /* as lame_encode_buffer, but for int's 823 | * !! NOTE: !! input should be scaled to the maximum range of 'int' 824 | * If int is 4 bytes, then the values should range from 825 | * +/- 2147483648. 826 | * 827 | * This routine does not (and cannot, without loosing precision) use 828 | * the same scaling as the rest of the lame_encode_buffer() routines. 829 | * 830 | */ 831 | int CDECL lame_encode_buffer_int( 832 | lame_global_flags* gfp, /* global context handle */ 833 | const int buffer_l [], /* PCM data for left channel */ 834 | const int buffer_r [], /* PCM data for right channel */ 835 | const int nsamples, /* number of samples per channel */ 836 | unsigned char* mp3buf, /* pointer to encoded MP3 stream */ 837 | const int mp3buf_size ); /* number of valid octets in this 838 | stream */ 839 | 840 | 841 | 842 | 843 | 844 | /* 845 | * REQUIRED: 846 | * lame_encode_flush will flush the intenal PCM buffers, padding with 847 | * 0's to make sure the final frame is complete, and then flush 848 | * the internal MP3 buffers, and thus may return a 849 | * final few mp3 frames. 'mp3buf' should be at least 7200 bytes long 850 | * to hold all possible emitted data. 851 | * 852 | * will also write id3v1 tags (if any) into the bitstream 853 | * 854 | * return code = number of bytes output to mp3buf. Can be 0 855 | */ 856 | int CDECL lame_encode_flush( 857 | lame_global_flags * gfp, /* global context handle */ 858 | unsigned char* mp3buf, /* pointer to encoded MP3 stream */ 859 | int size); /* number of valid octets in this stream */ 860 | 861 | /* 862 | * OPTIONAL: 863 | * lame_encode_flush_nogap will flush the internal mp3 buffers and pad 864 | * the last frame with ancillary data so it is a complete mp3 frame. 865 | * 866 | * 'mp3buf' should be at least 7200 bytes long 867 | * to hold all possible emitted data. 868 | * 869 | * After a call to this routine, the outputed mp3 data is complete, but 870 | * you may continue to encode new PCM samples and write future mp3 data 871 | * to a different file. The two mp3 files will play back with no gaps 872 | * if they are concatenated together. 873 | * 874 | * This routine will NOT write id3v1 tags into the bitstream. 875 | * 876 | * return code = number of bytes output to mp3buf. Can be 0 877 | */ 878 | int CDECL lame_encode_flush_nogap( 879 | lame_global_flags * gfp, /* global context handle */ 880 | unsigned char* mp3buf, /* pointer to encoded MP3 stream */ 881 | int size); /* number of valid octets in this stream */ 882 | 883 | /* 884 | * OPTIONAL: 885 | * Normally, this is called by lame_init_params(). It writes id3v2 and 886 | * Xing headers into the front of the bitstream, and sets frame counters 887 | * and bitrate histogram data to 0. You can also call this after 888 | * lame_encode_flush_nogap(). 889 | */ 890 | int CDECL lame_init_bitstream( 891 | lame_global_flags * gfp); /* global context handle */ 892 | 893 | 894 | 895 | /* 896 | * OPTIONAL: some simple statistics 897 | * a bitrate histogram to visualize the distribution of used frame sizes 898 | * a stereo mode histogram to visualize the distribution of used stereo 899 | * modes, useful in joint-stereo mode only 900 | * 0: LR left-right encoded 901 | * 1: LR-I left-right and intensity encoded (currently not supported) 902 | * 2: MS mid-side encoded 903 | * 3: MS-I mid-side and intensity encoded (currently not supported) 904 | * 905 | * attention: don't call them after lame_encode_finish 906 | * suggested: lame_encode_flush -> lame_*_hist -> lame_close 907 | */ 908 | 909 | void CDECL lame_bitrate_hist( 910 | const lame_global_flags * gfp, 911 | int bitrate_count[14] ); 912 | void CDECL lame_bitrate_kbps( 913 | const lame_global_flags * gfp, 914 | int bitrate_kbps [14] ); 915 | void CDECL lame_stereo_mode_hist( 916 | const lame_global_flags * gfp, 917 | int stereo_mode_count[4] ); 918 | 919 | void CDECL lame_bitrate_stereo_mode_hist ( 920 | const lame_global_flags * gfp, 921 | int bitrate_stmode_count[14][4] ); 922 | 923 | void CDECL lame_block_type_hist ( 924 | const lame_global_flags * gfp, 925 | int btype_count[6] ); 926 | 927 | void CDECL lame_bitrate_block_type_hist ( 928 | const lame_global_flags * gfp, 929 | int bitrate_btype_count[14][6] ); 930 | 931 | #if (DEPRECATED_OR_OBSOLETE_CODE_REMOVED && 0) 932 | #else 933 | /* 934 | * OPTIONAL: 935 | * lame_mp3_tags_fid will rewrite a Xing VBR tag to the mp3 file with file 936 | * pointer fid. These calls perform forward and backwards seeks, so make 937 | * sure fid is a real file. Make sure lame_encode_flush has been called, 938 | * and all mp3 data has been written to the file before calling this 939 | * function. 940 | * NOTE: 941 | * if VBR tags are turned off by the user, or turned off by LAME because 942 | * the output is not a regular file, this call does nothing 943 | * NOTE: 944 | * LAME wants to read from the file to skip an optional ID3v2 tag, so 945 | * make sure you opened the file for writing and reading. 946 | * NOTE: 947 | * You can call lame_get_lametag_frame instead, if you want to insert 948 | * the lametag yourself. 949 | */ 950 | void CDECL lame_mp3_tags_fid(lame_global_flags *, FILE* fid); 951 | #endif 952 | 953 | /* 954 | * OPTIONAL: 955 | * lame_get_lametag_frame copies the final LAME-tag into 'buffer'. 956 | * The function returns the number of bytes copied into buffer, or 957 | * the required buffer size, if the provided buffer is too small. 958 | * Function failed, if the return value is larger than 'size'! 959 | * Make sure lame_encode flush has been called before calling this function. 960 | * NOTE: 961 | * if VBR tags are turned off by the user, or turned off by LAME, 962 | * this call does nothing and returns 0. 963 | * NOTE: 964 | * LAME inserted an empty frame in the beginning of mp3 audio data, 965 | * which you have to replace by the final LAME-tag frame after encoding. 966 | * In case there is no ID3v2 tag, usually this frame will be the very first 967 | * data in your mp3 file. If you put some other leading data into your 968 | * file, you'll have to do some bookkeeping about where to write this buffer. 969 | */ 970 | size_t CDECL lame_get_lametag_frame( 971 | const lame_global_flags *, unsigned char* buffer, size_t size); 972 | 973 | /* 974 | * REQUIRED: 975 | * final call to free all remaining buffers 976 | */ 977 | int CDECL lame_close (lame_global_flags *); 978 | 979 | #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED 980 | #else 981 | /* 982 | * OBSOLETE: 983 | * lame_encode_finish combines lame_encode_flush() and lame_close() in 984 | * one call. However, once this call is made, the statistics routines 985 | * will no longer work because the data will have been cleared, and 986 | * lame_mp3_tags_fid() cannot be called to add data to the VBR header 987 | */ 988 | int CDECL lame_encode_finish( 989 | lame_global_flags* gfp, 990 | unsigned char* mp3buf, 991 | int size ); 992 | #endif 993 | 994 | 995 | 996 | 997 | 998 | 999 | /********************************************************************* 1000 | * 1001 | * decoding 1002 | * 1003 | * a simple interface to mpglib, part of mpg123, is also included if 1004 | * libmp3lame is compiled with HAVE_MPGLIB 1005 | * 1006 | *********************************************************************/ 1007 | 1008 | struct hip_global_struct; 1009 | typedef struct hip_global_struct hip_global_flags; 1010 | typedef hip_global_flags *hip_t; 1011 | 1012 | 1013 | typedef struct { 1014 | int header_parsed; /* 1 if header was parsed and following data was 1015 | computed */ 1016 | int stereo; /* number of channels */ 1017 | int samplerate; /* sample rate */ 1018 | int bitrate; /* bitrate */ 1019 | int mode; /* mp3 frame type */ 1020 | int mode_ext; /* mp3 frame type */ 1021 | int framesize; /* number of samples per mp3 frame */ 1022 | 1023 | /* this data is only computed if mpglib detects a Xing VBR header */ 1024 | unsigned long nsamp; /* number of samples in mp3 file. */ 1025 | int totalframes; /* total number of frames in mp3 file */ 1026 | 1027 | /* this data is not currently computed by the mpglib routines */ 1028 | int framenum; /* frames decoded counter */ 1029 | } mp3data_struct; 1030 | 1031 | /* required call to initialize decoder */ 1032 | hip_t CDECL hip_decode_init(void); 1033 | 1034 | /* cleanup call to exit decoder */ 1035 | int CDECL hip_decode_exit(hip_t gfp); 1036 | 1037 | /* HIP reporting functions */ 1038 | void CDECL hip_set_errorf(hip_t gfp, lame_report_function f); 1039 | void CDECL hip_set_debugf(hip_t gfp, lame_report_function f); 1040 | void CDECL hip_set_msgf (hip_t gfp, lame_report_function f); 1041 | 1042 | /********************************************************************* 1043 | * input 1 mp3 frame, output (maybe) pcm data. 1044 | * 1045 | * nout = hip_decode(hip, mp3buf,len,pcm_l,pcm_r); 1046 | * 1047 | * input: 1048 | * len : number of bytes of mp3 data in mp3buf 1049 | * mp3buf[len] : mp3 data to be decoded 1050 | * 1051 | * output: 1052 | * nout: -1 : decoding error 1053 | * 0 : need more data before we can complete the decode 1054 | * >0 : returned 'nout' samples worth of data in pcm_l,pcm_r 1055 | * pcm_l[nout] : left channel data 1056 | * pcm_r[nout] : right channel data 1057 | * 1058 | *********************************************************************/ 1059 | int CDECL hip_decode( hip_t gfp 1060 | , unsigned char * mp3buf 1061 | , size_t len 1062 | , short pcm_l[] 1063 | , short pcm_r[] 1064 | ); 1065 | 1066 | /* same as hip_decode, and also returns mp3 header data */ 1067 | int CDECL hip_decode_headers( hip_t gfp 1068 | , unsigned char* mp3buf 1069 | , size_t len 1070 | , short pcm_l[] 1071 | , short pcm_r[] 1072 | , mp3data_struct* mp3data 1073 | ); 1074 | 1075 | /* same as hip_decode, but returns at most one frame */ 1076 | int CDECL hip_decode1( hip_t gfp 1077 | , unsigned char* mp3buf 1078 | , size_t len 1079 | , short pcm_l[] 1080 | , short pcm_r[] 1081 | ); 1082 | 1083 | /* same as hip_decode1, but returns at most one frame and mp3 header data */ 1084 | int CDECL hip_decode1_headers( hip_t gfp 1085 | , unsigned char* mp3buf 1086 | , size_t len 1087 | , short pcm_l[] 1088 | , short pcm_r[] 1089 | , mp3data_struct* mp3data 1090 | ); 1091 | 1092 | /* same as hip_decode1_headers, but also returns enc_delay and enc_padding 1093 | from VBR Info tag, (-1 if no info tag was found) */ 1094 | int CDECL hip_decode1_headersB( hip_t gfp 1095 | , unsigned char* mp3buf 1096 | , size_t len 1097 | , short pcm_l[] 1098 | , short pcm_r[] 1099 | , mp3data_struct* mp3data 1100 | , int *enc_delay 1101 | , int *enc_padding 1102 | ); 1103 | 1104 | 1105 | 1106 | /* OBSOLETE: 1107 | * lame_decode... functions are there to keep old code working 1108 | * but it is strongly recommended to replace calls by hip_decode... 1109 | * function calls, see above. 1110 | */ 1111 | #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED 1112 | #else 1113 | int CDECL lame_decode_init(void); 1114 | int CDECL lame_decode( 1115 | unsigned char * mp3buf, 1116 | int len, 1117 | short pcm_l[], 1118 | short pcm_r[] ); 1119 | int CDECL lame_decode_headers( 1120 | unsigned char* mp3buf, 1121 | int len, 1122 | short pcm_l[], 1123 | short pcm_r[], 1124 | mp3data_struct* mp3data ); 1125 | int CDECL lame_decode1( 1126 | unsigned char* mp3buf, 1127 | int len, 1128 | short pcm_l[], 1129 | short pcm_r[] ); 1130 | int CDECL lame_decode1_headers( 1131 | unsigned char* mp3buf, 1132 | int len, 1133 | short pcm_l[], 1134 | short pcm_r[], 1135 | mp3data_struct* mp3data ); 1136 | int CDECL lame_decode1_headersB( 1137 | unsigned char* mp3buf, 1138 | int len, 1139 | short pcm_l[], 1140 | short pcm_r[], 1141 | mp3data_struct* mp3data, 1142 | int *enc_delay, 1143 | int *enc_padding ); 1144 | int CDECL lame_decode_exit(void); 1145 | 1146 | #endif /* obsolete lame_decode API calls */ 1147 | 1148 | 1149 | /********************************************************************* 1150 | * 1151 | * id3tag stuff 1152 | * 1153 | *********************************************************************/ 1154 | 1155 | /* 1156 | * id3tag.h -- Interface to write ID3 version 1 and 2 tags. 1157 | * 1158 | * Copyright (C) 2000 Don Melton. 1159 | * 1160 | * This library is free software; you can redistribute it and/or 1161 | * modify it under the terms of the GNU Library General Public 1162 | * License as published by the Free Software Foundation; either 1163 | * version 2 of the License, or (at your option) any later version. 1164 | * 1165 | * This library is distributed in the hope that it will be useful, 1166 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 1167 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1168 | * Library General Public License for more details. 1169 | * 1170 | * You should have received a copy of the GNU Library General Public 1171 | * License along with this library; if not, write to the Free Software 1172 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 1173 | */ 1174 | 1175 | /* utility to obtain alphabetically sorted list of genre names with numbers */ 1176 | void CDECL id3tag_genre_list( 1177 | void (*handler)(int, const char *, void *), 1178 | void* cookie); 1179 | 1180 | void CDECL id3tag_init (lame_t gfp); 1181 | 1182 | /* force addition of version 2 tag */ 1183 | void CDECL id3tag_add_v2 (lame_t gfp); 1184 | 1185 | /* add only a version 1 tag */ 1186 | void CDECL id3tag_v1_only (lame_t gfp); 1187 | 1188 | /* add only a version 2 tag */ 1189 | void CDECL id3tag_v2_only (lame_t gfp); 1190 | 1191 | /* pad version 1 tag with spaces instead of nulls */ 1192 | void CDECL id3tag_space_v1 (lame_t gfp); 1193 | 1194 | /* pad version 2 tag with extra 128 bytes */ 1195 | void CDECL id3tag_pad_v2 (lame_t gfp); 1196 | 1197 | /* pad version 2 tag with extra n bytes */ 1198 | void CDECL id3tag_set_pad (lame_t gfp, size_t n); 1199 | 1200 | void CDECL id3tag_set_title(lame_t gfp, const char* title); 1201 | void CDECL id3tag_set_artist(lame_t gfp, const char* artist); 1202 | void CDECL id3tag_set_album(lame_t gfp, const char* album); 1203 | void CDECL id3tag_set_year(lame_t gfp, const char* year); 1204 | void CDECL id3tag_set_comment(lame_t gfp, const char* comment); 1205 | 1206 | /* return -1 result if track number is out of ID3v1 range 1207 | and ignored for ID3v1 */ 1208 | int CDECL id3tag_set_track(lame_t gfp, const char* track); 1209 | 1210 | /* return non-zero result if genre name or number is invalid 1211 | result 0: OK 1212 | result -1: genre number out of range 1213 | result -2: no valid ID3v1 genre name, mapped to ID3v1 'Other' 1214 | but taken as-is for ID3v2 genre tag */ 1215 | int CDECL id3tag_set_genre(lame_t gfp, const char* genre); 1216 | 1217 | /* return non-zero result if field name is invalid */ 1218 | int CDECL id3tag_set_fieldvalue(lame_t gfp, const char* fieldvalue); 1219 | 1220 | /* return non-zero result if image type is invalid */ 1221 | int CDECL id3tag_set_albumart(lame_t gfp, const char* image, size_t size); 1222 | 1223 | /* lame_get_id3v1_tag copies ID3v1 tag into buffer. 1224 | * Function returns number of bytes copied into buffer, or number 1225 | * of bytes rquired if buffer 'size' is too small. 1226 | * Function fails, if returned value is larger than 'size'. 1227 | * NOTE: 1228 | * This functions does nothing, if user/LAME disabled ID3v1 tag. 1229 | */ 1230 | size_t CDECL lame_get_id3v1_tag(lame_t gfp, unsigned char* buffer, size_t size); 1231 | 1232 | /* lame_get_id3v2_tag copies ID3v2 tag into buffer. 1233 | * Function returns number of bytes copied into buffer, or number 1234 | * of bytes rquired if buffer 'size' is too small. 1235 | * Function fails, if returned value is larger than 'size'. 1236 | * NOTE: 1237 | * This functions does nothing, if user/LAME disabled ID3v2 tag. 1238 | */ 1239 | size_t CDECL lame_get_id3v2_tag(lame_t gfp, unsigned char* buffer, size_t size); 1240 | 1241 | /* normaly lame_init_param writes ID3v2 tags into the audio stream 1242 | * Call lame_set_write_id3tag_automatic(gfp, 0) before lame_init_param 1243 | * to turn off this behaviour and get ID3v2 tag with above function 1244 | * write it yourself into your file. 1245 | */ 1246 | void CDECL lame_set_write_id3tag_automatic(lame_global_flags * gfp, int); 1247 | int CDECL lame_get_write_id3tag_automatic(lame_global_flags const* gfp); 1248 | 1249 | /* experimental */ 1250 | int CDECL id3tag_set_textinfo_latin1(lame_t gfp, char const *id, char const *text); 1251 | 1252 | /* experimental */ 1253 | int CDECL id3tag_set_comment_latin1(lame_t gfp, char const *lang, char const *desc, char const *text); 1254 | 1255 | #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED 1256 | #else 1257 | /* experimental */ 1258 | int CDECL id3tag_set_textinfo_ucs2(lame_t gfp, char const *id, unsigned short const *text); 1259 | 1260 | /* experimental */ 1261 | int CDECL id3tag_set_comment_ucs2(lame_t gfp, char const *lang, 1262 | unsigned short const *desc, unsigned short const *text); 1263 | 1264 | /* experimental */ 1265 | int CDECL id3tag_set_fieldvalue_ucs2(lame_t gfp, const unsigned short *fieldvalue); 1266 | #endif 1267 | 1268 | /* experimental */ 1269 | int CDECL id3tag_set_fieldvalue_utf16(lame_t gfp, const unsigned short *fieldvalue); 1270 | 1271 | /* experimental */ 1272 | int CDECL id3tag_set_textinfo_utf16(lame_t gfp, char const *id, unsigned short const *text); 1273 | 1274 | /* experimental */ 1275 | int CDECL id3tag_set_comment_utf16(lame_t gfp, char const *lang, unsigned short const *desc, unsigned short const *text); 1276 | 1277 | 1278 | /*********************************************************************** 1279 | * 1280 | * list of valid bitrates [kbps] & sample frequencies [Hz]. 1281 | * first index: 0: MPEG-2 values (sample frequencies 16...24 kHz) 1282 | * 1: MPEG-1 values (sample frequencies 32...48 kHz) 1283 | * 2: MPEG-2.5 values (sample frequencies 8...12 kHz) 1284 | ***********************************************************************/ 1285 | 1286 | extern const int bitrate_table [3][16]; 1287 | extern const int samplerate_table [3][ 4]; 1288 | 1289 | /* access functions for use in DLL, global vars are not exported */ 1290 | int CDECL lame_get_bitrate(int mpeg_version, int table_index); 1291 | int CDECL lame_get_samplerate(int mpeg_version, int table_index); 1292 | 1293 | 1294 | /* maximum size of albumart image (128KB), which affects LAME_MAXMP3BUFFER 1295 | as well since lame_encode_buffer() also returns ID3v2 tag data */ 1296 | #define LAME_MAXALBUMART (128 * 1024) 1297 | 1298 | /* maximum size of mp3buffer needed if you encode at most 1152 samples for 1299 | each call to lame_encode_buffer. see lame_encode_buffer() below 1300 | (LAME_MAXMP3BUFFER is now obsolete) */ 1301 | #define LAME_MAXMP3BUFFER (16384 + LAME_MAXALBUMART) 1302 | 1303 | 1304 | typedef enum { 1305 | LAME_OKAY = 0, 1306 | LAME_NOERROR = 0, 1307 | LAME_GENERICERROR = -1, 1308 | LAME_NOMEM = -10, 1309 | LAME_BADBITRATE = -11, 1310 | LAME_BADSAMPFREQ = -12, 1311 | LAME_INTERNALERROR = -13, 1312 | 1313 | FRONTEND_READERROR = -80, 1314 | FRONTEND_WRITEERROR = -81, 1315 | FRONTEND_FILETOOLARGE = -82 1316 | 1317 | } lame_errorcodes_t; 1318 | 1319 | #if defined(__cplusplus) 1320 | } 1321 | #endif 1322 | #endif /* LAME_LAME_H */ 1323 | 1324 | -------------------------------------------------------------------------------- /ExtAudioConverter/libmp3lame.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lixing123/ExtAudioFileConverter/1f8f5ad927937d62b97e2a00b7687cde74ce5ec3/ExtAudioConverter/libmp3lame.a -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## An iOS project to convert audio from any format to any format.
2 | ExtAudioConverter is an implementation of the afconvert command on OS X,
3 | so this readme file uses some hints of afconvert help documentation. For example, LEI16 means little-endian signed int with 16 bit depth. 4 | 5 | ### How to use: 6 | 7 | 1. Link Binary with Library "AudioToolbox.framework"; 8 | 9 | 2. Add "ExtAudioConverter.h" and "ExtAudioConverter.m" to your project; 10 | 11 | 3. Test: 12 | ```objective-c 13 | ExtAudioConverter* converter = [[ExtAudioConverter alloc] init]; 14 | converter.inputFile = @"/Users/lixing/Desktop/input.caf"; 15 | converter.outputFile = @"/Users/lixing/Desktop/output.wav"; 16 | [converter convert]; 17 | ``` 18 | The following parameters are optional: 19 | 20 | Set the sample rate:
21 | ```objective-c 22 | converter.outputSampleRate = 44100; 23 | ``` 24 | Set channel count:
25 | ```objective-c 26 | converter.outputNumberChannels = 2; 27 | ``` 28 | 29 | Set bit depth:
30 | ```objective-c 31 | converter.outputBitDepth = BitDepth_16; 32 | ``` 33 | Set data format:
34 | ```objective-c 35 | converter.outputFormatID = kAudioFormatLinearPCM; 36 | ``` 37 | Set file format:
38 | ```objective-c 39 | converter.outputFileType = kAudioFileWAVEType; 40 | ``` 41 | 42 | Some parameter combinations is impossible, like mp3 file format together with wav data format.
43 | The valid file type/data format pair is described on the Apple documentation
https://developer.apple.com/library/ios/documentation/MusicAudio/Conceptual/CoreAudioOverview/SupportedAudioFormatsMacOSX/SupportedAudioFormatsMacOSX.html 44 | 45 | 46 | 47 | ### For mp3 format conversion 48 | Apple doesn't include the MP3 encode algorithm in its APIs, but include the decode algorithm.
49 | ~~So we can now convert from mp3 file to other formats, but can't convert to mp3 format.~~
50 | ~~We will use other open source mp3 codec, like lame, to convert to mp3 format.~~
51 | We have now supported conversion to mp3 format, using the famous lame mp3 codec. 52 | 53 | If you have any questions, please commit an issue, or mail me:shangwangwanwan@gmail.com. 54 | --------------------------------------------------------------------------------