23 #if defined (HAVE_CONFIG_H)
45 #if defined (HAVE_PORTAUDIO)
47 #include <portaudio.h>
50 bits_to_format (
int bits)
103 #if defined (HAVE_PORTAUDIO)
114 PaError
err = Pa_Initialize ();
116 if (err != paNoError)
117 error (
"audiodevinfo: PortAudio initialization failed");
119 int num_devices = Pa_GetDeviceCount ();
122 error (
"audiodevinfo: no audio device found");
125 for (
int i = 0;
i < num_devices;
i++)
127 const PaDeviceInfo *device_info = Pa_GetDeviceInfo (
i);
131 warning (
"Octave:invalid-audio-device",
132 "invalid audio device ID = %d",
i);
136 if (device_info->maxInputChannels != 0)
139 if (device_info->maxOutputChannels != 0)
151 for (
int i = 0;
i < num_devices;
i++)
153 const PaDeviceInfo *device_info = Pa_GetDeviceInfo (
i);
157 warning (
"Octave:invalid-audio-device",
158 "invalid audio device ID = %d",
i);
162 const PaHostApiInfo *api_info = Pa_GetHostApiInfo (device_info->hostApi);
164 const char *driver = api_info ? api_info->name :
"";
167 sprintf (name,
"%s (%s)", device_info->name, driver);
169 if (device_info->maxInputChannels != 0)
171 input_name(idx_i) =
name;
172 input_driver_version(idx_i) = driver;
177 if (device_info->maxOutputChannels != 0)
179 output_name(idx_o) =
name;
180 output_driver_version(idx_o) = driver;
181 output_id(idx_o) =
i;
187 inputdev.
setfield (
"Name", input_name);
188 inputdev.
setfield (
"DriverVersion", input_driver_version);
190 outputdev.
setfield (
"Name", output_name);
191 outputdev.
setfield (
"DriverVersion", output_driver_version);
192 outputdev.
setfield (
"ID", output_id);
193 devinfo.
setfield (
"input", inputdev);
194 devinfo.
setfield (
"output", outputdev);
203 else if (nargin == 1)
205 if (
args(0).int_value () == 0)
207 else if (
args(0).int_value () == 1)
210 error (
"audiodevinfo: please specify 0 for output and 1 for input devices");
213 else if (nargin == 2)
216 int outin =
args(0).int_value ();
217 if (
args(1).is_string ())
221 for (
int i = 0;
i < numoutput;
i++)
223 if (output_name(
i).string_value () ==
args(1).string_value ())
225 retval = output_id(
i);
233 for (
int i = 0;
i < numinput;
i++)
235 if (input_name(
i).string_value () ==
args(1).string_value ())
237 retval = input_id(
i);
244 error (
"audiodevinfo: please specify 0 for output and 1 for input devices");
250 for (
int i = 0;
i < numoutput;
i++)
252 if (output_id(
i).int_value () ==
args(1).int_value ())
254 retval = output_name(
i);
262 for (
int i = 0;
i < numinput;
i++)
264 if (input_id(
i).int_value () ==
args(1).int_value ())
266 retval = input_name(
i);
273 error (
"audiodevinfo: please specify 0 for output and 1 for input devices");
277 error (
"audiodevinfo: no device meeting the specified criteria found");
279 else if (nargin == 3)
284 else if (nargin == 4)
286 int io =
args(0).int_value ();
287 int rate =
args(1).int_value ();
288 int bits =
args(2).int_value ();
289 int chans =
args(3).int_value ();
291 for (
int i = 0;
i < num_devices;
i++)
293 PaStreamParameters stream_parameters;
294 stream_parameters.device =
i;
295 stream_parameters.channelCount = chans;
296 PaSampleFormat
format = bits_to_format (bits);
299 stream_parameters.sampleFormat =
format;
301 error (
"audiodevinfo: no such bits per sample format");
303 const PaDeviceInfo *device_info = Pa_GetDeviceInfo (
i);
307 warning (
"Octave:invalid-audio-device",
308 "invalid audio device ID = %d",
i);
312 stream_parameters.suggestedLatency
313 = device_info->defaultLowInputLatency;
315 stream_parameters.hostApiSpecificStreamInfo = 0;
319 if (device_info->maxOutputChannels < chans)
322 err = Pa_IsFormatSupported (0, &stream_parameters, rate);
324 if (err == paFormatIsSupported)
332 if (device_info->maxInputChannels < chans)
335 err = Pa_IsFormatSupported (&stream_parameters, 0, rate);
336 if (err == paFormatIsSupported)
346 else if (nargin == 5)
348 int io =
args(0).int_value ();
349 int id =
args(1).int_value ();
350 int rate =
args(2).int_value ();
351 int bits =
args(3).int_value ();
352 int chans =
args(4).int_value ();
353 PaStreamParameters stream_parameters;
354 stream_parameters.device =
id;
355 stream_parameters.channelCount = chans;
356 PaSampleFormat
format = bits_to_format (bits);
358 stream_parameters.sampleFormat =
format;
360 error (
"audiodevinfo: no such bits per sample format");
362 const PaDeviceInfo *device_info = Pa_GetDeviceInfo (
id);
365 error (
"audiodevinfo: invalid audio device ID = %d",
id);
367 stream_parameters.suggestedLatency
368 = device_info->defaultLowInputLatency;
370 stream_parameters.hostApiSpecificStreamInfo = 0;
373 if (device_info->maxOutputChannels < chans)
378 err = Pa_IsFormatSupported (0, &stream_parameters, rate);
379 if (err == paFormatIsSupported)
387 if (device_info->maxInputChannels < chans)
392 err = Pa_IsFormatSupported (&stream_parameters, 0, rate);
393 if (err == paFormatIsSupported)
400 error (
"audiodevinfo: please specify 0 for output and 1 for input devices");
408 octave_unused_parameter (
args);
411 "audio playback and recording through PortAudio");
451 #if defined (HAVE_PORTAUDIO)
453 enum audio_type { TYPE_INT8, TYPE_UINT8, TYPE_UINT16, TYPE_DOUBLE };
462 double player_value (
void)
const {
return 0; }
463 virtual double scalar_value (
bool =
false)
const {
return 0; }
464 void print (std::ostream& os,
bool pr_as_read_syntax =
false);
465 void print_raw (std::ostream& os,
bool pr_as_read_syntax)
const;
480 void set_fs (
int fs);
482 void set_nbits (
int nbits);
483 int get_nbits (
void);
484 void set_id (
int id);
486 int get_channels (
void);
487 audio_type get_type (
void);
489 void set_sample_number (
unsigned int sample);
490 unsigned int get_sample_number (
void);
491 unsigned int get_total_samples (
void);
492 void set_end_sample (
unsigned int sample);
493 unsigned int get_end_sample (
void);
494 void reset_end_sample (
void);
499 PaStream *get_stream (
void);
501 void playblocking (
void);
506 bool isplaying (
void);
515 unsigned int sample_number;
516 unsigned int end_sample;
523 PaStreamParameters output_parameters;
532 octave_play_callback (
const void *,
void *output,
unsigned long frames,
533 const PaStreamCallbackTimeInfo *,
534 PaStreamCallbackFlags,
void *data)
536 audioplayer *player =
static_cast<audioplayer *
> (data);
539 error (
"audio player callback function called without player");
542 ovl (static_cast<double> (frames)), 1);
545 error (
"audio player callback function failed");
550 if (frames - sound.
rows () != 0 || sound.
columns () < 1
552 error (
"audio player callback function failed");
560 ? sound_l : sound.
column (1));
562 const double *p_l = sound_l.
data ();
563 const double *p_r = sound_r.
data ();
565 switch (player->get_nbits ())
569 static double scale_factor =
std::pow (2.0, 7) - 1.0;
571 int8_t *buffer =
static_cast<int8_t *
> (output);
573 for (
unsigned long i = 0;
i < frames;
i++)
575 buffer[2*
i] = p_l[
i] * scale_factor;
576 buffer[2*
i+1] = p_r[
i] * scale_factor;
583 static double scale_factor =
std::pow (2.0, 15) - 1.0;
585 int16_t *buffer =
static_cast<int16_t *
> (output);
587 for (
unsigned long i = 0;
i < frames;
i++)
589 buffer[2*
i] = p_l[
i] * scale_factor;
590 buffer[2*
i+1] = p_r[
i] * scale_factor;
597 static double scale_factor =
std::pow (2.0, 23) - 1.0;
601 uint8_t *buffer =
static_cast<uint8_t *
> (output);
603 for (
unsigned long i = 0;
i < frames;
i++)
605 int32_t sample_l = p_l[
i];
606 int32_t sample_r = p_r[
i];
608 sample_l &= 0x00ffffff;
609 sample_r &= 0x00ffffff;
612 uint8_t *_sample_l =
reinterpret_cast<uint8_t *
> (&sample_l);
613 uint8_t *_sample_r =
reinterpret_cast<uint8_t *
> (&sample_r);
615 unsigned long offset =
i * 6;
617 buffer[offset+0] = _sample_l[0+big_endian] * scale_factor;
618 buffer[offset+1] = _sample_l[1+big_endian] * scale_factor;
619 buffer[offset+2] = _sample_l[2+big_endian] * scale_factor;
621 buffer[offset+3] = _sample_r[0+big_endian] * scale_factor;
622 buffer[offset+4] = _sample_r[1+big_endian] * scale_factor;
623 buffer[offset+5] = _sample_r[2+big_endian] * scale_factor;
629 error (
"invalid player bit depth in callback function");
632 return return_status;
636 portaudio_play_callback (
const void *,
void *output,
unsigned long frames,
637 const PaStreamCallbackTimeInfo*,
638 PaStreamCallbackFlags,
void *data)
640 audioplayer *player =
static_cast<audioplayer *
> (data);
643 error (
"audio player callback function called without player");
651 const RowVector sound_l = player->get_left ();
652 const RowVector sound_r = player->get_right ();
654 const double *pl = sound_l.
data ();
655 const double *pr = sound_r.
data ();
657 if (player->get_type () == TYPE_DOUBLE)
659 switch (player->get_nbits ())
663 static double scale_factor =
std::pow (2.0, 7) - 1.0;
665 int8_t *buffer =
static_cast<int8_t *
> (output);
667 for (
unsigned long j = 0; j < frames; j++)
669 unsigned int sample_number = player->get_sample_number ();
671 if (sample_number >= player->get_end_sample ())
674 unsigned long offset = j * 2;
676 buffer[offset+0] = pl[sample_number] * scale_factor;
677 buffer[offset+1] = pr[sample_number] * scale_factor;
679 player->set_sample_number (sample_number + 1);
686 static double scale_factor =
std::pow (2.0, 15) - 1.0;
688 int16_t *buffer =
static_cast<int16_t *
> (output);
690 for (
unsigned long j = 0; j < frames; j++)
692 unsigned int sample_number = player->get_sample_number ();
694 if (sample_number >= player->get_end_sample ())
697 unsigned long offset = j * 2;
699 buffer[offset+0] = pl[sample_number] * scale_factor;
700 buffer[offset+1] = pr[sample_number] * scale_factor;
702 player->set_sample_number (sample_number + 1);
709 static double scale_factor =
std::pow (2.0, 23) - 1.0;
713 uint8_t *buffer =
static_cast<uint8_t *
> (output);
715 for (
unsigned long j = 0; j < frames; j++)
717 unsigned int sample_number = player->get_sample_number ();
719 if (sample_number >= player->get_end_sample ())
722 int32_t sample_l = pl[sample_number] * scale_factor;
723 int32_t sample_r = pr[sample_number] * scale_factor;
725 sample_l &= 0x00ffffff;
726 sample_r &= 0x00ffffff;
729 uint8_t *_sample_l =
reinterpret_cast<uint8_t *
> (&sample_l);
730 uint8_t *_sample_r =
reinterpret_cast<uint8_t *
> (&sample_r);
732 unsigned long offset = j * 6;
734 buffer[offset+0] = _sample_l[0+big_endian];
735 buffer[offset+1] = _sample_l[1+big_endian];
736 buffer[offset+2] = _sample_l[2+big_endian];
738 buffer[offset+3] = _sample_r[0+big_endian];
739 buffer[offset+4] = _sample_r[1+big_endian];
740 buffer[offset+5] = _sample_r[2+big_endian];
742 player->set_sample_number (sample_number + 1);
748 error (
"invalid player bit depth in callback function");
751 else if (player->get_type () == TYPE_INT8)
753 int8_t *buffer =
static_cast<int8_t *
> (output);
755 for (
unsigned long j = 0; j < frames; j++)
757 unsigned int sample_number = player->get_sample_number ();
759 if (sample_number >= player->get_end_sample ())
762 unsigned long offset = j * 2;
764 buffer[offset+0] = pl[sample_number];
765 buffer[offset+1] = pr[sample_number];
767 player->set_sample_number (sample_number + 1);
770 else if (player->get_type () == TYPE_UINT8)
772 uint8_t *buffer =
static_cast<uint8_t *
> (output);
774 for (
unsigned long j = 0; j < frames; j++)
776 unsigned int sample_number = player->get_sample_number ();
778 if (sample_number >= player->get_end_sample ())
781 unsigned long offset = j * 2;
783 buffer[offset+0] = pl[sample_number];
784 buffer[offset+1] = pr[sample_number];
786 player->set_sample_number (sample_number + 1);
789 else if (player->get_type () == TYPE_UINT16)
791 int16_t *buffer =
static_cast<int16_t *
> (output);
793 for (
unsigned long j = 0; j < frames; j++)
795 unsigned int sample_number = player->get_sample_number ();
797 if (sample_number >= player->get_end_sample ())
800 unsigned long offset = j * 2;
802 buffer[offset+0] = pl[sample_number];
803 buffer[offset+1] = pr[sample_number];
805 player->set_sample_number (sample_number + 1);
813 safe_audioplayer_stop (audioplayer *player)
818 audioplayer::audioplayer (
void)
819 : octave_callback_function (0),
820 id (-1),
fs (0), nbits (16), channels (0), sample_number (0),
821 end_sample (-1), tag (
""),
y (), userdata (
Matrix ()),
825 audioplayer::~audioplayer (
void)
829 warning (
"Octave:audio-interrupt",
830 "interrupting playing audioplayer");
836 audioplayer::print (std::ostream& os,
bool pr_as_read_syntax)
838 print_raw (os, pr_as_read_syntax);
843 audioplayer::print_raw (std::ostream& os,
bool)
const
849 audioplayer::init_fn (
void)
851 if (Pa_Initialize () != paNoError)
852 error (
"audioplayer: initialization error!");
854 if (Pa_GetDeviceCount () < 1)
855 error (
"audioplayer: no audio devices found or available!");
857 int device = get_id ();
860 device = Pa_GetDefaultOutputDevice ();
862 output_parameters.device = device;
863 output_parameters.channelCount = 2;
864 output_parameters.sampleFormat = bits_to_format (get_nbits ());
866 const PaDeviceInfo *device_info = Pa_GetDeviceInfo (device);
869 warning (
"Octave:invalid-default-audio-device",
870 "invalid default audio device ID = %d", device);
872 output_parameters.suggestedLatency
873 = device_info ? device_info->defaultHighOutputLatency : -1;
875 output_parameters.hostApiSpecificStreamInfo = 0;
879 audioplayer::init (
void)
887 if (Pa_Initialize () != paNoError)
888 error (
"audioplayer: initialization error!");
890 if (Pa_GetDeviceCount () < 1)
891 error (
"audioplayer: no audio devices found or available!");
893 int device = get_id ();
896 device = Pa_GetDefaultOutputDevice ();
898 output_parameters.device = device;
899 output_parameters.channelCount = 2;
901 if (
type == TYPE_DOUBLE)
902 output_parameters.sampleFormat = bits_to_format (get_nbits ());
903 else if (
type == TYPE_INT8)
904 output_parameters.sampleFormat = paInt8;
905 else if (
type == TYPE_UINT8)
906 output_parameters.sampleFormat = paUInt8;
907 else if (
type == TYPE_UINT16)
908 output_parameters.sampleFormat = paInt16;
910 const PaDeviceInfo *device_info = Pa_GetDeviceInfo (device);
913 warning (
"Octave:invalid-default-audio-device",
914 "invalid default audio device ID = %d", device);
916 output_parameters.suggestedLatency
917 = device_info ? device_info->defaultHighOutputLatency : -1;
919 output_parameters.hostApiSpecificStreamInfo = 0;
939 channels =
y.rows ();
951 octave_callback_function = fn;
957 audioplayer::get_y (
void)
963 audioplayer::get_left (
void)
const
969 audioplayer::get_right (
void)
const
975 audioplayer::set_fs (
int fs_arg)
981 audioplayer::get_fs (
void)
987 audioplayer::set_nbits (
int nbits_arg)
993 audioplayer::get_nbits (
void)
999 audioplayer::set_id (
int id_arg)
1005 audioplayer::get_id (
void)
1011 audioplayer::get_channels (
void)
1017 audioplayer::get_type (
void)
1023 audioplayer::set_sample_number (
unsigned int sample_number_arg)
1025 sample_number = sample_number_arg;
1029 audioplayer::get_sample_number (
void)
1031 return sample_number;
1035 audioplayer::get_total_samples (
void)
1037 return left.numel ();
1041 audioplayer::set_end_sample (
unsigned int end_sample_arg)
1043 end_sample = end_sample_arg;
1047 audioplayer::get_end_sample (
void)
1053 audioplayer::reset_end_sample (
void)
1055 set_end_sample (
left.numel ());
1059 audioplayer::set_tag (
const charMatrix& tag_arg)
1065 audioplayer::get_tag (
void)
1071 audioplayer::set_userdata (
const octave_value& userdata_arg)
1073 userdata = userdata_arg;
1077 audioplayer::get_userdata (
void)
1083 audioplayer::playblocking (
void)
1088 const unsigned int buffer_size = get_fs () / 20;
1092 err = Pa_OpenStream (&stream, 0, &(output_parameters), get_fs (),
1093 buffer_size, paClipOff, 0, 0);
1094 if (err != paNoError)
1095 error (
"audioplayer: unable to open audio playback stream");
1097 err = Pa_StartStream (stream);
1098 if (err != paNoError)
1099 error (
"audioplayer: unable to start audio playback stream");
1101 unsigned int start, end;
1102 start = get_sample_number ();
1103 end = get_end_sample ();
1107 frame.
add_fcn (safe_audioplayer_stop,
this);
1109 for (
unsigned int i = start;
i < end;
i += buffer_size)
1112 if (octave_callback_function != 0)
1113 octave_play_callback (0, buffer, buffer_size, 0, 0,
this);
1115 portaudio_play_callback (0, buffer, buffer_size, 0, 0,
this);
1117 err = Pa_WriteStream (stream, buffer, buffer_size);
1122 audioplayer::play (
void)
1127 const unsigned int buffer_size = get_fs () / 20;
1130 if (octave_callback_function != 0)
1131 err = Pa_OpenStream (&stream, 0, &(output_parameters),
1132 get_fs (), buffer_size, paClipOff,
1133 octave_play_callback,
this);
1135 err = Pa_OpenStream (&stream, 0, &(output_parameters),
1136 get_fs (), buffer_size, paClipOff,
1137 portaudio_play_callback,
this);
1139 if (err != paNoError)
1140 error (
"audioplayer: failed to open audio playback stream");
1142 err = Pa_StartStream (stream);
1143 if (err != paNoError)
1144 error (
"audioplayer: failed to start audio playback stream");
1150 if (get_stream () == 0)
1154 err = Pa_StopStream (stream);
1155 if (err != paNoError)
1156 error (
"audiorecorder: failed to stop audio recording stream");
1160 audioplayer::resume (
void)
1162 if (get_stream () == 0)
1166 err = Pa_StartStream (stream);
1167 if (err != paNoError)
1168 error (
"audiorecorder: failed to start audio recording stream");
1172 audioplayer::get_stream (
void)
1178 audioplayer::stop (
void)
1180 if (get_stream () == 0)
1184 set_sample_number (0);
1185 reset_end_sample ();
1186 if (! Pa_IsStreamStopped (get_stream ()))
1188 err = Pa_AbortStream (get_stream ());
1189 if (err != paNoError)
1190 error (
"audioplayer: failed to stop audio playback stream");
1193 err = Pa_CloseStream (get_stream ());
1194 if (err != paNoError)
1195 error (
"audioplayer: failed to close audio playback stream");
1201 audioplayer::isplaying (
void)
1203 if (get_stream () == 0)
1207 err = Pa_IsStreamActive (stream);
1208 if (err != 0 && err != 1)
1209 error (
"audiorecorder: checking stream activity status failed");
1217 audiorecorder (
void);
1218 ~audiorecorder (
void);
1221 double player_value (
void)
const {
return 0; }
1222 virtual double scalar_value (
bool =
false)
const {
return 0; }
1223 void print (std::ostream& os,
bool pr_as_read_syntax =
false);
1224 void print_raw (std::ostream& os,
bool pr_as_read_syntax)
const;
1228 bool is_defined (
void)
const {
return true; }
1232 void set_fs (
int fs);
1234 void set_nbits (
int nbits);
1235 int get_nbits (
void);
1236 void set_id (
int id);
1238 void set_channels (
int channels);
1239 int get_channels (
void);
1240 audio_type get_type (
void);
1242 void set_sample_number (
unsigned int sample);
1243 unsigned int get_sample_number (
void);
1244 unsigned int get_total_samples (
void);
1245 void set_end_sample (
unsigned int sample);
1246 unsigned int get_end_sample (
void);
1247 void reset_end_sample (
void);
1252 PaStream *get_stream (
void);
1255 audioplayer *getplayer (
void);
1256 bool isrecording (
void);
1257 audioplayer play (
void);
1259 void recordblocking (
float seconds);
1263 void append (
float sample_l,
float sample_r);
1272 unsigned int sample_number;
1273 unsigned int end_sample;
1277 std::vector<float>
left;
1278 std::vector<float>
right;
1280 PaStreamParameters input_parameters;
1289 octave_record_callback (
const void *
input,
void *,
unsigned long frames,
1290 const PaStreamCallbackTimeInfo *,
1291 PaStreamCallbackFlags,
void *data)
1293 audiorecorder *recorder =
static_cast<audiorecorder *
> (data);
1296 error (
"audio recorder callback function called without player");
1298 int channels = recorder->get_channels ();
1300 Matrix sound (frames, 2);
1301 sound.
resize (frames, 2);
1303 if (recorder->get_nbits () == 8)
1305 static double scale_factor =
std::pow (2.0, 7) - 1.0;
1307 const int8_t *input8 =
static_cast<const int8_t *
> (
input);
1309 for (
unsigned long i = 0;
i < frames;
i++)
1311 float sample_l = input8[
i*channels] / scale_factor;
1312 float sample_r = input8[
i*channels + (channels - 1)] / scale_factor;
1314 sound(
i,0) = sample_l;
1315 sound(
i,1) = sample_r;
1318 else if (recorder->get_nbits () == 16)
1320 static double scale_factor =
std::pow (2.0, 15) - 1.0;
1322 const int16_t *input16 =
static_cast<const int16_t *
> (
input);
1324 for (
unsigned long i = 0;
i < frames;
i++)
1326 float sample_l = input16[
i*channels] / scale_factor;
1327 float sample_r = input16[
i*channels + (channels - 1)] / scale_factor;
1329 sound(
i,0) = sample_l;
1330 sound(
i,1) = sample_r;
1333 else if (recorder->get_nbits () == 24)
1335 static double scale_factor =
std::pow (2.0, 23);
1338 const uint8_t *input24 =
static_cast<const uint8_t *
> (
input);
1340 int32_t sample_l32 = 0, sample_r32 = 0;
1342 uint8_t *sample_l =
reinterpret_cast<uint8_t *
> (&sample_l32);
1343 uint8_t *sample_r =
reinterpret_cast<uint8_t *
> (&sample_r32);
1345 for (
unsigned long i = 0;
i < frames;
i++)
1347 for (
int j = 0; j < 3; j++)
1349 sample_l[j] = input24[
i*channels*3 + j];
1350 sample_r[j] = input24[
i*channels*3 + (channels - 1)*3 + j];
1353 if (sample_l32 & 0x00800000)
1354 sample_l32 |= 0xff000000;
1356 if (sample_r32 & 0x00800000)
1357 sample_r32 |= 0xff000000;
1359 sound(
i,0) = sample_l32 / scale_factor;
1360 sound(
i,1) = sample_r32 / scale_factor;
1365 =
feval (recorder->octave_callback_function,
ovl (sound), 1);
1371 portaudio_record_callback (
const void *input,
void *,
unsigned long frames,
1372 const PaStreamCallbackTimeInfo *,
1373 PaStreamCallbackFlags,
void *data)
1375 audiorecorder *recorder =
static_cast<audiorecorder *
> (data);
1378 error (
"audio recorder callback function called without player");
1380 int channels = recorder->get_channels ();
1382 if (recorder->get_nbits () == 8)
1384 static float scale_factor =
std::pow (2.0
f, 7) - 1.0f;
1386 const int8_t *input8 =
static_cast<const int8_t *
> (
input);
1388 for (
unsigned long i = 0;
i < frames;
i++)
1390 float sample_l = input8[
i*channels] / scale_factor;
1391 float sample_r = input8[
i*channels + (channels - 1)] / scale_factor;
1393 recorder->append (sample_l, sample_r);
1396 else if (recorder->get_nbits () == 16)
1398 static float scale_factor =
std::pow (2.0
f, 15) - 1.0f;
1400 const int16_t *input16 =
static_cast<const int16_t *
> (
input);
1402 for (
unsigned long i = 0;
i < frames;
i++)
1404 float sample_l = input16[
i*channels] / scale_factor;
1405 float sample_r = input16[
i*channels + (channels - 1)] / scale_factor;
1407 recorder->append (sample_l, sample_r);
1410 else if (recorder->get_nbits () == 24)
1412 static float scale_factor =
std::pow (2.0
f, 23);
1415 const uint8_t *input24 =
static_cast<const uint8_t *
> (
input);
1417 int32_t sample_l32 = 0, sample_r32 = 0;
1419 uint8_t *sample_l =
reinterpret_cast<uint8_t *
> (&sample_l32);
1420 uint8_t *sample_r =
reinterpret_cast<uint8_t *
> (&sample_r32);
1422 for (
unsigned long i = 0;
i < frames;
i++)
1424 for (
int j = 0; j < 3; j++)
1426 sample_l[j] = input24[
i*channels*3 + j];
1427 sample_r[j] = input24[
i*channels*3 + (channels - 1)*3 + j];
1430 if (sample_l32 & 0x00800000)
1431 sample_l32 |= 0xff000000;
1433 if (sample_r32 & 0x00800000)
1434 sample_r32 |= 0xff000000;
1436 recorder->append (sample_l32 / scale_factor,
1437 sample_r32 / scale_factor);
1441 if (recorder->get_sample_number () >= recorder->get_end_sample ())
1448 safe_audiorecorder_stop (audiorecorder *recorder)
1453 audiorecorder::audiorecorder (
void)
1454 : octave_callback_function (0),
1455 id (-1),
fs (44100), nbits (16), channels (2), sample_number (0),
1456 end_sample (-1), tag (
""),
y (), userdata (
Matrix ()),
1460 audiorecorder::~audiorecorder (
void)
1464 warning (
"Octave:audio-interrupt",
1465 "interrupting recording audiorecorder");
1471 audiorecorder::print (std::ostream& os,
bool pr_as_read_syntax)
1473 print_raw (os, pr_as_read_syntax);
1478 audiorecorder::print_raw (std::ostream& os,
bool)
const
1484 audiorecorder::init (
void)
1486 if (Pa_Initialize () != paNoError)
1487 error (
"audiorecorder: initialization error!");
1489 if (Pa_GetDeviceCount () < 1)
1490 error (
"audiorecorder: no audio devices found or available!");
1492 int device = get_id ();
1495 device = Pa_GetDefaultInputDevice ();
1497 input_parameters.device = device;
1498 input_parameters.channelCount = get_channels ();
1499 input_parameters.sampleFormat = bits_to_format (get_nbits ());
1501 const PaDeviceInfo *device_info = Pa_GetDeviceInfo (device);
1504 warning (
"Octave:invalid-default-audio-device",
1505 "invalid default audio device ID = %d", device);
1507 input_parameters.suggestedLatency
1508 = device_info ? device_info->defaultHighInputLatency : -1;
1510 input_parameters.hostApiSpecificStreamInfo = 0;
1514 audiorecorder::set_fs (
int fs_arg)
1520 audiorecorder::get_fs (
void)
1526 audiorecorder::set_nbits (
int nbits_arg)
1532 audiorecorder::get_nbits (
void)
1538 audiorecorder::set_id (
int id_arg)
1544 audiorecorder::get_id (
void)
1550 audiorecorder::set_channels (
int channels_arg)
1552 assert (channels_arg == 1 || channels_arg == 2);
1553 channels = channels_arg;
1557 audiorecorder::get_channels (
void)
1563 audiorecorder::get_type (
void)
1569 audiorecorder::set_sample_number (
unsigned int sample_number_arg)
1571 sample_number = sample_number_arg;
1575 audiorecorder::get_sample_number (
void)
1577 return sample_number;
1581 audiorecorder::get_total_samples (
void)
1583 return left.size ();
1587 audiorecorder::set_end_sample (
unsigned int end_sample_arg)
1589 end_sample = end_sample_arg;
1593 audiorecorder::get_end_sample (
void)
1599 audiorecorder::reset_end_sample (
void)
1601 set_end_sample (
left.size ());
1605 audiorecorder::set_tag (
const charMatrix& tag_arg)
1611 audiorecorder::get_tag (
void)
1617 audiorecorder::set_userdata (
const octave_value& userdata_arg)
1619 userdata = userdata_arg;
1623 audiorecorder::get_userdata (
void)
1629 audiorecorder::getaudiodata (
void)
1633 for (
unsigned int i = 0;
i <
left.size ();
i++)
1643 audiorecorder::getplayer (
void)
1645 audioplayer *player =
new audioplayer ();
1647 player->set_y (getaudiodata ());
1648 player->set_fs (get_fs ());
1649 player->set_nbits (get_nbits ());
1656 audiorecorder::isrecording (
void)
1658 if (get_stream () == 0)
1662 err = Pa_IsStreamActive (stream);
1663 if (err != 0 && err != 1)
1664 error (
"audiorecorder: checking stream activity status failed");
1670 audiorecorder::record (
void)
1678 const unsigned int buffer_size = get_fs () / 20;
1681 if (octave_callback_function != 0)
1683 err = Pa_OpenStream (&stream, &(input_parameters), 0,
1684 get_fs (), buffer_size, paClipOff,
1685 octave_record_callback,
this);
1689 err = Pa_OpenStream (&stream, &(input_parameters), 0,
1690 get_fs (), buffer_size, paClipOff,
1691 portaudio_record_callback,
this);
1693 if (err != paNoError)
1694 error (
"audiorecorder: unable to open audio recording stream");
1696 err = Pa_StartStream (stream);
1697 if (err != paNoError)
1698 error (
"audiorecorder: unable to start audio recording stream");
1702 audiorecorder::recordblocking (
float seconds)
1710 const unsigned int buffer_size = get_fs () / 20;
1714 err = Pa_OpenStream (&stream, &(input_parameters), 0,
1715 get_fs (), buffer_size, paClipOff, 0,
this);
1716 if (err != paNoError)
1717 error (
"audiorecorder: unable to open audio recording stream");
1719 err = Pa_StartStream (stream);
1720 if (err != paNoError)
1721 error (
"audiorecorder: unable to start audio recording stream");
1723 unsigned int frames = seconds * get_fs ();
1727 frame.
add_fcn (safe_audiorecorder_stop,
this);
1729 for (
unsigned int i = 0;
i < frames;
i += buffer_size)
1732 Pa_ReadStream (get_stream (), buffer, buffer_size);
1734 if (octave_callback_function != 0)
1735 octave_record_callback (buffer, 0, buffer_size, 0, 0,
this);
1737 portaudio_record_callback (buffer, 0, buffer_size, 0, 0,
this);
1744 if (get_stream () == 0)
1748 err = Pa_StopStream (stream);
1749 if (err != paNoError)
1750 error (
"audiorecorder: unable to stop audio recording stream");
1754 audiorecorder::resume (
void)
1756 if (get_stream () == 0)
1760 err = Pa_StartStream (stream);
1761 if (err != paNoError)
1762 error (
"audiorecorder: unable to start audio recording stream");
1766 audiorecorder::stop (
void)
1768 if (get_stream () == 0)
1772 if (! Pa_IsStreamStopped (get_stream ()))
1774 err = Pa_AbortStream (get_stream ());
1775 if (err != paNoError)
1776 error (
"audioplayer: unable to stop audio playback stream");
1779 err = Pa_CloseStream (stream);
1780 if (err != paNoError)
1781 error (
"audiorecorder: unable to close audio recording stream");
1783 set_sample_number (0);
1784 reset_end_sample ();
1791 left.push_back (sample_l);
1792 right.push_back (sample_r);
1793 set_sample_number (get_sample_number () + 1);
1797 audiorecorder::get_stream (
void)
1814 #if ! defined (HAVE_PORTAUDIO)
1815 octave_unused_parameter (
args);
1818 "audio playback and recording through PortAudio");
1823 audiorecorder* recorder =
new audiorecorder ();
1827 bool is_function = (
args(0).is_string () ||
args(0).is_function_handle ()
1828 ||
args(0).is_inline_function ());
1831 error (
"audioplayer: callbacks not yet implemented");
1836 recorder->set_fs (
args(0).int_value ());
1837 recorder->set_nbits (
args(1).int_value ());
1838 recorder->set_channels (
args(2).int_value ());
1843 recorder->set_id (
args(3).int_value ());
1854 #if defined (HAVE_PORTAUDIO)
1856 static audiorecorder *
1863 audiorecorder *rec =
dynamic_cast<audiorecorder *
> (ncrep);
1865 error (
"audiodevinfo.cc get_recorder: dynamic_cast to audiorecorder failed");
1879 #if ! defined (HAVE_PORTAUDIO)
1880 octave_unused_parameter (
args);
1883 "audio playback and recording through PortAudio");
1885 retval = get_recorder (
args(0))->getaudiodata ();
1897 #if ! defined (HAVE_PORTAUDIO)
1898 octave_unused_parameter (
args);
1901 "audio playback and recording through PortAudio");
1903 retval = get_recorder (
args(0))->get_channels ();
1915 #if ! defined (HAVE_PORTAUDIO)
1916 octave_unused_parameter (
args);
1919 "audio playback and recording through PortAudio");
1921 retval = get_recorder (
args(0))->get_fs ();
1933 #if ! defined (HAVE_PORTAUDIO)
1934 octave_unused_parameter (
args);
1937 "audio playback and recording through PortAudio");
1939 retval = get_recorder (
args(0))->get_id ();
1951 #if ! defined (HAVE_PORTAUDIO)
1952 octave_unused_parameter (
args);
1955 "audio playback and recording through PortAudio");
1957 retval = get_recorder (
args(0))->get_nbits ();
1969 #if ! defined (HAVE_PORTAUDIO)
1970 octave_unused_parameter (
args);
1973 "audio playback and recording through PortAudio");
1975 retval = get_recorder (
args(0))->get_sample_number ();
1987 #if ! defined (HAVE_PORTAUDIO)
1988 octave_unused_parameter (
args);
1991 "audio playback and recording through PortAudio");
1993 retval = get_recorder (
args(0))->get_tag ();
2005 #if ! defined (HAVE_PORTAUDIO)
2006 octave_unused_parameter (
args);
2009 "audio playback and recording through PortAudio");
2011 retval = get_recorder (
args(0))->get_total_samples ();
2023 #if ! defined (HAVE_PORTAUDIO)
2024 octave_unused_parameter (
args);
2027 "audio playback and recording through PortAudio");
2029 retval = get_recorder (
args(0))->get_userdata ();
2041 #if ! defined (HAVE_PORTAUDIO)
2042 octave_unused_parameter (
args);
2045 "audio playback and recording through PortAudio");
2047 retval = get_recorder (
args(0))->isrecording ();
2058 #if ! defined (HAVE_PORTAUDIO)
2059 octave_unused_parameter (
args);
2062 "audio playback and recording through PortAudio");
2064 get_recorder (
args(0))->pause ();
2075 #if ! defined (HAVE_PORTAUDIO)
2076 octave_unused_parameter (
args);
2079 "audio playback and recording through PortAudio");
2081 float seconds =
args(1).float_value ();
2082 get_recorder (
args(0))->recordblocking (seconds);
2094 #if ! defined (HAVE_PORTAUDIO)
2095 octave_unused_parameter (
args);
2098 "audio playback and recording through PortAudio");
2100 audiorecorder *recorder = get_recorder (
args(0));
2102 if (
args.length () == 2)
2103 recorder->set_end_sample (
args(1).int_value () * recorder->get_fs ());
2105 recorder->record ();
2116 #if ! defined (HAVE_PORTAUDIO)
2117 octave_unused_parameter (
args);
2120 "audio playback and recording through PortAudio");
2122 if (
args.length () == 1)
2123 get_recorder (
args(0))->resume ();
2134 #if ! defined (HAVE_PORTAUDIO)
2135 octave_unused_parameter (
args);
2138 "audio playback and recording through PortAudio");
2140 if (
args.length () == 2)
2141 get_recorder (
args(0))->set_fs (
args(1).int_value ());
2152 #if ! defined (HAVE_PORTAUDIO)
2153 octave_unused_parameter (
args);
2156 "audio playback and recording through PortAudio");
2158 if (
args.length () == 2)
2159 get_recorder (
args(0))->set_tag (
args(1).char_matrix_value ());
2170 #if ! defined (HAVE_PORTAUDIO)
2171 octave_unused_parameter (
args);
2174 "audio playback and recording through PortAudio");
2176 if (
args.length () == 2)
2177 get_recorder (
args(0))->set_userdata (
args(1));
2188 #if ! defined (HAVE_PORTAUDIO)
2189 octave_unused_parameter (
args);
2192 "audio playback and recording through PortAudio");
2194 if (
args.length () == 1)
2195 get_recorder (
args(0))->stop ();
2209 #if ! defined (HAVE_PORTAUDIO)
2210 octave_unused_parameter (
args);
2213 "audio playback and recording through PortAudio");
2216 int nargin =
args.length ();
2218 audioplayer* recorder =
new audioplayer ();
2221 error (
"__player_audioplayer__: Couldn't instantiate new audioplayer");
2223 bool is_function = (
args(0).is_string () ||
args(0).is_function_handle ()
2224 ||
args(0).is_inline_function ());
2227 error (
"audioplayer: callbacks not yet implemented");
2229 recorder->set_y (
args(0));
2230 recorder->set_fs (
args(1).int_value ());
2235 recorder->set_nbits (
args(2).int_value ());
2239 recorder->set_nbits (
args(2).int_value ());
2240 recorder->set_id (
args(3).int_value ());
2245 recorder->init_fn ();
2254 #if defined (HAVE_PORTAUDIO)
2256 static audioplayer *
2263 audioplayer *pl =
dynamic_cast<audioplayer *
> (ncrep);
2265 error (
"audiodevinfo.cc get_player: dynamic_cast to audioplayer failed");
2279 #if ! defined (HAVE_PORTAUDIO)
2280 octave_unused_parameter (
args);
2283 "audio playback and recording through PortAudio");
2285 if (
args.length () == 1)
2286 retval = get_player (
args(0))->get_channels ();
2298 #if ! defined (HAVE_PORTAUDIO)
2299 octave_unused_parameter (
args);
2302 "audio playback and recording through PortAudio");
2304 if (
args.length () == 1)
2305 retval = get_player (
args(0))->get_fs ();
2317 #if ! defined (HAVE_PORTAUDIO)
2318 octave_unused_parameter (
args);
2321 "audio playback and recording through PortAudio");
2323 if (
args.length () == 1)
2324 retval = get_player (
args(0))->get_id ();
2336 #if ! defined (HAVE_PORTAUDIO)
2337 octave_unused_parameter (
args);
2340 "audio playback and recording through PortAudio");
2342 if (
args.length () == 1)
2343 retval = get_player (
args(0))->get_nbits ();
2355 #if ! defined (HAVE_PORTAUDIO)
2356 octave_unused_parameter (
args);
2359 "audio playback and recording through PortAudio");
2361 if (
args.length () == 1)
2362 retval = get_player (
args(0))->get_sample_number ();
2374 #if ! defined (HAVE_PORTAUDIO)
2375 octave_unused_parameter (
args);
2378 "audio playback and recording through PortAudio");
2380 if (
args.length () == 1)
2381 retval = get_player (
args(0))->get_tag ();
2393 #if ! defined (HAVE_PORTAUDIO)
2394 octave_unused_parameter (
args);
2397 "audio playback and recording through PortAudio");
2399 if (
args.length () == 1)
2400 retval = get_player (
args(0))->get_total_samples ();
2412 #if ! defined (HAVE_PORTAUDIO)
2413 octave_unused_parameter (
args);
2416 "audio playback and recording through PortAudio");
2418 if (
args.length () == 1)
2419 retval = get_player (
args(0))->get_userdata ();
2431 #if ! defined (HAVE_PORTAUDIO)
2432 octave_unused_parameter (
args);
2435 "audio playback and recording through PortAudio");
2437 if (
args.length () == 1)
2438 retval = get_player (
args(0))->isplaying ();
2449 #if ! defined (HAVE_PORTAUDIO)
2450 octave_unused_parameter (
args);
2453 "audio playback and recording through PortAudio");
2455 if (
args.length () == 1)
2469 #if ! defined (HAVE_PORTAUDIO)
2470 octave_unused_parameter (
args);
2473 "audio playback and recording through PortAudio");
2476 audioplayer *player = get_player (
args(0));
2478 if (
args.length () == 1)
2480 player->playblocking ();
2482 else if (
args.length () == 2)
2484 if (
args(1).is_matrix_type ())
2488 unsigned int start = range.
elem (0) - 1;
2489 unsigned int end = range.
elem (1) - 1;
2491 if (start > player->get_total_samples ()
2492 || start > end || end > player->get_total_samples ())
2493 error (
"audioplayer: invalid range specified for playback");
2495 player->set_sample_number (start);
2496 player->set_end_sample (end);
2500 unsigned int start =
args(1).int_value () - 1;
2502 if (start > player->get_total_samples ())
2503 error (
"audioplayer: invalid range specified for playback");
2505 player->set_sample_number (start);
2508 player->playblocking ();
2523 #if ! defined (HAVE_PORTAUDIO)
2524 octave_unused_parameter (
args);
2527 "audio playback and recording through PortAudio");
2530 if (
args.length () == 1)
2532 get_player (
args(0))->play ();
2534 else if (
args.length () == 2)
2536 audioplayer *player = get_player (
args(0));
2538 if (
args(1).is_matrix_type ())
2542 unsigned int start = range.
elem (0) - 1;
2543 unsigned int end = range.
elem (1) - 1;
2545 if (start > player->get_total_samples ()
2546 || start > end || end > player->get_total_samples ())
2547 error (
"audioplayer: invalid range specified for playback");
2549 player->set_sample_number (start);
2550 player->set_end_sample (end);
2554 unsigned int start =
args(1).int_value () - 1;
2556 if (start > player->get_total_samples ())
2557 error (
"audioplayer: invalid range specified for playback");
2559 player->set_sample_number (start);
2575 #if ! defined (HAVE_PORTAUDIO)
2576 octave_unused_parameter (
args);
2579 "audio playback and recording through PortAudio");
2581 if (
args.length () == 1)
2582 get_player (
args(0))->resume ();
2593 #if ! defined (HAVE_PORTAUDIO)
2594 octave_unused_parameter (
args);
2597 "audio playback and recording through PortAudio");
2599 if (
args.length () == 2)
2600 get_player (
args(0))->set_fs (
args(1).int_value ());
2611 #if ! defined (HAVE_PORTAUDIO)
2612 octave_unused_parameter (
args);
2615 "audio playback and recording through PortAudio");
2617 if (
args.length () == 2)
2618 get_player (
args(0))->set_tag (
args(1).char_matrix_value ());
2629 #if ! defined (HAVE_PORTAUDIO)
2630 octave_unused_parameter (
args);
2633 "audio playback and recording through PortAudio");
2635 if (
args.length () == 2)
2636 get_player (
args(0))->set_userdata (
args(1));
2647 #if ! defined (HAVE_PORTAUDIO)
2648 octave_unused_parameter (
args);
2651 "audio playback and recording through PortAudio");
2653 if (
args.length () == 1)
2654 get_player (
args(0))->stop ();
void resize(octave_idx_type nr, octave_idx_type nc, double rfv=0)
OCTAVE_EXPORT octave_value_list isa nd deftypefn *return ovl(args(0).is_integer_type())
OCTINTERP_API void print_usage(void)
F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T F77_REAL F77_REAL &F77_RET_T F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE const F77_DBLE * f
octave_idx_type length(void) const
int int_value(bool req_int=false, bool frc_str_conv=false) const
virtual double scalar_value(bool frc_str_conv=false) const
void error(const char *fmt,...)
bool is_int8_type(void) const
void setfield(const std::string &key, const octave_value &val)
#define DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(t, n, c)
T & elem(octave_idx_type n)
OCTAVE_EXPORT octave_value_list return the value of the option it must match the dimension of the state and the relative tolerance must also be a vector of the same length tem it must match the dimension of the state and the absolute tolerance must also be a vector of the same length The local error test applied at each integration step is xample roup calculate Y_a and Y _d item Given calculate Y nd enumerate In either initial values for the given components are input
in this the arguments are accumulated from left to right
octave_idx_type rows(void) const
virtual void print(std::ostream &os, bool pr_as_read_syntax=false)
OCTAVE_EXPORT octave_value_list search each directory of the loadpath for element of the cell array and return the first that matches If the second optional argument return a cell array containing the list of all files that have the same name in the path If no files are found
#define DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
void add_fcn(void(*fcn)(void))
static bool words_big_endian(void)
const T * data(void) const
octave_int< T > pow(const octave_int< T > &a, const octave_int< T > &b)
virtual bool print_as_scalar(void) const
Matrix matrix_value(bool frc_str_conv=false) const
virtual bool is_defined(void) const
void setfield(const std::string &key, const Cell &val)
bool is_int16_type(void) const
void warning(const char *fmt,...)
virtual bool is_constant(void) const
octave::unwind_protect frame
=val(i)}if ode{val(i)}occurs in table i
bool is_uint8_type(void) const
const octave_base_value & get_rep(void) const
ColumnVector column(octave_idx_type i) const
the element is set to zero In other the statement xample y
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
octave::sys::file_stat fs(filename)
virtual void print_raw(std::ostream &os, bool pr_as_read_syntax=false) const
#define DEFUN_DLD(name, args_name, nargout_name, doc)
OCTAVE_EXPORT octave_value_list error nd deftypefn *const octave_scalar_map err
Vector representing the dimensions (size) of an Array.
void err_disabled_feature(const std::string &fcn, const std::string &feature, const std::string &pkg)
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
octave_idx_type columns(void) const
OCTAVE_EXPORT octave_value_list or cell arrays Arguments are concatenated vertically The returned values are padded with blanks as needed to make each row of the string array have the same length Empty input strings are significant and will concatenated in the output For numerical each element is converted to the corresponding ASCII character A range error results if an input is outside the ASCII range(0-255).For cell arrays