audio 0 → 0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e3138318ed37af8b4a5921015231c48d82a86fc6
4
- data.tar.gz: 02d940091ca420f1f33d9e0bd308b438187e1575
3
+ metadata.gz: 3f7750670a7a9f4d0554765012808dbe2f6477c9
4
+ data.tar.gz: a9e49107f1c2d316f416ecacc9a0f4ede1df1e66
5
5
  SHA512:
6
- metadata.gz: 5caac54e7891da34d0641eb8fa953cc3b151a7fab0fd044e0f4b82abbc55c2edd21a066829f86384899cc6570a73ce4925585fb15b1f7b823deb253218aa5936
7
- data.tar.gz: 4a3356fa7fdf3b7633d990b54274a43010078c6bed9aaed84d2e799ab4d45e7b2dbd5b402a34fdd8c1d45297e7154bacebc70572a06abd072b893f33b6303cc6
6
+ metadata.gz: 8a813230ad12d52963266b54ab57dfef88728af3fc6b6883bc19a1c71b783e9fcae205b2f06dfcecb2f06869e91185dfb2c47c2defbdec07d286b61c2a8ab414
7
+ data.tar.gz: a6dbf92c29fbce40913e41e099f549b9f314e1c7bed5f50eeaf73f2d79a73a41cf847b94e870c609cc0bc71bb2029d7cddbf21d081d43e9e100a7e148902c6bb
data/README.md CHANGED
@@ -1,6 +1,62 @@
1
1
  # Audio
2
2
 
3
- TODO: Write a gem description
3
+ 'Audio' is a cross-platform audio device interface that allows you to read and
4
+ write audio streams from the comfort and safety of Ruby.
5
+
6
+ ## Cross-Platform Status
7
+
8
+ Currently, only support for OS X has been implemented. Support for Windows and
9
+ Linux will be added in the future. If you feel like working on either of those,
10
+ I'm more than happy to take Pull Requests!
11
+
12
+ ## Usage
13
+
14
+ ### Listing Available Audio Devices
15
+
16
+ The Audio module provides a method that retrieves a list of all of the audio
17
+ devices available on your system.
18
+
19
+ ```ruby
20
+ require 'audio'
21
+
22
+ devices = Audio.devices # => An Array of Device objects
23
+ ```
24
+
25
+ Each Device object has attributes that wrap the various properties provided by
26
+ the host operating system. For example, to get a list of device names...
27
+
28
+ ```ruby
29
+ Audio.devices.each do |device|
30
+ puts "Device Name: #{device.device_name}"
31
+ end
32
+ ```
33
+
34
+ Running that on a MacBook Pro (late 2013), with a single external microphone
35
+ connected, produces...
36
+
37
+ ```
38
+ Device Name: Built-in Microphone
39
+ Device Name: Built-in Output
40
+ Device Name: Blue Snowball
41
+ ```
42
+
43
+ ### Recording Audio
44
+
45
+ You can record audio from a particular device by calling its `start` method.
46
+ Once started, the device will continue recording until its `stop` method is
47
+ called. If you provide a block parameter to `start`, it will be called whenever
48
+ the host OS provides a new buffer of audio samples.
49
+
50
+ ```ruby
51
+ device = Audio.devices.last # Hopefully that's an input device
52
+ device.start do |*args|
53
+ # Do something fancy
54
+ end
55
+
56
+ sleep 5 # Record 5 seconds of audio
57
+
58
+ device.stop
59
+ ```
4
60
 
5
61
  ## Installation
6
62
 
@@ -18,14 +74,7 @@ Or install it yourself as:
18
74
 
19
75
  $ gem install audio
20
76
 
21
- ## Usage
22
-
23
- TODO: Write usage instructions here
24
-
25
- ## Contributing
77
+ License
78
+ -------
26
79
 
27
- 1. Fork it ( https://github.com/[my-github-username]/audio/fork )
28
- 2. Create your feature branch (`git checkout -b my-new-feature`)
29
- 3. Commit your changes (`git commit -am 'Add some feature'`)
30
- 4. Push to the branch (`git push origin my-new-feature`)
31
- 5. Create a new Pull Request
80
+ Copyright 2015 Brandon Fosdick <bfoz@bfoz.net> and released under the BSD license.
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "audio"
7
- spec.version = '0'
7
+ spec.version = '0.1'
8
8
  spec.authors = ["Brandon Fosdick"]
9
9
  spec.email = ["bfoz@bfoz.net"]
10
10
  spec.summary = %q{Cross-platform Audio Device Input and Output}
@@ -1,3 +1,8 @@
1
+ require_relative 'core_audio'
2
+
1
3
  module Audio
2
- # Your code goes here...
4
+ # @return [Array<Device>] the list of available audio devices
5
+ def self.devices
6
+ CoreAudio.devices
7
+ end
3
8
  end
@@ -0,0 +1,54 @@
1
+ require 'ffi'
2
+
3
+ module CoreAudio
4
+ extend FFI::Library
5
+ ffi_lib '/System/Library/Frameworks/CoreAudio.framework/CoreAudio'
6
+
7
+ typedef :uint32, :OSStatus
8
+
9
+ # @group CoreAudioTypes.h
10
+ class AudioBuffer < FFI::Struct
11
+ layout :mNumberChannels, :uint32,
12
+ :mDataByteSize, :uint32,
13
+ :mData, :pointer
14
+
15
+ # @return [String] the raw bytes
16
+ def bytes
17
+ self[:mData].get_bytes(0, self[:mDataByteSize])
18
+ end
19
+ end
20
+
21
+ class AudioBufferList < FFI::Struct
22
+ layout :mNumberBuffers, :uint32,
23
+ :mBuffers, AudioBuffer
24
+ end
25
+ # @endgroup
26
+ end
27
+
28
+ require_relative 'core_audio/audio_device'
29
+
30
+ module CoreAudio
31
+ # AudioHardware.h
32
+ # OSStatus AudioObjectGetPropertyDataSize(AudioObjectID inObjectID,
33
+ # const AudioObjectPropertyAddress* inAddress,
34
+ # UInt32 inQualifierDataSize,
35
+ # const void* inQualifierData,
36
+ # UInt32* outDataSize)
37
+ attach_function :AudioObjectGetPropertyDataSize, [AudioObject::ObjectID, AudioObject::PropertyAddress.by_ref, :uint32, :pointer, :pointer], :OSStatus
38
+
39
+ # OSStatus AudioObjectGetPropertyData(AudioObjectID inObjectID,
40
+ # const AudioObjectPropertyAddress* inAddress,
41
+ # UInt32 inQualifierDataSize,
42
+ # const void* inQualifierData,
43
+ # UInt32* ioDataSize,
44
+ # void* outData)
45
+ attach_function :AudioObjectGetPropertyData, [AudioObject::ObjectID, AudioObject::PropertyAddress.by_ref, :uint32, :pointer, :pointer, :pointer], :OSStatus
46
+
47
+ # @return [Array<AudioObject>] the list of available audio devices
48
+ def self.devices
49
+ address = AudioObject::PropertyAddress.global_master(AudioHardware::PropertyDevices)
50
+ buffer = AudioObject.system.get_property(address)
51
+ device_IDs = buffer.get_array_of_int32(0, buffer.size/4)
52
+ device_IDs.map {|id| AudioDevice.new(id)}
53
+ end
54
+ end
@@ -0,0 +1,97 @@
1
+ require_relative 'audio_object'
2
+
3
+ module CoreAudio
4
+ AudioDeviceIOProcID = FFI::Pointer
5
+ typedef :pointer, :AudioDeviceIOProcID
6
+
7
+ # @group AudioHardware.h
8
+
9
+ # typedef OSStatus (*AudioDeviceIOProc)(AudioObjectID inDevice,
10
+ # const AudioTimeStamp* inNow,
11
+ # const AudioBufferList* inInputData,
12
+ # const AudioTimeStamp* inInputTime,
13
+ # AudioBufferList* outOutputData,
14
+ # const AudioTimeStamp* inOutputTime,
15
+ # void* inClientData);
16
+ callback :AudioDeviceIOProc, [AudioObject::ObjectID, :pointer, AudioBufferList.by_ref, :pointer, AudioBufferList.by_ref, :pointer, :pointer], :OSStatus
17
+
18
+ # OSStatus AudioDeviceCreateIOProcID(AudioObjectID inDevice,
19
+ # AudioDeviceIOProc inProc,
20
+ # void* inClientData,
21
+ # AudioDeviceIOProcID* outIOProcID)
22
+ attach_function :AudioDeviceCreateIOProcID, [AudioObject::ObjectID, :AudioDeviceIOProc, :pointer, :pointer], :OSStatus
23
+
24
+ # OSStatus AudioDeviceDestroyIOProcID(AudioObjectID inDevice,
25
+ # AudioDeviceIOProcID inIOProcID
26
+ attach_function :AudioDeviceDestroyIOProcID, [AudioObject::ObjectID, :AudioDeviceIOProc], :OSStatus
27
+
28
+ # OSStatus AudioDeviceStart(AudioObjectID inDevice,
29
+ # AudioDeviceIOProcID inProcID)
30
+ attach_function :AudioDeviceStart, [AudioObject::ObjectID, :AudioDeviceIOProcID], :OSStatus
31
+
32
+ # OSStatus AudioDeviceStop(AudioObjectID inDevice,
33
+ # AudioDeviceIOProcID inProcID)
34
+ attach_function :AudioDeviceStop, [AudioObject::ObjectID, :AudioDeviceIOProcID], :OSStatus
35
+
36
+ # @endgroup
37
+
38
+ class AudioDevice < AudioObject
39
+
40
+ # @group AudioHardware.h: AudioDevice Properties
41
+ PropertyPlugIn = 'plug'
42
+ PropertyDeviceHasChanged = 'diff'
43
+ PropertyDeviceIsRunningSomewhere = 'gone'
44
+ ProcessorOverload = 'over'
45
+ PropertyIOStoppedAbnormally = 'stpd'
46
+ PropertyHogMode = 'oink'
47
+ PropertyBufferFrameSize = 'fsiz'
48
+ PropertyBufferFrameSizeRange = 'fsz#'
49
+ PropertyUsesVariableBufferFrameSizes = 'vfsz'
50
+ PropertyIOCycleUsage = 'ncyc'
51
+ PropertyStreamConfiguration = 'slay'
52
+ PropertyIOProcStreamUsage = 'suse'
53
+ PropertyActualSampleRate = 'asrt'
54
+ # @endgroup
55
+
56
+ # @group Properties
57
+ def actual_sample_rate
58
+ address = PropertyAddress.global_master(PropertyActualSampleRate)
59
+ get_property(address).get_float64(0)
60
+ end
61
+
62
+ def buffer_frame_size
63
+ address = PropertyAddress.global_master(PropertyBufferFrameSize)
64
+ get_property(address).get_uint32(0)
65
+ end
66
+
67
+ def running_somewhere?
68
+ address = PropertyAddress.global_master(PropertyDeviceIsRunningSomewhere)
69
+ 0 != get_property(address).get_uint32(0)
70
+ end
71
+ # @endgroup
72
+
73
+ # Start the AudioDevice
74
+ # If a block is provided, register it as a callback before starting the device
75
+ # @note The device will continue to run until `stop` is called
76
+ def start(&block)
77
+ if block_given?
78
+ io_proc_id = FFI::MemoryPointer.new(:pointer)
79
+ status = CoreAudio.AudioDeviceCreateIOProcID(id, block, nil, io_proc_id)
80
+
81
+ raise "Couldn't create an IO Proc #{status} => '#{[status].pack('L').reverse}'" unless status.zero? # && !@proc_id.nil?
82
+
83
+ @proc_id = io_proc_id.get_pointer(0)
84
+ end
85
+
86
+ Thread.start do
87
+ CoreAudio.AudioDeviceStart(id, @proc_id)
88
+ end
89
+ end
90
+
91
+ # Stop the AudioDevice and delete any registered callbacks
92
+ def stop
93
+ CoreAudio.AudioDeviceStop(id, @proc_id)
94
+ CoreAudio.AudioDeviceDestroyIOProcID(id, @proc_id)
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,188 @@
1
+ require_relative '../core_foundation'
2
+
3
+ module CoreAudio
4
+ extend FFI::Library
5
+
6
+ module AudioHardwareBase
7
+ # AudioHardwareBase.h: AudioDevice Properties
8
+ AudioDevicePropertyConfigurationApplication = 'capp'
9
+ AudioDevicePropertyDeviceUID = 'uid '
10
+ AudioDevicePropertyModelUID = 'muid'
11
+ AudioDevicePropertyTransportType = 'tran'
12
+ AudioDevicePropertyRelatedDevices = 'akin'
13
+ AudioDevicePropertyClockDomain = 'clkd'
14
+ AudioDevicePropertyDeviceIsAlive = 'livn'
15
+ AudioDevicePropertyDeviceIsRunning = 'goin'
16
+ AudioDevicePropertyDeviceCanBeDefaultDevice = 'dflt'
17
+ AudioDevicePropertyDeviceCanBeDefaultSystemDevice = 'sflt'
18
+ AudioDevicePropertyLatency = 'ltnc'
19
+ AudioDevicePropertyStreams = 'stm#'
20
+ AudioObjectPropertyControlList = 'ctrl'
21
+ AudioDevicePropertySafetyOffset = 'saft'
22
+ AudioDevicePropertyNominalSampleRate = 'nsrt'
23
+ AudioDevicePropertyAvailableNominalSampleRates = 'nsr#'
24
+ AudioDevicePropertyIcon = 'icon'
25
+ AudioDevicePropertyIsHidden = 'hidn'
26
+ AudioDevicePropertyPreferredChannelsForStereo = 'dch2'
27
+ AudioDevicePropertyPreferredChannelLayout = 'srnd'
28
+ end
29
+
30
+ module AudioHardware
31
+ # AudioHardware.h: AudioSystemObject Properties
32
+ PropertyDevices = 'dev#'
33
+ PropertyDefaultInputDevice = 'dIn '
34
+ PropertyDefaultOutputDevice = 'dOut'
35
+ PropertyDefaultSystemOutputDevice = 'sOut'
36
+ PropertyTranslateUIDToDevice = 'uidd'
37
+ PropertyMixStereoToMono = 'stmo'
38
+ PropertyPlugInList = 'plg#'
39
+ PropertyTranslateBundleIDToPlugIn = 'bidp'
40
+ PropertyTransportManagerList = 'tmg#'
41
+ PropertyTranslateBundleIDToTransportManager = 'tmbi'
42
+ PropertyBoxList = 'box#'
43
+ PropertyTranslateUIDToBox = 'uidb'
44
+ PropertyProcessIsMaster = 'mast'
45
+ PropertyIsInitingOrExiting = 'inot'
46
+ PropertyUserIDChanged = 'euid'
47
+ PropertyProcessIsAudible = 'pmut'
48
+ PropertySleepingIsAllowed = 'slep'
49
+ PropertyUnloadingIsAllowed = 'unld'
50
+ PropertyHogModeIsAllowed = 'hogr'
51
+ PropertyUserSessionIsActiveOrHeadless = 'user'
52
+ PropertyServiceRestarted = 'srst'
53
+ PropertyPowerHint = 'powh'
54
+
55
+ # AudioHardware.h: AudioDevice Properties
56
+ AudioDevicePropertyPlugIn = 'plug'
57
+ AudioDevicePropertyDeviceHasChanged = 'diff'
58
+ AudioDevicePropertyDeviceIsRunningSomewhere = 'gone'
59
+ AudioDeviceProcessorOverload = 'over'
60
+ AudioDevicePropertyIOStoppedAbnormally = 'stpd'
61
+ AudioDevicePropertyHogMode = 'oink'
62
+ AudioDevicePropertyBufferFrameSize = 'fsiz'
63
+ AudioDevicePropertyBufferFrameSizeRange = 'fsz#'
64
+ AudioDevicePropertyUsesVariableBufferFrameSizes = 'vfsz'
65
+ AudioDevicePropertyIOCycleUsage = 'ncyc'
66
+ AudioDevicePropertyStreamConfiguration = 'slay'
67
+ AudioDevicePropertyIOProcStreamUsage = 'suse'
68
+ AudioDevicePropertyActualSampleRate = 'asrt'
69
+ end
70
+
71
+ class AudioObject
72
+ attr_reader :id
73
+
74
+ ObjectID = FFI::Type::UINT32
75
+ PropertyElement = FFI::Type::UINT32
76
+ PropertyScope = FFI::Type::UINT32
77
+ PropertySelector = FFI::Type::UINT32
78
+
79
+ # AudioHardwareBase.h: Basic Constants
80
+ PropertyScopeGlobal = 'glob'
81
+ PropertyScopeInput = 'inpt'
82
+ PropertyScopeOutput = 'outp'
83
+ PropertyScopePlayThrough = 'ptru'
84
+ PropertyElementMaster = 0
85
+
86
+ # AudioHardwareBase.h: AudioObject Properties
87
+ PropertyBaseClass = 'bcls'
88
+ PropertyClass = 'clas'
89
+ PropertyOwner = 'stdv'
90
+ PropertyName = 'lnam'
91
+ PropertyModelName = 'lmod'
92
+ PropertyManufacturer = 'lmak'
93
+ PropertyElementName = 'lchn'
94
+ PropertyElementCategoryName = 'lccn'
95
+ PropertyElementNumberName = 'lcnn'
96
+ PropertyOwnedObjects = 'ownd'
97
+ PropertyIdentify = 'iden'
98
+ PropertySerialNumber = 'snum'
99
+ PropertyFirmwareVersion = 'fwvn'
100
+
101
+ # AudioHardware.h: Basic Constants
102
+ SystemObject = 1
103
+
104
+ def self.system
105
+ new(SystemObject)
106
+ end
107
+
108
+ def initialize(id)
109
+ @id = id
110
+ end
111
+
112
+ # @return [FFI::MemoryPointer]
113
+ def get_property(address)
114
+ buffer_size = FFI::MemoryPointer.new(:uint32)
115
+ status = CoreAudio.AudioObjectGetPropertyDataSize(id, address, 0, nil, buffer_size)
116
+ raise('Could not get audio property size') unless 0 == status
117
+
118
+ # buffer_size is now the size of the buffer to be passed to AudioObjectGetPropertyData()
119
+ buffer = FFI::MemoryPointer.new(1, buffer_size.get_int32(0))
120
+ status = CoreAudio.AudioObjectGetPropertyData(id, address, 0, nil, buffer_size, buffer)
121
+ raise('Could not get the audio property data') unless 0 == status
122
+
123
+ buffer
124
+ end
125
+
126
+ # @group Convenience Attributes
127
+ def external?
128
+ not internal?
129
+ end
130
+
131
+ def internal?
132
+ transport_type == 'bltn'
133
+ end
134
+ # @endgroup
135
+
136
+ # @return [String] the name of the device
137
+ def device_name
138
+ address = PropertyAddress.global_master(PropertyName)
139
+ get_string(address)
140
+ end
141
+
142
+ def device_uid
143
+ address = PropertyAddress.global_master(AudioHardwareBase::AudioDevicePropertyDeviceUID)
144
+ get_string(address)
145
+ end
146
+
147
+ # @return [String] a persistent identifier for the model of an AudioDevice
148
+ def model_uid
149
+ address = PropertyAddress.global_master(AudioHardwareBase::AudioDevicePropertyModelUID)
150
+ get_string(address)
151
+ end
152
+
153
+ # @return [String] the 4-character transport type identifier
154
+ def transport_type
155
+ address = PropertyAddress.global_master(AudioHardwareBase::AudioDevicePropertyTransportType)
156
+ buffer = get_property(address)
157
+ buffer.get_bytes(0, buffer.size).reverse
158
+ end
159
+
160
+ class PropertyAddress < FFI::Struct
161
+ layout :mSelector, AudioObject::PropertySelector,
162
+ :mScope, AudioObject::PropertyScope,
163
+ :mElement, AudioObject::PropertyElement
164
+
165
+ def self.make(selector, scope, element)
166
+ element, scope, selector = [element, scope, selector].map {|a| a.is_a?(String) ? a.reverse.unpack('L').first : a }
167
+ new.tap do |address|
168
+ address[:mSelector] = selector
169
+ address[:mScope] = scope
170
+ address[:mElement] = element
171
+ end
172
+ end
173
+
174
+ def self.global_master(selector)
175
+ make(selector, PropertyScopeGlobal, PropertyElementMaster)
176
+ end
177
+ end
178
+
179
+ private
180
+
181
+ # @return [String] the String for the addressed property
182
+ def get_string(address)
183
+ buffer = get_property(address)
184
+ cf_string_ref = buffer.get_pointer(0)
185
+ CoreFoundation::CFStringRef.new(cf_string_ref).to_s
186
+ end
187
+ end
188
+ end
@@ -0,0 +1,87 @@
1
+ require 'ffi'
2
+
3
+ module CoreFoundation
4
+ extend FFI::Library
5
+ ffi_lib '/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation'
6
+
7
+ typedef :pointer, :CFStringRef
8
+
9
+ if FFI::Platform::ARCH == 'x86_64'
10
+ CFIndex = FFI::Type::LONG_LONG
11
+ else
12
+ CFIndex = FFI::Type::LONG
13
+ end
14
+
15
+ # CFString.h
16
+ CFStringEncoding = enum :uint32,
17
+ :MacRoman, 0,
18
+ :WindowsLatin1, 0x0500, # ANSI codepage 1252
19
+ :ISOLatin1, 0x0201, # ISO 8859-1
20
+ :NextStepLatin, 0x0B01, # NextStep encoding
21
+ :ASCII, 0x0600, # 0..127 (in creating CFString, values greater than 0x7F are treated as corresponding Unicode value)
22
+ :Unicode, 0x0100, # kTextEncodingUnicodeDefault + kTextEncodingDefaultFormat (aka kUnicode16BitFormat)
23
+ :UTF8, 0x08000100, # kTextEncodingUnicodeDefault + kUnicodeUTF8Format
24
+ :NonLossyASCII, 0x0BFF, # 7bit Unicode variants used by Cocoa & Java
25
+ :UTF16, 0x0100, # kTextEncodingUnicodeDefault + kUnicodeUTF16Format (alias of kCFStringEncodingUnicode)
26
+ :UTF16BE, 0x10000100, # kTextEncodingUnicodeDefault + kUnicodeUTF16BEFormat
27
+ :UTF16LE, 0x14000100, # kTextEncodingUnicodeDefault + kUnicodeUTF16LEFormat
28
+ :UTF32, 0x0c000100, # kTextEncodingUnicodeDefault + kUnicodeUTF32Format
29
+ :UTF32BE, 0x18000100, # kTextEncodingUnicodeDefault + kUnicodeUTF32BEFormat
30
+ :UTF32LE, 0x1c000100, # kTextEncodingUnicodeDefault + kUnicodeUTF32LEFormat
31
+ :Invalid, 0xffffffff # Invalid Encoding
32
+
33
+ class CFRange < FFI::Struct
34
+ layout :location, CFIndex,
35
+ :length, CFIndex
36
+
37
+ def self.make(location:0, length:0)
38
+ new.tap do |range|
39
+ range[:location] = location
40
+ range[:length] = length
41
+ end
42
+ end
43
+ end
44
+
45
+ class CFStringRef < FFI::Pointer
46
+ # @return [CFIndex] the length of the referenced CFString
47
+ def length
48
+ CoreFoundation.CFStringGetLength(self)
49
+ end
50
+
51
+ # @return [CFIndex] the maximum size of the buffer that will hold the string
52
+ def max_size
53
+ CoreFoundation.CFStringGetMaximumSizeForEncoding(length, CFStringEncoding[:UTF8])
54
+ end
55
+
56
+ # @return [String] the CFString, converted to a UTF-8 string
57
+ def to_s
58
+ buffer = FFI::MemoryPointer.new(:char, max_size)
59
+ used_bytes = FFI::MemoryPointer.new(CFIndex)
60
+ CoreFoundation.CFStringGetBytes(self,
61
+ CFRange.make(location:0, length:length),
62
+ CFStringEncoding[:UTF8],
63
+ 0,
64
+ false,
65
+ buffer,
66
+ buffer.size,
67
+ used_bytes)
68
+
69
+ used_bytes = if CFIndex == CoreFoundation.find_type(:long_long)
70
+ used_bytes.read_long_long
71
+ else
72
+ used_bytes.read_long
73
+ end
74
+
75
+ buffer.read_string(used_bytes).force_encoding(Encoding::UTF_8)
76
+ end
77
+ end
78
+
79
+ # CFIndex CFStringGetBytes(CFStringRef theString, CFRange range, CFStringEncoding encoding, UInt8 lossByte, Boolean isExternalRepresentation, UInt8 *buffer, CFIndex maxBufLen, CFIndex *usedBufLen)
80
+ attach_function :CFStringGetBytes, [:CFStringRef, CFRange.by_value, CFStringEncoding, :uint8, :bool, :buffer_out, CFIndex, :buffer_out], CFIndex
81
+
82
+ # CFIndex CFStringGetLength(CFStringRef theString)
83
+ attach_function :CFStringGetLength, [:CFStringRef], CFIndex
84
+
85
+ # CFIndex CFStringGetMaximumSizeForEncoding(CFIndex length, CFStringEncoding encoding)
86
+ attach_function :CFStringGetMaximumSizeForEncoding, [CFIndex, CFStringEncoding], CFIndex
87
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: audio
3
3
  version: !ruby/object:Gem::Version
4
- version: '0'
4
+ version: '0.1'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandon Fosdick
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-13 00:00:00.000000000 Z
11
+ date: 2015-02-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -51,6 +51,10 @@ files:
51
51
  - Rakefile
52
52
  - audio.gemspec
53
53
  - lib/audio.rb
54
+ - lib/core_audio.rb
55
+ - lib/core_audio/audio_device.rb
56
+ - lib/core_audio/audio_object.rb
57
+ - lib/core_foundation.rb
54
58
  homepage: http://github.com/bfoz/audio-ruby
55
59
  licenses:
56
60
  - BSD