26 #if defined (HAVE_CONFIG_H)
54 #if defined (HAVE_PORTAUDIO)
55 # include <portaudio.h>
60 #if defined (HAVE_PORTAUDIO)
63 bits_to_format (
int bits)
121 #if defined (HAVE_PORTAUDIO)
123 int nargin = args.length ();
132 PaError err = Pa_Initialize ();
134 if (err != paNoError)
135 error (
"audiodevinfo: PortAudio initialization failed");
137 int num_devices = Pa_GetDeviceCount ();
143 numinput = numoutput = 0;
144 for (
int i = 0; i < num_devices; i++)
146 const PaDeviceInfo *device_info = Pa_GetDeviceInfo (i);
151 "invalid audio device ID = %d", i);
155 if (device_info->maxInputChannels != 0)
158 if (device_info->maxOutputChannels != 0)
171 for (
int i = 0; i < num_devices; i++)
173 const PaDeviceInfo *device_info = Pa_GetDeviceInfo (i);
178 "invalid audio device ID = %d", i);
182 const PaHostApiInfo *api_info = Pa_GetHostApiInfo (device_info->hostApi);
184 const char *driver = (api_info ? api_info->name :
"");
187 sprintf (name,
"%s (%s)", device_info->name, driver);
189 if (device_info->maxInputChannels != 0)
191 input_name(idx_i) = name;
192 input_driver_version(idx_i) = driver;
197 if (device_info->maxOutputChannels != 0)
199 output_name(idx_o) = name;
200 output_driver_version(idx_o) = driver;
201 output_id(idx_o) = i;
207 inputdev.
setfield (
"Name", input_name);
208 inputdev.
setfield (
"DriverVersion", input_driver_version);
210 outputdev.
setfield (
"Name", output_name);
211 outputdev.
setfield (
"DriverVersion", output_driver_version);
212 outputdev.
setfield (
"ID", output_id);
213 devinfo.
setfield (
"input", inputdev);
214 devinfo.
setfield (
"output", outputdev);
224 else if (nargin == 1)
226 if (args(0).int_value () == 0)
228 else if (args(0).int_value () == 1)
231 error (
"audiodevinfo: specify 0 for output and 1 for input devices");
234 else if (nargin == 2)
237 int outin = args(0).int_value ();
238 if (args(1).is_string ())
240 std::string name = args(1).string_value ();
243 for (
int i = 0; i < numoutput; i++)
245 if (output_name(i).string_value () == name)
247 retval = output_id(i);
255 for (
int i = 0; i < numinput; i++)
257 if (input_name(i).string_value () == name)
259 retval = input_id(i);
266 error (
"audiodevinfo: specify 0 for output and 1 for input devices");
272 for (
int i = 0; i < numoutput; i++)
274 if (output_id(i).int_value () == args(1).int_value ())
276 retval = output_name(i);
284 for (
int i = 0; i < numinput; i++)
286 if (input_id(i).int_value () == args(1).int_value ())
288 retval = input_name(i);
295 error (
"audiodevinfo: specify 0 for output and 1 for input devices");
299 error (
"audiodevinfo: no device found for the specified criteria");
302 else if (nargin == 3)
305 int outin = args(0).int_value ();
306 int m_id = args(1).int_value ();
308 std::string arg3 = args(2).string_value ();
309 std::transform (arg3.begin (), arg3.end (), arg3.begin (), tolower);
310 if (arg3 !=
"driverversion")
311 error (R
"(audiodevinfo: third argument must be "DriverVersion")");
315 for (
int i = 0; i < numoutput; i++)
317 if (output_id(i).int_value () == m_id)
320 retval = output_driver_version(i);
327 for (
int i = 0; i < numinput; i++)
329 if (input_id(i).int_value () == m_id)
332 retval = input_driver_version(i);
338 error (
"audiodevinfo: specify 0 for output and 1 for input devices");
341 error (
"audiodevinfo: no device found for the specified criteria");
344 else if (nargin == 4)
346 int io = args(0).int_value ();
347 int rate = args(1).int_value ();
348 int bits = args(2).int_value ();
349 int chans = args(3).int_value ();
351 for (
int i = 0; i < num_devices; i++)
353 PaStreamParameters stream_parameters;
354 stream_parameters.device = i;
355 stream_parameters.channelCount = chans;
356 PaSampleFormat
format = bits_to_format (bits);
359 stream_parameters.sampleFormat =
format;
361 error (
"audiodevinfo: invalid bits per sample format");
363 const PaDeviceInfo *device_info = Pa_GetDeviceInfo (i);
368 "invalid audio device ID = %d", i);
372 stream_parameters.suggestedLatency
373 = device_info->defaultLowInputLatency;
375 stream_parameters.hostApiSpecificStreamInfo =
nullptr;
379 if (device_info->maxOutputChannels < chans)
382 err = Pa_IsFormatSupported (
nullptr, &stream_parameters, rate);
384 if (err == paFormatIsSupported)
392 if (device_info->maxInputChannels < chans)
395 err = Pa_IsFormatSupported (&stream_parameters,
nullptr, rate);
396 if (err == paFormatIsSupported)
406 else if (nargin == 5)
409 int m_id = args(1).int_value ();
410 int rate = args(2).int_value ();
411 int bits = args(3).int_value ();
412 int chans = args(4).int_value ();
413 PaStreamParameters stream_parameters;
414 stream_parameters.device = m_id;
415 stream_parameters.channelCount = chans;
416 PaSampleFormat
format = bits_to_format (bits);
418 stream_parameters.sampleFormat =
format;
420 error (
"audiodevinfo: invalid bits per sample format");
422 const PaDeviceInfo *device_info = Pa_GetDeviceInfo (m_id);
425 error (
"audiodevinfo: invalid audio device ID = %d", m_id);
427 stream_parameters.suggestedLatency
428 = device_info->defaultLowInputLatency;
430 stream_parameters.hostApiSpecificStreamInfo =
nullptr;
433 if (device_info->maxOutputChannels < chans)
438 err = Pa_IsFormatSupported (
nullptr, &stream_parameters, rate);
439 if (err == paFormatIsSupported)
447 if (device_info->maxInputChannels < chans)
452 err = Pa_IsFormatSupported (&stream_parameters,
nullptr, rate);
453 if (err == paFormatIsSupported)
460 error (
"audiodevinfo: specify 0 for output and 1 for input devices");
468 octave_unused_parameter (args);
471 "audio playback and recording through PortAudio");
518 #if defined (HAVE_PORTAUDIO)
520 enum audio_type { TYPE_INT8, TYPE_UINT8, TYPE_UINT16, TYPE_DOUBLE };
528 OCTAVE_DISABLE_COPY_MOVE (audioplayer)
533 double player_value ()
const {
return 0; }
534 virtual double scalar_value (
bool =
false)
const {
return 0; }
535 void print (std::ostream& os,
bool pr_as_read_syntax =
false);
536 void print_raw (std::ostream& os,
bool pr_as_read_syntax)
const;
546 void set_y (std::string fcn);
550 void set_fs (
int m_fs);
552 void set_nbits (
int m_nbits);
554 void set_id (
int m_id);
557 audio_type get_type ();
559 void set_sample_number (
unsigned int sample);
560 unsigned int get_sample_number ();
561 unsigned int get_total_samples ();
562 void set_end_sample (
unsigned int sample);
563 unsigned int get_end_sample ();
564 void reset_end_sample ();
569 PaStream * get_stream ();
572 void playblocking ();
585 unsigned int m_sample_number;
586 unsigned int m_end_sample;
593 PaStreamParameters m_output_parameters;
602 octave_play_callback (
const void *,
void *output,
unsigned long frames,
603 const PaStreamCallbackTimeInfo *,
604 PaStreamCallbackFlags,
void *data)
606 audioplayer *player =
static_cast<audioplayer *
> (data);
609 error (
"audioplayer callback function called without player");
614 = interp.
feval (player->octave_callback_function,
615 ovl (
static_cast<double> (frames)), 1);
618 error (
"audioplayer callback function failed");
620 const Matrix sound = retval(0).matrix_value ();
621 int return_status = retval(1).int_value ();
623 if (frames - sound.
rows () != 0 || sound.
columns () < 1
625 error (
"audioplayer callback function failed");
633 ? sound_l : sound.
column (1));
635 const double *p_l = sound_l.
data ();
636 const double *p_r = sound_r.
data ();
638 switch (player->get_nbits ())
642 static double scale_factor =
std::pow (2.0, 7) - 1.0;
644 int8_t *buffer =
static_cast<int8_t *
> (output);
646 for (
unsigned long i = 0; i < frames; i++)
648 buffer[2*i] = p_l[i] * scale_factor;
649 buffer[2*i+1] = p_r[i] * scale_factor;
656 static double scale_factor =
std::pow (2.0, 15) - 1.0;
658 int16_t *buffer =
static_cast<int16_t *
> (output);
660 for (
unsigned long i = 0; i < frames; i++)
662 buffer[2*i] = p_l[i] * scale_factor;
663 buffer[2*i+1] = p_r[i] * scale_factor;
670 static double scale_factor =
std::pow (2.0, 23) - 1.0;
674 uint8_t *buffer =
static_cast<uint8_t *
> (output);
676 for (
unsigned long i = 0; i < frames; i++)
678 int32_t sample_l = p_l[i];
679 int32_t sample_r = p_r[i];
681 sample_l &= 0x00ffffff;
682 sample_r &= 0x00ffffff;
684 uint8_t *_sample_l =
reinterpret_cast<uint8_t *
> (&sample_l);
685 uint8_t *_sample_r =
reinterpret_cast<uint8_t *
> (&sample_r);
687 unsigned long offset = i * 6;
689 buffer[offset+0] = _sample_l[0+big_endian] * scale_factor;
690 buffer[offset+1] = _sample_l[1+big_endian] * scale_factor;
691 buffer[offset+2] = _sample_l[2+big_endian] * scale_factor;
693 buffer[offset+3] = _sample_r[0+big_endian] * scale_factor;
694 buffer[offset+4] = _sample_r[1+big_endian] * scale_factor;
695 buffer[offset+5] = _sample_r[2+big_endian] * scale_factor;
701 error (
"invalid bit depth in audioplayer callback function");
704 return return_status;
708 portaudio_play_callback (
const void *,
void *output,
unsigned long frames,
709 const PaStreamCallbackTimeInfo *,
710 PaStreamCallbackFlags,
void *data)
712 audioplayer *player =
static_cast<audioplayer *
> (data);
715 error (
"audioplayer callback function called without player");
722 const RowVector sound_l = player->get_left ();
723 const RowVector sound_r = player->get_right ();
725 const double *pl = sound_l.
data ();
726 const double *pr = sound_r.
data ();
728 if (player->get_type () == TYPE_DOUBLE)
730 switch (player->get_nbits ())
734 static double scale_factor =
std::pow (2.0, 7) - 1.0;
736 int8_t *buffer =
static_cast<int8_t *
> (output);
738 for (
unsigned long j = 0; j < frames; j++)
740 unsigned int m_sample_number = player->get_sample_number ();
742 if (m_sample_number >= player->get_end_sample ())
745 unsigned long offset = j * 2;
747 buffer[offset+0] = pl[m_sample_number] * scale_factor;
748 buffer[offset+1] = pr[m_sample_number] * scale_factor;
750 player->set_sample_number (m_sample_number + 1);
757 static double scale_factor =
std::pow (2.0, 15) - 1.0;
759 int16_t *buffer =
static_cast<int16_t *
> (output);
761 for (
unsigned long j = 0; j < frames; j++)
763 unsigned int m_sample_number = player->get_sample_number ();
765 if (m_sample_number >= player->get_end_sample ())
768 unsigned long offset = j * 2;
770 buffer[offset+0] = pl[m_sample_number] * scale_factor;
771 buffer[offset+1] = pr[m_sample_number] * scale_factor;
773 player->set_sample_number (m_sample_number + 1);
780 static double scale_factor =
std::pow (2.0, 23) - 1.0;
784 uint8_t *buffer =
static_cast<uint8_t *
> (output);
786 for (
unsigned long j = 0; j < frames; j++)
788 unsigned int m_sample_number = player->get_sample_number ();
790 if (m_sample_number >= player->get_end_sample ())
793 int32_t sample_l = pl[m_sample_number] * scale_factor;
794 int32_t sample_r = pr[m_sample_number] * scale_factor;
796 sample_l &= 0x00ffffff;
797 sample_r &= 0x00ffffff;
799 uint8_t *_sample_l =
reinterpret_cast<uint8_t *
> (&sample_l);
800 uint8_t *_sample_r =
reinterpret_cast<uint8_t *
> (&sample_r);
802 unsigned long offset = j * 6;
804 buffer[offset+0] = _sample_l[0+big_endian];
805 buffer[offset+1] = _sample_l[1+big_endian];
806 buffer[offset+2] = _sample_l[2+big_endian];
808 buffer[offset+3] = _sample_r[0+big_endian];
809 buffer[offset+4] = _sample_r[1+big_endian];
810 buffer[offset+5] = _sample_r[2+big_endian];
812 player->set_sample_number (m_sample_number + 1);
818 error (
"invalid bit depth in audioplayer callback function");
821 else if (player->get_type () == TYPE_INT8)
823 int8_t *buffer =
static_cast<int8_t *
> (output);
825 for (
unsigned long j = 0; j < frames; j++)
827 unsigned int m_sample_number = player->get_sample_number ();
829 if (m_sample_number >= player->get_end_sample ())
832 unsigned long offset = j * 2;
834 buffer[offset+0] = pl[m_sample_number];
835 buffer[offset+1] = pr[m_sample_number];
837 player->set_sample_number (m_sample_number + 1);
840 else if (player->get_type () == TYPE_UINT8)
842 uint8_t *buffer =
static_cast<uint8_t *
> (output);
844 for (
unsigned long j = 0; j < frames; j++)
846 unsigned int m_sample_number = player->get_sample_number ();
848 if (m_sample_number >= player->get_end_sample ())
851 unsigned long offset = j * 2;
853 buffer[offset+0] = pl[m_sample_number];
854 buffer[offset+1] = pr[m_sample_number];
856 player->set_sample_number (m_sample_number + 1);
859 else if (player->get_type () == TYPE_UINT16)
861 int16_t *buffer =
static_cast<int16_t *
> (output);
863 for (
unsigned long j = 0; j < frames; j++)
865 unsigned int m_sample_number = player->get_sample_number ();
867 if (m_sample_number >= player->get_end_sample ())
870 unsigned long offset = j * 2;
872 buffer[offset+0] = pl[m_sample_number];
873 buffer[offset+1] = pr[m_sample_number];
875 player->set_sample_number (m_sample_number + 1);
882 audioplayer::audioplayer ()
883 : octave_callback_function (nullptr),
884 m_id (-1), m_fs (0), m_nbits (16), m_channels (0), m_sample_number (0),
885 m_end_sample (-1), m_tag (
""), m_y (), m_userdata (
Matrix ()),
886 m_left (), m_right (), m_stream (nullptr), m_output_parameters (), m_type ()
889 audioplayer::~audioplayer ()
894 "interrupting audioplayer during playback");
900 audioplayer::print (std::ostream& os,
bool pr_as_read_syntax)
902 print_raw (os, pr_as_read_syntax);
907 audioplayer::print_raw (std::ostream& os,
bool)
const
921 if (Pa_Initialize () != paNoError)
922 error (
"audioplayer: initialization error");
924 if (Pa_GetDeviceCount () < 1)
925 error (
"audioplayer: no audio devices found or available");
927 int device = get_id ();
930 device = Pa_GetDefaultOutputDevice ();
932 m_output_parameters.device = device;
933 m_output_parameters.channelCount = 2;
935 if (m_type == TYPE_DOUBLE)
936 m_output_parameters.sampleFormat = bits_to_format (get_nbits ());
937 else if (m_type == TYPE_INT8)
938 m_output_parameters.sampleFormat = paInt8;
939 else if (m_type == TYPE_UINT8)
940 m_output_parameters.sampleFormat = paUInt8;
941 else if (m_type == TYPE_UINT16)
942 m_output_parameters.sampleFormat = paInt16;
944 const PaDeviceInfo *device_info = Pa_GetDeviceInfo (device);
948 "invalid default audio device ID = %d", device);
950 m_output_parameters.suggestedLatency
951 = (device_info ? device_info->defaultHighOutputLatency : -1);
953 m_output_parameters.hostApiSpecificStreamInfo =
nullptr;
964 m_type = TYPE_UINT16;
966 m_type = TYPE_DOUBLE;
973 m_channels = m_y.
rows ();
974 m_left = m_y.row (0);
977 m_right = m_y.row (1);
985 octave_callback_function = fcn;
991 audioplayer::get_y ()
997 audioplayer::get_left ()
const
1003 audioplayer::get_right ()
const
1005 return m_channels == 1 ? m_left : m_right;
1009 audioplayer::set_fs (
int fs_arg)
1015 audioplayer::get_fs ()
1021 audioplayer::set_nbits (
int nbits_arg)
1023 m_nbits = nbits_arg;
1027 audioplayer::get_nbits ()
1033 audioplayer::set_id (
int id_arg)
1039 audioplayer::get_id ()
1045 audioplayer::get_channels ()
1051 audioplayer::get_type ()
1057 audioplayer::set_sample_number (
unsigned int sample_number_arg)
1059 m_sample_number = sample_number_arg;
1063 audioplayer::get_sample_number ()
1065 return m_sample_number;
1069 audioplayer::get_total_samples ()
1071 return m_left.
numel ();
1075 audioplayer::set_end_sample (
unsigned int end_sample_arg)
1077 m_end_sample = end_sample_arg;
1081 audioplayer::get_end_sample ()
1083 return m_end_sample;
1087 audioplayer::reset_end_sample ()
1089 set_end_sample (m_left.numel ());
1093 audioplayer::set_tag (
const charMatrix& tag_arg)
1099 audioplayer::get_tag ()
1105 audioplayer::set_userdata (
const octave_value& userdata_arg)
1107 m_userdata = userdata_arg;
1111 audioplayer::get_userdata ()
1117 audioplayer::playblocking ()
1122 const unsigned int buffer_size = get_fs () / 20;
1126 err = Pa_OpenStream (&m_stream,
nullptr, &(m_output_parameters), get_fs (),
1127 buffer_size, paClipOff,
nullptr,
nullptr);
1128 if (err != paNoError)
1129 error (
"audioplayer: unable to open audio playback stream");
1131 err = Pa_StartStream (m_stream);
1132 if (err != paNoError)
1133 error (
"audioplayer: unable to start audio playback stream");
1135 unsigned int start, end;
1136 start = get_sample_number ();
1137 end = get_end_sample ();
1141 for (
unsigned int i = start; i < end; i += buffer_size)
1145 if (octave_callback_function !=
nullptr)
1146 octave_play_callback (
nullptr, buffer, buffer_size,
nullptr, 0,
this);
1148 portaudio_play_callback (
nullptr, buffer, buffer_size,
nullptr, 0,
this);
1150 err = Pa_WriteStream (m_stream, buffer, buffer_size);
1155 audioplayer::play ()
1160 const unsigned int buffer_size = get_fs () / 20;
1163 if (octave_callback_function !=
nullptr)
1164 err = Pa_OpenStream (&m_stream,
nullptr, &(m_output_parameters),
1165 get_fs (), buffer_size, paClipOff,
1166 octave_play_callback,
this);
1168 err = Pa_OpenStream (&m_stream,
nullptr, &(m_output_parameters),
1169 get_fs (), buffer_size, paClipOff,
1170 portaudio_play_callback,
this);
1172 if (err != paNoError)
1173 error (
"audioplayer: failed to open audio playback stream");
1175 err = Pa_StartStream (m_stream);
1176 if (err != paNoError)
1177 error (
"audioplayer: failed to start audio playback stream");
1181 audioplayer::pause ()
1183 if (get_stream () ==
nullptr)
1187 err = Pa_StopStream (m_stream);
1188 if (err != paNoError)
1189 error (
"audioplayer: failed to stop audio playback stream");
1193 audioplayer::resume ()
1195 if (get_stream () ==
nullptr)
1199 err = Pa_StartStream (m_stream);
1200 if (err != paNoError)
1201 error (
"audioplayer: failed to start audio playback stream");
1205 audioplayer::get_stream ()
1211 audioplayer::stop ()
1213 if (get_stream () ==
nullptr)
1217 set_sample_number (0);
1218 reset_end_sample ();
1219 if (! Pa_IsStreamStopped (get_stream ()))
1221 err = Pa_AbortStream (get_stream ());
1222 if (err != paNoError)
1223 error (
"audioplayer: failed to stop audio playback stream");
1226 err = Pa_CloseStream (get_stream ());
1227 if (err != paNoError)
1228 error (
"audioplayer: failed to close audio playback stream");
1234 audioplayer::isplaying ()
1236 if (get_stream () ==
nullptr)
1240 err = Pa_IsStreamActive (m_stream);
1241 if (err != 0 && err != 1)
1242 error (
"audioplayer: checking stream activity status failed");
1253 OCTAVE_DISABLE_COPY_MOVE (audiorecorder)
1258 double player_value ()
const {
return 0; }
1259 virtual double scalar_value (
bool =
false)
const {
return 0; }
1260 void print (std::ostream& os,
bool pr_as_read_syntax =
false);
1261 void print_raw (std::ostream& os,
bool pr_as_read_syntax)
const;
1269 void set_fs (
int m_fs);
1271 void set_nbits (
int m_nbits);
1273 PaSampleFormat get_sampleFormat ();
1274 void set_id (
int m_id);
1276 void set_channels (
int m_channels);
1277 int get_channels ();
1278 audio_type get_type ();
1280 void set_sample_number (
unsigned int sample);
1281 unsigned int get_sample_number ();
1282 unsigned int get_total_samples ();
1283 void set_end_sample (
unsigned int sample);
1284 unsigned int get_end_sample ();
1285 void reset_end_sample ();
1290 PaStream * get_stream ();
1293 audioplayer * getplayer ();
1294 bool isrecording ();
1295 audioplayer play ();
1297 void recordblocking (
float seconds);
1301 void append (
float sample_l,
float sample_r);
1310 unsigned int m_sample_number;
1311 unsigned int m_end_sample;
1315 std::vector<float> m_left;
1316 std::vector<float> m_right;
1318 PaStreamParameters m_input_parameters;
1327 octave_record_callback (
const void *input,
void *,
unsigned long frames,
1328 const PaStreamCallbackTimeInfo *,
1329 PaStreamCallbackFlags,
void *data)
1331 audiorecorder *recorder =
static_cast<audiorecorder *
> (data);
1334 error (
"audiorecorder callback function called without recorder");
1336 int m_channels = recorder->get_channels ();
1338 Matrix sound (frames, 2);
1339 sound.
resize (frames, 2);
1341 if (recorder->get_sampleFormat () == bits_to_format (8))
1343 static double scale_factor =
std::pow (2.0, 7) - 1.0;
1345 const int8_t *input8 =
static_cast<const int8_t *
> (input);
1347 for (
unsigned long i = 0; i < frames; i++)
1349 float sample_l = input8[i*m_channels] / scale_factor;
1350 float sample_r = input8[i*m_channels + (m_channels - 1)] / scale_factor;
1352 sound(i, 0) = sample_l;
1353 sound(i, 1) = sample_r;
1359 else if (recorder->get_sampleFormat () == bits_to_format (16)
1360 && recorder->get_nbits () == 8)
1362 static double scale_factor =
std::pow (2.0, 7) - 1.0;
1364 const int16_t *input16 =
static_cast<const int16_t *
> (input);
1366 for (
unsigned long i = 0; i < frames; i++)
1368 float sample_l = (input16[i*m_channels] >> 8) / scale_factor;
1369 float sample_r = (input16[i*m_channels + (m_channels - 1)] >> 8)
1372 sound(i, 0) = sample_l;
1373 sound(i, 1) = sample_r;
1376 else if (recorder->get_sampleFormat () == bits_to_format (16))
1378 static double scale_factor =
std::pow (2.0, 15) - 1.0;
1380 const int16_t *input16 =
static_cast<const int16_t *
> (input);
1382 for (
unsigned long i = 0; i < frames; i++)
1384 float sample_l = input16[i*m_channels] / scale_factor;
1385 float sample_r = input16[i*m_channels + (m_channels - 1)] / scale_factor;
1387 sound(i, 0) = sample_l;
1388 sound(i, 1) = sample_r;
1391 else if (recorder->get_sampleFormat () == bits_to_format (24))
1393 static double scale_factor =
std::pow (2.0, 23);
1397 const uint8_t *input24 =
static_cast<const uint8_t *
> (input);
1399 int32_t sample_l32, sample_r32;
1401 uint8_t *sample_l =
reinterpret_cast<uint8_t *
> (&sample_l32);
1402 uint8_t *sample_r =
reinterpret_cast<uint8_t *
> (&sample_r32);
1404 for (
unsigned long i = 0; i < frames; i++)
1406 sample_l32 = sample_r32 = 0;
1407 for (
int j = 0; j < 3; j++)
1409 sample_l[j] = input24[i*m_channels*3 + j];
1410 sample_r[j] = input24[i*m_channels*3 + (m_channels - 1)*3 + j];
1413 if (sample_l32 & 0x00800000)
1414 sample_l32 |= 0xff000000;
1416 if (sample_r32 & 0x00800000)
1417 sample_r32 |= 0xff000000;
1419 sound(i, 0) = sample_l32 / scale_factor;
1420 sound(i, 1) = sample_r32 / scale_factor;
1427 = interp.
feval (recorder->octave_callback_function,
ovl (sound), 1);
1429 return retval(0).int_value ();
1433 portaudio_record_callback (
const void *input,
void *,
unsigned long frames,
1434 const PaStreamCallbackTimeInfo *,
1435 PaStreamCallbackFlags,
void *data)
1437 audiorecorder *recorder =
static_cast<audiorecorder *
> (data);
1440 error (
"audiorecorder callback function called without recorder");
1442 int m_channels = recorder->get_channels ();
1444 if (recorder->get_sampleFormat () == bits_to_format (8))
1446 static float scale_factor =
std::pow (2.0f, 7) - 1.0f;
1448 const int8_t *input8 =
static_cast<const int8_t *
> (input);
1450 for (
unsigned long i = 0; i < frames; i++)
1452 float sample_l = input8[i*m_channels] / scale_factor;
1453 float sample_r = input8[i*m_channels + (m_channels - 1)] / scale_factor;
1455 recorder->append (sample_l, sample_r);
1461 else if (recorder->get_sampleFormat () == bits_to_format (16)
1462 && recorder->get_nbits () == 8)
1464 static double scale_factor =
std::pow (2.0, 7) - 1.0;
1466 const int16_t *input16 =
static_cast<const int16_t *
> (input);
1468 for (
unsigned long i = 0; i < frames; i++)
1470 float sample_l = (input16[i*m_channels] >> 8) / scale_factor;
1471 float sample_r = (input16[i*m_channels + (m_channels - 1)] >> 8)
1474 recorder->append (sample_l, sample_r);
1477 else if (recorder->get_sampleFormat () == bits_to_format (16))
1479 static float scale_factor =
std::pow (2.0f, 15) - 1.0f;
1481 const int16_t *input16 =
static_cast<const int16_t *
> (input);
1483 for (
unsigned long i = 0; i < frames; i++)
1485 float sample_l = input16[i*m_channels] / scale_factor;
1486 float sample_r = input16[i*m_channels + (m_channels - 1)] / scale_factor;
1488 recorder->append (sample_l, sample_r);
1491 else if (recorder->get_sampleFormat () == bits_to_format (24))
1493 static float scale_factor =
std::pow (2.0f, 23);
1497 const uint8_t *input24 =
static_cast<const uint8_t *
> (input);
1499 int32_t sample_l32, sample_r32;
1501 uint8_t *sample_l =
reinterpret_cast<uint8_t *
> (&sample_l32);
1502 uint8_t *sample_r =
reinterpret_cast<uint8_t *
> (&sample_r32);
1504 for (
unsigned long i = 0; i < frames; i++)
1506 sample_l32 = sample_r32 = 0;
1507 for (
int j = 0; j < 3; j++)
1509 sample_l[j] = input24[i*m_channels*3 + j];
1510 sample_r[j] = input24[i*m_channels*3 + (m_channels - 1)*3 + j];
1513 if (sample_l32 & 0x00800000)
1514 sample_l32 |= 0xff000000;
1516 if (sample_r32 & 0x00800000)
1517 sample_r32 |= 0xff000000;
1519 recorder->append (sample_l32 / scale_factor,
1520 sample_r32 / scale_factor);
1524 if (recorder->get_sample_number () >= recorder->get_end_sample ())
1530 audiorecorder::audiorecorder ()
1531 : octave_callback_function (nullptr),
1532 m_id (-1), m_fs (8000), m_nbits (8), m_channels (1), m_sample_number (0),
1533 m_end_sample (-1), m_tag (
""), m_y (), m_userdata (
Matrix ()),
1534 m_left (), m_right (), m_stream (nullptr), m_input_parameters (), m_type ()
1537 audiorecorder::~audiorecorder ()
1542 "interrupting audiorecorder during recording");
1548 audiorecorder::print (std::ostream& os,
bool pr_as_read_syntax)
1550 print_raw (os, pr_as_read_syntax);
1555 audiorecorder::print_raw (std::ostream& os,
bool)
const
1561 audiorecorder::init ()
1563 if (Pa_Initialize () != paNoError)
1564 error (
"audiorecorder: initialization error");
1566 if (Pa_GetDeviceCount () < 1)
1567 error (
"audiorecorder: no audio devices found or available");
1569 int device = get_id ();
1572 device = Pa_GetDefaultInputDevice ();
1574 m_input_parameters.device = device;
1575 m_input_parameters.channelCount = get_channels ();
1576 m_input_parameters.sampleFormat = bits_to_format (get_nbits ());
1581 if (get_nbits () == 8)
1582 m_input_parameters.sampleFormat = bits_to_format (16);
1584 const PaDeviceInfo *device_info = Pa_GetDeviceInfo (device);
1588 "invalid default audio device ID = %d", device);
1590 m_input_parameters.suggestedLatency
1591 = (device_info ? device_info->defaultHighInputLatency : -1);
1593 m_input_parameters.hostApiSpecificStreamInfo =
nullptr;
1597 audiorecorder::set_fs (
int fs_arg)
1603 audiorecorder::get_fs ()
1609 audiorecorder::set_nbits (
int nbits_arg)
1611 m_nbits = nbits_arg;
1615 audiorecorder::get_nbits ()
1621 audiorecorder::get_sampleFormat ()
1623 return m_input_parameters.sampleFormat;
1627 audiorecorder::set_id (
int id_arg)
1633 audiorecorder::get_id ()
1639 audiorecorder::set_channels (
int channels_arg)
1641 if (channels_arg != 1 && channels_arg != 2)
1642 error (
"audiorecorder: number of channels must be 1 or 2");
1644 m_channels = channels_arg;
1648 audiorecorder::get_channels ()
1654 audiorecorder::get_type ()
1660 audiorecorder::set_sample_number (
unsigned int sample_number_arg)
1662 m_sample_number = sample_number_arg;
1666 audiorecorder::get_sample_number ()
1668 return m_sample_number;
1672 audiorecorder::get_total_samples ()
1674 return m_left.size ();
1678 audiorecorder::set_end_sample (
unsigned int end_sample_arg)
1680 m_end_sample = end_sample_arg;
1684 audiorecorder::get_end_sample ()
1686 return m_end_sample;
1690 audiorecorder::reset_end_sample ()
1692 set_end_sample (m_left.size ());
1696 audiorecorder::set_tag (
const charMatrix& tag_arg)
1702 audiorecorder::get_tag ()
1708 audiorecorder::set_userdata (
const octave_value& userdata_arg)
1710 m_userdata = userdata_arg;
1714 audiorecorder::get_userdata ()
1720 audiorecorder::getaudiodata ()
1724 unsigned int ls = m_left.
size ();
1727 for (
unsigned int i = 0; i < ls; i++)
1729 audio(0, i) = m_left[i];
1730 audio(1, i) = m_right[i];
1737 audiorecorder::getplayer ()
1739 audioplayer *player =
new audioplayer ();
1741 player->set_y (getaudiodata ());
1742 player->set_fs (get_fs ());
1743 player->set_nbits (get_nbits ());
1750 audiorecorder::isrecording ()
1752 if (get_stream () ==
nullptr)
1756 err = Pa_IsStreamActive (m_stream);
1757 if (err != 0 && err != 1)
1758 error (
"audiorecorder: checking stream activity status failed");
1764 audiorecorder::record ()
1772 const unsigned int buffer_size = get_fs () / 20;
1775 if (octave_callback_function !=
nullptr)
1777 err = Pa_OpenStream (&m_stream, &(m_input_parameters),
nullptr,
1778 get_fs (), buffer_size, paClipOff,
1779 octave_record_callback,
this);
1783 err = Pa_OpenStream (&m_stream, &(m_input_parameters),
nullptr,
1784 get_fs (), buffer_size, paClipOff,
1785 portaudio_record_callback,
this);
1787 if (err != paNoError)
1788 error (
"audiorecorder: unable to open audio recording stream");
1790 err = Pa_StartStream (m_stream);
1791 if (err != paNoError)
1792 error (
"audiorecorder: unable to start audio recording stream");
1796 audiorecorder::recordblocking (
float seconds)
1804 const unsigned int buffer_size = get_fs () / 20;
1808 err = Pa_OpenStream (&m_stream, &(m_input_parameters),
nullptr,
1809 get_fs (), buffer_size, paClipOff,
nullptr,
this);
1810 if (err != paNoError)
1811 error (
"audiorecorder: unable to open audio recording stream");
1813 err = Pa_StartStream (m_stream);
1814 if (err != paNoError)
1815 error (
"audiorecorder: unable to start audio recording stream");
1817 unsigned int frames = seconds * get_fs ();
1821 for (
unsigned int i = 0; i < frames; i += buffer_size)
1825 Pa_ReadStream (get_stream (), buffer, buffer_size);
1827 if (octave_callback_function !=
nullptr)
1828 octave_record_callback (buffer,
nullptr, buffer_size,
nullptr, 0,
this);
1830 portaudio_record_callback (buffer,
nullptr, buffer_size,
nullptr, 0,
this);
1835 audiorecorder::pause ()
1837 if (get_stream () ==
nullptr)
1841 err = Pa_StopStream (m_stream);
1842 if (err != paNoError)
1843 error (
"audiorecorder: unable to stop audio recording stream");
1847 audiorecorder::resume ()
1849 if (get_stream () ==
nullptr)
1853 err = Pa_StartStream (m_stream);
1854 if (err != paNoError)
1855 error (
"audiorecorder: unable to start audio recording stream");
1859 audiorecorder::stop ()
1861 if (get_stream () ==
nullptr)
1865 if (! Pa_IsStreamStopped (get_stream ()))
1867 err = Pa_AbortStream (get_stream ());
1868 if (err != paNoError)
1869 error (
"audioplayer: unable to stop audio playback stream");
1872 err = Pa_CloseStream (m_stream);
1873 if (err != paNoError)
1874 error (
"audiorecorder: unable to close audio recording stream");
1876 set_sample_number (0);
1877 reset_end_sample ();
1882 audiorecorder::append (
float sample_l,
float sample_r)
1884 m_left.push_back (sample_l);
1885 m_right.push_back (sample_r);
1886 set_sample_number (get_sample_number () + 1);
1890 audiorecorder::get_stream ()
1897 DEFUN_DLD (__recorder_audiorecorder__, args, ,
1906 #if defined (HAVE_PORTAUDIO)
1908 int nargin = args.
length ();
1910 audiorecorder *recorder =
new audiorecorder ();
1914 recorder->set_fs (args(0).int_value ());
1915 recorder->set_nbits (args(1).int_value ());
1916 recorder->set_channels (args(2).int_value ());
1921 recorder->set_id (args(3).int_value ());
1928 octave_unused_parameter (args);
1931 "audio playback and recording through PortAudio");
1937 #if defined (HAVE_PORTAUDIO)
1939 static audiorecorder *
1946 audiorecorder *rec =
dynamic_cast<audiorecorder *
> (ncrep);
1948 error (
"audiodevinfo.cc (get_recorder): dynamic_cast to audiorecorder failed");
1955 DEFUN_DLD (__recorder_getaudiodata__, args, ,
1963 #if defined (HAVE_PORTAUDIO)
1964 retval = get_recorder (args(0))->getaudiodata ();
1966 octave_unused_parameter (args);
1969 "audio playback and recording through PortAudio");
1975 DEFUN_DLD (__recorder_get_channels__, args, ,
1983 #if defined (HAVE_PORTAUDIO)
1984 retval = get_recorder (args(0))->get_channels ();
1986 octave_unused_parameter (args);
1989 "audio playback and recording through PortAudio");
2003 #if defined (HAVE_PORTAUDIO)
2004 retval = get_recorder (args(0))->get_fs ();
2006 octave_unused_parameter (args);
2009 "audio playback and recording through PortAudio");
2023 #if defined (HAVE_PORTAUDIO)
2024 retval = get_recorder (args(0))->get_id ();
2026 octave_unused_parameter (args);
2029 "audio playback and recording through PortAudio");
2035 DEFUN_DLD (__recorder_get_nbits__, args, ,
2043 #if defined (HAVE_PORTAUDIO)
2044 retval = get_recorder (args(0))->get_nbits ();
2046 octave_unused_parameter (args);
2049 "audio playback and recording through PortAudio");
2055 DEFUN_DLD (__recorder_get_sample_number__, args, ,
2063 #if defined (HAVE_PORTAUDIO)
2064 retval = get_recorder (args(0))->get_sample_number ();
2066 octave_unused_parameter (args);
2069 "audio playback and recording through PortAudio");
2075 DEFUN_DLD (__recorder_get_tag__, args, ,
2083 #if defined (HAVE_PORTAUDIO)
2084 retval = get_recorder (args(0))->get_tag ();
2086 octave_unused_parameter (args);
2089 "audio playback and recording through PortAudio");
2095 DEFUN_DLD (__recorder_get_total_samples__, args, ,
2103 #if defined (HAVE_PORTAUDIO)
2104 retval = get_recorder (args(0))->get_total_samples ();
2106 octave_unused_parameter (args);
2109 "audio playback and recording through PortAudio");
2115 DEFUN_DLD (__recorder_get_userdata__, args, ,
2123 #if defined (HAVE_PORTAUDIO)
2124 retval = get_recorder (args(0))->get_userdata ();
2126 octave_unused_parameter (args);
2129 "audio playback and recording through PortAudio");
2135 DEFUN_DLD (__recorder_isrecording__, args, ,
2143 #if defined (HAVE_PORTAUDIO)
2144 retval = get_recorder (args(0))->isrecording ();
2146 octave_unused_parameter (args);
2149 "audio playback and recording through PortAudio");
2161 #if defined (HAVE_PORTAUDIO)
2162 get_recorder (args(0))->pause ();
2165 octave_unused_parameter (args);
2168 "audio playback and recording through PortAudio");
2172 DEFUN_DLD (__recorder_recordblocking__, args, ,
2178 #if defined (HAVE_PORTAUDIO)
2179 float seconds = args(1).float_value ();
2180 get_recorder (args(0))->recordblocking (seconds);
2183 octave_unused_parameter (args);
2186 "audio playback and recording through PortAudio");
2197 #if defined (HAVE_PORTAUDIO)
2198 audiorecorder *recorder = get_recorder (args(0));
2200 if (args.length () == 2)
2201 recorder->set_end_sample (args(1).int_value () * recorder->get_fs ());
2203 recorder->record ();
2206 octave_unused_parameter (args);
2209 "audio playback and recording through PortAudio");
2219 #if defined (HAVE_PORTAUDIO)
2220 if (args.length () == 1)
2221 get_recorder (args(0))->resume ();
2224 octave_unused_parameter (args);
2227 "audio playback and recording through PortAudio");
2237 #if defined (HAVE_PORTAUDIO)
2238 if (args.length () == 2)
2239 get_recorder (args(0))->set_fs (args(1).int_value ());
2242 octave_unused_parameter (args);
2245 "audio playback and recording through PortAudio");
2249 DEFUN_DLD (__recorder_set_tag__, args, ,
2255 #if defined (HAVE_PORTAUDIO)
2256 if (args.length () == 2)
2257 get_recorder (args(0))->set_tag (args(1).char_matrix_value ());
2260 octave_unused_parameter (args);
2263 "audio playback and recording through PortAudio");
2267 DEFUN_DLD (__recorder_set_userdata__, args, ,
2273 #if defined (HAVE_PORTAUDIO)
2274 if (args.length () == 2)
2275 get_recorder (args(0))->set_userdata (args(1));
2278 octave_unused_parameter (args);
2281 "audio playback and recording through PortAudio");
2291 #if defined (HAVE_PORTAUDIO)
2292 if (args.length () == 1)
2293 get_recorder (args(0))->stop ();
2296 octave_unused_parameter (args);
2299 "audio playback and recording through PortAudio");
2303 DEFUN_DLD (__player_audioplayer__, args, ,
2313 #if defined (HAVE_PORTAUDIO)
2315 audioplayer *recorder =
new audioplayer ();
2317 recorder->set_y (args(0));
2318 recorder->set_fs (args(1).int_value ());
2320 if (args.length () > 2)
2323 int m_nbits = args(2).int_value ();
2324 if (m_nbits != 8 && m_nbits != 16 && m_nbits != 24)
2325 error (
"audioplayer: NBITS must be 8, 16, or 24");
2327 switch (args.length ())
2330 recorder->set_nbits (m_nbits);
2334 recorder->set_nbits (m_nbits);
2335 recorder->set_id (args(3).int_value ());
2344 octave_unused_parameter (args);
2347 "audio playback and recording through PortAudio");
2353 #if defined (HAVE_PORTAUDIO)
2355 static audioplayer *
2362 audioplayer *pl =
dynamic_cast<audioplayer *
> (ncrep);
2364 error (
"audiodevinfo.cc (get_player): dynamic_cast to audioplayer failed");
2371 DEFUN_DLD (__player_get_channels__, args, ,
2379 #if defined (HAVE_PORTAUDIO)
2380 if (args.length () == 1)
2381 retval = get_player (args(0))->get_channels ();
2383 octave_unused_parameter (args);
2386 "audio playback and recording through PortAudio");
2400 #if defined (HAVE_PORTAUDIO)
2401 if (args.length () == 1)
2402 retval = get_player (args(0))->get_fs ();
2404 octave_unused_parameter (args);
2407 "audio playback and recording through PortAudio");
2421 #if defined (HAVE_PORTAUDIO)
2422 if (args.length () == 1)
2423 retval = get_player (args(0))->get_id ();
2425 octave_unused_parameter (args);
2428 "audio playback and recording through PortAudio");
2434 DEFUN_DLD (__player_get_nbits__, args, ,
2442 #if defined (HAVE_PORTAUDIO)
2443 if (args.length () == 1)
2444 retval = get_player (args(0))->get_nbits ();
2446 octave_unused_parameter (args);
2449 "audio playback and recording through PortAudio");
2455 DEFUN_DLD (__player_get_sample_number__, args, ,
2463 #if defined (HAVE_PORTAUDIO)
2464 if (args.length () == 1)
2465 retval = get_player (args(0))->get_sample_number ();
2467 octave_unused_parameter (args);
2470 "audio playback and recording through PortAudio");
2484 #if defined (HAVE_PORTAUDIO)
2485 if (args.length () == 1)
2486 retval = get_player (args(0))->get_tag ();
2488 octave_unused_parameter (args);
2491 "audio playback and recording through PortAudio");
2497 DEFUN_DLD (__player_get_total_samples__, args, ,
2505 #if defined (HAVE_PORTAUDIO)
2506 if (args.length () == 1)
2507 retval = get_player (args(0))->get_total_samples ();
2509 octave_unused_parameter (args);
2512 "audio playback and recording through PortAudio");
2518 DEFUN_DLD (__player_get_userdata__, args, ,
2526 #if defined (HAVE_PORTAUDIO)
2527 if (args.length () == 1)
2528 retval = get_player (args(0))->get_userdata ();
2530 octave_unused_parameter (args);
2533 "audio playback and recording through PortAudio");
2539 DEFUN_DLD (__player_isplaying__, args, ,
2547 #if defined (HAVE_PORTAUDIO)
2548 if (args.length () == 1)
2549 retval = get_player (args(0))->isplaying ();
2551 octave_unused_parameter (args);
2554 "audio playback and recording through PortAudio");
2566 #if defined (HAVE_PORTAUDIO)
2567 if (args.length () == 1)
2568 get_player (args(0))->pause ();
2571 octave_unused_parameter (args);
2574 "audio playback and recording through PortAudio");
2578 DEFUN_DLD (__player_playblocking__, args, ,
2586 #if defined (HAVE_PORTAUDIO)
2588 audioplayer *player = get_player (args(0));
2590 if (args.length () == 1)
2592 player->playblocking ();
2594 else if (args.length () == 2)
2596 if (args(1).is_matrix_type ())
2600 unsigned int start =
range.elem (0) - 1;
2601 unsigned int end =
range.elem (1) - 1;
2603 if (start > player->get_total_samples ()
2604 || start > end || end > player->get_total_samples ())
2605 error (
"audioplayer: invalid range specified for playback");
2607 player->set_sample_number (start);
2608 player->set_end_sample (end);
2612 unsigned int start = args(1).int_value () - 1;
2614 if (start > player->get_total_samples ())
2615 error (
"audioplayer: invalid range specified for playback");
2617 player->set_sample_number (start);
2620 player->playblocking ();
2625 octave_unused_parameter (args);
2628 "audio playback and recording through PortAudio");
2640 #if defined (HAVE_PORTAUDIO)
2642 if (args.length () == 1)
2644 get_player (args(0))->play ();
2646 else if (args.length () == 2)
2648 audioplayer *player = get_player (args(0));
2650 if (args(1).is_matrix_type ())
2654 unsigned int start =
range.elem (0) - 1;
2655 unsigned int end =
range.elem (1) - 1;
2657 if (start > player->get_total_samples ()
2658 || start > end || end > player->get_total_samples ())
2659 error (
"audioplayer: invalid range specified for playback");
2661 player->set_sample_number (start);
2662 player->set_end_sample (end);
2666 unsigned int start = args(1).int_value () - 1;
2668 if (start > player->get_total_samples ())
2669 error (
"audioplayer: invalid range specified for playback");
2671 player->set_sample_number (start);
2679 octave_unused_parameter (args);
2682 "audio playback and recording through PortAudio");
2692 #if defined (HAVE_PORTAUDIO)
2693 if (args.length () == 1)
2694 get_player (args(0))->resume ();
2697 octave_unused_parameter (args);
2700 "audio playback and recording through PortAudio");
2710 #if defined (HAVE_PORTAUDIO)
2711 if (args.length () == 2)
2712 get_player (args(0))->set_fs (args(1).int_value ());
2715 octave_unused_parameter (args);
2718 "audio playback and recording through PortAudio");
2728 #if defined (HAVE_PORTAUDIO)
2729 if (args.length () == 2)
2730 get_player (args(0))->set_tag (args(1).char_matrix_value ());
2733 octave_unused_parameter (args);
2736 "audio playback and recording through PortAudio");
2740 DEFUN_DLD (__player_set_userdata__, args, ,
2746 #if defined (HAVE_PORTAUDIO)
2747 if (args.length () == 2)
2748 get_player (args(0))->set_userdata (args(1));
2751 octave_unused_parameter (args);
2754 "audio playback and recording through PortAudio");
2764 #if defined (HAVE_PORTAUDIO)
2765 if (args.length () == 1)
2766 get_player (args(0))->stop ();
2769 octave_unused_parameter (args);
2772 "audio playback and recording through PortAudio");
2776 OCTAVE_END_NAMESPACE(
octave)
octave_idx_type rows() const
const T * data() const
Size of the specified dimension.
octave_idx_type columns() const
octave_idx_type numel() const
Number of elements in the array.
void resize(octave_idx_type nr, octave_idx_type nc, double rfv=0)
ColumnVector column(octave_idx_type i) const
Vector representing the dimensions (size) of an Array.
octave_value_list feval(const char *name, const octave_value_list &args=octave_value_list(), int nargout=0)
Evaluate an Octave function (built-in or interpreted) and return the list of result values.
virtual bool is_constant() const
virtual void print_raw(std::ostream &os, bool pr_as_read_syntax=false) const
virtual bool print_as_scalar() const
virtual double scalar_value(bool frc_str_conv=false) const
virtual void print(std::ostream &os, bool pr_as_read_syntax=false)
virtual bool is_defined() const
void setfield(const std::string &key, const Cell &val)
void setfield(const std::string &key, const octave_value &val)
octave_idx_type length() const
int int_value(bool req_int=false, bool frc_str_conv=false) const
bool is_int8_type() const
const octave_base_value & get_rep() const
bool is_uint8_type() const
bool is_int16_type() const
Matrix matrix_value(bool frc_str_conv=false) const
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
#define DEFUN_DLD(name, args_name, nargout_name, doc)
Macro to define an at run time dynamically loadable builtin function.
void warning_with_id(const char *id, const char *fmt,...)
void() error(const char *fmt,...)
void err_disabled_feature(const std::string &fcn, const std::string &feature, const std::string &pkg)
ColumnVector transform(const Matrix &m, double x, double y, double z)
interpreter & __get_interpreter__()
octave_int< T > pow(const octave_int< T > &a, const octave_int< T > &b)
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
#define DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
#define DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(t, n, c)
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
std::size_t format(std::ostream &os, const char *fmt,...)