haskell - Sound.Pulse.Simple 不起作用?

标签 haskell audio

我下载了Sound.Pulse.Simple并复制并粘贴示例程序:

main=do
  s<-simpleNew Nothing "example" Play Nothing "this is example application"
      (SampleSpec (F32 LittleEndian) 44100 1) Nothing Nothing
  simpleWrite s [sin $ 2*pi*440*(t/44100)|t<-[1..44100*10]]
  simpleDrain s
  simpleFree s

进入 atom 并尝试编译它只是为了确保它可以在我的系统上运行。 ghc 真的很沮丧,这是完整的错误消息(即使它很长):
soundtest.hs:6:5:
No instance for (Foreign.Storable.Storable a0)
  arising from a use of `simpleWrite'
The type variable `a0' is ambiguous
Note: there are several potential instances:
  instance Foreign.Storable.Storable BufferAttr -- Defined in `Sound'
  instance Foreign.Storable.Storable Sound.ChannelMap
    -- Defined in `Sound'
  instance Foreign.Storable.Storable SampleSpec -- Defined in `Sound'
  ...plus 45 others
In a stmt of a 'do' block:
  simpleWrite
    s [sin $ 2 * pi * 440 * (t / 44100) | t <- [1 .. 44100 * 10]]
In the expression:
  do { s <- simpleNew
              Nothing
              "example"
              Play
              Nothing
              "this is example application"
              (SampleSpec (F32 LittleEndian) 44100 1)
              Nothing
              Nothing;
       simpleWrite
         s [sin $ 2 * pi * 440 * (t / 44100) | t <- [1 .. 44100 * 10]];
       simpleDrain s;
       simpleFree s }
In an equation for `main':
    main
      = do { s <- simpleNew
                    Nothing
                    "example"
                    Play
                    Nothing
                    "this is example application"
                    (SampleSpec (F32 LittleEndian) 44100 1)
                    Nothing
                    Nothing;
             simpleWrite
               s [sin $ 2 * pi * 440 * (t / 44100) | t <- [1 .. 44100 * 10]];
             simpleDrain s;
             .... }

soundtest.hs:6:20:
No instance for (Floating a0) arising from a use of `sin'
The type variable `a0' is ambiguous
Relevant bindings include t :: a0 (bound at soundtest.hs:6:45)
Note: there are several potential instances:
  instance Floating Foreign.C.Types.CDouble
    -- Defined in `Foreign.C.Types'
  instance Floating Foreign.C.Types.CFloat
    -- Defined in `Foreign.C.Types'
  instance Floating Double -- Defined in `GHC.Float'
  ...plus one other
In the expression: sin
In the expression: sin $ 2 * pi * 440 * (t / 44100)
In the second argument of `simpleWrite', namely
  `[sin $ 2 * pi * 440 * (t / 44100) | t <- [1 .. 44100 * 10]]'

soundtest.hs:6:37:
No instance for (Fractional a0) arising from a use of `/'
The type variable `a0' is ambiguous
Relevant bindings include t :: a0 (bound at soundtest.hs:6:45)
Note: there are several potential instances:
  instance Fractional Foreign.C.Types.CDouble
    -- Defined in `Foreign.C.Types'
  instance Fractional Foreign.C.Types.CFloat
    -- Defined in `Foreign.C.Types'
  instance Integral a => Fractional (GHC.Real.Ratio a)
    -- Defined in `GHC.Real'
  ...plus two others
In the second argument of `(*)', namely `(t / 44100)'
In the second argument of `($)', namely
  `2 * pi * 440 * (t / 44100)'
In the expression: sin $ 2 * pi * 440 * (t / 44100)

soundtest.hs:6:48:
No instance for (Enum a0)
  arising from the arithmetic sequence `1 .. 44100 * 10'
The type variable `a0' is ambiguous
Note: there are several potential instances:
  instance Enum ChannelPosition -- Defined in `Sound'
  instance Enum Direction -- Defined in `Sound'
  instance Enum SampleFormat -- Defined in `Sound'
  ...plus 45 others
In the expression: [1 .. 44100 * 10]
In a stmt of a list comprehension: t <- [1 .. 44100 * 10]
In the second argument of `simpleWrite', namely
  `[sin $ 2 * pi * 440 * (t / 44100) | t <- [1 .. 44100 * 10]]'

soundtest.hs:6:49:
No instance for (Num a0) arising from the literal `1'
The type variable `a0' is ambiguous
Note: there are several potential instances:
  instance Num Foreign.C.Types.CChar -- Defined in `Foreign.C.Types'
  instance Num Foreign.C.Types.CClock -- Defined in `Foreign.C.Types'
  instance Num Foreign.C.Types.CDouble
    -- Defined in `Foreign.C.Types'
  ...plus 38 others
In the expression: 1
In the expression: [1 .. 44100 * 10]
In a stmt of a list comprehension: t <- [1 .. 44100 * 10]

soundtest.hs:6:5:
No instance for (Foreign.Storable.Storable a0)
  arising from a use of `simpleWrite'
The type variable `a0' is ambiguous
Note: there are several potential instances:
  instance Foreign.Storable.Storable BufferAttr -- Defined in `Sound'
  instance Foreign.Storable.Storable Sound.ChannelMap
    -- Defined in `Sound'
  instance Foreign.Storable.Storable SampleSpec -- Defined in `Sound'
  ...plus 45 others
In a stmt of a 'do' block:
  simpleWrite
    s
    [sin $ 2.0 * pi * 440.0 * (t / 44100.0) |
       t <- [1.0, 2.0 .. 44100.0 * 10.0]]
In the expression:
  do { s <- simpleNew
              Nothing
              "example"
              Play
              Nothing
              "this is example application"
              (SampleSpec (F32 LittleEndian) 44100 1)
              Nothing
              Nothing;
       simpleWrite
         s
         [sin $ 2.0 * pi * 440.0 * (t / 44100.0) |
            t <- [1.0, 2.0 .. 44100.0 * 10.0]];
       simpleDrain s;
       simpleFree s }
In an equation for `main':
    main
      = do { s <- simpleNew
                    Nothing
                    "example"
                    Play
                    Nothing
                    "this is example application"
                    (SampleSpec (F32 LittleEndian) 44100 1)
                    Nothing
                    Nothing;
             simpleWrite
               s
               [sin $ 2.0 * pi * 440.0 * (t / 44100.0) |
                  t <- [1.0, 2.0 .. 44100.0 * 10.0]];
             simpleDrain s;
             .... }

soundtest.hs:6:20:
No instance for (Floating a0) arising from a use of `sin'
The type variable `a0' is ambiguous
Relevant bindings include t :: a0 (bound at soundtest.hs:6:51)
Note: there are several potential instances:
  instance Floating Foreign.C.Types.CDouble
    -- Defined in `Foreign.C.Types'
  instance Floating Foreign.C.Types.CFloat
    -- Defined in `Foreign.C.Types'
  instance Floating Double -- Defined in `GHC.Float'
  ...plus one other
In the expression: sin
In the expression: sin $ 2.0 * pi * 440.0 * (t / 44100.0)
In the second argument of `simpleWrite', namely
  `[sin $ 2.0 * pi * 440.0 * (t / 44100.0) |
      t <- [1.0, 2.0 .. 44100.0 * 10.0]]'

soundtest.hs:6:54:
No instance for (Enum a0)
  arising from the arithmetic sequence `1.0, 2.0 .. 44100.0 * 10.0'
The type variable `a0' is ambiguous
Note: there are several potential instances:
  instance Enum ChannelPosition -- Defined in `Sound'
  instance Enum Direction -- Defined in `Sound'
  instance Enum SampleFormat -- Defined in `Sound'
  ...plus 45 others
In the expression: [1.0, 2.0 .. 44100.0 * 10.0]
In a stmt of a list comprehension:
  t <- [1.0, 2.0 .. 44100.0 * 10.0]
In the second argument of `simpleWrite', namely
  `[sin $ 2.0 * pi * 440.0 * (t / 44100.0) |
      t <- [1.0, 2.0 .. 44100.0 * 10.0]]'

soundtest.hs:6:55:
No instance for (Fractional a0) arising from the literal `1.0'
The type variable `a0' is ambiguous
Note: there are several potential instances:
  instance Fractional Foreign.C.Types.CDouble
    -- Defined in `Foreign.C.Types'
  instance Fractional Foreign.C.Types.CFloat
    -- Defined in `Foreign.C.Types'
  instance Integral a => Fractional (GHC.Real.Ratio a)
    -- Defined in `GHC.Real'
  ...plus two others
In the expression: 1.0
In the expression: [1.0, 2.0 .. 44100.0 * 10.0]
In a stmt of a list comprehension:
  t <- [1.0, 2.0 .. 44100.0 * 10.0]

soundtest.hs:6:71:
No instance for (Num a0) arising from a use of `*'
The type variable `a0' is ambiguous
Note: there are several potential instances:
  instance Num Foreign.C.Types.CChar -- Defined in `Foreign.C.Types'
  instance Num Foreign.C.Types.CClock -- Defined in `Foreign.C.Types'
  instance Num Foreign.C.Types.CDouble
    -- Defined in `Foreign.C.Types'
  ...plus 38 others
In the expression: 44100.0 * 10.0
In the expression: [1.0, 2.0 .. 44100.0 * 10.0]
In a stmt of a list comprehension:
  t <- [1.0, 2.0 .. 44100.0 * 10.0]

我尝试将所有内容切换为 Float (即使这可能会导致范围内的浮点不精确)并且它仍然无法编译。我还需要下载另一个库吗?我应该使用不同的声音输出库吗?我在 Windows 上并使用 Haskell 平台 2014.2.0.0

最佳答案

“模糊类型变量”错误意味着类型检查器没有足够的信息来决定它应该使用哪种类型来实例化类型类。要解决此问题,请添加一个指定列表元素类型的类型注释,例如:

simpleWrite s ([sin $ 2*pi*440*(t/44100)|t<-[1..44100*10]] :: [Float])

(与您链接的示例不同, documentation for the latest version of the library 中的示例确实包含缺少的注释。)

不过,还有一些事情需要解释。首先,您提到您尝试通过“将所有内容切换为浮点数”来修复错误。我想此尝试对应于您包含的第二组错误,并且您将 [1 .. 44100 * 10] 更改为 [1.0, 2.0 .. 44100.0 * 10.0] 等等。如果确实如此,它就不起作用,因为添加小数点实际上并没有将类型更改为 Float ,因为 Haskell 数字文字是多态的:
GHCi> :t 1
1 :: Num t => t
GHCi> :t 1.0
1.0 :: Fractional t => t

这也意味着即使在没有类型注释的情况下, [sin $ 2*pi*440*(t/44100)|t<-[1..44100*10]] 中的范围也会生成浮点值,好像情况并非如此,就无法将它们与 sin(/) 一起使用。虽然在您的情况下,就范围而言没有不准确的风险(该问题仅出现在步长不是整数的情况下,或者由于不同的原因,使用非常大的数字),使用例如只要您引入合适的转换函数,范围的 Integer s 是可能的:
[sin $ 2*pi*440*(fromInteger t/44100)|t<-[1..44100*10]]

其次,您可能想知道为什么这次会出现歧义错误,因为您之前一直在使用这些多态文字而没有任何问题。您通常不会收到此类错误,因为多态数有一个默认机制,在不明确的情况下,会选择 IntegerDouble 中更合适的一个(有关详细信息,请参阅 Haskell Report)。然而,这种机制只有在多态数调用的类是从一组有限的标准类中提取时才起作用——这是有道理的,就好像你正在使用更奇特的类一样,编译器猜测不恰当的几率会增加.现在,如果您查看 simpleWrite 的类型...
simpleWrite :: Storable a => Simple -> [a] -> IO ()

...您会注意到它需要 StorableStorable 不在上述一组标准类中,因此没有默认值。

关于haskell - Sound.Pulse.Simple 不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43485073/

相关文章:

ios - 如何使视频的音轨在IOS中消失

android - Android录制钢琴应用程序的音频

haskell - 哪些程序可以简单地指定为依赖类型,但实现起来很复杂?

parsing - 如何使用 Parsec 制作子解析器?

haskell - 从一系列较小的类型类实例中推断出通用类型类实例?

haskell - 如何导入模块进行测试?

java - 有什么想法为什么录制音频会这么慢我的整个应用程序?

html - HTML5音频-在Safari上搜索后,currentTime属性错误

iphone - 为此我需要哪种音频播放技术?

haskell - 这种抽象数据类型叫什么?