<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>src/System/Mac/Types.hs</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -2,6 +2,8 @@
 
 import Control.Concurrent (threadDelay)
 import Sound.AudioToolbox.AUGraph
+import Prelude hiding (any)
+import System.Mac.Components
 
 -- Define ComponentDescriptions for AudioUnits in example
 dlsSynth = ComponentDescription {
@@ -49,3 +51,6 @@ main = do
   -- Stop rendering and release graph
   stop graph
   dispose graph
+  
+  cs &lt;- components $ ComponentDescription &quot;aumu&quot; any any 0 0
+  putStrLn =&lt;&lt; componentName (head cs)</diff>
      <filename>doc/examples/Test.hs</filename>
    </modified>
    <modified>
      <diff>@@ -22,7 +22,8 @@ Library
         Sound.AudioToolbox.AUGraph,
         System.Mac.Components,
         System.Mac.OSStatus,
-        System.Mac.OSType
+        System.Mac.OSType,
+        System.Mac.Types
     frameworks: AudioToolbox, AudioUnit
     
     build-depends:</diff>
      <filename>hs-coreaudio.cabal</filename>
    </modified>
    <modified>
      <diff>@@ -1,7 +1,9 @@
 {-# LANGUAGE EmptyDataDecls, ForeignFunctionInterface, OverloadedStrings, PatternGuards #-}
 
 -- | Types and operations corresponding to the definitions in
--- @AudioToolbox/AUGraph.h@
+-- @AudioToolbox/AUGraph.h@. For an overview of the api, see the section
+-- titled &quot;Hosting Audio Units&quot; in the document at
+-- &lt;http://developer.apple.com/mac/library/documentation/MusicAudio/Conceptual/CoreAudioOverview/ARoadmaptoCommonTasks/ARoadmaptoCommonTasks.html&gt;.
 
 module Sound.AudioToolbox.AUGraph (
   ComponentDescription (..), -- | See &quot;System.Mac.Components&quot;
@@ -23,9 +25,10 @@ module Sound.AudioToolbox.AUGraph (
   caShow
 ) where
 
+import Control.Applicative
 import Foreign (Ptr, Storable (..), alloca, nullPtr)
 import Foreign.C.Types (CInt, CUInt)
-import System.Mac.Components
+import System.Mac.Components hiding (componentDescription)
 import System.Mac.OSStatus
 import Sound.AudioUnit.AUComponent
 import Sound.AudioUnit.MusicDevice
@@ -149,7 +152,7 @@ musicDevice :: AUGraph -&gt; AUNode -&gt; IO MusicDeviceComponent
 musicDevice graph node = do
   cd &lt;- componentDescription graph node
   case componentType cd of
-    &quot;aumu&quot; -&gt; return . MusicDeviceComponent =&lt;&lt; audioUnit graph node
+    &quot;aumu&quot; -&gt; MusicDeviceComponent &lt;$&gt; audioUnit graph node
     _      -&gt; error $ show (componentType cd) ++ &quot; is not a MusicDevice&quot;
 {-# INLINE musicDevice #-}
 </diff>
      <filename>src/Sound/AudioToolbox/AUGraph.hs</filename>
    </modified>
    <modified>
      <diff>@@ -6,13 +6,26 @@
 
 module System.Mac.Components (
   ComponentDescription (..),
+  Component,
   ComponentInstance,
-  ComponentResult
+  ComponentResult,
+  any,
+  noComponent,
+  countComponents,
+  findNextComponent,
+  components,
+  componentDescription,
+  componentName
 ) where
 
-import Foreign (Ptr, Storable (..))
-import Foreign.C.Types (CInt, CUInt)
+import Prelude hiding (any)
+import Control.Applicative
+import Control.Exception (bracket)
+import Data.Bits (bitSize)
+import Foreign (Ptr, Storable (..), alloca, nullPtr)
+import Foreign.C.Types (CInt, CUInt, CLong)
 import System.Mac.OSType
+import System.Mac.Types
 
 #include &quot;/System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Headers/Components.h&quot;
 #let alignment t = &quot;%lu&quot;, (unsigned long)offsetof(struct {char x__; t (y__); }, y__)
@@ -42,8 +55,73 @@ instance Storable ComponentDescription where
     #{poke ComponentDescription, componentFlags} ptr f
     #{poke ComponentDescription, componentFlagsMask} ptr k
 
+data ComponentRecord
+
+type Component = Ptr ComponentRecord
+
 data ComponentInstanceRecord
 
 type ComponentInstance = Ptr ComponentInstanceRecord
 
 type ComponentResult = CInt
+
+-- | When searching for components by a ComponentDescription, setting a field's
+-- value to 'any' causes the component manager to ignore that field.
+any :: OSType
+any = OSType 0
+
+noComponent :: Component
+noComponent = nullPtr
+
+foreign import ccall &quot;Components.h CountComponents&quot;
+  c_CountComponents :: Ptr ComponentDescription -&gt; IO CLong
+
+-- | Count the number of components matching a given 'ComponentDescription'.
+-- Define any 'ComponentDescription' field as 'any' to ignore it.
+countComponents :: ComponentDescription -&gt; IO Int
+countComponents desc = alloca $ \ptr -&gt; do
+  poke ptr desc
+  fromIntegral &lt;$&gt; c_CountComponents ptr
+{-# INLINE countComponents #-}
+
+foreign import ccall &quot;Components.h FindNextComponent&quot;
+  c_FindNextComponent :: Component -&gt; Ptr ComponentDescription -&gt; IO Component
+
+findNextComponent :: Component -&gt; ComponentDescription -&gt; IO (Maybe Component)
+findNextComponent component looking = alloca $ \ptr -&gt; do
+  poke ptr looking
+  box &lt;$&gt; c_FindNextComponent component ptr
+  where box found | found == noComponent = Nothing
+                  | otherwise = Just found
+{-# INLINE findNextComponent #-}
+
+-- | Find all 'Component's matching a given description
+components :: ComponentDescription -&gt; IO [Component]
+components desc = search noComponent []
+    where search c cs = do
+            out &lt;- findNextComponent c desc
+            case out of
+              Just found -&gt; search found $ cs ++ [found]
+              Nothing    -&gt; return cs
+
+foreign import ccall &quot;Components.h GetComponentInfo&quot;
+  c_GetComponentInfo :: Component -&gt; Ptr ComponentDescription
+                     -&gt; Handle -&gt; Handle -&gt; Handle
+                     -&gt; IO OSErr
+
+-- | Call @GetComponentInfo@ to retrieve a 'Component''s ComponentDescription
+componentDescription :: Component -&gt; IO ComponentDescription
+componentDescription component = alloca $ \ptr -&gt; do
+  c_GetComponentInfo component ptr nullPtr nullPtr nullPtr
+  peek ptr
+{-# INLINE componentDescription #-}
+
+-- | Call @GetComponentInfo@ to retrieve a 'Component''s name as a String
+componentName :: Component -&gt; IO String
+componentName component = bracket
+  (c_NewHandle $ bitSize (undefined::CInt) `div` 8)
+  c_DisposeHandle
+  (\h -&gt; do
+    c_GetComponentInfo component nullPtr h nullPtr nullPtr
+    peek h &gt;&gt;= peekPascalStr)
+{-# INLINE componentName #-}</diff>
      <filename>src/System/Mac/Components.hsc</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>0554dec91229971c12486dad3d5a99d6a22d0219</id>
    </parent>
  </parents>
  <author>
    <name>Jeremy Voorhis</name>
    <email>jvoorhis@jeremy-voorhiss-macbook-2.local</email>
  </author>
  <url>http://github.com/jvoorhis/hs-coreaudio/commit/6ea91ccdcdd714b9e7f3c152c0eccb73e317ad3d</url>
  <id>6ea91ccdcdd714b9e7f3c152c0eccb73e317ad3d</id>
  <committed-date>2009-10-19T17:17:48-07:00</committed-date>
  <authored-date>2009-10-19T17:17:48-07:00</authored-date>
  <message>Implemented some Component Manager queries, including looking up components by type, and finding their names and ComponentDescriptions. Added System.Mac.Types module to loosely correspond to MacTypes. Implemented a Handle type and wrappers for related functionality. Implemented peekPascalStr.</message>
  <tree>a917ac88c775d5f03af2bee4e7afa41c4ecca6ac</tree>
  <committer>
    <name>Jeremy Voorhis</name>
    <email>jvoorhis@jeremy-voorhiss-macbook-2.local</email>
  </committer>
</commit>
