audio 0 → 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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