windsp 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/lib/windsp.rb +81 -38
  4. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9b40da30b2b860996cf31c7368ac836aa5456e56
4
- data.tar.gz: b7da40fe4ffe89ba12110a9ec36da0dd4f5f7f54
3
+ metadata.gz: 9818962b3f928fab87a3900c52e0e87608473402
4
+ data.tar.gz: 95377f4b3e86a0bf4168036b7afe0ab65c16af6c
5
5
  SHA512:
6
- metadata.gz: 877ad9b7b102de4f055b2105b6bdf407a0fbe572f3f7c0913ea85a5916941a32937e381fd36950b2c19ce8b5833e8e251db04605d83db7e968861b19f972a29d
7
- data.tar.gz: 357b8e93fa930462ae7e9b040641b8c739fc948f666cf07663f2be73151aa50bac191708afc074871e4e95ba8ddc9779beaf751ec28fb81b5ac02685425cca21
6
+ metadata.gz: 5ac607666568ec3fed4136bbf5d431cc4746925743b491998fef6458175efe94dedcd5527f011f94c2ef41722b54e5a28d8413ec131c40562e250ac2b5adfdf3
7
+ data.tar.gz: 8c800f99298c0db3f4046579d7c7415b33c40f4ae9672c69ff237b7eceafe0099c6930b45343ee64ca5635e3fe995dddc99e870ad29548192437b400c50081f7
data/.gitignore CHANGED
@@ -1,2 +1,5 @@
1
1
  pkg/*
2
2
  Gemfile.lock
3
+ x.rb
4
+ y.rb
5
+ z.rb
@@ -4,39 +4,26 @@ class WinDSP
4
4
  module WinMM
5
5
  extend Fiddle::Importer
6
6
  dlload "winmm.dll"
7
- extern "int PlaySound(void *, void *, long)"
8
-
9
- SND_SYNC = 0x0000
10
- SND_ASYNC = 0x0001
11
- SND_NODEFAULT = 0x0002
12
- SND_MEMORY = 0x0004
13
- SND_LOOP = 0x0008
14
- SND_NOSTOP = 0x0010
15
- SND_NOWAIT = 0x00002000
16
- SND_ALIAS = 0x00010000
17
- SND_ALIAS_ID = 0x00110000
18
- SND_FILENAME = 0x00020000
19
- SND_RESOURCE = 0x00040004
20
- SND_PURGE = 0x0040
21
- SND_APPLICATION = 0x0080
22
- SND_SENTRY = 0x00080000
23
- SND_RING = 0x00100000
24
- SND_SYSTEM = 0x00200000
25
-
26
- def self.make_wave(pcm)
27
- head = ["WAVEfmt ", 16, 1, 1, 8000, 8000 * 1 * 1, 1 * 1, 8].pack('a*VvvVVvv')
28
- data = ["data", pcm.bytesize, pcm].pack('a*Va*')
29
- ["RIFF", head.bytesize + data.bytesize, head, data].pack('a*Va*a*')
7
+ if /64/ =~ RUBY_PLATFORM
8
+ int_ptr = "long long"
9
+ else
10
+ int_ptr = "long"
30
11
  end
12
+ extern "int waveOutOpen(void *, #{int_ptr}, void *, #{int_ptr}, #{int_ptr}, long)"
13
+ extern "int waveOutClose(#{int_ptr})"
14
+ extern "int waveOutPrepareHeader(#{int_ptr}, void *, int)"
15
+ extern "int waveOutUnprepareHeader(#{int_ptr}, void *, int)"
16
+ extern "int waveOutWrite(#{int_ptr}, void *, int)"
17
+ extern "int waveOutGetPosition(#{int_ptr}, void *, int)"
31
18
 
32
- def self.play_pcm(pcm, sync: true)
33
- flags = SND_NODEFAULT | SND_MEMORY
34
- flags |= SND_ASYNC unless sync
35
- PlaySound(make_wave(pcm), nil, flags)
36
- end
19
+ WAVE_FORMAT_PCM = 1
20
+ WAVE_ALLOWSYNC = 0x0002
21
+ WAVE_MAPPED = 0x0004
22
+ WHDR_DONE = 0x00000001
23
+ WHDR_INQUEUE = 0x00000010
37
24
  end
38
25
 
39
- VERSION = "0.0.1"
26
+ VERSION = "0.0.2"
40
27
 
41
28
  def self.open(*rest, &block)
42
29
  io = self.new(rest)
@@ -51,28 +38,60 @@ class WinDSP
51
38
  end
52
39
  end
53
40
 
41
+ CHANNELS = 1
42
+ BITS = 8
43
+ FREQUENCY = 8000
44
+
54
45
  def initialize(*rest)
55
- @buf = ""
46
+ tmp = "\0" * 8
47
+ form = [WinMM::WAVE_FORMAT_PCM, CHANNELS, FREQUENCY, rate, (BITS / 8) * CHANNELS, BITS, 0].pack("vvVVvvv")
48
+ ret = WinMM.waveOutOpen(tmp, 0, form, 0, 0, WinMM::WAVE_ALLOWSYNC | WinMM::WAVE_MAPPED)
49
+ raise "cannot open wave device: #{ret}" if ret != 0
50
+ if /64/ =~ RUBY_PLATFORM
51
+ @handle, = tmp.unpack("Q!")
52
+ else
53
+ @handle, = tmp.unpack("L!")
54
+ end
55
+ @buffer = ""
56
56
  end
57
57
 
58
58
  def close
59
59
  flush
60
- WinMM.PlaySound(nil, nil, 0)
60
+ WinMM.waveOutClose(@handle)
61
61
  end
62
62
 
63
63
  def flush
64
- if @buf.bytesize >= 0
65
- until WinMM.play_pcm(@buf, sync: false)
66
- sleep 0.1
64
+ if /64/ =~ RUBY_PLATFORM
65
+ x = "Q!"
66
+ else
67
+ x = "L!"
68
+ end
69
+ hdr = [@buffer, @buffer.bytesize, 0, 0, 0, 0, nil, 0].pack("pVV#{x}VVp#{x}")
70
+ @buffer = ""
71
+ ret = WinMM.waveOutPrepareHeader(@handle, hdr, hdr.bytesize)
72
+ raise "error in waveOutPrepareHeader: #{ret}" if ret != 0
73
+ begin
74
+ ret = WinMM.waveOutWrite(@handle, hdr, hdr.bytesize)
75
+ raise "error in waveOutWrite: #{ret}" if ret != 0
76
+ while true
77
+ break if (hdr.unpack("pVV#{x}VVp#{x}")[4] & WinMM::WHDR_DONE) == WinMM::WHDR_DONE
78
+ sleep 0
67
79
  end
80
+ ensure
81
+ WinMM.waveOutUnprepareHeader(@handle, hdr, hdr.bytesize)
68
82
  end
69
- @buf = ""
70
- WinMM.play_pcm("", sync: true)
83
+
84
+ self
71
85
  end
72
86
 
87
+ BUFFER_FLUSH_SEC = 30
73
88
  def write(str)
74
- @buf << str
75
- flush if @buf.bytesize > 8000 * 1 * 1 * 4
89
+ @buffer << str
90
+ flush if @buffer.bytesize >= BUFFER_FLUSH_SEC * rate
91
+ end
92
+
93
+ def rate
94
+ FREQUENCY * (BITS / 8) * CHANNELS
76
95
  end
77
96
 
78
97
  alias binwrite write
@@ -96,3 +115,27 @@ module Kernel
96
115
  end
97
116
  module_function :open
98
117
  end
118
+
119
+ class << IO
120
+ alias windsp_orig_write write
121
+ def write(name, data, offset = nil)
122
+ if name == "/dev/dsp"
123
+ WinDSP.open do |dsp|
124
+ dsp.write(data)
125
+ end
126
+ else
127
+ windsp_orig_binwrite(path, data, offset)
128
+ end
129
+ end
130
+
131
+ alias windsp_orig_binwrite binwrite
132
+ def binwrite(name, data, offset = nil)
133
+ if name == "/dev/dsp"
134
+ WinDSP.open do |dsp|
135
+ dsp.binwrite(data)
136
+ end
137
+ else
138
+ windsp_orig_binwrite(path, data, offset)
139
+ end
140
+ end
141
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: windsp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - U.Nakamura
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-03 00:00:00.000000000 Z
11
+ date: 2015-05-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler