Module: Sound::DeviceLibrary::ALSA

Extended by:
FFI::Library, ALSA
Included in:
ALSA
Defined in:
lib/sound/device_library/alsa.rb

Defined Under Namespace

Classes: Handle

Constant Summary collapse

SND_PCM_STREAM_PLAYBACK =
0
SND_PCM_STREAM_CAPTURE =
1
DEFAULT_DEVICE_ID =
"default"
SND_PCM_ASYNC =
2
ASYNC =
SND_PCM_ASYNC
SND_PCM_FORMAT_UNKNOWN =

snd_pcm formats Unknown

-1
# Signed 8 bit
SND_PCM_FORMAT_S8 =

Signed 8 bit

0
SND_PCM_FORMAT_U8 =

Unsigned 8 bit

1
SND_PCM_FORMAT_S16_LE =

Signed 16 bit Little Endian

2
SND_PCM_FORMAT_S16_BE =

Signed 16 bit Big Endian

3
SND_PCM_FORMAT_U16_LE =

Unsigned 16 bit Little Endian

4
SND_PCM_FORMAT_U16_BE =

Unsigned 16 bit Big Endian

5
SND_PCM_FORMAT_S24_LE =

Signed 24 bit Little Endian using low three bytes in 32-bit word

6
SND_PCM_FORMAT_S24_BE =

Signed 24 bit Big Endian using low three bytes in 32-bit word

7
SND_PCM_FORMAT_U24_LE =

Unsigned 24 bit Little Endian using low three bytes in 32-bit word

8
SND_PCM_FORMAT_U24_BE =

Unsigned 24 bit Big Endian using low three bytes in 32-bit word

9
SND_PCM_FORMAT_S32_LE =

Signed 32 bit Little Endian

10
SND_PCM_FORMAT_S32_BE =

Signed 32 bit Big Endian

11
SND_PCM_FORMAT_U32_LE =

Unsigned 32 bit Little Endian

12
SND_PCM_FORMAT_U32_BE =

Unsigned 32 bit Big Endian

13
SND_PCM_FORMAT_FLOAT_LE =

Float 32 bit Little Endian, Range -1.0 to 1.0

14
SND_PCM_FORMAT_FLOAT_BE =

Float 32 bit Big Endian, Range -1.0 to 1.0

15
SND_PCM_FORMAT_FLOAT64_LE =

Float 64 bit Little Endian, Range -1.0 to 1.0

16
SND_PCM_FORMAT_FLOAT64_BE =

Float 64 bit Big Endian, Range -1.0 to 1.0

17
SND_PCM_FORMAT_IEC958_SUBFRAME_LE =

IEC-958 Little Endian

18
SND_PCM_FORMAT_IEC958_SUBFRAME_BE =

IEC-958 Big Endian

19
SND_PCM_FORMAT_MU_LAW =

Mu-Law

20
SND_PCM_FORMAT_A_LAW =

A-Law

21
SND_PCM_FORMAT_IMA_ADPCM =

Ima-ADPCM

22
SND_PCM_FORMAT_MPEG =

MPEG

23
SND_PCM_FORMAT_GSM =

GSM

24
SND_PCM_FORMAT_SPECIAL =

Special

31
SND_PCM_FORMAT_S24_3LE =

Signed 24bit Little Endian in 3bytes format

32
SND_PCM_FORMAT_S24_3BE =

Signed 24bit Big Endian in 3bytes format

33
SND_PCM_FORMAT_U24_3LE =

Unsigned 24bit Little Endian in 3bytes format

34
SND_PCM_FORMAT_U24_3BE =

Unsigned 24bit Big Endian in 3bytes format

35
SND_PCM_FORMAT_S20_3LE =

Signed 20bit Little Endian in 3bytes format

36
SND_PCM_FORMAT_S20_3BE =

Signed 20bit Big Endian in 3bytes format

37
SND_PCM_FORMAT_U20_3LE =

Unsigned 20bit Little Endian in 3bytes format

38
SND_PCM_FORMAT_U20_3BE =

Unsigned 20bit Big Endian in 3bytes format

39
SND_PCM_FORMAT_S18_3LE =

Signed 18bit Little Endian in 3bytes format

40
SND_PCM_FORMAT_S18_3BE =

Signed 18bit Big Endian in 3bytes format

41
SND_PCM_FORMAT_U18_3LE =

Unsigned 18bit Little Endian in 3bytes format

42
SND_PCM_FORMAT_U18_3BE =

Unsigned 18bit Big Endian in 3bytes format

43
SND_PCM_FORMAT_LAST =
SND_PCM_FORMAT_U18_3BE
SND_PCM_ACCESS_MMAP_INTERLEAVED =

snd_pcm access mmap access with simple interleaved channels

0
SND_PCM_ACCESS_MMAP_NONINTERLEAVED =

mmap access with simple non interleaved channels

1
SND_PCM_ACCESS_MMAP_COMPLEX =

mmap access with complex placement

2
SND_PCM_ACCESS_RW_INTERLEAVED =

snd_pcm_readi/snd_pcm_writei access

3
SND_PCM_ACCESS_RW_NONINTERLEAVED =

snd_pcm_readn/snd_pcm_writen access

4
SND_PCM_ACCESS_LAST =
SND_PCM_ACCESS_RW_NONINTERLEAVED

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.snd_pcm_open(*args) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
# File 'lib/sound/device_library/alsa.rb', line 43

def self.snd_pcm_open(*args)
  output = `aplay -l 2>&1`
  if output.match(/no soundcard/m)
    raise NoDeviceError, "No sound devices present"
  elsif output.match(/not found/m)
    raise NoDependencyError,
      "aplay is not present in your environment. Install alsa-utils package for audio playback."
  else
    snd_pcm_open(*args)
  end
end

Instance Method Details

#allocate_param_memoryObject



111
112
113
# File 'lib/sound/device_library/alsa.rb', line 111

def allocate_param_memory
  snd_pcm_hw_params_malloc(params_handle.pointer)
end

#alter_allocated_param_memoryObject



119
120
121
122
123
# File 'lib/sound/device_library/alsa.rb', line 119

def alter_allocated_param_memory
  set_up_to_change_any_params
  modify_desired_params
  set_params_on_hw_buffer
end

#buffer_lengthObject



89
90
91
# File 'lib/sound/device_library/alsa.rb', line 89

def buffer_length
  Thread.current[:buffer_length] ||= data_buffer.size/2
end

#close_deviceObject



81
82
83
# File 'lib/sound/device_library/alsa.rb', line 81

def close_device
  snd_pcm_close(handle.id) unless Sound.no_device
end

#dataObject



97
98
99
# File 'lib/sound/device_library/alsa.rb', line 97

def data
  Thread.current[:data] ||= Sound::Data.new
end

#data_bufferObject



101
102
103
# File 'lib/sound/device_library/alsa.rb', line 101

def data_buffer
  Thread.current[:data_buffer] ||= FFI::MemoryPointer.new(:int, data.pcm_data.size).write_array_of_int data.pcm_data
end

#free_param_memoryObject



115
116
117
# File 'lib/sound/device_library/alsa.rb', line 115

def free_param_memory
  snd_pcm_hw_params_free(params_handle.id)
end

#handleObject



93
94
95
# File 'lib/sound/device_library/alsa.rb', line 93

def handle
  Thread.current[:handle] ||= Handle.new
end

#modify_desired_paramsObject



129
130
131
132
133
134
135
136
# File 'lib/sound/device_library/alsa.rb', line 129

def modify_desired_params
  # I think these can happen in any order
  snd_pcm_hw_params_set_access(handle.id, params_handle.id, SND_PCM_ACCESS_RW_INTERLEAVED)
  snd_pcm_hw_params_set_format(handle.id, params_handle.id, SND_PCM_FORMAT_S16_LE)
   # need to change this to set_rate_near at some point
  snd_pcm_hw_params_set_rate(handle.id, params_handle.id, data.format.sample_rate, 0)
  snd_pcm_hw_params_set_channels(handle.id, params_handle.id, data.format.channels)
end

#open_device(device) ⇒ Object



55
56
57
58
59
60
61
# File 'lib/sound/device_library/alsa.rb', line 55

def open_device(device)
  begin
    self.snd_pcm_open(handle.pointer, device.id, 0, ASYNC)
  rescue NoDeviceError
    Sound.no_device = true
  end
end

#params_handleObject



85
86
87
# File 'lib/sound/device_library/alsa.rb', line 85

def params_handle
  Thread.current[:params_handle] ||= Handle.new
end

#prepare_bufferObject



63
64
65
66
67
68
69
70
71
# File 'lib/sound/device_library/alsa.rb', line 63

def prepare_buffer
  
  unless Sound.no_device
    buffer_length
    set_params
    snd_pcm_prepare(handle.id)
  end
  
end

#set_paramsObject



105
106
107
108
109
# File 'lib/sound/device_library/alsa.rb', line 105

def set_params
  allocate_param_memory
  alter_allocated_param_memory
  free_param_memory
end

#set_params_on_hw_bufferObject



138
139
140
# File 'lib/sound/device_library/alsa.rb', line 138

def set_params_on_hw_buffer
  snd_pcm_hw_params(handle.id, params_handle.id)
end

#set_up_to_change_any_paramsObject



125
126
127
# File 'lib/sound/device_library/alsa.rb', line 125

def set_up_to_change_any_params
  snd_pcm_hw_params_any(handle.id, params_handle.id)
end

#unprepare_bufferObject



77
78
79
# File 'lib/sound/device_library/alsa.rb', line 77

def unprepare_buffer
  snd_pcm_drain(handle.id) unless Sound.no_device
end

#write_to_deviceObject



73
74
75
# File 'lib/sound/device_library/alsa.rb', line 73

def write_to_device
  snd_pcm_writei(handle.id, data_buffer, buffer_length) unless Sound.no_device
end