]*>.*')
tag_match5 = re.compile(r'.*
]*>.*')
index_match = re.compile(r'.*
]*>[\d\.\s]*(?P[^<]+)
.*')
index_match2 = re.compile(r'.*
]*>[\d\.\s]*(?P[^<]+)<.*')
tag = "top"
has_h2 = False
has_h3 = False
has_h4 = False
#pat_match = re.compile(r'.*(?P[.]+)$')
with open(name + ".html", 'rt') as fin:
with open(name + ".qhp", 'wt') as f:
f.write('\n')
f.write('\n')
f.write(' octave.community.{}\n'.format(name))
f.write(' doc\n')
f.write(' \n')
f.write(' \n')
f.write(' \n'.format(title, name))
# chapters here
for line in fin:
line = line.strip()
e = tag_match1.match(line)
if not e:
e = tag_match2.match(line)
if not e:
e = tag_match3.match(line)
if not e:
e = tag_match4.match(line)
if not e:
e = tag_match5.match(line)
if e:
tag = e.group("tag")
e = h2_match.match(line)
if not e:
e = h2a_match.match(line)
if not e:
e = h2i_match.match(line)
if e:
if has_h4:
f.write(' \n')
has_h4 = False
if has_h3:
f.write(' \n')
has_h3 = False
if has_h2:
f.write(' \n')
has_h2 = True
f.write(' \n'.format(e.group("title"), name, tag))
e = h3_match.match(line)
if e:
if has_h4:
f.write(' \n')
has_h4 = False
if has_h3:
f.write(' \n')
has_h3 = True
f.write(' \n'.format(e.group("title"), name, tag))
e = h4_match.match(line)
if e:
if has_h4:
f.write(' \n')
has_h4 = True
#f.write(' \n'.format(e.group("title"), name, tag))
f.write(' \n'.format(e.group("title"), name, tag))
e = h5_match.match(line)
if e:
f.write(' \n'.format(e.group("title"), name, tag))
if has_h4:
f.write(' \n')
if has_h3:
f.write(' \n')
if has_h2:
f.write(' \n')
f.write(' \n')
f.write(' \n')
f.write(' \n')
fin.seek(0)
for line in fin:
line = line.strip()
e = tag_match1.match(line)
if not e:
e = tag_match2.match(line)
if e:
tag = e.group("tag")
e = index_match.match(line)
if not e:
e = index_match2.match(line)
if e:
f.write(' \n'.format(e.group("name"), name, tag))
f.write(' \n')
f.write(' \n')
f.write(' {}.html\n'.format(name))
# include octave.css if we have it
if os.path.exists("octave.css"):
f.write(' octave.css\n')
if os.path.exists("{}.css".format(name)):
f.write(' {}.css\n'.format(name))
f.write(' \n')
f.write(' \n')
f.write('\n')
def show_usage():
print (sys.argv[0], "projname")
if __name__ == "__main__":
if len(sys.argv) > 1:
status = process(sys.argv[1])
sys.exit(status)
else:
show_usage()
gnu-octave-octave-audio-125c0f5/doc/octave.css 0000664 0000000 0000000 00000014442 15135415131 0021233 0 ustar 00root root 0000000 0000000 /*
Copyright (C) 2016-2026 The Octave Project Developers
See the file COPYRIGHT.md in the top-level directory of this
distribution or .
This file is part of Octave.
Octave is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Octave is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Octave; see the file COPYING. If not, see
.
*/
/* Import web font Roboto Condensed, Font Library Version 2015-06-06 */
@font-face {
font-family: 'Roboto Condensed';
src: local('Roboto Condensed Bold'),
local('RobotoCondensed-Bold'),
url('https://fontlibrary.org/assets/fonts/roboto-condensed/71405335c70332d94afd24ae4f06c9b2/4b8b4b377e8cb358cf886d13c7bb287c/RobotoCondensedBold.ttf') format('truetype');
font-weight: bold;
font-style: normal; }
@font-face
{
font-family: 'Roboto Condensed';
src: local('Roboto Condensed Bold Italic'),
local('RobotoCondensed-BoldItalic'),
url('https://fontlibrary.org/assets/fonts/roboto-condensed/71405335c70332d94afd24ae4f06c9b2/9b1d05d1b332e5b95ad86e71ca8404fb/RobotoCondensedBoldItalic.ttf') format('truetype');
font-weight: bold;
font-style: italic;
}
@font-face
{
font-family: 'Roboto Condensed';
src: local('Roboto Condensed Italic'),
local('RobotoCondensed-Italic'),
url('https://fontlibrary.org/assets/fonts/roboto-condensed/71405335c70332d94afd24ae4f06c9b2/d02fffb6890e4f28023dd149916d1b8a/RobotoCondensedItalic.ttf') format('truetype');
font-weight: normal;
font-style: italic;
}
@font-face
{
font-family: 'Roboto Condensed';
src: local('Roboto Condensed Regular'),
local('RobotoCondensed-Regular'),
url('https://fontlibrary.org/assets/fonts/roboto-condensed/71405335c70332d94afd24ae4f06c9b2/b0b1845ecce8ab6a503971e808a8409c/RobotoCondensedRegular.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
/* Import web font Fantasque Sans Mono, Font Library Version 2016-04-05 */
@font-face
{
font-family: 'Fantasque Sans Mono', FreeMono, 'Courier New', Cousine, Courier, monospace;
src: local('Fantasque Sans Mono Bold'),
local('FantasqueSansMono-Bold'),
url('https://fontlibrary.org/assets/fonts/fantasque-sans-mono/b0cbb25e73a9f8354e96d89524f613e7/a46033d3a07d9385620dc83b7655203f/FantasqueSansMonoBold.ttf') format('truetype');
font-weight: bold;
font-style: normal;
}
@font-face
{
font-family: 'Fantasque Sans Mono', FreeMono, 'Courier New', Cousine, Courier, 'monospace';
src: local('Fantasque Sans Mono Bold Italic'),
local('FantasqueSansMono-BoldItalic'),
url('https://fontlibrary.org/assets/fonts/fantasque-sans-mono/b0cbb25e73a9f8354e96d89524f613e7/b0683ef4c834908aa372ec78dea42349/FantasqueSansMonoBoldItalic.ttf') format('truetype');
font-weight: bold;
font-style: italic;
}
@font-face
{
font-family: 'Fantasque Sans Mono', FreeMono, 'Courier New', Cousine, Courier, monospace;
src: local('Fantasque Sans Mono Italic'),
local('FantasqueSansMono-Italic'),
url('https://fontlibrary.org/assets/fonts/fantasque-sans-mono/b0cbb25e73a9f8354e96d89524f613e7/b78d0a48e4443f797e8d45dcf97594f7/FantasqueSansMonoItalic.ttf') format('truetype');
font-weight: normal;
font-style: italic;
}
@font-face
{
font-family: 'Fantasque Sans Mono', FreeMono, 'Courier New', Cousine, Courier, monospace;
src: local('Fantasque Sans Mono Regular'),
local('FantasqueSansMono-Regular'),
url('https://fontlibrary.org/assets/fonts/fantasque-sans-mono/b0cbb25e73a9f8354e96d89524f613e7/f3fdc4f0f26e4431f54e8b552d55480c/FantasqueSansMonoRegular.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
/* Use custom fonts */
code, kbd, samp, tt, pre { font-family: 'Fantasque Sans Mono', FreeMono, 'Courier New', Cousine, Courier, monospace; }
code, kbd, samp, tt {
font-style: italic;
padding: 0 0.1ex; /* slightly increase margin to surrounding text */ }
body, .sansserif { font-family: 'Roboto Condensed', sans-serif; }
h1, h2, h3, h4, h5, .menu-comment, .roman, .menu-preformatted {
font-family: 'Roboto Condensed', serif; }
/* Use colors from the solarized color theme (sparsely), the main text
will remain in default colors for optimal readability (black on white). */
pre.example, .header, .float-caption, hr {
/* base00 ~ body text in light solarized theme */
color: #657b83;
border-color: #657b83; }
pre.example {
/* base3 ~Â background color in light solarized theme */
background-color: #fdf6e3;
padding: 0.5em; }
a { color: #268bd2; /* blue */ }
a:visited { color: #d33682; /* magenta */ }
/* Center floating tables and images */
.float table, .float img, .float object {
margin-left: auto;
margin-right: auto; }
/* Decrease table width, but not on small screens */
.float table { max-width: 38em; }
/* Use horizontal lines: above/below tables and after table headers
(Chicago Style). */
.float table, .float th {
border-collapse: collapse;
border-top: 1px solid black;
border-bottom: 1px solid black; }
.float th, .float td { padding: 0.5em; }
/* Use horizontal ruler with double lines */
hr { border-width: 0; border-top-width: 3px; border-style: double; }
/* Smaller gap between subsequent @group blocks */
.example { margin-bottom: 1em; }
.example + .example { margin-top: -0.5em }
/* Smaller gap between definition and its description */
dd > p:first-child { margin-top: 0.5em; }
/* Limit maximum body width such that text is easier to read */
body { max-width: 42em; margin-left: 0.5em; margin-right: 0.5em; }
/* On small screens don't indent the code examples to prevent overflow */
div.example { margin-left: auto; max-width: 38.8em; }
/*
Use left margin such that text is easier to read,
but don't sacrifice space on small screens.
*/
@media screen and (min-width: 43em)
{
/* Smooth transition for screens between 43em and 57em */
body { margin-left: auto; margin-right: auto; }
@media (min-width: 57em)
{
body { margin-left: 7.5em; }
}
}
gnu-octave-octave-audio-125c0f5/inst/ 0000775 0000000 0000000 00000000000 15135415131 0017443 5 ustar 00root root 0000000 0000000 gnu-octave-octave-audio-125c0f5/inst/@midimsg/ 0000775 0000000 0000000 00000000000 15135415131 0021174 5 ustar 00root root 0000000 0000000 gnu-octave-octave-audio-125c0f5/inst/@midimsg/properties.m 0000664 0000000 0000000 00000002135 15135415131 0023547 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2023 John Donoghue
##
## This file is part of Octave.
##
## Octave is free software; you can redistribute it and/or modify it
## under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 3 of the License, or (at
## your option) any later version.
##
## Octave is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
## General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with Octave; see the file COPYING. If not, see
## .
## -*- texinfo -*-
## @deftypefn {} {&var{props} =} properties (@var{rf})
## Return the properties the midimsg
## @seealso{midimsg}
## @end deftypefn
function props = properties(this)
# in octave <= 6.4, 'properties' cant t be be used as a function name
# otherwise will be a syntax error, so currently using separate file for the function
props = __properties__(this);
endfunction
gnu-octave-octave-audio-125c0f5/inst/@octave_midi/ 0000775 0000000 0000000 00000000000 15135415131 0022026 5 ustar 00root root 0000000 0000000 gnu-octave-octave-audio-125c0f5/inst/@octave_midi/hasdata.m 0000664 0000000 0000000 00000002342 15135415131 0023612 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2022 John Donoghue
##
## This program is free software: you can redistribute it and/or modify it
## under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program. If not, see
## .
## -*- texinfo -*-
## @deftypefn {} {@var{tf} =} hasdata (@var{dev})
## Return whether there is data available to read
##
## @subsubheading Inputs
## @var{dev} - a octave midi device opened using mididevice.@*
##
## @subsubheading Outputs
## @var{tf} - true if device has data available to read@*
##
## @seealso{mididevice}
## @end deftypefn
function tf = hasdata(dev)
if nargin < 1 || !isobject(dev) || !strcmp(typeinfo(dev), "octave_midi")
error ("Expected midi device");
endif
tf = __midistat__(dev);
endfunction
gnu-octave-octave-audio-125c0f5/inst/__load_audio__.m 0000664 0000000 0000000 00000002643 15135415131 0022522 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2023 John Donoghue
##
## This program is free software; you can redistribute it and/or
## modify it under the terms of the GNU General Public License as
## published by the Free Software Foundation; either version 3 of the
## License, or (at your option) any later version.
##
## This program is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
## General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, see
## .
## -*- texinfo -*-
## @deftypefn {} {} __load_audio__ ()
## Undocumented internal function of audio package.
## @end deftypefn
## PKG_ADD: __load_audio__ ()
function __load_audio__ ()
# on package load, attempt to load docs
try
pkg_dir = fileparts (fullfile (mfilename ("fullpath")));
doc_file = fullfile (pkg_dir, "doc", "audio.qch");
doc_file = strrep (doc_file, '\', '/');
if exist(doc_file, "file")
if exist("__event_manager_register_documentation__")
__event_manager_register_documentation__ (doc_file);
elseif exist("__event_manager_register_doc__")
__event_manager_register_doc__ (doc_file);
endif
endif
catch
# do nothing
end_try_catch
endfunction
gnu-octave-octave-audio-125c0f5/inst/__unload_audio__.m 0000664 0000000 0000000 00000002665 15135415131 0023071 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2023 John Donoghue
##
## This program is free software; you can redistribute it and/or
## modify it under the terms of the GNU General Public License as
## published by the Free Software Foundation; either version 3 of the
## License, or (at your option) any later version.
##
## This program is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
## General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, see
## .
## -*- texinfo -*-
## @deftypefn {} {} __unload_audio__ ()
## Undocumented internal function of audio package.
## @end deftypefn
## PKG_DEL: __unload_audio__ ()
function __unload_audio__ ()
# on package unload, attempt to unload docs
try
pkg_dir = fileparts (fullfile (mfilename ("fullpath")));
doc_file = fullfile (pkg_dir, "doc", "audio.qch");
doc_file = strrep (doc_file, '\', '/');
if exist(doc_file, "file")
if exist("__event_manager_unregister_documentation__")
__event_manager_unregister_documentation__ (doc_file);
elseif exist("__event_manager_unregister_doc__")
__event_manager_unregister_doc__ (doc_file);
endif
endif
catch
# do nothing
end_try_catch
endfunction
gnu-octave-octave-audio-125c0f5/inst/audio.m 0000664 0000000 0000000 00000005225 15135415131 0020726 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2019 John Donoghue
##
## This program is free software: you can redistribute it and/or modify it
## under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program. If not, see
## .
## -*- texinfo -*-
## The Audio package provides basic MIDI and audio functionality for GNU octave.
##
## @subheading MIDI
## The following MIDI functions are available:
##
## @subsubheading MIDI Device query:
## @table @asis
## @item mididevinfo
## list any MIDI devices detected in the system
## @end table
##
## @subsubheading MIDI Device creation and manipulation:
## @table @asis
## @item mididevice
## Create a midi device
## @item midimsg
## Create a MIDI message or group of messages
## @item midireceive
## receive a MIDI message from a device
## @item midisend
## Send a MIDI message to a device
## @end table
##
## @subsubheading MIDI Controller Interface Functions:
## @table @asis
## @item midiid
## Identify a midi controller
## @item midicontrols
## Create a MIDI controller object
## @item midireceive
## Receive data from a MIDI controller object
## @item midisend
## Send data to a MIDI controller.
## @end table
##
## @subsubheading Writing and reading basic MIDI files:
## @table @asis
## @item midifileinfo
## read information about a MIDI file, including number of tracks,
## comments etc.
## @item midifileread
## read a MIDI file into a midimsg array
## @item midifilewrite
## write a midimsg array to a MIDI file
## @end table
##
## @subsubheading General usage:
##
## Normal usage would involve querying the devices that are available:
## @example
## mididevinfo
## @end example
##
## Then selecting the device(s) to connect to, and creating a mididevice to perform read and write functionality:
## @example
## dev = mididevice(0);
## @end example
##
## And then performing I/O on the device:
## @example
## msg = midireceive(dev)
## @end example
##
## @subheading Audio
## The following Audio functions are available:
## @table @asis
## @item hz2mel, hz2bark, hz2erp, mel2hz, bark2hz, erp2hz
## Convert between hz and other frequenct scales
## @item audioOscillator
## Create a audio waveform generator
## @end table
function audio()
help audio;
endfunction
gnu-octave-octave-audio-125c0f5/inst/audioOscillator.m 0000664 0000000 0000000 00000035102 15135415131 0022757 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2023 John Donoghue
##
## This program is free software: you can redistribute it and/or modify it
## under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program. If not, see
## .
classdef audioOscillator < handle
## -*- texinfo -*-
## @deftypefn {} {} audioOscillator
## Generate sine, sawtool and square waveforms
## @end deftypefn
##
## @subheading Methods
## @deftypefn {} {@var{obj} =} audioOscillator ()
## @deftypefnx {} {@var{obj} =} audioOscillator (@var{signalTypeValue})
## @deftypefnx {} {@var{obj} =} audioOscillator (@var{signalTypeValue}, @var{frequencyValue})
## @deftypefnx {} {@var{obj} =} audioOscillator (__, @var{propertyname}, @var{propertyvalue})
## Create a audioOscillator object
##
## @subsubheading Inputs
## @var{signalTypeValue} - signal type of "sine" (default), "square", "sawtooth".@*
## @var{frequencyValue} - hz frequency value of waveform (default 100).@*
## @var{propertyname}, @var{propertyvalue} - properties to set on the object.
##
## Known properties are:
## @table @asis
## @item SignalType
## signal type of "sine" (default), "square" or "sawtooth". (readonly)
## @item Frequency
## frequency of the waveform (default 100)
## @item Amplitude
## amplitude of the signal (default 1)
## @item SampleRate
## sample rate of the signal (default 44100)
## @item PhaseOffset
## phase offset of signal 0 (default) - 1 (readonly)
## @item DutyCycle
## dutycycle of the signal 0 - 1 (default 0.5) when signal is a square wave.
## @item SamplePerFrame
## Samples per frame as returned from () (default 512)
## @item MaxSamplePerFrame
## Max samples per frame (default 192000)
## @item DCOffset
## DC Offset of signal (default 0)
## @item Width
## Width of sawtooth (default 1)
## @item OutputDataType
## Output data type of 'single' or 'double' (default 'double')
## @end table
##
## @subsubheading Outputs
## @var{obj} - signalGenerator object
##
## @subsubheading Examples
## Create a 100 hz sine wave and plot first 512 samples
## @example
## sinosc = audioOscillator
## data = sinosc();
## plot(data);
## @end example
##
## Create a 2 hz square wave with duty cycle of 0.5
## @example
## sqosc = audioOscillator('square', 'DutyCycle', 0.50, 'Frequency', 2);
## @end example
##
## @end deftypefn
##
## @deftypefn {} {@var{data} =} @var{obj}()
## Generate a frame of waveform data from the generator function
##
## @subsubheading Inputs
## @var{obj} - signalGenerator object
##
## @subsubheading Outputs
## @var{data} - waveform data
## @end deftypefn
##
## @deftypefn {} {} release(@var{obj})
## Release resources of generator
##
## @subsubheading Inputs
## @var{obj} - signalGenerator object
##
## @subsubheading Outputs
## None
## @end deftypefn
properties (SetAccess = private, GetAccess = public)
# read only properties
SignalType = "sine";
PhaseOffset = 0;
endproperties
properties (Access = public)
# read/write properties
SampleRate = 44100;
DutyCycle = 0.5;
Frequency = 100;
Amplitude = 1.0;
SamplesPerFrame = 512;
Width = 1;
DCOffset = 0;
MaxSamplesPerFrame = 192000;
OutputDataType = 'double'
endproperties
properties (Static = true, Access = private)
# data validation functions
check_sig_value = @(x) ischar(x) && any (strcmp (x, {'sine', 'square', 'sawtooth'}));
check_odt_value = @(x) ischar(x) && any (strcmp (x, {'single', 'double'}));
check_amp_value = @(x) isnumeric(x) && isreal(x) && (x >= 0)
check_duty_value = @(x) isnumeric(x) && isreal(x) && isscalar(x) && (x >= 0 && x <= 1)
check_freq_value = @(x) isnumeric(x) && isreal(x) && (x >= 0)
check_srate_value = @(x) isnumeric(x) && isscalar(x) && isreal(x) && (x > 0)
check_spf_value = @(x) isnumeric(x) && isscalar(x) && (rem(x, 1) == 0) && (x > 0)
check_mspf_value = @(x) isnumeric(x) && isscalar(x) && (rem(x, 1) == 0) && (x > 0)
check_width_value = @(x) isnumeric(x) && isscalar(x) && (x >= 0 && x <= 1)
check_dcoff_value = @(x) isnumeric(x) && isreal(x)
check_phase_value = @(x) isnumeric(x) && isreal(x) && all(x >= 0 && x <= 1)
endproperties
properties (Access = private)
# internal data structure for waveform
_wavedata = struct("data", [], "pos", 0);
endproperties
methods (Access = public)
function this = audioOscillator(varargin)
if nargin > 0
# either a property name or signal type
if !ischar(varargin{1})
error ("Expected first input argument to be signal type or property name.")
endif
propstart = 1;
# do we have signal type or possible property name/value?
if this.check_sig_value(varargin{1})
this.SignalType = varargin{1};
propstart = 2;
# we have frequency too ?
if nargin > 1 && isnumeric(varargin{2})
propstart = 3;
this.Frequency = varargin{2};
endif
elseif !is_property(this, varargin{1})
error ("Expected first input argument to be signal type or property name.")
endif
if mod(length(varargin)-propstart, 2) != 1
error ("Expected property name/value pairs.")
endif
# handle the properties
p = inputParser(CaseSensitive=false, FunctionName='audioOscillator');
p.addParameter('SignalType', this.SignalType, this.check_sig_value);
p.addParameter('Amplitude', this.Amplitude, this.check_amp_value);
p.addParameter('DutyCycle', this.DutyCycle, this.check_duty_value);
p.addParameter('Frequency', this.Frequency, this.check_freq_value);
p.addParameter('SampleRate', this.SampleRate, this.check_srate_value);
p.addParameter('SamplesPerFrame', this.SamplesPerFrame, this.check_spf_value);
p.addParameter('Width', this.Width, this.check_width_value);
p.addParameter('DCOffset', this.DCOffset, this.check_dcoff_value);
p.addParameter('MaxSamplesPerFrame', this.MaxSamplesPerFrame, this.check_mspf_value);
p.addParameter('OutputDataType', this.OutputDataType, this.check_odt_value);
p.addParameter('PhaseOffset', this.PhaseOffset, this.check_phase_value);
p.parse(varargin{propstart:end})
# verify samples per frame vs maxsample per frame
if p.Results.SamplesPerFrame > p.Results.MaxSamplesPerFrame
error ("Invalid SamplesPerFrame - Can not be greater than MaxSamplesPerFrame")
endif
this.MaxSamplesPerFrame = p.Results.MaxSamplesPerFrame;
# set properties from inputs/defaults
fields = fieldnames(p.Results);
for f = 1:length(fields)
propname = fields{f};
propval = p.Results.(propname);
this.(propname) = propval;
endfor
endif
endfunction
function release(this)
# anything we need release ?
if ! isempty(this._wavedata.data)
this._wavedata.data = [];
this._wavedata.pos = 0;
endif
endfunction
function data = subsref(this, S)
if nargin == 1 || (S(1).type == "()" && isempty(S(1).subs))
# build the waveform if we dont have one yet
if isempty(this._wavedata.data)
this._wavedata.pos = 0;
# phase
theta = this.PhaseOffset * 2 * pi;
t = linspace(theta,2*pi*this.Frequency+theta,this.SampleRate);
if strcmp(this.SignalType, "sine")
wavedata = sin(t);
elseif strcmp(this.SignalType, "square")
t = t / 2*pi;
wavedata = ones(size(t));
wavedata(t-floor(t) >= this.DutyCycle) = -1;
elseif strcmp(this.SignalType, "sawtooth")
t = mod (t / (2 * pi), 1);
wavedata = zeros (size (t));
if this.Width != 0
wavedata(t < this.Width) = 2 * t(t= this.Width) = -2 * t(t>=this.Width) / (1-this.Width) +1;
endif
else
# should never be able to get here
error ("Unknown SignalType");
endif
wavedata = this.DCOffset + (this.Amplitude * wavedata);
if strcmp(this.OutputDataType, 'single')
wavedata = single(wavedata);
endif
this._wavedata.data = wavedata;
endif
# extract some of the sample
data = [];
len = this.SamplesPerFrame - length(data);
while len > 0
left = length(this._wavedata.data) - this._wavedata.pos;
if left <= len
# use up all thats left
data = [data this._wavedata.data(this._wavedata.pos+1:end)];
this._wavedata.pos = 0;
else
data = [data this._wavedata.data(this._wavedata.pos+1:this._wavedata.pos+len)];
this._wavedata.pos = this._wavedata.pos + len;
endif
len = this.SamplesPerFrame - length(data);
endwhile
S = S(2:end);
else
data = this;
endif
if (numel (S) > 0)
data = builtin('subsref',data, S);
endif
endfunction
function this = set.SampleRate(this, rate)
if ! this.check_srate_value(rate)
error ("Invalid SampleRate - validation %s", func2str(this.check_srate_value))
endif
this.SampleRate = rate;
# clear data so will be regenerated
this._wavedata.data = [];
endfunction
function this = set.DutyCycle(this, rate)
if ! this.check_duty_value(rate)
error ("Invalid DutyCycle - validation %s", func2str(this.check_duty_value))
endif
this.DutyCycle = rate;
# clear data so will be regenerated
this._wavedata.data = [];
endfunction
function this = set.Amplitude(this, amp)
if ! this.check_amp_value(amp)
error ("Invalid Amplitude - validation %s", func2str(this.check_amp_value))
endif
this.Amplitude = amp;
# clear data so will be regenerated
this._wavedata.data = [];
endfunction
function this = set.SamplesPerFrame(this, value)
if ! this.check_spf_value(value)
error ("Invalid SamplesPerFrame - validation %s", func2str(this.check_spf_value))
endif
if value > this.MaxSamplesPerFrame
error ("Invalid SamplesPerFrame - Can not be greater than MaxSamplesPerFrame");
endif
this.SamplesPerFrame = value;
# clear data so will be regenerated
this._wavedata.data = [];
endfunction
function this = set.MaxSamplesPerFrame(this, value)
if ! this.check_mspf_value(value)
error ("Invalid MaxSamplesPerFrame - validation %s", func2str(this.check_mspf_value))
endif
this.MaxSamplesPerFrame = value;
# scale back samples per frame if now is invalid
if this.SamplesPerFrame > value
this.SamplesPerFrame = value;
endif
endfunction
function this = set.Width(this, value)
if ! this.check_width_value(value)
error ("Invalid Width - validation %s", func2str(this.check_width_value))
endif
this.Width = value;
# clear data so will be regenerated
this._wavedata.data = [];
endfunction
function this = set.DCOffset(this, value)
if ! this.check_dcoff_value(value)
error ("Invalid DCOffset - validation %s", func2str(this.check_dcoff_value))
endif
this.DCOffset = value;
# clear data so will be regenerated
this._wavedata.data = [];
endfunction
function this = set.OutputDataType(this, value)
if ! this.check_odt_value(value)
error ("Invalid OutputDataType - validation %s", func2str(this.check_odt_value))
endif
this.OutputDataType = value;
# clear data so will be regenerated
this._wavedata.data = [];
endfunction
function this = set.Frequency(this, value)
if ! this.check_freq_value(value)
error ("Invalid Frequency - validation %s", func2str(this.check_freq_value))
endif
this.Frequency = value;
# clear data so will be regenerated
this._wavedata.data = [];
endfunction
endmethods
methods (Access = private)
function y = is_property(this, value)
y = false;
if exist ("properties")
props_f = str2func("properties");
props = props_f(this);
else
# no properties function so manually look at classinfo
props_all = metaclass(this).Properties;
props = {};
for idx=1:length(props_all)
p = props_all{idx};
if strcmp(p.GetAccess, "public")
props{end+1} = p.Name;
endif
endfor
endif
if any(strcmpi(value, props))
y = true;
endif
endfunction
endmethods
endclassdef
%!error audioOscillator(1)
%!error audioOscillator("unknown")
%!error audioOscillator("sine", "a")
%!test
%! osc = audioOscillator();
%! assert(osc.Frequency, 100);
%! assert(osc.SampleRate, 44100);
%! assert(osc.SignalType, "sine");
%! osc = audioOscillator("sine");
%! assert(osc.SignalType, "sine");
%! osc = audioOscillator("SignalType", "sine");
%! assert(osc.SignalType, "sine");
%! osc = audioOscillator("sine", 2);
%! assert(osc.SignalType, "sine");
%! assert(osc.Frequency, 2);
%!test
%! osc = audioOscillator("square");
%! assert(osc.Frequency, 100);
%! assert(osc.SampleRate, 44100);
%! assert(osc.SignalType, "square");
%! osc = audioOscillator("SignalType", "square");
%! assert(osc.SignalType, "square");
%! osc = audioOscillator("square", 2);
%! assert(osc.SignalType, "square");
%! assert(osc.Frequency, 2);
%!test
%! osc = audioOscillator("sawtooth");
%! assert(osc.Frequency, 100);
%! assert(osc.SampleRate, 44100);
%! assert(osc.SignalType, "sawtooth");
%! osc = audioOscillator("SignalType", "sawtooth");
%! assert(osc.SignalType, "sawtooth");
%!test
%! osc = audioOscillator("SignalType", "sine", "Frequency", 2, "Amplitude", 1.1, "SamplesPerFrame", 1024);
%! assert(osc.Frequency, 2);
%! assert(osc.Amplitude, 1.1);
%! assert(osc.SamplesPerFrame, 1024);
%! assert(osc.SampleRate, 44100);
%!test
%! osc = audioOscillator("sine");
%! data = osc();
%! assert(length(data), osc.SamplesPerFrame)
gnu-octave-octave-audio-125c0f5/inst/bark2hz.m 0000664 0000000 0000000 00000003256 15135415131 0021172 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2023 John Donoghue
##
## This program is free software: you can redistribute it and/or modify it
## under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program. If not, see
## .
## -*- texinfo -*-
## @deftypefn {} {@var{hz} =} bark2hz (@var{bark})
## Convert equivalent Bark Frequency to Hz.
##
## @subsubheading Inputs
## @var{bark} - input frequency in bark.
##
## @subsubheading Outputs
## @var{hz} - Output frequency in Hz.
##
## @subsubheading References
## TraunmĂ¼ller, Hartmut. @cite{Analytical Expressions for the Tonotopic Sensory Scale.
## Journal of the Acoustical Society of America. Vol. 88, Issue 1, 1990}
##
## @seealso {hz2bark}
## @end deftypefn
function hz = bark2hz (bark)
if nargin < 1
show_usage()
endif
if ! (isnumeric(bark) && isreal(bark))
error ("Expected real scalar or vector");
endif
idx1 = find(bark<2);
idx2 = find(bark>20.1);
bark(idx1) = (bark(idx1) - 0.3) / 0.85;
bark(idx2) = (bark(idx2) + 4.422) / 1.22;
hz = 1960 * (bark + 0.53) / (26.28 - bark);
endfunction
%!error bark2hz()
%!error bark2hz('a')
%!error bark2hz(2i)
%!test
%! bark = hz2bark(10);
%! hz = bark2hz(bark);
%! assert(hz, 10, 100*eps)
gnu-octave-octave-audio-125c0f5/inst/data/ 0000775 0000000 0000000 00000000000 15135415131 0020354 5 ustar 00root root 0000000 0000000 gnu-octave-octave-audio-125c0f5/inst/data/c_maj_melody.mid 0000664 0000000 0000000 00000000472 15135415131 0023474 0 ustar 00root root 0000000 0000000 MThd àMTrk ¸ ÿX ÿY °y À °d
@ [ ] ÿ!