changeset 19510:e1f98e402a7e

New files - @audiorecorder and @audioplayer classes * @audiorecorder: new files implementing methods for the audiorecorder class * @audioplayer: new files implementing methods for the audioplayer class
author Vytautas Jančauskas <unaudio@gmail.com>
date Wed, 11 Sep 2013 22:40:18 +0300
parents b9df6b3fd5ef
children ec76e10c28de
files scripts/@audioplayer/__get_properties__.m scripts/@audioplayer/audioplayer.m scripts/@audioplayer/display.m scripts/@audioplayer/get.m scripts/@audioplayer/isplaying.m scripts/@audioplayer/pause.m scripts/@audioplayer/play.m scripts/@audioplayer/playblocking.m scripts/@audioplayer/resume.m scripts/@audioplayer/set.m scripts/@audioplayer/stop.m scripts/@audioplayer/subsasgn.m scripts/@audioplayer/subsref.m scripts/@audiorecorder/__get_properties__.m scripts/@audiorecorder/audiorecorder.m scripts/@audiorecorder/display.m scripts/@audiorecorder/get.m scripts/@audiorecorder/getaudiodata.m scripts/@audiorecorder/getplayer.m scripts/@audiorecorder/isrecording.m scripts/@audiorecorder/pause.m scripts/@audiorecorder/play.m scripts/@audiorecorder/record.m scripts/@audiorecorder/recordblocking.m scripts/@audiorecorder/resume.m scripts/@audiorecorder/set.m scripts/@audiorecorder/stop.m scripts/@audiorecorder/subsasgn.m scripts/@audiorecorder/subsref.m
diffstat 29 files changed, 740 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/@audioplayer/__get_properties__.m	Wed Sep 11 22:40:18 2013 +0300
@@ -0,0 +1,22 @@
+## -*- texinfo -*-
+## @deftypefn{Function File} @var{Properties} = __get_properties__ (@var{playerObj})
+## For a given audioplayer object this function gathers and returns the current values of all properties.
+## @end deftypefn
+
+function properties = __get_properties__ (player)
+  properties.BitsPerSample = __player_get_nbits__ (struct(player).player);
+  properties.CurrentSample = __player_get_sample_number__ (struct(player).player);
+  properties.DeviceID = __player_get_id__ (struct(player).player);
+  properties.NumberOfChannels = __player_get_channels__ (struct(player).player);
+  if __player_isplaying__ (struct(player).player)
+    running = "on";
+  else
+    running = "off";
+  endif
+  properties.Running = running;
+  properties.SampleRate = __player_get_fs__ (struct (player).player);
+  properties.TotalSamples = __player_get_total_samples__ (struct (player).player);
+  properties.Tag = __player_get_tag__ (struct (player).player);
+  properties.Type = "audioplayer";
+  properties.UserData = __player_get_userdata__ (struct (player).player);
+endfunction
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/@audioplayer/audioplayer.m	Wed Sep 11 22:40:18 2013 +0300
@@ -0,0 +1,175 @@
+## -*- texinfo -*-
+## @deftypefn{Function File} player = audioplayer (@var{Y}, @var{Fs})
+## Create an audioplayer object that will play back data @var{Y} at sample rate @var{Fs}.
+## @deftypefnx{Function File} player = audioplayer (@var{Y}, @var{Fs}, @var{nBytes})
+## Create an audioplayer object that will play back data @var{Y} at sample rate @var{Fs} and bit depth @var{nBytes}.
+## @deftypefnx{Function File} player = audioplayer (@var{Y}, @var{Fs}, @var{nBytes}, @var{ID})
+## Create an audioplayer object that will play back data @var{Y} at sample rate @var{Fs}, bit depth @var{nBytes} and using a device with @var{ID} that you can get using the audiodevinfo function.
+## @deftypefnx{Function File} player = audioplayer (@var{function}, @var{Fs})
+## Argument @var{function} is a function handle, inline function or a string value of a function name that will get called to process audio. Audio will be played at @var{Fs} sampling rate.
+## @deftypefnx{Function File} player = audioplayer (@var{function}, @var{Fs}, @var{nBytes})
+## Same as above but also allows you to specify the number of bytes per sample.
+## @deftypefnx{Function File} player = audioplayer (@var{function}, @var{Fs}, @var{nBytes}, @var{ID})
+## Same as above but also allows you to specify device ID that will be used.
+## @deftypefnx{Function File} player = audioplayer (@var{recorder})
+## Create an audioplayer object that will use data and other information such as sample rate from an audiorecorder object.
+## @deftypefnx{Function File} player = audioplayer (@var{recorder}, @var{ID})
+## Create an audioplayer object that will use data and other information from an audiorecorder object and that will use a device with the given @var{ID}.
+##
+## The signal @var{Y} can be a vector or a two dimensional array.
+##
+## The following example will create an audioplayer object that will play back one second of white noise at 44100 sample rate using 8 bits per sample.
+##
+## @example
+## @group
+## @code{y = randn (2, 44100) - 0.5;}
+## @code{player = audioplayer (y, 44100, 8);}
+## @code{play (player);}
+## @end group
+## @end example
+##
+## The following example will create and register a callback that generates a sine wave on both channels.
+##
+## @example
+## @group
+## @code{function [ sound, status ] = callback_sine (frames)}
+## @code{  global lphase = 0.0;}
+## @code{  global rphase = 0.0;}
+## @code{  incl = 440.0 / 44100.0;}
+## @code{  incr = 443.0 / 44100.0;}
+## @code{  nl = incl * frames;}
+## @code{  nr = incr * frames;}
+## @code{  left = sin (2.0 * pi * [lphase:incl:lphase+nl]);}
+## @code{  right = sin (2.0 * pi * [rphase:incr:rphase+nr]);}
+## @code{  sound = [left', right'];}
+## @code{  status = 0;}
+## @code{  lphase = lphase + nl;}
+## @code{  rphase = rphase + nr;}
+## @code{endfunction}
+## @code{player = audioplayer(@callback_sine, 44100);}
+## @code{play (player);}
+## @code{# play for as long as you want}
+## @code{stop (player);}
+## @end group
+## @end example
+## @end deftypefn
+
+function player = audioplayer (varargin)
+  if (nargin < 1 || nargin > 4)
+    print_usage ();
+  endif
+  if ((isa(varargin{1}, 'function_handle') || ischar(varargin{1})) && nargin < 2)
+    print_usage ();
+  endif
+  if isa (varargin{1}, 'audiorecorder')
+    if nargin == 1
+      player = getplayer(varargin{1});
+    elseif nargin == 2
+      recorder = varargin{1};
+      data = getaudiodata (recorder);
+      player = audioplayer (data, get (recorder, 'SampleRate'), get (recorder, 'BitsPerSample'), varargin{2});    
+    else
+      print_usage ();
+    endif
+  else
+    if ischar(varargin{1})
+      varargin{1} = str2func(varargin{1});
+    endif
+    player.player = __player_audioplayer__ (varargin{:});
+    player = class (player, "audioplayer");
+  endif
+endfunction
+
+%!test
+%!  mono = randn (1, 44100) - 0.5;
+%!  stereo = randn (2, 44100) - 0.5;
+%!  fs = 44100;
+%!  player1 = audioplayer (mono, fs);
+%!  player2 = audioplayer (stereo, fs);
+%!  assert (player1.NumberOfChannels, 1);
+%!  assert (player2.NumberOfChannels, 2);
+%!  assert (player1.SampleRate, 44100);
+%!  assert (player2.SampleRate, 44100);
+%!  assert (player1.TotalSamples, 44100);
+%!  assert (player2.TotalSamples, 44100);
+%!  playblocking (player1);
+%!  playblocking (player2);
+
+%!test
+%!  audio = randn (2, 88200) - 0.5;
+%!  fs = 44100;
+%!  player = audioplayer (audio, fs);
+%!  assert (!isplaying (player));
+%!  play (player);
+%!  assert (isplaying (player));
+%!  sleep (1);
+%!  pause (player);
+%!  assert (!isplaying (player));
+%!  sleep (1);
+%!  resume (player);
+%!  assert (isplaying (player));
+%!  sleep (1);
+
+%!test
+%!  audio = randn (2, 88200) - 0.5;
+%!  fs = 44100;
+%!  player = audioplayer (audio, fs);
+%!  assert (!isplaying (player));
+%!  play (player);
+%!  assert (isplaying (player));
+%!  sleep (1);
+%!  stop (player);
+%!  sleep (1);
+%!  assert (!isplaying (player));
+%!  assert (player.CurrentSample, 0);
+
+%!test
+%!  audio = randn (2, 44100) - 0.5;
+%!  fs = 44100;
+%!  player = audioplayer (audio, fs);
+%!  set (player, {'SampleRate', 'Tag', 'UserData'}, {8000, 'tag', [1, 2; 3, 4]});
+%!  assert (player.SampleRate, 8000);
+%!  assert (player.Tag, 'tag');
+%!  assert (player.UserData, [1, 2; 3, 4]);
+
+%!test
+%!  audio = randn (2, 44100) - 0.5;
+%!  fs = 44100;
+%!  player = audioplayer (audio, fs);
+%!  settable = set (player);
+%!  settable.SampleRate = 8000;
+%!  settable.Tag = 'tag';
+%!  settable.UserData = [1, 2; 3, 4];
+%!  set (player, settable);
+%!  assert (player.SampleRate, 8000);
+%!  assert (player.Tag, 'tag');
+%!  assert (player.UserData, [1, 2; 3, 4]);
+
+%!test
+%!  audio = randn (2, 44100) - 0.5;
+%!  fs = 44100;
+%!  player = audioplayer (audio, fs);
+%!  player.SampleRate = 8000;
+%!  player.Tag = 'tag';
+%!  player.UserData = [1, 2; 3, 4];
+%!  properties = get (player, {'SampleRate', 'Tag', 'UserData'});
+%!  assert (properties, {8000, 'tag', [1, 2; 3, 4]});
+
+%!function [ sound, status ] = callback (samples)
+%!  sound = rand (samples, 2) - 0.5;
+%!  status = 0;
+%!endfunction
+
+%!test
+%!  player = audioplayer (@callback, 44100);
+%!  play (player);
+%!  sleep (2);
+%!  stop (player);
+%!  assert (1);
+
+%!test
+%!  player = audioplayer ("callback", 44100, 16);
+%!  play (player);
+%!  sleep (2);
+%!  stop(player);
+%!  assert (1);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/@audioplayer/display.m	Wed Sep 11 22:40:18 2013 +0300
@@ -0,0 +1,8 @@
+## -*- texinfo -*-
+## @deftypefn{Function File} display (@var{playerObj})
+## Display an audioplayer object.
+## @end deftypefn
+
+function display(player)
+  disp(__get_properties__(player));
+endfunction
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/@audioplayer/get.m	Wed Sep 11 22:40:18 2013 +0300
@@ -0,0 +1,30 @@
+## -*- texinfo -*-
+## @deftypefn{Function File} @var{Value} = get (@var{playerObj}, @var{Name})
+## Returns the @var{Value} of the property identified by @var{Name}.
+## @deftypefnx{Function File} @var{Values} = get (@var{playerObj}, @{@var{Name1}, ... , @var{NameN}@})
+## Returns the @var{Values} of the properties identified by @var{Name1} to @var{NameN}.
+## @deftypefnx{Function File} @var{Values} = get (@var{playerObj})
+## Returns a scalar structure with values of all properties of @var{playerObj}. 
+## The field names correspond to property names.
+## @end deftypefn
+
+function result = get (varargin)
+  player = varargin{1};
+  properties = __get_properties__ (player);
+  if nargin == 1
+    result = properties;
+  elseif nargin == 2
+    if ischar (varargin{2})
+      result = getfield (properties, varargin{2});
+    else
+      result = {};
+      index = 1;
+      for property = varargin{2}
+        result{index} = getfield (properties, char(property));
+        index = index + 1;
+      endfor
+    endif
+  else
+    error ('audioplayer: wrong number of arguments to the get method');
+  endif
+endfunction
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/@audioplayer/isplaying.m	Wed Sep 11 22:40:18 2013 +0300
@@ -0,0 +1,9 @@
+## -*- texinfo -*-
+## @deftypefn{Function File} isplaying (@var{playerObj})
+## Returns 1 if the audioplayer object is currently playing back audio.
+## Returns 0 otherwise.
+## @end deftypefn
+
+function result = isplaying(player)
+    result = __player_isplaying__(struct(player).player);
+endfunction
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/@audioplayer/pause.m	Wed Sep 11 22:40:18 2013 +0300
@@ -0,0 +1,8 @@
+## -*- texinfo -*-
+## @deftypefn{Function File} pause (@var{playerObj})
+## Pause the playback with the possibility of resuming it later at the same place.
+## @end deftypefn
+
+function pause(player)
+    __player_pause__(struct(player).player);
+endfunction
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/@audioplayer/play.m	Wed Sep 11 22:40:18 2013 +0300
@@ -0,0 +1,15 @@
+## -*- texinfo -*-
+## @deftypefn{Function File} play (@var{playerObj})
+## Play back audio stored in an audioplayer object without blocking.
+## @deftypefnx{Function File} play  (@var{playerObj}, @var{start})
+## Play back audio stored in an audioplayer object starting at the time in seconds specified by @var{start}.
+## @deftypefnx{Function File} play (@var{playerObj}, [@var{start}, @var{end}])
+## Play back audio stored in an audioplayer object starting at the time in seconds specified by @var{start} and ending at the time specified by @var{end}.
+## @end deftypefn
+
+function play(varargin)
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif 
+  __player_play__(struct(varargin{1}).player, varargin{2:end});
+endfunction
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/@audioplayer/playblocking.m	Wed Sep 11 22:40:18 2013 +0300
@@ -0,0 +1,15 @@
+## -*- texinfo -*-
+## @deftypefn{Function File} playblocking (@var{playerObj})
+## Play back audio stored in the audioplayer object with blocking.
+## @deftypefnx{Function File} playblocking (@var{playerObj}, @var{start})
+## Play back audio stored in the audioplayer object starting at the time in seconds specified by @var{start}.
+## @deftypefnx{Function File} playblocking (@var{playerObj}, [@var{start}, @var{end}])
+## Play back audio stored in the audioplayer object starting at the time in seconds specified by @var{start} and ending at the time specified by @var{end}.
+## @end deftypefn
+
+function playblocking(varargin)
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif 
+  __player_playblocking__(struct(varargin{1}).player, varargin{2:end});
+endfunction
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/@audioplayer/resume.m	Wed Sep 11 22:40:18 2013 +0300
@@ -0,0 +1,8 @@
+## -*- texinfo -*-
+## @deftypefn{Function File} resume (@var{playerObj})
+## Resume playback for a previously paused audioplayer object.
+## @end deftypefn
+
+function resume(player)
+    __player_resume__(struct(player).player);
+endfunction
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/@audioplayer/set.m	Wed Sep 11 22:40:18 2013 +0300
@@ -0,0 +1,51 @@
+## -*- texinfo -*-
+## @deftypefn{Function File} set (@var{playerObj}, @var{Name}, @var{Value})
+## Set the value of property specified by @var{Name} to a given @var{Value}.
+## @deftypefnx{Function File} set (@var{playerObj}, @var{CellOfNames}, @var{CellOfValues})
+## Given a cell array of property names and a cell array of values, set each property to a corresponding value.
+## @deftypefnx{Function File} set (@var{playerObj}, @var{StructOfProperties})
+## Given a structure where fields are property names, set the value of those properties for an audioplayer object to corresponding values.
+## @deftypefnx{Function File} @var{settableProperties} = set (@var{playerObj})
+## Returns a structure of settable properties.
+## @end deftypefn
+
+function settable = set (varargin)
+  if nargin < 1 || nargin > 3
+    print_usage();
+  endif
+  player = struct (varargin{1}).player;
+  if nargin == 1
+    settable.SampleRate = {};
+    settable.Tag = {};
+    settable.UserData = {};
+  elseif nargin == 2
+    for [value, property] = varargin{2}
+      setproperty (player, property, value);
+    endfor
+  elseif nargin == 3
+    if iscell (varargin{2})
+      index = 1;
+      for property = varargin{2}
+        setproperty (player, char(property), varargin{3}{index});
+        index = index + 1;
+      endfor
+    else
+      setproperty (player, varargin{2}, varargin{3});
+    endif
+  else
+    error ('audioplayer: wrong number of arguments to the set method');
+  endif
+endfunction
+
+function setproperty (player, property, value)
+  switch property
+    case 'SampleRate'
+      __player_set_fs__ (player, value);
+    case 'Tag'
+      __player_set_tag__ (player, value);
+    case 'UserData'
+      __player_set_userdata__ (player, value);
+    otherwise
+      error ('audioplayer: no such property or the property specified is read-only');
+  endswitch
+endfunction
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/@audioplayer/stop.m	Wed Sep 11 22:40:18 2013 +0300
@@ -0,0 +1,8 @@
+## -*- texinfo -*-
+## @deftypefn{Function File} stop (@var{playerObj})
+## Stop the playback and reset the relevant variables to their starting values.
+## @end deftypefn
+
+function stop(player)
+    __player_stop__(struct(player).player);
+endfunction
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/@audioplayer/subsasgn.m	Wed Sep 11 22:40:18 2013 +0300
@@ -0,0 +1,12 @@
+function value = subsasgn(player, idx, rhs)
+  if (isempty (idx))
+    error ("audioplayer: missing index");
+  endif
+  if (strcmp(idx(1).type, "."))
+    field = idx.subs;
+    set(player, field, rhs);
+    value = player;
+  else
+    error ("audioplayer: invalid subscript type");
+  endif
+endfunction
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/@audioplayer/subsref.m	Wed Sep 11 22:40:18 2013 +0300
@@ -0,0 +1,11 @@
+function value = subsref(player, idx)
+  if (isempty (idx))
+    error ("audioplayer: missing index");
+  endif
+  if (strcmp(idx(1).type, "."))
+    field = idx.subs;
+    value = get(player, field);
+  else
+    error ("audioplayer: invalid subscript file")
+  endif
+endfunction
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/@audiorecorder/__get_properties__.m	Wed Sep 11 22:40:18 2013 +0300
@@ -0,0 +1,17 @@
+function properties = __get_properties__ (recorder)
+  properties.BitsPerSample = __recorder_get_nbits__ (struct(recorder).recorder);
+  properties.CurrentSample = __recorder_get_sample_number__ (struct(recorder).recorder);
+  properties.DeviceID = __recorder_get_id__ (struct(recorder).recorder);
+  properties.NumberOfChannels = __recorder_get_channels__ (struct(recorder).recorder);
+  if __recorder_isrecording__ (struct(recorder).recorder)
+    running = "on";
+  else
+    running = "off";
+  endif
+  properties.Running = running;
+  properties.SampleRate = __recorder_get_fs__ (struct (recorder).recorder);
+  properties.TotalSamples = __recorder_get_total_samples__ (struct (recorder).recorder);
+  properties.Tag = __recorder_get_tag__ (struct (recorder).recorder);
+  properties.Type = "audiorecorder";
+  properties.UserData = __recorder_get_userdata__ (struct (recorder).recorder);
+endfunction
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/@audiorecorder/audiorecorder.m	Wed Sep 11 22:40:18 2013 +0300
@@ -0,0 +1,113 @@
+## -*- texinfo -*-
+## @deftypefn{Function File} recorder = audiorecorder
+## Create an audiorecorder object recording 8 bit mono audio at 8000 Hz sample rate.
+## @deftypefnx{Function File} recorder = audiorecorder (@var{Fs}, @var{nBytes}, @var{Channels})
+## Create an audiorecorder object recording at specified sample rate @var{Fs}, specified bit depth @var{nBytes} and specified number of @var{Channels}.
+## @deftypefnx{Function File} recorder = audiorecorder (@var{Fs}, @var{nBytes}, @var{Channels}, @var{ID})
+## Create an audiorecorder object recording at specified sample rate @var{Fs}, specified bit depth @var{nBytes}, number of @var{Channels} and recording on the device specified by @var{ID}. You can get device IDs by using the audiodevinfo function.
+## @deftypefnx{Function File} recorder = audiorecorder (@var{function}, @var{Fs})
+## Argument @var{function} is a function handle, inline function or a string value of a function name that will get called to process audio. Audio will be recorded at @var{Fs} sampling rate.
+## @deftypefnx{Function File} recorder = audiorecorder (@var{function}, @var{Fs}, @var{nBytes})
+## Same as above but also allows you to specify the number of bytes per sample.
+## @deftypefnx{Function File} recorder = audiorecorder (@var{function}, @var{Fs}, @var{nBytes}, @var{ID})
+## Same as above but also allows you to specify device ID that will be used.
+## @end deftypefn
+
+function recorder = audiorecorder (varargin)
+  if (nargin > 5)
+    print_usage ();
+  endif
+  if nargin > 0 && ischar(varargin{1})
+    varargin{1} = str2func(varargin{1});
+  endif
+  recorder.recorder = __recorder_audiorecorder__ (varargin{:});
+  recorder = class (recorder, "audiorecorder");
+endfunction
+
+%!test
+%!  recorder = audiorecorder (44100, 16, 2);
+%!  recordblocking (recorder, 1);
+%!  data = getaudiodata (recorder, 'int16');
+%!  assert (strcmp (class (data), 'int16'));
+%!  data = getaudiodata (recorder, 'int8');
+%!  assert (strcmp (class (data), 'int8'));
+%!  data = getaudiodata (recorder, 'uint8');
+%!  assert (strcmp (class (data), 'uint8'));
+%!  assert (size (data)(1), recorder.TotalSamples);
+%!  assert (size (data)(2), 2);
+%!  assert (size (data)(1) != 0);
+
+%!test
+%!  recorder = audiorecorder (44100, 16, 2);
+%!  record (recorder, 1)
+%!  sleep (2);
+%!  record (recorder, 1);
+%!  sleep (2);
+%!  data = getaudiodata(recorder);
+%!  assert (size (data)(1) < 44100 * 2);
+
+%!test
+%!  recorder = audiorecorder (44100, 16, 2);
+%!  record (recorder, 1);
+%!  sleep (2);
+%!  player1 = audioplayer (recorder);
+%!  player2 = getplayer (recorder);
+%!  play (player1);
+%!  sleep (2);
+%!  play (player2);
+%!  sleep (2);
+%!  assert (player1.TotalSamples, recorder.TotalSamples);
+%!  assert (player2.TotalSamples, recorder.TotalSamples);
+
+%!test
+%!  recorder = audiorecorder;
+%!  set (recorder, {'SampleRate', 'Tag', 'UserData'}, {8000, 'tag', [1, 2; 3, 4]});
+%!  assert (recorder.SampleRate, 8000);
+%!  assert (recorder.Tag, 'tag');
+%!  assert (recorder.UserData, [1, 2; 3, 4]);
+
+%!test
+%!  recorder = audiorecorder;
+%!  settable = set (recorder);
+%!  settable.SampleRate = 8000;
+%!  settable.Tag = 'tag';
+%!  settable.UserData = [1, 2; 3, 4];
+%!  set (recorder, settable);
+%!  assert (recorder.SampleRate, 8000);
+%!  assert (recorder.Tag, 'tag');
+%!  assert (recorder.UserData, [1, 2; 3, 4]);
+
+%!test
+%!  recorder = audiorecorder;
+%!  recorder.SampleRate = 8000;
+%!  recorder.Tag = 'tag';
+%!  recorder.UserData = [1, 2; 3, 4];
+%!  properties = get (recorder, {'SampleRate', 'Tag', 'UserData'});
+%!  assert (properties, {8000, 'tag', [1, 2; 3, 4]});
+
+#%!function status = callback_record (sound)
+#%!  fid = fopen('record.txt', 'at');
+#%!  for index = 1:rows(sound)
+#%!    fprintf(fid, "%.4f, %.4f\n", sound(index, 1), sound(index, 2));
+#%!  endfor
+#%!  fclose(fid);
+#%!  status = 0;
+#%!endfunction
+
+#%!test
+#%!  recorder = audiorecorder (@callback_record, 44100);
+#%!  unlink('record.txt')
+#%!  record (recorder);
+#%!  sleep (2);
+#%!  stop (player);
+#%!  s = stat('record.txt');
+#%!  assert (s.size > 0);
+
+#%!test
+#%!  recorder = audiorecorder (@callback_record, 44100);
+#%!  unlink('record.txt')
+#%!  record (recorder);
+#%!  sleep (2);
+#%!  stop (recorder);
+#%!  s = stat('record.txt');
+#%!  assert (s.size > 0);
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/@audiorecorder/display.m	Wed Sep 11 22:40:18 2013 +0300
@@ -0,0 +1,8 @@
+## -*- texinfo -*-
+## @deftypefn{Function File} display (@var{recorderObj})
+## Display an audiorecorder object.
+## @end deftypefn
+
+function display(recorder)
+  disp(__get_properties__(recorder));
+endfunction
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/@audiorecorder/get.m	Wed Sep 11 22:40:18 2013 +0300
@@ -0,0 +1,30 @@
+## -*- texinfo -*-
+## @deftypefn{Function File} @var{Value} = get (@var{recorderObj}, @var{Name})
+## Returns the @var{Value} of the property identified by @var{Name}.
+## @deftypefnx{Function File} @var{Values} = get (@var{recorderObj}, @{@var{Name1}, ... , @var{NameN}@})
+## Returns the @var{Values} of the properties identified by @var{Name1} to @var{NameN}.
+## @deftypefnx{Function File} @var{Values} = get (@var{recorderObj})
+## Returns a scalar structure with values of all properties of @var{recorderObj}. 
+## The field names correspond to property names.
+## @end deftypefn
+
+function result = get (varargin)
+  recorder = varargin{1};
+  properties = __get_properties__ (recorder);
+  if nargin == 1
+    result = properties;
+  elseif nargin == 2
+    if ischar (varargin{2})
+      result = getfield (properties, varargin{2});
+    else
+      result = {};
+      index = 1;
+      for property = varargin{2}
+        result{index} = getfield (properties, char(property));
+        index = index + 1;
+      endfor
+    endif
+  else
+    error ('audiorecorder: wrong number of arguments to the get method');
+  endif
+endfunction
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/@audiorecorder/getaudiodata.m	Wed Sep 11 22:40:18 2013 +0300
@@ -0,0 +1,33 @@
+## -*- texinfo -*-
+## @deftypefn{Function File} getaudiodata (@var{recorderObj})
+## Returns recorder audio data as a Matrix with values between -1.0 and 1.0 and with as many columns as there are channels in the recorder.
+## @deftypefnx{Function File} getaudiodata (@var{recorderObj}, @var{dataType})
+## Converts recorded data to specified @var{dataType}. It can be set to 'double',
+## 'single', 'int16', 'int8' or 'uint8'.
+## @end deftypefn
+
+function data = getaudiodata(varargin)
+    if (nargin < 1 || nargin > 2)
+      print_usage ();
+    endif
+    recorder = varargin{1};
+    if (nargin == 1)
+      data = __recorder_getaudiodata__(struct(recorder).recorder);
+    else
+      data = __recorder_getaudiodata__(struct(recorder).recorder);
+      type = varargin{2};
+      switch type
+        case 'int16'
+          data = int16(data * (2.0 ^ 15));
+        case 'int8'
+          data = int8(data * (2.0 ^ 7));
+        case 'uint8'
+          data = uint8((data + 1.0) * 0.5 * (2.0 ^ 8 - 1));
+      endswitch
+    endif
+    if get(recorder, 'NumberOfChannels') == 2
+      data = data';
+    else
+      data = data(1,:)';
+    endif
+endfunction
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/@audiorecorder/getplayer.m	Wed Sep 11 22:40:18 2013 +0300
@@ -0,0 +1,13 @@
+## -*- texinfo -*-
+## @deftypefn{Function File} getplayer (@var{recorderObj})
+## Returns an audioplayer object with data recorded by the recorder.
+## @end deftypefn
+
+function player = getplayer(varargin)
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif 
+  recorder = varargin{1};
+  data = getaudiodata(recorder);
+  player = audioplayer(data, get(recorder, 'SampleRate'), get(recorder, 'BitsPerSample'));
+endfunction
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/@audiorecorder/isrecording.m	Wed Sep 11 22:40:18 2013 +0300
@@ -0,0 +1,9 @@
+## -*- texinfo -*-
+## @deftypefn{Function File} isrecording (@var{recorderObj})
+## Returns 1 if the audiorecorder object is currently recording audio.
+## Returns 0 otherwise.
+## @end deftypefn
+
+function result = isrecording(recorder)
+    result = __recorder_isrecording__(struct(recorder).recorder);
+endfunction
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/@audiorecorder/pause.m	Wed Sep 11 22:40:18 2013 +0300
@@ -0,0 +1,8 @@
+## -*- texinfo -*-
+## @deftypefn{Function File} pause (@var{recorderObj})
+## Pause recording with the possibility of resuming it later.
+## @end deftypefn
+
+function pause(recorder)
+    __recorder_pause__(struct(recorder).recorder);
+endfunction
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/@audiorecorder/play.m	Wed Sep 11 22:40:18 2013 +0300
@@ -0,0 +1,22 @@
+## -*- texinfo -*-
+## @deftypefn{Function File} player = play (@var{recorderObj})
+## Play the audio recorded in @var{recorderObj} and return a corresponding audioplayer object.
+## @deftypefnx{Function File} player = play (@var{recorderObj}, start)
+## Play the audio recorded in @var{recorderObj} starting from @var{start} seconds in to the recording. Returns a corresponding audioplayer object.
+## @deftypefnx{Function File} player = play (@var{recorderObj}, [start, end])
+## Play the audio recorded in @var{recorderObj} starting from @var{start} seconds and ending at @var{end} seconds in the recording. Returns a corresponding audioplayer object.
+## @end deftypefn
+
+function player = play(varargin)
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif 
+  recorder = varargin{1};
+  data = getaudiodata(recorder);
+  player = audioplayer(data, get(recorder, 'SampleRate'), get(recorder, 'BitsPerSample'));
+  if (nargin == 1)
+    play(player);
+  else
+    play(player, varargin{2});
+  endif
+endfunction
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/@audiorecorder/record.m	Wed Sep 11 22:40:18 2013 +0300
@@ -0,0 +1,13 @@
+## -*- texinfo -*-
+## @deftypefn{Function File} record (@var{recorderObj})
+## Record audio without blocking. The recording will continue until you use the stop method on @var{recorderObj}.
+## @deftypefnx{Function File} record (@var{playerObj}, @var{length})
+## Record audio without blocking. The recording will continue for @var{length} seconds.
+## @end deftypefn
+
+function record(varargin)
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif 
+  __recorder_record__(struct(varargin{1}).recorder, varargin{2:end});
+endfunction
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/@audiorecorder/recordblocking.m	Wed Sep 11 22:40:18 2013 +0300
@@ -0,0 +1,12 @@
+## -*- texinfo -*-
+## @deftypefn{Function File} recordblocking (@var{recorderObj}, @var{length})
+## Record audio with blocking (synchronous I/O). You must specify the number of seconds
+## that the recording will continue for.
+## @end deftypefn
+
+function recordblocking(varargin)
+  if (nargin != 2)
+    print_usage ();
+  endif 
+  __recorder_recordblocking__(struct(varargin{1}).recorder, varargin{2});
+endfunction
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/@audiorecorder/resume.m	Wed Sep 11 22:40:18 2013 +0300
@@ -0,0 +1,8 @@
+## -*- texinfo -*-
+## @deftypefn{Function File} resume (@var{recorderObj})
+## Will resume recording if pause was used before on @var{recorderObj}.
+## @end deftypefn
+
+function resume(recorder)
+    __recorder_resume__(struct(recorder).recorder);
+endfunction
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/@audiorecorder/set.m	Wed Sep 11 22:40:18 2013 +0300
@@ -0,0 +1,51 @@
+## -*- texinfo -*-
+## @deftypefn{Function File} set (@var{recorderObj}, @var{Name}, @var{Value})
+## Set the value of property specified by @var{Name} to a given @var{Value}.
+## @deftypefnx{Function File} set (@var{recorderObj}, @var{CellOfNames}, @var{CellOfValues})
+## Given a cell array of property names and a cell array of values, set each property to a corresponding value.
+## @deftypefnx{Function File} set (@var{recorderObj}, @var{StructOfProperties})
+## Given a structure where fields are property names, set the value of those properties for an audiorecorder object to corresponding values.
+## @deftypefnx{Function File} @var{settableProperties} = set (@var{recorderObj})
+## Returns a structure of settable properties.
+## @end deftypefn
+
+function settable = set (varargin)
+  if nargin < 1 || nargin > 3
+    print_usage();
+  endif
+  recorder = struct (varargin{1}).recorder;
+  if nargin == 1
+    settable.SampleRate = {};
+    settable.Tag = {};
+    settable.UserData = {};
+  elseif nargin == 2
+    for [value, property] = varargin{2}
+      setproperty (recorder, property, value);
+    endfor
+  elseif nargin == 3
+    if iscell (varargin{2})
+      index = 1;
+      for property = varargin{2}
+        setproperty (recorder, char(property), varargin{3}{index});
+        index = index + 1;
+      endfor
+    else
+      setproperty (recorder, varargin{2}, varargin{3});
+    endif
+  else
+    error ('audiorecorder: wrong number of arguments to the set method');
+  endif
+endfunction
+
+function setproperty (recorder, property, value)
+  switch property
+    case 'SampleRate'
+      __recorder_set_fs__ (recorder, value);
+    case 'Tag'
+      __recorder_set_tag__ (recorder, value);
+    case 'UserData'
+      __recorder_set_userdata__ (recorder, value);
+    otherwise
+      error ('audiorecorder: no such property or the property specified is read-only');
+  endswitch
+endfunction
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/@audiorecorder/stop.m	Wed Sep 11 22:40:18 2013 +0300
@@ -0,0 +1,8 @@
+## -*- texinfo -*-
+## @deftypefn{Function File} stop (@var{recorderObj})
+## Will stop recording, clean up any audio streams.
+## @end deftypefn
+
+function stop(recorder)
+    __recorder_stop__(struct(recorder).recorder);
+endfunction
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/@audiorecorder/subsasgn.m	Wed Sep 11 22:40:18 2013 +0300
@@ -0,0 +1,12 @@
+function value = subsasgn(recorder, idx, rhs)
+  if (isempty (idx))
+    error ("audiorecorder: missing index");
+  endif
+  if (strcmp(idx(1).type, "."))
+    field = idx.subs;
+    set(recorder, field, rhs);
+    value = recorder;
+  else
+    error ("audiorecorder: invalid subscript type");
+  endif
+endfunction
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/@audiorecorder/subsref.m	Wed Sep 11 22:40:18 2013 +0300
@@ -0,0 +1,11 @@
+function value = subsref(recorder, idx)
+  if (isempty (idx))
+    error ("audiorecorder: missing index");
+  endif
+  if (strcmp(idx(1).type, "."))
+    field = idx.subs;
+    value = get(recorder, field);
+  else
+    error ("audiorecorder: invalid subscript file")
+  endif
+endfunction
\ No newline at end of file