pd-0.46-7/0000775000175000017500000000000012574202336010400 5ustar mspmsppd-0.46-7/bin/0000775000175000017500000000000012574202336011150 5ustar mspmsppd-0.46-7/obj/0000775000175000017500000000000012574202336011152 5ustar mspmsppd-0.46-7/pd.pc.in0000664000175000017500000000107712160204055011730 0ustar mspmsp# Pure data pkg-config file # LATER: shouldn't "--libs" output all flags for building an external? prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ ############################### # variables # the default file-extension for externals (e.g. "l_i386") extension=@EXTERNAL_EXTENSION@ # where to install externals externaldir=${libdir}/pd/extra ############################### # core configuration Name: pd Description: Pure data externals Version: @PACKAGE_VERSION@ Cflags: -I${includedir}/pd -DPD @EXTERNAL_CFLAGS@ Libs: @EXTERNAL_LDFLAGS@ pd-0.46-7/m4/0000775000175000017500000000000012160204055010707 5ustar mspmsppd-0.46-7/m4/iphone.m40000664000175000017500000000633212160204055012437 0ustar mspmspdnl Copyright (C) 2010 IOhannes m zmölnig dnl This file is free software; IOhannes m zmölnig dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. # AM_CHECK_IPHONE (ACTION_IF_FOUND, ACTION_IF_NOT_FOUND, [ACTION_IF_FAILED]) # enables the "--with-iphone" flag; # if the iPhoneSDK is detected, this will # - set the CC & CPP to the cross-compiler ( resp preprocessor) # - as well as the apropriate CFLAGS, INCLUDES and LDFLAGS # - these values can also be found in IPHONE_CC, IPHONE_CPP, # IPHONE_INCLUDES, IPHONE_ARCH, IPHONE_CFLAGS, IPHONE_LDFLAGS # it will then call ACTION_IF_FOUND # elif ACTION_IF_FAILED is set and the iPhoneSDK is not detected even though the user # requested it (by specifying a path, or simply saying "--with-iphone=yes"), # then ACTION_IF_FAILED is called # else # ACTION_IF_NOT_FOUND is called # # TODO: only run checks when architecture is right (x-compiling) # hc's code used "arm*darwin*" # -------------------------------------------------------------- AC_DEFUN([PD_CHECK_IPHONE], [ AC_REQUIRE([AC_CANONICAL_HOST])dnl define([iphonepath_default],[/Developer/Platforms/iPhoneOS.platform/Developer]) define([iphoneversion_default],[3.0]) AC_ARG_WITH([iphone], AS_HELP_STRING( [--with-iphone=], [specify iPhone BaseDirectory (only used when building for iPhone) [iphonepath_default]]), iphonepath=$withval) AC_ARG_WITH([iphoneversion], AS_HELP_STRING( [--with-iphoneversion=], [specify iPhone SDK version (only used when building for iPhone) [iphoneversion_default]]), iphone_version=$withval) case $host in arm*darwin*) ;; *) AC_MSG_NOTICE([iPhone SDK only available for arm-apple-darwin hosts, skipping tests]) with_iphone="no" ;; esac if test "x${with_iphone}" != "xno" ; then AC_MSG_CHECKING([iPhone SDK]) if test "x${iphonepath}" = "xyes" || test "x${iphonepath}" = "x"; then iphonepath=iphonepath_default fi if test "x${iphone_version}" = "x"; then iphone_version=iphoneversion_default fi IPHONE_CC="${iphonepath}/usr/bin/gcc" IPHONE_CPP="${iphonepath}/usr/bin/cpp" IPHONE_SYSROOT="${iphonepath}/SDKs/iPhoneOS${iphone_version}.sdk" #echo "sysroot = ${IPHONE_SYSROOT}" #echo "cpp = ${IPHONE_CPP}" #echo "cc = ${IPHONE_CC}" if test -d "${IPHONE_SYSROOT}" && test -x "${IPHONE_CC}" && test -x "${IPHONE_CPP}"; then CC="${IPHONE_CC}" CPP="${IPHONE_CPP}" IPHONE_ARCH="-arch armv6" IPHONE_CFLAGS="-miphoneos-version-min=${iphone_version} -isysroot ${IPHONE_SYSROT}" IPHONE_LDFLAGS="" CFLAGS="${CFLAGS} ${IPHONE_CFLAGS} ${IPHONE_ARCH}" LDFLAGS="${LDFLAGS} ${IPHONE_ARCH} ${LDFLAGS}" # workaround for rpl_malloc/rpl_realloc bug in autoconf when cross-compiling ac_cv_func_malloc_0_nonnull=yes ac_cv_func_realloc_0_nonnull=yes _iphone_result=yes AC_MSG_RESULT([yes]) [$1] else _iphone_result=no IPHONE_CC="" IPHONE_CPP="" IPHONE_SYSROOT="" if test "x${with_iphone}" = "x"; then with_iphone="no" fi AC_MSG_RESULT([no]) if test "x${with_iphone}" = "xno"; then : [$2] else : ifelse([$3], , [$2], [$3]) fi fi else # --without-iphone [$2] fi undefine([iphonepath_default]) undefine([iphoneversion_default]) ])pd-0.46-7/m4/config/0000755000175000017500000000000012053314300012146 5ustar mspmsppd-0.46-7/m4/generated/0000775000175000017500000000000012053314276012655 5ustar mspmsppd-0.46-7/m4/android.m40000664000175000017500000001027712160204055012600 0ustar mspmspdnl Copyright (C) 2010 IOhannes m zmölnig dnl This file is free software; IOhannes m zmölnig dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. # AM_CHECK_ANDROID (ACTION_IF_FOUND, ACTION_IF_NOT_FOUND, [ACTION_IF_FAILED]) # enables the "--with-android" flag; # if the androidSDK is detected, this will # - set the CC & CPP to the cross-compiler ( resp preprocessor) # - as well as the apropriate CFLAGS, INCLUDES and LDFLAGS # - these values can also be found in ANDROID_CC, ANDROID_CPP, # ANDROID_INCLUDES, ANDROID_ARCH, ANDROID_CFLAGS, ANDROID_LDFLAGS # it will then call ACTION_IF_FOUND # elif ACTION_IF_FAILED is set and the androidSDK is not detected even though the user # requested it (by specifying a path, or simply saying "--with-android=yes"), # then ACTION_IF_FAILED is called # else # ACTION_IF_NOT_FOUND is called # # TODO: only run checks when architecture is right (x-compiling) # hc's code used "arm-linux" # -------------------------------------------------------------- AC_DEFUN([PD_CHECK_ANDROID], [ define([androidpath_default],[${HOME}/src/android/android-ndk-1.6_r1]) define([androidversion_default],[android-4]) AC_ARG_WITH([android], AS_HELP_STRING( [--with-android=], [specify path to Android SDK (only used when building for Android) [androidpath_default]]), android_path=$withval) AC_ARG_WITH([androidversion], AS_HELP_STRING( [--with-androidversion=], [specify Android target version (only used when building for Android) [androidversion_default]]), android_target_platform=$withval) case $host in arm-linux) ;; *) AC_MSG_NOTICE([Android SDK only available for arm-linux hosts, skipping tests]) with_android="no" ;; esac if test "x${with_android}" != "xno" ; then AC_MSG_CHECKING([android SDK]) if test "x${android_path}" = "xyes"; then android_path=androidpath_default fi if test "x${android_target_platform}" = "x"; then android_target_platform=androidversion_default fi android_target_arch_abi=arm android_gcc_path="${android_path}/build/prebuilt/linux-x86/arm-eabi-4.2.1/bin" ANDROID_CPP="${android_gcc_path}/arm-eabi-cpp" ANDROID_CC="${android_gcc_path}/arm-eabi-gcc" ANDROID_LD="${android_gcc_path}/arm-eabi-ld" ANDROID_SYSROOT="${android_path}/build/platforms/${android_target_platform}/arch-${android_target_arch_abi}" if test -d "${ANDROID_SYSROOT}/usr/include" && test -x "${ANDROID_CC}" && test -x "${ANDROID_LD}" && test -x "${ANDROID_CPP}"; then CPP="${ANDROID_CPP}" CC="${ANDROID_CC}" LD="${ANDROID_LD}" android_target_libgcc=$(${ANDROID_CC} -print-libgcc-file-name) #ah, i don't like all this... #why do we have to specify _HAVE_UNISTD_H and HAVE_GL: can't we use autoconf tests? ANDROID_DEFS="-DANDROID -D__linux__ -D_HAVE_UNISTD_H -DHAVE_LIBGL -D__BSD_VISIBLE= 1" ANDROID_INCLUDES="-I${ANDROID_SYSROOT}/usr/include" # what broken compiler is this, if we have to specify all the architecture defines manually? ANDROID_ARCH_CFLAGS="-march=armv5te -mtune=xscale -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__" #shan't we test for these flags? ANDROID_OPT_CFLAGS=" -msoft-float -fpic -mthumb-interwork -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -mthumb -fno-strict-aliasing -finline-limit=64 -O2" ANDROID_CFLAGS="${ANDROID_ARCH_CFLAGS} ${ANDROID_OPT_CFLAGS}" ANDROID_LDFLAGS="-nostdlib -Wl,--no-undefined -Wl,-rpath-link=${ANDROID_SYSROOT}/usr/lib ${android_target_libgcc}" INCLUDES="${INCLUDES} ${ANDROID_INCLUDES}" CFLAGS="${CFLAGS} ${ANDROID_CFLAGS}" LDFLAGS="${LDFLAGS} ${ANDROID_LDFLAGS}" # workaround for rpl_malloc/rpl_realloc bug in autoconf when cross-compiling ac_cv_func_malloc_0_nonnull=yes ac_cv_func_realloc_0_nonnull=yes AC_MSG_RESULT([yes]) [$1] else ANDROID_CPP="" ANDROID_CC="" ANDROID_LD="" ANDROID_SYSROOT="" if test "x${with_android}" = "x"; then with_android="no" fi AC_MSG_RESULT([no]) if test "x${with_android}" = "xno"; then : [$2] else : ifelse([$3], , [$2], [$3]) fi fi else # --without-android [$2] fi undefine([androidpath_default]) undefine([androidversion_default]) ])pd-0.46-7/m4/universal.m40000664000175000017500000000554012160204055013165 0ustar mspmspdnl Copyright (C) 2005-2010 IOhannes m zmölnig dnl This file is free software; IOhannes m zmölnig dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. # PD_CHECK_UNIVERSAL([VARIABLE-NAME], [ACTION-IF-SUCCESS], [ACTION-IF-NO-SUCCESS]) # will enable the "--enable-universal=" flag # if is "yes", platform defaults are used # the system tries to build a test program with the archs, on succes it calls ACTION-IF-SUCCESS, and ACTION-IF-NO-SUCCESS otherwise # on success it will also add the flags to: # [VARIABLE-NAME]_CFLAGS will hold a list of cflags to compile for all requested archs # [VARIABLE-NAME]_LDFLAGS will hold a list of ldflags to link for all requested archs AC_DEFUN([PD_CHECK_UNIVERSAL], [ AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_ARG_ENABLE(universal, [ --enable-universal= build an Apple Multi Architecture Binary (MAB); ARCHS is a comma-delimited list of architectures for which to build; if ARCHS is omitted, then the package will be built for all architectures supported by the platform (e.g. "ppc,i386" for MacOS/X and Darwin); if this option is disabled or omitted entirely, then the package will be built only for the target platform], [universal_binary=$enableval], [universal_binary=no]) if test "$universal_binary" != no; then AC_MSG_CHECKING([target architectures]) # Respect TARGET_ARCHS setting from environment if available. if test -z "$TARGET_ARCHS"; then # Respect ARCH given to --enable-universal-binary if present. if test "$universal_binary" != yes; then TARGET_ARCHS=$(echo "$universal_binary" | tr ',' ' ') else # Choose a default set of architectures based upon platform. case $host in *darwin*) TARGET_ARCHS="ppc i386" ;; *) TARGET_ARCHS="" ;; esac fi fi AC_MSG_RESULT([$TARGET_ARCHS]) # /usr/lib/arch_tool -archify_list $TARGET_ARCHS _pd_universal="" for archs in $TARGET_ARCHS do _pd_universal="$_pd_universal -arch $archs" done dnl run checks whether the compiler linker like this... if test "x$_pd_universal" != "x"; then tmp_arch_cflags="$CFLAGS" tmp_arch_ldflags="$LDFLAGS" CFLAGS="$CFLAGS $_pd_universal" LDFLAGS="$LDFLAGS $_universal" AC_TRY_LINK([], [return 0;], [ if test "x$1" != "x"; then $1[]_CFLAGS="$[]$1[]_CFLAGS $_pd_universal" $1[]_LDFLAGS="$[]$1[]_LDFLAGS $_pd_universal" AC_SUBST($1[]_CFLAGS) AC_SUBST($1[]_LDFLAGS) fi [$2] ], [ : [$3] ]) CFLAGS="$tmp_arch_cflags" LDFLAGS="$tmp_arch_ldflags" else : [$3] fi else : [$3] fi ])# GEM_CHECK_UNIVERSAL pd-0.46-7/po/0000775000175000017500000000000012374250720011014 5ustar mspmsppd-0.46-7/po/de.po0000664000175000017500000006547712160204055011760 0ustar mspmsp# German translation of Pure Data # This file is put in the public domain # Max Neupert , 2009. # msgid "" msgstr "" "Project-Id-Version: Pure Data 0.43\n" "Report-Msgid-Bugs-To: pd-dev@iem.at\n" "POT-Creation-Date: 2009-08-27 10:01-0400\n" "PO-Revision-Date: 2009-09-22 13:00-0400\n" "Last-Translator: Max Neupert \n" "Language-Team: Deutsch \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "Undo duplicate" msgstr "Duplizieren widerrufen" msgid "Undo paste" msgstr "Einfügen widerrufen" msgid "Undo motion" msgstr "Bewegen widerrufen" msgid "Undo cut" msgstr "Ausschneiden widerrufen" msgid "Undo disconnect" msgstr "Trennen widerrufen" msgid "Undo connect" msgstr "Verbinden widerrufen" msgid "Undo clear" msgstr "Löschen widerrufen" msgid "Undo typing" msgstr "Eingabe widerrufen" msgid "Discard changes to '%s'?" msgstr "Änderungen an '%s' verwerfen?" msgid "Do you want to save the changes you made in '%s'?" msgstr "Änderungen in '%s' speichern?" #: ../src/dialog_array.tcl:115 #: ../src/dialog_array.tcl:117 #: ../src/pd_menus.tcl:100 #: ../src/pd_menus.tcl:101 #: ../src/pd_menus.tcl:146 #: ../src/pd_menus.tcl:147 msgid "Copy" msgstr "Kopieren" #: ../src/dialog_array.tcl:118 #: ../src/dialog_array.tcl:120 #: ../src/pd_menus.tcl:102 #: ../src/pd_menus.tcl:103 #: ../src/pd_menus.tcl:148 #: ../src/pd_menus.tcl:149 msgid "Paste" msgstr "Einfügen" #: ../src/dialog_array.tcl:264 #: ../src/dialog_array.tcl:266 msgid "Array Properties" msgstr "Feld-Eingenschaften" #: ../src/dialog_array.tcl:270 #: ../src/dialog_array.tcl:272 msgid "Name:" msgstr "Name:" #: ../src/dialog_array.tcl:276 #: ../src/dialog_array.tcl:278 #: ../src/dialog_canvas.tcl:178 #: ../src/dialog_canvas.tcl:193 #: ../src/dialog_iemgui.tcl:619 #: ../src/dialog_iemgui.tcl:621 msgid "Size:" msgstr "Größe:" #: ../src/dialog_array.tcl:280 #: ../src/dialog_array.tcl:282 msgid "Save contents" msgstr "Inhalt speichern" #: ../src/dialog_array.tcl:284 #: ../src/dialog_array.tcl:286 msgid "Draw as:" msgstr "Zeichne als:" #: ../src/dialog_array.tcl:287 #: ../src/dialog_array.tcl:289 msgid "Points" msgstr "Punkte" #: ../src/dialog_array.tcl:289 #: ../src/dialog_array.tcl:291 msgid "Polygon" msgstr "Vieleck" #: ../src/dialog_array.tcl:291 #: ../src/dialog_array.tcl:293 msgid "Bezier curve" msgstr "Bezier Kurve" #: ../src/dialog_array.tcl:297 #: ../src/dialog_array.tcl:299 msgid "Put array into:" msgstr "Feld einfügen in:" #: ../src/dialog_array.tcl:300 #: ../src/dialog_array.tcl:302 msgid "New graph" msgstr "Neue Kurve" #: ../src/dialog_array.tcl:302 #: ../src/dialog_array.tcl:304 msgid "Last graph" msgstr "Letzte Kurve" #: ../src/dialog_array.tcl:306 #: ../src/dialog_array.tcl:308 msgid "Delete array" msgstr "Feld löschen" #: ../src/dialog_array.tcl:312 #: ../src/dialog_array.tcl:314 msgid "Open List View..." msgstr "Öffne Listenanzeige..." #: ../src/dialog_array.tcl:319 #: ../src/dialog_array.tcl:321 #: ../src/dialog_audio.tcl:136 #: ../src/dialog_canvas.tcl:205 #: ../src/dialog_font.tcl:51 #: ../src/dialog_gatom.tcl:153 #: ../src/dialog_gatom.tcl:161 #: ../src/dialog_iemgui.tcl:742 #: ../src/dialog_iemgui.tcl:748 #: ../src/dialog_midi.tcl:91 #: ../src/dialog_midi.tcl:226 msgid "Cancel" msgstr "Abbrechen" #: ../src/dialog_array.tcl:321 #: ../src/dialog_array.tcl:323 #: ../src/dialog_audio.tcl:138 #: ../src/dialog_canvas.tcl:207 #: ../src/dialog_gatom.tcl:156 #: ../src/dialog_gatom.tcl:164 #: ../src/dialog_iemgui.tcl:745 #: ../src/dialog_iemgui.tcl:751 #: ../src/dialog_midi.tcl:93 #: ../src/dialog_midi.tcl:228 msgid "Apply" msgstr "Anwenden" #: ../src/dialog_array.tcl:323 #: ../src/dialog_array.tcl:325 #: ../src/dialog_audio.tcl:140 #: ../src/dialog_canvas.tcl:209 #: ../src/dialog_font.tcl:53 #: ../src/dialog_font.tcl:92 #: ../src/dialog_font.tcl:100 #: ../src/dialog_font.tcl:101 #: ../src/dialog_gatom.tcl:159 #: ../src/dialog_gatom.tcl:167 #: ../src/dialog_iemgui.tcl:748 #: ../src/dialog_iemgui.tcl:754 #: ../src/dialog_midi.tcl:95 #: ../src/dialog_midi.tcl:230 msgid "OK" msgstr "OK" #: ../src/dialog_audio.tcl:130 msgid "Audio Settings" msgstr "Audioeinstellungen" #: ../src/dialog_audio.tcl:142 msgid "Save All Settings" msgstr "Einstellungen speichern" #: ../src/dialog_audio.tcl:151 msgid "Sample rate:" msgstr "Samplingrate:" #: ../src/dialog_audio.tcl:153 msgid "Delay (msec):" msgstr "Verzögerung (msec):" #: ../src/dialog_audio.tcl:158 msgid "Use callbacks" msgstr "Rückfragen verwenden" #: ../src/dialog_audio.tcl:166 #: ../src/dialog_midi.tcl:105 #: ../src/dialog_midi.tcl:241 msgid "Input device 1:" msgstr "Eingabegerät 1:" #: ../src/dialog_audio.tcl:169 #: ../src/dialog_audio.tcl:183 #: ../src/dialog_audio.tcl:198 #: ../src/dialog_audio.tcl:213 #: ../src/dialog_audio.tcl:232 #: ../src/dialog_audio.tcl:250 #: ../src/dialog_audio.tcl:265 #: ../src/dialog_audio.tcl:280 msgid "Channels:" msgstr "Kanäle:" #: ../src/dialog_audio.tcl:179 #: ../src/dialog_midi.tcl:115 #: ../src/dialog_midi.tcl:251 msgid "Input device 2:" msgstr "Eingabegerät 2:" #: ../src/dialog_audio.tcl:194 #: ../src/dialog_midi.tcl:127 #: ../src/dialog_midi.tcl:263 msgid "Input device 3:" msgstr "Eingabegerät 3:" #: ../src/dialog_audio.tcl:209 #: ../src/dialog_midi.tcl:139 #: ../src/dialog_midi.tcl:275 msgid "Input device 4:" msgstr "Eingabegerät 4:" #: ../src/dialog_audio.tcl:223 #: ../src/dialog_midi.tcl:150 #: ../src/dialog_midi.tcl:286 msgid "Output device 1:" msgstr "Ausgabegerät 1:" #: ../src/dialog_audio.tcl:226 msgid "(same as input device) .............. " msgstr "(wie Eingabegerät) .............. " #: ../src/dialog_audio.tcl:246 #: ../src/dialog_midi.tcl:160 #: ../src/dialog_midi.tcl:296 msgid "Output device 2:" msgstr "Ausgabegerät 2:" #: ../src/dialog_audio.tcl:261 #: ../src/dialog_midi.tcl:171 #: ../src/dialog_midi.tcl:307 msgid "Output device 3:" msgstr "Ausgabegerät 3:" #: ../src/dialog_audio.tcl:276 #: ../src/dialog_midi.tcl:182 #: ../src/dialog_midi.tcl:318 msgid "Output device 4:" msgstr "Ausgabegerät 4:" #: ../src/dialog_audio.tcl:291 #: ../src/dialog_midi.tcl:195 msgid "Use multiple devices" msgstr "Mehrere Geräte verwenden" #: ../src/dialog_canvas.tcl:142 msgid "Canvas Properties" msgstr "Arbeitsflächen-Eigenschaften" #: ../src/dialog_canvas.tcl:146 msgid "Scale" msgstr "Skalierung" #: ../src/dialog_canvas.tcl:150 msgid "X units per pixel:" msgstr "X Einheiten pro Pixel:" #: ../src/dialog_canvas.tcl:155 msgid "Y units per pixel:" msgstr "Y Einheiten pro Pixel:" #: ../src/dialog_canvas.tcl:159 msgid "Appearance on parent patch" msgstr "Erscheinen auf dem übergeordneten Patch" #: ../src/dialog_canvas.tcl:161 msgid "Graph-On-Parent" msgstr "Auf dem Übergeordneten Patch anzeigen" #: ../src/dialog_canvas.tcl:165 msgid "Hide object name and arguments" msgstr "Objektname und Argumente verbergen" #: ../src/dialog_canvas.tcl:170 msgid "Range and size" msgstr "Spanne und Größe" #: ../src/dialog_canvas.tcl:174 msgid "X range, from" msgstr "X Spanne, von" #: ../src/dialog_canvas.tcl:176 #: ../src/dialog_canvas.tcl:191 msgid "to" msgstr "bis" #: ../src/dialog_canvas.tcl:180 #: ../src/dialog_canvas.tcl:195 msgid "Margin:" msgstr "Abstand:" #: ../src/dialog_canvas.tcl:189 msgid "Y range, from" msgstr "Y Spanne, von" #: ../src/dialog_find.tcl:63 #: ../src/dialog_find.tcl:66 #: ../src/dialog_find.tcl:79 #: ../src/dialog_find.tcl:80 #: ../src/dialog_find.tcl:83 #: ../src/dialog_find.tcl:85 #: ../src/dialog_find.tcl:87 #: ../src/dialog_find.tcl:101 #: ../src/dialog_find.tcl:105 #: ../src/dialog_find.tcl:107 #: ../src/pd_menus.tcl:45 msgid "Find" msgstr "Finde" #: ../src/dialog_find.tcl:70 #: ../src/dialog_find.tcl:73 #: ../src/dialog_find.tcl:87 #: ../src/dialog_find.tcl:91 #: ../src/dialog_find.tcl:93 msgid "Search in" msgstr "Suche in" #: ../src/dialog_find.tcl:72 #: ../src/dialog_find.tcl:75 #: ../src/dialog_find.tcl:89 #: ../src/dialog_find.tcl:93 #: ../src/dialog_find.tcl:95 msgid "for:" msgstr "für:" #: ../src/dialog_find.tcl:83 #: ../src/dialog_find.tcl:90 #: ../src/dialog_find.tcl:104 #: ../src/dialog_find.tcl:108 #: ../src/dialog_find.tcl:110 #: ../src/pd_menus.tcl:86 #: ../src/pd_menus.tcl:87 #: ../src/pd_menus.tcl:132 #: ../src/pd_menus.tcl:133 #: ../src/pd_menus.tcl:259 #: ../src/pd_menus.tcl:272 #: ../src/pd_menus.tcl:295 #: ../src/pd_menus.tcl:308 #: ../src/pd_menus.tcl:332 #: ../src/pd_menus.tcl:345 #: ../src/pd_menus.tcl:354 #: ../src/pd_menus.tcl:381 #: ../src/pd_menus.tcl:392 #: ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:431 #: ../src/pd_menus.tcl:458 msgid "Close" msgstr "Schließen" #: ../src/dialog_find.tcl:83 #: ../src/dialog_find.tcl:97 #: ../src/dialog_find.tcl:101 #: ../src/dialog_find.tcl:103 msgid "Match whole word only" msgstr "Ganzes Wort abgleichen" #: ../src/dialog_find.tcl:92 #: ../src/dialog_font.tcl:49 #: ../src/dialog_font.tcl:50 #: ../src/pd-gui.tcl:280 #: ../src/pd-gui.tcl:283 #: ../src/pd-gui.tcl:286 #: ../src/pd-gui.tcl:288 #: ../src/pd-gui.tcl:291 #: ../src/pd_menus.tcl:212 #: ../src/pd_menus.tcl:258 #: ../src/pd_menus.tcl:285 #: ../src/pdwindow.tcl:33 msgid "Pd window" msgstr "Pd Fenster" #: ../src/dialog_font.tcl:45 msgid "Font Properties" msgstr "Zeichensatz-Einstellungen" #: ../src/dialog_font.tcl:46 #: ../src/dialog_font.tcl:54 #: ../src/dialog_font.tcl:55 #, tcl-format msgid "%s Font" msgstr "%s Zeichensatz" #: ../src/dialog_font.tcl:61 #: ../src/dialog_font.tcl:96 #: ../src/dialog_font.tcl:104 #: ../src/dialog_font.tcl:105 msgid "Font Size" msgstr "Zeichensatzgröße" #: ../src/dialog_font.tcl:89 #: ../src/dialog_font.tcl:108 #: ../src/dialog_font.tcl:116 #: ../src/dialog_font.tcl:117 msgid "Stretch" msgstr "Dehnen" #: ../src/dialog_font.tcl:96 #: ../src/dialog_font.tcl:115 #: ../src/dialog_font.tcl:123 #: ../src/dialog_font.tcl:124 msgid "X and Y" msgstr "X und Y" #: ../src/dialog_font.tcl:98 #: ../src/dialog_font.tcl:117 #: ../src/dialog_font.tcl:125 #: ../src/dialog_font.tcl:126 msgid "X only" msgstr "nur X" #: ../src/dialog_font.tcl:100 #: ../src/dialog_font.tcl:119 #: ../src/dialog_font.tcl:127 #: ../src/dialog_font.tcl:128 msgid "Y only" msgstr "nur Y" #: ../src/dialog_gatom.tcl:93 msgid "Atom Box Properties" msgstr "Atom Box Eigenschaften" #: ../src/dialog_gatom.tcl:99 msgid "Width:" msgstr "Breite:" #: ../src/dialog_gatom.tcl:103 msgid "Limits" msgstr "Bereich" #: ../src/dialog_gatom.tcl:107 msgid "Lower:" msgstr "Unterer:" #: ../src/dialog_gatom.tcl:112 #: ../src/dialog_gatom.tcl:113 msgid "Upper:" msgstr "Oberer:" #: ../src/dialog_gatom.tcl:116 #: ../src/dialog_gatom.tcl:121 #: ../src/dialog_iemgui.tcl:600 #: ../src/dialog_iemgui.tcl:652 #: ../src/dialog_iemgui.tcl:657 msgid "Label" msgstr "Etikett" #: ../src/dialog_gatom.tcl:124 #: ../src/dialog_gatom.tcl:129 msgid "Left " msgstr "Links " #: ../src/dialog_gatom.tcl:126 #: ../src/dialog_gatom.tcl:131 msgid "Right" msgstr "Rechts" #: ../src/dialog_gatom.tcl:128 #: ../src/dialog_gatom.tcl:133 msgid "Top" msgstr "Oben" #: ../src/dialog_gatom.tcl:130 #: ../src/dialog_gatom.tcl:135 msgid "Bottom" msgstr "Unten" #: ../src/dialog_gatom.tcl:137 #: ../src/dialog_gatom.tcl:145 #: ../src/dialog_iemgui.tcl:574 msgid "Messages" msgstr "Nachrichten" #: ../src/dialog_gatom.tcl:141 #: ../src/dialog_gatom.tcl:149 #: ../src/dialog_iemgui.tcl:578 msgid "Send symbol:" msgstr "Sendesymbol:" #: ../src/dialog_gatom.tcl:147 #: ../src/dialog_gatom.tcl:155 #: ../src/dialog_iemgui.tcl:585 msgid "Receive symbol:" msgstr "Empfangssymbol" #: ../src/dialog_iemgui.tcl:197 msgid "Background color" msgstr "Hintergrundfarbe" #: ../src/dialog_iemgui.tcl:204 msgid "Foreground color" msgstr "Vordergrundfarbe" #: ../src/dialog_iemgui.tcl:211 msgid "Label color" msgstr "Etikettenfarbe" #: ../src/dialog_iemgui.tcl:272 msgid "Init" msgstr "Init" #: ../src/dialog_iemgui.tcl:275 #: ../src/dialog_iemgui.tcl:546 msgid "No init" msgstr "Kein Init" #: ../src/dialog_iemgui.tcl:287 #: ../src/dialog_iemgui.tcl:558 msgid "Jump on click" msgstr "Sprung bei Klick" #: ../src/dialog_iemgui.tcl:290 #: ../src/dialog_iemgui.tcl:561 msgid "Steady on click" msgstr "Gleichbleibend bei Klick" #: ../src/dialog_iemgui.tcl:498 #, tcl-format msgid "%s Properties" msgstr "%s Eigenschaften" #: ../src/dialog_iemgui.tcl:550 #: ../src/pd_menus.tcl:83 #: ../src/pd_menus.tcl:84 #: ../src/pd_menus.tcl:129 #: ../src/pd_menus.tcl:130 #: ../src/pd_menus.tcl:260 #: ../src/pd_menus.tcl:273 #: ../src/pd_menus.tcl:288 #: ../src/pd_menus.tcl:301 #: ../src/pd_menus.tcl:325 #: ../src/pd_menus.tcl:338 #: ../src/pd_menus.tcl:355 #: ../src/pd_menus.tcl:382 #: ../src/pd_menus.tcl:383 #: ../src/pd_menus.tcl:410 #: ../src/pd_menus.tcl:422 #: ../src/pd_menus.tcl:449 msgid "Save" msgstr "Speichern" #: ../src/dialog_iemgui.tcl:608 msgid "X offset" msgstr "X Verschiebung" #: ../src/dialog_iemgui.tcl:611 #: ../src/dialog_iemgui.tcl:612 msgid "Y offset" msgstr "Y Verschiebung" #: ../src/dialog_iemgui.tcl:642 #: ../src/dialog_iemgui.tcl:645 msgid "Colors" msgstr "Farben" #: ../src/dialog_iemgui.tcl:648 #: ../src/dialog_iemgui.tcl:651 msgid "Background" msgstr "Hintergrund" #: ../src/dialog_iemgui.tcl:650 #: ../src/dialog_iemgui.tcl:654 msgid "Front" msgstr "Vordergrund" #: ../src/dialog_iemgui.tcl:662 #: ../src/dialog_iemgui.tcl:668 msgid "Compose color" msgstr "Farbe einstellen" #: ../src/dialog_iemgui.tcl:682 #: ../src/dialog_iemgui.tcl:688 msgid "Test label" msgstr "Test Etikett" #: ../src/dialog_midi.tcl:85 msgid "MIDI Settings" msgstr "MIDI Einstellungen" #: ../src/dialog_midi.tcl:220 msgid "ALSA MIDI Settings" msgstr "ALSA MIDI Einstellungen" #: ../src/dialog_midi.tcl:331 msgid "Use multiple ALSA devices" msgstr "Mehrere ALSA Geräte verwenden" #: ../src/dialog_midi.tcl:337 msgid "In Ports:" msgstr "Eingänge:" #: ../src/dialog_midi.tcl:340 msgid "Out Ports:" msgstr "Ausgänge:" #: ../src/g_editor.c:1663 msgid "Discard changes to this window??" msgstr "Änderungen an diesem Fenster verwerfen?" #: ../src/g_editor.c:1668 msgid "really quit?" msgstr "Wirklich Abbrechen?" #: ../src/g_editor.c:1699 msgid "Close this window??" msgstr "Dieses Fenster schließen?" #: ../src/pd-gui.tcl:185 #: ../src/pd-gui.tcl:195 #: ../src/pd-gui.tcl:203 #: ../src/pd-gui.tcl:206 #: ../src/pd-gui.tcl:215 #: ../src/pd-gui.tcl:226 msgid "Associated Files" msgstr "Zugehörige Dateien" #: ../src/pd-gui.tcl:186 #: ../src/pd-gui.tcl:196 #: ../src/pd-gui.tcl:204 #: ../src/pd-gui.tcl:207 #: ../src/pd-gui.tcl:216 #: ../src/pd-gui.tcl:227 msgid "Pd Files" msgstr "Pd Dateien" #: ../src/pd-gui.tcl:187 #: ../src/pd-gui.tcl:205 #: ../src/pd-gui.tcl:208 #: ../src/pd-gui.tcl:228 msgid "Max Patch Files" msgstr "Max Patch Dateien" #: ../src/pd-gui.tcl:188 #: ../src/pd-gui.tcl:206 #: ../src/pd-gui.tcl:209 #: ../src/pd-gui.tcl:229 msgid "Max Text Files" msgstr "Max Textdateien" #: ../src/pd-gui.tcl:197 #: ../src/pd-gui.tcl:217 msgid "Max Patch Files (.pat)" msgstr "Max Patch Dateien (.pat)" #: ../src/pd-gui.tcl:198 #: ../src/pd-gui.tcl:218 msgid "Max Text Files (.mxt)" msgstr "Max Textdateien (.mxt)" #: ../src/pd-gui.tcl:270 #: ../src/pd-gui.tcl:290 #, tcl-format msgid "WARNING: Font family '%s' not found, using default (%s)" msgstr "" "WARNUNG: Zeichensatzfamilie '%s' nicht gefunden, Standard wird verwendet (%s)" #: ../src/pd-gui.tcl:278 #: ../src/pd-gui.tcl:298 #, tcl-format msgid "WARNING: Font weight '%s' not found, using default (%s)" msgstr "" "WARNUNG: Zeichensatz Schnitt '%s' nicht gefunden, Standard wird verwendet (%" "s)" #: ../src/pd-gui.tcl:303 #: ../src/pd-gui.tcl:323 #, tcl-format msgid "ERROR: %s failed to find font size (%s) that fits into %sx%s!" msgstr "FEHLER: %s failed to find font size (%s) that fits into %sx%s!" #: ../src/pd-gui.tcl:478 #: ../src/pd-gui.tcl:483 #: ../src/pd-gui.tcl:501 msgid "ERROR: 'pd' never showed up, 'pd-gui' quitting!" msgstr "FEHLER: 'pd' startete nicht, 'pd-gui' beendet sich!" #: ../src/pd_menucommands.tcl:19 msgid "Untitled" msgstr "Unbenannt" #: ../src/pd_menucommands.tcl:78 #: ../src/pd_menucommands.tcl:79 #: ../src/pd_menucommands.tcl:90 msgid "Send Message..." msgstr "Nachricht senden..." #: ../src/pd_menucommands.tcl:82 #: ../src/pd_menucommands.tcl:83 #: ../src/pd_menucommands.tcl:94 #: ../src/pd_menus.tcl:87 #: ../src/pd_menus.tcl:88 #: ../src/pd_menus.tcl:133 #: ../src/pd_menus.tcl:134 #: ../src/pd_menus.tcl:147 #: ../src/pd_menus.tcl:192 #: ../src/pd_menus.tcl:193 #: ../src/pd_menus.tcl:265 #: ../src/pd_menus.tcl:278 #: ../src/pd_menus.tcl:292 #: ../src/pd_menus.tcl:305 #: ../src/pd_menus.tcl:329 #: ../src/pd_menus.tcl:342 #: ../src/pd_menus.tcl:360 #: ../src/pd_menus.tcl:387 #: ../src/pd_menus.tcl:414 #: ../src/pd_menus.tcl:426 #: ../src/pd_menus.tcl:453 #: ../startup/object_db.tcl:123 msgid "Message" msgstr "Nachricht" #: ../src/pd_menucommands.tcl:108 #: ../src/pd_menucommands.tcl:111 #: ../src/pd_menus.tcl:112 #: ../src/pd_menus.tcl:113 #: ../src/pd_menus.tcl:117 #: ../src/pd_menus.tcl:118 #: ../src/pd_menus.tcl:158 #: ../src/pd_menus.tcl:159 #: ../src/pd_menus.tcl:163 #: ../src/pd_menus.tcl:164 msgid "Font" msgstr "Zeichensatz" #: ../src/pd_menucommands.tcl:123 #: ../src/pd_menucommands.tcl:126 #: ../src/pd_menus.tcl:138 #: ../src/pd_menus.tcl:183 #: ../src/pd_menus.tcl:184 msgid "Preferences" msgstr "Voreinstellungen" #: ../src/pd_menus.tcl:45 msgid "Edit" msgstr "Bearbeiten" #: ../src/pd_menus.tcl:45 msgid "File" msgstr "Datei" #: ../src/pd_menus.tcl:45 #: ../src/pdtk_canvas.tcl:48 #: ../src/pdtk_canvas.tcl:110 #: ../src/pdtk_canvas.tcl:113 msgid "Help" msgstr "Hilfe" #: ../src/pd_menus.tcl:45 msgid "Media" msgstr "Medien" #: ../src/pd_menus.tcl:45 msgid "Put" msgstr "Einfügen" #: ../src/pd_menus.tcl:45 msgid "Window" msgstr "Fenster" #: ../src/pd_menus.tcl:81 #: ../src/pd_menus.tcl:82 #: ../src/pd_menus.tcl:127 #: ../src/pd_menus.tcl:128 #: ../src/pd_menus.tcl:255 #: ../src/pd_menus.tcl:267 #: ../src/pd_menus.tcl:285 #: ../src/pd_menus.tcl:298 #: ../src/pd_menus.tcl:322 #: ../src/pd_menus.tcl:335 #: ../src/pd_menus.tcl:349 #: ../src/pd_menus.tcl:376 #: ../src/pd_menus.tcl:380 #: ../src/pd_menus.tcl:407 #: ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:446 msgid "New" msgstr "Neu" #: ../src/pd_menus.tcl:82 #: ../src/pd_menus.tcl:83 #: ../src/pd_menus.tcl:128 #: ../src/pd_menus.tcl:129 #: ../src/pd_menus.tcl:256 #: ../src/pd_menus.tcl:268 #: ../src/pd_menus.tcl:286 #: ../src/pd_menus.tcl:299 #: ../src/pd_menus.tcl:323 #: ../src/pd_menus.tcl:336 #: ../src/pd_menus.tcl:350 #: ../src/pd_menus.tcl:377 #: ../src/pd_menus.tcl:381 #: ../src/pd_menus.tcl:408 #: ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:447 #: ../src/pdtk_canvas.tcl:46 #: ../src/pdtk_canvas.tcl:108 #: ../src/pdtk_canvas.tcl:111 #: ../src/pdtk_canvas.tcl:128 #: ../src/pdtk_canvas.tcl:130 #: ../src/pdtk_canvas.tcl:131 #: ../src/pdtk_canvas.tcl:133 msgid "Open" msgstr "Öffnen" #: ../src/pd_menus.tcl:84 #: ../src/pd_menus.tcl:85 #: ../src/pd_menus.tcl:130 #: ../src/pd_menus.tcl:131 #: ../src/pd_menus.tcl:261 #: ../src/pd_menus.tcl:274 #: ../src/pd_menus.tcl:289 #: ../src/pd_menus.tcl:302 #: ../src/pd_menus.tcl:326 #: ../src/pd_menus.tcl:339 #: ../src/pd_menus.tcl:356 #: ../src/pd_menus.tcl:383 #: ../src/pd_menus.tcl:384 #: ../src/pd_menus.tcl:411 #: ../src/pd_menus.tcl:423 #: ../src/pd_menus.tcl:450 msgid "Save As..." msgstr "Speichern als..." #: ../src/pd_menus.tcl:88 #: ../src/pd_menus.tcl:89 #: ../src/pd_menus.tcl:134 #: ../src/pd_menus.tcl:135 #: ../src/pd_menus.tcl:267 #: ../src/pd_menus.tcl:280 #: ../src/pd_menus.tcl:293 #: ../src/pd_menus.tcl:306 #: ../src/pd_menus.tcl:330 #: ../src/pd_menus.tcl:343 #: ../src/pd_menus.tcl:362 #: ../src/pd_menus.tcl:388 #: ../src/pd_menus.tcl:389 #: ../src/pd_menus.tcl:415 #: ../src/pd_menus.tcl:427 #: ../src/pd_menus.tcl:454 msgid "Print..." msgstr "Drucken" #: ../src/pd_menus.tcl:93 #: ../src/pd_menus.tcl:94 #: ../src/pd_menus.tcl:139 #: ../src/pd_menus.tcl:140 msgid "Undo" msgstr "Widerrufen" #: ../src/pd_menus.tcl:95 #: ../src/pd_menus.tcl:96 #: ../src/pd_menus.tcl:141 #: ../src/pd_menus.tcl:142 msgid "Redo" msgstr "Wiederholen" #: ../src/pd_menus.tcl:98 #: ../src/pd_menus.tcl:99 #: ../src/pd_menus.tcl:144 #: ../src/pd_menus.tcl:145 msgid "Cut" msgstr "Ausschneiden" #: ../src/pd_menus.tcl:104 #: ../src/pd_menus.tcl:105 #: ../src/pd_menus.tcl:150 #: ../src/pd_menus.tcl:151 msgid "Duplicate" msgstr "Duplizieren" #: ../src/pd_menus.tcl:106 #: ../src/pd_menus.tcl:107 #: ../src/pd_menus.tcl:152 #: ../src/pd_menus.tcl:153 msgid "Select All" msgstr "Alles auswählen" #: ../src/pd_menus.tcl:110 #: ../src/pd_menus.tcl:111 #: ../src/pd_menus.tcl:115 #: ../src/pd_menus.tcl:116 #: ../src/pd_menus.tcl:156 #: ../src/pd_menus.tcl:157 #: ../src/pd_menus.tcl:161 #: ../src/pd_menus.tcl:162 msgid "Text Editor" msgstr "Texteditor" #: ../src/pd_menus.tcl:120 #: ../src/pd_menus.tcl:121 #: ../src/pd_menus.tcl:166 #: ../src/pd_menus.tcl:167 msgid "Tidy Up" msgstr "Aufräumen" #: ../src/pd_menus.tcl:122 #: ../src/pd_menus.tcl:123 #: ../src/pd_menus.tcl:168 #: ../src/pd_menus.tcl:169 msgid "Toggle Console" msgstr "Konsole Ein/Aus" #: ../src/pd_menus.tcl:124 #: ../src/pd_menus.tcl:125 #: ../src/pd_menus.tcl:170 #: ../src/pd_menus.tcl:171 msgid "Clear Console" msgstr "Konsole löschen" #: ../src/pd_menus.tcl:128 #: ../src/pd_menus.tcl:129 #: ../src/pd_menus.tcl:174 #: ../src/pd_menus.tcl:175 msgid "Edit Mode" msgstr "Editiermodus" #: ../src/pd_menus.tcl:145 #: ../src/pd_menus.tcl:190 #: ../src/pd_menus.tcl:191 msgid "Object" msgstr "Objekt" #: ../src/pd_menus.tcl:149 #: ../src/pd_menus.tcl:194 #: ../src/pd_menus.tcl:195 msgid "Number" msgstr "Zahl" #: ../src/pd_menus.tcl:151 #: ../src/pd_menus.tcl:196 #: ../src/pd_menus.tcl:197 msgid "Symbol" msgstr "Symbol" #: ../src/pd_menus.tcl:153 #: ../src/pd_menus.tcl:198 #: ../src/pd_menus.tcl:199 msgid "Comment" msgstr "Kommentar" #: ../src/pd_menus.tcl:156 #: ../src/pd_menus.tcl:201 #: ../src/pd_menus.tcl:202 msgid "Bang" msgstr "Taster (Bang)" #: ../src/pd_menus.tcl:158 #: ../src/pd_menus.tcl:203 #: ../src/pd_menus.tcl:204 msgid "Toggle" msgstr "Schalter" #: ../src/pd_menus.tcl:160 #: ../src/pd_menus.tcl:205 #: ../src/pd_menus.tcl:206 msgid "Number2" msgstr "Zahl2" #: ../src/pd_menus.tcl:162 #: ../src/pd_menus.tcl:207 #: ../src/pd_menus.tcl:208 msgid "Vslider" msgstr "Vertikaler Schieberegler" #: ../src/pd_menus.tcl:164 #: ../src/pd_menus.tcl:209 #: ../src/pd_menus.tcl:210 msgid "Hslider" msgstr "Horizontaler Schieberegler" #: ../src/pd_menus.tcl:166 #: ../src/pd_menus.tcl:211 #: ../src/pd_menus.tcl:212 msgid "Vradio" msgstr "Vertikaler Radioknopf" #: ../src/pd_menus.tcl:168 #: ../src/pd_menus.tcl:213 #: ../src/pd_menus.tcl:214 msgid "Hradio" msgstr "Horizontaler Radioknopf" #: ../src/pd_menus.tcl:170 #: ../src/pd_menus.tcl:215 #: ../src/pd_menus.tcl:216 msgid "VU Meter" msgstr "Aussteuerungsanzeige" #: ../src/pd_menus.tcl:172 #: ../src/pd_menus.tcl:217 #: ../src/pd_menus.tcl:218 msgid "Canvas" msgstr "Arbeitsfläche" #: ../src/pd_menus.tcl:175 #: ../src/pd_menus.tcl:220 #: ../src/pd_menus.tcl:221 msgid "Graph" msgstr "Kurve" #: ../src/pd_menus.tcl:176 #: ../src/pd_menus.tcl:221 #: ../src/pd_menus.tcl:222 msgid "Array" msgstr "Feld" #: ../src/pd_menus.tcl:181 #: ../src/pd_menus.tcl:226 #: ../src/pd_menus.tcl:227 msgid "Find..." msgstr "Finde..." #: ../src/pd_menus.tcl:183 #: ../src/pd_menus.tcl:228 #: ../src/pd_menus.tcl:229 msgid "Find Again" msgstr "Finde nochmal" #: ../src/pd_menus.tcl:185 #: ../src/pd_menus.tcl:230 #: ../src/pd_menus.tcl:231 msgid "Find Last Error" msgstr "Letzten Fehler finden" #: ../src/pd_menus.tcl:191 #: ../src/pd_menus.tcl:236 #: ../src/pd_menus.tcl:237 msgid "DSP On" msgstr "DSP An" #: ../src/pd_menus.tcl:193 #: ../src/pd_menus.tcl:238 #: ../src/pd_menus.tcl:239 msgid "DSP Off" msgstr "DSP Aus" #: ../src/pd_menus.tcl:196 #: ../src/pd_menus.tcl:242 #: ../src/pd_menus.tcl:269 msgid "Test Audio and MIDI..." msgstr "Teste Audio und MIDI..." #: ../src/pd_menus.tcl:198 #: ../src/pd_menus.tcl:244 #: ../src/pd_menus.tcl:271 msgid "Load Meter" msgstr "Auslastungsanzeige" #: ../src/pd_menus.tcl:205 #: ../src/pd_menus.tcl:251 #: ../src/pd_menus.tcl:278 msgid "Minimize" msgstr "Minimieren" #: ../src/pd_menus.tcl:207 #: ../src/pd_menus.tcl:253 #: ../src/pd_menus.tcl:280 msgid "Zoom" msgstr "Zoom" #: ../src/pd_menus.tcl:210 #: ../src/pd_menus.tcl:256 #: ../src/pd_menus.tcl:283 msgid "Parent Window" msgstr "Übergeordnetes Fenster" #: ../src/pd_menus.tcl:216 #: ../src/pd_menus.tcl:262 #: ../src/pd_menus.tcl:289 msgid "Bring All to Front" msgstr "Alle nach vorne bringen" #: ../src/pd_menus.tcl:224 #: ../src/pd_menus.tcl:241 #: ../src/pd_menus.tcl:253 #: ../src/pd_menus.tcl:270 #: ../src/pd_menus.tcl:297 #: ../src/pd_menus.tcl:335 #: ../src/pd_menus.tcl:362 msgid "About Pd" msgstr "Über Pd" #: ../src/pd_menus.tcl:227 #: ../src/pd_menus.tcl:273 #: ../src/pd_menus.tcl:300 msgid "HTML Manual..." msgstr "HTML Anleitung" #: ../src/pd_menus.tcl:229 #: ../src/pd_menus.tcl:275 #: ../src/pd_menus.tcl:302 msgid "Browser..." msgstr "Patch Browser..." #: ../src/pd_menus.tcl:248 #: ../src/pd_menus.tcl:260 #: ../src/pd_menus.tcl:342 #: ../src/pd_menus.tcl:369 msgid "Preferences..." msgstr "Voreinstellungen..." #: ../src/pd_menus.tcl:257 #: ../src/pd_menus.tcl:270 #: ../src/pd_menus.tcl:352 #: ../src/pd_menus.tcl:379 msgid "Open Recent" msgstr "Letzte Dateien öffnen" #: ../src/pd_menus.tcl:263 msgid "Audio Settings..." msgstr "Audioeinstellungen..." #: ../src/pd_menus.tcl:265 msgid "MIDI Settings..." msgstr "MIDI Einstellungen..." #: ../src/pd_menus.tcl:296 #: ../src/pd_menus.tcl:309 #: ../src/pd_menus.tcl:333 #: ../src/pd_menus.tcl:346 #: ../src/pd_menus.tcl:393 #: ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:432 #: ../src/pd_menus.tcl:459 msgid "Quit" msgstr "Beenden" #: ../src/pd_menus.tcl:304 #: ../src/pd_menus.tcl:331 msgid "Clear Menu" msgstr "Menü löschen" #: ../src/pdtk_canvas.tcl:44 #: ../src/pdtk_canvas.tcl:106 #: ../src/pdtk_canvas.tcl:109 #: ../src/pdtk_canvas.tcl:123 #: ../src/pdtk_canvas.tcl:125 #: ../src/pdtk_canvas.tcl:126 #: ../src/pdtk_canvas.tcl:128 msgid "Properties" msgstr "Einstellungen" #, fuzzy #: ../src/pdwindow.tcl:43 msgid "DSP" msgstr "" #, fuzzy #: ../startup/object_db.tcl:113 msgid "Signal" msgstr "" #: ../startup/object_db.tcl:114 msgid "Generators" msgstr "Generatoren" #: ../startup/object_db.tcl:115 msgid "Filters" msgstr "Filter" #: ../startup/object_db.tcl:116 #: ../startup/object_db.tcl:124 msgid "Math" msgstr "Mathe" #, fuzzy #: ../startup/object_db.tcl:117 #: ../startup/object_db.tcl:125 msgid "I/O" msgstr "" #, fuzzy #: ../startup/object_db.tcl:118 #: ../startup/object_db.tcl:126 msgid "Sampling" msgstr "" #: ../startup/object_db.tcl:119 #: ../startup/object_db.tcl:128 msgid "Routing" msgstr "Signalverlauf" #: ../startup/object_db.tcl:120 #: ../startup/object_db.tcl:129 msgid "Others" msgstr "Andere" #, fuzzy #: ../startup/object_db.tcl:127 msgid "GUI" msgstr "" # iemgui msgid "left:" msgstr "links:" # iemgui msgid "right:" msgstr "rechts:" # iemgui msgid "----------dimensions(pix):-----------" msgstr "----------Rahmengröße(pix):-----------" # iemgui msgid "--------dimensions(pix)(pix):--------" msgstr "--------Rahmengröße(pix)(pix):--------" # iemgui msgid "-------dimensions(digits)(pix):-------" msgstr "------Rahmengröße(Zahlen)(pix):-------" pd-0.46-7/po/bg.po0000664000175000017500000006176112160204055011750 0ustar mspmsp# Bulgarian translation of Pure Data # This file is put in the public domain. # Rostislav Raykov , 2005. # msgid "" msgstr "" "Project-Id-Version: Pure Data 0.43\n" "Report-Msgid-Bugs-To: pd-dev@iem.at\n" "POT-Creation-Date: 2009-08-27 10:01-0400\n" "PO-Revision-Date: 2005-05-20 17:51+0300\n" "Last-Translator: Rostislav Raykov \n" "Language-Team: Bulgarian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" #, fuzzy msgid "Undo duplicate" msgstr "Дата" msgid "Undo paste" msgstr "" msgid "Undo motion" msgstr "" #, fuzzy msgid "Undo cut" msgstr "Уганда" msgid "Undo disconnect" msgstr "" msgid "Undo connect" msgstr "" msgid "Undo clear" msgstr "" msgid "Undo typing" msgstr "" msgid "Discard changes to '%s'?" msgstr "" msgid "Do you want to save the changes you made in '%s'?" msgstr "" #: ../src/dialog_array.tcl:115 ../src/dialog_array.tcl:117 #: ../src/pd_menus.tcl:100 ../src/pd_menus.tcl:101 ../src/pd_menus.tcl:146 #: ../src/pd_menus.tcl:147 msgid "Copy" msgstr "Копиране" #: ../src/dialog_array.tcl:118 ../src/dialog_array.tcl:120 #: ../src/pd_menus.tcl:102 ../src/pd_menus.tcl:103 ../src/pd_menus.tcl:148 #: ../src/pd_menus.tcl:149 #, fuzzy msgid "Paste" msgstr "Дата" #: ../src/dialog_array.tcl:264 ../src/dialog_array.tcl:266 msgid "Array Properties" msgstr "" #: ../src/dialog_array.tcl:270 ../src/dialog_array.tcl:272 #, fuzzy msgid "Name:" msgstr "Име" #: ../src/dialog_array.tcl:276 ../src/dialog_array.tcl:278 #: ../src/dialog_canvas.tcl:178 ../src/dialog_canvas.tcl:193 #: ../src/dialog_iemgui.tcl:619 ../src/dialog_iemgui.tcl:621 #, fuzzy msgid "Size:" msgstr "Размер" #: ../src/dialog_array.tcl:280 ../src/dialog_array.tcl:282 #, fuzzy msgid "Save contents" msgstr "_Потребителско ръководство" #: ../src/dialog_array.tcl:284 ../src/dialog_array.tcl:286 msgid "Draw as:" msgstr "" #: ../src/dialog_array.tcl:287 ../src/dialog_array.tcl:289 #, fuzzy msgid "Points" msgstr "Порт" #: ../src/dialog_array.tcl:289 ../src/dialog_array.tcl:291 #, fuzzy msgid "Polygon" msgstr "Полша" #: ../src/dialog_array.tcl:291 ../src/dialog_array.tcl:293 msgid "Bezier curve" msgstr "" #: ../src/dialog_array.tcl:297 ../src/dialog_array.tcl:299 msgid "Put array into:" msgstr "" #: ../src/dialog_array.tcl:300 ../src/dialog_array.tcl:302 msgid "New graph" msgstr "" #: ../src/dialog_array.tcl:302 ../src/dialog_array.tcl:304 #, fuzzy msgid "Last graph" msgstr "Последно съобщение: %s" #: ../src/dialog_array.tcl:306 ../src/dialog_array.tcl:308 #, fuzzy msgid "Delete array" msgstr "Изтриване" #: ../src/dialog_array.tcl:312 ../src/dialog_array.tcl:314 #, fuzzy msgid "Open List View..." msgstr "Списък със забранение адреси..." #: ../src/dialog_array.tcl:319 ../src/dialog_array.tcl:321 #: ../src/dialog_audio.tcl:136 ../src/dialog_canvas.tcl:205 #: ../src/dialog_font.tcl:51 ../src/dialog_gatom.tcl:153 #: ../src/dialog_gatom.tcl:161 ../src/dialog_iemgui.tcl:742 #: ../src/dialog_iemgui.tcl:748 ../src/dialog_midi.tcl:91 #: ../src/dialog_midi.tcl:226 msgid "Cancel" msgstr "Отмяна" #: ../src/dialog_array.tcl:321 ../src/dialog_array.tcl:323 #: ../src/dialog_audio.tcl:138 ../src/dialog_canvas.tcl:207 #: ../src/dialog_gatom.tcl:156 ../src/dialog_gatom.tcl:164 #: ../src/dialog_iemgui.tcl:745 ../src/dialog_iemgui.tcl:751 #: ../src/dialog_midi.tcl:93 ../src/dialog_midi.tcl:228 msgid "Apply" msgstr "Прилагане" #: ../src/dialog_array.tcl:323 ../src/dialog_array.tcl:325 #: ../src/dialog_audio.tcl:140 ../src/dialog_canvas.tcl:209 #: ../src/dialog_font.tcl:53 ../src/dialog_font.tcl:92 #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:101 #: ../src/dialog_gatom.tcl:159 ../src/dialog_gatom.tcl:167 #: ../src/dialog_iemgui.tcl:748 ../src/dialog_iemgui.tcl:754 #: ../src/dialog_midi.tcl:95 ../src/dialog_midi.tcl:230 msgid "OK" msgstr "" #: ../src/dialog_audio.tcl:130 msgid "Audio Settings" msgstr "" #: ../src/dialog_audio.tcl:142 msgid "Save All Settings" msgstr "" #: ../src/dialog_audio.tcl:151 msgid "Sample rate:" msgstr "" #: ../src/dialog_audio.tcl:153 msgid "Delay (msec):" msgstr "" #: ../src/dialog_audio.tcl:158 msgid "Use callbacks" msgstr "" #: ../src/dialog_audio.tcl:166 ../src/dialog_midi.tcl:105 #: ../src/dialog_midi.tcl:241 msgid "Input device 1:" msgstr "" #: ../src/dialog_audio.tcl:169 ../src/dialog_audio.tcl:183 #: ../src/dialog_audio.tcl:198 ../src/dialog_audio.tcl:213 #: ../src/dialog_audio.tcl:232 ../src/dialog_audio.tcl:250 #: ../src/dialog_audio.tcl:265 ../src/dialog_audio.tcl:280 #, fuzzy msgid "Channels:" msgstr "Отмяна" #: ../src/dialog_audio.tcl:179 ../src/dialog_midi.tcl:115 #: ../src/dialog_midi.tcl:251 msgid "Input device 2:" msgstr "" #: ../src/dialog_audio.tcl:194 ../src/dialog_midi.tcl:127 #: ../src/dialog_midi.tcl:263 msgid "Input device 3:" msgstr "" #: ../src/dialog_audio.tcl:209 ../src/dialog_midi.tcl:139 #: ../src/dialog_midi.tcl:275 msgid "Input device 4:" msgstr "" #: ../src/dialog_audio.tcl:223 ../src/dialog_midi.tcl:150 #: ../src/dialog_midi.tcl:286 msgid "Output device 1:" msgstr "" #: ../src/dialog_audio.tcl:226 msgid "(same as input device) .............. " msgstr "" #: ../src/dialog_audio.tcl:246 ../src/dialog_midi.tcl:160 #: ../src/dialog_midi.tcl:296 msgid "Output device 2:" msgstr "" #: ../src/dialog_audio.tcl:261 ../src/dialog_midi.tcl:171 #: ../src/dialog_midi.tcl:307 msgid "Output device 3:" msgstr "" #: ../src/dialog_audio.tcl:276 ../src/dialog_midi.tcl:182 #: ../src/dialog_midi.tcl:318 msgid "Output device 4:" msgstr "" #: ../src/dialog_audio.tcl:291 ../src/dialog_midi.tcl:195 msgid "Use multiple devices" msgstr "" #: ../src/dialog_canvas.tcl:142 msgid "Canvas Properties" msgstr "" #: ../src/dialog_canvas.tcl:146 #, fuzzy msgid "Scale" msgstr "Запазване" #: ../src/dialog_canvas.tcl:150 msgid "X units per pixel:" msgstr "" #: ../src/dialog_canvas.tcl:155 msgid "Y units per pixel:" msgstr "" #: ../src/dialog_canvas.tcl:159 msgid "Appearance on parent patch" msgstr "" #: ../src/dialog_canvas.tcl:161 msgid "Graph-On-Parent" msgstr "" #: ../src/dialog_canvas.tcl:165 msgid "Hide object name and arguments" msgstr "" #: ../src/dialog_canvas.tcl:170 msgid "Range and size" msgstr "" #: ../src/dialog_canvas.tcl:174 msgid "X range, from" msgstr "" #: ../src/dialog_canvas.tcl:176 ../src/dialog_canvas.tcl:191 msgid "to" msgstr "" #: ../src/dialog_canvas.tcl:180 ../src/dialog_canvas.tcl:195 #, fuzzy msgid "Margin:" msgstr "Отбелязваща линия:" #: ../src/dialog_canvas.tcl:189 msgid "Y range, from" msgstr "" #: ../src/dialog_find.tcl:63 ../src/dialog_find.tcl:66 #: ../src/dialog_find.tcl:79 ../src/dialog_find.tcl:80 #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:85 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:101 #: ../src/dialog_find.tcl:105 ../src/dialog_find.tcl:107 #: ../src/pd_menus.tcl:45 msgid "Find" msgstr "Търсене" #: ../src/dialog_find.tcl:70 ../src/dialog_find.tcl:73 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:91 #: ../src/dialog_find.tcl:93 #, fuzzy msgid "Search in" msgstr "Търсене из текста..." #: ../src/dialog_find.tcl:72 ../src/dialog_find.tcl:75 #: ../src/dialog_find.tcl:89 ../src/dialog_find.tcl:93 #: ../src/dialog_find.tcl:95 #, fuzzy msgid "for:" msgstr "Порт:" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:90 #: ../src/dialog_find.tcl:104 ../src/dialog_find.tcl:108 #: ../src/dialog_find.tcl:110 ../src/pd_menus.tcl:86 ../src/pd_menus.tcl:87 #: ../src/pd_menus.tcl:132 ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:259 #: ../src/pd_menus.tcl:272 ../src/pd_menus.tcl:295 ../src/pd_menus.tcl:308 #: ../src/pd_menus.tcl:332 ../src/pd_menus.tcl:345 ../src/pd_menus.tcl:354 #: ../src/pd_menus.tcl:381 ../src/pd_menus.tcl:392 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:431 ../src/pd_menus.tcl:458 msgid "Close" msgstr "Затваряне" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:97 #: ../src/dialog_find.tcl:101 ../src/dialog_find.tcl:103 msgid "Match whole word only" msgstr "" #: ../src/dialog_find.tcl:92 ../src/dialog_font.tcl:49 #: ../src/dialog_font.tcl:50 ../src/pd-gui.tcl:280 ../src/pd-gui.tcl:283 #: ../src/pd-gui.tcl:286 ../src/pd-gui.tcl:288 ../src/pd-gui.tcl:291 #: ../src/pd_menus.tcl:212 ../src/pd_menus.tcl:258 ../src/pd_menus.tcl:285 #: ../src/pdwindow.tcl:33 #, fuzzy msgid "Pd window" msgstr "Прозореца за изпращане на файлове" #: ../src/dialog_font.tcl:45 msgid "Font Properties" msgstr "" #: ../src/dialog_font.tcl:46 ../src/dialog_font.tcl:54 #: ../src/dialog_font.tcl:55 #, fuzzy, tcl-format msgid "%s Font" msgstr "Шрифт:" #: ../src/dialog_font.tcl:61 ../src/dialog_font.tcl:96 #: ../src/dialog_font.tcl:104 ../src/dialog_font.tcl:105 #, fuzzy msgid "Font Size" msgstr "Размер" #: ../src/dialog_font.tcl:89 ../src/dialog_font.tcl:108 #: ../src/dialog_font.tcl:116 ../src/dialog_font.tcl:117 #, fuzzy msgid "Stretch" msgstr "Време на начало" #: ../src/dialog_font.tcl:96 ../src/dialog_font.tcl:115 #: ../src/dialog_font.tcl:123 ../src/dialog_font.tcl:124 msgid "X and Y" msgstr "" #: ../src/dialog_font.tcl:98 ../src/dialog_font.tcl:117 #: ../src/dialog_font.tcl:125 ../src/dialog_font.tcl:126 msgid "X only" msgstr "" #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:119 #: ../src/dialog_font.tcl:127 ../src/dialog_font.tcl:128 msgid "Y only" msgstr "" #: ../src/dialog_gatom.tcl:93 msgid "Atom Box Properties" msgstr "" #: ../src/dialog_gatom.tcl:99 msgid "Width:" msgstr "" #: ../src/dialog_gatom.tcl:103 #, fuzzy msgid "Limits" msgstr "Списъци" #: ../src/dialog_gatom.tcl:107 msgid "Lower:" msgstr "" #: ../src/dialog_gatom.tcl:112 ../src/dialog_gatom.tcl:113 #, fuzzy msgid "Upper:" msgstr "Потребител" #: ../src/dialog_gatom.tcl:116 ../src/dialog_gatom.tcl:121 #: ../src/dialog_iemgui.tcl:600 ../src/dialog_iemgui.tcl:652 #: ../src/dialog_iemgui.tcl:657 msgid "Label" msgstr "" #: ../src/dialog_gatom.tcl:124 ../src/dialog_gatom.tcl:129 #, fuzzy msgid "Left " msgstr "Ляво" #: ../src/dialog_gatom.tcl:126 ../src/dialog_gatom.tcl:131 msgid "Right" msgstr "Дясно" #: ../src/dialog_gatom.tcl:128 ../src/dialog_gatom.tcl:133 msgid "Top" msgstr "Горе" #: ../src/dialog_gatom.tcl:130 ../src/dialog_gatom.tcl:135 msgid "Bottom" msgstr "Долу" #: ../src/dialog_gatom.tcl:137 ../src/dialog_gatom.tcl:145 #: ../src/dialog_iemgui.tcl:574 #, fuzzy msgid "Messages" msgstr "Съобщение" #: ../src/dialog_gatom.tcl:141 ../src/dialog_gatom.tcl:149 #: ../src/dialog_iemgui.tcl:578 msgid "Send symbol:" msgstr "" #: ../src/dialog_gatom.tcl:147 ../src/dialog_gatom.tcl:155 #: ../src/dialog_iemgui.tcl:585 #, fuzzy msgid "Receive symbol:" msgstr "Прозореца за получване на файлове" #: ../src/dialog_iemgui.tcl:197 #, fuzzy msgid "Background color" msgstr "Фон:" #: ../src/dialog_iemgui.tcl:204 #, fuzzy msgid "Foreground color" msgstr "Цвят:" #: ../src/dialog_iemgui.tcl:211 #, fuzzy msgid "Label color" msgstr "Избор на цвят" #: ../src/dialog_iemgui.tcl:272 #, fuzzy msgid "Init" msgstr "Покана" #: ../src/dialog_iemgui.tcl:275 ../src/dialog_iemgui.tcl:546 msgid "No init" msgstr "" #: ../src/dialog_iemgui.tcl:287 ../src/dialog_iemgui.tcl:558 msgid "Jump on click" msgstr "" #: ../src/dialog_iemgui.tcl:290 ../src/dialog_iemgui.tcl:561 msgid "Steady on click" msgstr "" #: ../src/dialog_iemgui.tcl:498 #, tcl-format msgid "%s Properties" msgstr "" #: ../src/dialog_iemgui.tcl:550 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:84 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:130 ../src/pd_menus.tcl:260 #: ../src/pd_menus.tcl:273 ../src/pd_menus.tcl:288 ../src/pd_menus.tcl:301 #: ../src/pd_menus.tcl:325 ../src/pd_menus.tcl:338 ../src/pd_menus.tcl:355 #: ../src/pd_menus.tcl:382 ../src/pd_menus.tcl:383 ../src/pd_menus.tcl:410 #: ../src/pd_menus.tcl:422 ../src/pd_menus.tcl:449 msgid "Save" msgstr "Запазване" #: ../src/dialog_iemgui.tcl:608 msgid "X offset" msgstr "" #: ../src/dialog_iemgui.tcl:611 ../src/dialog_iemgui.tcl:612 msgid "Y offset" msgstr "" #: ../src/dialog_iemgui.tcl:642 ../src/dialog_iemgui.tcl:645 msgid "Colors" msgstr "Цветове" #: ../src/dialog_iemgui.tcl:648 ../src/dialog_iemgui.tcl:651 #, fuzzy msgid "Background" msgstr "Фон:" #: ../src/dialog_iemgui.tcl:650 ../src/dialog_iemgui.tcl:654 #, fuzzy msgid "Front" msgstr "Шрифт:" #: ../src/dialog_iemgui.tcl:662 ../src/dialog_iemgui.tcl:668 msgid "Compose color" msgstr "" #: ../src/dialog_iemgui.tcl:682 ../src/dialog_iemgui.tcl:688 #, fuzzy msgid "Test label" msgstr "Тестване на всички" #: ../src/dialog_midi.tcl:85 msgid "MIDI Settings" msgstr "" #: ../src/dialog_midi.tcl:220 msgid "ALSA MIDI Settings" msgstr "" #: ../src/dialog_midi.tcl:331 msgid "Use multiple ALSA devices" msgstr "" #: ../src/dialog_midi.tcl:337 msgid "In Ports:" msgstr "" #: ../src/dialog_midi.tcl:340 msgid "Out Ports:" msgstr "" #: ../src/g_editor.c:1663 msgid "Discard changes to this window??" msgstr "" #: ../src/g_editor.c:1668 msgid "really quit?" msgstr "" #: ../src/g_editor.c:1699 #, fuzzy msgid "Close this window??" msgstr "Затваряне на този таб/прозорец" #: ../src/pd-gui.tcl:185 ../src/pd-gui.tcl:195 ../src/pd-gui.tcl:203 #: ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:215 ../src/pd-gui.tcl:226 msgid "Associated Files" msgstr "" #: ../src/pd-gui.tcl:186 ../src/pd-gui.tcl:196 ../src/pd-gui.tcl:204 #: ../src/pd-gui.tcl:207 ../src/pd-gui.tcl:216 ../src/pd-gui.tcl:227 #, fuzzy msgid "Pd Files" msgstr "Файл" #: ../src/pd-gui.tcl:187 ../src/pd-gui.tcl:205 ../src/pd-gui.tcl:208 #: ../src/pd-gui.tcl:228 msgid "Max Patch Files" msgstr "" #: ../src/pd-gui.tcl:188 ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:209 #: ../src/pd-gui.tcl:229 msgid "Max Text Files" msgstr "" #: ../src/pd-gui.tcl:197 ../src/pd-gui.tcl:217 msgid "Max Patch Files (.pat)" msgstr "" #: ../src/pd-gui.tcl:198 ../src/pd-gui.tcl:218 msgid "Max Text Files (.mxt)" msgstr "" #: ../src/pd-gui.tcl:270 ../src/pd-gui.tcl:290 #, tcl-format msgid "WARNING: Font family '%s' not found, using default (%s)" msgstr "" #: ../src/pd-gui.tcl:278 ../src/pd-gui.tcl:298 #, tcl-format msgid "WARNING: Font weight '%s' not found, using default (%s)" msgstr "" #: ../src/pd-gui.tcl:303 ../src/pd-gui.tcl:323 #, tcl-format msgid "ERROR: %s failed to find font size (%s) that fits into %sx%s!" msgstr "" #: ../src/pd-gui.tcl:478 ../src/pd-gui.tcl:483 ../src/pd-gui.tcl:501 msgid "ERROR: 'pd' never showed up, 'pd-gui' quitting!" msgstr "" #: ../src/pd_menucommands.tcl:19 msgid "Untitled" msgstr "" #: ../src/pd_menucommands.tcl:78 ../src/pd_menucommands.tcl:79 #: ../src/pd_menucommands.tcl:90 #, fuzzy msgid "Send Message..." msgstr "Съобщение" #: ../src/pd_menucommands.tcl:82 ../src/pd_menucommands.tcl:83 #: ../src/pd_menucommands.tcl:94 ../src/pd_menus.tcl:87 ../src/pd_menus.tcl:88 #: ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:134 ../src/pd_menus.tcl:147 #: ../src/pd_menus.tcl:192 ../src/pd_menus.tcl:193 ../src/pd_menus.tcl:265 #: ../src/pd_menus.tcl:278 ../src/pd_menus.tcl:292 ../src/pd_menus.tcl:305 #: ../src/pd_menus.tcl:329 ../src/pd_menus.tcl:342 ../src/pd_menus.tcl:360 #: ../src/pd_menus.tcl:387 ../src/pd_menus.tcl:414 ../src/pd_menus.tcl:426 #: ../src/pd_menus.tcl:453 ../startup/object_db.tcl:123 msgid "Message" msgstr "Съобщение" #: ../src/pd_menucommands.tcl:108 ../src/pd_menucommands.tcl:111 #: ../src/pd_menus.tcl:112 ../src/pd_menus.tcl:113 ../src/pd_menus.tcl:117 #: ../src/pd_menus.tcl:118 ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:159 #: ../src/pd_menus.tcl:163 ../src/pd_menus.tcl:164 #, fuzzy msgid "Font" msgstr "Шрифт:" #: ../src/pd_menucommands.tcl:123 ../src/pd_menucommands.tcl:126 #: ../src/pd_menus.tcl:138 ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:184 #, fuzzy msgid "Preferences" msgstr "Настройки" #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Edit" msgstr "_Редактиране" #: ../src/pd_menus.tcl:45 msgid "File" msgstr "Файл" #: ../src/pd_menus.tcl:45 ../src/pdtk_canvas.tcl:48 ../src/pdtk_canvas.tcl:110 #: ../src/pdtk_canvas.tcl:113 msgid "Help" msgstr "Помощ" #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Media" msgstr "Македония" #: ../src/pd_menus.tcl:45 msgid "Put" msgstr "" #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Window" msgstr "Прозорец" #: ../src/pd_menus.tcl:81 ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:127 #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:255 ../src/pd_menus.tcl:267 #: ../src/pd_menus.tcl:285 ../src/pd_menus.tcl:298 ../src/pd_menus.tcl:322 #: ../src/pd_menus.tcl:335 ../src/pd_menus.tcl:349 ../src/pd_menus.tcl:376 #: ../src/pd_menus.tcl:380 ../src/pd_menus.tcl:407 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:446 msgid "New" msgstr "Ново" #: ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:128 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:268 #: ../src/pd_menus.tcl:286 ../src/pd_menus.tcl:299 ../src/pd_menus.tcl:323 #: ../src/pd_menus.tcl:336 ../src/pd_menus.tcl:350 ../src/pd_menus.tcl:377 #: ../src/pd_menus.tcl:381 ../src/pd_menus.tcl:408 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:447 ../src/pdtk_canvas.tcl:46 #: ../src/pdtk_canvas.tcl:108 ../src/pdtk_canvas.tcl:111 #: ../src/pdtk_canvas.tcl:128 ../src/pdtk_canvas.tcl:130 #: ../src/pdtk_canvas.tcl:131 ../src/pdtk_canvas.tcl:133 msgid "Open" msgstr "Отваряне" #: ../src/pd_menus.tcl:84 ../src/pd_menus.tcl:85 ../src/pd_menus.tcl:130 #: ../src/pd_menus.tcl:131 ../src/pd_menus.tcl:261 ../src/pd_menus.tcl:274 #: ../src/pd_menus.tcl:289 ../src/pd_menus.tcl:302 ../src/pd_menus.tcl:326 #: ../src/pd_menus.tcl:339 ../src/pd_menus.tcl:356 ../src/pd_menus.tcl:383 #: ../src/pd_menus.tcl:384 ../src/pd_menus.tcl:411 ../src/pd_menus.tcl:423 #: ../src/pd_menus.tcl:450 #, fuzzy msgid "Save As..." msgstr "Записване като..." #: ../src/pd_menus.tcl:88 ../src/pd_menus.tcl:89 ../src/pd_menus.tcl:134 #: ../src/pd_menus.tcl:135 ../src/pd_menus.tcl:267 ../src/pd_menus.tcl:280 #: ../src/pd_menus.tcl:293 ../src/pd_menus.tcl:306 ../src/pd_menus.tcl:330 #: ../src/pd_menus.tcl:343 ../src/pd_menus.tcl:362 ../src/pd_menus.tcl:388 #: ../src/pd_menus.tcl:389 ../src/pd_menus.tcl:415 ../src/pd_menus.tcl:427 #: ../src/pd_menus.tcl:454 #, fuzzy msgid "Print..." msgstr "_Редактиране..." #: ../src/pd_menus.tcl:93 ../src/pd_menus.tcl:94 ../src/pd_menus.tcl:139 #: ../src/pd_menus.tcl:140 #, fuzzy msgid "Undo" msgstr "Уганда" #: ../src/pd_menus.tcl:95 ../src/pd_menus.tcl:96 ../src/pd_menus.tcl:141 #: ../src/pd_menus.tcl:142 #, fuzzy msgid "Redo" msgstr "Червено:" #: ../src/pd_menus.tcl:98 ../src/pd_menus.tcl:99 ../src/pd_menus.tcl:144 #: ../src/pd_menus.tcl:145 msgid "Cut" msgstr "" #: ../src/pd_menus.tcl:104 ../src/pd_menus.tcl:105 ../src/pd_menus.tcl:150 #: ../src/pd_menus.tcl:151 #, fuzzy msgid "Duplicate" msgstr "Дата" #: ../src/pd_menus.tcl:106 ../src/pd_menus.tcl:107 ../src/pd_menus.tcl:152 #: ../src/pd_menus.tcl:153 #, fuzzy msgid "Select All" msgstr "Изтрива всички" #: ../src/pd_menus.tcl:110 ../src/pd_menus.tcl:111 ../src/pd_menus.tcl:115 #: ../src/pd_menus.tcl:116 ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:157 #: ../src/pd_menus.tcl:161 ../src/pd_menus.tcl:162 #, fuzzy msgid "Text Editor" msgstr "Цветове за текста" #: ../src/pd_menus.tcl:120 ../src/pd_menus.tcl:121 ../src/pd_menus.tcl:166 #: ../src/pd_menus.tcl:167 msgid "Tidy Up" msgstr "" #: ../src/pd_menus.tcl:122 ../src/pd_menus.tcl:123 ../src/pd_menus.tcl:168 #: ../src/pd_menus.tcl:169 msgid "Toggle Console" msgstr "" #: ../src/pd_menus.tcl:124 ../src/pd_menus.tcl:125 ../src/pd_menus.tcl:170 #: ../src/pd_menus.tcl:171 #, fuzzy msgid "Clear Console" msgstr "Изчистване на списъка" #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:174 #: ../src/pd_menus.tcl:175 #, fuzzy msgid "Edit Mode" msgstr "Режим \"Редакция\"" #: ../src/pd_menus.tcl:145 ../src/pd_menus.tcl:190 ../src/pd_menus.tcl:191 msgid "Object" msgstr "" #: ../src/pd_menus.tcl:149 ../src/pd_menus.tcl:194 ../src/pd_menus.tcl:195 #, fuzzy msgid "Number" msgstr "$ Номер" #: ../src/pd_menus.tcl:151 ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:197 msgid "Symbol" msgstr "" #: ../src/pd_menus.tcl:153 ../src/pd_menus.tcl:198 ../src/pd_menus.tcl:199 #, fuzzy msgid "Comment" msgstr "Команда" #: ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:201 ../src/pd_menus.tcl:202 #, fuzzy msgid "Bang" msgstr "Забрана" #: ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:203 ../src/pd_menus.tcl:204 #, fuzzy msgid "Toggle" msgstr "Того" #: ../src/pd_menus.tcl:160 ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:206 #, fuzzy msgid "Number2" msgstr "$ Номер" #: ../src/pd_menus.tcl:162 ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:208 msgid "Vslider" msgstr "" #: ../src/pd_menus.tcl:164 ../src/pd_menus.tcl:209 ../src/pd_menus.tcl:210 #, fuzzy msgid "Hslider" msgstr "Скрит" #: ../src/pd_menus.tcl:166 ../src/pd_menus.tcl:211 ../src/pd_menus.tcl:212 #, fuzzy msgid "Vradio" msgstr "Версия" #: ../src/pd_menus.tcl:168 ../src/pd_menus.tcl:213 ../src/pd_menus.tcl:214 msgid "Hradio" msgstr "" #: ../src/pd_menus.tcl:170 ../src/pd_menus.tcl:215 ../src/pd_menus.tcl:216 msgid "VU Meter" msgstr "" #: ../src/pd_menus.tcl:172 ../src/pd_menus.tcl:217 ../src/pd_menus.tcl:218 #, fuzzy msgid "Canvas" msgstr "Канада" #: ../src/pd_menus.tcl:175 ../src/pd_menus.tcl:220 ../src/pd_menus.tcl:221 msgid "Graph" msgstr "Графа" #: ../src/pd_menus.tcl:176 ../src/pd_menus.tcl:221 ../src/pd_menus.tcl:222 #, fuzzy msgid "Array" msgstr "Андора" #: ../src/pd_menus.tcl:181 ../src/pd_menus.tcl:226 ../src/pd_menus.tcl:227 #, fuzzy msgid "Find..." msgstr "Изпращане на файлове..." #: ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:228 ../src/pd_menus.tcl:229 msgid "Find Again" msgstr "" #: ../src/pd_menus.tcl:185 ../src/pd_menus.tcl:230 ../src/pd_menus.tcl:231 msgid "Find Last Error" msgstr "" #: ../src/pd_menus.tcl:191 ../src/pd_menus.tcl:236 ../src/pd_menus.tcl:237 msgid "DSP On" msgstr "" #: ../src/pd_menus.tcl:193 ../src/pd_menus.tcl:238 ../src/pd_menus.tcl:239 #, fuzzy msgid "DSP Off" msgstr "Изкл." #: ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:242 ../src/pd_menus.tcl:269 msgid "Test Audio and MIDI..." msgstr "" #: ../src/pd_menus.tcl:198 ../src/pd_menus.tcl:244 ../src/pd_menus.tcl:271 #, fuzzy msgid "Load Meter" msgstr "Измервател на забавянето:" #: ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:251 ../src/pd_menus.tcl:278 msgid "Minimize" msgstr "" #: ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:253 ../src/pd_menus.tcl:280 #, fuzzy msgid "Zoom" msgstr "Долу" #: ../src/pd_menus.tcl:210 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:283 #, fuzzy msgid "Parent Window" msgstr "Прозореца за изпращане на файлове" #: ../src/pd_menus.tcl:216 ../src/pd_menus.tcl:262 ../src/pd_menus.tcl:289 msgid "Bring All to Front" msgstr "" #: ../src/pd_menus.tcl:224 ../src/pd_menus.tcl:241 ../src/pd_menus.tcl:253 #: ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:297 ../src/pd_menus.tcl:335 #: ../src/pd_menus.tcl:362 #, fuzzy msgid "About Pd" msgstr "_Относно" #: ../src/pd_menus.tcl:227 ../src/pd_menus.tcl:273 ../src/pd_menus.tcl:300 msgid "HTML Manual..." msgstr "" #: ../src/pd_menus.tcl:229 ../src/pd_menus.tcl:275 ../src/pd_menus.tcl:302 #, fuzzy msgid "Browser..." msgstr "Разглеждане..." #: ../src/pd_menus.tcl:248 ../src/pd_menus.tcl:260 ../src/pd_menus.tcl:342 #: ../src/pd_menus.tcl:369 msgid "Preferences..." msgstr "Настройки" #: ../src/pd_menus.tcl:257 ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:352 #: ../src/pd_menus.tcl:379 msgid "Open Recent" msgstr "" #: ../src/pd_menus.tcl:263 msgid "Audio Settings..." msgstr "" #: ../src/pd_menus.tcl:265 msgid "MIDI Settings..." msgstr "" #: ../src/pd_menus.tcl:296 ../src/pd_menus.tcl:309 ../src/pd_menus.tcl:333 #: ../src/pd_menus.tcl:346 ../src/pd_menus.tcl:393 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:432 ../src/pd_menus.tcl:459 msgid "Quit" msgstr "Изход" #: ../src/pd_menus.tcl:304 ../src/pd_menus.tcl:331 #, fuzzy msgid "Clear Menu" msgstr "Изчистване на списъка" #: ../src/pdtk_canvas.tcl:44 ../src/pdtk_canvas.tcl:106 #: ../src/pdtk_canvas.tcl:109 ../src/pdtk_canvas.tcl:123 #: ../src/pdtk_canvas.tcl:125 ../src/pdtk_canvas.tcl:126 #: ../src/pdtk_canvas.tcl:128 msgid "Properties" msgstr "" #: ../src/pdwindow.tcl:43 #, fuzzy msgid "DSP" msgstr "Изкл." #: ../startup/object_db.tcl:113 msgid "Signal" msgstr "" #: ../startup/object_db.tcl:114 msgid "Generators" msgstr "" #: ../startup/object_db.tcl:115 #, fuzzy msgid "Filters" msgstr "Файл" #: ../startup/object_db.tcl:116 ../startup/object_db.tcl:124 msgid "Math" msgstr "" #: ../startup/object_db.tcl:117 ../startup/object_db.tcl:125 msgid "I/O" msgstr "" #: ../startup/object_db.tcl:118 ../startup/object_db.tcl:126 msgid "Sampling" msgstr "" #: ../startup/object_db.tcl:119 ../startup/object_db.tcl:128 msgid "Routing" msgstr "" #: ../startup/object_db.tcl:120 ../startup/object_db.tcl:129 msgid "Others" msgstr "" #: ../startup/object_db.tcl:127 msgid "GUI" msgstr "" pd-0.46-7/po/gu.po0000664000175000017500000006231712160204055011771 0ustar mspmsp# Translation of Pure Data-0.43.gu.po to Gujarati. # This file is put in the public domain. # Ankit Patel , 2005. # msgid "" msgstr "" "Project-Id-Version: Pure Data-0.43\n" "Report-Msgid-Bugs-To: pd-dev@iem.at\n" "POT-Creation-Date: 2009-08-27 10:01-0400\n" "PO-Revision-Date: 2005-09-14 12:49+0530\n" "Last-Translator: Ankit Patel \n" "Language-Team: Gujarati \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: KBabel 1.9.1\n" "Plural-Forms: nplurals=2; plural=(n!=1);\n" "\n" #, fuzzy msgid "Undo duplicate" msgstr "તારીખ" msgid "Undo paste" msgstr "" msgid "Undo motion" msgstr "" #, fuzzy msgid "Undo cut" msgstr "યુગાન્ડા" msgid "Undo disconnect" msgstr "" msgid "Undo connect" msgstr "" msgid "Undo clear" msgstr "" msgid "Undo typing" msgstr "" msgid "Discard changes to '%s'?" msgstr "" msgid "Do you want to save the changes you made in '%s'?" msgstr "" #: ../src/dialog_array.tcl:115 ../src/dialog_array.tcl:117 #: ../src/pd_menus.tcl:100 ../src/pd_menus.tcl:101 ../src/pd_menus.tcl:146 #: ../src/pd_menus.tcl:147 msgid "Copy" msgstr "નકલ કરો" #: ../src/dialog_array.tcl:118 ../src/dialog_array.tcl:120 #: ../src/pd_menus.tcl:102 ../src/pd_menus.tcl:103 ../src/pd_menus.tcl:148 #: ../src/pd_menus.tcl:149 #, fuzzy msgid "Paste" msgstr "તારીખ" #: ../src/dialog_array.tcl:264 ../src/dialog_array.tcl:266 msgid "Array Properties" msgstr "" #: ../src/dialog_array.tcl:270 ../src/dialog_array.tcl:272 #, fuzzy msgid "Name:" msgstr "નામ" #: ../src/dialog_array.tcl:276 ../src/dialog_array.tcl:278 #: ../src/dialog_canvas.tcl:178 ../src/dialog_canvas.tcl:193 #: ../src/dialog_iemgui.tcl:619 ../src/dialog_iemgui.tcl:621 msgid "Size:" msgstr "માપ:" #: ../src/dialog_array.tcl:280 ../src/dialog_array.tcl:282 #, fuzzy msgid "Save contents" msgstr "સમાવિષ્ટો (_C)" #: ../src/dialog_array.tcl:284 ../src/dialog_array.tcl:286 msgid "Draw as:" msgstr "" #: ../src/dialog_array.tcl:287 ../src/dialog_array.tcl:289 #, fuzzy msgid "Points" msgstr "પોર્ટ" #: ../src/dialog_array.tcl:289 ../src/dialog_array.tcl:291 #, fuzzy msgid "Polygon" msgstr "પોલેન્ડ" #: ../src/dialog_array.tcl:291 ../src/dialog_array.tcl:293 msgid "Bezier curve" msgstr "" #: ../src/dialog_array.tcl:297 ../src/dialog_array.tcl:299 msgid "Put array into:" msgstr "" #: ../src/dialog_array.tcl:300 ../src/dialog_array.tcl:302 msgid "New graph" msgstr "" #: ../src/dialog_array.tcl:302 ../src/dialog_array.tcl:304 #, fuzzy msgid "Last graph" msgstr "છેલ્લો સંદેશો:" #: ../src/dialog_array.tcl:306 ../src/dialog_array.tcl:308 #, fuzzy msgid "Delete array" msgstr "દૂર કરો" #: ../src/dialog_array.tcl:312 ../src/dialog_array.tcl:314 #, fuzzy msgid "Open List View..." msgstr "બેન યાદી..." #: ../src/dialog_array.tcl:319 ../src/dialog_array.tcl:321 #: ../src/dialog_audio.tcl:136 ../src/dialog_canvas.tcl:205 #: ../src/dialog_font.tcl:51 ../src/dialog_gatom.tcl:153 #: ../src/dialog_gatom.tcl:161 ../src/dialog_iemgui.tcl:742 #: ../src/dialog_iemgui.tcl:748 ../src/dialog_midi.tcl:91 #: ../src/dialog_midi.tcl:226 msgid "Cancel" msgstr "રદ કરો" #: ../src/dialog_array.tcl:321 ../src/dialog_array.tcl:323 #: ../src/dialog_audio.tcl:138 ../src/dialog_canvas.tcl:207 #: ../src/dialog_gatom.tcl:156 ../src/dialog_gatom.tcl:164 #: ../src/dialog_iemgui.tcl:745 ../src/dialog_iemgui.tcl:751 #: ../src/dialog_midi.tcl:93 ../src/dialog_midi.tcl:228 msgid "Apply" msgstr "અમલમાં મૂકો" #: ../src/dialog_array.tcl:323 ../src/dialog_array.tcl:325 #: ../src/dialog_audio.tcl:140 ../src/dialog_canvas.tcl:209 #: ../src/dialog_font.tcl:53 ../src/dialog_font.tcl:92 #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:101 #: ../src/dialog_gatom.tcl:159 ../src/dialog_gatom.tcl:167 #: ../src/dialog_iemgui.tcl:748 ../src/dialog_iemgui.tcl:754 #: ../src/dialog_midi.tcl:95 ../src/dialog_midi.tcl:230 msgid "OK" msgstr "" #: ../src/dialog_audio.tcl:130 msgid "Audio Settings" msgstr "" #: ../src/dialog_audio.tcl:142 msgid "Save All Settings" msgstr "" #: ../src/dialog_audio.tcl:151 msgid "Sample rate:" msgstr "" #: ../src/dialog_audio.tcl:153 msgid "Delay (msec):" msgstr "" #: ../src/dialog_audio.tcl:158 msgid "Use callbacks" msgstr "" #: ../src/dialog_audio.tcl:166 ../src/dialog_midi.tcl:105 #: ../src/dialog_midi.tcl:241 msgid "Input device 1:" msgstr "" #: ../src/dialog_audio.tcl:169 ../src/dialog_audio.tcl:183 #: ../src/dialog_audio.tcl:198 ../src/dialog_audio.tcl:213 #: ../src/dialog_audio.tcl:232 ../src/dialog_audio.tcl:250 #: ../src/dialog_audio.tcl:265 ../src/dialog_audio.tcl:280 #, fuzzy msgid "Channels:" msgstr "રદ કરો" #: ../src/dialog_audio.tcl:179 ../src/dialog_midi.tcl:115 #: ../src/dialog_midi.tcl:251 msgid "Input device 2:" msgstr "" #: ../src/dialog_audio.tcl:194 ../src/dialog_midi.tcl:127 #: ../src/dialog_midi.tcl:263 msgid "Input device 3:" msgstr "" #: ../src/dialog_audio.tcl:209 ../src/dialog_midi.tcl:139 #: ../src/dialog_midi.tcl:275 msgid "Input device 4:" msgstr "" #: ../src/dialog_audio.tcl:223 ../src/dialog_midi.tcl:150 #: ../src/dialog_midi.tcl:286 msgid "Output device 1:" msgstr "" #: ../src/dialog_audio.tcl:226 msgid "(same as input device) .............. " msgstr "" #: ../src/dialog_audio.tcl:246 ../src/dialog_midi.tcl:160 #: ../src/dialog_midi.tcl:296 msgid "Output device 2:" msgstr "" #: ../src/dialog_audio.tcl:261 ../src/dialog_midi.tcl:171 #: ../src/dialog_midi.tcl:307 msgid "Output device 3:" msgstr "" #: ../src/dialog_audio.tcl:276 ../src/dialog_midi.tcl:182 #: ../src/dialog_midi.tcl:318 msgid "Output device 4:" msgstr "" #: ../src/dialog_audio.tcl:291 ../src/dialog_midi.tcl:195 msgid "Use multiple devices" msgstr "" #: ../src/dialog_canvas.tcl:142 msgid "Canvas Properties" msgstr "" #: ../src/dialog_canvas.tcl:146 #, fuzzy msgid "Scale" msgstr "સંગ્રહ કરો" #: ../src/dialog_canvas.tcl:150 msgid "X units per pixel:" msgstr "" #: ../src/dialog_canvas.tcl:155 msgid "Y units per pixel:" msgstr "" #: ../src/dialog_canvas.tcl:159 msgid "Appearance on parent patch" msgstr "" #: ../src/dialog_canvas.tcl:161 msgid "Graph-On-Parent" msgstr "" #: ../src/dialog_canvas.tcl:165 msgid "Hide object name and arguments" msgstr "" #: ../src/dialog_canvas.tcl:170 msgid "Range and size" msgstr "" #: ../src/dialog_canvas.tcl:174 msgid "X range, from" msgstr "" #: ../src/dialog_canvas.tcl:176 ../src/dialog_canvas.tcl:191 msgid "to" msgstr "" #: ../src/dialog_canvas.tcl:180 ../src/dialog_canvas.tcl:195 #, fuzzy msgid "Margin:" msgstr "માર્કર લાઈન:" #: ../src/dialog_canvas.tcl:189 msgid "Y range, from" msgstr "" #: ../src/dialog_find.tcl:63 ../src/dialog_find.tcl:66 #: ../src/dialog_find.tcl:79 ../src/dialog_find.tcl:80 #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:85 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:101 #: ../src/dialog_find.tcl:105 ../src/dialog_find.tcl:107 #: ../src/pd_menus.tcl:45 msgid "Find" msgstr "શોધો" #: ../src/dialog_find.tcl:70 ../src/dialog_find.tcl:73 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:91 #: ../src/dialog_find.tcl:93 #, fuzzy msgid "Search in" msgstr "લખાણ શોધો..." #: ../src/dialog_find.tcl:72 ../src/dialog_find.tcl:75 #: ../src/dialog_find.tcl:89 ../src/dialog_find.tcl:93 #: ../src/dialog_find.tcl:95 #, fuzzy msgid "for:" msgstr "પોર્ટ:" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:90 #: ../src/dialog_find.tcl:104 ../src/dialog_find.tcl:108 #: ../src/dialog_find.tcl:110 ../src/pd_menus.tcl:86 ../src/pd_menus.tcl:87 #: ../src/pd_menus.tcl:132 ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:259 #: ../src/pd_menus.tcl:272 ../src/pd_menus.tcl:295 ../src/pd_menus.tcl:308 #: ../src/pd_menus.tcl:332 ../src/pd_menus.tcl:345 ../src/pd_menus.tcl:354 #: ../src/pd_menus.tcl:381 ../src/pd_menus.tcl:392 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:431 ../src/pd_menus.tcl:458 msgid "Close" msgstr "બંધ કરો" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:97 #: ../src/dialog_find.tcl:101 ../src/dialog_find.tcl:103 msgid "Match whole word only" msgstr "" #: ../src/dialog_find.tcl:92 ../src/dialog_font.tcl:49 #: ../src/dialog_font.tcl:50 ../src/pd-gui.tcl:280 ../src/pd-gui.tcl:283 #: ../src/pd-gui.tcl:286 ../src/pd-gui.tcl:288 ../src/pd-gui.tcl:291 #: ../src/pd_menus.tcl:212 ../src/pd_menus.tcl:258 ../src/pd_menus.tcl:285 #: ../src/pdwindow.tcl:33 #, fuzzy msgid "Pd window" msgstr "મોકલો વિન્ડો" #: ../src/dialog_font.tcl:45 msgid "Font Properties" msgstr "" #: ../src/dialog_font.tcl:46 ../src/dialog_font.tcl:54 #: ../src/dialog_font.tcl:55 #, fuzzy, tcl-format msgid "%s Font" msgstr "ફોન્ટ:" #: ../src/dialog_font.tcl:61 ../src/dialog_font.tcl:96 #: ../src/dialog_font.tcl:104 ../src/dialog_font.tcl:105 #, fuzzy msgid "Font Size" msgstr "માપ:" #: ../src/dialog_font.tcl:89 ../src/dialog_font.tcl:108 #: ../src/dialog_font.tcl:116 ../src/dialog_font.tcl:117 #, fuzzy msgid "Stretch" msgstr "શરૂ કરાયેલ:" #: ../src/dialog_font.tcl:96 ../src/dialog_font.tcl:115 #: ../src/dialog_font.tcl:123 ../src/dialog_font.tcl:124 msgid "X and Y" msgstr "" #: ../src/dialog_font.tcl:98 ../src/dialog_font.tcl:117 #: ../src/dialog_font.tcl:125 ../src/dialog_font.tcl:126 msgid "X only" msgstr "" #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:119 #: ../src/dialog_font.tcl:127 ../src/dialog_font.tcl:128 msgid "Y only" msgstr "" #: ../src/dialog_gatom.tcl:93 msgid "Atom Box Properties" msgstr "" #: ../src/dialog_gatom.tcl:99 msgid "Width:" msgstr "" #: ../src/dialog_gatom.tcl:103 #, fuzzy msgid "Limits" msgstr "વપરાશકર્તા મર્યાદા" #: ../src/dialog_gatom.tcl:107 msgid "Lower:" msgstr "" #: ../src/dialog_gatom.tcl:112 ../src/dialog_gatom.tcl:113 #, fuzzy msgid "Upper:" msgstr "વપરાશકર્તા:" #: ../src/dialog_gatom.tcl:116 ../src/dialog_gatom.tcl:121 #: ../src/dialog_iemgui.tcl:600 ../src/dialog_iemgui.tcl:652 #: ../src/dialog_iemgui.tcl:657 msgid "Label" msgstr "" #: ../src/dialog_gatom.tcl:124 ../src/dialog_gatom.tcl:129 #, fuzzy msgid "Left " msgstr "ડાબે" #: ../src/dialog_gatom.tcl:126 ../src/dialog_gatom.tcl:131 msgid "Right" msgstr "જમણુ" #: ../src/dialog_gatom.tcl:128 ../src/dialog_gatom.tcl:133 msgid "Top" msgstr "ઉપર" #: ../src/dialog_gatom.tcl:130 ../src/dialog_gatom.tcl:135 msgid "Bottom" msgstr "નીચે" #: ../src/dialog_gatom.tcl:137 ../src/dialog_gatom.tcl:145 #: ../src/dialog_iemgui.tcl:574 #, fuzzy msgid "Messages" msgstr "સંદેશો" #: ../src/dialog_gatom.tcl:141 ../src/dialog_gatom.tcl:149 #: ../src/dialog_iemgui.tcl:578 msgid "Send symbol:" msgstr "" #: ../src/dialog_gatom.tcl:147 ../src/dialog_gatom.tcl:155 #: ../src/dialog_iemgui.tcl:585 #, fuzzy msgid "Receive symbol:" msgstr "મેળવો વિન્ડો" #: ../src/dialog_iemgui.tcl:197 #, fuzzy msgid "Background color" msgstr "પાશ્વ ભાગ:" #: ../src/dialog_iemgui.tcl:204 #, fuzzy msgid "Foreground color" msgstr "અગ્ર ભાગ:" #: ../src/dialog_iemgui.tcl:211 #, fuzzy msgid "Label color" msgstr "રંગ પસંદ કરો" #: ../src/dialog_iemgui.tcl:272 #, fuzzy msgid "Init" msgstr "આમંત્રણ આપો" #: ../src/dialog_iemgui.tcl:275 ../src/dialog_iemgui.tcl:546 msgid "No init" msgstr "" #: ../src/dialog_iemgui.tcl:287 ../src/dialog_iemgui.tcl:558 msgid "Jump on click" msgstr "" #: ../src/dialog_iemgui.tcl:290 ../src/dialog_iemgui.tcl:561 msgid "Steady on click" msgstr "" #: ../src/dialog_iemgui.tcl:498 #, tcl-format msgid "%s Properties" msgstr "" #: ../src/dialog_iemgui.tcl:550 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:84 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:130 ../src/pd_menus.tcl:260 #: ../src/pd_menus.tcl:273 ../src/pd_menus.tcl:288 ../src/pd_menus.tcl:301 #: ../src/pd_menus.tcl:325 ../src/pd_menus.tcl:338 ../src/pd_menus.tcl:355 #: ../src/pd_menus.tcl:382 ../src/pd_menus.tcl:383 ../src/pd_menus.tcl:410 #: ../src/pd_menus.tcl:422 ../src/pd_menus.tcl:449 msgid "Save" msgstr "સંગ્રહ કરો" #: ../src/dialog_iemgui.tcl:608 msgid "X offset" msgstr "" #: ../src/dialog_iemgui.tcl:611 ../src/dialog_iemgui.tcl:612 msgid "Y offset" msgstr "" #: ../src/dialog_iemgui.tcl:642 ../src/dialog_iemgui.tcl:645 msgid "Colors" msgstr "રંગો" #: ../src/dialog_iemgui.tcl:648 ../src/dialog_iemgui.tcl:651 #, fuzzy msgid "Background" msgstr "પાશ્વ ભાગ:" #: ../src/dialog_iemgui.tcl:650 ../src/dialog_iemgui.tcl:654 #, fuzzy msgid "Front" msgstr "ફોન્ટ:" #: ../src/dialog_iemgui.tcl:662 ../src/dialog_iemgui.tcl:668 msgid "Compose color" msgstr "" #: ../src/dialog_iemgui.tcl:682 ../src/dialog_iemgui.tcl:688 #, fuzzy msgid "Test label" msgstr "બધું ચકાસો" #: ../src/dialog_midi.tcl:85 msgid "MIDI Settings" msgstr "" #: ../src/dialog_midi.tcl:220 msgid "ALSA MIDI Settings" msgstr "" #: ../src/dialog_midi.tcl:331 msgid "Use multiple ALSA devices" msgstr "" #: ../src/dialog_midi.tcl:337 msgid "In Ports:" msgstr "" #: ../src/dialog_midi.tcl:340 msgid "Out Ports:" msgstr "" #: ../src/g_editor.c:1663 msgid "Discard changes to this window??" msgstr "" #: ../src/g_editor.c:1668 msgid "really quit?" msgstr "" #: ../src/g_editor.c:1699 #, fuzzy msgid "Close this window??" msgstr "આ ટેબ/વિન્ડો બંધ કરો" #: ../src/pd-gui.tcl:185 ../src/pd-gui.tcl:195 ../src/pd-gui.tcl:203 #: ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:215 ../src/pd-gui.tcl:226 msgid "Associated Files" msgstr "" #: ../src/pd-gui.tcl:186 ../src/pd-gui.tcl:196 ../src/pd-gui.tcl:204 #: ../src/pd-gui.tcl:207 ../src/pd-gui.tcl:216 ../src/pd-gui.tcl:227 #, fuzzy msgid "Pd Files" msgstr "ફાઇલ" #: ../src/pd-gui.tcl:187 ../src/pd-gui.tcl:205 ../src/pd-gui.tcl:208 #: ../src/pd-gui.tcl:228 msgid "Max Patch Files" msgstr "" #: ../src/pd-gui.tcl:188 ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:209 #: ../src/pd-gui.tcl:229 msgid "Max Text Files" msgstr "" #: ../src/pd-gui.tcl:197 ../src/pd-gui.tcl:217 msgid "Max Patch Files (.pat)" msgstr "" #: ../src/pd-gui.tcl:198 ../src/pd-gui.tcl:218 msgid "Max Text Files (.mxt)" msgstr "" #: ../src/pd-gui.tcl:270 ../src/pd-gui.tcl:290 #, tcl-format msgid "WARNING: Font family '%s' not found, using default (%s)" msgstr "" #: ../src/pd-gui.tcl:278 ../src/pd-gui.tcl:298 #, tcl-format msgid "WARNING: Font weight '%s' not found, using default (%s)" msgstr "" #: ../src/pd-gui.tcl:303 ../src/pd-gui.tcl:323 #, tcl-format msgid "ERROR: %s failed to find font size (%s) that fits into %sx%s!" msgstr "" #: ../src/pd-gui.tcl:478 ../src/pd-gui.tcl:483 ../src/pd-gui.tcl:501 msgid "ERROR: 'pd' never showed up, 'pd-gui' quitting!" msgstr "" #: ../src/pd_menucommands.tcl:19 msgid "Untitled" msgstr "" #: ../src/pd_menucommands.tcl:78 ../src/pd_menucommands.tcl:79 #: ../src/pd_menucommands.tcl:90 #, fuzzy msgid "Send Message..." msgstr "સંદેશો" #: ../src/pd_menucommands.tcl:82 ../src/pd_menucommands.tcl:83 #: ../src/pd_menucommands.tcl:94 ../src/pd_menus.tcl:87 ../src/pd_menus.tcl:88 #: ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:134 ../src/pd_menus.tcl:147 #: ../src/pd_menus.tcl:192 ../src/pd_menus.tcl:193 ../src/pd_menus.tcl:265 #: ../src/pd_menus.tcl:278 ../src/pd_menus.tcl:292 ../src/pd_menus.tcl:305 #: ../src/pd_menus.tcl:329 ../src/pd_menus.tcl:342 ../src/pd_menus.tcl:360 #: ../src/pd_menus.tcl:387 ../src/pd_menus.tcl:414 ../src/pd_menus.tcl:426 #: ../src/pd_menus.tcl:453 ../startup/object_db.tcl:123 msgid "Message" msgstr "સંદેશો" #: ../src/pd_menucommands.tcl:108 ../src/pd_menucommands.tcl:111 #: ../src/pd_menus.tcl:112 ../src/pd_menus.tcl:113 ../src/pd_menus.tcl:117 #: ../src/pd_menus.tcl:118 ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:159 #: ../src/pd_menus.tcl:163 ../src/pd_menus.tcl:164 #, fuzzy msgid "Font" msgstr "ફોન્ટ:" #: ../src/pd_menucommands.tcl:123 ../src/pd_menucommands.tcl:126 #: ../src/pd_menus.tcl:138 ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:184 #, fuzzy msgid "Preferences" msgstr "પસંદગીઓ..." #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Edit" msgstr "ફેરફાર કરો (_E)" #: ../src/pd_menus.tcl:45 msgid "File" msgstr "ફાઇલ" #: ../src/pd_menus.tcl:45 ../src/pdtk_canvas.tcl:48 ../src/pdtk_canvas.tcl:110 #: ../src/pdtk_canvas.tcl:113 msgid "Help" msgstr "મદદ" #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Media" msgstr "મેકેડોનિયા" #: ../src/pd_menus.tcl:45 msgid "Put" msgstr "" #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Window" msgstr "વિન્ડો (_W)" #: ../src/pd_menus.tcl:81 ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:127 #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:255 ../src/pd_menus.tcl:267 #: ../src/pd_menus.tcl:285 ../src/pd_menus.tcl:298 ../src/pd_menus.tcl:322 #: ../src/pd_menus.tcl:335 ../src/pd_menus.tcl:349 ../src/pd_menus.tcl:376 #: ../src/pd_menus.tcl:380 ../src/pd_menus.tcl:407 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:446 msgid "New" msgstr "નવું" #: ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:128 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:268 #: ../src/pd_menus.tcl:286 ../src/pd_menus.tcl:299 ../src/pd_menus.tcl:323 #: ../src/pd_menus.tcl:336 ../src/pd_menus.tcl:350 ../src/pd_menus.tcl:377 #: ../src/pd_menus.tcl:381 ../src/pd_menus.tcl:408 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:447 ../src/pdtk_canvas.tcl:46 #: ../src/pdtk_canvas.tcl:108 ../src/pdtk_canvas.tcl:111 #: ../src/pdtk_canvas.tcl:128 ../src/pdtk_canvas.tcl:130 #: ../src/pdtk_canvas.tcl:131 ../src/pdtk_canvas.tcl:133 msgid "Open" msgstr "ખોલો" #: ../src/pd_menus.tcl:84 ../src/pd_menus.tcl:85 ../src/pd_menus.tcl:130 #: ../src/pd_menus.tcl:131 ../src/pd_menus.tcl:261 ../src/pd_menus.tcl:274 #: ../src/pd_menus.tcl:289 ../src/pd_menus.tcl:302 ../src/pd_menus.tcl:326 #: ../src/pd_menus.tcl:339 ../src/pd_menus.tcl:356 ../src/pd_menus.tcl:383 #: ../src/pd_menus.tcl:384 ../src/pd_menus.tcl:411 ../src/pd_menus.tcl:423 #: ../src/pd_menus.tcl:450 #, fuzzy msgid "Save As..." msgstr "આ રીતે સંગ્રહ કરો" #: ../src/pd_menus.tcl:88 ../src/pd_menus.tcl:89 ../src/pd_menus.tcl:134 #: ../src/pd_menus.tcl:135 ../src/pd_menus.tcl:267 ../src/pd_menus.tcl:280 #: ../src/pd_menus.tcl:293 ../src/pd_menus.tcl:306 ../src/pd_menus.tcl:330 #: ../src/pd_menus.tcl:343 ../src/pd_menus.tcl:362 ../src/pd_menus.tcl:388 #: ../src/pd_menus.tcl:389 ../src/pd_menus.tcl:415 ../src/pd_menus.tcl:427 #: ../src/pd_menus.tcl:454 #, fuzzy msgid "Print..." msgstr "ફેરફાર કરો (_E)..." #: ../src/pd_menus.tcl:93 ../src/pd_menus.tcl:94 ../src/pd_menus.tcl:139 #: ../src/pd_menus.tcl:140 #, fuzzy msgid "Undo" msgstr "યુગાન્ડા" #: ../src/pd_menus.tcl:95 ../src/pd_menus.tcl:96 ../src/pd_menus.tcl:141 #: ../src/pd_menus.tcl:142 #, fuzzy msgid "Redo" msgstr "લાલ:" #: ../src/pd_menus.tcl:98 ../src/pd_menus.tcl:99 ../src/pd_menus.tcl:144 #: ../src/pd_menus.tcl:145 msgid "Cut" msgstr "" #: ../src/pd_menus.tcl:104 ../src/pd_menus.tcl:105 ../src/pd_menus.tcl:150 #: ../src/pd_menus.tcl:151 #, fuzzy msgid "Duplicate" msgstr "તારીખ" #: ../src/pd_menus.tcl:106 ../src/pd_menus.tcl:107 ../src/pd_menus.tcl:152 #: ../src/pd_menus.tcl:153 #, fuzzy msgid "Select All" msgstr "રંગ પસંદ કરો" #: ../src/pd_menus.tcl:110 ../src/pd_menus.tcl:111 ../src/pd_menus.tcl:115 #: ../src/pd_menus.tcl:116 ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:157 #: ../src/pd_menus.tcl:161 ../src/pd_menus.tcl:162 #, fuzzy msgid "Text Editor" msgstr "લખાણ રંગો" #: ../src/pd_menus.tcl:120 ../src/pd_menus.tcl:121 ../src/pd_menus.tcl:166 #: ../src/pd_menus.tcl:167 msgid "Tidy Up" msgstr "" #: ../src/pd_menus.tcl:122 ../src/pd_menus.tcl:123 ../src/pd_menus.tcl:168 #: ../src/pd_menus.tcl:169 msgid "Toggle Console" msgstr "" #: ../src/pd_menus.tcl:124 ../src/pd_menus.tcl:125 ../src/pd_menus.tcl:170 #: ../src/pd_menus.tcl:171 #, fuzzy msgid "Clear Console" msgstr "યાદી સાફ કરો" #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:174 #: ../src/pd_menus.tcl:175 #, fuzzy msgid "Edit Mode" msgstr "સ્થિતિ" #: ../src/pd_menus.tcl:145 ../src/pd_menus.tcl:190 ../src/pd_menus.tcl:191 msgid "Object" msgstr "" #: ../src/pd_menus.tcl:149 ../src/pd_menus.tcl:194 ../src/pd_menus.tcl:195 #, fuzzy msgid "Number" msgstr "$ નંબર" #: ../src/pd_menus.tcl:151 ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:197 msgid "Symbol" msgstr "" #: ../src/pd_menus.tcl:153 ../src/pd_menus.tcl:198 ../src/pd_menus.tcl:199 #, fuzzy msgid "Comment" msgstr "આદેશ" #: ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:201 ../src/pd_menus.tcl:202 #, fuzzy msgid "Bang" msgstr "બેન" #: ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:203 ../src/pd_menus.tcl:204 #, fuzzy msgid "Toggle" msgstr "ટોગો" #: ../src/pd_menus.tcl:160 ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:206 #, fuzzy msgid "Number2" msgstr "$ નંબર" #: ../src/pd_menus.tcl:162 ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:208 msgid "Vslider" msgstr "" #: ../src/pd_menus.tcl:164 ../src/pd_menus.tcl:209 ../src/pd_menus.tcl:210 #, fuzzy msgid "Hslider" msgstr "છુપુ" #: ../src/pd_menus.tcl:166 ../src/pd_menus.tcl:211 ../src/pd_menus.tcl:212 #, fuzzy msgid "Vradio" msgstr "આવૃત્તિ" #: ../src/pd_menus.tcl:168 ../src/pd_menus.tcl:213 ../src/pd_menus.tcl:214 msgid "Hradio" msgstr "" #: ../src/pd_menus.tcl:170 ../src/pd_menus.tcl:215 ../src/pd_menus.tcl:216 msgid "VU Meter" msgstr "" #: ../src/pd_menus.tcl:172 ../src/pd_menus.tcl:217 ../src/pd_menus.tcl:218 #, fuzzy msgid "Canvas" msgstr "કેનેડા" #: ../src/pd_menus.tcl:175 ../src/pd_menus.tcl:220 ../src/pd_menus.tcl:221 msgid "Graph" msgstr "ગ્રાફ" #: ../src/pd_menus.tcl:176 ../src/pd_menus.tcl:221 ../src/pd_menus.tcl:222 #, fuzzy msgid "Array" msgstr "અન્ડોરા" #: ../src/pd_menus.tcl:181 ../src/pd_menus.tcl:226 ../src/pd_menus.tcl:227 #, fuzzy msgid "Find..." msgstr "ફાઈલ મોકલો..." #: ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:228 ../src/pd_menus.tcl:229 msgid "Find Again" msgstr "" #: ../src/pd_menus.tcl:185 ../src/pd_menus.tcl:230 ../src/pd_menus.tcl:231 msgid "Find Last Error" msgstr "" #: ../src/pd_menus.tcl:191 ../src/pd_menus.tcl:236 ../src/pd_menus.tcl:237 msgid "DSP On" msgstr "" #: ../src/pd_menus.tcl:193 ../src/pd_menus.tcl:238 ../src/pd_menus.tcl:239 #, fuzzy msgid "DSP Off" msgstr "બંધ" #: ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:242 ../src/pd_menus.tcl:269 msgid "Test Audio and MIDI..." msgstr "" #: ../src/pd_menus.tcl:198 ../src/pd_menus.tcl:244 ../src/pd_menus.tcl:271 #, fuzzy msgid "Load Meter" msgstr "લેગ મીટર:" #: ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:251 ../src/pd_menus.tcl:278 msgid "Minimize" msgstr "" #: ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:253 ../src/pd_menus.tcl:280 #, fuzzy msgid "Zoom" msgstr "નીચે" #: ../src/pd_menus.tcl:210 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:283 #, fuzzy msgid "Parent Window" msgstr "મોકલો વિન્ડો" #: ../src/pd_menus.tcl:216 ../src/pd_menus.tcl:262 ../src/pd_menus.tcl:289 msgid "Bring All to Front" msgstr "" #: ../src/pd_menus.tcl:224 ../src/pd_menus.tcl:241 ../src/pd_menus.tcl:253 #: ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:297 ../src/pd_menus.tcl:335 #: ../src/pd_menus.tcl:362 #, fuzzy msgid "About Pd" msgstr "વિશે (_A)" #: ../src/pd_menus.tcl:227 ../src/pd_menus.tcl:273 ../src/pd_menus.tcl:300 msgid "HTML Manual..." msgstr "" #: ../src/pd_menus.tcl:229 ../src/pd_menus.tcl:275 ../src/pd_menus.tcl:302 #, fuzzy msgid "Browser..." msgstr "શોધો..." #: ../src/pd_menus.tcl:248 ../src/pd_menus.tcl:260 ../src/pd_menus.tcl:342 #: ../src/pd_menus.tcl:369 msgid "Preferences..." msgstr "પસંદગીઓ..." #: ../src/pd_menus.tcl:257 ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:352 #: ../src/pd_menus.tcl:379 msgid "Open Recent" msgstr "" #: ../src/pd_menus.tcl:263 msgid "Audio Settings..." msgstr "" #: ../src/pd_menus.tcl:265 msgid "MIDI Settings..." msgstr "" #: ../src/pd_menus.tcl:296 ../src/pd_menus.tcl:309 ../src/pd_menus.tcl:333 #: ../src/pd_menus.tcl:346 ../src/pd_menus.tcl:393 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:432 ../src/pd_menus.tcl:459 msgid "Quit" msgstr "બહાર નીકળો" #: ../src/pd_menus.tcl:304 ../src/pd_menus.tcl:331 #, fuzzy msgid "Clear Menu" msgstr "યાદી સાફ કરો" #: ../src/pdtk_canvas.tcl:44 ../src/pdtk_canvas.tcl:106 #: ../src/pdtk_canvas.tcl:109 ../src/pdtk_canvas.tcl:123 #: ../src/pdtk_canvas.tcl:125 ../src/pdtk_canvas.tcl:126 #: ../src/pdtk_canvas.tcl:128 msgid "Properties" msgstr "" #: ../src/pdwindow.tcl:43 #, fuzzy msgid "DSP" msgstr "બંધ" #: ../startup/object_db.tcl:113 msgid "Signal" msgstr "" #: ../startup/object_db.tcl:114 msgid "Generators" msgstr "" #: ../startup/object_db.tcl:115 #, fuzzy msgid "Filters" msgstr "ફાઇલ" #: ../startup/object_db.tcl:116 ../startup/object_db.tcl:124 msgid "Math" msgstr "" #: ../startup/object_db.tcl:117 ../startup/object_db.tcl:125 msgid "I/O" msgstr "" #: ../startup/object_db.tcl:118 ../startup/object_db.tcl:126 msgid "Sampling" msgstr "" #: ../startup/object_db.tcl:119 ../startup/object_db.tcl:128 msgid "Routing" msgstr "" #: ../startup/object_db.tcl:120 ../startup/object_db.tcl:129 msgid "Others" msgstr "" #: ../startup/object_db.tcl:127 msgid "GUI" msgstr "" pd-0.46-7/po/hu.po0000664000175000017500000006276712160204055012003 0ustar mspmsp# Hungarian translation of Pure Data. # This file is put in the public domain # # Andras Muranyi , 2009, 2010. msgid "" msgstr "" "Project-Id-Version: Pure Data 0.43\n" "Report-Msgid-Bugs-To: pd-dev@iem.at\n" "POT-Creation-Date: 2009-08-27 10:01-0400\n" "PO-Revision-Date: 2010-01-29 21:09+0100\n" "Last-Translator: Andras Muranyi \n" "Language-Team: Hungarian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: " msgid "Undo duplicate" msgstr "Mégsem duplikál" msgid "Undo paste" msgstr "Mégsem illeszt be" msgid "Undo motion" msgstr "Mégsem mozgat" msgid "Undo cut" msgstr "Mégsem vág ki" msgid "Undo disconnect" msgstr "Mégsem törli a csatlakozást" msgid "Undo connect" msgstr "Mégsem csatlakoztat" msgid "Undo clear" msgstr "Mégsem töröl" msgid "Undo typing" msgstr "Mégsem ír" msgid "Discard changes to '%s'?" msgstr "Elveti '%s' változtatásait?" msgid "Do you want to save the changes you made in '%s'?" msgstr "El akarja menteni '%s' változásait?" #: ../src/dialog_array.tcl:115 ../src/dialog_array.tcl:117 #: ../src/pd_menus.tcl:100 ../src/pd_menus.tcl:101 ../src/pd_menus.tcl:146 #: ../src/pd_menus.tcl:147 msgid "Copy" msgstr "Másol" #: ../src/dialog_array.tcl:118 ../src/dialog_array.tcl:120 #: ../src/pd_menus.tcl:102 ../src/pd_menus.tcl:103 ../src/pd_menus.tcl:148 #: ../src/pd_menus.tcl:149 msgid "Paste" msgstr "Beilleszt" #: ../src/dialog_array.tcl:264 ../src/dialog_array.tcl:266 msgid "Array Properties" msgstr "Array tulajdonságai" #: ../src/dialog_array.tcl:270 ../src/dialog_array.tcl:272 msgid "Name:" msgstr "Név:" #: ../src/dialog_array.tcl:276 ../src/dialog_array.tcl:278 #: ../src/dialog_canvas.tcl:178 ../src/dialog_canvas.tcl:193 #: ../src/dialog_iemgui.tcl:619 ../src/dialog_iemgui.tcl:621 msgid "Size:" msgstr "Méret:" #: ../src/dialog_array.tcl:280 ../src/dialog_array.tcl:282 msgid "Save contents" msgstr "Tartalom mentése" #: ../src/dialog_array.tcl:284 ../src/dialog_array.tcl:286 msgid "Draw as:" msgstr "Megjelenítés:" #: ../src/dialog_array.tcl:287 ../src/dialog_array.tcl:289 msgid "Points" msgstr "Pontok" #: ../src/dialog_array.tcl:289 ../src/dialog_array.tcl:291 msgid "Polygon" msgstr "Sokszög" #: ../src/dialog_array.tcl:291 ../src/dialog_array.tcl:293 msgid "Bezier curve" msgstr "Bezier görbe" #: ../src/dialog_array.tcl:297 ../src/dialog_array.tcl:299 msgid "Put array into:" msgstr "Array helye:" #: ../src/dialog_array.tcl:300 ../src/dialog_array.tcl:302 msgid "New graph" msgstr "Új graph" #: ../src/dialog_array.tcl:302 ../src/dialog_array.tcl:304 msgid "Last graph" msgstr "Legutóbbi graph" #: ../src/dialog_array.tcl:306 ../src/dialog_array.tcl:308 msgid "Delete array" msgstr "Array-t töröl" #: ../src/dialog_array.tcl:312 ../src/dialog_array.tcl:314 msgid "Open List View..." msgstr "Lista nézet megnyitása..." #: ../src/dialog_array.tcl:319 ../src/dialog_array.tcl:321 #: ../src/dialog_audio.tcl:136 ../src/dialog_canvas.tcl:205 #: ../src/dialog_font.tcl:51 ../src/dialog_gatom.tcl:153 #: ../src/dialog_gatom.tcl:161 ../src/dialog_iemgui.tcl:742 #: ../src/dialog_iemgui.tcl:748 ../src/dialog_midi.tcl:91 #: ../src/dialog_midi.tcl:226 msgid "Cancel" msgstr "Mégsem" #: ../src/dialog_array.tcl:321 ../src/dialog_array.tcl:323 #: ../src/dialog_audio.tcl:138 ../src/dialog_canvas.tcl:207 #: ../src/dialog_gatom.tcl:156 ../src/dialog_gatom.tcl:164 #: ../src/dialog_iemgui.tcl:745 ../src/dialog_iemgui.tcl:751 #: ../src/dialog_midi.tcl:93 ../src/dialog_midi.tcl:228 msgid "Apply" msgstr "Alkalmaz" #: ../src/dialog_array.tcl:323 ../src/dialog_array.tcl:325 #: ../src/dialog_audio.tcl:140 ../src/dialog_canvas.tcl:209 #: ../src/dialog_font.tcl:53 ../src/dialog_font.tcl:92 #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:101 #: ../src/dialog_gatom.tcl:159 ../src/dialog_gatom.tcl:167 #: ../src/dialog_iemgui.tcl:748 ../src/dialog_iemgui.tcl:754 #: ../src/dialog_midi.tcl:95 ../src/dialog_midi.tcl:230 msgid "OK" msgstr "OK" #: ../src/dialog_audio.tcl:130 msgid "Audio Settings" msgstr "Hang beállítások" #: ../src/dialog_audio.tcl:142 msgid "Save All Settings" msgstr "Minden bellítást ment" #: ../src/dialog_audio.tcl:151 msgid "Sample rate:" msgstr "Mintavétel (Hz):" #: ../src/dialog_audio.tcl:153 msgid "Delay (msec):" msgstr "Késés (ms):" #: ../src/dialog_audio.tcl:158 msgid "Use callbacks" msgstr "Callback-ek használata" #: ../src/dialog_audio.tcl:166 ../src/dialog_midi.tcl:105 #: ../src/dialog_midi.tcl:241 msgid "Input device 1:" msgstr "1. bemeneti eszköz:" #: ../src/dialog_audio.tcl:169 ../src/dialog_audio.tcl:183 #: ../src/dialog_audio.tcl:198 ../src/dialog_audio.tcl:213 #: ../src/dialog_audio.tcl:232 ../src/dialog_audio.tcl:250 #: ../src/dialog_audio.tcl:265 ../src/dialog_audio.tcl:280 msgid "Channels:" msgstr "Csatornák:" #: ../src/dialog_audio.tcl:179 ../src/dialog_midi.tcl:115 #: ../src/dialog_midi.tcl:251 msgid "Input device 2:" msgstr "2. bemeneti eszköz:" #: ../src/dialog_audio.tcl:194 ../src/dialog_midi.tcl:127 #: ../src/dialog_midi.tcl:263 msgid "Input device 3:" msgstr "3. bemeneti eszköz:" #: ../src/dialog_audio.tcl:209 ../src/dialog_midi.tcl:139 #: ../src/dialog_midi.tcl:275 msgid "Input device 4:" msgstr "4. bemeneti eszköz:" #: ../src/dialog_audio.tcl:223 ../src/dialog_midi.tcl:150 #: ../src/dialog_midi.tcl:286 msgid "Output device 1:" msgstr "1. kimeneti eszköz:" #: ../src/dialog_audio.tcl:226 msgid "(same as input device) .............. " msgstr "(ugyanaz mint a bemeneti eszköz) .............. " #: ../src/dialog_audio.tcl:246 ../src/dialog_midi.tcl:160 #: ../src/dialog_midi.tcl:296 msgid "Output device 2:" msgstr "2. kimeneti eszköz:" #: ../src/dialog_audio.tcl:261 ../src/dialog_midi.tcl:171 #: ../src/dialog_midi.tcl:307 msgid "Output device 3:" msgstr "3. kimeneti eszköz:" #: ../src/dialog_audio.tcl:276 ../src/dialog_midi.tcl:182 #: ../src/dialog_midi.tcl:318 msgid "Output device 4:" msgstr "4. kimeneti eszköz:" #: ../src/dialog_audio.tcl:291 ../src/dialog_midi.tcl:195 msgid "Use multiple devices" msgstr "Több eszköz használata" #: ../src/dialog_canvas.tcl:142 msgid "Canvas Properties" msgstr "Canvas tulajdonságai" #: ../src/dialog_canvas.tcl:146 msgid "Scale" msgstr "Méretarány" #: ../src/dialog_canvas.tcl:150 msgid "X units per pixel:" msgstr "X egység képpontonként:" #: ../src/dialog_canvas.tcl:155 msgid "Y units per pixel:" msgstr "Y egység képpontonként:" #: ../src/dialog_canvas.tcl:159 msgid "Appearance on parent patch" msgstr "Megjelenés a szülő patch-en" #: ../src/dialog_canvas.tcl:161 msgid "Graph-On-Parent" msgstr "Megjelenítés a szülőn (GOP)" #: ../src/dialog_canvas.tcl:165 msgid "Hide object name and arguments" msgstr "Elemnév és paraméterek elrejtése" #: ../src/dialog_canvas.tcl:170 msgid "Range and size" msgstr "Tartomány és méret" #: ../src/dialog_canvas.tcl:174 msgid "X range, from" msgstr "X tartomány kezdete" #: ../src/dialog_canvas.tcl:176 ../src/dialog_canvas.tcl:191 msgid "to" msgstr "vége" #: ../src/dialog_canvas.tcl:180 ../src/dialog_canvas.tcl:195 msgid "Margin:" msgstr "Margó:" #: ../src/dialog_canvas.tcl:189 msgid "Y range, from" msgstr "Y tartomány kezdete" #: ../src/dialog_find.tcl:63 ../src/dialog_find.tcl:66 #: ../src/dialog_find.tcl:79 ../src/dialog_find.tcl:80 #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:85 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:101 #: ../src/dialog_find.tcl:105 ../src/dialog_find.tcl:107 #: ../src/pd_menus.tcl:45 msgid "Find" msgstr "Keres" #: ../src/dialog_find.tcl:70 ../src/dialog_find.tcl:73 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:91 #: ../src/dialog_find.tcl:93 msgid "Search in" msgstr "Keresés itt:" #: ../src/dialog_find.tcl:72 ../src/dialog_find.tcl:75 #: ../src/dialog_find.tcl:89 ../src/dialog_find.tcl:93 #: ../src/dialog_find.tcl:95 msgid "for:" msgstr "erre:" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:90 #: ../src/dialog_find.tcl:104 ../src/dialog_find.tcl:108 #: ../src/dialog_find.tcl:110 ../src/pd_menus.tcl:86 ../src/pd_menus.tcl:87 #: ../src/pd_menus.tcl:132 ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:259 #: ../src/pd_menus.tcl:272 ../src/pd_menus.tcl:295 ../src/pd_menus.tcl:308 #: ../src/pd_menus.tcl:332 ../src/pd_menus.tcl:345 ../src/pd_menus.tcl:354 #: ../src/pd_menus.tcl:381 ../src/pd_menus.tcl:392 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:431 ../src/pd_menus.tcl:458 msgid "Close" msgstr "Bezár" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:97 #: ../src/dialog_find.tcl:101 ../src/dialog_find.tcl:103 msgid "Match whole word only" msgstr "Csak egész szavas egyezés" #: ../src/dialog_find.tcl:92 ../src/dialog_font.tcl:49 #: ../src/dialog_font.tcl:50 ../src/pd-gui.tcl:280 ../src/pd-gui.tcl:283 #: ../src/pd-gui.tcl:286 ../src/pd-gui.tcl:288 ../src/pd-gui.tcl:291 #: ../src/pd_menus.tcl:212 ../src/pd_menus.tcl:258 ../src/pd_menus.tcl:285 #: ../src/pdwindow.tcl:33 msgid "Pd window" msgstr "Pd ablak" #: ../src/dialog_font.tcl:45 msgid "Font Properties" msgstr "Betű tulajdonságai" #: ../src/dialog_font.tcl:46 ../src/dialog_font.tcl:54 #: ../src/dialog_font.tcl:55 #, tcl-format msgid "%s Font" msgstr "%s betűkészlet" #: ../src/dialog_font.tcl:61 ../src/dialog_font.tcl:96 #: ../src/dialog_font.tcl:104 ../src/dialog_font.tcl:105 msgid "Font Size" msgstr "Betűméret" #: ../src/dialog_font.tcl:89 ../src/dialog_font.tcl:108 #: ../src/dialog_font.tcl:116 ../src/dialog_font.tcl:117 msgid "Stretch" msgstr "Nyújtás" #: ../src/dialog_font.tcl:96 ../src/dialog_font.tcl:115 #: ../src/dialog_font.tcl:123 ../src/dialog_font.tcl:124 msgid "X and Y" msgstr "X és Y" #: ../src/dialog_font.tcl:98 ../src/dialog_font.tcl:117 #: ../src/dialog_font.tcl:125 ../src/dialog_font.tcl:126 msgid "X only" msgstr "csak X" #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:119 #: ../src/dialog_font.tcl:127 ../src/dialog_font.tcl:128 msgid "Y only" msgstr "csak Y" #: ../src/dialog_gatom.tcl:93 msgid "Atom Box Properties" msgstr "Atom Box tulajdonságai" #: ../src/dialog_gatom.tcl:99 msgid "Width:" msgstr "Szélesség:" #: ../src/dialog_gatom.tcl:103 msgid "Limits" msgstr "Korlátok" #: ../src/dialog_gatom.tcl:107 msgid "Lower:" msgstr "Alsó:" #: ../src/dialog_gatom.tcl:112 ../src/dialog_gatom.tcl:113 msgid "Upper:" msgstr "Felső:" #: ../src/dialog_gatom.tcl:116 ../src/dialog_gatom.tcl:121 #: ../src/dialog_iemgui.tcl:600 ../src/dialog_iemgui.tcl:652 #: ../src/dialog_iemgui.tcl:657 msgid "Label" msgstr "Címke" #: ../src/dialog_gatom.tcl:124 ../src/dialog_gatom.tcl:129 msgid "Left " msgstr "Bal" #: ../src/dialog_gatom.tcl:126 ../src/dialog_gatom.tcl:131 msgid "Right" msgstr "Jobb" #: ../src/dialog_gatom.tcl:128 ../src/dialog_gatom.tcl:133 msgid "Top" msgstr "Fent" #: ../src/dialog_gatom.tcl:130 ../src/dialog_gatom.tcl:135 msgid "Bottom" msgstr "Lent" #: ../src/dialog_gatom.tcl:137 ../src/dialog_gatom.tcl:145 #: ../src/dialog_iemgui.tcl:574 msgid "Messages" msgstr "Üzenetek" #: ../src/dialog_gatom.tcl:141 ../src/dialog_gatom.tcl:149 #: ../src/dialog_iemgui.tcl:578 msgid "Send symbol:" msgstr "Küldött symbol:" #: ../src/dialog_gatom.tcl:147 ../src/dialog_gatom.tcl:155 #: ../src/dialog_iemgui.tcl:585 msgid "Receive symbol:" msgstr "Fogadott symbol:" #: ../src/dialog_iemgui.tcl:197 msgid "Background color" msgstr "Háttérszín" #: ../src/dialog_iemgui.tcl:204 msgid "Foreground color" msgstr "Szín" #: ../src/dialog_iemgui.tcl:211 msgid "Label color" msgstr "Címkeszín" #: ../src/dialog_iemgui.tcl:272 msgid "Init" msgstr "Kezdőérték" #: ../src/dialog_iemgui.tcl:275 ../src/dialog_iemgui.tcl:546 msgid "No init" msgstr "Nincs kezdőérték" #: ../src/dialog_iemgui.tcl:287 ../src/dialog_iemgui.tcl:558 msgid "Jump on click" msgstr "Kattintásra ugorjon" #: ../src/dialog_iemgui.tcl:290 ../src/dialog_iemgui.tcl:561 msgid "Steady on click" msgstr "Kattintásra várjon" #: ../src/dialog_iemgui.tcl:498 #, tcl-format msgid "%s Properties" msgstr "%s tulajdonságai" #: ../src/dialog_iemgui.tcl:550 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:84 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:130 ../src/pd_menus.tcl:260 #: ../src/pd_menus.tcl:273 ../src/pd_menus.tcl:288 ../src/pd_menus.tcl:301 #: ../src/pd_menus.tcl:325 ../src/pd_menus.tcl:338 ../src/pd_menus.tcl:355 #: ../src/pd_menus.tcl:382 ../src/pd_menus.tcl:383 ../src/pd_menus.tcl:410 #: ../src/pd_menus.tcl:422 ../src/pd_menus.tcl:449 msgid "Save" msgstr "Ment" #: ../src/dialog_iemgui.tcl:608 msgid "X offset" msgstr "X offszet" #: ../src/dialog_iemgui.tcl:611 ../src/dialog_iemgui.tcl:612 msgid "Y offset" msgstr "Y offszet" #: ../src/dialog_iemgui.tcl:642 ../src/dialog_iemgui.tcl:645 msgid "Colors" msgstr "Színek" #: ../src/dialog_iemgui.tcl:648 ../src/dialog_iemgui.tcl:651 msgid "Background" msgstr "Háttér" #: ../src/dialog_iemgui.tcl:650 ../src/dialog_iemgui.tcl:654 msgid "Front" msgstr "Előtér" #: ../src/dialog_iemgui.tcl:662 ../src/dialog_iemgui.tcl:668 msgid "Compose color" msgstr "Színkeverés" #: ../src/dialog_iemgui.tcl:682 ../src/dialog_iemgui.tcl:688 msgid "Test label" msgstr "Teszt címke" #: ../src/dialog_midi.tcl:85 msgid "MIDI Settings" msgstr "MIDI beállítások" #: ../src/dialog_midi.tcl:220 msgid "ALSA MIDI Settings" msgstr "ALSA MIDI beállítások" #: ../src/dialog_midi.tcl:331 msgid "Use multiple ALSA devices" msgstr "Több ALSA eszköz használata" #: ../src/dialog_midi.tcl:337 msgid "In Ports:" msgstr "Bejövő portok:" #: ../src/dialog_midi.tcl:340 msgid "Out Ports:" msgstr "Kimenő portok:" #: ../src/g_editor.c:1663 msgid "Discard changes to this window??" msgstr "Elveti az ablak változtatásait?" #: ../src/g_editor.c:1668 msgid "really quit?" msgstr "tényleg kilép?" #: ../src/g_editor.c:1699 msgid "Close this window??" msgstr "Bezárja ezt az ablakot?" #: ../src/pd-gui.tcl:185 ../src/pd-gui.tcl:195 ../src/pd-gui.tcl:203 #: ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:215 ../src/pd-gui.tcl:226 msgid "Associated Files" msgstr "Kapcsolódó fájlok" #: ../src/pd-gui.tcl:186 ../src/pd-gui.tcl:196 ../src/pd-gui.tcl:204 #: ../src/pd-gui.tcl:207 ../src/pd-gui.tcl:216 ../src/pd-gui.tcl:227 msgid "Pd Files" msgstr "Pd fájlok" #: ../src/pd-gui.tcl:187 ../src/pd-gui.tcl:205 ../src/pd-gui.tcl:208 #: ../src/pd-gui.tcl:228 msgid "Max Patch Files" msgstr "Max patch fájlok" #: ../src/pd-gui.tcl:188 ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:209 #: ../src/pd-gui.tcl:229 msgid "Max Text Files" msgstr "Max szövegfájlok" #: ../src/pd-gui.tcl:197 ../src/pd-gui.tcl:217 msgid "Max Patch Files (.pat)" msgstr "Max patch fájlok (.pat)" #: ../src/pd-gui.tcl:198 ../src/pd-gui.tcl:218 msgid "Max Text Files (.mxt)" msgstr "Max szövegfájlok (.mxt)" #: ../src/pd-gui.tcl:270 ../src/pd-gui.tcl:290 #, tcl-format msgid "WARNING: Font family '%s' not found, using default (%s)" msgstr "" "FIGYELEM: Nem található '%s' betűcsalád, az alapbeállítás (%s) érvényes" #: ../src/pd-gui.tcl:278 ../src/pd-gui.tcl:298 #, tcl-format msgid "WARNING: Font weight '%s' not found, using default (%s)" msgstr "" "FIGYELEM: Nem található '%s' betűvastagság, az alapbeállítás (%s) érvényes" #: ../src/pd-gui.tcl:303 ../src/pd-gui.tcl:323 #, tcl-format msgid "ERROR: %s failed to find font size (%s) that fits into %sx%s!" msgstr "FIGYELEM: nem található %s betűkészlet %sx%s (%s) méretben!" #: ../src/pd-gui.tcl:478 ../src/pd-gui.tcl:483 ../src/pd-gui.tcl:501 msgid "ERROR: 'pd' never showed up, 'pd-gui' quitting!" msgstr "HIBA: a 'pd' nem jelentkezett, a 'pd-gui' kilép!" #: ../src/pd_menucommands.tcl:19 msgid "Untitled" msgstr "Névtelen" #: ../src/pd_menucommands.tcl:78 ../src/pd_menucommands.tcl:79 #: ../src/pd_menucommands.tcl:90 msgid "Send Message..." msgstr "Üzenet küldése..." #: ../src/pd_menucommands.tcl:82 ../src/pd_menucommands.tcl:83 #: ../src/pd_menucommands.tcl:94 ../src/pd_menus.tcl:87 ../src/pd_menus.tcl:88 #: ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:134 ../src/pd_menus.tcl:147 #: ../src/pd_menus.tcl:192 ../src/pd_menus.tcl:193 ../src/pd_menus.tcl:265 #: ../src/pd_menus.tcl:278 ../src/pd_menus.tcl:292 ../src/pd_menus.tcl:305 #: ../src/pd_menus.tcl:329 ../src/pd_menus.tcl:342 ../src/pd_menus.tcl:360 #: ../src/pd_menus.tcl:387 ../src/pd_menus.tcl:414 ../src/pd_menus.tcl:426 #: ../src/pd_menus.tcl:453 ../startup/object_db.tcl:123 msgid "Message" msgstr "Üzenet" #: ../src/pd_menucommands.tcl:108 ../src/pd_menucommands.tcl:111 #: ../src/pd_menus.tcl:112 ../src/pd_menus.tcl:113 ../src/pd_menus.tcl:117 #: ../src/pd_menus.tcl:118 ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:159 #: ../src/pd_menus.tcl:163 ../src/pd_menus.tcl:164 msgid "Font" msgstr "Betű" #: ../src/pd_menucommands.tcl:123 ../src/pd_menucommands.tcl:126 #: ../src/pd_menus.tcl:138 ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:184 msgid "Preferences" msgstr "Beállítások" #: ../src/pd_menus.tcl:45 msgid "Edit" msgstr "Szerkeszt" #: ../src/pd_menus.tcl:45 msgid "File" msgstr "Fájl" #: ../src/pd_menus.tcl:45 ../src/pdtk_canvas.tcl:48 ../src/pdtk_canvas.tcl:110 #: ../src/pdtk_canvas.tcl:113 msgid "Help" msgstr "Súgó" #: ../src/pd_menus.tcl:45 msgid "Media" msgstr "Média" #: ../src/pd_menus.tcl:45 msgid "Put" msgstr "Új" #: ../src/pd_menus.tcl:45 msgid "Window" msgstr "Ablak" #: ../src/pd_menus.tcl:81 ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:127 #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:255 ../src/pd_menus.tcl:267 #: ../src/pd_menus.tcl:285 ../src/pd_menus.tcl:298 ../src/pd_menus.tcl:322 #: ../src/pd_menus.tcl:335 ../src/pd_menus.tcl:349 ../src/pd_menus.tcl:376 #: ../src/pd_menus.tcl:380 ../src/pd_menus.tcl:407 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:446 msgid "New" msgstr "Új" #: ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:128 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:268 #: ../src/pd_menus.tcl:286 ../src/pd_menus.tcl:299 ../src/pd_menus.tcl:323 #: ../src/pd_menus.tcl:336 ../src/pd_menus.tcl:350 ../src/pd_menus.tcl:377 #: ../src/pd_menus.tcl:381 ../src/pd_menus.tcl:408 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:447 ../src/pdtk_canvas.tcl:46 #: ../src/pdtk_canvas.tcl:108 ../src/pdtk_canvas.tcl:111 #: ../src/pdtk_canvas.tcl:128 ../src/pdtk_canvas.tcl:130 #: ../src/pdtk_canvas.tcl:131 ../src/pdtk_canvas.tcl:133 msgid "Open" msgstr "Megnyit" #: ../src/pd_menus.tcl:84 ../src/pd_menus.tcl:85 ../src/pd_menus.tcl:130 #: ../src/pd_menus.tcl:131 ../src/pd_menus.tcl:261 ../src/pd_menus.tcl:274 #: ../src/pd_menus.tcl:289 ../src/pd_menus.tcl:302 ../src/pd_menus.tcl:326 #: ../src/pd_menus.tcl:339 ../src/pd_menus.tcl:356 ../src/pd_menus.tcl:383 #: ../src/pd_menus.tcl:384 ../src/pd_menus.tcl:411 ../src/pd_menus.tcl:423 #: ../src/pd_menus.tcl:450 msgid "Save As..." msgstr "Ment új néven..." #: ../src/pd_menus.tcl:88 ../src/pd_menus.tcl:89 ../src/pd_menus.tcl:134 #: ../src/pd_menus.tcl:135 ../src/pd_menus.tcl:267 ../src/pd_menus.tcl:280 #: ../src/pd_menus.tcl:293 ../src/pd_menus.tcl:306 ../src/pd_menus.tcl:330 #: ../src/pd_menus.tcl:343 ../src/pd_menus.tcl:362 ../src/pd_menus.tcl:388 #: ../src/pd_menus.tcl:389 ../src/pd_menus.tcl:415 ../src/pd_menus.tcl:427 #: ../src/pd_menus.tcl:454 msgid "Print..." msgstr "Nyomtat..." #: ../src/pd_menus.tcl:93 ../src/pd_menus.tcl:94 ../src/pd_menus.tcl:139 #: ../src/pd_menus.tcl:140 msgid "Undo" msgstr "Mégsem!" #: ../src/pd_menus.tcl:95 ../src/pd_menus.tcl:96 ../src/pd_menus.tcl:141 #: ../src/pd_menus.tcl:142 msgid "Redo" msgstr "Mégis!" #: ../src/pd_menus.tcl:98 ../src/pd_menus.tcl:99 ../src/pd_menus.tcl:144 #: ../src/pd_menus.tcl:145 msgid "Cut" msgstr "Kivág" #: ../src/pd_menus.tcl:104 ../src/pd_menus.tcl:105 ../src/pd_menus.tcl:150 #: ../src/pd_menus.tcl:151 msgid "Duplicate" msgstr "Duplikál" #: ../src/pd_menus.tcl:106 ../src/pd_menus.tcl:107 ../src/pd_menus.tcl:152 #: ../src/pd_menus.tcl:153 msgid "Select All" msgstr "Mindent kijelöl" #: ../src/pd_menus.tcl:110 ../src/pd_menus.tcl:111 ../src/pd_menus.tcl:115 #: ../src/pd_menus.tcl:116 ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:157 #: ../src/pd_menus.tcl:161 ../src/pd_menus.tcl:162 msgid "Text Editor" msgstr "Szövegszerkesztő" #: ../src/pd_menus.tcl:120 ../src/pd_menus.tcl:121 ../src/pd_menus.tcl:166 #: ../src/pd_menus.tcl:167 msgid "Tidy Up" msgstr "Elrendez" #: ../src/pd_menus.tcl:122 ../src/pd_menus.tcl:123 ../src/pd_menus.tcl:168 #: ../src/pd_menus.tcl:169 msgid "Toggle Console" msgstr "Konzol ki/be" #: ../src/pd_menus.tcl:124 ../src/pd_menus.tcl:125 ../src/pd_menus.tcl:170 #: ../src/pd_menus.tcl:171 msgid "Clear Console" msgstr "Konzolt ürít" #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:174 #: ../src/pd_menus.tcl:175 msgid "Edit Mode" msgstr "Szerkesztő üzemmód" #: ../src/pd_menus.tcl:145 ../src/pd_menus.tcl:190 ../src/pd_menus.tcl:191 msgid "Object" msgstr "Object" #: ../src/pd_menus.tcl:149 ../src/pd_menus.tcl:194 ../src/pd_menus.tcl:195 msgid "Number" msgstr "Number" #: ../src/pd_menus.tcl:151 ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:197 msgid "Symbol" msgstr "Symbol" #: ../src/pd_menus.tcl:153 ../src/pd_menus.tcl:198 ../src/pd_menus.tcl:199 msgid "Comment" msgstr "Comment" #: ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:201 ../src/pd_menus.tcl:202 msgid "Bang" msgstr "Bang" #: ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:203 ../src/pd_menus.tcl:204 msgid "Toggle" msgstr "Toggle" #: ../src/pd_menus.tcl:160 ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:206 msgid "Number2" msgstr "Number2" #: ../src/pd_menus.tcl:162 ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:208 msgid "Vslider" msgstr "Vslider" #: ../src/pd_menus.tcl:164 ../src/pd_menus.tcl:209 ../src/pd_menus.tcl:210 msgid "Hslider" msgstr "Hslider" #: ../src/pd_menus.tcl:166 ../src/pd_menus.tcl:211 ../src/pd_menus.tcl:212 msgid "Vradio" msgstr "Vradio" #: ../src/pd_menus.tcl:168 ../src/pd_menus.tcl:213 ../src/pd_menus.tcl:214 msgid "Hradio" msgstr "Hradio" #: ../src/pd_menus.tcl:170 ../src/pd_menus.tcl:215 ../src/pd_menus.tcl:216 msgid "VU Meter" msgstr "VU meter" #: ../src/pd_menus.tcl:172 ../src/pd_menus.tcl:217 ../src/pd_menus.tcl:218 msgid "Canvas" msgstr "Canvas" #: ../src/pd_menus.tcl:175 ../src/pd_menus.tcl:220 ../src/pd_menus.tcl:221 msgid "Graph" msgstr "Graph" #: ../src/pd_menus.tcl:176 ../src/pd_menus.tcl:221 ../src/pd_menus.tcl:222 msgid "Array" msgstr "Array" #: ../src/pd_menus.tcl:181 ../src/pd_menus.tcl:226 ../src/pd_menus.tcl:227 msgid "Find..." msgstr "Keres..." #: ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:228 ../src/pd_menus.tcl:229 msgid "Find Again" msgstr "Újra keres" #: ../src/pd_menus.tcl:185 ../src/pd_menus.tcl:230 ../src/pd_menus.tcl:231 msgid "Find Last Error" msgstr "Legutóbbi hiba helye" #: ../src/pd_menus.tcl:191 ../src/pd_menus.tcl:236 ../src/pd_menus.tcl:237 msgid "DSP On" msgstr "DSP be" #: ../src/pd_menus.tcl:193 ../src/pd_menus.tcl:238 ../src/pd_menus.tcl:239 msgid "DSP Off" msgstr "DSP ki" #: ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:242 ../src/pd_menus.tcl:269 msgid "Test Audio and MIDI..." msgstr "Hang és MIDI tesztelése..." #: ../src/pd_menus.tcl:198 ../src/pd_menus.tcl:244 ../src/pd_menus.tcl:271 msgid "Load Meter" msgstr "Terhelésmérő" #: ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:251 ../src/pd_menus.tcl:278 msgid "Minimize" msgstr "Kicsinyít" #: ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:253 ../src/pd_menus.tcl:280 msgid "Zoom" msgstr "Nagyító" #: ../src/pd_menus.tcl:210 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:283 msgid "Parent Window" msgstr "Szülő ablak" #: ../src/pd_menus.tcl:216 ../src/pd_menus.tcl:262 ../src/pd_menus.tcl:289 msgid "Bring All to Front" msgstr "Mindent előtérbe hoz" #: ../src/pd_menus.tcl:224 ../src/pd_menus.tcl:241 ../src/pd_menus.tcl:253 #: ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:297 ../src/pd_menus.tcl:335 #: ../src/pd_menus.tcl:362 msgid "About Pd" msgstr "A Pd-ről" #: ../src/pd_menus.tcl:227 ../src/pd_menus.tcl:273 ../src/pd_menus.tcl:300 msgid "HTML Manual..." msgstr "HTML kézikönyv..." #: ../src/pd_menus.tcl:229 ../src/pd_menus.tcl:275 ../src/pd_menus.tcl:302 msgid "Browser..." msgstr "Beépített böngésző..." #: ../src/pd_menus.tcl:248 ../src/pd_menus.tcl:260 ../src/pd_menus.tcl:342 #: ../src/pd_menus.tcl:369 msgid "Preferences..." msgstr "Beállítások..." #: ../src/pd_menus.tcl:257 ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:352 #: ../src/pd_menus.tcl:379 msgid "Open Recent" msgstr "Legutóbbi fájlok" #: ../src/pd_menus.tcl:263 msgid "Audio Settings..." msgstr "Hang beállítások..." #: ../src/pd_menus.tcl:265 msgid "MIDI Settings..." msgstr "MIDI beállítások..." #: ../src/pd_menus.tcl:296 ../src/pd_menus.tcl:309 ../src/pd_menus.tcl:333 #: ../src/pd_menus.tcl:346 ../src/pd_menus.tcl:393 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:432 ../src/pd_menus.tcl:459 msgid "Quit" msgstr "Kilép" #: ../src/pd_menus.tcl:304 ../src/pd_menus.tcl:331 msgid "Clear Menu" msgstr "Menüt ürít" #: ../src/pdtk_canvas.tcl:44 ../src/pdtk_canvas.tcl:106 #: ../src/pdtk_canvas.tcl:109 ../src/pdtk_canvas.tcl:123 #: ../src/pdtk_canvas.tcl:125 ../src/pdtk_canvas.tcl:126 #: ../src/pdtk_canvas.tcl:128 msgid "Properties" msgstr "Tulajdonságok" #: ../src/pdwindow.tcl:43 msgid "DSP" msgstr "DSP" #: ../startup/object_db.tcl:113 msgid "Signal" msgstr "Jel" #: ../startup/object_db.tcl:114 msgid "Generators" msgstr "Generátorok" #: ../startup/object_db.tcl:115 msgid "Filters" msgstr "Szűrők" #: ../startup/object_db.tcl:116 ../startup/object_db.tcl:124 msgid "Math" msgstr "Számítások" #: ../startup/object_db.tcl:117 ../startup/object_db.tcl:125 msgid "I/O" msgstr "I/O" #: ../startup/object_db.tcl:118 ../startup/object_db.tcl:126 msgid "Sampling" msgstr "Mintavételezés" #: ../startup/object_db.tcl:119 ../startup/object_db.tcl:128 msgid "Routing" msgstr "" #: ../startup/object_db.tcl:120 ../startup/object_db.tcl:129 msgid "Others" msgstr "Egyéb" #: ../startup/object_db.tcl:127 msgid "GUI" msgstr "Kezelőfelület" #~ msgid "Patch Font" #~ msgstr "Patch betűkészlet" pd-0.46-7/po/fr.po0000664000175000017500000002501112160204055011753 0ustar mspmsp# French translation for Pure Data # This file is put in the public domain. # msgid "" msgstr "" "Project-Id-Version: Pure Data 0.43\n" "Report-Msgid-Bugs-To: pd-dev@iem.at\n" "POT-Creation-Date: 2009-08-18 20:56-0400\n" "PO-Revision-Date: \n" "Last-Translator: Cyrille Henry\n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: ../src/dialog_array.tcl:117 ../src/pd_menus.tcl:100 msgid "Copy" msgstr "Copier" #: ../src/dialog_array.tcl:120 ../src/pd_menus.tcl:102 msgid "Paste" msgstr "Coller" #: ../src/dialog_array.tcl:266 msgid "Array Properties" msgstr "Propriétés du tableau" #: ../src/dialog_array.tcl:272 msgid "Name:" msgstr "Nom:" #: ../src/dialog_array.tcl:278 ../src/dialog_canvas.tcl:178 #: ../src/dialog_canvas.tcl:193 ../src/dialog_iemgui.tcl:619 msgid "Size:" msgstr "Taille:" #: ../src/dialog_array.tcl:282 msgid "Save contents" msgstr "Sauver le contenu" #: ../src/dialog_array.tcl:286 msgid "Draw as:" msgstr "" #: ../src/dialog_array.tcl:289 msgid "Points" msgstr "Points" #: ../src/dialog_array.tcl:291 msgid "Polygon" msgstr "Polygone" #: ../src/dialog_array.tcl:293 msgid "Bezier curve" msgstr "courbe de Bezier" #: ../src/dialog_array.tcl:299 msgid "Put array into:" msgstr "" #: ../src/dialog_array.tcl:302 msgid "New graph" msgstr "Nouveau graphique" #: ../src/dialog_array.tcl:304 msgid "Last graph" msgstr "" #: ../src/dialog_array.tcl:308 msgid "Delete array" msgstr "supprimer le tableau" #: ../src/dialog_array.tcl:314 msgid "Open List View..." msgstr "" #: ../src/dialog_array.tcl:321 ../src/dialog_canvas.tcl:205 #: ../src/dialog_font.tcl:51 ../src/dialog_gatom.tcl:161 #: ../src/dialog_iemgui.tcl:742 msgid "Cancel" msgstr "Annuler" #: ../src/dialog_array.tcl:323 ../src/dialog_canvas.tcl:207 #: ../src/dialog_gatom.tcl:164 ../src/dialog_iemgui.tcl:745 msgid "Apply" msgstr "Appliquer" #: ../src/dialog_array.tcl:325 ../src/dialog_canvas.tcl:209 #: ../src/dialog_font.tcl:53 ../src/dialog_gatom.tcl:167 #: ../src/dialog_iemgui.tcl:748 msgid "OK" msgstr "OK" #: ../src/dialog_canvas.tcl:142 msgid "Canvas Properties" msgstr "Propriétés du Canvas" #: ../src/dialog_canvas.tcl:146 msgid "Scale" msgstr "Echéle" #: ../src/dialog_canvas.tcl:150 msgid "X units per pixel:" msgstr "" #: ../src/dialog_canvas.tcl:155 msgid "Y units per pixel:" msgstr "" #: ../src/dialog_canvas.tcl:159 msgid "Appearance on parent patch" msgstr "" #: ../src/dialog_canvas.tcl:161 msgid "Graph-On-Parent" msgstr "" #: ../src/dialog_canvas.tcl:165 msgid "Hide object name and arguments" msgstr "cacher le nom et arguments de l'objet" #: ../src/dialog_canvas.tcl:170 msgid "Range and size" msgstr "taille et échèle" #: ../src/dialog_canvas.tcl:174 msgid "X range, from" msgstr "" #: ../src/dialog_canvas.tcl:176 ../src/dialog_canvas.tcl:191 msgid "to" msgstr "à" #: ../src/dialog_canvas.tcl:180 ../src/dialog_canvas.tcl:195 msgid "Margin:" msgstr "Marges" #: ../src/dialog_canvas.tcl:189 msgid "Y range, from" msgstr "" #: ../src/dialog_find.tcl:63 ../src/dialog_find.tcl:80 ../src/pd_menus.tcl:45 msgid "Find" msgstr "Rechercher" #: ../src/dialog_find.tcl:70 msgid "Search in" msgstr "Rechercher dans" #: ../src/dialog_find.tcl:72 msgid "for:" msgstr "pour:" #: ../src/dialog_find.tcl:83 ../src/pd_menus.tcl:86 ../src/pd_menus.tcl:259 #: ../src/pd_menus.tcl:295 ../src/pd_menus.tcl:332 msgid "Close" msgstr "Fermer" #: ../src/dialog_font.tcl:45 msgid "Patch Font" msgstr "Police du patch" #: ../src/dialog_font.tcl:61 msgid "Font Size:" msgstr "taille de la police:" #: ../src/dialog_font.tcl:89 msgid "Stretch:" msgstr "Étirer" #: ../src/dialog_font.tcl:96 msgid "X and Y" msgstr "X et Y" #: ../src/dialog_font.tcl:98 msgid "X only" msgstr "seulement X" #: ../src/dialog_font.tcl:100 msgid "Y only" msgstr "seulement Y" #: ../src/dialog_gatom.tcl:93 msgid "Atom Box Properties" msgstr "Propriétés du nombre" #: ../src/dialog_gatom.tcl:99 msgid "Width:" msgstr "Largeur:" #: ../src/dialog_gatom.tcl:103 msgid "Limits" msgstr "Limites" #: ../src/dialog_gatom.tcl:107 msgid "Lower:" msgstr "Inférieur:" #: ../src/dialog_gatom.tcl:113 msgid "Upper:" msgstr "Supérieur:" #: ../src/dialog_gatom.tcl:121 ../src/dialog_iemgui.tcl:600 #: ../src/dialog_iemgui.tcl:652 msgid "Label" msgstr "Label" #: ../src/dialog_gatom.tcl:129 msgid "Left " msgstr "Gauche" #: ../src/dialog_gatom.tcl:131 msgid "Right" msgstr "Droite" #: ../src/dialog_gatom.tcl:133 msgid "Top" msgstr "Haut" #: ../src/dialog_gatom.tcl:135 msgid "Bottom" msgstr "Bas" #: ../src/dialog_gatom.tcl:145 ../src/dialog_iemgui.tcl:574 msgid "Messages" msgstr "Messages" #: ../src/dialog_gatom.tcl:149 ../src/dialog_iemgui.tcl:578 msgid "Send symbol:" msgstr "Envoyer au symbole:" #: ../src/dialog_gatom.tcl:155 ../src/dialog_iemgui.tcl:585 msgid "Receive symbol:" msgstr "Reçois du symbole" #: ../src/dialog_iemgui.tcl:197 msgid "Background color" msgstr "Couleur du fond" #: ../src/dialog_iemgui.tcl:204 msgid "Foreground color" msgstr "Couleur du premier plan" #: ../src/dialog_iemgui.tcl:211 msgid "Label color" msgstr "" #: ../src/dialog_iemgui.tcl:272 msgid "Init" msgstr "Initialisation" #: ../src/dialog_iemgui.tcl:275 ../src/dialog_iemgui.tcl:546 msgid "No init" msgstr "Pas d'initialisation" #: ../src/dialog_iemgui.tcl:287 ../src/dialog_iemgui.tcl:558 msgid "Jump on click" msgstr "" #: ../src/dialog_iemgui.tcl:290 ../src/dialog_iemgui.tcl:561 msgid "Steady on click" msgstr "" #: ../src/dialog_iemgui.tcl:498 #, tcl-format msgid "%s Properties" msgstr "%s Propriétés" #: ../src/dialog_iemgui.tcl:550 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:260 #: ../src/pd_menus.tcl:288 ../src/pd_menus.tcl:325 msgid "Save" msgstr "Sauvegarder" #: ../src/dialog_iemgui.tcl:608 msgid "X offset" msgstr "Offset en X" #: ../src/dialog_iemgui.tcl:611 msgid "Y offset" msgstr "Offset en Y" #: ../src/dialog_iemgui.tcl:642 msgid "Colors" msgstr "Couleur" #: ../src/dialog_iemgui.tcl:648 msgid "Background" msgstr "" #: ../src/dialog_iemgui.tcl:650 msgid "Front" msgstr "Police de caractére" #: ../src/dialog_iemgui.tcl:662 msgid "Compose color" msgstr "créer la couleur" #: ../src/dialog_iemgui.tcl:682 msgid "Test label" msgstr "" #: ../src/pd-gui.tcl:280 ../src/pd-gui.tcl:283 ../src/pd_menus.tcl:212 msgid "Pd window" msgstr "Fenêtre Pd" #: ../src/pd_menucommands.tcl:90 msgid "Send Message..." msgstr "Envoyer Message..." #: ../src/pd_menucommands.tcl:94 ../src/pd_menus.tcl:87 #: ../src/pd_menus.tcl:147 ../src/pd_menus.tcl:265 ../src/pd_menus.tcl:292 #: ../src/pd_menus.tcl:329 msgid "Message" msgstr "Message" #: ../src/pd_menucommands.tcl:108 ../src/pd_menucommands.tcl:111 #: ../src/pd_menus.tcl:112 ../src/pd_menus.tcl:117 msgid "Font" msgstr "Police" #: ../src/pd_menucommands.tcl:123 ../src/pd_menucommands.tcl:126 #: ../src/pd_menus.tcl:138 msgid "Preferences" msgstr "Préférences" #: ../src/pd_menus.tcl:45 msgid "Edit" msgstr "Édition" #: ../src/pd_menus.tcl:45 msgid "File" msgstr "Fichier" #: ../src/pd_menus.tcl:45 ../src/pdtk_canvas.tcl:48 msgid "Help" msgstr "Aide" #: ../src/pd_menus.tcl:45 msgid "Media" msgstr "Média" #: ../src/pd_menus.tcl:45 msgid "Put" msgstr "Ajouter" #: ../src/pd_menus.tcl:45 msgid "Window" msgstr "Fenêtre" #: ../src/pd_menus.tcl:81 ../src/pd_menus.tcl:255 ../src/pd_menus.tcl:285 #: ../src/pd_menus.tcl:322 msgid "New" msgstr "Nouveau" "" #: ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:286 #: ../src/pd_menus.tcl:323 ../src/pdtk_canvas.tcl:46 msgid "Open" msgstr "Ouvrir" #: ../src/pd_menus.tcl:84 ../src/pd_menus.tcl:261 ../src/pd_menus.tcl:289 #: ../src/pd_menus.tcl:326 msgid "Save As..." msgstr "Sauvegarder Sous..." #: ../src/pd_menus.tcl:88 ../src/pd_menus.tcl:267 ../src/pd_menus.tcl:293 #: ../src/pd_menus.tcl:330 msgid "Print..." msgstr "Imprimer..." #: ../src/pd_menus.tcl:93 msgid "Undo" msgstr "Défaire" #: ../src/pd_menus.tcl:95 msgid "Redo" msgstr "Refaire" #: ../src/pd_menus.tcl:98 msgid "Cut" msgstr "Couper" #: ../src/pd_menus.tcl:104 msgid "Duplicate" msgstr "Dupliquer" #: ../src/pd_menus.tcl:106 msgid "Select All" msgstr "Sélectionner tout" #: ../src/pd_menus.tcl:110 ../src/pd_menus.tcl:115 msgid "Text Editor" msgstr "éditeur de texte..." #: ../src/pd_menus.tcl:120 msgid "Tidy Up" msgstr "Aligner" #: ../src/pd_menus.tcl:122 msgid "Toggle Console" msgstr "" #: ../src/pd_menus.tcl:124 msgid "Clear Console" msgstr "Effacer la console" #: ../src/pd_menus.tcl:128 msgid "Edit Mode" msgstr "Mode d'édition" #: ../src/pd_menus.tcl:145 msgid "Object" msgstr "Objet" #: ../src/pd_menus.tcl:149 msgid "Number" msgstr "Nombre" #: ../src/pd_menus.tcl:151 msgid "Symbol" msgstr "Symbole" #: ../src/pd_menus.tcl:153 msgid "Comment" msgstr "Commentaire" #: ../src/pd_menus.tcl:156 msgid "Bang" msgstr "Bang" #: ../src/pd_menus.tcl:158 msgid "Toggle" msgstr "interrupteur" #: ../src/pd_menus.tcl:160 msgid "Number2" msgstr "Nombre2" #: ../src/pd_menus.tcl:162 msgid "Vslider" msgstr "slider_V" #: ../src/pd_menus.tcl:164 msgid "Hslider" msgstr "Slider_H" #: ../src/pd_menus.tcl:166 msgid "Vradio" msgstr "selecteur_V" #: ../src/pd_menus.tcl:168 msgid "Hradio" msgstr "selecteur_H" #: ../src/pd_menus.tcl:170 msgid "VU Meter" msgstr "VU-mètre" #: ../src/pd_menus.tcl:172 msgid "Canvas" msgstr "Canvas" #: ../src/pd_menus.tcl:175 msgid "Graph" msgstr "Graphique" #: ../src/pd_menus.tcl:176 msgid "Array" msgstr "Tableau" #: ../src/pd_menus.tcl:181 msgid "Find..." msgstr "Rechercher" #: ../src/pd_menus.tcl:183 msgid "Find Again" msgstr "Rechercher encore" #: ../src/pd_menus.tcl:185 msgid "Find Last Error" msgstr "Rechercher la dernière erreur" #: ../src/pd_menus.tcl:191 msgid "DSP On" msgstr "DSP On" #: ../src/pd_menus.tcl:193 msgid "DSP Off" msgstr "DSP off" #: ../src/pd_menus.tcl:196 msgid "Test Audio and MIDI..." msgstr "Tester l'audio et le MIDI" #: ../src/pd_menus.tcl:198 msgid "Load Meter" msgstr "CPU-mètre" #: ../src/pd_menus.tcl:205 msgid "Minimize" msgstr "Minimiser" #: ../src/pd_menus.tcl:207 msgid "Zoom" msgstr "Zoom" #: ../src/pd_menus.tcl:210 msgid "Parent Window" msgstr "Fenêtre" #: ../src/pd_menus.tcl:216 msgid "Bring All to Front" msgstr "Tout au premier plan" #: ../src/pd_menus.tcl:241 msgid "About Pd" msgstr "À propos de Pd" #: ../src/pd_menus.tcl:248 msgid "Preferences..." msgstr "Préférences..." #: ../src/pd_menus.tcl:257 msgid "Open Recent" msgstr "ouvrir éléments récent" #: ../src/pd_menus.tcl:296 ../src/pd_menus.tcl:333 msgid "Quit" msgstr "Quitter" #: ../src/pdtk_canvas.tcl:44 msgid "Properties" msgstr "Propriétés" #~ msgid "Audio OFF" #~ msgstr "Audio OFF" #~ msgid "Audio ON" #~ msgstr "Audio ON" #~ msgid "Paths" #~ msgstr "Chemins..." pd-0.46-7/po/be.po0000664000175000017500000006144712160204055011747 0ustar mspmsp# Translation of Pure Data-0.43.po to Belarusian. # This file is put in the public domain. # Pavel Piatruk , 2006, 2007. # msgid "" msgstr "" "Project-Id-Version: Pure Data 0.43\n" "Report-Msgid-Bugs-To: pd-dev@iem.at\n" "POT-Creation-Date: 2009-08-27 10:01-0400\n" "PO-Revision-Date: 2007-06-26 12:02+0300\n" "Last-Translator: Pavel Piatruk \n" "Language-Team: Belarusian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: KBabel 1.10.2\n" #, fuzzy msgid "Undo duplicate" msgstr "Дата" msgid "Undo paste" msgstr "" msgid "Undo motion" msgstr "" #, fuzzy msgid "Undo cut" msgstr "Уганда" msgid "Undo disconnect" msgstr "" msgid "Undo connect" msgstr "" msgid "Undo clear" msgstr "" msgid "Undo typing" msgstr "" msgid "Discard changes to '%s'?" msgstr "" msgid "Do you want to save the changes you made in '%s'?" msgstr "" #: ../src/dialog_array.tcl:115 ../src/dialog_array.tcl:117 #: ../src/pd_menus.tcl:100 ../src/pd_menus.tcl:101 ../src/pd_menus.tcl:146 #: ../src/pd_menus.tcl:147 msgid "Copy" msgstr "Капіяваць" #: ../src/dialog_array.tcl:118 ../src/dialog_array.tcl:120 #: ../src/pd_menus.tcl:102 ../src/pd_menus.tcl:103 ../src/pd_menus.tcl:148 #: ../src/pd_menus.tcl:149 #, fuzzy msgid "Paste" msgstr "Дата" #: ../src/dialog_array.tcl:264 ../src/dialog_array.tcl:266 msgid "Array Properties" msgstr "" #: ../src/dialog_array.tcl:270 ../src/dialog_array.tcl:272 #, fuzzy msgid "Name:" msgstr "Імя" #: ../src/dialog_array.tcl:276 ../src/dialog_array.tcl:278 #: ../src/dialog_canvas.tcl:178 ../src/dialog_canvas.tcl:193 #: ../src/dialog_iemgui.tcl:619 ../src/dialog_iemgui.tcl:621 #, fuzzy msgid "Size:" msgstr "Памер" #: ../src/dialog_array.tcl:280 ../src/dialog_array.tcl:282 #, fuzzy msgid "Save contents" msgstr "_Змест" #: ../src/dialog_array.tcl:284 ../src/dialog_array.tcl:286 msgid "Draw as:" msgstr "" #: ../src/dialog_array.tcl:287 ../src/dialog_array.tcl:289 #, fuzzy msgid "Points" msgstr "Порт" #: ../src/dialog_array.tcl:289 ../src/dialog_array.tcl:291 #, fuzzy msgid "Polygon" msgstr "Польшча" #: ../src/dialog_array.tcl:291 ../src/dialog_array.tcl:293 msgid "Bezier curve" msgstr "" #: ../src/dialog_array.tcl:297 ../src/dialog_array.tcl:299 msgid "Put array into:" msgstr "" #: ../src/dialog_array.tcl:300 ../src/dialog_array.tcl:302 msgid "New graph" msgstr "" #: ../src/dialog_array.tcl:302 ../src/dialog_array.tcl:304 #, fuzzy msgid "Last graph" msgstr "Апошняе паведамленне:" #: ../src/dialog_array.tcl:306 ../src/dialog_array.tcl:308 #, fuzzy msgid "Delete array" msgstr "Выдаліць" #: ../src/dialog_array.tcl:312 ../src/dialog_array.tcl:314 #, fuzzy msgid "Open List View..." msgstr "Спіс забароненых..." #: ../src/dialog_array.tcl:319 ../src/dialog_array.tcl:321 #: ../src/dialog_audio.tcl:136 ../src/dialog_canvas.tcl:205 #: ../src/dialog_font.tcl:51 ../src/dialog_gatom.tcl:153 #: ../src/dialog_gatom.tcl:161 ../src/dialog_iemgui.tcl:742 #: ../src/dialog_iemgui.tcl:748 ../src/dialog_midi.tcl:91 #: ../src/dialog_midi.tcl:226 msgid "Cancel" msgstr "Адмяніць" #: ../src/dialog_array.tcl:321 ../src/dialog_array.tcl:323 #: ../src/dialog_audio.tcl:138 ../src/dialog_canvas.tcl:207 #: ../src/dialog_gatom.tcl:156 ../src/dialog_gatom.tcl:164 #: ../src/dialog_iemgui.tcl:745 ../src/dialog_iemgui.tcl:751 #: ../src/dialog_midi.tcl:93 ../src/dialog_midi.tcl:228 msgid "Apply" msgstr "" #: ../src/dialog_array.tcl:323 ../src/dialog_array.tcl:325 #: ../src/dialog_audio.tcl:140 ../src/dialog_canvas.tcl:209 #: ../src/dialog_font.tcl:53 ../src/dialog_font.tcl:92 #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:101 #: ../src/dialog_gatom.tcl:159 ../src/dialog_gatom.tcl:167 #: ../src/dialog_iemgui.tcl:748 ../src/dialog_iemgui.tcl:754 #: ../src/dialog_midi.tcl:95 ../src/dialog_midi.tcl:230 msgid "OK" msgstr "" #: ../src/dialog_audio.tcl:130 msgid "Audio Settings" msgstr "" #: ../src/dialog_audio.tcl:142 msgid "Save All Settings" msgstr "" #: ../src/dialog_audio.tcl:151 msgid "Sample rate:" msgstr "" #: ../src/dialog_audio.tcl:153 msgid "Delay (msec):" msgstr "" #: ../src/dialog_audio.tcl:158 msgid "Use callbacks" msgstr "" #: ../src/dialog_audio.tcl:166 ../src/dialog_midi.tcl:105 #: ../src/dialog_midi.tcl:241 msgid "Input device 1:" msgstr "" #: ../src/dialog_audio.tcl:169 ../src/dialog_audio.tcl:183 #: ../src/dialog_audio.tcl:198 ../src/dialog_audio.tcl:213 #: ../src/dialog_audio.tcl:232 ../src/dialog_audio.tcl:250 #: ../src/dialog_audio.tcl:265 ../src/dialog_audio.tcl:280 #, fuzzy msgid "Channels:" msgstr "Адмяніць" #: ../src/dialog_audio.tcl:179 ../src/dialog_midi.tcl:115 #: ../src/dialog_midi.tcl:251 msgid "Input device 2:" msgstr "" #: ../src/dialog_audio.tcl:194 ../src/dialog_midi.tcl:127 #: ../src/dialog_midi.tcl:263 msgid "Input device 3:" msgstr "" #: ../src/dialog_audio.tcl:209 ../src/dialog_midi.tcl:139 #: ../src/dialog_midi.tcl:275 msgid "Input device 4:" msgstr "" #: ../src/dialog_audio.tcl:223 ../src/dialog_midi.tcl:150 #: ../src/dialog_midi.tcl:286 msgid "Output device 1:" msgstr "" #: ../src/dialog_audio.tcl:226 msgid "(same as input device) .............. " msgstr "" #: ../src/dialog_audio.tcl:246 ../src/dialog_midi.tcl:160 #: ../src/dialog_midi.tcl:296 msgid "Output device 2:" msgstr "" #: ../src/dialog_audio.tcl:261 ../src/dialog_midi.tcl:171 #: ../src/dialog_midi.tcl:307 msgid "Output device 3:" msgstr "" #: ../src/dialog_audio.tcl:276 ../src/dialog_midi.tcl:182 #: ../src/dialog_midi.tcl:318 msgid "Output device 4:" msgstr "" #: ../src/dialog_audio.tcl:291 ../src/dialog_midi.tcl:195 msgid "Use multiple devices" msgstr "" #: ../src/dialog_canvas.tcl:142 msgid "Canvas Properties" msgstr "" #: ../src/dialog_canvas.tcl:146 #, fuzzy msgid "Scale" msgstr "Захаваць" #: ../src/dialog_canvas.tcl:150 msgid "X units per pixel:" msgstr "" #: ../src/dialog_canvas.tcl:155 msgid "Y units per pixel:" msgstr "" #: ../src/dialog_canvas.tcl:159 msgid "Appearance on parent patch" msgstr "" #: ../src/dialog_canvas.tcl:161 msgid "Graph-On-Parent" msgstr "" #: ../src/dialog_canvas.tcl:165 msgid "Hide object name and arguments" msgstr "" #: ../src/dialog_canvas.tcl:170 msgid "Range and size" msgstr "" #: ../src/dialog_canvas.tcl:174 msgid "X range, from" msgstr "" #: ../src/dialog_canvas.tcl:176 ../src/dialog_canvas.tcl:191 msgid "to" msgstr "да" #: ../src/dialog_canvas.tcl:180 ../src/dialog_canvas.tcl:195 #, fuzzy msgid "Margin:" msgstr "Лінія-адзнака:" #: ../src/dialog_canvas.tcl:189 msgid "Y range, from" msgstr "" #: ../src/dialog_find.tcl:63 ../src/dialog_find.tcl:66 #: ../src/dialog_find.tcl:79 ../src/dialog_find.tcl:80 #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:85 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:101 #: ../src/dialog_find.tcl:105 ../src/dialog_find.tcl:107 #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Find" msgstr "Знайсці:" #: ../src/dialog_find.tcl:70 ../src/dialog_find.tcl:73 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:91 #: ../src/dialog_find.tcl:93 #, fuzzy msgid "Search in" msgstr "_Пошук" #: ../src/dialog_find.tcl:72 ../src/dialog_find.tcl:75 #: ../src/dialog_find.tcl:89 ../src/dialog_find.tcl:93 #: ../src/dialog_find.tcl:95 #, fuzzy msgid "for:" msgstr "Порт:" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:90 #: ../src/dialog_find.tcl:104 ../src/dialog_find.tcl:108 #: ../src/dialog_find.tcl:110 ../src/pd_menus.tcl:86 ../src/pd_menus.tcl:87 #: ../src/pd_menus.tcl:132 ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:259 #: ../src/pd_menus.tcl:272 ../src/pd_menus.tcl:295 ../src/pd_menus.tcl:308 #: ../src/pd_menus.tcl:332 ../src/pd_menus.tcl:345 ../src/pd_menus.tcl:354 #: ../src/pd_menus.tcl:381 ../src/pd_menus.tcl:392 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:431 ../src/pd_menus.tcl:458 #, fuzzy msgid "Close" msgstr "_Закрыць" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:97 #: ../src/dialog_find.tcl:101 ../src/dialog_find.tcl:103 msgid "Match whole word only" msgstr "" #: ../src/dialog_find.tcl:92 ../src/dialog_font.tcl:49 #: ../src/dialog_font.tcl:50 ../src/pd-gui.tcl:280 ../src/pd-gui.tcl:283 #: ../src/pd-gui.tcl:286 ../src/pd-gui.tcl:288 ../src/pd-gui.tcl:291 #: ../src/pd_menus.tcl:212 ../src/pd_menus.tcl:258 ../src/pd_menus.tcl:285 #: ../src/pdwindow.tcl:33 #, fuzzy msgid "Pd window" msgstr "Акно дасылкі" #: ../src/dialog_font.tcl:45 msgid "Font Properties" msgstr "" #: ../src/dialog_font.tcl:46 ../src/dialog_font.tcl:54 #: ../src/dialog_font.tcl:55 #, fuzzy, tcl-format msgid "%s Font" msgstr "Шрыфт:" #: ../src/dialog_font.tcl:61 ../src/dialog_font.tcl:96 #: ../src/dialog_font.tcl:104 ../src/dialog_font.tcl:105 #, fuzzy msgid "Font Size" msgstr "Шрыфт:" #: ../src/dialog_font.tcl:89 ../src/dialog_font.tcl:108 #: ../src/dialog_font.tcl:116 ../src/dialog_font.tcl:117 msgid "Stretch" msgstr "" #: ../src/dialog_font.tcl:96 ../src/dialog_font.tcl:115 #: ../src/dialog_font.tcl:123 ../src/dialog_font.tcl:124 msgid "X and Y" msgstr "" #: ../src/dialog_font.tcl:98 ../src/dialog_font.tcl:117 #: ../src/dialog_font.tcl:125 ../src/dialog_font.tcl:126 #, fuzzy msgid "X only" msgstr "Паказаць толькі:" #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:119 #: ../src/dialog_font.tcl:127 ../src/dialog_font.tcl:128 #, fuzzy msgid "Y only" msgstr "Паказаць толькі:" #: ../src/dialog_gatom.tcl:93 msgid "Atom Box Properties" msgstr "" #: ../src/dialog_gatom.tcl:99 msgid "Width:" msgstr "" #: ../src/dialog_gatom.tcl:103 #, fuzzy msgid "Limits" msgstr "Абмежаванне карыстальніка" #: ../src/dialog_gatom.tcl:107 msgid "Lower:" msgstr "" #: ../src/dialog_gatom.tcl:112 ../src/dialog_gatom.tcl:113 #, fuzzy msgid "Upper:" msgstr "Карыстальнік:" #: ../src/dialog_gatom.tcl:116 ../src/dialog_gatom.tcl:121 #: ../src/dialog_iemgui.tcl:600 ../src/dialog_iemgui.tcl:652 #: ../src/dialog_iemgui.tcl:657 msgid "Label" msgstr "" #: ../src/dialog_gatom.tcl:124 ../src/dialog_gatom.tcl:129 msgid "Left " msgstr "" #: ../src/dialog_gatom.tcl:126 ../src/dialog_gatom.tcl:131 msgid "Right" msgstr "" #: ../src/dialog_gatom.tcl:128 ../src/dialog_gatom.tcl:133 msgid "Top" msgstr "Верх" #: ../src/dialog_gatom.tcl:130 ../src/dialog_gatom.tcl:135 msgid "Bottom" msgstr "Ніз" #: ../src/dialog_gatom.tcl:137 ../src/dialog_gatom.tcl:145 #: ../src/dialog_iemgui.tcl:574 #, fuzzy msgid "Messages" msgstr "Паведамленне" #: ../src/dialog_gatom.tcl:141 ../src/dialog_gatom.tcl:149 #: ../src/dialog_iemgui.tcl:578 msgid "Send symbol:" msgstr "" #: ../src/dialog_gatom.tcl:147 ../src/dialog_gatom.tcl:155 #: ../src/dialog_iemgui.tcl:585 #, fuzzy msgid "Receive symbol:" msgstr "Акно атрымання" #: ../src/dialog_iemgui.tcl:197 #, fuzzy msgid "Background color" msgstr "Фон:" #: ../src/dialog_iemgui.tcl:204 #, fuzzy msgid "Foreground color" msgstr "Колер літар:" #: ../src/dialog_iemgui.tcl:211 #, fuzzy msgid "Label color" msgstr "Лакальныя колеры:" #: ../src/dialog_iemgui.tcl:272 #, fuzzy msgid "Init" msgstr "Запрашэнне" #: ../src/dialog_iemgui.tcl:275 ../src/dialog_iemgui.tcl:546 msgid "No init" msgstr "" #: ../src/dialog_iemgui.tcl:287 ../src/dialog_iemgui.tcl:558 msgid "Jump on click" msgstr "" #: ../src/dialog_iemgui.tcl:290 ../src/dialog_iemgui.tcl:561 msgid "Steady on click" msgstr "" #: ../src/dialog_iemgui.tcl:498 #, tcl-format msgid "%s Properties" msgstr "" #: ../src/dialog_iemgui.tcl:550 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:84 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:130 ../src/pd_menus.tcl:260 #: ../src/pd_menus.tcl:273 ../src/pd_menus.tcl:288 ../src/pd_menus.tcl:301 #: ../src/pd_menus.tcl:325 ../src/pd_menus.tcl:338 ../src/pd_menus.tcl:355 #: ../src/pd_menus.tcl:382 ../src/pd_menus.tcl:383 ../src/pd_menus.tcl:410 #: ../src/pd_menus.tcl:422 ../src/pd_menus.tcl:449 msgid "Save" msgstr "Захаваць" #: ../src/dialog_iemgui.tcl:608 msgid "X offset" msgstr "" #: ../src/dialog_iemgui.tcl:611 ../src/dialog_iemgui.tcl:612 msgid "Y offset" msgstr "" #: ../src/dialog_iemgui.tcl:642 ../src/dialog_iemgui.tcl:645 msgid "Colors" msgstr "Колеры" #: ../src/dialog_iemgui.tcl:648 ../src/dialog_iemgui.tcl:651 #, fuzzy msgid "Background" msgstr "Фон:" #: ../src/dialog_iemgui.tcl:650 ../src/dialog_iemgui.tcl:654 #, fuzzy msgid "Front" msgstr "Шрыфт:" #: ../src/dialog_iemgui.tcl:662 ../src/dialog_iemgui.tcl:668 msgid "Compose color" msgstr "" #: ../src/dialog_iemgui.tcl:682 ../src/dialog_iemgui.tcl:688 #, fuzzy msgid "Test label" msgstr "Праверыць усё" #: ../src/dialog_midi.tcl:85 msgid "MIDI Settings" msgstr "" #: ../src/dialog_midi.tcl:220 msgid "ALSA MIDI Settings" msgstr "" #: ../src/dialog_midi.tcl:331 msgid "Use multiple ALSA devices" msgstr "" #: ../src/dialog_midi.tcl:337 msgid "In Ports:" msgstr "" #: ../src/dialog_midi.tcl:340 msgid "Out Ports:" msgstr "" #: ../src/g_editor.c:1663 msgid "Discard changes to this window??" msgstr "" #: ../src/g_editor.c:1668 msgid "really quit?" msgstr "" #: ../src/g_editor.c:1699 #, fuzzy msgid "Close this window??" msgstr "_Закрыць акно" #: ../src/pd-gui.tcl:185 ../src/pd-gui.tcl:195 ../src/pd-gui.tcl:203 #: ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:215 ../src/pd-gui.tcl:226 msgid "Associated Files" msgstr "" #: ../src/pd-gui.tcl:186 ../src/pd-gui.tcl:196 ../src/pd-gui.tcl:204 #: ../src/pd-gui.tcl:207 ../src/pd-gui.tcl:216 ../src/pd-gui.tcl:227 #, fuzzy msgid "Pd Files" msgstr "Файл" #: ../src/pd-gui.tcl:187 ../src/pd-gui.tcl:205 ../src/pd-gui.tcl:208 #: ../src/pd-gui.tcl:228 msgid "Max Patch Files" msgstr "" #: ../src/pd-gui.tcl:188 ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:209 #: ../src/pd-gui.tcl:229 msgid "Max Text Files" msgstr "" #: ../src/pd-gui.tcl:197 ../src/pd-gui.tcl:217 msgid "Max Patch Files (.pat)" msgstr "" #: ../src/pd-gui.tcl:198 ../src/pd-gui.tcl:218 msgid "Max Text Files (.mxt)" msgstr "" #: ../src/pd-gui.tcl:270 ../src/pd-gui.tcl:290 #, tcl-format msgid "WARNING: Font family '%s' not found, using default (%s)" msgstr "" #: ../src/pd-gui.tcl:278 ../src/pd-gui.tcl:298 #, tcl-format msgid "WARNING: Font weight '%s' not found, using default (%s)" msgstr "" #: ../src/pd-gui.tcl:303 ../src/pd-gui.tcl:323 #, tcl-format msgid "ERROR: %s failed to find font size (%s) that fits into %sx%s!" msgstr "" #: ../src/pd-gui.tcl:478 ../src/pd-gui.tcl:483 ../src/pd-gui.tcl:501 msgid "ERROR: 'pd' never showed up, 'pd-gui' quitting!" msgstr "" #: ../src/pd_menucommands.tcl:19 msgid "Untitled" msgstr "" #: ../src/pd_menucommands.tcl:78 ../src/pd_menucommands.tcl:79 #: ../src/pd_menucommands.tcl:90 #, fuzzy msgid "Send Message..." msgstr "Паведамленне" #: ../src/pd_menucommands.tcl:82 ../src/pd_menucommands.tcl:83 #: ../src/pd_menucommands.tcl:94 ../src/pd_menus.tcl:87 ../src/pd_menus.tcl:88 #: ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:134 ../src/pd_menus.tcl:147 #: ../src/pd_menus.tcl:192 ../src/pd_menus.tcl:193 ../src/pd_menus.tcl:265 #: ../src/pd_menus.tcl:278 ../src/pd_menus.tcl:292 ../src/pd_menus.tcl:305 #: ../src/pd_menus.tcl:329 ../src/pd_menus.tcl:342 ../src/pd_menus.tcl:360 #: ../src/pd_menus.tcl:387 ../src/pd_menus.tcl:414 ../src/pd_menus.tcl:426 #: ../src/pd_menus.tcl:453 ../startup/object_db.tcl:123 msgid "Message" msgstr "Паведамленне" #: ../src/pd_menucommands.tcl:108 ../src/pd_menucommands.tcl:111 #: ../src/pd_menus.tcl:112 ../src/pd_menus.tcl:113 ../src/pd_menus.tcl:117 #: ../src/pd_menus.tcl:118 ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:159 #: ../src/pd_menus.tcl:163 ../src/pd_menus.tcl:164 #, fuzzy msgid "Font" msgstr "Шрыфт:" #: ../src/pd_menucommands.tcl:123 ../src/pd_menucommands.tcl:126 #: ../src/pd_menus.tcl:138 ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:184 #, fuzzy msgid "Preferences" msgstr "_Асаблівасці" #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Edit" msgstr "_Рэдагаваць" #: ../src/pd_menus.tcl:45 msgid "File" msgstr "Файл" #: ../src/pd_menus.tcl:45 ../src/pdtk_canvas.tcl:48 ../src/pdtk_canvas.tcl:110 #: ../src/pdtk_canvas.tcl:113 msgid "Help" msgstr "Дапамога" #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Media" msgstr "Македонія" #: ../src/pd_menus.tcl:45 msgid "Put" msgstr "" #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Window" msgstr "Акно" #: ../src/pd_menus.tcl:81 ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:127 #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:255 ../src/pd_menus.tcl:267 #: ../src/pd_menus.tcl:285 ../src/pd_menus.tcl:298 ../src/pd_menus.tcl:322 #: ../src/pd_menus.tcl:335 ../src/pd_menus.tcl:349 ../src/pd_menus.tcl:376 #: ../src/pd_menus.tcl:380 ../src/pd_menus.tcl:407 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:446 #, fuzzy msgid "New" msgstr "_Новы" #: ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:128 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:268 #: ../src/pd_menus.tcl:286 ../src/pd_menus.tcl:299 ../src/pd_menus.tcl:323 #: ../src/pd_menus.tcl:336 ../src/pd_menus.tcl:350 ../src/pd_menus.tcl:377 #: ../src/pd_menus.tcl:381 ../src/pd_menus.tcl:408 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:447 ../src/pdtk_canvas.tcl:46 #: ../src/pdtk_canvas.tcl:108 ../src/pdtk_canvas.tcl:111 #: ../src/pdtk_canvas.tcl:128 ../src/pdtk_canvas.tcl:130 #: ../src/pdtk_canvas.tcl:131 ../src/pdtk_canvas.tcl:133 #, fuzzy msgid "Open" msgstr "Аперацыя" #: ../src/pd_menus.tcl:84 ../src/pd_menus.tcl:85 ../src/pd_menus.tcl:130 #: ../src/pd_menus.tcl:131 ../src/pd_menus.tcl:261 ../src/pd_menus.tcl:274 #: ../src/pd_menus.tcl:289 ../src/pd_menus.tcl:302 ../src/pd_menus.tcl:326 #: ../src/pd_menus.tcl:339 ../src/pd_menus.tcl:356 ../src/pd_menus.tcl:383 #: ../src/pd_menus.tcl:384 ../src/pd_menus.tcl:411 ../src/pd_menus.tcl:423 #: ../src/pd_menus.tcl:450 msgid "Save As..." msgstr "Захаваць як..." #: ../src/pd_menus.tcl:88 ../src/pd_menus.tcl:89 ../src/pd_menus.tcl:134 #: ../src/pd_menus.tcl:135 ../src/pd_menus.tcl:267 ../src/pd_menus.tcl:280 #: ../src/pd_menus.tcl:293 ../src/pd_menus.tcl:306 ../src/pd_menus.tcl:330 #: ../src/pd_menus.tcl:343 ../src/pd_menus.tcl:362 ../src/pd_menus.tcl:388 #: ../src/pd_menus.tcl:389 ../src/pd_menus.tcl:415 ../src/pd_menus.tcl:427 #: ../src/pd_menus.tcl:454 #, fuzzy msgid "Print..." msgstr "_Змяніць..." #: ../src/pd_menus.tcl:93 ../src/pd_menus.tcl:94 ../src/pd_menus.tcl:139 #: ../src/pd_menus.tcl:140 #, fuzzy msgid "Undo" msgstr "Уганда" #: ../src/pd_menus.tcl:95 ../src/pd_menus.tcl:96 ../src/pd_menus.tcl:141 #: ../src/pd_menus.tcl:142 #, fuzzy msgid "Redo" msgstr "Чырвоны" #: ../src/pd_menus.tcl:98 ../src/pd_menus.tcl:99 ../src/pd_menus.tcl:144 #: ../src/pd_menus.tcl:145 msgid "Cut" msgstr "" #: ../src/pd_menus.tcl:104 ../src/pd_menus.tcl:105 ../src/pd_menus.tcl:150 #: ../src/pd_menus.tcl:151 #, fuzzy msgid "Duplicate" msgstr "Дата" #: ../src/pd_menus.tcl:106 ../src/pd_menus.tcl:107 ../src/pd_menus.tcl:152 #: ../src/pd_menus.tcl:153 #, fuzzy msgid "Select All" msgstr "Вылучце колер" #: ../src/pd_menus.tcl:110 ../src/pd_menus.tcl:111 ../src/pd_menus.tcl:115 #: ../src/pd_menus.tcl:116 ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:157 #: ../src/pd_menus.tcl:161 ../src/pd_menus.tcl:162 #, fuzzy msgid "Text Editor" msgstr "Колеры тэксту" #: ../src/pd_menus.tcl:120 ../src/pd_menus.tcl:121 ../src/pd_menus.tcl:166 #: ../src/pd_menus.tcl:167 msgid "Tidy Up" msgstr "" #: ../src/pd_menus.tcl:122 ../src/pd_menus.tcl:123 ../src/pd_menus.tcl:168 #: ../src/pd_menus.tcl:169 msgid "Toggle Console" msgstr "" #: ../src/pd_menus.tcl:124 ../src/pd_menus.tcl:125 ../src/pd_menus.tcl:170 #: ../src/pd_menus.tcl:171 #, fuzzy msgid "Clear Console" msgstr "Ачысціць спіс" #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:174 #: ../src/pd_menus.tcl:175 #, fuzzy msgid "Edit Mode" msgstr "Рэжым" #: ../src/pd_menus.tcl:145 ../src/pd_menus.tcl:190 ../src/pd_menus.tcl:191 msgid "Object" msgstr "" #: ../src/pd_menus.tcl:149 ../src/pd_menus.tcl:194 ../src/pd_menus.tcl:195 #, fuzzy msgid "Number" msgstr "$ Лічба" #: ../src/pd_menus.tcl:151 ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:197 msgid "Symbol" msgstr "" #: ../src/pd_menus.tcl:153 ../src/pd_menus.tcl:198 ../src/pd_menus.tcl:199 #, fuzzy msgid "Comment" msgstr "Каманда" #: ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:201 ../src/pd_menus.tcl:202 #, fuzzy msgid "Bang" msgstr "Забараніць" #: ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:203 ../src/pd_menus.tcl:204 #, fuzzy msgid "Toggle" msgstr "Тога" #: ../src/pd_menus.tcl:160 ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:206 #, fuzzy msgid "Number2" msgstr "$ Лічба" #: ../src/pd_menus.tcl:162 ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:208 msgid "Vslider" msgstr "" #: ../src/pd_menus.tcl:164 ../src/pd_menus.tcl:209 ../src/pd_menus.tcl:210 #, fuzzy msgid "Hslider" msgstr "С_хаваць" #: ../src/pd_menus.tcl:166 ../src/pd_menus.tcl:211 ../src/pd_menus.tcl:212 #, fuzzy msgid "Vradio" msgstr "Версія" #: ../src/pd_menus.tcl:168 ../src/pd_menus.tcl:213 ../src/pd_menus.tcl:214 msgid "Hradio" msgstr "" #: ../src/pd_menus.tcl:170 ../src/pd_menus.tcl:215 ../src/pd_menus.tcl:216 msgid "VU Meter" msgstr "" #: ../src/pd_menus.tcl:172 ../src/pd_menus.tcl:217 ../src/pd_menus.tcl:218 #, fuzzy msgid "Canvas" msgstr "Канада" #: ../src/pd_menus.tcl:175 ../src/pd_menus.tcl:220 ../src/pd_menus.tcl:221 msgid "Graph" msgstr "Графік" #: ../src/pd_menus.tcl:176 ../src/pd_menus.tcl:221 ../src/pd_menus.tcl:222 #, fuzzy msgid "Array" msgstr "Андора" #: ../src/pd_menus.tcl:181 ../src/pd_menus.tcl:226 ../src/pd_menus.tcl:227 #, fuzzy msgid "Find..." msgstr "Знайсці:" #: ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:228 ../src/pd_menus.tcl:229 msgid "Find Again" msgstr "" #: ../src/pd_menus.tcl:185 ../src/pd_menus.tcl:230 ../src/pd_menus.tcl:231 msgid "Find Last Error" msgstr "" #: ../src/pd_menus.tcl:191 ../src/pd_menus.tcl:236 ../src/pd_menus.tcl:237 msgid "DSP On" msgstr "" #: ../src/pd_menus.tcl:193 ../src/pd_menus.tcl:238 ../src/pd_menus.tcl:239 #, fuzzy msgid "DSP Off" msgstr "Выкл" #: ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:242 ../src/pd_menus.tcl:269 msgid "Test Audio and MIDI..." msgstr "" #: ../src/pd_menus.tcl:198 ../src/pd_menus.tcl:244 ../src/pd_menus.tcl:271 msgid "Load Meter" msgstr "" #: ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:251 ../src/pd_menus.tcl:278 #, fuzzy msgid "Minimize" msgstr "_Паменшыць у сподак" #: ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:253 ../src/pd_menus.tcl:280 #, fuzzy msgid "Zoom" msgstr "Ніз" #: ../src/pd_menus.tcl:210 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:283 #, fuzzy msgid "Parent Window" msgstr "Акно дасылкі" #: ../src/pd_menus.tcl:216 ../src/pd_menus.tcl:262 ../src/pd_menus.tcl:289 msgid "Bring All to Front" msgstr "" #: ../src/pd_menus.tcl:224 ../src/pd_menus.tcl:241 ../src/pd_menus.tcl:253 #: ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:297 ../src/pd_menus.tcl:335 #: ../src/pd_menus.tcl:362 #, fuzzy msgid "About Pd" msgstr "Аб праграме" #: ../src/pd_menus.tcl:227 ../src/pd_menus.tcl:273 ../src/pd_menus.tcl:300 msgid "HTML Manual..." msgstr "" #: ../src/pd_menus.tcl:229 ../src/pd_menus.tcl:275 ../src/pd_menus.tcl:302 #, fuzzy msgid "Browser..." msgstr "Агляд.." #: ../src/pd_menus.tcl:248 ../src/pd_menus.tcl:260 ../src/pd_menus.tcl:342 #: ../src/pd_menus.tcl:369 #, fuzzy msgid "Preferences..." msgstr "_Асаблівасці" #: ../src/pd_menus.tcl:257 ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:352 #: ../src/pd_menus.tcl:379 msgid "Open Recent" msgstr "" #: ../src/pd_menus.tcl:263 msgid "Audio Settings..." msgstr "" #: ../src/pd_menus.tcl:265 msgid "MIDI Settings..." msgstr "" #: ../src/pd_menus.tcl:296 ../src/pd_menus.tcl:309 ../src/pd_menus.tcl:333 #: ../src/pd_menus.tcl:346 ../src/pd_menus.tcl:393 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:432 ../src/pd_menus.tcl:459 #, fuzzy msgid "Quit" msgstr "_Выйсці" #: ../src/pd_menus.tcl:304 ../src/pd_menus.tcl:331 #, fuzzy msgid "Clear Menu" msgstr "Ачысціць спіс" #: ../src/pdtk_canvas.tcl:44 ../src/pdtk_canvas.tcl:106 #: ../src/pdtk_canvas.tcl:109 ../src/pdtk_canvas.tcl:123 #: ../src/pdtk_canvas.tcl:125 ../src/pdtk_canvas.tcl:126 #: ../src/pdtk_canvas.tcl:128 msgid "Properties" msgstr "" #: ../src/pdwindow.tcl:43 #, fuzzy msgid "DSP" msgstr "Выкл" #: ../startup/object_db.tcl:113 msgid "Signal" msgstr "" #: ../startup/object_db.tcl:114 msgid "Generators" msgstr "" #: ../startup/object_db.tcl:115 #, fuzzy msgid "Filters" msgstr "Файл" #: ../startup/object_db.tcl:116 ../startup/object_db.tcl:124 msgid "Math" msgstr "" #: ../startup/object_db.tcl:117 ../startup/object_db.tcl:125 msgid "I/O" msgstr "" #: ../startup/object_db.tcl:118 ../startup/object_db.tcl:126 msgid "Sampling" msgstr "" #: ../startup/object_db.tcl:119 ../startup/object_db.tcl:128 msgid "Routing" msgstr "" #: ../startup/object_db.tcl:120 ../startup/object_db.tcl:129 msgid "Others" msgstr "" #: ../startup/object_db.tcl:127 msgid "GUI" msgstr "" pd-0.46-7/po/az.po0000664000175000017500000006022512160204055011764 0ustar mspmsp# translation of Pure Data 0.43 to Azerbaijani Turkish # This file is put in the public domain. # Metin Amiroff , 2004. # msgid "" msgstr "" "Project-Id-Version: Pure Data 0.43\n" "Report-Msgid-Bugs-To: pd-dev@iem.at\n" "POT-Creation-Date: 2009-08-27 10:01-0400\n" "PO-Revision-Date: 2004-03-12 22:22+0200\n" "Last-Translator: Metin Amiroff \n" "Language-Team: Azerbaijani \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #, fuzzy msgid "Undo duplicate" msgstr "Tarix" msgid "Undo paste" msgstr "" msgid "Undo motion" msgstr "" #, fuzzy msgid "Undo cut" msgstr "Uqanda" msgid "Undo disconnect" msgstr "" msgid "Undo connect" msgstr "" msgid "Undo clear" msgstr "" msgid "Undo typing" msgstr "" msgid "Discard changes to '%s'?" msgstr "" msgid "Do you want to save the changes you made in '%s'?" msgstr "" #: ../src/dialog_array.tcl:115 ../src/dialog_array.tcl:117 #: ../src/pd_menus.tcl:100 ../src/pd_menus.tcl:101 ../src/pd_menus.tcl:146 #: ../src/pd_menus.tcl:147 msgid "Copy" msgstr "Köçür" #: ../src/dialog_array.tcl:118 ../src/dialog_array.tcl:120 #: ../src/pd_menus.tcl:102 ../src/pd_menus.tcl:103 ../src/pd_menus.tcl:148 #: ../src/pd_menus.tcl:149 #, fuzzy msgid "Paste" msgstr "Tarix" #: ../src/dialog_array.tcl:264 ../src/dialog_array.tcl:266 msgid "Array Properties" msgstr "" #: ../src/dialog_array.tcl:270 ../src/dialog_array.tcl:272 #, fuzzy msgid "Name:" msgstr "Ad" #: ../src/dialog_array.tcl:276 ../src/dialog_array.tcl:278 #: ../src/dialog_canvas.tcl:178 ../src/dialog_canvas.tcl:193 #: ../src/dialog_iemgui.tcl:619 ../src/dialog_iemgui.tcl:621 #, fuzzy msgid "Size:" msgstr "Böyüklük" #: ../src/dialog_array.tcl:280 ../src/dialog_array.tcl:282 #, fuzzy msgid "Save contents" msgstr "_Məzmun" #: ../src/dialog_array.tcl:284 ../src/dialog_array.tcl:286 msgid "Draw as:" msgstr "" #: ../src/dialog_array.tcl:287 ../src/dialog_array.tcl:289 #, fuzzy msgid "Points" msgstr "Port" #: ../src/dialog_array.tcl:289 ../src/dialog_array.tcl:291 #, fuzzy msgid "Polygon" msgstr "Polşa" #: ../src/dialog_array.tcl:291 ../src/dialog_array.tcl:293 msgid "Bezier curve" msgstr "" #: ../src/dialog_array.tcl:297 ../src/dialog_array.tcl:299 msgid "Put array into:" msgstr "" #: ../src/dialog_array.tcl:300 ../src/dialog_array.tcl:302 msgid "New graph" msgstr "" #: ../src/dialog_array.tcl:302 ../src/dialog_array.tcl:304 #, fuzzy msgid "Last graph" msgstr "Son ismarış: %s" #: ../src/dialog_array.tcl:306 ../src/dialog_array.tcl:308 #, fuzzy msgid "Delete array" msgstr "Sil" #: ../src/dialog_array.tcl:312 ../src/dialog_array.tcl:314 #, fuzzy msgid "Open List View..." msgstr "Ban Siyahısı..." #: ../src/dialog_array.tcl:319 ../src/dialog_array.tcl:321 #: ../src/dialog_audio.tcl:136 ../src/dialog_canvas.tcl:205 #: ../src/dialog_font.tcl:51 ../src/dialog_gatom.tcl:153 #: ../src/dialog_gatom.tcl:161 ../src/dialog_iemgui.tcl:742 #: ../src/dialog_iemgui.tcl:748 ../src/dialog_midi.tcl:91 #: ../src/dialog_midi.tcl:226 msgid "Cancel" msgstr "Ləğv Et" #: ../src/dialog_array.tcl:321 ../src/dialog_array.tcl:323 #: ../src/dialog_audio.tcl:138 ../src/dialog_canvas.tcl:207 #: ../src/dialog_gatom.tcl:156 ../src/dialog_gatom.tcl:164 #: ../src/dialog_iemgui.tcl:745 ../src/dialog_iemgui.tcl:751 #: ../src/dialog_midi.tcl:93 ../src/dialog_midi.tcl:228 msgid "Apply" msgstr "Tətbiq Et" #: ../src/dialog_array.tcl:323 ../src/dialog_array.tcl:325 #: ../src/dialog_audio.tcl:140 ../src/dialog_canvas.tcl:209 #: ../src/dialog_font.tcl:53 ../src/dialog_font.tcl:92 #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:101 #: ../src/dialog_gatom.tcl:159 ../src/dialog_gatom.tcl:167 #: ../src/dialog_iemgui.tcl:748 ../src/dialog_iemgui.tcl:754 #: ../src/dialog_midi.tcl:95 ../src/dialog_midi.tcl:230 msgid "OK" msgstr "" #: ../src/dialog_audio.tcl:130 msgid "Audio Settings" msgstr "" #: ../src/dialog_audio.tcl:142 msgid "Save All Settings" msgstr "" #: ../src/dialog_audio.tcl:151 msgid "Sample rate:" msgstr "" #: ../src/dialog_audio.tcl:153 msgid "Delay (msec):" msgstr "" #: ../src/dialog_audio.tcl:158 msgid "Use callbacks" msgstr "" #: ../src/dialog_audio.tcl:166 ../src/dialog_midi.tcl:105 #: ../src/dialog_midi.tcl:241 msgid "Input device 1:" msgstr "" #: ../src/dialog_audio.tcl:169 ../src/dialog_audio.tcl:183 #: ../src/dialog_audio.tcl:198 ../src/dialog_audio.tcl:213 #: ../src/dialog_audio.tcl:232 ../src/dialog_audio.tcl:250 #: ../src/dialog_audio.tcl:265 ../src/dialog_audio.tcl:280 #, fuzzy msgid "Channels:" msgstr "Ləğv Et" #: ../src/dialog_audio.tcl:179 ../src/dialog_midi.tcl:115 #: ../src/dialog_midi.tcl:251 msgid "Input device 2:" msgstr "" #: ../src/dialog_audio.tcl:194 ../src/dialog_midi.tcl:127 #: ../src/dialog_midi.tcl:263 msgid "Input device 3:" msgstr "" #: ../src/dialog_audio.tcl:209 ../src/dialog_midi.tcl:139 #: ../src/dialog_midi.tcl:275 msgid "Input device 4:" msgstr "" #: ../src/dialog_audio.tcl:223 ../src/dialog_midi.tcl:150 #: ../src/dialog_midi.tcl:286 msgid "Output device 1:" msgstr "" #: ../src/dialog_audio.tcl:226 msgid "(same as input device) .............. " msgstr "" #: ../src/dialog_audio.tcl:246 ../src/dialog_midi.tcl:160 #: ../src/dialog_midi.tcl:296 msgid "Output device 2:" msgstr "" #: ../src/dialog_audio.tcl:261 ../src/dialog_midi.tcl:171 #: ../src/dialog_midi.tcl:307 msgid "Output device 3:" msgstr "" #: ../src/dialog_audio.tcl:276 ../src/dialog_midi.tcl:182 #: ../src/dialog_midi.tcl:318 msgid "Output device 4:" msgstr "" #: ../src/dialog_audio.tcl:291 ../src/dialog_midi.tcl:195 msgid "Use multiple devices" msgstr "" #: ../src/dialog_canvas.tcl:142 msgid "Canvas Properties" msgstr "" #: ../src/dialog_canvas.tcl:146 #, fuzzy msgid "Scale" msgstr "Qeyd Et" #: ../src/dialog_canvas.tcl:150 msgid "X units per pixel:" msgstr "" #: ../src/dialog_canvas.tcl:155 msgid "Y units per pixel:" msgstr "" #: ../src/dialog_canvas.tcl:159 msgid "Appearance on parent patch" msgstr "" #: ../src/dialog_canvas.tcl:161 msgid "Graph-On-Parent" msgstr "" #: ../src/dialog_canvas.tcl:165 msgid "Hide object name and arguments" msgstr "" #: ../src/dialog_canvas.tcl:170 msgid "Range and size" msgstr "" #: ../src/dialog_canvas.tcl:174 msgid "X range, from" msgstr "" #: ../src/dialog_canvas.tcl:176 ../src/dialog_canvas.tcl:191 msgid "to" msgstr "" #: ../src/dialog_canvas.tcl:180 ../src/dialog_canvas.tcl:195 #, fuzzy msgid "Margin:" msgstr "Ön işarə:" #: ../src/dialog_canvas.tcl:189 msgid "Y range, from" msgstr "" #: ../src/dialog_find.tcl:63 ../src/dialog_find.tcl:66 #: ../src/dialog_find.tcl:79 ../src/dialog_find.tcl:80 #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:85 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:101 #: ../src/dialog_find.tcl:105 ../src/dialog_find.tcl:107 #: ../src/pd_menus.tcl:45 msgid "Find" msgstr "Axtar" #: ../src/dialog_find.tcl:70 ../src/dialog_find.tcl:73 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:91 #: ../src/dialog_find.tcl:93 #, fuzzy msgid "Search in" msgstr "Mətni Axtar..." #: ../src/dialog_find.tcl:72 ../src/dialog_find.tcl:75 #: ../src/dialog_find.tcl:89 ../src/dialog_find.tcl:93 #: ../src/dialog_find.tcl:95 #, fuzzy msgid "for:" msgstr "Qapı:" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:90 #: ../src/dialog_find.tcl:104 ../src/dialog_find.tcl:108 #: ../src/dialog_find.tcl:110 ../src/pd_menus.tcl:86 ../src/pd_menus.tcl:87 #: ../src/pd_menus.tcl:132 ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:259 #: ../src/pd_menus.tcl:272 ../src/pd_menus.tcl:295 ../src/pd_menus.tcl:308 #: ../src/pd_menus.tcl:332 ../src/pd_menus.tcl:345 ../src/pd_menus.tcl:354 #: ../src/pd_menus.tcl:381 ../src/pd_menus.tcl:392 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:431 ../src/pd_menus.tcl:458 msgid "Close" msgstr "Bağla" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:97 #: ../src/dialog_find.tcl:101 ../src/dialog_find.tcl:103 msgid "Match whole word only" msgstr "" #: ../src/dialog_find.tcl:92 ../src/dialog_font.tcl:49 #: ../src/dialog_font.tcl:50 ../src/pd-gui.tcl:280 ../src/pd-gui.tcl:283 #: ../src/pd-gui.tcl:286 ../src/pd-gui.tcl:288 ../src/pd-gui.tcl:291 #: ../src/pd_menus.tcl:212 ../src/pd_menus.tcl:258 ../src/pd_menus.tcl:285 #: ../src/pdwindow.tcl:33 #, fuzzy msgid "Pd window" msgstr "Fayl Yolla" #: ../src/dialog_font.tcl:45 msgid "Font Properties" msgstr "" #: ../src/dialog_font.tcl:46 ../src/dialog_font.tcl:54 #: ../src/dialog_font.tcl:55 #, fuzzy, tcl-format msgid "%s Font" msgstr "Yazı növü:" #: ../src/dialog_font.tcl:61 ../src/dialog_font.tcl:96 #: ../src/dialog_font.tcl:104 ../src/dialog_font.tcl:105 #, fuzzy msgid "Font Size" msgstr "Böyüklük" #: ../src/dialog_font.tcl:89 ../src/dialog_font.tcl:108 #: ../src/dialog_font.tcl:116 ../src/dialog_font.tcl:117 #, fuzzy msgid "Stretch" msgstr "Başlanğıc Vaxtı" #: ../src/dialog_font.tcl:96 ../src/dialog_font.tcl:115 #: ../src/dialog_font.tcl:123 ../src/dialog_font.tcl:124 msgid "X and Y" msgstr "" #: ../src/dialog_font.tcl:98 ../src/dialog_font.tcl:117 #: ../src/dialog_font.tcl:125 ../src/dialog_font.tcl:126 msgid "X only" msgstr "" #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:119 #: ../src/dialog_font.tcl:127 ../src/dialog_font.tcl:128 msgid "Y only" msgstr "" #: ../src/dialog_gatom.tcl:93 msgid "Atom Box Properties" msgstr "" #: ../src/dialog_gatom.tcl:99 msgid "Width:" msgstr "" #: ../src/dialog_gatom.tcl:103 #, fuzzy msgid "Limits" msgstr "Siyahılar" #: ../src/dialog_gatom.tcl:107 msgid "Lower:" msgstr "" #: ../src/dialog_gatom.tcl:112 ../src/dialog_gatom.tcl:113 #, fuzzy msgid "Upper:" msgstr "İstifadəçi" #: ../src/dialog_gatom.tcl:116 ../src/dialog_gatom.tcl:121 #: ../src/dialog_iemgui.tcl:600 ../src/dialog_iemgui.tcl:652 #: ../src/dialog_iemgui.tcl:657 msgid "Label" msgstr "" #: ../src/dialog_gatom.tcl:124 ../src/dialog_gatom.tcl:129 #, fuzzy msgid "Left " msgstr "Solda" #: ../src/dialog_gatom.tcl:126 ../src/dialog_gatom.tcl:131 msgid "Right" msgstr "Sağda" #: ../src/dialog_gatom.tcl:128 ../src/dialog_gatom.tcl:133 msgid "Top" msgstr "Üstdə" #: ../src/dialog_gatom.tcl:130 ../src/dialog_gatom.tcl:135 msgid "Bottom" msgstr "Altda" #: ../src/dialog_gatom.tcl:137 ../src/dialog_gatom.tcl:145 #: ../src/dialog_iemgui.tcl:574 #, fuzzy msgid "Messages" msgstr "İsmarış" #: ../src/dialog_gatom.tcl:141 ../src/dialog_gatom.tcl:149 #: ../src/dialog_iemgui.tcl:578 msgid "Send symbol:" msgstr "" #: ../src/dialog_gatom.tcl:147 ../src/dialog_gatom.tcl:155 #: ../src/dialog_iemgui.tcl:585 #, fuzzy msgid "Receive symbol:" msgstr "Alıcı" #: ../src/dialog_iemgui.tcl:197 #, fuzzy msgid "Background color" msgstr "Arxa plan:" #: ../src/dialog_iemgui.tcl:204 #, fuzzy msgid "Foreground color" msgstr "Ön plan:" #: ../src/dialog_iemgui.tcl:211 #, fuzzy msgid "Label color" msgstr "Rəng seç" #: ../src/dialog_iemgui.tcl:272 #, fuzzy msgid "Init" msgstr "Dəvət Et" #: ../src/dialog_iemgui.tcl:275 ../src/dialog_iemgui.tcl:546 msgid "No init" msgstr "" #: ../src/dialog_iemgui.tcl:287 ../src/dialog_iemgui.tcl:558 msgid "Jump on click" msgstr "" #: ../src/dialog_iemgui.tcl:290 ../src/dialog_iemgui.tcl:561 msgid "Steady on click" msgstr "" #: ../src/dialog_iemgui.tcl:498 #, tcl-format msgid "%s Properties" msgstr "" #: ../src/dialog_iemgui.tcl:550 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:84 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:130 ../src/pd_menus.tcl:260 #: ../src/pd_menus.tcl:273 ../src/pd_menus.tcl:288 ../src/pd_menus.tcl:301 #: ../src/pd_menus.tcl:325 ../src/pd_menus.tcl:338 ../src/pd_menus.tcl:355 #: ../src/pd_menus.tcl:382 ../src/pd_menus.tcl:383 ../src/pd_menus.tcl:410 #: ../src/pd_menus.tcl:422 ../src/pd_menus.tcl:449 msgid "Save" msgstr "Qeyd Et" #: ../src/dialog_iemgui.tcl:608 msgid "X offset" msgstr "" #: ../src/dialog_iemgui.tcl:611 ../src/dialog_iemgui.tcl:612 msgid "Y offset" msgstr "" #: ../src/dialog_iemgui.tcl:642 ../src/dialog_iemgui.tcl:645 msgid "Colors" msgstr "Rənglər" #: ../src/dialog_iemgui.tcl:648 ../src/dialog_iemgui.tcl:651 #, fuzzy msgid "Background" msgstr "Arxa plan:" #: ../src/dialog_iemgui.tcl:650 ../src/dialog_iemgui.tcl:654 #, fuzzy msgid "Front" msgstr "Yazı növü:" #: ../src/dialog_iemgui.tcl:662 ../src/dialog_iemgui.tcl:668 msgid "Compose color" msgstr "" #: ../src/dialog_iemgui.tcl:682 ../src/dialog_iemgui.tcl:688 #, fuzzy msgid "Test label" msgstr "Hamısı Sına" #: ../src/dialog_midi.tcl:85 msgid "MIDI Settings" msgstr "" #: ../src/dialog_midi.tcl:220 msgid "ALSA MIDI Settings" msgstr "" #: ../src/dialog_midi.tcl:331 msgid "Use multiple ALSA devices" msgstr "" #: ../src/dialog_midi.tcl:337 msgid "In Ports:" msgstr "" #: ../src/dialog_midi.tcl:340 msgid "Out Ports:" msgstr "" #: ../src/g_editor.c:1663 msgid "Discard changes to this window??" msgstr "" #: ../src/g_editor.c:1668 msgid "really quit?" msgstr "" #: ../src/g_editor.c:1699 #, fuzzy msgid "Close this window??" msgstr "Bu səkmə/pəncərəni bağla" #: ../src/pd-gui.tcl:185 ../src/pd-gui.tcl:195 ../src/pd-gui.tcl:203 #: ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:215 ../src/pd-gui.tcl:226 msgid "Associated Files" msgstr "" #: ../src/pd-gui.tcl:186 ../src/pd-gui.tcl:196 ../src/pd-gui.tcl:204 #: ../src/pd-gui.tcl:207 ../src/pd-gui.tcl:216 ../src/pd-gui.tcl:227 #, fuzzy msgid "Pd Files" msgstr "Fayl" #: ../src/pd-gui.tcl:187 ../src/pd-gui.tcl:205 ../src/pd-gui.tcl:208 #: ../src/pd-gui.tcl:228 msgid "Max Patch Files" msgstr "" #: ../src/pd-gui.tcl:188 ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:209 #: ../src/pd-gui.tcl:229 msgid "Max Text Files" msgstr "" #: ../src/pd-gui.tcl:197 ../src/pd-gui.tcl:217 msgid "Max Patch Files (.pat)" msgstr "" #: ../src/pd-gui.tcl:198 ../src/pd-gui.tcl:218 msgid "Max Text Files (.mxt)" msgstr "" #: ../src/pd-gui.tcl:270 ../src/pd-gui.tcl:290 #, tcl-format msgid "WARNING: Font family '%s' not found, using default (%s)" msgstr "" #: ../src/pd-gui.tcl:278 ../src/pd-gui.tcl:298 #, tcl-format msgid "WARNING: Font weight '%s' not found, using default (%s)" msgstr "" #: ../src/pd-gui.tcl:303 ../src/pd-gui.tcl:323 #, tcl-format msgid "ERROR: %s failed to find font size (%s) that fits into %sx%s!" msgstr "" #: ../src/pd-gui.tcl:478 ../src/pd-gui.tcl:483 ../src/pd-gui.tcl:501 msgid "ERROR: 'pd' never showed up, 'pd-gui' quitting!" msgstr "" #: ../src/pd_menucommands.tcl:19 msgid "Untitled" msgstr "" #: ../src/pd_menucommands.tcl:78 ../src/pd_menucommands.tcl:79 #: ../src/pd_menucommands.tcl:90 #, fuzzy msgid "Send Message..." msgstr "İsmarış" #: ../src/pd_menucommands.tcl:82 ../src/pd_menucommands.tcl:83 #: ../src/pd_menucommands.tcl:94 ../src/pd_menus.tcl:87 ../src/pd_menus.tcl:88 #: ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:134 ../src/pd_menus.tcl:147 #: ../src/pd_menus.tcl:192 ../src/pd_menus.tcl:193 ../src/pd_menus.tcl:265 #: ../src/pd_menus.tcl:278 ../src/pd_menus.tcl:292 ../src/pd_menus.tcl:305 #: ../src/pd_menus.tcl:329 ../src/pd_menus.tcl:342 ../src/pd_menus.tcl:360 #: ../src/pd_menus.tcl:387 ../src/pd_menus.tcl:414 ../src/pd_menus.tcl:426 #: ../src/pd_menus.tcl:453 ../startup/object_db.tcl:123 msgid "Message" msgstr "İsmarış" #: ../src/pd_menucommands.tcl:108 ../src/pd_menucommands.tcl:111 #: ../src/pd_menus.tcl:112 ../src/pd_menus.tcl:113 ../src/pd_menus.tcl:117 #: ../src/pd_menus.tcl:118 ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:159 #: ../src/pd_menus.tcl:163 ../src/pd_menus.tcl:164 #, fuzzy msgid "Font" msgstr "Yazı növü:" #: ../src/pd_menucommands.tcl:123 ../src/pd_menucommands.tcl:126 #: ../src/pd_menus.tcl:138 ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:184 #, fuzzy msgid "Preferences" msgstr "Seçimlər..." #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Edit" msgstr "_Yüklə..." #: ../src/pd_menus.tcl:45 msgid "File" msgstr "Fayl" #: ../src/pd_menus.tcl:45 ../src/pdtk_canvas.tcl:48 ../src/pdtk_canvas.tcl:110 #: ../src/pdtk_canvas.tcl:113 msgid "Help" msgstr "Yardım" #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Media" msgstr "Makedoniya" #: ../src/pd_menus.tcl:45 msgid "Put" msgstr "" #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Window" msgstr "_Pəncərə" #: ../src/pd_menus.tcl:81 ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:127 #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:255 ../src/pd_menus.tcl:267 #: ../src/pd_menus.tcl:285 ../src/pd_menus.tcl:298 ../src/pd_menus.tcl:322 #: ../src/pd_menus.tcl:335 ../src/pd_menus.tcl:349 ../src/pd_menus.tcl:376 #: ../src/pd_menus.tcl:380 ../src/pd_menus.tcl:407 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:446 msgid "New" msgstr "Yeni" #: ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:128 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:268 #: ../src/pd_menus.tcl:286 ../src/pd_menus.tcl:299 ../src/pd_menus.tcl:323 #: ../src/pd_menus.tcl:336 ../src/pd_menus.tcl:350 ../src/pd_menus.tcl:377 #: ../src/pd_menus.tcl:381 ../src/pd_menus.tcl:408 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:447 ../src/pdtk_canvas.tcl:46 #: ../src/pdtk_canvas.tcl:108 ../src/pdtk_canvas.tcl:111 #: ../src/pdtk_canvas.tcl:128 ../src/pdtk_canvas.tcl:130 #: ../src/pdtk_canvas.tcl:131 ../src/pdtk_canvas.tcl:133 msgid "Open" msgstr "Aç" #: ../src/pd_menus.tcl:84 ../src/pd_menus.tcl:85 ../src/pd_menus.tcl:130 #: ../src/pd_menus.tcl:131 ../src/pd_menus.tcl:261 ../src/pd_menus.tcl:274 #: ../src/pd_menus.tcl:289 ../src/pd_menus.tcl:302 ../src/pd_menus.tcl:326 #: ../src/pd_menus.tcl:339 ../src/pd_menus.tcl:356 ../src/pd_menus.tcl:383 #: ../src/pd_menus.tcl:384 ../src/pd_menus.tcl:411 ../src/pd_menus.tcl:423 #: ../src/pd_menus.tcl:450 #, fuzzy msgid "Save As..." msgstr "Fərqli Qeyd Et" #: ../src/pd_menus.tcl:88 ../src/pd_menus.tcl:89 ../src/pd_menus.tcl:134 #: ../src/pd_menus.tcl:135 ../src/pd_menus.tcl:267 ../src/pd_menus.tcl:280 #: ../src/pd_menus.tcl:293 ../src/pd_menus.tcl:306 ../src/pd_menus.tcl:330 #: ../src/pd_menus.tcl:343 ../src/pd_menus.tcl:362 ../src/pd_menus.tcl:388 #: ../src/pd_menus.tcl:389 ../src/pd_menus.tcl:415 ../src/pd_menus.tcl:427 #: ../src/pd_menus.tcl:454 #, fuzzy msgid "Print..." msgstr "_Yüklə..." #: ../src/pd_menus.tcl:93 ../src/pd_menus.tcl:94 ../src/pd_menus.tcl:139 #: ../src/pd_menus.tcl:140 #, fuzzy msgid "Undo" msgstr "Uqanda" #: ../src/pd_menus.tcl:95 ../src/pd_menus.tcl:96 ../src/pd_menus.tcl:141 #: ../src/pd_menus.tcl:142 #, fuzzy msgid "Redo" msgstr "Səbəb" #: ../src/pd_menus.tcl:98 ../src/pd_menus.tcl:99 ../src/pd_menus.tcl:144 #: ../src/pd_menus.tcl:145 msgid "Cut" msgstr "" #: ../src/pd_menus.tcl:104 ../src/pd_menus.tcl:105 ../src/pd_menus.tcl:150 #: ../src/pd_menus.tcl:151 #, fuzzy msgid "Duplicate" msgstr "Tarix" #: ../src/pd_menus.tcl:106 ../src/pd_menus.tcl:107 ../src/pd_menus.tcl:152 #: ../src/pd_menus.tcl:153 #, fuzzy msgid "Select All" msgstr "Hamısı Sil" #: ../src/pd_menus.tcl:110 ../src/pd_menus.tcl:111 ../src/pd_menus.tcl:115 #: ../src/pd_menus.tcl:116 ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:157 #: ../src/pd_menus.tcl:161 ../src/pd_menus.tcl:162 #, fuzzy msgid "Text Editor" msgstr "Rənglər" #: ../src/pd_menus.tcl:120 ../src/pd_menus.tcl:121 ../src/pd_menus.tcl:166 #: ../src/pd_menus.tcl:167 msgid "Tidy Up" msgstr "" #: ../src/pd_menus.tcl:122 ../src/pd_menus.tcl:123 ../src/pd_menus.tcl:168 #: ../src/pd_menus.tcl:169 msgid "Toggle Console" msgstr "" #: ../src/pd_menus.tcl:124 ../src/pd_menus.tcl:125 ../src/pd_menus.tcl:170 #: ../src/pd_menus.tcl:171 #, fuzzy msgid "Clear Console" msgstr "Siyahını təmizlə" #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:174 #: ../src/pd_menus.tcl:175 #, fuzzy msgid "Edit Mode" msgstr "Təfərruatlar" #: ../src/pd_menus.tcl:145 ../src/pd_menus.tcl:190 ../src/pd_menus.tcl:191 msgid "Object" msgstr "" #: ../src/pd_menus.tcl:149 ../src/pd_menus.tcl:194 ../src/pd_menus.tcl:195 #, fuzzy msgid "Number" msgstr "$ Nömrəsi" #: ../src/pd_menus.tcl:151 ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:197 msgid "Symbol" msgstr "" #: ../src/pd_menus.tcl:153 ../src/pd_menus.tcl:198 ../src/pd_menus.tcl:199 #, fuzzy msgid "Comment" msgstr "Əmr" #: ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:201 ../src/pd_menus.tcl:202 #, fuzzy msgid "Bang" msgstr "Ban-la" #: ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:203 ../src/pd_menus.tcl:204 #, fuzzy msgid "Toggle" msgstr "Toqo" #: ../src/pd_menus.tcl:160 ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:206 #, fuzzy msgid "Number2" msgstr "$ Nömrəsi" #: ../src/pd_menus.tcl:162 ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:208 msgid "Vslider" msgstr "" #: ../src/pd_menus.tcl:164 ../src/pd_menus.tcl:209 ../src/pd_menus.tcl:210 #, fuzzy msgid "Hslider" msgstr "Göstərmə" #: ../src/pd_menus.tcl:166 ../src/pd_menus.tcl:211 ../src/pd_menus.tcl:212 #, fuzzy msgid "Vradio" msgstr "Buraxılış" #: ../src/pd_menus.tcl:168 ../src/pd_menus.tcl:213 ../src/pd_menus.tcl:214 msgid "Hradio" msgstr "" #: ../src/pd_menus.tcl:170 ../src/pd_menus.tcl:215 ../src/pd_menus.tcl:216 msgid "VU Meter" msgstr "" #: ../src/pd_menus.tcl:172 ../src/pd_menus.tcl:217 ../src/pd_menus.tcl:218 #, fuzzy msgid "Canvas" msgstr "Kanada" #: ../src/pd_menus.tcl:175 ../src/pd_menus.tcl:220 ../src/pd_menus.tcl:221 msgid "Graph" msgstr "Qrafika" #: ../src/pd_menus.tcl:176 ../src/pd_menus.tcl:221 ../src/pd_menus.tcl:222 #, fuzzy msgid "Array" msgstr "Andorra" #: ../src/pd_menus.tcl:181 ../src/pd_menus.tcl:226 ../src/pd_menus.tcl:227 #, fuzzy msgid "Find..." msgstr "Fayl Göndərilməsi..." #: ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:228 ../src/pd_menus.tcl:229 msgid "Find Again" msgstr "" #: ../src/pd_menus.tcl:185 ../src/pd_menus.tcl:230 ../src/pd_menus.tcl:231 msgid "Find Last Error" msgstr "" #: ../src/pd_menus.tcl:191 ../src/pd_menus.tcl:236 ../src/pd_menus.tcl:237 msgid "DSP On" msgstr "" #: ../src/pd_menus.tcl:193 ../src/pd_menus.tcl:238 ../src/pd_menus.tcl:239 #, fuzzy msgid "DSP Off" msgstr "Bağlı" #: ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:242 ../src/pd_menus.tcl:269 msgid "Test Audio and MIDI..." msgstr "" #: ../src/pd_menus.tcl:198 ../src/pd_menus.tcl:244 ../src/pd_menus.tcl:271 #, fuzzy msgid "Load Meter" msgstr "Lag ölçəni:" #: ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:251 ../src/pd_menus.tcl:278 msgid "Minimize" msgstr "" #: ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:253 ../src/pd_menus.tcl:280 #, fuzzy msgid "Zoom" msgstr "Altda" #: ../src/pd_menus.tcl:210 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:283 #, fuzzy msgid "Parent Window" msgstr "Fayl Yolla" #: ../src/pd_menus.tcl:216 ../src/pd_menus.tcl:262 ../src/pd_menus.tcl:289 msgid "Bring All to Front" msgstr "" #: ../src/pd_menus.tcl:224 ../src/pd_menus.tcl:241 ../src/pd_menus.tcl:253 #: ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:297 ../src/pd_menus.tcl:335 #: ../src/pd_menus.tcl:362 #, fuzzy msgid "About Pd" msgstr "_Haqqında" #: ../src/pd_menus.tcl:227 ../src/pd_menus.tcl:273 ../src/pd_menus.tcl:300 msgid "HTML Manual..." msgstr "" #: ../src/pd_menus.tcl:229 ../src/pd_menus.tcl:275 ../src/pd_menus.tcl:302 #, fuzzy msgid "Browser..." msgstr "Gəz..." #: ../src/pd_menus.tcl:248 ../src/pd_menus.tcl:260 ../src/pd_menus.tcl:342 #: ../src/pd_menus.tcl:369 msgid "Preferences..." msgstr "Seçimlər..." #: ../src/pd_menus.tcl:257 ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:352 #: ../src/pd_menus.tcl:379 msgid "Open Recent" msgstr "" #: ../src/pd_menus.tcl:263 msgid "Audio Settings..." msgstr "" #: ../src/pd_menus.tcl:265 msgid "MIDI Settings..." msgstr "" #: ../src/pd_menus.tcl:296 ../src/pd_menus.tcl:309 ../src/pd_menus.tcl:333 #: ../src/pd_menus.tcl:346 ../src/pd_menus.tcl:393 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:432 ../src/pd_menus.tcl:459 msgid "Quit" msgstr "Çıx" #: ../src/pd_menus.tcl:304 ../src/pd_menus.tcl:331 #, fuzzy msgid "Clear Menu" msgstr "Siyahını təmizlə" #: ../src/pdtk_canvas.tcl:44 ../src/pdtk_canvas.tcl:106 #: ../src/pdtk_canvas.tcl:109 ../src/pdtk_canvas.tcl:123 #: ../src/pdtk_canvas.tcl:125 ../src/pdtk_canvas.tcl:126 #: ../src/pdtk_canvas.tcl:128 msgid "Properties" msgstr "" #: ../src/pdwindow.tcl:43 #, fuzzy msgid "DSP" msgstr "Bağlı" #: ../startup/object_db.tcl:113 msgid "Signal" msgstr "" #: ../startup/object_db.tcl:114 msgid "Generators" msgstr "" #: ../startup/object_db.tcl:115 #, fuzzy msgid "Filters" msgstr "Fayl" #: ../startup/object_db.tcl:116 ../startup/object_db.tcl:124 msgid "Math" msgstr "" #: ../startup/object_db.tcl:117 ../startup/object_db.tcl:125 msgid "I/O" msgstr "" #: ../startup/object_db.tcl:118 ../startup/object_db.tcl:126 msgid "Sampling" msgstr "" #: ../startup/object_db.tcl:119 ../startup/object_db.tcl:128 msgid "Routing" msgstr "" #: ../startup/object_db.tcl:120 ../startup/object_db.tcl:129 msgid "Others" msgstr "" #: ../startup/object_db.tcl:127 msgid "GUI" msgstr "" pd-0.46-7/po/eu.po0000664000175000017500000006021112160204055011756 0ustar mspmsp# Basque translation of Pure Data. # This file is put in the public domain. # Mikel Olasagasti , 2004, 2005. # msgid "" msgstr "" "Project-Id-Version: Pure Data 0.43\n" "Report-Msgid-Bugs-To: pd-dev@iem.at\n" "POT-Creation-Date: 2009-08-27 10:01-0400\n" "PO-Revision-Date: 2005-08-21 21:10+0200\n" "Last-Translator: Mikel Olasagasti \n" "Language-Team: Basque \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #, fuzzy msgid "Undo duplicate" msgstr "Data" msgid "Undo paste" msgstr "" msgid "Undo motion" msgstr "" #, fuzzy msgid "Undo cut" msgstr "Uganda" msgid "Undo disconnect" msgstr "" msgid "Undo connect" msgstr "" msgid "Undo clear" msgstr "" msgid "Undo typing" msgstr "" msgid "Discard changes to '%s'?" msgstr "" msgid "Do you want to save the changes you made in '%s'?" msgstr "" #: ../src/dialog_array.tcl:115 ../src/dialog_array.tcl:117 #: ../src/pd_menus.tcl:100 ../src/pd_menus.tcl:101 ../src/pd_menus.tcl:146 #: ../src/pd_menus.tcl:147 msgid "Copy" msgstr "Kopiatu" #: ../src/dialog_array.tcl:118 ../src/dialog_array.tcl:120 #: ../src/pd_menus.tcl:102 ../src/pd_menus.tcl:103 ../src/pd_menus.tcl:148 #: ../src/pd_menus.tcl:149 #, fuzzy msgid "Paste" msgstr "Data" #: ../src/dialog_array.tcl:264 ../src/dialog_array.tcl:266 msgid "Array Properties" msgstr "" #: ../src/dialog_array.tcl:270 ../src/dialog_array.tcl:272 #, fuzzy msgid "Name:" msgstr "Izena" #: ../src/dialog_array.tcl:276 ../src/dialog_array.tcl:278 #: ../src/dialog_canvas.tcl:178 ../src/dialog_canvas.tcl:193 #: ../src/dialog_iemgui.tcl:619 ../src/dialog_iemgui.tcl:621 msgid "Size:" msgstr "Tamainua:" #: ../src/dialog_array.tcl:280 ../src/dialog_array.tcl:282 #, fuzzy msgid "Save contents" msgstr "_Edukia" #: ../src/dialog_array.tcl:284 ../src/dialog_array.tcl:286 msgid "Draw as:" msgstr "" #: ../src/dialog_array.tcl:287 ../src/dialog_array.tcl:289 #, fuzzy msgid "Points" msgstr "Ataka" #: ../src/dialog_array.tcl:289 ../src/dialog_array.tcl:291 #, fuzzy msgid "Polygon" msgstr "Polonia" #: ../src/dialog_array.tcl:291 ../src/dialog_array.tcl:293 msgid "Bezier curve" msgstr "" #: ../src/dialog_array.tcl:297 ../src/dialog_array.tcl:299 msgid "Put array into:" msgstr "" #: ../src/dialog_array.tcl:300 ../src/dialog_array.tcl:302 msgid "New graph" msgstr "" #: ../src/dialog_array.tcl:302 ../src/dialog_array.tcl:304 #, fuzzy msgid "Last graph" msgstr "Azken mezua:" #: ../src/dialog_array.tcl:306 ../src/dialog_array.tcl:308 #, fuzzy msgid "Delete array" msgstr "Ezabatu" #: ../src/dialog_array.tcl:312 ../src/dialog_array.tcl:314 #, fuzzy msgid "Open List View..." msgstr "Debekatuen zerrenda..." #: ../src/dialog_array.tcl:319 ../src/dialog_array.tcl:321 #: ../src/dialog_audio.tcl:136 ../src/dialog_canvas.tcl:205 #: ../src/dialog_font.tcl:51 ../src/dialog_gatom.tcl:153 #: ../src/dialog_gatom.tcl:161 ../src/dialog_iemgui.tcl:742 #: ../src/dialog_iemgui.tcl:748 ../src/dialog_midi.tcl:91 #: ../src/dialog_midi.tcl:226 msgid "Cancel" msgstr "Utzi" #: ../src/dialog_array.tcl:321 ../src/dialog_array.tcl:323 #: ../src/dialog_audio.tcl:138 ../src/dialog_canvas.tcl:207 #: ../src/dialog_gatom.tcl:156 ../src/dialog_gatom.tcl:164 #: ../src/dialog_iemgui.tcl:745 ../src/dialog_iemgui.tcl:751 #: ../src/dialog_midi.tcl:93 ../src/dialog_midi.tcl:228 msgid "Apply" msgstr "Aplikatu" #: ../src/dialog_array.tcl:323 ../src/dialog_array.tcl:325 #: ../src/dialog_audio.tcl:140 ../src/dialog_canvas.tcl:209 #: ../src/dialog_font.tcl:53 ../src/dialog_font.tcl:92 #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:101 #: ../src/dialog_gatom.tcl:159 ../src/dialog_gatom.tcl:167 #: ../src/dialog_iemgui.tcl:748 ../src/dialog_iemgui.tcl:754 #: ../src/dialog_midi.tcl:95 ../src/dialog_midi.tcl:230 msgid "OK" msgstr "" #: ../src/dialog_audio.tcl:130 msgid "Audio Settings" msgstr "" #: ../src/dialog_audio.tcl:142 msgid "Save All Settings" msgstr "" #: ../src/dialog_audio.tcl:151 msgid "Sample rate:" msgstr "" #: ../src/dialog_audio.tcl:153 msgid "Delay (msec):" msgstr "" #: ../src/dialog_audio.tcl:158 msgid "Use callbacks" msgstr "" #: ../src/dialog_audio.tcl:166 ../src/dialog_midi.tcl:105 #: ../src/dialog_midi.tcl:241 msgid "Input device 1:" msgstr "" #: ../src/dialog_audio.tcl:169 ../src/dialog_audio.tcl:183 #: ../src/dialog_audio.tcl:198 ../src/dialog_audio.tcl:213 #: ../src/dialog_audio.tcl:232 ../src/dialog_audio.tcl:250 #: ../src/dialog_audio.tcl:265 ../src/dialog_audio.tcl:280 #, fuzzy msgid "Channels:" msgstr "Utzi" #: ../src/dialog_audio.tcl:179 ../src/dialog_midi.tcl:115 #: ../src/dialog_midi.tcl:251 msgid "Input device 2:" msgstr "" #: ../src/dialog_audio.tcl:194 ../src/dialog_midi.tcl:127 #: ../src/dialog_midi.tcl:263 msgid "Input device 3:" msgstr "" #: ../src/dialog_audio.tcl:209 ../src/dialog_midi.tcl:139 #: ../src/dialog_midi.tcl:275 msgid "Input device 4:" msgstr "" #: ../src/dialog_audio.tcl:223 ../src/dialog_midi.tcl:150 #: ../src/dialog_midi.tcl:286 msgid "Output device 1:" msgstr "" #: ../src/dialog_audio.tcl:226 msgid "(same as input device) .............. " msgstr "" #: ../src/dialog_audio.tcl:246 ../src/dialog_midi.tcl:160 #: ../src/dialog_midi.tcl:296 msgid "Output device 2:" msgstr "" #: ../src/dialog_audio.tcl:261 ../src/dialog_midi.tcl:171 #: ../src/dialog_midi.tcl:307 msgid "Output device 3:" msgstr "" #: ../src/dialog_audio.tcl:276 ../src/dialog_midi.tcl:182 #: ../src/dialog_midi.tcl:318 msgid "Output device 4:" msgstr "" #: ../src/dialog_audio.tcl:291 ../src/dialog_midi.tcl:195 msgid "Use multiple devices" msgstr "" #: ../src/dialog_canvas.tcl:142 msgid "Canvas Properties" msgstr "" #: ../src/dialog_canvas.tcl:146 #, fuzzy msgid "Scale" msgstr "Gorde" #: ../src/dialog_canvas.tcl:150 msgid "X units per pixel:" msgstr "" #: ../src/dialog_canvas.tcl:155 msgid "Y units per pixel:" msgstr "" #: ../src/dialog_canvas.tcl:159 msgid "Appearance on parent patch" msgstr "" #: ../src/dialog_canvas.tcl:161 msgid "Graph-On-Parent" msgstr "" #: ../src/dialog_canvas.tcl:165 msgid "Hide object name and arguments" msgstr "" #: ../src/dialog_canvas.tcl:170 msgid "Range and size" msgstr "" #: ../src/dialog_canvas.tcl:174 msgid "X range, from" msgstr "" #: ../src/dialog_canvas.tcl:176 ../src/dialog_canvas.tcl:191 msgid "to" msgstr "" #: ../src/dialog_canvas.tcl:180 ../src/dialog_canvas.tcl:195 #, fuzzy msgid "Margin:" msgstr "Marka lerroa:" #: ../src/dialog_canvas.tcl:189 msgid "Y range, from" msgstr "" #: ../src/dialog_find.tcl:63 ../src/dialog_find.tcl:66 #: ../src/dialog_find.tcl:79 ../src/dialog_find.tcl:80 #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:85 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:101 #: ../src/dialog_find.tcl:105 ../src/dialog_find.tcl:107 #: ../src/pd_menus.tcl:45 msgid "Find" msgstr "Bilatu" #: ../src/dialog_find.tcl:70 ../src/dialog_find.tcl:73 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:91 #: ../src/dialog_find.tcl:93 #, fuzzy msgid "Search in" msgstr "Bilatu testua..." #: ../src/dialog_find.tcl:72 ../src/dialog_find.tcl:75 #: ../src/dialog_find.tcl:89 ../src/dialog_find.tcl:93 #: ../src/dialog_find.tcl:95 #, fuzzy msgid "for:" msgstr "Ataka:" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:90 #: ../src/dialog_find.tcl:104 ../src/dialog_find.tcl:108 #: ../src/dialog_find.tcl:110 ../src/pd_menus.tcl:86 ../src/pd_menus.tcl:87 #: ../src/pd_menus.tcl:132 ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:259 #: ../src/pd_menus.tcl:272 ../src/pd_menus.tcl:295 ../src/pd_menus.tcl:308 #: ../src/pd_menus.tcl:332 ../src/pd_menus.tcl:345 ../src/pd_menus.tcl:354 #: ../src/pd_menus.tcl:381 ../src/pd_menus.tcl:392 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:431 ../src/pd_menus.tcl:458 msgid "Close" msgstr "Itxi" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:97 #: ../src/dialog_find.tcl:101 ../src/dialog_find.tcl:103 msgid "Match whole word only" msgstr "" #: ../src/dialog_find.tcl:92 ../src/dialog_font.tcl:49 #: ../src/dialog_font.tcl:50 ../src/pd-gui.tcl:280 ../src/pd-gui.tcl:283 #: ../src/pd-gui.tcl:286 ../src/pd-gui.tcl:288 ../src/pd-gui.tcl:291 #: ../src/pd_menus.tcl:212 ../src/pd_menus.tcl:258 ../src/pd_menus.tcl:285 #: ../src/pdwindow.tcl:33 #, fuzzy msgid "Pd window" msgstr "Bidalketa leihoa" #: ../src/dialog_font.tcl:45 msgid "Font Properties" msgstr "" #: ../src/dialog_font.tcl:46 ../src/dialog_font.tcl:54 #: ../src/dialog_font.tcl:55 #, fuzzy, tcl-format msgid "%s Font" msgstr "Letra-tipoa" #: ../src/dialog_font.tcl:61 ../src/dialog_font.tcl:96 #: ../src/dialog_font.tcl:104 ../src/dialog_font.tcl:105 #, fuzzy msgid "Font Size" msgstr "Tamainua:" #: ../src/dialog_font.tcl:89 ../src/dialog_font.tcl:108 #: ../src/dialog_font.tcl:116 ../src/dialog_font.tcl:117 #, fuzzy msgid "Stretch" msgstr "Hasiera:" #: ../src/dialog_font.tcl:96 ../src/dialog_font.tcl:115 #: ../src/dialog_font.tcl:123 ../src/dialog_font.tcl:124 msgid "X and Y" msgstr "" #: ../src/dialog_font.tcl:98 ../src/dialog_font.tcl:117 #: ../src/dialog_font.tcl:125 ../src/dialog_font.tcl:126 msgid "X only" msgstr "" #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:119 #: ../src/dialog_font.tcl:127 ../src/dialog_font.tcl:128 msgid "Y only" msgstr "" #: ../src/dialog_gatom.tcl:93 msgid "Atom Box Properties" msgstr "" #: ../src/dialog_gatom.tcl:99 msgid "Width:" msgstr "" #: ../src/dialog_gatom.tcl:103 #, fuzzy msgid "Limits" msgstr "Zerrendak" #: ../src/dialog_gatom.tcl:107 msgid "Lower:" msgstr "" #: ../src/dialog_gatom.tcl:112 ../src/dialog_gatom.tcl:113 #, fuzzy msgid "Upper:" msgstr "Erabiltzailea:" #: ../src/dialog_gatom.tcl:116 ../src/dialog_gatom.tcl:121 #: ../src/dialog_iemgui.tcl:600 ../src/dialog_iemgui.tcl:652 #: ../src/dialog_iemgui.tcl:657 msgid "Label" msgstr "" #: ../src/dialog_gatom.tcl:124 ../src/dialog_gatom.tcl:129 #, fuzzy msgid "Left " msgstr "Ezkerrean" #: ../src/dialog_gatom.tcl:126 ../src/dialog_gatom.tcl:131 msgid "Right" msgstr "Eskuinean" #: ../src/dialog_gatom.tcl:128 ../src/dialog_gatom.tcl:133 msgid "Top" msgstr "Goian" #: ../src/dialog_gatom.tcl:130 ../src/dialog_gatom.tcl:135 msgid "Bottom" msgstr "Behean" #: ../src/dialog_gatom.tcl:137 ../src/dialog_gatom.tcl:145 #: ../src/dialog_iemgui.tcl:574 #, fuzzy msgid "Messages" msgstr "Mezua" #: ../src/dialog_gatom.tcl:141 ../src/dialog_gatom.tcl:149 #: ../src/dialog_iemgui.tcl:578 msgid "Send symbol:" msgstr "" #: ../src/dialog_gatom.tcl:147 ../src/dialog_gatom.tcl:155 #: ../src/dialog_iemgui.tcl:585 #, fuzzy msgid "Receive symbol:" msgstr "Jaso leihoa" #: ../src/dialog_iemgui.tcl:197 #, fuzzy msgid "Background color" msgstr "Atzeko planoa:" #: ../src/dialog_iemgui.tcl:204 #, fuzzy msgid "Foreground color" msgstr "Aurreko planoa:" #: ../src/dialog_iemgui.tcl:211 #, fuzzy msgid "Label color" msgstr "Aukeratu kolorea" #: ../src/dialog_iemgui.tcl:272 #, fuzzy msgid "Init" msgstr "Gonbidatu" #: ../src/dialog_iemgui.tcl:275 ../src/dialog_iemgui.tcl:546 msgid "No init" msgstr "" #: ../src/dialog_iemgui.tcl:287 ../src/dialog_iemgui.tcl:558 msgid "Jump on click" msgstr "" #: ../src/dialog_iemgui.tcl:290 ../src/dialog_iemgui.tcl:561 msgid "Steady on click" msgstr "" #: ../src/dialog_iemgui.tcl:498 #, tcl-format msgid "%s Properties" msgstr "" #: ../src/dialog_iemgui.tcl:550 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:84 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:130 ../src/pd_menus.tcl:260 #: ../src/pd_menus.tcl:273 ../src/pd_menus.tcl:288 ../src/pd_menus.tcl:301 #: ../src/pd_menus.tcl:325 ../src/pd_menus.tcl:338 ../src/pd_menus.tcl:355 #: ../src/pd_menus.tcl:382 ../src/pd_menus.tcl:383 ../src/pd_menus.tcl:410 #: ../src/pd_menus.tcl:422 ../src/pd_menus.tcl:449 msgid "Save" msgstr "Gorde" #: ../src/dialog_iemgui.tcl:608 msgid "X offset" msgstr "" #: ../src/dialog_iemgui.tcl:611 ../src/dialog_iemgui.tcl:612 msgid "Y offset" msgstr "" #: ../src/dialog_iemgui.tcl:642 ../src/dialog_iemgui.tcl:645 msgid "Colors" msgstr "Koloreak" #: ../src/dialog_iemgui.tcl:648 ../src/dialog_iemgui.tcl:651 #, fuzzy msgid "Background" msgstr "Atzeko planoa:" #: ../src/dialog_iemgui.tcl:650 ../src/dialog_iemgui.tcl:654 #, fuzzy msgid "Front" msgstr "Letra-tipoa" #: ../src/dialog_iemgui.tcl:662 ../src/dialog_iemgui.tcl:668 msgid "Compose color" msgstr "" #: ../src/dialog_iemgui.tcl:682 ../src/dialog_iemgui.tcl:688 #, fuzzy msgid "Test label" msgstr "Egiaztatu denak" #: ../src/dialog_midi.tcl:85 msgid "MIDI Settings" msgstr "" #: ../src/dialog_midi.tcl:220 msgid "ALSA MIDI Settings" msgstr "" #: ../src/dialog_midi.tcl:331 msgid "Use multiple ALSA devices" msgstr "" #: ../src/dialog_midi.tcl:337 msgid "In Ports:" msgstr "" #: ../src/dialog_midi.tcl:340 msgid "Out Ports:" msgstr "" #: ../src/g_editor.c:1663 msgid "Discard changes to this window??" msgstr "" #: ../src/g_editor.c:1668 msgid "really quit?" msgstr "" #: ../src/g_editor.c:1699 #, fuzzy msgid "Close this window??" msgstr "Fitxa/leiho hau itxitzen du" #: ../src/pd-gui.tcl:185 ../src/pd-gui.tcl:195 ../src/pd-gui.tcl:203 #: ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:215 ../src/pd-gui.tcl:226 msgid "Associated Files" msgstr "" #: ../src/pd-gui.tcl:186 ../src/pd-gui.tcl:196 ../src/pd-gui.tcl:204 #: ../src/pd-gui.tcl:207 ../src/pd-gui.tcl:216 ../src/pd-gui.tcl:227 #, fuzzy msgid "Pd Files" msgstr "Fitxategia" #: ../src/pd-gui.tcl:187 ../src/pd-gui.tcl:205 ../src/pd-gui.tcl:208 #: ../src/pd-gui.tcl:228 msgid "Max Patch Files" msgstr "" #: ../src/pd-gui.tcl:188 ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:209 #: ../src/pd-gui.tcl:229 msgid "Max Text Files" msgstr "" #: ../src/pd-gui.tcl:197 ../src/pd-gui.tcl:217 msgid "Max Patch Files (.pat)" msgstr "" #: ../src/pd-gui.tcl:198 ../src/pd-gui.tcl:218 msgid "Max Text Files (.mxt)" msgstr "" #: ../src/pd-gui.tcl:270 ../src/pd-gui.tcl:290 #, tcl-format msgid "WARNING: Font family '%s' not found, using default (%s)" msgstr "" #: ../src/pd-gui.tcl:278 ../src/pd-gui.tcl:298 #, tcl-format msgid "WARNING: Font weight '%s' not found, using default (%s)" msgstr "" #: ../src/pd-gui.tcl:303 ../src/pd-gui.tcl:323 #, tcl-format msgid "ERROR: %s failed to find font size (%s) that fits into %sx%s!" msgstr "" #: ../src/pd-gui.tcl:478 ../src/pd-gui.tcl:483 ../src/pd-gui.tcl:501 msgid "ERROR: 'pd' never showed up, 'pd-gui' quitting!" msgstr "" #: ../src/pd_menucommands.tcl:19 msgid "Untitled" msgstr "" #: ../src/pd_menucommands.tcl:78 ../src/pd_menucommands.tcl:79 #: ../src/pd_menucommands.tcl:90 #, fuzzy msgid "Send Message..." msgstr "Mezua" #: ../src/pd_menucommands.tcl:82 ../src/pd_menucommands.tcl:83 #: ../src/pd_menucommands.tcl:94 ../src/pd_menus.tcl:87 ../src/pd_menus.tcl:88 #: ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:134 ../src/pd_menus.tcl:147 #: ../src/pd_menus.tcl:192 ../src/pd_menus.tcl:193 ../src/pd_menus.tcl:265 #: ../src/pd_menus.tcl:278 ../src/pd_menus.tcl:292 ../src/pd_menus.tcl:305 #: ../src/pd_menus.tcl:329 ../src/pd_menus.tcl:342 ../src/pd_menus.tcl:360 #: ../src/pd_menus.tcl:387 ../src/pd_menus.tcl:414 ../src/pd_menus.tcl:426 #: ../src/pd_menus.tcl:453 ../startup/object_db.tcl:123 msgid "Message" msgstr "Mezua" #: ../src/pd_menucommands.tcl:108 ../src/pd_menucommands.tcl:111 #: ../src/pd_menus.tcl:112 ../src/pd_menus.tcl:113 ../src/pd_menus.tcl:117 #: ../src/pd_menus.tcl:118 ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:159 #: ../src/pd_menus.tcl:163 ../src/pd_menus.tcl:164 #, fuzzy msgid "Font" msgstr "Letra-tipoa" #: ../src/pd_menucommands.tcl:123 ../src/pd_menucommands.tcl:126 #: ../src/pd_menus.tcl:138 ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:184 #, fuzzy msgid "Preferences" msgstr "Hobespenak..." #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Edit" msgstr "_Editatu" #: ../src/pd_menus.tcl:45 msgid "File" msgstr "Fitxategia" #: ../src/pd_menus.tcl:45 ../src/pdtk_canvas.tcl:48 ../src/pdtk_canvas.tcl:110 #: ../src/pdtk_canvas.tcl:113 msgid "Help" msgstr "Laguntza" #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Media" msgstr "Macedonia" #: ../src/pd_menus.tcl:45 msgid "Put" msgstr "" #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Window" msgstr "_Leihoa" #: ../src/pd_menus.tcl:81 ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:127 #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:255 ../src/pd_menus.tcl:267 #: ../src/pd_menus.tcl:285 ../src/pd_menus.tcl:298 ../src/pd_menus.tcl:322 #: ../src/pd_menus.tcl:335 ../src/pd_menus.tcl:349 ../src/pd_menus.tcl:376 #: ../src/pd_menus.tcl:380 ../src/pd_menus.tcl:407 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:446 msgid "New" msgstr "Berria" #: ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:128 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:268 #: ../src/pd_menus.tcl:286 ../src/pd_menus.tcl:299 ../src/pd_menus.tcl:323 #: ../src/pd_menus.tcl:336 ../src/pd_menus.tcl:350 ../src/pd_menus.tcl:377 #: ../src/pd_menus.tcl:381 ../src/pd_menus.tcl:408 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:447 ../src/pdtk_canvas.tcl:46 #: ../src/pdtk_canvas.tcl:108 ../src/pdtk_canvas.tcl:111 #: ../src/pdtk_canvas.tcl:128 ../src/pdtk_canvas.tcl:130 #: ../src/pdtk_canvas.tcl:131 ../src/pdtk_canvas.tcl:133 msgid "Open" msgstr "Ireki" #: ../src/pd_menus.tcl:84 ../src/pd_menus.tcl:85 ../src/pd_menus.tcl:130 #: ../src/pd_menus.tcl:131 ../src/pd_menus.tcl:261 ../src/pd_menus.tcl:274 #: ../src/pd_menus.tcl:289 ../src/pd_menus.tcl:302 ../src/pd_menus.tcl:326 #: ../src/pd_menus.tcl:339 ../src/pd_menus.tcl:356 ../src/pd_menus.tcl:383 #: ../src/pd_menus.tcl:384 ../src/pd_menus.tcl:411 ../src/pd_menus.tcl:423 #: ../src/pd_menus.tcl:450 #, fuzzy msgid "Save As..." msgstr "Gorde honela" #: ../src/pd_menus.tcl:88 ../src/pd_menus.tcl:89 ../src/pd_menus.tcl:134 #: ../src/pd_menus.tcl:135 ../src/pd_menus.tcl:267 ../src/pd_menus.tcl:280 #: ../src/pd_menus.tcl:293 ../src/pd_menus.tcl:306 ../src/pd_menus.tcl:330 #: ../src/pd_menus.tcl:343 ../src/pd_menus.tcl:362 ../src/pd_menus.tcl:388 #: ../src/pd_menus.tcl:389 ../src/pd_menus.tcl:415 ../src/pd_menus.tcl:427 #: ../src/pd_menus.tcl:454 #, fuzzy msgid "Print..." msgstr "_Editatu..." #: ../src/pd_menus.tcl:93 ../src/pd_menus.tcl:94 ../src/pd_menus.tcl:139 #: ../src/pd_menus.tcl:140 #, fuzzy msgid "Undo" msgstr "Uganda" #: ../src/pd_menus.tcl:95 ../src/pd_menus.tcl:96 ../src/pd_menus.tcl:141 #: ../src/pd_menus.tcl:142 #, fuzzy msgid "Redo" msgstr "Gorria:" #: ../src/pd_menus.tcl:98 ../src/pd_menus.tcl:99 ../src/pd_menus.tcl:144 #: ../src/pd_menus.tcl:145 msgid "Cut" msgstr "" #: ../src/pd_menus.tcl:104 ../src/pd_menus.tcl:105 ../src/pd_menus.tcl:150 #: ../src/pd_menus.tcl:151 #, fuzzy msgid "Duplicate" msgstr "Data" #: ../src/pd_menus.tcl:106 ../src/pd_menus.tcl:107 ../src/pd_menus.tcl:152 #: ../src/pd_menus.tcl:153 #, fuzzy msgid "Select All" msgstr "Ezabatu guztiak" #: ../src/pd_menus.tcl:110 ../src/pd_menus.tcl:111 ../src/pd_menus.tcl:115 #: ../src/pd_menus.tcl:116 ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:157 #: ../src/pd_menus.tcl:161 ../src/pd_menus.tcl:162 #, fuzzy msgid "Text Editor" msgstr "Testu koloreak" #: ../src/pd_menus.tcl:120 ../src/pd_menus.tcl:121 ../src/pd_menus.tcl:166 #: ../src/pd_menus.tcl:167 msgid "Tidy Up" msgstr "" #: ../src/pd_menus.tcl:122 ../src/pd_menus.tcl:123 ../src/pd_menus.tcl:168 #: ../src/pd_menus.tcl:169 msgid "Toggle Console" msgstr "" #: ../src/pd_menus.tcl:124 ../src/pd_menus.tcl:125 ../src/pd_menus.tcl:170 #: ../src/pd_menus.tcl:171 #, fuzzy msgid "Clear Console" msgstr "Garbitu zerrenda" #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:174 #: ../src/pd_menus.tcl:175 #, fuzzy msgid "Edit Mode" msgstr "Edizio modua" #: ../src/pd_menus.tcl:145 ../src/pd_menus.tcl:190 ../src/pd_menus.tcl:191 msgid "Object" msgstr "" #: ../src/pd_menus.tcl:149 ../src/pd_menus.tcl:194 ../src/pd_menus.tcl:195 #, fuzzy msgid "Number" msgstr "$ Zenbakia" #: ../src/pd_menus.tcl:151 ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:197 msgid "Symbol" msgstr "" #: ../src/pd_menus.tcl:153 ../src/pd_menus.tcl:198 ../src/pd_menus.tcl:199 #, fuzzy msgid "Comment" msgstr "Komandoa" #: ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:201 ../src/pd_menus.tcl:202 #, fuzzy msgid "Bang" msgstr "Debekatu" #: ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:203 ../src/pd_menus.tcl:204 #, fuzzy msgid "Toggle" msgstr "Togo" #: ../src/pd_menus.tcl:160 ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:206 #, fuzzy msgid "Number2" msgstr "$ Zenbakia" #: ../src/pd_menus.tcl:162 ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:208 msgid "Vslider" msgstr "" #: ../src/pd_menus.tcl:164 ../src/pd_menus.tcl:209 ../src/pd_menus.tcl:210 #, fuzzy msgid "Hslider" msgstr "Ezkutatu" #: ../src/pd_menus.tcl:166 ../src/pd_menus.tcl:211 ../src/pd_menus.tcl:212 #, fuzzy msgid "Vradio" msgstr "Bertsioa" #: ../src/pd_menus.tcl:168 ../src/pd_menus.tcl:213 ../src/pd_menus.tcl:214 msgid "Hradio" msgstr "" #: ../src/pd_menus.tcl:170 ../src/pd_menus.tcl:215 ../src/pd_menus.tcl:216 msgid "VU Meter" msgstr "" #: ../src/pd_menus.tcl:172 ../src/pd_menus.tcl:217 ../src/pd_menus.tcl:218 #, fuzzy msgid "Canvas" msgstr "Kanada" #: ../src/pd_menus.tcl:175 ../src/pd_menus.tcl:220 ../src/pd_menus.tcl:221 msgid "Graph" msgstr "Grafikoa" #: ../src/pd_menus.tcl:176 ../src/pd_menus.tcl:221 ../src/pd_menus.tcl:222 #, fuzzy msgid "Array" msgstr "Andorra" #: ../src/pd_menus.tcl:181 ../src/pd_menus.tcl:226 ../src/pd_menus.tcl:227 #, fuzzy msgid "Find..." msgstr "Bidali fitxategiak..." #: ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:228 ../src/pd_menus.tcl:229 msgid "Find Again" msgstr "" #: ../src/pd_menus.tcl:185 ../src/pd_menus.tcl:230 ../src/pd_menus.tcl:231 msgid "Find Last Error" msgstr "" #: ../src/pd_menus.tcl:191 ../src/pd_menus.tcl:236 ../src/pd_menus.tcl:237 msgid "DSP On" msgstr "" #: ../src/pd_menus.tcl:193 ../src/pd_menus.tcl:238 ../src/pd_menus.tcl:239 #, fuzzy msgid "DSP Off" msgstr "Off" #: ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:242 ../src/pd_menus.tcl:269 msgid "Test Audio and MIDI..." msgstr "" #: ../src/pd_menus.tcl:198 ../src/pd_menus.tcl:244 ../src/pd_menus.tcl:271 #, fuzzy msgid "Load Meter" msgstr "Atzerapen neurtzailea:" #: ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:251 ../src/pd_menus.tcl:278 msgid "Minimize" msgstr "" #: ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:253 ../src/pd_menus.tcl:280 #, fuzzy msgid "Zoom" msgstr "Behean" #: ../src/pd_menus.tcl:210 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:283 #, fuzzy msgid "Parent Window" msgstr "Bidalketa leihoa" #: ../src/pd_menus.tcl:216 ../src/pd_menus.tcl:262 ../src/pd_menus.tcl:289 msgid "Bring All to Front" msgstr "" #: ../src/pd_menus.tcl:224 ../src/pd_menus.tcl:241 ../src/pd_menus.tcl:253 #: ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:297 ../src/pd_menus.tcl:335 #: ../src/pd_menus.tcl:362 #, fuzzy msgid "About Pd" msgstr "_Honi buruz" #: ../src/pd_menus.tcl:227 ../src/pd_menus.tcl:273 ../src/pd_menus.tcl:300 msgid "HTML Manual..." msgstr "" #: ../src/pd_menus.tcl:229 ../src/pd_menus.tcl:275 ../src/pd_menus.tcl:302 #, fuzzy msgid "Browser..." msgstr "Arakatu..." #: ../src/pd_menus.tcl:248 ../src/pd_menus.tcl:260 ../src/pd_menus.tcl:342 #: ../src/pd_menus.tcl:369 msgid "Preferences..." msgstr "Hobespenak..." #: ../src/pd_menus.tcl:257 ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:352 #: ../src/pd_menus.tcl:379 msgid "Open Recent" msgstr "" #: ../src/pd_menus.tcl:263 msgid "Audio Settings..." msgstr "" #: ../src/pd_menus.tcl:265 msgid "MIDI Settings..." msgstr "" #: ../src/pd_menus.tcl:296 ../src/pd_menus.tcl:309 ../src/pd_menus.tcl:333 #: ../src/pd_menus.tcl:346 ../src/pd_menus.tcl:393 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:432 ../src/pd_menus.tcl:459 msgid "Quit" msgstr "Irten" #: ../src/pd_menus.tcl:304 ../src/pd_menus.tcl:331 #, fuzzy msgid "Clear Menu" msgstr "Garbitu zerrenda" #: ../src/pdtk_canvas.tcl:44 ../src/pdtk_canvas.tcl:106 #: ../src/pdtk_canvas.tcl:109 ../src/pdtk_canvas.tcl:123 #: ../src/pdtk_canvas.tcl:125 ../src/pdtk_canvas.tcl:126 #: ../src/pdtk_canvas.tcl:128 msgid "Properties" msgstr "" #: ../src/pdwindow.tcl:43 #, fuzzy msgid "DSP" msgstr "Off" #: ../startup/object_db.tcl:113 msgid "Signal" msgstr "" #: ../startup/object_db.tcl:114 msgid "Generators" msgstr "" #: ../startup/object_db.tcl:115 #, fuzzy msgid "Filters" msgstr "Fitxategia" #: ../startup/object_db.tcl:116 ../startup/object_db.tcl:124 msgid "Math" msgstr "" #: ../startup/object_db.tcl:117 ../startup/object_db.tcl:125 msgid "I/O" msgstr "" #: ../startup/object_db.tcl:118 ../startup/object_db.tcl:126 msgid "Sampling" msgstr "" #: ../startup/object_db.tcl:119 ../startup/object_db.tcl:128 msgid "Routing" msgstr "" #: ../startup/object_db.tcl:120 ../startup/object_db.tcl:129 msgid "Others" msgstr "" #: ../startup/object_db.tcl:127 msgid "GUI" msgstr "" pd-0.46-7/po/hi.po0000664000175000017500000006212212160204055011750 0ustar mspmsp# Translation of Pure Data 0.43.po to Hindi. # This file is put in the public domain. # Rajesh Ranjan , 2005. # msgid "" msgstr "" "Project-Id-Version: Pure Data 0.43\n" "Report-Msgid-Bugs-To: pd-dev@iem.at\n" "POT-Creation-Date: 2009-08-27 10:01-0400\n" "PO-Revision-Date: 2005-05-04 12:50+0530\n" "Last-Translator: Rajesh Ranjan \n" "Language-Team: Hindi \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: KBabel 1.9.1\n" #, fuzzy msgid "Undo duplicate" msgstr "तारीख़" msgid "Undo paste" msgstr "" msgid "Undo motion" msgstr "" #, fuzzy msgid "Undo cut" msgstr "यूगांडा" msgid "Undo disconnect" msgstr "" msgid "Undo connect" msgstr "" msgid "Undo clear" msgstr "" msgid "Undo typing" msgstr "" msgid "Discard changes to '%s'?" msgstr "" msgid "Do you want to save the changes you made in '%s'?" msgstr "" #: ../src/dialog_array.tcl:115 ../src/dialog_array.tcl:117 #: ../src/pd_menus.tcl:100 ../src/pd_menus.tcl:101 ../src/pd_menus.tcl:146 #: ../src/pd_menus.tcl:147 msgid "Copy" msgstr "कॉपी" #: ../src/dialog_array.tcl:118 ../src/dialog_array.tcl:120 #: ../src/pd_menus.tcl:102 ../src/pd_menus.tcl:103 ../src/pd_menus.tcl:148 #: ../src/pd_menus.tcl:149 #, fuzzy msgid "Paste" msgstr "तारीख़" #: ../src/dialog_array.tcl:264 ../src/dialog_array.tcl:266 msgid "Array Properties" msgstr "" #: ../src/dialog_array.tcl:270 ../src/dialog_array.tcl:272 #, fuzzy msgid "Name:" msgstr "नाम" #: ../src/dialog_array.tcl:276 ../src/dialog_array.tcl:278 #: ../src/dialog_canvas.tcl:178 ../src/dialog_canvas.tcl:193 #: ../src/dialog_iemgui.tcl:619 ../src/dialog_iemgui.tcl:621 #, fuzzy msgid "Size:" msgstr "आकार" #: ../src/dialog_array.tcl:280 ../src/dialog_array.tcl:282 #, fuzzy msgid "Save contents" msgstr "विषय सूची (_C)" #: ../src/dialog_array.tcl:284 ../src/dialog_array.tcl:286 msgid "Draw as:" msgstr "" #: ../src/dialog_array.tcl:287 ../src/dialog_array.tcl:289 #, fuzzy msgid "Points" msgstr "पोर्ट" #: ../src/dialog_array.tcl:289 ../src/dialog_array.tcl:291 #, fuzzy msgid "Polygon" msgstr "पोलेंड" #: ../src/dialog_array.tcl:291 ../src/dialog_array.tcl:293 msgid "Bezier curve" msgstr "" #: ../src/dialog_array.tcl:297 ../src/dialog_array.tcl:299 msgid "Put array into:" msgstr "" #: ../src/dialog_array.tcl:300 ../src/dialog_array.tcl:302 msgid "New graph" msgstr "" #: ../src/dialog_array.tcl:302 ../src/dialog_array.tcl:304 msgid "Last graph" msgstr "" #: ../src/dialog_array.tcl:306 ../src/dialog_array.tcl:308 #, fuzzy msgid "Delete array" msgstr "मिटाओ" #: ../src/dialog_array.tcl:312 ../src/dialog_array.tcl:314 #, fuzzy msgid "Open List View..." msgstr "प्रतिबंध सूची..." #: ../src/dialog_array.tcl:319 ../src/dialog_array.tcl:321 #: ../src/dialog_audio.tcl:136 ../src/dialog_canvas.tcl:205 #: ../src/dialog_font.tcl:51 ../src/dialog_gatom.tcl:153 #: ../src/dialog_gatom.tcl:161 ../src/dialog_iemgui.tcl:742 #: ../src/dialog_iemgui.tcl:748 ../src/dialog_midi.tcl:91 #: ../src/dialog_midi.tcl:226 msgid "Cancel" msgstr "रद्द" #: ../src/dialog_array.tcl:321 ../src/dialog_array.tcl:323 #: ../src/dialog_audio.tcl:138 ../src/dialog_canvas.tcl:207 #: ../src/dialog_gatom.tcl:156 ../src/dialog_gatom.tcl:164 #: ../src/dialog_iemgui.tcl:745 ../src/dialog_iemgui.tcl:751 #: ../src/dialog_midi.tcl:93 ../src/dialog_midi.tcl:228 msgid "Apply" msgstr "लागू करो" #: ../src/dialog_array.tcl:323 ../src/dialog_array.tcl:325 #: ../src/dialog_audio.tcl:140 ../src/dialog_canvas.tcl:209 #: ../src/dialog_font.tcl:53 ../src/dialog_font.tcl:92 #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:101 #: ../src/dialog_gatom.tcl:159 ../src/dialog_gatom.tcl:167 #: ../src/dialog_iemgui.tcl:748 ../src/dialog_iemgui.tcl:754 #: ../src/dialog_midi.tcl:95 ../src/dialog_midi.tcl:230 msgid "OK" msgstr "" #: ../src/dialog_audio.tcl:130 msgid "Audio Settings" msgstr "" #: ../src/dialog_audio.tcl:142 msgid "Save All Settings" msgstr "" #: ../src/dialog_audio.tcl:151 msgid "Sample rate:" msgstr "" #: ../src/dialog_audio.tcl:153 msgid "Delay (msec):" msgstr "" #: ../src/dialog_audio.tcl:158 msgid "Use callbacks" msgstr "" #: ../src/dialog_audio.tcl:166 ../src/dialog_midi.tcl:105 #: ../src/dialog_midi.tcl:241 msgid "Input device 1:" msgstr "" #: ../src/dialog_audio.tcl:169 ../src/dialog_audio.tcl:183 #: ../src/dialog_audio.tcl:198 ../src/dialog_audio.tcl:213 #: ../src/dialog_audio.tcl:232 ../src/dialog_audio.tcl:250 #: ../src/dialog_audio.tcl:265 ../src/dialog_audio.tcl:280 #, fuzzy msgid "Channels:" msgstr "रद्द" #: ../src/dialog_audio.tcl:179 ../src/dialog_midi.tcl:115 #: ../src/dialog_midi.tcl:251 msgid "Input device 2:" msgstr "" #: ../src/dialog_audio.tcl:194 ../src/dialog_midi.tcl:127 #: ../src/dialog_midi.tcl:263 msgid "Input device 3:" msgstr "" #: ../src/dialog_audio.tcl:209 ../src/dialog_midi.tcl:139 #: ../src/dialog_midi.tcl:275 msgid "Input device 4:" msgstr "" #: ../src/dialog_audio.tcl:223 ../src/dialog_midi.tcl:150 #: ../src/dialog_midi.tcl:286 msgid "Output device 1:" msgstr "" #: ../src/dialog_audio.tcl:226 msgid "(same as input device) .............. " msgstr "" #: ../src/dialog_audio.tcl:246 ../src/dialog_midi.tcl:160 #: ../src/dialog_midi.tcl:296 msgid "Output device 2:" msgstr "" #: ../src/dialog_audio.tcl:261 ../src/dialog_midi.tcl:171 #: ../src/dialog_midi.tcl:307 msgid "Output device 3:" msgstr "" #: ../src/dialog_audio.tcl:276 ../src/dialog_midi.tcl:182 #: ../src/dialog_midi.tcl:318 msgid "Output device 4:" msgstr "" #: ../src/dialog_audio.tcl:291 ../src/dialog_midi.tcl:195 msgid "Use multiple devices" msgstr "" #: ../src/dialog_canvas.tcl:142 msgid "Canvas Properties" msgstr "" #: ../src/dialog_canvas.tcl:146 #, fuzzy msgid "Scale" msgstr "सहेजें" #: ../src/dialog_canvas.tcl:150 msgid "X units per pixel:" msgstr "" #: ../src/dialog_canvas.tcl:155 msgid "Y units per pixel:" msgstr "" #: ../src/dialog_canvas.tcl:159 msgid "Appearance on parent patch" msgstr "" #: ../src/dialog_canvas.tcl:161 msgid "Graph-On-Parent" msgstr "" #: ../src/dialog_canvas.tcl:165 msgid "Hide object name and arguments" msgstr "" #: ../src/dialog_canvas.tcl:170 msgid "Range and size" msgstr "" #: ../src/dialog_canvas.tcl:174 msgid "X range, from" msgstr "" #: ../src/dialog_canvas.tcl:176 ../src/dialog_canvas.tcl:191 msgid "to" msgstr "" #: ../src/dialog_canvas.tcl:180 ../src/dialog_canvas.tcl:195 #, fuzzy msgid "Margin:" msgstr "मार्कर पंक्ति:" #: ../src/dialog_canvas.tcl:189 msgid "Y range, from" msgstr "" #: ../src/dialog_find.tcl:63 ../src/dialog_find.tcl:66 #: ../src/dialog_find.tcl:79 ../src/dialog_find.tcl:80 #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:85 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:101 #: ../src/dialog_find.tcl:105 ../src/dialog_find.tcl:107 #: ../src/pd_menus.tcl:45 msgid "Find" msgstr "ढूंढें" #: ../src/dialog_find.tcl:70 ../src/dialog_find.tcl:73 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:91 #: ../src/dialog_find.tcl:93 #, fuzzy msgid "Search in" msgstr "पाठ खोजें..." #: ../src/dialog_find.tcl:72 ../src/dialog_find.tcl:75 #: ../src/dialog_find.tcl:89 ../src/dialog_find.tcl:93 #: ../src/dialog_find.tcl:95 #, fuzzy msgid "for:" msgstr "पोर्टः" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:90 #: ../src/dialog_find.tcl:104 ../src/dialog_find.tcl:108 #: ../src/dialog_find.tcl:110 ../src/pd_menus.tcl:86 ../src/pd_menus.tcl:87 #: ../src/pd_menus.tcl:132 ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:259 #: ../src/pd_menus.tcl:272 ../src/pd_menus.tcl:295 ../src/pd_menus.tcl:308 #: ../src/pd_menus.tcl:332 ../src/pd_menus.tcl:345 ../src/pd_menus.tcl:354 #: ../src/pd_menus.tcl:381 ../src/pd_menus.tcl:392 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:431 ../src/pd_menus.tcl:458 msgid "Close" msgstr "बन्द करो" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:97 #: ../src/dialog_find.tcl:101 ../src/dialog_find.tcl:103 msgid "Match whole word only" msgstr "" #: ../src/dialog_find.tcl:92 ../src/dialog_font.tcl:49 #: ../src/dialog_font.tcl:50 ../src/pd-gui.tcl:280 ../src/pd-gui.tcl:283 #: ../src/pd-gui.tcl:286 ../src/pd-gui.tcl:288 ../src/pd-gui.tcl:291 #: ../src/pd_menus.tcl:212 ../src/pd_menus.tcl:258 ../src/pd_menus.tcl:285 #: ../src/pdwindow.tcl:33 #, fuzzy msgid "Pd window" msgstr "भेजें विंडो" #: ../src/dialog_font.tcl:45 msgid "Font Properties" msgstr "" #: ../src/dialog_font.tcl:46 ../src/dialog_font.tcl:54 #: ../src/dialog_font.tcl:55 #, fuzzy, tcl-format msgid "%s Font" msgstr "फ़ॉन्टः" #: ../src/dialog_font.tcl:61 ../src/dialog_font.tcl:96 #: ../src/dialog_font.tcl:104 ../src/dialog_font.tcl:105 #, fuzzy msgid "Font Size" msgstr "फ़ॉन्टः" #: ../src/dialog_font.tcl:89 ../src/dialog_font.tcl:108 #: ../src/dialog_font.tcl:116 ../src/dialog_font.tcl:117 msgid "Stretch" msgstr "" #: ../src/dialog_font.tcl:96 ../src/dialog_font.tcl:115 #: ../src/dialog_font.tcl:123 ../src/dialog_font.tcl:124 msgid "X and Y" msgstr "" #: ../src/dialog_font.tcl:98 ../src/dialog_font.tcl:117 #: ../src/dialog_font.tcl:125 ../src/dialog_font.tcl:126 msgid "X only" msgstr "" #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:119 #: ../src/dialog_font.tcl:127 ../src/dialog_font.tcl:128 msgid "Y only" msgstr "" #: ../src/dialog_gatom.tcl:93 msgid "Atom Box Properties" msgstr "" #: ../src/dialog_gatom.tcl:99 msgid "Width:" msgstr "" #: ../src/dialog_gatom.tcl:103 #, fuzzy msgid "Limits" msgstr "उपयोक्ता सीमा" #: ../src/dialog_gatom.tcl:107 msgid "Lower:" msgstr "" #: ../src/dialog_gatom.tcl:112 ../src/dialog_gatom.tcl:113 #, fuzzy msgid "Upper:" msgstr "आपरेटर" #: ../src/dialog_gatom.tcl:116 ../src/dialog_gatom.tcl:121 #: ../src/dialog_iemgui.tcl:600 ../src/dialog_iemgui.tcl:652 #: ../src/dialog_iemgui.tcl:657 msgid "Label" msgstr "" #: ../src/dialog_gatom.tcl:124 ../src/dialog_gatom.tcl:129 #, fuzzy msgid "Left " msgstr "बायाँ" #: ../src/dialog_gatom.tcl:126 ../src/dialog_gatom.tcl:131 msgid "Right" msgstr "दाहिना" #: ../src/dialog_gatom.tcl:128 ../src/dialog_gatom.tcl:133 msgid "Top" msgstr "ऊपर" #: ../src/dialog_gatom.tcl:130 ../src/dialog_gatom.tcl:135 msgid "Bottom" msgstr "नीचे" #: ../src/dialog_gatom.tcl:137 ../src/dialog_gatom.tcl:145 #: ../src/dialog_iemgui.tcl:574 #, fuzzy msgid "Messages" msgstr "संदेश" #: ../src/dialog_gatom.tcl:141 ../src/dialog_gatom.tcl:149 #: ../src/dialog_iemgui.tcl:578 msgid "Send symbol:" msgstr "" #: ../src/dialog_gatom.tcl:147 ../src/dialog_gatom.tcl:155 #: ../src/dialog_iemgui.tcl:585 #, fuzzy msgid "Receive symbol:" msgstr "विंडो पायें" #: ../src/dialog_iemgui.tcl:197 #, fuzzy msgid "Background color" msgstr "पृष्ठभूमि:" #: ../src/dialog_iemgui.tcl:204 #, fuzzy msgid "Foreground color" msgstr "अग्रभूमि:" #: ../src/dialog_iemgui.tcl:211 #, fuzzy msgid "Label color" msgstr "रंग चुनें" #: ../src/dialog_iemgui.tcl:272 #, fuzzy msgid "Init" msgstr "निमंत्रित करें" #: ../src/dialog_iemgui.tcl:275 ../src/dialog_iemgui.tcl:546 msgid "No init" msgstr "" #: ../src/dialog_iemgui.tcl:287 ../src/dialog_iemgui.tcl:558 msgid "Jump on click" msgstr "" #: ../src/dialog_iemgui.tcl:290 ../src/dialog_iemgui.tcl:561 msgid "Steady on click" msgstr "" #: ../src/dialog_iemgui.tcl:498 #, tcl-format msgid "%s Properties" msgstr "" #: ../src/dialog_iemgui.tcl:550 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:84 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:130 ../src/pd_menus.tcl:260 #: ../src/pd_menus.tcl:273 ../src/pd_menus.tcl:288 ../src/pd_menus.tcl:301 #: ../src/pd_menus.tcl:325 ../src/pd_menus.tcl:338 ../src/pd_menus.tcl:355 #: ../src/pd_menus.tcl:382 ../src/pd_menus.tcl:383 ../src/pd_menus.tcl:410 #: ../src/pd_menus.tcl:422 ../src/pd_menus.tcl:449 msgid "Save" msgstr "सहेजें" #: ../src/dialog_iemgui.tcl:608 msgid "X offset" msgstr "" #: ../src/dialog_iemgui.tcl:611 ../src/dialog_iemgui.tcl:612 msgid "Y offset" msgstr "" #: ../src/dialog_iemgui.tcl:642 ../src/dialog_iemgui.tcl:645 msgid "Colors" msgstr "रंग" #: ../src/dialog_iemgui.tcl:648 ../src/dialog_iemgui.tcl:651 #, fuzzy msgid "Background" msgstr "पृष्ठभूमि:" #: ../src/dialog_iemgui.tcl:650 ../src/dialog_iemgui.tcl:654 #, fuzzy msgid "Front" msgstr "फ़ॉन्टः" #: ../src/dialog_iemgui.tcl:662 ../src/dialog_iemgui.tcl:668 msgid "Compose color" msgstr "" #: ../src/dialog_iemgui.tcl:682 ../src/dialog_iemgui.tcl:688 #, fuzzy msgid "Test label" msgstr "सबको जांचें" #: ../src/dialog_midi.tcl:85 msgid "MIDI Settings" msgstr "" #: ../src/dialog_midi.tcl:220 msgid "ALSA MIDI Settings" msgstr "" #: ../src/dialog_midi.tcl:331 msgid "Use multiple ALSA devices" msgstr "" #: ../src/dialog_midi.tcl:337 msgid "In Ports:" msgstr "" #: ../src/dialog_midi.tcl:340 msgid "Out Ports:" msgstr "" #: ../src/g_editor.c:1663 msgid "Discard changes to this window??" msgstr "" #: ../src/g_editor.c:1668 msgid "really quit?" msgstr "" #: ../src/g_editor.c:1699 #, fuzzy msgid "Close this window??" msgstr "इस tab/window बंद करें" #: ../src/pd-gui.tcl:185 ../src/pd-gui.tcl:195 ../src/pd-gui.tcl:203 #: ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:215 ../src/pd-gui.tcl:226 msgid "Associated Files" msgstr "" #: ../src/pd-gui.tcl:186 ../src/pd-gui.tcl:196 ../src/pd-gui.tcl:204 #: ../src/pd-gui.tcl:207 ../src/pd-gui.tcl:216 ../src/pd-gui.tcl:227 #, fuzzy msgid "Pd Files" msgstr "फाइल" #: ../src/pd-gui.tcl:187 ../src/pd-gui.tcl:205 ../src/pd-gui.tcl:208 #: ../src/pd-gui.tcl:228 msgid "Max Patch Files" msgstr "" #: ../src/pd-gui.tcl:188 ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:209 #: ../src/pd-gui.tcl:229 msgid "Max Text Files" msgstr "" #: ../src/pd-gui.tcl:197 ../src/pd-gui.tcl:217 msgid "Max Patch Files (.pat)" msgstr "" #: ../src/pd-gui.tcl:198 ../src/pd-gui.tcl:218 msgid "Max Text Files (.mxt)" msgstr "" #: ../src/pd-gui.tcl:270 ../src/pd-gui.tcl:290 #, tcl-format msgid "WARNING: Font family '%s' not found, using default (%s)" msgstr "" #: ../src/pd-gui.tcl:278 ../src/pd-gui.tcl:298 #, tcl-format msgid "WARNING: Font weight '%s' not found, using default (%s)" msgstr "" #: ../src/pd-gui.tcl:303 ../src/pd-gui.tcl:323 #, tcl-format msgid "ERROR: %s failed to find font size (%s) that fits into %sx%s!" msgstr "" #: ../src/pd-gui.tcl:478 ../src/pd-gui.tcl:483 ../src/pd-gui.tcl:501 msgid "ERROR: 'pd' never showed up, 'pd-gui' quitting!" msgstr "" #: ../src/pd_menucommands.tcl:19 msgid "Untitled" msgstr "" #: ../src/pd_menucommands.tcl:78 ../src/pd_menucommands.tcl:79 #: ../src/pd_menucommands.tcl:90 #, fuzzy msgid "Send Message..." msgstr "संदेश" #: ../src/pd_menucommands.tcl:82 ../src/pd_menucommands.tcl:83 #: ../src/pd_menucommands.tcl:94 ../src/pd_menus.tcl:87 ../src/pd_menus.tcl:88 #: ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:134 ../src/pd_menus.tcl:147 #: ../src/pd_menus.tcl:192 ../src/pd_menus.tcl:193 ../src/pd_menus.tcl:265 #: ../src/pd_menus.tcl:278 ../src/pd_menus.tcl:292 ../src/pd_menus.tcl:305 #: ../src/pd_menus.tcl:329 ../src/pd_menus.tcl:342 ../src/pd_menus.tcl:360 #: ../src/pd_menus.tcl:387 ../src/pd_menus.tcl:414 ../src/pd_menus.tcl:426 #: ../src/pd_menus.tcl:453 ../startup/object_db.tcl:123 msgid "Message" msgstr "संदेश" #: ../src/pd_menucommands.tcl:108 ../src/pd_menucommands.tcl:111 #: ../src/pd_menus.tcl:112 ../src/pd_menus.tcl:113 ../src/pd_menus.tcl:117 #: ../src/pd_menus.tcl:118 ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:159 #: ../src/pd_menus.tcl:163 ../src/pd_menus.tcl:164 #, fuzzy msgid "Font" msgstr "फ़ॉन्टः" #: ../src/pd_menucommands.tcl:123 ../src/pd_menucommands.tcl:126 #: ../src/pd_menus.tcl:138 ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:184 #, fuzzy msgid "Preferences" msgstr "प्राथमिकताएं..." #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Edit" msgstr "संपादन (_E)" #: ../src/pd_menus.tcl:45 msgid "File" msgstr "फाइल" #: ../src/pd_menus.tcl:45 ../src/pdtk_canvas.tcl:48 ../src/pdtk_canvas.tcl:110 #: ../src/pdtk_canvas.tcl:113 msgid "Help" msgstr "मदद" #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Media" msgstr "मेसीडोनिया" #: ../src/pd_menus.tcl:45 msgid "Put" msgstr "" #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Window" msgstr "विंडो (_W)" #: ../src/pd_menus.tcl:81 ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:127 #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:255 ../src/pd_menus.tcl:267 #: ../src/pd_menus.tcl:285 ../src/pd_menus.tcl:298 ../src/pd_menus.tcl:322 #: ../src/pd_menus.tcl:335 ../src/pd_menus.tcl:349 ../src/pd_menus.tcl:376 #: ../src/pd_menus.tcl:380 ../src/pd_menus.tcl:407 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:446 msgid "New" msgstr "नया" #: ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:128 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:268 #: ../src/pd_menus.tcl:286 ../src/pd_menus.tcl:299 ../src/pd_menus.tcl:323 #: ../src/pd_menus.tcl:336 ../src/pd_menus.tcl:350 ../src/pd_menus.tcl:377 #: ../src/pd_menus.tcl:381 ../src/pd_menus.tcl:408 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:447 ../src/pdtk_canvas.tcl:46 #: ../src/pdtk_canvas.tcl:108 ../src/pdtk_canvas.tcl:111 #: ../src/pdtk_canvas.tcl:128 ../src/pdtk_canvas.tcl:130 #: ../src/pdtk_canvas.tcl:131 ../src/pdtk_canvas.tcl:133 msgid "Open" msgstr "खोलें" #: ../src/pd_menus.tcl:84 ../src/pd_menus.tcl:85 ../src/pd_menus.tcl:130 #: ../src/pd_menus.tcl:131 ../src/pd_menus.tcl:261 ../src/pd_menus.tcl:274 #: ../src/pd_menus.tcl:289 ../src/pd_menus.tcl:302 ../src/pd_menus.tcl:326 #: ../src/pd_menus.tcl:339 ../src/pd_menus.tcl:356 ../src/pd_menus.tcl:383 #: ../src/pd_menus.tcl:384 ../src/pd_menus.tcl:411 ../src/pd_menus.tcl:423 #: ../src/pd_menus.tcl:450 #, fuzzy msgid "Save As..." msgstr "इस रूप में सहेजें" #: ../src/pd_menus.tcl:88 ../src/pd_menus.tcl:89 ../src/pd_menus.tcl:134 #: ../src/pd_menus.tcl:135 ../src/pd_menus.tcl:267 ../src/pd_menus.tcl:280 #: ../src/pd_menus.tcl:293 ../src/pd_menus.tcl:306 ../src/pd_menus.tcl:330 #: ../src/pd_menus.tcl:343 ../src/pd_menus.tcl:362 ../src/pd_menus.tcl:388 #: ../src/pd_menus.tcl:389 ../src/pd_menus.tcl:415 ../src/pd_menus.tcl:427 #: ../src/pd_menus.tcl:454 #, fuzzy msgid "Print..." msgstr "संपादित करें (_E)..." #: ../src/pd_menus.tcl:93 ../src/pd_menus.tcl:94 ../src/pd_menus.tcl:139 #: ../src/pd_menus.tcl:140 #, fuzzy msgid "Undo" msgstr "यूगांडा" #: ../src/pd_menus.tcl:95 ../src/pd_menus.tcl:96 ../src/pd_menus.tcl:141 #: ../src/pd_menus.tcl:142 #, fuzzy msgid "Redo" msgstr "लाल:" #: ../src/pd_menus.tcl:98 ../src/pd_menus.tcl:99 ../src/pd_menus.tcl:144 #: ../src/pd_menus.tcl:145 msgid "Cut" msgstr "" #: ../src/pd_menus.tcl:104 ../src/pd_menus.tcl:105 ../src/pd_menus.tcl:150 #: ../src/pd_menus.tcl:151 #, fuzzy msgid "Duplicate" msgstr "तारीख़" #: ../src/pd_menus.tcl:106 ../src/pd_menus.tcl:107 ../src/pd_menus.tcl:152 #: ../src/pd_menus.tcl:153 #, fuzzy msgid "Select All" msgstr "रंग चुनें" #: ../src/pd_menus.tcl:110 ../src/pd_menus.tcl:111 ../src/pd_menus.tcl:115 #: ../src/pd_menus.tcl:116 ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:157 #: ../src/pd_menus.tcl:161 ../src/pd_menus.tcl:162 #, fuzzy msgid "Text Editor" msgstr "पाठ रंग" #: ../src/pd_menus.tcl:120 ../src/pd_menus.tcl:121 ../src/pd_menus.tcl:166 #: ../src/pd_menus.tcl:167 msgid "Tidy Up" msgstr "" #: ../src/pd_menus.tcl:122 ../src/pd_menus.tcl:123 ../src/pd_menus.tcl:168 #: ../src/pd_menus.tcl:169 msgid "Toggle Console" msgstr "" #: ../src/pd_menus.tcl:124 ../src/pd_menus.tcl:125 ../src/pd_menus.tcl:170 #: ../src/pd_menus.tcl:171 #, fuzzy msgid "Clear Console" msgstr "सूची साफ करें" #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:174 #: ../src/pd_menus.tcl:175 #, fuzzy msgid "Edit Mode" msgstr "मोड" #: ../src/pd_menus.tcl:145 ../src/pd_menus.tcl:190 ../src/pd_menus.tcl:191 msgid "Object" msgstr "" #: ../src/pd_menus.tcl:149 ../src/pd_menus.tcl:194 ../src/pd_menus.tcl:195 #, fuzzy msgid "Number" msgstr "$ संख्या" #: ../src/pd_menus.tcl:151 ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:197 msgid "Symbol" msgstr "" #: ../src/pd_menus.tcl:153 ../src/pd_menus.tcl:198 ../src/pd_menus.tcl:199 #, fuzzy msgid "Comment" msgstr "कमांड" #: ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:201 ../src/pd_menus.tcl:202 #, fuzzy msgid "Bang" msgstr "प्रतिबंध" #: ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:203 ../src/pd_menus.tcl:204 #, fuzzy msgid "Toggle" msgstr "टोगो" #: ../src/pd_menus.tcl:160 ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:206 #, fuzzy msgid "Number2" msgstr "$ संख्या" #: ../src/pd_menus.tcl:162 ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:208 msgid "Vslider" msgstr "" #: ../src/pd_menus.tcl:164 ../src/pd_menus.tcl:209 ../src/pd_menus.tcl:210 #, fuzzy msgid "Hslider" msgstr "छुपा हुआ" #: ../src/pd_menus.tcl:166 ../src/pd_menus.tcl:211 ../src/pd_menus.tcl:212 #, fuzzy msgid "Vradio" msgstr "संस्करण" #: ../src/pd_menus.tcl:168 ../src/pd_menus.tcl:213 ../src/pd_menus.tcl:214 msgid "Hradio" msgstr "" #: ../src/pd_menus.tcl:170 ../src/pd_menus.tcl:215 ../src/pd_menus.tcl:216 msgid "VU Meter" msgstr "" #: ../src/pd_menus.tcl:172 ../src/pd_menus.tcl:217 ../src/pd_menus.tcl:218 #, fuzzy msgid "Canvas" msgstr "कनाडा" #: ../src/pd_menus.tcl:175 ../src/pd_menus.tcl:220 ../src/pd_menus.tcl:221 msgid "Graph" msgstr "ग्राफ" #: ../src/pd_menus.tcl:176 ../src/pd_menus.tcl:221 ../src/pd_menus.tcl:222 #, fuzzy msgid "Array" msgstr "अंडोरा" #: ../src/pd_menus.tcl:181 ../src/pd_menus.tcl:226 ../src/pd_menus.tcl:227 #, fuzzy msgid "Find..." msgstr "फाइल भेजें..." #: ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:228 ../src/pd_menus.tcl:229 msgid "Find Again" msgstr "" #: ../src/pd_menus.tcl:185 ../src/pd_menus.tcl:230 ../src/pd_menus.tcl:231 msgid "Find Last Error" msgstr "" #: ../src/pd_menus.tcl:191 ../src/pd_menus.tcl:236 ../src/pd_menus.tcl:237 msgid "DSP On" msgstr "" #: ../src/pd_menus.tcl:193 ../src/pd_menus.tcl:238 ../src/pd_menus.tcl:239 #, fuzzy msgid "DSP Off" msgstr "बंद" #: ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:242 ../src/pd_menus.tcl:269 msgid "Test Audio and MIDI..." msgstr "" #: ../src/pd_menus.tcl:198 ../src/pd_menus.tcl:244 ../src/pd_menus.tcl:271 #, fuzzy msgid "Load Meter" msgstr "लैग मीटर:" #: ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:251 ../src/pd_menus.tcl:278 msgid "Minimize" msgstr "" #: ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:253 ../src/pd_menus.tcl:280 #, fuzzy msgid "Zoom" msgstr "नीचे" #: ../src/pd_menus.tcl:210 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:283 #, fuzzy msgid "Parent Window" msgstr "भेजें विंडो" #: ../src/pd_menus.tcl:216 ../src/pd_menus.tcl:262 ../src/pd_menus.tcl:289 msgid "Bring All to Front" msgstr "" #: ../src/pd_menus.tcl:224 ../src/pd_menus.tcl:241 ../src/pd_menus.tcl:253 #: ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:297 ../src/pd_menus.tcl:335 #: ../src/pd_menus.tcl:362 #, fuzzy msgid "About Pd" msgstr "के बारे में (_A)" #: ../src/pd_menus.tcl:227 ../src/pd_menus.tcl:273 ../src/pd_menus.tcl:300 msgid "HTML Manual..." msgstr "" #: ../src/pd_menus.tcl:229 ../src/pd_menus.tcl:275 ../src/pd_menus.tcl:302 #, fuzzy msgid "Browser..." msgstr "ब्राउज़..." #: ../src/pd_menus.tcl:248 ../src/pd_menus.tcl:260 ../src/pd_menus.tcl:342 #: ../src/pd_menus.tcl:369 msgid "Preferences..." msgstr "प्राथमिकताएं..." #: ../src/pd_menus.tcl:257 ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:352 #: ../src/pd_menus.tcl:379 msgid "Open Recent" msgstr "" #: ../src/pd_menus.tcl:263 msgid "Audio Settings..." msgstr "" #: ../src/pd_menus.tcl:265 msgid "MIDI Settings..." msgstr "" #: ../src/pd_menus.tcl:296 ../src/pd_menus.tcl:309 ../src/pd_menus.tcl:333 #: ../src/pd_menus.tcl:346 ../src/pd_menus.tcl:393 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:432 ../src/pd_menus.tcl:459 msgid "Quit" msgstr "बाहर" #: ../src/pd_menus.tcl:304 ../src/pd_menus.tcl:331 #, fuzzy msgid "Clear Menu" msgstr "सूची साफ करें" #: ../src/pdtk_canvas.tcl:44 ../src/pdtk_canvas.tcl:106 #: ../src/pdtk_canvas.tcl:109 ../src/pdtk_canvas.tcl:123 #: ../src/pdtk_canvas.tcl:125 ../src/pdtk_canvas.tcl:126 #: ../src/pdtk_canvas.tcl:128 msgid "Properties" msgstr "" #: ../src/pdwindow.tcl:43 #, fuzzy msgid "DSP" msgstr "बंद" #: ../startup/object_db.tcl:113 msgid "Signal" msgstr "" #: ../startup/object_db.tcl:114 msgid "Generators" msgstr "" #: ../startup/object_db.tcl:115 #, fuzzy msgid "Filters" msgstr "फाइल" #: ../startup/object_db.tcl:116 ../startup/object_db.tcl:124 msgid "Math" msgstr "" #: ../startup/object_db.tcl:117 ../startup/object_db.tcl:125 msgid "I/O" msgstr "" #: ../startup/object_db.tcl:118 ../startup/object_db.tcl:126 msgid "Sampling" msgstr "" #: ../startup/object_db.tcl:119 ../startup/object_db.tcl:128 msgid "Routing" msgstr "" #: ../startup/object_db.tcl:120 ../startup/object_db.tcl:129 msgid "Others" msgstr "" #: ../startup/object_db.tcl:127 msgid "GUI" msgstr "" pd-0.46-7/po/pt_br.po0000664000175000017500000012611312160204055012457 0ustar mspmsp# Brazilian Portuguese translation of Pure Data. # This file is put in the public domain # msgid "" msgstr "" "Project-Id-Version: Pure Data 0.43\n" "Report-Msgid-Bugs-To: pd-dev@iem.at\n" "POT-Creation-Date: 2010-01-17 19:19-0500\n" "PO-Revision-Date: 2010-01-23 03:45-0200\n" "Last-Translator: Vilson Vieira \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit" #: ../src/dialog_array.tcl:115 ../src/dialog_array.tcl:117 #: ../src/pd_menus.tcl:100 ../src/pd_menus.tcl:101 ../src/pd_menus.tcl:146 #: ../src/pd_menus.tcl:147 ../src/pd_menus.tcl:152 ../src/pd_menus.tcl:157 msgid "Copy" msgstr "Copiar" #: ../src/dialog_array.tcl:118 ../src/dialog_array.tcl:120 #: ../src/pd_menus.tcl:102 ../src/pd_menus.tcl:103 ../src/pd_menus.tcl:148 #: ../src/pd_menus.tcl:149 ../src/pd_menus.tcl:154 ../src/pd_menus.tcl:159 msgid "Paste" msgstr "Colar" #: ../src/dialog_array.tcl:264 ../src/dialog_array.tcl:266 msgid "Array Properties" msgstr "Propriedades do Vetor" #: ../src/dialog_array.tcl:270 ../src/dialog_array.tcl:272 #: ../src/dialog_array.tcl:274 msgid "Name:" msgstr "Nome:" #: ../src/dialog_array.tcl:276 ../src/dialog_array.tcl:278 #: ../src/dialog_array.tcl:280 ../src/dialog_canvas.tcl:178 #: ../src/dialog_canvas.tcl:182 ../src/dialog_canvas.tcl:193 #: ../src/dialog_canvas.tcl:197 ../src/dialog_iemgui.tcl:617 #: ../src/dialog_iemgui.tcl:619 ../src/dialog_iemgui.tcl:621 #: ../src/dialog_iemgui.tcl:626 msgid "Size:" msgstr "Tamanho:" #: ../src/dialog_array.tcl:280 ../src/dialog_array.tcl:282 #: ../src/dialog_array.tcl:284 msgid "Save contents" msgstr "Salvar conteúdo" #: ../src/dialog_array.tcl:284 ../src/dialog_array.tcl:286 #: ../src/dialog_array.tcl:288 msgid "Draw as:" msgstr "Desenhar como:" #: ../src/dialog_array.tcl:287 ../src/dialog_array.tcl:289 #: ../src/dialog_array.tcl:291 msgid "Points" msgstr "Pontos" #: ../src/dialog_array.tcl:289 ../src/dialog_array.tcl:291 #: ../src/dialog_array.tcl:293 msgid "Polygon" msgstr "Polígono" #: ../src/dialog_array.tcl:291 ../src/dialog_array.tcl:293 #: ../src/dialog_array.tcl:295 msgid "Bezier curve" msgstr "Curva de Bezier" #: ../src/dialog_array.tcl:297 ../src/dialog_array.tcl:299 #: ../src/dialog_array.tcl:301 msgid "Put array into:" msgstr "Inserir vetor em:" #: ../src/dialog_array.tcl:300 ../src/dialog_array.tcl:302 #: ../src/dialog_array.tcl:304 msgid "New graph" msgstr "Novo gráfico" #: ../src/dialog_array.tcl:302 ../src/dialog_array.tcl:304 #: ../src/dialog_array.tcl:306 msgid "Last graph" msgstr "Último gráfico" #: ../src/dialog_array.tcl:306 ../src/dialog_array.tcl:308 #: ../src/dialog_array.tcl:310 msgid "Delete array" msgstr "Excluir vetor" #: ../src/dialog_array.tcl:312 ../src/dialog_array.tcl:314 #: ../src/dialog_array.tcl:316 msgid "Open List View..." msgstr "Abrir Visualização em Lista..." #: ../src/dialog_array.tcl:319 ../src/dialog_array.tcl:321 #: ../src/dialog_array.tcl:323 ../src/dialog_audio.tcl:136 #: ../src/dialog_audio.tcl:138 ../src/dialog_audio.tcl:144 #: ../src/dialog_canvas.tcl:205 ../src/dialog_canvas.tcl:209 #: ../src/dialog_find.tcl:160 ../src/dialog_font.tcl:51 #: ../src/dialog_gatom.tcl:153 ../src/dialog_gatom.tcl:157 #: ../src/dialog_gatom.tcl:161 ../src/dialog_iemgui.tcl:738 #: ../src/dialog_iemgui.tcl:742 ../src/dialog_iemgui.tcl:747 #: ../src/dialog_iemgui.tcl:748 ../src/dialog_midi.tcl:91 #: ../src/dialog_midi.tcl:93 ../src/dialog_midi.tcl:97 #: ../src/dialog_midi.tcl:226 ../src/dialog_midi.tcl:228 #: ../src/dialog_midi.tcl:232 ../src/scrollboxwindow.tcl:82 msgid "Cancel" msgstr "Cancelar" #: ../src/dialog_array.tcl:321 ../src/dialog_array.tcl:323 #: ../src/dialog_array.tcl:327 ../src/dialog_audio.tcl:138 #: ../src/dialog_audio.tcl:140 ../src/dialog_audio.tcl:148 #: ../src/dialog_canvas.tcl:207 ../src/dialog_canvas.tcl:213 #: ../src/dialog_gatom.tcl:156 ../src/dialog_gatom.tcl:161 #: ../src/dialog_gatom.tcl:164 ../src/dialog_iemgui.tcl:741 #: ../src/dialog_iemgui.tcl:745 ../src/dialog_iemgui.tcl:751 #: ../src/dialog_midi.tcl:93 ../src/dialog_midi.tcl:95 #: ../src/dialog_midi.tcl:99 ../src/dialog_midi.tcl:228 #: ../src/dialog_midi.tcl:230 ../src/dialog_midi.tcl:234 #: ../src/scrollboxwindow.tcl:84 msgid "Apply" msgstr "Aplicar" #: ../src/dialog_array.tcl:323 ../src/dialog_array.tcl:325 #: ../src/dialog_array.tcl:331 ../src/dialog_audio.tcl:140 #: ../src/dialog_audio.tcl:142 ../src/dialog_audio.tcl:152 #: ../src/dialog_canvas.tcl:209 ../src/dialog_canvas.tcl:217 #: ../src/dialog_font.tcl:53 ../src/dialog_font.tcl:92 #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:101 #: ../src/dialog_font.tcl:103 ../src/dialog_gatom.tcl:159 #: ../src/dialog_gatom.tcl:165 ../src/dialog_gatom.tcl:167 #: ../src/dialog_iemgui.tcl:744 ../src/dialog_iemgui.tcl:748 #: ../src/dialog_iemgui.tcl:754 ../src/dialog_iemgui.tcl:755 #: ../src/dialog_midi.tcl:95 ../src/dialog_midi.tcl:97 #: ../src/dialog_midi.tcl:101 ../src/dialog_midi.tcl:230 #: ../src/dialog_midi.tcl:232 ../src/dialog_midi.tcl:236 #: ../src/dialog_startup.tcl:29 ../src/dialog_startup.tcl:30 #: ../src/scrollboxwindow.tcl:86 msgid "OK" msgstr "OK" #: ../src/dialog_audio.tcl:130 ../src/dialog_audio.tcl:132 msgid "Audio Settings" msgstr "Configurações de Áudio" #: ../src/dialog_audio.tcl:142 ../src/dialog_audio.tcl:144 #: ../src/dialog_audio.tcl:156 msgid "Save all settings" msgstr "Salvar todas as configurações" #: ../src/dialog_audio.tcl:151 ../src/dialog_audio.tcl:153 #: ../src/dialog_audio.tcl:164 msgid "Sample rate:" msgstr "Taxa de amostragem:" #: ../src/dialog_audio.tcl:153 ../src/dialog_audio.tcl:155 #: ../src/dialog_audio.tcl:166 msgid "Delay (msec):" msgstr "Delay (ms):" #: ../src/dialog_audio.tcl:158 ../src/dialog_audio.tcl:160 #: ../src/dialog_audio.tcl:172 msgid "Use callbacks" msgstr "Usar callbacks" #: ../src/dialog_audio.tcl:166 ../src/dialog_audio.tcl:168 #: ../src/dialog_audio.tcl:180 ../src/dialog_midi.tcl:105 #: ../src/dialog_midi.tcl:107 ../src/dialog_midi.tcl:111 #: ../src/dialog_midi.tcl:241 ../src/dialog_midi.tcl:243 #: ../src/dialog_midi.tcl:247 msgid "Input device 1:" msgstr "Dispositivo de entrada 1:" #: ../src/dialog_audio.tcl:169 ../src/dialog_audio.tcl:171 #: ../src/dialog_audio.tcl:183 ../src/dialog_audio.tcl:185 #: ../src/dialog_audio.tcl:198 ../src/dialog_audio.tcl:200 #: ../src/dialog_audio.tcl:213 ../src/dialog_audio.tcl:214 #: ../src/dialog_audio.tcl:215 ../src/dialog_audio.tcl:229 #: ../src/dialog_audio.tcl:232 ../src/dialog_audio.tcl:234 #: ../src/dialog_audio.tcl:249 ../src/dialog_audio.tcl:250 #: ../src/dialog_audio.tcl:252 ../src/dialog_audio.tcl:265 #: ../src/dialog_audio.tcl:267 ../src/dialog_audio.tcl:268 #: ../src/dialog_audio.tcl:280 ../src/dialog_audio.tcl:282 #: ../src/dialog_audio.tcl:284 ../src/dialog_audio.tcl:300 msgid "Channels:" msgstr "Canais:" #: ../src/dialog_audio.tcl:179 ../src/dialog_audio.tcl:181 #: ../src/dialog_audio.tcl:194 ../src/dialog_midi.tcl:115 #: ../src/dialog_midi.tcl:117 ../src/dialog_midi.tcl:121 #: ../src/dialog_midi.tcl:251 ../src/dialog_midi.tcl:253 #: ../src/dialog_midi.tcl:257 msgid "Input device 2:" msgstr "Dispositivo de entrada 2:" #: ../src/dialog_audio.tcl:194 ../src/dialog_audio.tcl:196 #: ../src/dialog_audio.tcl:210 ../src/dialog_midi.tcl:127 #: ../src/dialog_midi.tcl:129 ../src/dialog_midi.tcl:133 #: ../src/dialog_midi.tcl:263 ../src/dialog_midi.tcl:265 #: ../src/dialog_midi.tcl:269 msgid "Input device 3:" msgstr "Dispositivo de entrada 3:" #: ../src/dialog_audio.tcl:209 ../src/dialog_audio.tcl:211 #: ../src/dialog_audio.tcl:225 ../src/dialog_midi.tcl:139 #: ../src/dialog_midi.tcl:141 ../src/dialog_midi.tcl:145 #: ../src/dialog_midi.tcl:275 ../src/dialog_midi.tcl:277 #: ../src/dialog_midi.tcl:281 msgid "Input device 4:" msgstr "Dispositivo de entrada 4:" #: ../src/dialog_audio.tcl:223 ../src/dialog_audio.tcl:225 #: ../src/dialog_audio.tcl:240 ../src/dialog_midi.tcl:150 #: ../src/dialog_midi.tcl:152 ../src/dialog_midi.tcl:156 #: ../src/dialog_midi.tcl:286 ../src/dialog_midi.tcl:288 #: ../src/dialog_midi.tcl:292 msgid "Output device 1:" msgstr "Dispositivo de saída 1:" #: ../src/dialog_audio.tcl:226 ../src/dialog_audio.tcl:228 #: ../src/dialog_audio.tcl:243 msgid "(same as input device) .............. " msgstr "(mesmo que o dispositivo de entrada) .............. " #: ../src/dialog_audio.tcl:246 ../src/dialog_audio.tcl:248 #: ../src/dialog_audio.tcl:264 ../src/dialog_midi.tcl:160 #: ../src/dialog_midi.tcl:162 ../src/dialog_midi.tcl:166 #: ../src/dialog_midi.tcl:296 ../src/dialog_midi.tcl:298 #: ../src/dialog_midi.tcl:302 msgid "Output device 2:" msgstr "Dispositivo de saída 2:" #: ../src/dialog_audio.tcl:261 ../src/dialog_audio.tcl:263 #: ../src/dialog_audio.tcl:280 ../src/dialog_midi.tcl:171 #: ../src/dialog_midi.tcl:173 ../src/dialog_midi.tcl:177 #: ../src/dialog_midi.tcl:307 ../src/dialog_midi.tcl:309 #: ../src/dialog_midi.tcl:313 msgid "Output device 3:" msgstr "Dispositivo de saída 3:" #: ../src/dialog_audio.tcl:276 ../src/dialog_audio.tcl:278 #: ../src/dialog_audio.tcl:296 ../src/dialog_midi.tcl:182 #: ../src/dialog_midi.tcl:184 ../src/dialog_midi.tcl:188 #: ../src/dialog_midi.tcl:318 ../src/dialog_midi.tcl:320 #: ../src/dialog_midi.tcl:324 msgid "Output device 4:" msgstr "Dispositivo de saída 4:" #: ../src/dialog_audio.tcl:291 ../src/dialog_audio.tcl:293 #: ../src/dialog_audio.tcl:312 ../src/dialog_midi.tcl:195 #: ../src/dialog_midi.tcl:197 ../src/dialog_midi.tcl:201 msgid "Use multiple devices" msgstr "Usar múltiplos dispositivos" #: ../src/dialog_canvas.tcl:122 msgid "WARNING: unknown graphme flags received in pdtk_canvas_dialog" msgstr "AVISO: flags graphme desconhecidas recebidas em pdtk_canvas_dialog" #: ../src/dialog_canvas.tcl:142 msgid "Canvas Properties" msgstr "Propriedades da Tela" #: ../src/dialog_canvas.tcl:146 ../src/dialog_canvas.tcl:150 msgid "Scale" msgstr "Escala" #: ../src/dialog_canvas.tcl:150 ../src/dialog_canvas.tcl:154 msgid "X units per pixel:" msgstr "Unidades X por pixel:" #: ../src/dialog_canvas.tcl:155 ../src/dialog_canvas.tcl:159 msgid "Y units per pixel:" msgstr "Unidades Y por pixel:" #: ../src/dialog_canvas.tcl:159 ../src/dialog_canvas.tcl:163 msgid "Appearance on parent patch" msgstr "Aparência no patch pai" #: ../src/dialog_canvas.tcl:161 ../src/dialog_canvas.tcl:165 msgid "Graph-On-Parent" msgstr "Desenhar-No-Pai" #: ../src/dialog_canvas.tcl:165 ../src/dialog_canvas.tcl:169 msgid "Hide object name and arguments" msgstr "Esconder nome e argumentos do objeto" #: ../src/dialog_canvas.tcl:170 ../src/dialog_canvas.tcl:174 msgid "Range and size" msgstr "Registro de valores e tamanho" #: ../src/dialog_canvas.tcl:174 ../src/dialog_canvas.tcl:178 msgid "X range, from" msgstr "Registro de X, de" #: ../src/dialog_canvas.tcl:176 ../src/dialog_canvas.tcl:180 #: ../src/dialog_canvas.tcl:191 ../src/dialog_canvas.tcl:195 msgid "to" msgstr "a" #: ../src/dialog_canvas.tcl:180 ../src/dialog_canvas.tcl:184 #: ../src/dialog_canvas.tcl:195 ../src/dialog_canvas.tcl:199 msgid "Margin:" msgstr "Margem:" #: ../src/dialog_canvas.tcl:189 ../src/dialog_canvas.tcl:193 msgid "Y range, from" msgstr "Registro de Y, de" #: ../src/dialog_data.tcl:29 msgid "Data Properties" msgstr "Propriedades dos Dados" #: ../src/dialog_data.tcl:37 msgid "Send (Ctrl s)" msgstr "Enviar (Ctrl s)" #: ../src/dialog_data.tcl:39 msgid "OK (Ctrl t)" msgstr "OK (Ctrl t)" #: ../src/dialog_find.tcl:63 ../src/dialog_find.tcl:66 #: ../src/dialog_find.tcl:79 ../src/dialog_find.tcl:80 #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:85 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:93 #: ../src/dialog_find.tcl:101 ../src/dialog_find.tcl:105 #: ../src/dialog_find.tcl:107 ../src/dialog_find.tcl:115 #: ../src/dialog_find.tcl:123 ../src/dialog_find.tcl:164 #: ../src/pd_menus.tcl:45 msgid "Find" msgstr "Procurar" #: ../src/dialog_find.tcl:70 ../src/dialog_find.tcl:73 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:91 #: ../src/dialog_find.tcl:93 ../src/dialog_find.tcl:101 #: ../src/dialog_find.tcl:142 msgid "Search in" msgstr "Procurar em" #: ../src/dialog_find.tcl:72 ../src/dialog_find.tcl:75 #: ../src/dialog_find.tcl:89 ../src/dialog_find.tcl:93 #: ../src/dialog_find.tcl:95 ../src/dialog_find.tcl:103 #: ../src/dialog_find.tcl:144 msgid "for:" msgstr "por:" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:90 #: ../src/dialog_find.tcl:104 ../src/dialog_find.tcl:108 #: ../src/dialog_find.tcl:110 ../src/dialog_find.tcl:118 #: ../src/dialog_find.tcl:168 ../src/pd_menus.tcl:63 ../src/pd_menus.tcl:74 #: ../src/pd_menus.tcl:85 ../src/pd_menus.tcl:86 ../src/pd_menus.tcl:87 #: ../src/pd_menus.tcl:95 ../src/pd_menus.tcl:111 ../src/pd_menus.tcl:118 #: ../src/pd_menus.tcl:132 ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:138 #: ../src/pd_menus.tcl:143 ../src/pd_menus.tcl:259 ../src/pd_menus.tcl:272 #: ../src/pd_menus.tcl:295 ../src/pd_menus.tcl:308 ../src/pd_menus.tcl:332 #: ../src/pd_menus.tcl:345 ../src/pd_menus.tcl:354 ../src/pd_menus.tcl:381 #: ../src/pd_menus.tcl:392 ../src/pd_menus.tcl:410 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:431 ../src/pd_menus.tcl:448 ../src/pd_menus.tcl:458 #: ../src/pd_menus.tcl:489 ../src/pd_menus.tcl:496 ../src/pd_menus.tcl:527 #: ../src/pd_menus.tcl:574 msgid "Close" msgstr "Fechar" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:97 #: ../src/dialog_find.tcl:101 ../src/dialog_find.tcl:103 #: ../src/dialog_find.tcl:111 ../src/dialog_find.tcl:154 msgid "Match whole word only" msgstr "Casar somente palavra inteira" #: ../src/dialog_find.tcl:92 ../src/dialog_find.tcl:102 #: ../src/dialog_find.tcl:143 ../src/dialog_font.tcl:49 #: ../src/dialog_font.tcl:50 ../src/pd-gui.tcl:280 ../src/pd-gui.tcl:283 #: ../src/pd-gui.tcl:286 ../src/pd-gui.tcl:288 ../src/pd-gui.tcl:291 #: ../src/pd_menus.tcl:212 ../src/pd_menus.tcl:258 ../src/pd_menus.tcl:285 #: ../src/pd_menus.tcl:289 ../src/pd_menus.tcl:296 ../src/pdwindow.tcl:33 #: ../src/pdwindow.tcl:128 ../src/pdwindow.tcl:277 ../src/pdwindow.tcl:278 msgid "Pd window" msgstr "Janela do PD" #: ../src/dialog_find.tcl:105 #, tcl-format msgid "Couldn't find '%s' in %s" msgstr "Não foi possível encontrar '%s' em %s" #: ../src/dialog_font.tcl:45 msgid "Font Properties" msgstr "Propriedades da Fonte" #: ../src/dialog_font.tcl:46 ../src/dialog_font.tcl:49 #: ../src/dialog_font.tcl:54 ../src/dialog_font.tcl:55 #, tcl-format msgid "%s Font" msgstr "Fonte %s" #: ../src/dialog_font.tcl:61 ../src/dialog_font.tcl:96 #: ../src/dialog_font.tcl:104 ../src/dialog_font.tcl:105 #: ../src/dialog_font.tcl:107 msgid "Font Size" msgstr "Tamanho da Fonte" #: ../src/dialog_font.tcl:89 ../src/dialog_font.tcl:108 #: ../src/dialog_font.tcl:116 ../src/dialog_font.tcl:117 #: ../src/dialog_font.tcl:119 msgid "Stretch" msgstr "Esticar" #: ../src/dialog_font.tcl:96 ../src/dialog_font.tcl:115 #: ../src/dialog_font.tcl:123 ../src/dialog_font.tcl:124 #: ../src/dialog_font.tcl:126 msgid "X and Y" msgstr "X e Y" #: ../src/dialog_font.tcl:98 ../src/dialog_font.tcl:117 #: ../src/dialog_font.tcl:125 ../src/dialog_font.tcl:126 #: ../src/dialog_font.tcl:128 msgid "X only" msgstr "Somente X" #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:119 #: ../src/dialog_font.tcl:127 ../src/dialog_font.tcl:128 #: ../src/dialog_font.tcl:130 msgid "Y only" msgstr "Somente Y" #: ../src/dialog_gatom.tcl:93 msgid "Atom Box Properties" msgstr "Propriedades de Caixa de Átomos" #: ../src/dialog_gatom.tcl:99 ../src/dialog_gatom.tcl:103 msgid "Width:" msgstr "Largura:" #: ../src/dialog_gatom.tcl:103 ../src/dialog_gatom.tcl:107 msgid "Limits" msgstr "Limites" #: ../src/dialog_gatom.tcl:107 ../src/dialog_gatom.tcl:111 msgid "Lower:" msgstr "Menor:" #: ../src/dialog_gatom.tcl:112 ../src/dialog_gatom.tcl:113 #: ../src/dialog_gatom.tcl:116 msgid "Upper:" msgstr "Maior:" #: ../src/dialog_gatom.tcl:116 ../src/dialog_gatom.tcl:120 #: ../src/dialog_gatom.tcl:121 ../src/dialog_iemgui.tcl:598 #: ../src/dialog_iemgui.tcl:600 ../src/dialog_iemgui.tcl:606 #: ../src/dialog_iemgui.tcl:650 ../src/dialog_iemgui.tcl:652 #: ../src/dialog_iemgui.tcl:657 ../src/dialog_iemgui.tcl:659 msgid "Label" msgstr "Etiqueta" #: ../src/dialog_gatom.tcl:124 ../src/dialog_gatom.tcl:128 #: ../src/dialog_gatom.tcl:129 msgid "Left " msgstr "Esquerda " #: ../src/dialog_gatom.tcl:126 ../src/dialog_gatom.tcl:130 #: ../src/dialog_gatom.tcl:131 msgid "Right" msgstr "Direita" #: ../src/dialog_gatom.tcl:128 ../src/dialog_gatom.tcl:132 #: ../src/dialog_gatom.tcl:133 msgid "Top" msgstr "Topo" #: ../src/dialog_gatom.tcl:130 ../src/dialog_gatom.tcl:134 #: ../src/dialog_gatom.tcl:135 msgid "Bottom" msgstr "Fundo" #: ../src/dialog_gatom.tcl:137 ../src/dialog_gatom.tcl:141 #: ../src/dialog_gatom.tcl:145 ../src/dialog_iemgui.tcl:572 #: ../src/dialog_iemgui.tcl:574 ../src/dialog_iemgui.tcl:576 msgid "Messages" msgstr "Mensagens" #: ../src/dialog_gatom.tcl:141 ../src/dialog_gatom.tcl:145 #: ../src/dialog_gatom.tcl:149 ../src/dialog_iemgui.tcl:576 #: ../src/dialog_iemgui.tcl:578 ../src/dialog_iemgui.tcl:580 msgid "Send symbol:" msgstr "Símbolo de 'send':" #: ../src/dialog_gatom.tcl:147 ../src/dialog_gatom.tcl:151 #: ../src/dialog_gatom.tcl:155 ../src/dialog_iemgui.tcl:583 #: ../src/dialog_iemgui.tcl:585 ../src/dialog_iemgui.tcl:589 msgid "Receive symbol:" msgstr "Símbolo de 'receive':" #: ../src/dialog_iemgui.tcl:197 msgid "Background color" msgstr "Cor de plano de fundo" #: ../src/dialog_iemgui.tcl:204 msgid "Foreground color" msgstr "Cor de plano de frente" #: ../src/dialog_iemgui.tcl:211 msgid "Label color" msgstr "Cor da etiqueta" #: ../src/dialog_iemgui.tcl:272 msgid "Init" msgstr "Inicialização" #: ../src/dialog_iemgui.tcl:275 ../src/dialog_iemgui.tcl:546 #: ../src/dialog_iemgui.tcl:550 msgid "No init" msgstr "Sem inicialização" #: ../src/dialog_iemgui.tcl:287 ../src/dialog_iemgui.tcl:556 #: ../src/dialog_iemgui.tcl:558 ../src/dialog_iemgui.tcl:560 msgid "Jump on click" msgstr "Pular ao clicar" #: ../src/dialog_iemgui.tcl:290 ../src/dialog_iemgui.tcl:559 #: ../src/dialog_iemgui.tcl:561 ../src/dialog_iemgui.tcl:563 msgid "Steady on click" msgstr "Fixo ao clicar" #: ../src/dialog_iemgui.tcl:498 #, tcl-format msgid "%s Properties" msgstr "Propriedades de %s" #: ../src/dialog_iemgui.tcl:549 ../src/dialog_iemgui.tcl:550 #: ../src/dialog_iemgui.tcl:553 ../src/pd_menus.tcl:60 ../src/pd_menus.tcl:71 #: ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:84 #: ../src/pd_menus.tcl:92 ../src/pd_menus.tcl:107 ../src/pd_menus.tcl:115 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:130 ../src/pd_menus.tcl:135 #: ../src/pd_menus.tcl:140 ../src/pd_menus.tcl:260 ../src/pd_menus.tcl:273 #: ../src/pd_menus.tcl:288 ../src/pd_menus.tcl:301 ../src/pd_menus.tcl:325 #: ../src/pd_menus.tcl:338 ../src/pd_menus.tcl:355 ../src/pd_menus.tcl:382 #: ../src/pd_menus.tcl:383 ../src/pd_menus.tcl:410 ../src/pd_menus.tcl:411 #: ../src/pd_menus.tcl:422 ../src/pd_menus.tcl:439 ../src/pd_menus.tcl:449 #: ../src/pd_menus.tcl:487 ../src/pd_menus.tcl:490 ../src/pd_menus.tcl:518 #: ../src/pd_menus.tcl:563 msgid "Save" msgstr "Salvar" #: ../src/dialog_iemgui.tcl:606 ../src/dialog_iemgui.tcl:608 #: ../src/dialog_iemgui.tcl:614 msgid "X offset" msgstr "Deslocamento X" #: ../src/dialog_iemgui.tcl:609 ../src/dialog_iemgui.tcl:611 #: ../src/dialog_iemgui.tcl:612 ../src/dialog_iemgui.tcl:617 msgid "Y offset" msgstr "Deslocamento Y" #: ../src/dialog_iemgui.tcl:640 ../src/dialog_iemgui.tcl:642 #: ../src/dialog_iemgui.tcl:645 ../src/dialog_iemgui.tcl:649 msgid "Colors" msgstr "Cores" #: ../src/dialog_iemgui.tcl:646 ../src/dialog_iemgui.tcl:648 #: ../src/dialog_iemgui.tcl:651 ../src/dialog_iemgui.tcl:655 msgid "Background" msgstr "Plano de fundo" #: ../src/dialog_iemgui.tcl:648 ../src/dialog_iemgui.tcl:650 #: ../src/dialog_iemgui.tcl:654 ../src/dialog_iemgui.tcl:657 msgid "Front" msgstr "Frente" #: ../src/dialog_iemgui.tcl:660 ../src/dialog_iemgui.tcl:662 #: ../src/dialog_iemgui.tcl:668 ../src/dialog_iemgui.tcl:669 msgid "Compose color" msgstr "Compor cor" #: ../src/dialog_iemgui.tcl:679 ../src/dialog_iemgui.tcl:682 #: ../src/dialog_iemgui.tcl:688 msgid "Test label" msgstr "Etiqueta de teste" #: ../src/dialog_message.tcl:61 msgid "Send a Pd message" msgstr "Enviar uma mensagem PD" #: ../src/dialog_message.tcl:80 msgid "(use arrow keys for history)" msgstr "(use as setas do teclado para histórico)" #: ../src/dialog_midi.tcl:85 msgid "MIDI Settings" msgstr "Configurações de MIDI" #: ../src/dialog_midi.tcl:220 ../src/dialog_midi.tcl:222 #: ../src/dialog_midi.tcl:226 msgid "ALSA MIDI Settings" msgstr "Configurações de ALSA MIDI" #: ../src/dialog_midi.tcl:331 ../src/dialog_midi.tcl:333 #: ../src/dialog_midi.tcl:337 msgid "Use multiple ALSA devices" msgstr "Usar múltiplos dispositivos ALSA" #: ../src/dialog_midi.tcl:337 ../src/dialog_midi.tcl:339 #: ../src/dialog_midi.tcl:343 msgid "In Ports:" msgstr "Portas de Entrada:" #: ../src/dialog_midi.tcl:340 ../src/dialog_midi.tcl:342 #: ../src/dialog_midi.tcl:346 msgid "Out Ports:" msgstr "Portas de Saída:" #: ../src/dialog_path.tcl:30 msgid "Pd search path for objects, help, fonts, and other files" msgstr "Caminho de busca do PD para objetos, arquivos de ajuda, fontes e outros" #: ../src/dialog_path.tcl:35 msgid "Use standard extensions" msgstr "Usar extensões padrões" #: ../src/dialog_path.tcl:37 msgid "Verbose" msgstr "Informativo" #: ../src/dialog_startup.tcl:49 msgid "Add new library" msgstr "Adicionar nova biblioteca" #: ../src/dialog_startup.tcl:53 msgid "Edit library" msgstr "Editar biblioteca" #: ../src/dialog_startup.tcl:79 msgid "Pd libraries to load on startup" msgstr "Bibliotecas PD para carregar na inicialização" #: ../src/dialog_startup.tcl:82 msgid "Startup flags:" msgstr "Flags de inicialização:" #: ../src/dialog_startup.tcl:91 msgid "Defeat real-time scheduling" msgstr "Anular agendamento em tempo real" #: ../src/g_editor.c:1663 msgid "Discard changes to this window??" msgstr "Descartar mudanças feitas nessa janela??" #: ../src/g_editor.c:1668 msgid "really quit?" msgstr "deseja realmente sair?" #: ../src/g_editor.c:1699 msgid "Close this window??" msgstr "Fechar esta janela??" #: ../src/helpbrowser.tcl:25 msgid "Help Browser" msgstr "Navegador da Ajuda" #: ../src/pd-gui.tcl:185 ../src/pd-gui.tcl:195 ../src/pd-gui.tcl:203 #: ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:215 ../src/pd-gui.tcl:218 #: ../src/pd-gui.tcl:226 ../src/pd-gui.tcl:230 ../src/pd-gui.tcl:241 #: ../src/pd-gui.tcl:259 ../src/pd-gui.tcl:277 ../src/pd-gui.tcl:296 msgid "Associated Files" msgstr "Arquivos Associados" #: ../src/pd-gui.tcl:186 ../src/pd-gui.tcl:196 ../src/pd-gui.tcl:204 #: ../src/pd-gui.tcl:207 ../src/pd-gui.tcl:216 ../src/pd-gui.tcl:219 #: ../src/pd-gui.tcl:227 ../src/pd-gui.tcl:231 ../src/pd-gui.tcl:242 #: ../src/pd-gui.tcl:260 ../src/pd-gui.tcl:278 ../src/pd-gui.tcl:297 msgid "Pd Files" msgstr "Arquivos PD" #: ../src/pd-gui.tcl:187 ../src/pd-gui.tcl:205 ../src/pd-gui.tcl:208 #: ../src/pd-gui.tcl:220 ../src/pd-gui.tcl:228 ../src/pd-gui.tcl:243 #: ../src/pd-gui.tcl:261 ../src/pd-gui.tcl:298 msgid "Max Patch Files" msgstr "Arquivos de Patch Max" #: ../src/pd-gui.tcl:188 ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:209 #: ../src/pd-gui.tcl:221 ../src/pd-gui.tcl:229 ../src/pd-gui.tcl:244 #: ../src/pd-gui.tcl:262 ../src/pd-gui.tcl:299 msgid "Max Text Files" msgstr "Arquivos de Texto Max" #: ../src/pd-gui.tcl:197 ../src/pd-gui.tcl:217 ../src/pd-gui.tcl:232 #: ../src/pd-gui.tcl:279 msgid "Max Patch Files (.pat)" msgstr "Arquivos de Patch Max (.pat)" #: ../src/pd-gui.tcl:198 ../src/pd-gui.tcl:218 ../src/pd-gui.tcl:233 #: ../src/pd-gui.tcl:280 msgid "Max Text Files (.mxt)" msgstr "Arquivos de Texto Max (.mxt)" #: ../src/pd-gui.tcl:270 ../src/pd-gui.tcl:290 ../src/pd-gui.tcl:305 #: ../src/pd-gui.tcl:374 #, tcl-format msgid "WARNING: Font family '%s' not found, using default (%s)" msgstr "AVISO: Fonte '%s' não encontrada, usando a padrão (%s)" #: ../src/pd-gui.tcl:278 ../src/pd-gui.tcl:298 ../src/pd-gui.tcl:313 #: ../src/pd-gui.tcl:382 #, tcl-format msgid "WARNING: Font weight '%s' not found, using default (%s)" msgstr "AVISO: Tamanho de fonte '%s' não encontrado, usando o padrão (%s)" #: ../src/pd-gui.tcl:303 ../src/pd-gui.tcl:323 #, tcl-format msgid "ERROR: %s failed to find font size (%s) that fits into %sx%s!" msgstr "ERRO: %s Falha ao procurar o tamanho de fonte (%s) que caiba em %sx%s!" #: ../src/pd-gui.tcl:338 ../src/pd-gui.tcl:407 #, tcl-format msgid "WARNING: %s failed to find font size (%s) that fits into %sx%s!" msgstr "AVISO: %s Falha ao procurar o tamanho de fonte (%s) que caiba em %sx%s!" #: ../src/pd-gui.tcl:478 ../src/pd-gui.tcl:483 ../src/pd-gui.tcl:501 #: ../src/pd-gui.tcl:518 ../src/pd-gui.tcl:620 msgid "ERROR: 'pd' never showed up, 'pd-gui' quitting!" msgstr "ERRO: 'pd' não apareceu, 'pd-gui' saindo!" #: ../src/pd_connect.tcl:76 ../src/pd_connect.tcl:85 ../src/pdwindow.tcl:90 #: ../src/pdwindow.tcl:239 msgid "(Tcl) INVALID COMMAND NAME: " msgstr "(Tcl) NOME DE COMANDO INVÁLIDO: " #: ../src/pd_connect.tcl:78 ../src/pd_connect.tcl:87 ../src/pdwindow.tcl:92 #: ../src/pdwindow.tcl:241 msgid "(Tcl) UNHANDLED ERROR: " msgstr "(Tcl) ERRO NÃO TRATADO:" #: ../src/pd_menucommands.tcl:19 msgid "Untitled" msgstr "Sem título" #: ../src/pd_menucommands.tcl:78 ../src/pd_menucommands.tcl:79 #: ../src/pd_menucommands.tcl:83 ../src/pd_menucommands.tcl:90 msgid "Send Message..." msgstr "Enviar Mensagem..." #: ../src/pd_menucommands.tcl:82 ../src/pd_menucommands.tcl:83 #: ../src/pd_menucommands.tcl:87 ../src/pd_menucommands.tcl:94 #: ../src/pd_menus.tcl:87 ../src/pd_menus.tcl:88 ../src/pd_menus.tcl:133 #: ../src/pd_menus.tcl:134 ../src/pd_menus.tcl:144 ../src/pd_menus.tcl:147 #: ../src/pd_menus.tcl:190 ../src/pd_menus.tcl:192 ../src/pd_menus.tcl:193 #: ../src/pd_menus.tcl:203 ../src/pd_menus.tcl:265 ../src/pd_menus.tcl:278 #: ../src/pd_menus.tcl:292 ../src/pd_menus.tcl:305 ../src/pd_menus.tcl:329 #: ../src/pd_menus.tcl:342 ../src/pd_menus.tcl:360 ../src/pd_menus.tcl:387 #: ../src/pd_menus.tcl:414 ../src/pd_menus.tcl:416 ../src/pd_menus.tcl:426 #: ../src/pd_menus.tcl:443 ../src/pd_menus.tcl:453 ../src/pd_menus.tcl:491 #: ../startup/object_db.tcl:123 msgid "Message" msgstr "Mensagem" #: ../src/pd_menucommands.tcl:108 ../src/pd_menucommands.tcl:111 #: ../src/pd_menus.tcl:112 ../src/pd_menus.tcl:113 ../src/pd_menus.tcl:117 #: ../src/pd_menus.tcl:118 ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:159 #: ../src/pd_menus.tcl:163 ../src/pd_menus.tcl:164 ../src/pd_menus.tcl:169 #: ../src/pd_menus.tcl:174 msgid "Font" msgstr "Fonte" #: ../src/pd_menucommands.tcl:123 ../src/pd_menucommands.tcl:126 #: ../src/pd_menus.tcl:138 ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:184 #: ../src/pd_menus.tcl:194 ../src/pd_menus.tcl:267 ../src/pd_menus.tcl:475 #: ../src/pd_menus.tcl:569 msgid "Preferences" msgstr "Preferências" #: ../src/pd_menus.tcl:45 msgid "Edit" msgstr "Editar" #: ../src/pd_menus.tcl:45 msgid "File" msgstr "Arquivo" #: ../src/pd_menus.tcl:45 ../src/pdtk_canvas.tcl:48 ../src/pdtk_canvas.tcl:110 #: ../src/pdtk_canvas.tcl:113 ../src/pdtk_canvas.tcl:160 msgid "Help" msgstr "Ajuda" #: ../src/pd_menus.tcl:45 msgid "Media" msgstr "Mídia" #: ../src/pd_menus.tcl:45 msgid "Put" msgstr "Inserir" #: ../src/pd_menus.tcl:45 msgid "Window" msgstr "Janela" #: ../src/pd_menus.tcl:61 ../src/pd_menus.tcl:72 ../src/pd_menus.tcl:83 #: ../src/pd_menus.tcl:84 ../src/pd_menus.tcl:85 ../src/pd_menus.tcl:93 #: ../src/pd_menus.tcl:108 ../src/pd_menus.tcl:116 ../src/pd_menus.tcl:130 #: ../src/pd_menus.tcl:131 ../src/pd_menus.tcl:136 ../src/pd_menus.tcl:141 #: ../src/pd_menus.tcl:261 ../src/pd_menus.tcl:274 ../src/pd_menus.tcl:289 #: ../src/pd_menus.tcl:302 ../src/pd_menus.tcl:326 ../src/pd_menus.tcl:339 #: ../src/pd_menus.tcl:356 ../src/pd_menus.tcl:383 ../src/pd_menus.tcl:384 #: ../src/pd_menus.tcl:411 ../src/pd_menus.tcl:412 ../src/pd_menus.tcl:423 #: ../src/pd_menus.tcl:440 ../src/pd_menus.tcl:450 ../src/pd_menus.tcl:488 #: ../src/pd_menus.tcl:491 ../src/pd_menus.tcl:519 ../src/pd_menus.tcl:564 msgid "Save As..." msgstr "Salvar Como..." #: ../src/pd_menus.tcl:62 ../src/pd_menus.tcl:73 ../src/pd_menus.tcl:84 #: ../src/pd_menus.tcl:88 ../src/pd_menus.tcl:89 ../src/pd_menus.tcl:94 #: ../src/pd_menus.tcl:109 ../src/pd_menus.tcl:117 ../src/pd_menus.tcl:134 #: ../src/pd_menus.tcl:135 ../src/pd_menus.tcl:140 ../src/pd_menus.tcl:145 #: ../src/pd_menus.tcl:267 ../src/pd_menus.tcl:280 ../src/pd_menus.tcl:293 #: ../src/pd_menus.tcl:306 ../src/pd_menus.tcl:330 ../src/pd_menus.tcl:343 #: ../src/pd_menus.tcl:362 ../src/pd_menus.tcl:388 ../src/pd_menus.tcl:389 #: ../src/pd_menus.tcl:415 ../src/pd_menus.tcl:418 ../src/pd_menus.tcl:427 #: ../src/pd_menus.tcl:444 ../src/pd_menus.tcl:454 ../src/pd_menus.tcl:492 #: ../src/pd_menus.tcl:497 ../src/pd_menus.tcl:523 ../src/pd_menus.tcl:570 msgid "Print..." msgstr "Imprimir..." #: ../src/pd_menus.tcl:65 ../src/pd_menus.tcl:76 ../src/pd_menus.tcl:87 #: ../src/pd_menus.tcl:97 ../src/pd_menus.tcl:104 ../src/pd_menus.tcl:105 #: ../src/pd_menus.tcl:113 ../src/pd_menus.tcl:120 ../src/pd_menus.tcl:150 #: ../src/pd_menus.tcl:151 ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:161 msgid "Duplicate" msgstr "Duplicar" #: ../src/pd_menus.tcl:66 ../src/pd_menus.tcl:77 ../src/pd_menus.tcl:88 #: ../src/pd_menus.tcl:98 ../src/pd_menus.tcl:114 ../src/pd_menus.tcl:120 #: ../src/pd_menus.tcl:121 ../src/pd_menus.tcl:166 ../src/pd_menus.tcl:167 #: ../src/pd_menus.tcl:172 ../src/pd_menus.tcl:177 msgid "Tidy Up" msgstr "Organizar" #: ../src/pd_menus.tcl:67 ../src/pd_menus.tcl:78 ../src/pd_menus.tcl:89 #: ../src/pd_menus.tcl:99 ../src/pd_menus.tcl:115 ../src/pd_menus.tcl:122 #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:174 #: ../src/pd_menus.tcl:175 ../src/pd_menus.tcl:178 ../src/pd_menus.tcl:185 #: ../src/pd_menus.tcl:551 ../src/pdtk_canvas.tcl:224 #: ../src/pdtk_canvas.tcl:226 msgid "Edit Mode" msgstr "Modo de Edição" #: ../src/pd_menus.tcl:70 ../src/pd_menus.tcl:80 ../src/pd_menus.tcl:93 #: ../src/pd_menus.tcl:94 ../src/pd_menus.tcl:118 ../src/pd_menus.tcl:124 #: ../src/pd_menus.tcl:139 ../src/pd_menus.tcl:140 ../src/pd_menus.tcl:145 #: ../src/pd_menus.tcl:150 ../src/pd_menus.tcl:320 ../src/pd_menus.tcl:326 msgid "Undo" msgstr "Desfazer" #: ../src/pd_menus.tcl:71 ../src/pd_menus.tcl:81 ../src/pd_menus.tcl:95 #: ../src/pd_menus.tcl:96 ../src/pd_menus.tcl:119 ../src/pd_menus.tcl:125 #: ../src/pd_menus.tcl:141 ../src/pd_menus.tcl:142 ../src/pd_menus.tcl:147 #: ../src/pd_menus.tcl:152 ../src/pd_menus.tcl:326 ../src/pd_menus.tcl:332 msgid "Redo" msgstr "Refazer" #: ../src/pd_menus.tcl:81 ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:127 #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:138 #: ../src/pd_menus.tcl:255 ../src/pd_menus.tcl:267 ../src/pd_menus.tcl:285 #: ../src/pd_menus.tcl:298 ../src/pd_menus.tcl:322 ../src/pd_menus.tcl:335 #: ../src/pd_menus.tcl:349 ../src/pd_menus.tcl:376 ../src/pd_menus.tcl:380 #: ../src/pd_menus.tcl:405 ../src/pd_menus.tcl:407 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:436 ../src/pd_menus.tcl:446 ../src/pd_menus.tcl:484 #: ../src/pd_menus.tcl:515 ../src/pd_menus.tcl:560 msgid "New" msgstr "Novo" #: ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:128 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:134 ../src/pd_menus.tcl:139 #: ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:268 ../src/pd_menus.tcl:286 #: ../src/pd_menus.tcl:299 ../src/pd_menus.tcl:323 ../src/pd_menus.tcl:336 #: ../src/pd_menus.tcl:350 ../src/pd_menus.tcl:377 ../src/pd_menus.tcl:381 #: ../src/pd_menus.tcl:406 ../src/pd_menus.tcl:408 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:437 ../src/pd_menus.tcl:447 ../src/pd_menus.tcl:485 #: ../src/pd_menus.tcl:516 ../src/pd_menus.tcl:561 ../src/pdtk_canvas.tcl:46 #: ../src/pdtk_canvas.tcl:108 ../src/pdtk_canvas.tcl:111 #: ../src/pdtk_canvas.tcl:128 ../src/pdtk_canvas.tcl:130 #: ../src/pdtk_canvas.tcl:131 ../src/pdtk_canvas.tcl:133 #: ../src/pdtk_canvas.tcl:158 ../src/pdtk_canvas.tcl:178 #: ../src/pdtk_canvas.tcl:180 msgid "Open" msgstr "Abrir" #: ../src/pd_menus.tcl:98 ../src/pd_menus.tcl:99 ../src/pd_menus.tcl:144 #: ../src/pd_menus.tcl:145 ../src/pd_menus.tcl:150 ../src/pd_menus.tcl:155 msgid "Cut" msgstr "Cortar" #: ../src/pd_menus.tcl:106 ../src/pd_menus.tcl:107 ../src/pd_menus.tcl:152 #: ../src/pd_menus.tcl:153 ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:163 msgid "Select All" msgstr "Selecionar Tudo" #: ../src/pd_menus.tcl:110 ../src/pd_menus.tcl:111 ../src/pd_menus.tcl:115 #: ../src/pd_menus.tcl:116 ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:157 #: ../src/pd_menus.tcl:161 ../src/pd_menus.tcl:162 ../src/pd_menus.tcl:167 #: ../src/pd_menus.tcl:172 msgid "Text Editor" msgstr "Editor de Texto" #: ../src/pd_menus.tcl:122 ../src/pd_menus.tcl:123 ../src/pd_menus.tcl:168 #: ../src/pd_menus.tcl:169 ../src/pd_menus.tcl:179 msgid "Toggle Console" msgstr "Ativar Console" #: ../src/pd_menus.tcl:124 ../src/pd_menus.tcl:125 ../src/pd_menus.tcl:170 #: ../src/pd_menus.tcl:171 ../src/pd_menus.tcl:174 ../src/pd_menus.tcl:181 msgid "Clear Console" msgstr "Limpar Console" #: ../src/pd_menus.tcl:139 ../src/pd_menus.tcl:495 ../src/pd_menus.tcl:522 #: ../src/pd_menus.tcl:567 msgid "Message..." msgstr "Mensagem..." #: ../src/pd_menus.tcl:145 ../src/pd_menus.tcl:188 ../src/pd_menus.tcl:190 #: ../src/pd_menus.tcl:191 ../src/pd_menus.tcl:201 msgid "Object" msgstr "Objeto" #: ../src/pd_menus.tcl:149 ../src/pd_menus.tcl:192 ../src/pd_menus.tcl:194 #: ../src/pd_menus.tcl:195 ../src/pd_menus.tcl:205 msgid "Number" msgstr "Número" #: ../src/pd_menus.tcl:151 ../src/pd_menus.tcl:194 ../src/pd_menus.tcl:196 #: ../src/pd_menus.tcl:197 ../src/pd_menus.tcl:207 msgid "Symbol" msgstr "Símbolo" #: ../src/pd_menus.tcl:153 ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:198 #: ../src/pd_menus.tcl:199 ../src/pd_menus.tcl:209 msgid "Comment" msgstr "Comentário" #: ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:199 ../src/pd_menus.tcl:201 #: ../src/pd_menus.tcl:202 ../src/pd_menus.tcl:212 msgid "Bang" msgstr "Bang" #: ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:201 ../src/pd_menus.tcl:203 #: ../src/pd_menus.tcl:204 ../src/pd_menus.tcl:214 msgid "Toggle" msgstr "Toggle" #: ../src/pd_menus.tcl:160 ../src/pd_menus.tcl:203 ../src/pd_menus.tcl:205 #: ../src/pd_menus.tcl:206 ../src/pd_menus.tcl:216 msgid "Number2" msgstr "Número2" #: ../src/pd_menus.tcl:162 ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:207 #: ../src/pd_menus.tcl:208 ../src/pd_menus.tcl:218 msgid "Vslider" msgstr "Slider Vertical" #: ../src/pd_menus.tcl:164 ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:209 #: ../src/pd_menus.tcl:210 ../src/pd_menus.tcl:220 msgid "Hslider" msgstr "Slider Horizontal" #: ../src/pd_menus.tcl:166 ../src/pd_menus.tcl:209 ../src/pd_menus.tcl:211 #: ../src/pd_menus.tcl:212 ../src/pd_menus.tcl:222 msgid "Vradio" msgstr "Seleção Vertical" #: ../src/pd_menus.tcl:168 ../src/pd_menus.tcl:211 ../src/pd_menus.tcl:213 #: ../src/pd_menus.tcl:214 ../src/pd_menus.tcl:224 msgid "Hradio" msgstr "Seleção Horizontal" #: ../src/pd_menus.tcl:170 ../src/pd_menus.tcl:213 ../src/pd_menus.tcl:215 #: ../src/pd_menus.tcl:216 ../src/pd_menus.tcl:226 msgid "VU Meter" msgstr "Medidor de VU" #: ../src/pd_menus.tcl:172 ../src/pd_menus.tcl:215 ../src/pd_menus.tcl:217 #: ../src/pd_menus.tcl:218 ../src/pd_menus.tcl:228 msgid "Canvas" msgstr "Tela" #: ../src/pd_menus.tcl:175 ../src/pd_menus.tcl:218 ../src/pd_menus.tcl:220 #: ../src/pd_menus.tcl:221 ../src/pd_menus.tcl:231 msgid "Graph" msgstr "Gráfico" #: ../src/pd_menus.tcl:176 ../src/pd_menus.tcl:219 ../src/pd_menus.tcl:221 #: ../src/pd_menus.tcl:222 ../src/pd_menus.tcl:232 msgid "Array" msgstr "Vetor" #: ../src/pd_menus.tcl:181 ../src/pd_menus.tcl:224 ../src/pd_menus.tcl:226 #: ../src/pd_menus.tcl:227 ../src/pd_menus.tcl:237 msgid "Find..." msgstr "Procurar..." #: ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:226 ../src/pd_menus.tcl:228 #: ../src/pd_menus.tcl:229 ../src/pd_menus.tcl:239 msgid "Find Again" msgstr "Procurar Novamente" #: ../src/pd_menus.tcl:185 ../src/pd_menus.tcl:228 ../src/pd_menus.tcl:230 #: ../src/pd_menus.tcl:231 ../src/pd_menus.tcl:241 msgid "Find Last Error" msgstr "Procurar Último Erro" #: ../src/pd_menus.tcl:191 ../src/pd_menus.tcl:234 ../src/pd_menus.tcl:236 #: ../src/pd_menus.tcl:237 ../src/pd_menus.tcl:247 msgid "DSP On" msgstr "DSP Ligado" #: ../src/pd_menus.tcl:193 ../src/pd_menus.tcl:236 ../src/pd_menus.tcl:238 #: ../src/pd_menus.tcl:239 ../src/pd_menus.tcl:249 msgid "DSP Off" msgstr "DSP Desligado" #: ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:240 ../src/pd_menus.tcl:242 #: ../src/pd_menus.tcl:269 ../src/pd_menus.tcl:280 msgid "Test Audio and MIDI..." msgstr "Testar Áudio e MIDI..." #: ../src/pd_menus.tcl:198 ../src/pd_menus.tcl:242 ../src/pd_menus.tcl:244 #: ../src/pd_menus.tcl:271 ../src/pd_menus.tcl:282 msgid "Load Meter" msgstr "Medidor de Carga de CPU" #: ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:251 ../src/pd_menus.tcl:274 #: ../src/pd_menus.tcl:278 ../src/pd_menus.tcl:289 msgid "Minimize" msgstr "Minimizar" #: ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:253 ../src/pd_menus.tcl:276 #: ../src/pd_menus.tcl:280 ../src/pd_menus.tcl:291 msgid "Zoom" msgstr "Ampliar" #: ../src/pd_menus.tcl:210 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:283 #: ../src/pd_menus.tcl:291 ../src/pd_menus.tcl:294 msgid "Parent Window" msgstr "Janela Mãe" #: ../src/pd_menus.tcl:216 ../src/pd_menus.tcl:262 ../src/pd_menus.tcl:278 #: ../src/pd_menus.tcl:289 ../src/pd_menus.tcl:300 msgid "Bring All to Front" msgstr "Trazer Tudo para Frente" #: ../src/pd_menus.tcl:224 ../src/pd_menus.tcl:241 ../src/pd_menus.tcl:253 #: ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:297 ../src/pd_menus.tcl:298 #: ../src/pd_menus.tcl:308 ../src/pd_menus.tcl:335 ../src/pd_menus.tcl:362 #: ../src/pd_menus.tcl:390 ../src/pd_menus.tcl:472 msgid "About Pd" msgstr "Sobre PD" #: ../src/pd_menus.tcl:227 ../src/pd_menus.tcl:273 ../src/pd_menus.tcl:300 #: ../src/pd_menus.tcl:311 msgid "HTML Manual..." msgstr "Manual HTML..." #: ../src/pd_menus.tcl:229 ../src/pd_menus.tcl:275 ../src/pd_menus.tcl:302 #: ../src/pd_menus.tcl:313 msgid "Browser..." msgstr "Navegador..." #: ../src/pd_menus.tcl:248 ../src/pd_menus.tcl:260 ../src/pd_menus.tcl:342 #: ../src/pd_menus.tcl:369 ../src/pd_menus.tcl:395 msgid "Preferences..." msgstr "Preferências..." #: ../src/pd_menus.tcl:257 ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:352 #: ../src/pd_menus.tcl:379 ../src/pd_menus.tcl:408 ../src/pd_menus.tcl:487 msgid "Open Recent" msgstr "Abrir Recente" #: ../src/pd_menus.tcl:263 ../src/pd_menus.tcl:274 msgid "Audio settings..." msgstr "Configurações de Áudio..." #: ../src/pd_menus.tcl:265 ../src/pd_menus.tcl:276 ../src/pd_menus.tcl:461 msgid "MIDI settings..." msgstr "Configurações de MIDI..." #: ../src/pd_menus.tcl:281 msgid "Next Window" msgstr "Próxima Janela" #: ../src/pd_menus.tcl:284 msgid "Previous Window" msgstr "Janela Anterior" #: ../src/pd_menus.tcl:296 ../src/pd_menus.tcl:309 ../src/pd_menus.tcl:333 #: ../src/pd_menus.tcl:346 ../src/pd_menus.tcl:393 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:432 ../src/pd_menus.tcl:449 ../src/pd_menus.tcl:459 #: ../src/pd_menus.tcl:497 ../src/pd_menus.tcl:528 ../src/pd_menus.tcl:575 msgid "Quit" msgstr "Sair" #: ../src/pd_menus.tcl:304 ../src/pd_menus.tcl:331 ../src/pd_menus.tcl:350 #: ../src/pd_menus.tcl:356 msgid "Clear Menu" msgstr "Limpar Menu" #: ../src/pd_menus.tcl:305 msgid "puredata.info" msgstr "puredata.info" #: ../src/pd_menus.tcl:307 msgid "Report a bug" msgstr "Reportar um bug" #: ../src/pd_menus.tcl:455 msgid "Path..." msgstr "Caminho..." #: ../src/pd_menus.tcl:457 msgid "Startup..." msgstr "Inicialização..." #: ../src/pd_menus.tcl:459 msgid "Audio Settings..." msgstr "Configurações de Áudio..." #: ../src/pdtk_canvas.tcl:44 ../src/pdtk_canvas.tcl:106 #: ../src/pdtk_canvas.tcl:109 ../src/pdtk_canvas.tcl:123 #: ../src/pdtk_canvas.tcl:125 ../src/pdtk_canvas.tcl:126 #: ../src/pdtk_canvas.tcl:128 ../src/pdtk_canvas.tcl:156 #: ../src/pdtk_canvas.tcl:173 ../src/pdtk_canvas.tcl:175 msgid "Properties" msgstr "Propriedades" #: ../src/pdwindow.tcl:43 ../src/pdwindow.tcl:164 ../src/pdwindow.tcl:309 msgid "DSP" msgstr "DSP" #: ../src/pdwindow.tcl:86 ../src/pdwindow.tcl:235 msgid "(Tcl) MISSING CLOSE-BRACE '}': " msgstr "(Tcl) FALTANDO FECHA CHAVES '}': " #: ../src/pdwindow.tcl:88 ../src/pdwindow.tcl:237 msgid "(Tcl) MISSING CLOSE-BRACKET ']': " msgstr "(Tcl) FALTANDO FECHA COLCHETES ']': " #: ../src/pdwindow.tcl:161 ../src/pdwindow.tcl:306 msgid "IN" msgstr "ENTRADA" #: ../src/pdwindow.tcl:162 ../src/pdwindow.tcl:307 msgid "OUT" msgstr "SAÍDA" #: ../src/pdwindow.tcl:168 ../src/pdwindow.tcl:314 msgid "DIO" msgstr "DIO" #: ../src/pdwindow.tcl:177 ../src/pdwindow.tcl:324 msgid "Tcl:" msgstr "Tcl:" #: ../src/wheredoesthisgo.tcl:19 #, tcl-format msgid "Ignoring '%s': doesn't look like a Pd-file" msgstr "Ignorando '%s': não parece ser um arquivo PD válido" #: ../startup/object_db.tcl:113 msgid "Signal" msgstr "Sinal" #: ../startup/object_db.tcl:114 msgid "Generators" msgstr "Geradores" #: ../startup/object_db.tcl:115 msgid "Filters" msgstr "Filtros" #: ../startup/object_db.tcl:116 ../startup/object_db.tcl:124 msgid "Math" msgstr "Matemática" #: ../startup/object_db.tcl:117 ../startup/object_db.tcl:125 msgid "I/O" msgstr "E/S" #: ../startup/object_db.tcl:118 ../startup/object_db.tcl:126 msgid "Sampling" msgstr "Amostragem" #: ../startup/object_db.tcl:119 ../startup/object_db.tcl:128 msgid "Routing" msgstr "Roteamento" #: ../startup/object_db.tcl:120 ../startup/object_db.tcl:129 msgid "Others" msgstr "Outros" #: ../startup/object_db.tcl:127 msgid "GUI" msgstr "GUI" # iemgui msgid "-------dimensions(digits)(pix):-------" msgstr "------dimensões(dígitos)(pix):-------" # iemgui msgid "--------dimensions(pix)(pix):--------" msgstr "--------dimensões(pix)(pix):--------" # iemgui msgid "----------dimensions(pix):-----------" msgstr "----------dimensões(pix):-----------" # iemgui # iemgui msgid "------selectable_dimensions(pix):------" msgstr "----dimensões_selecionáveis(pix):-----" # iemgui msgid "------visible_rectangle(pix)(pix):------" msgstr "-----retângulo_visível(pix)(pix):------" # iemgui msgid "-----------output-range:-----------" msgstr "---------registro-de-saída:---------" # iemgui msgid "--------flash-time(ms)(ms):---------" msgstr "-----tempo-de-flash(ms)(ms):-------" # iemgui msgid "log-height:" msgstr "altura-do-log:" # iemgui msgid "log" msgstr "log" # iemgui msgid "lin" msgstr "lin" # iemgui msgid "top:" msgstr "topo:" # iemgui msgid "bottom:" msgstr "fundo:" # iemgui msgid "value:" msgstr "valor:" # iemgui msgid "max:" msgstr "máx:" # iemgui msgid "min:" msgstr "min:" # iemgui msgid "right:" msgstr "direita:" # iemgui msgid "left:" msgstr "esquerda:" # iemgui msgid "hold:" msgstr "segurar:" # iemgui msgid "intrrpt:" msgstr "interromper:" # iemgui msgid "size:" msgstr "tamanho:" # iemgui msgid "width:" msgstr "largura:" # iemgui msgid "height:" msgstr "altura:" msgid "Do you want to save the changes you made in '%s'?" msgstr "Você deseja salvar as alterações feitas em '%s'?" msgid "Discard changes to '%s'?" msgstr "Descartar as mudanças em '%s'?" msgid "Undo typing" msgstr "Desfazer digitação" msgid "Undo clear" msgstr "Desfazer limpar" msgid "Undo connect" msgstr "Desfazer conectar" msgid "Undo disconnect" msgstr "Desfazer desconectar" msgid "Undo cut" msgstr "Desfazer cortar" msgid "Undo motion" msgstr "Desfazer movimentar" msgid "Undo paste" msgstr "Desfazer colar" msgid "Undo duplicate" msgstr "Desfazer duplicar" msgid "Redo typing" msgstr "Refazer digitação" msgid "Redo clear" msgstr "Refazer limpar" msgid "Redo connect" msgstr "Refazer conectar" msgid "Redo disconnect" msgstr "Refazer desconectar" msgid "Redo cut" msgstr "Refazer cortar" msgid "Redo motion" msgstr "Refazer movimentar" msgid "Redo paste" msgstr "Refazer colar" msgid "Redo duplicate" msgstr "Refazer duplicar" pd-0.46-7/po/el.po0000664000175000017500000006616212160204055011760 0ustar mspmsp# Greek translation of Pure Data # This file is put in the public domain # Γεώργιος Κερατζάκης , 2009. # msgid "" msgstr "" "Project-Id-Version: Pure Data 0.43\n" "Report-Msgid-Bugs-To: pd-dev@iem.at\n" "POT-Creation-Date: 2009-08-25 23:00-0400\n" "PO-Revision-Date: 2009-09-13 01:51+0200\n" "Last-Translator: Γεώργιος Κερατζάκης \n" "Language-Team: Greek \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "Discard changes to '%s'?" msgstr "Απόρριψη αλλαγών σε '%s';" msgid "Do you want to save the changes you made in '%s'?" msgstr "Αποθήκευση αλλαγών που έγιναν στο '%s';" #: ../src/dialog_array.tcl:115 #: ../src/dialog_array.tcl:117 #: ../src/pd_menus.tcl:100 #: ../src/pd_menus.tcl:101 #: ../src/pd_menus.tcl:146 #: ../src/pd_menus.tcl:147 msgid "Copy" msgstr "Αντιγραφή" #: ../src/dialog_array.tcl:118 #: ../src/dialog_array.tcl:120 #: ../src/pd_menus.tcl:102 #: ../src/pd_menus.tcl:103 #: ../src/pd_menus.tcl:148 #: ../src/pd_menus.tcl:149 msgid "Paste" msgstr "Επικόλληση" #: ../src/dialog_array.tcl:264 #: ../src/dialog_array.tcl:266 msgid "Array Properties" msgstr "Ιδιότητες Πίνακα" #: ../src/dialog_array.tcl:270 #: ../src/dialog_array.tcl:272 msgid "Name:" msgstr "Όνομα:" #: ../src/dialog_array.tcl:276 #: ../src/dialog_array.tcl:278 #: ../src/dialog_canvas.tcl:178 #: ../src/dialog_canvas.tcl:193 #: ../src/dialog_iemgui.tcl:619 #: ../src/dialog_iemgui.tcl:621 msgid "Size:" msgstr "Μέγεθος:" #: ../src/dialog_array.tcl:280 #: ../src/dialog_array.tcl:282 msgid "Save contents" msgstr "Αποθήκευση περιεχομένων" #: ../src/dialog_array.tcl:284 #: ../src/dialog_array.tcl:286 msgid "Draw as:" msgstr "Σχεδίαση ως:" #: ../src/dialog_array.tcl:287 #: ../src/dialog_array.tcl:289 msgid "Points" msgstr "Σημεία" #: ../src/dialog_array.tcl:289 #: ../src/dialog_array.tcl:291 msgid "Polygon" msgstr "Πολύγωνο" #: ../src/dialog_array.tcl:291 #: ../src/dialog_array.tcl:293 msgid "Bezier curve" msgstr "Καμπύλη Bezier" #: ../src/dialog_array.tcl:297 #: ../src/dialog_array.tcl:299 msgid "Put array into:" msgstr "Προσθήκη πίνακα σε:" #: ../src/dialog_array.tcl:300 #: ../src/dialog_array.tcl:302 msgid "New graph" msgstr "Νέο γράφημα" #: ../src/dialog_array.tcl:302 #: ../src/dialog_array.tcl:304 msgid "Last graph" msgstr "Τελευταίο γράφημα" #: ../src/dialog_array.tcl:306 #: ../src/dialog_array.tcl:308 msgid "Delete array" msgstr "Διαγραφή πίνακα" #: ../src/dialog_array.tcl:312 #: ../src/dialog_array.tcl:314 msgid "Open List View..." msgstr "Άνοιγμα Προβολής Λίστας..." #: ../src/dialog_array.tcl:319 #: ../src/dialog_array.tcl:321 #: ../src/dialog_audio.tcl:136 #: ../src/dialog_canvas.tcl:205 #: ../src/dialog_font.tcl:51 #: ../src/dialog_gatom.tcl:153 #: ../src/dialog_gatom.tcl:161 #: ../src/dialog_iemgui.tcl:742 #: ../src/dialog_iemgui.tcl:748 #: ../src/dialog_midi.tcl:91 #: ../src/dialog_midi.tcl:226 msgid "Cancel" msgstr "Ακύρωση" #: ../src/dialog_array.tcl:321 #: ../src/dialog_array.tcl:323 #: ../src/dialog_audio.tcl:138 #: ../src/dialog_canvas.tcl:207 #: ../src/dialog_gatom.tcl:156 #: ../src/dialog_gatom.tcl:164 #: ../src/dialog_iemgui.tcl:745 #: ../src/dialog_iemgui.tcl:751 #: ../src/dialog_midi.tcl:93 #: ../src/dialog_midi.tcl:228 msgid "Apply" msgstr "Εφαρμογή" #: ../src/dialog_array.tcl:323 #: ../src/dialog_array.tcl:325 #: ../src/dialog_audio.tcl:140 #: ../src/dialog_canvas.tcl:209 #: ../src/dialog_font.tcl:53 #: ../src/dialog_font.tcl:92 #: ../src/dialog_font.tcl:100 #: ../src/dialog_gatom.tcl:159 #: ../src/dialog_gatom.tcl:167 #: ../src/dialog_iemgui.tcl:748 #: ../src/dialog_iemgui.tcl:754 #: ../src/dialog_midi.tcl:95 #: ../src/dialog_midi.tcl:230 msgid "OK" msgstr "ΟΚ" #: ../src/dialog_audio.tcl:130 msgid "Audio Settings" msgstr "Ρυθμίσεις Ήχου" #: ../src/dialog_audio.tcl:142 msgid "Save All Settings" msgstr "Αποθήκευση όλων των ρυθμίσεων" #: ../src/dialog_audio.tcl:151 #, fuzzy msgid "Sample rate:" msgstr "Ταχύτητα δειγματοληψίας:" #: ../src/dialog_audio.tcl:153 msgid "Delay (msec):" msgstr "Καθυστέρηση (msec):" #: ../src/dialog_audio.tcl:158 msgid "Use callbacks" msgstr "Χρήση επανακλήσεων" #: ../src/dialog_audio.tcl:166 #: ../src/dialog_midi.tcl:105 #: ../src/dialog_midi.tcl:241 msgid "Input device 1:" msgstr "Συσκευή εισόδου 1:" #: ../src/dialog_audio.tcl:169 #: ../src/dialog_audio.tcl:183 #: ../src/dialog_audio.tcl:198 #: ../src/dialog_audio.tcl:213 #: ../src/dialog_audio.tcl:232 #: ../src/dialog_audio.tcl:250 #: ../src/dialog_audio.tcl:265 #: ../src/dialog_audio.tcl:280 msgid "Channels:" msgstr "Κανάλια:" #: ../src/dialog_audio.tcl:179 #: ../src/dialog_midi.tcl:115 #: ../src/dialog_midi.tcl:251 msgid "Input device 2:" msgstr "Συσκευή εισόδου 2:" #: ../src/dialog_audio.tcl:194 #: ../src/dialog_midi.tcl:127 #: ../src/dialog_midi.tcl:263 msgid "Input device 3:" msgstr "Συσκευή εισόδου 3:" #: ../src/dialog_audio.tcl:209 #: ../src/dialog_midi.tcl:139 #: ../src/dialog_midi.tcl:275 msgid "Input device 4:" msgstr "Συσκευή εισόδου 4:" #: ../src/dialog_audio.tcl:223 #: ../src/dialog_midi.tcl:150 #: ../src/dialog_midi.tcl:286 msgid "Output device 1:" msgstr "Συσκευή εξόδου 1:" #: ../src/dialog_audio.tcl:226 msgid "(same as input device) .............. " msgstr "(ομοίως με συσκευή εισόδου) .............." #: ../src/dialog_audio.tcl:246 #: ../src/dialog_midi.tcl:160 #: ../src/dialog_midi.tcl:296 msgid "Output device 2:" msgstr "Συσκευή εξόδου 2:" #: ../src/dialog_audio.tcl:261 #: ../src/dialog_midi.tcl:171 #: ../src/dialog_midi.tcl:307 msgid "Output device 3:" msgstr "Συσκευή εξόδου 3:" #: ../src/dialog_audio.tcl:276 #: ../src/dialog_midi.tcl:182 #: ../src/dialog_midi.tcl:318 msgid "Output device 4:" msgstr "Συσκευή εξόδου 4:" #: ../src/dialog_audio.tcl:291 #: ../src/dialog_midi.tcl:195 msgid "Use multiple devices" msgstr "Χρήση πολλαπλών συσκευών" #: ../src/dialog_canvas.tcl:142 msgid "Canvas Properties" msgstr "Ιδιότητες Καμβά" #: ../src/dialog_canvas.tcl:146 msgid "Scale" msgstr "Κλίμακα" #: ../src/dialog_canvas.tcl:150 msgid "X units per pixel:" msgstr "Χ μονάδες ανά εικονοστοιχείο" #: ../src/dialog_canvas.tcl:155 msgid "Y units per pixel:" msgstr "Υ μονάδες ανά εικονοστοιχείο" #: ../src/dialog_canvas.tcl:159 msgid "Appearance on parent patch" msgstr "Εμφάνιση στο γονεϊκό patch" #: ../src/dialog_canvas.tcl:161 msgid "Graph-On-Parent" msgstr "" #: ../src/dialog_canvas.tcl:165 msgid "Hide object name and arguments" msgstr "Απόκρυψη ονόματος και ορισμάτων του object" #: ../src/dialog_canvas.tcl:170 msgid "Range and size" msgstr "Περιοχή και μέγεθος" #: ../src/dialog_canvas.tcl:174 msgid "X range, from" msgstr "περιοχή Χ, από" #: ../src/dialog_canvas.tcl:176 #: ../src/dialog_canvas.tcl:191 msgid "to" msgstr "σε" #: ../src/dialog_canvas.tcl:180 #: ../src/dialog_canvas.tcl:195 msgid "Margin:" msgstr "Περιθώριο:" #: ../src/dialog_canvas.tcl:189 msgid "Y range, from" msgstr "περιοχή Y, από" #: ../src/dialog_find.tcl:63 #: ../src/dialog_find.tcl:66 #: ../src/dialog_find.tcl:79 #: ../src/dialog_find.tcl:80 #: ../src/dialog_find.tcl:85 #: ../src/dialog_find.tcl:87 #: ../src/dialog_find.tcl:101 #: ../src/dialog_find.tcl:107 #: ../src/pd_menus.tcl:45 msgid "Find" msgstr "Εύρεση" #: ../src/dialog_find.tcl:70 #: ../src/dialog_find.tcl:73 #: ../src/dialog_find.tcl:87 #: ../src/dialog_find.tcl:93 msgid "Search in" msgstr "Αναζήτηση σε" #: ../src/dialog_find.tcl:72 #: ../src/dialog_find.tcl:75 #: ../src/dialog_find.tcl:89 #: ../src/dialog_find.tcl:95 msgid "for:" msgstr "για:" #: ../src/dialog_find.tcl:83 #: ../src/dialog_find.tcl:90 #: ../src/dialog_find.tcl:104 #: ../src/dialog_find.tcl:110 #: ../src/pd_menus.tcl:86 #: ../src/pd_menus.tcl:87 #: ../src/pd_menus.tcl:132 #: ../src/pd_menus.tcl:133 #: ../src/pd_menus.tcl:259 #: ../src/pd_menus.tcl:272 #: ../src/pd_menus.tcl:295 #: ../src/pd_menus.tcl:308 #: ../src/pd_menus.tcl:332 #: ../src/pd_menus.tcl:345 #: ../src/pd_menus.tcl:354 #: ../src/pd_menus.tcl:381 #: ../src/pd_menus.tcl:392 #: ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:431 #: ../src/pd_menus.tcl:458 msgid "Close" msgstr "Κλείσιμο" #: ../src/dialog_find.tcl:83 #: ../src/dialog_find.tcl:97 #: ../src/dialog_find.tcl:103 msgid "Match whole word only" msgstr "Ταύτιση μόνο ολόκληρης λέξης" #: ../src/dialog_font.tcl:45 msgid "Font Properties" msgstr "Ιδιότητες Γραμματοσειράς" #: ../src/dialog_font.tcl:46 #: ../src/dialog_font.tcl:54 #, tcl-format msgid "%s Font" msgstr "Γραμματοσειρά %s" #: ../src/dialog_font.tcl:49 #: ../src/pd-gui.tcl:280 #: ../src/pd-gui.tcl:283 #: ../src/pd-gui.tcl:286 #: ../src/pd-gui.tcl:288 #: ../src/pd-gui.tcl:291 #: ../src/pd_menus.tcl:212 #: ../src/pd_menus.tcl:258 #: ../src/pd_menus.tcl:285 #: ../src/pdwindow.tcl:33 msgid "Pd window" msgstr "Παράθυρο Pd" #: ../src/dialog_font.tcl:61 #: ../src/dialog_font.tcl:96 #: ../src/dialog_font.tcl:104 msgid "Font Size" msgstr "Μέγεθος Γραμματοσειράς" #: ../src/dialog_font.tcl:89 #: ../src/dialog_font.tcl:108 #: ../src/dialog_font.tcl:116 msgid "Stretch" msgstr "Τέντωμα" #: ../src/dialog_font.tcl:96 #: ../src/dialog_font.tcl:115 #: ../src/dialog_font.tcl:123 msgid "X and Y" msgstr "Χ και Y" #: ../src/dialog_font.tcl:98 #: ../src/dialog_font.tcl:117 #: ../src/dialog_font.tcl:125 msgid "X only" msgstr "Μόνο Χ" #: ../src/dialog_font.tcl:100 #: ../src/dialog_font.tcl:119 #: ../src/dialog_font.tcl:127 msgid "Y only" msgstr "Μόνο Y" #: ../src/dialog_gatom.tcl:93 msgid "Atom Box Properties" msgstr "Ιδιότητες Atom Box" #: ../src/dialog_gatom.tcl:99 msgid "Width:" msgstr "Εύρος:" #: ../src/dialog_gatom.tcl:103 msgid "Limits" msgstr "Όρια" #: ../src/dialog_gatom.tcl:107 msgid "Lower:" msgstr "Κατώτερο:" #: ../src/dialog_gatom.tcl:112 #: ../src/dialog_gatom.tcl:113 msgid "Upper:" msgstr "Ανώτερο:" #: ../src/dialog_gatom.tcl:116 #: ../src/dialog_gatom.tcl:121 #: ../src/dialog_iemgui.tcl:600 #: ../src/dialog_iemgui.tcl:652 #: ../src/dialog_iemgui.tcl:657 msgid "Label" msgstr "Ετικέτα" #: ../src/dialog_gatom.tcl:124 #: ../src/dialog_gatom.tcl:129 msgid "Left " msgstr "Αριστερά" #: ../src/dialog_gatom.tcl:126 #: ../src/dialog_gatom.tcl:131 msgid "Right" msgstr "Δεξιά" #: ../src/dialog_gatom.tcl:128 #: ../src/dialog_gatom.tcl:133 msgid "Top" msgstr "Κορυφή" #: ../src/dialog_gatom.tcl:130 #: ../src/dialog_gatom.tcl:135 msgid "Bottom" msgstr "Κάτω" #: ../src/dialog_gatom.tcl:137 #: ../src/dialog_gatom.tcl:145 #: ../src/dialog_iemgui.tcl:574 msgid "Messages" msgstr "Μηνύματα" #: ../src/dialog_gatom.tcl:141 #: ../src/dialog_gatom.tcl:149 #: ../src/dialog_iemgui.tcl:578 msgid "Send symbol:" msgstr "Αποστολή symbol:" #: ../src/dialog_gatom.tcl:147 #: ../src/dialog_gatom.tcl:155 #: ../src/dialog_iemgui.tcl:585 msgid "Receive symbol:" msgstr "Λήψη συμβόλου:" #: ../src/dialog_iemgui.tcl:197 msgid "Background color" msgstr "Χρώμα φόντου" #: ../src/dialog_iemgui.tcl:204 msgid "Foreground color" msgstr "Χρώμα πρώτου πλάνου" #: ../src/dialog_iemgui.tcl:211 msgid "Label color" msgstr "Χρώμα ετικέτας" #: ../src/dialog_iemgui.tcl:272 msgid "Init" msgstr "" #: ../src/dialog_iemgui.tcl:275 #: ../src/dialog_iemgui.tcl:546 msgid "No init" msgstr "" #: ../src/dialog_iemgui.tcl:287 #: ../src/dialog_iemgui.tcl:558 #, fuzzy msgid "Jump on click" msgstr "Μεταπήδηση στο κλικ" #: ../src/dialog_iemgui.tcl:290 #: ../src/dialog_iemgui.tcl:561 #, fuzzy msgid "Steady on click" msgstr "Σταθερότητα στο κλικ" #: ../src/dialog_iemgui.tcl:498 #, tcl-format msgid "%s Properties" msgstr "%s Ιδιότητες" #: ../src/dialog_iemgui.tcl:550 #: ../src/pd_menus.tcl:83 #: ../src/pd_menus.tcl:84 #: ../src/pd_menus.tcl:129 #: ../src/pd_menus.tcl:130 #: ../src/pd_menus.tcl:260 #: ../src/pd_menus.tcl:273 #: ../src/pd_menus.tcl:288 #: ../src/pd_menus.tcl:301 #: ../src/pd_menus.tcl:325 #: ../src/pd_menus.tcl:338 #: ../src/pd_menus.tcl:355 #: ../src/pd_menus.tcl:382 #: ../src/pd_menus.tcl:383 #: ../src/pd_menus.tcl:410 #: ../src/pd_menus.tcl:422 #: ../src/pd_menus.tcl:449 msgid "Save" msgstr "Αποθήκευση" #: ../src/dialog_iemgui.tcl:608 msgid "X offset" msgstr "Παράθεση Χ" #: ../src/dialog_iemgui.tcl:611 #: ../src/dialog_iemgui.tcl:612 msgid "Y offset" msgstr "Παράθεση Υ" #: ../src/dialog_iemgui.tcl:642 #: ../src/dialog_iemgui.tcl:645 msgid "Colors" msgstr "Χρώματα" #: ../src/dialog_iemgui.tcl:648 #: ../src/dialog_iemgui.tcl:651 msgid "Background" msgstr "Φόντο" #: ../src/dialog_iemgui.tcl:650 #: ../src/dialog_iemgui.tcl:654 msgid "Front" msgstr "Πρώτο Πλάνο" #: ../src/dialog_iemgui.tcl:662 #: ../src/dialog_iemgui.tcl:668 msgid "Compose color" msgstr "Σύνθεση χρώματος" #: ../src/dialog_iemgui.tcl:682 #: ../src/dialog_iemgui.tcl:688 #, fuzzy msgid "Test label" msgstr "" #: ../src/dialog_midi.tcl:85 msgid "MIDI Settings" msgstr "Ρυθμίσεις MIDI" #: ../src/dialog_midi.tcl:220 msgid "ALSA MIDI Settings" msgstr "Ρυθμίσεις ALSA MIDI" #: ../src/dialog_midi.tcl:331 msgid "Use multiple ALSA devices" msgstr "Χρήση πολλαπλών συσκευών ALSA" #: ../src/dialog_midi.tcl:337 msgid "In Ports:" msgstr "Θύρες Εισόδου:" #: ../src/dialog_midi.tcl:340 msgid "Out Ports:" msgstr "Θύρες Εξόδου:" #: ../src/g_editor.c:1663 msgid "Discard changes to this window??" msgstr "Απόρριψη αλλαγών σε αυτό το παράθυρο;;" #: ../src/g_editor.c:1668 #, fuzzy msgid "really quit?" msgstr "έξοδος οπωσδήποτε;" #: ../src/g_editor.c:1699 msgid "Close this window??" msgstr "Κλείσιμο αυτού του παραθύρου;;" #: ../src/pd-gui.tcl:185 #: ../src/pd-gui.tcl:195 #: ../src/pd-gui.tcl:206 msgid "Associated Files" msgstr "Συνδεόμενα Αρχεία" #: ../src/pd-gui.tcl:186 #: ../src/pd-gui.tcl:196 #: ../src/pd-gui.tcl:207 msgid "Pd Files" msgstr "Αρχεία Pd" #: ../src/pd-gui.tcl:187 #: ../src/pd-gui.tcl:208 msgid "Max Patch Files" msgstr "Αρχεία Patch από MAX" #: ../src/pd-gui.tcl:188 #: ../src/pd-gui.tcl:209 msgid "Max Text Files" msgstr "Αρχεία Κειμένου από MAX" #: ../src/pd-gui.tcl:197 msgid "Max Patch Files (.pat)" msgstr "Αρχεία Patch από MAX (.pat)" #: ../src/pd-gui.tcl:198 msgid "Max Text Files (.mxt)" msgstr "Αρχεία Κειμένου από MAX (.mxt)" #: ../src/pd-gui.tcl:270 #, tcl-format msgid "WARNING: Font family '%s' not found, using default (%s)" msgstr "ΠΡΟΣΟΧΗ: Η οικογένεια γραμματοσειράς '%s' δεν βρέθηκε, χρήση προεπιλογής (%s)" #: ../src/pd-gui.tcl:278 #, tcl-format msgid "WARNING: Font weight '%s' not found, using default (%s)" msgstr "ΠΡΟΣΟΧΗ: Το βάρος γραμματοσειράς '%s' δεν βρέθηκε, χρήση προεπιλογής (%s)" #: ../src/pd-gui.tcl:303 #, fuzzy, tcl-format msgid "ERROR: %s failed to find font size (%s) that fits into %sx%s!" msgstr "ΣΦΑΛΜΑ: %s αποτυχία εύρεσης μεγέθους γραμματοσειράς (%s) που προσαρμόζεται στο %sx%s!" #: ../src/pd-gui.tcl:478 msgid "ERROR: 'pd' never showed up, 'pd-gui' quitting!" msgstr "ΣΦΑΛΜΑ: το 'pd' δεν εμφανίστηκε ποτέ, έξοδος του 'pd-gui'!" #: ../src/pd_menucommands.tcl:19 msgid "Untitled" msgstr "Ανώνυμο" #: ../src/pd_menucommands.tcl:78 #: ../src/pd_menucommands.tcl:79 #: ../src/pd_menucommands.tcl:90 msgid "Send Message..." msgstr "Αποστολή Μηνύματος..." #: ../src/pd_menucommands.tcl:82 #: ../src/pd_menucommands.tcl:83 #: ../src/pd_menucommands.tcl:94 #: ../src/pd_menus.tcl:87 #: ../src/pd_menus.tcl:88 #: ../src/pd_menus.tcl:133 #: ../src/pd_menus.tcl:134 #: ../src/pd_menus.tcl:147 #: ../src/pd_menus.tcl:192 #: ../src/pd_menus.tcl:193 #: ../src/pd_menus.tcl:265 #: ../src/pd_menus.tcl:278 #: ../src/pd_menus.tcl:292 #: ../src/pd_menus.tcl:305 #: ../src/pd_menus.tcl:329 #: ../src/pd_menus.tcl:342 #: ../src/pd_menus.tcl:360 #: ../src/pd_menus.tcl:387 #: ../src/pd_menus.tcl:414 #: ../src/pd_menus.tcl:426 #: ../src/pd_menus.tcl:453 #: ../startup/object_db.tcl:123 msgid "Message" msgstr "Μήνυμα" #: ../src/pd_menucommands.tcl:108 #: ../src/pd_menucommands.tcl:111 #: ../src/pd_menus.tcl:112 #: ../src/pd_menus.tcl:113 #: ../src/pd_menus.tcl:117 #: ../src/pd_menus.tcl:118 #: ../src/pd_menus.tcl:158 #: ../src/pd_menus.tcl:159 #: ../src/pd_menus.tcl:163 #: ../src/pd_menus.tcl:164 msgid "Font" msgstr "Γραμματοσειρά" #: ../src/pd_menucommands.tcl:123 #: ../src/pd_menucommands.tcl:126 #: ../src/pd_menus.tcl:138 #: ../src/pd_menus.tcl:183 #: ../src/pd_menus.tcl:184 msgid "Preferences" msgstr "Προτιμήσεις" #: ../src/pd_menus.tcl:45 msgid "Edit" msgstr "Επεξεργασία" #: ../src/pd_menus.tcl:45 msgid "File" msgstr "Αρχείο" #: ../src/pd_menus.tcl:45 #: ../src/pdtk_canvas.tcl:48 #: ../src/pdtk_canvas.tcl:113 msgid "Help" msgstr "Βοήθεια" #: ../src/pd_menus.tcl:45 msgid "Media" msgstr "Μέσα" #: ../src/pd_menus.tcl:45 msgid "Put" msgstr "Προσθήκη" #: ../src/pd_menus.tcl:45 msgid "Window" msgstr "Παράθυρο" #: ../src/pd_menus.tcl:81 #: ../src/pd_menus.tcl:82 #: ../src/pd_menus.tcl:127 #: ../src/pd_menus.tcl:128 #: ../src/pd_menus.tcl:255 #: ../src/pd_menus.tcl:267 #: ../src/pd_menus.tcl:285 #: ../src/pd_menus.tcl:298 #: ../src/pd_menus.tcl:322 #: ../src/pd_menus.tcl:335 #: ../src/pd_menus.tcl:349 #: ../src/pd_menus.tcl:376 #: ../src/pd_menus.tcl:380 #: ../src/pd_menus.tcl:407 #: ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:446 msgid "New" msgstr "Νέο" #: ../src/pd_menus.tcl:82 #: ../src/pd_menus.tcl:83 #: ../src/pd_menus.tcl:128 #: ../src/pd_menus.tcl:129 #: ../src/pd_menus.tcl:256 #: ../src/pd_menus.tcl:268 #: ../src/pd_menus.tcl:286 #: ../src/pd_menus.tcl:299 #: ../src/pd_menus.tcl:323 #: ../src/pd_menus.tcl:336 #: ../src/pd_menus.tcl:350 #: ../src/pd_menus.tcl:377 #: ../src/pd_menus.tcl:381 #: ../src/pd_menus.tcl:408 #: ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:447 #: ../src/pdtk_canvas.tcl:46 #: ../src/pdtk_canvas.tcl:111 #: ../src/pdtk_canvas.tcl:131 #: ../src/pdtk_canvas.tcl:133 msgid "Open" msgstr "Άνοιγμα" #: ../src/pd_menus.tcl:84 #: ../src/pd_menus.tcl:85 #: ../src/pd_menus.tcl:130 #: ../src/pd_menus.tcl:131 #: ../src/pd_menus.tcl:261 #: ../src/pd_menus.tcl:274 #: ../src/pd_menus.tcl:289 #: ../src/pd_menus.tcl:302 #: ../src/pd_menus.tcl:326 #: ../src/pd_menus.tcl:339 #: ../src/pd_menus.tcl:356 #: ../src/pd_menus.tcl:383 #: ../src/pd_menus.tcl:384 #: ../src/pd_menus.tcl:411 #: ../src/pd_menus.tcl:423 #: ../src/pd_menus.tcl:450 msgid "Save As..." msgstr "Αποθήκευση Ως..." #: ../src/pd_menus.tcl:88 #: ../src/pd_menus.tcl:89 #: ../src/pd_menus.tcl:134 #: ../src/pd_menus.tcl:135 #: ../src/pd_menus.tcl:267 #: ../src/pd_menus.tcl:280 #: ../src/pd_menus.tcl:293 #: ../src/pd_menus.tcl:306 #: ../src/pd_menus.tcl:330 #: ../src/pd_menus.tcl:343 #: ../src/pd_menus.tcl:362 #: ../src/pd_menus.tcl:388 #: ../src/pd_menus.tcl:389 #: ../src/pd_menus.tcl:415 #: ../src/pd_menus.tcl:427 #: ../src/pd_menus.tcl:454 msgid "Print..." msgstr "Εκτύπωση..." #: ../src/pd_menus.tcl:93 #: ../src/pd_menus.tcl:94 #: ../src/pd_menus.tcl:139 #: ../src/pd_menus.tcl:140 msgid "Undo" msgstr "Αναίρεση" #: ../src/pd_menus.tcl:95 #: ../src/pd_menus.tcl:96 #: ../src/pd_menus.tcl:141 #: ../src/pd_menus.tcl:142 msgid "Redo" msgstr "Ακύρωση Αναίρεσης" #: ../src/pd_menus.tcl:98 #: ../src/pd_menus.tcl:99 #: ../src/pd_menus.tcl:144 #: ../src/pd_menus.tcl:145 msgid "Cut" msgstr "Αποκοπή" #: ../src/pd_menus.tcl:104 #: ../src/pd_menus.tcl:105 #: ../src/pd_menus.tcl:150 #: ../src/pd_menus.tcl:151 msgid "Duplicate" msgstr "Αντίγραφο" #: ../src/pd_menus.tcl:106 #: ../src/pd_menus.tcl:107 #: ../src/pd_menus.tcl:152 #: ../src/pd_menus.tcl:153 msgid "Select All" msgstr "Επιλογή Όλων" #: ../src/pd_menus.tcl:110 #: ../src/pd_menus.tcl:111 #: ../src/pd_menus.tcl:115 #: ../src/pd_menus.tcl:116 #: ../src/pd_menus.tcl:156 #: ../src/pd_menus.tcl:157 #: ../src/pd_menus.tcl:161 #: ../src/pd_menus.tcl:162 msgid "Text Editor" msgstr "Επεξεργαστής Κειμένου" #: ../src/pd_menus.tcl:120 #: ../src/pd_menus.tcl:121 #: ../src/pd_menus.tcl:166 #: ../src/pd_menus.tcl:167 msgid "Tidy Up" msgstr "Τακτοποίηση" #: ../src/pd_menus.tcl:122 #: ../src/pd_menus.tcl:123 #: ../src/pd_menus.tcl:168 #: ../src/pd_menus.tcl:169 msgid "Toggle Console" msgstr "Εναλλαγή Κονσόλας" #: ../src/pd_menus.tcl:124 #: ../src/pd_menus.tcl:125 #: ../src/pd_menus.tcl:170 #: ../src/pd_menus.tcl:171 msgid "Clear Console" msgstr "Καθαρισμός Κονσόλας" #: ../src/pd_menus.tcl:128 #: ../src/pd_menus.tcl:129 #: ../src/pd_menus.tcl:174 #: ../src/pd_menus.tcl:175 msgid "Edit Mode" msgstr "Κατάσταση Επεξεργασίας" #: ../src/pd_menus.tcl:145 #: ../src/pd_menus.tcl:190 #: ../src/pd_menus.tcl:191 msgid "Object" msgstr "" #: ../src/pd_menus.tcl:149 #: ../src/pd_menus.tcl:194 #: ../src/pd_menus.tcl:195 msgid "Number" msgstr "" #: ../src/pd_menus.tcl:151 #: ../src/pd_menus.tcl:196 #: ../src/pd_menus.tcl:197 msgid "Symbol" msgstr "" #: ../src/pd_menus.tcl:153 #: ../src/pd_menus.tcl:198 #: ../src/pd_menus.tcl:199 msgid "Comment" msgstr "Σχόλιο" #: ../src/pd_menus.tcl:156 #: ../src/pd_menus.tcl:201 #: ../src/pd_menus.tcl:202 msgid "Bang" msgstr "" #: ../src/pd_menus.tcl:158 #: ../src/pd_menus.tcl:203 #: ../src/pd_menus.tcl:204 msgid "Toggle" msgstr "" #: ../src/pd_menus.tcl:160 #: ../src/pd_menus.tcl:205 #: ../src/pd_menus.tcl:206 msgid "Number2" msgstr "" #: ../src/pd_menus.tcl:162 #: ../src/pd_menus.tcl:207 #: ../src/pd_menus.tcl:208 msgid "Vslider" msgstr "Κάθετο slider" #: ../src/pd_menus.tcl:164 #: ../src/pd_menus.tcl:209 #: ../src/pd_menus.tcl:210 msgid "Hslider" msgstr "Οριζόντιο slider" #: ../src/pd_menus.tcl:166 #: ../src/pd_menus.tcl:211 #: ../src/pd_menus.tcl:212 #, fuzzy msgid "Vradio" msgstr "Κάθετο radio" #: ../src/pd_menus.tcl:168 #: ../src/pd_menus.tcl:213 #: ../src/pd_menus.tcl:214 #, fuzzy msgid "Hradio" msgstr "Οριζόντιο radio" #: ../src/pd_menus.tcl:170 #: ../src/pd_menus.tcl:215 #: ../src/pd_menus.tcl:216 msgid "VU Meter" msgstr "Μετρητής VU" #: ../src/pd_menus.tcl:172 #: ../src/pd_menus.tcl:217 #: ../src/pd_menus.tcl:218 msgid "Canvas" msgstr "Καμβάς" #: ../src/pd_menus.tcl:175 #: ../src/pd_menus.tcl:220 #: ../src/pd_menus.tcl:221 msgid "Graph" msgstr "Γράφημα" #: ../src/pd_menus.tcl:176 #: ../src/pd_menus.tcl:221 #: ../src/pd_menus.tcl:222 msgid "Array" msgstr "Πίνακας" #: ../src/pd_menus.tcl:181 #: ../src/pd_menus.tcl:226 #: ../src/pd_menus.tcl:227 msgid "Find..." msgstr "Εύρεση..." #: ../src/pd_menus.tcl:183 #: ../src/pd_menus.tcl:228 #: ../src/pd_menus.tcl:229 msgid "Find Again" msgstr "Εύρεση εκ νέου" #: ../src/pd_menus.tcl:185 #: ../src/pd_menus.tcl:230 #: ../src/pd_menus.tcl:231 msgid "Find Last Error" msgstr "Εύρεση Τελευταίου Σφάλματος" #: ../src/pd_menus.tcl:191 #: ../src/pd_menus.tcl:236 #: ../src/pd_menus.tcl:237 msgid "DSP On" msgstr "Ενεργοποίηση DSP" #: ../src/pd_menus.tcl:193 #: ../src/pd_menus.tcl:238 #: ../src/pd_menus.tcl:239 msgid "DSP Off" msgstr "Απενεργοποίση DSP" #: ../src/pd_menus.tcl:196 #: ../src/pd_menus.tcl:242 #: ../src/pd_menus.tcl:269 msgid "Test Audio and MIDI..." msgstr "Έλεγχος 'Ηχου και MIDI..." #: ../src/pd_menus.tcl:198 #: ../src/pd_menus.tcl:244 #: ../src/pd_menus.tcl:271 msgid "Load Meter" msgstr "Φόρτωση Μετρητή" #: ../src/pd_menus.tcl:205 #: ../src/pd_menus.tcl:251 #: ../src/pd_menus.tcl:278 msgid "Minimize" msgstr "Ελαχιστοποιήση" #: ../src/pd_menus.tcl:207 #: ../src/pd_menus.tcl:253 #: ../src/pd_menus.tcl:280 msgid "Zoom" msgstr "Εστίαση" #: ../src/pd_menus.tcl:210 #: ../src/pd_menus.tcl:256 #: ../src/pd_menus.tcl:283 msgid "Parent Window" msgstr "Γονεϊκό Παράθυρο" #: ../src/pd_menus.tcl:216 #: ../src/pd_menus.tcl:262 #: ../src/pd_menus.tcl:289 msgid "Bring All to Front" msgstr "Μεταφορά Όλων σε Πρώτο Πλάνο" #: ../src/pd_menus.tcl:224 #: ../src/pd_menus.tcl:241 #: ../src/pd_menus.tcl:253 #: ../src/pd_menus.tcl:270 #: ../src/pd_menus.tcl:297 #: ../src/pd_menus.tcl:335 #: ../src/pd_menus.tcl:362 msgid "About Pd" msgstr "Περί..." #: ../src/pd_menus.tcl:227 #: ../src/pd_menus.tcl:273 #: ../src/pd_menus.tcl:300 msgid "HTML Manual..." msgstr "Εγχειρίδιο HTML..." #: ../src/pd_menus.tcl:229 #: ../src/pd_menus.tcl:275 #: ../src/pd_menus.tcl:302 #, fuzzy msgid "Browser..." msgstr "Πλοήγηση..." #: ../src/pd_menus.tcl:248 #: ../src/pd_menus.tcl:260 #: ../src/pd_menus.tcl:342 #: ../src/pd_menus.tcl:369 msgid "Preferences..." msgstr "Προτιμήσεις..." #: ../src/pd_menus.tcl:257 #: ../src/pd_menus.tcl:270 #: ../src/pd_menus.tcl:352 #: ../src/pd_menus.tcl:379 msgid "Open Recent" msgstr "Άνοιγμα Πρόσφατου" #: ../src/pd_menus.tcl:263 msgid "Audio Settings..." msgstr "Ρυθμίσεις Ήχου..." #: ../src/pd_menus.tcl:265 msgid "MIDI Settings..." msgstr "Ρυθμίσεις MIDI..." #: ../src/pd_menus.tcl:296 #: ../src/pd_menus.tcl:309 #: ../src/pd_menus.tcl:333 #: ../src/pd_menus.tcl:346 #: ../src/pd_menus.tcl:393 #: ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:432 #: ../src/pd_menus.tcl:459 msgid "Quit" msgstr "Έξοδος" #: ../src/pd_menus.tcl:304 #: ../src/pd_menus.tcl:331 msgid "Clear Menu" msgstr "Καθαρισμός Μενού" #: ../src/pdtk_canvas.tcl:44 #: ../src/pdtk_canvas.tcl:109 #: ../src/pdtk_canvas.tcl:126 #: ../src/pdtk_canvas.tcl:128 msgid "Properties" msgstr "Ιδιότητες" #: ../src/pdwindow.tcl:43 msgid "DSP" msgstr "" #: ../startup/object_db.tcl:113 msgid "Signal" msgstr "Σήμα" #: ../startup/object_db.tcl:114 msgid "Generators" msgstr "Γεννήτριες" #: ../startup/object_db.tcl:115 msgid "Filters" msgstr "Φίλτρα" #: ../startup/object_db.tcl:116 #: ../startup/object_db.tcl:124 msgid "Math" msgstr "Μαθηματικά" #: ../startup/object_db.tcl:117 #: ../startup/object_db.tcl:125 msgid "I/O" msgstr "" #: ../startup/object_db.tcl:118 #: ../startup/object_db.tcl:126 msgid "Sampling" msgstr "Δειγματοληψία" #: ../startup/object_db.tcl:119 #: ../startup/object_db.tcl:128 msgid "Routing" msgstr "Δρομολόγηση" #: ../startup/object_db.tcl:120 #: ../startup/object_db.tcl:129 msgid "Others" msgstr "Άλλα" #: ../startup/object_db.tcl:127 msgid "GUI" msgstr "" #, fuzzy #~ msgid "Patch Font" #~ msgstr "Γραμματοσειρά του Patch" pd-0.46-7/po/it.po0000664000175000017500000006273012160204055011771 0ustar mspmsp# Italian translation for Pure Data # This file is put in the public domain # # Lorenzo Sutton (lorenzosu) , 2009. msgid "" msgstr "" "Project-Id-Version: Pure Data 0.43\n" "Report-Msgid-Bugs-To: pd-dev@iem.at\n" "POT-Creation-Date: 2009-08-27 10:01-0400\n" "PO-Revision-Date: 2009-10-27 21:07+0100\n" "Last-Translator: Lorenzo Sutton (lorenzosu) \n" "Language-Team: American English <>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Lokalize 1.0\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" msgid "Undo duplicate" msgstr "Annulla duplica" msgid "Undo paste" msgstr "Annulla incolla" msgid "Undo motion" msgstr "Annulla spostamento " msgid "Undo cut" msgstr "Annulla taglia" msgid "Undo disconnect" msgstr "Annulla disconnetti" msgid "Undo connect" msgstr "Annulla connetti" msgid "Undo clear" msgstr "Annulla pulisci" msgid "Undo typing" msgstr "Annulla inserimento" msgid "Discard changes to '%s'?" msgstr "Cestinare le modifiche apportate a '%s'?" msgid "Do you want to save the changes you made in '%s'?" msgstr "Salvare le modifiche apportate a '%s'?" #: ../src/dialog_array.tcl:115 ../src/dialog_array.tcl:117 #: ../src/pd_menus.tcl:100 ../src/pd_menus.tcl:101 ../src/pd_menus.tcl:146 #: ../src/pd_menus.tcl:147 msgid "Copy" msgstr "Copia" #: ../src/dialog_array.tcl:118 ../src/dialog_array.tcl:120 #: ../src/pd_menus.tcl:102 ../src/pd_menus.tcl:103 ../src/pd_menus.tcl:148 #: ../src/pd_menus.tcl:149 msgid "Paste" msgstr "Incolla" #: ../src/dialog_array.tcl:264 ../src/dialog_array.tcl:266 msgid "Array Properties" msgstr "Proprietà Array" #: ../src/dialog_array.tcl:270 ../src/dialog_array.tcl:272 msgid "Name:" msgstr "Nome:" #: ../src/dialog_array.tcl:276 ../src/dialog_array.tcl:278 #: ../src/dialog_canvas.tcl:178 ../src/dialog_canvas.tcl:193 #: ../src/dialog_iemgui.tcl:619 ../src/dialog_iemgui.tcl:621 msgid "Size:" msgstr "Dimensione:" #: ../src/dialog_array.tcl:280 ../src/dialog_array.tcl:282 msgid "Save contents" msgstr "Salva contenuto" #: ../src/dialog_array.tcl:284 ../src/dialog_array.tcl:286 msgid "Draw as:" msgstr "Disegna come:" #: ../src/dialog_array.tcl:287 ../src/dialog_array.tcl:289 msgid "Points" msgstr "Punti" #: ../src/dialog_array.tcl:289 ../src/dialog_array.tcl:291 msgid "Polygon" msgstr "Poligono" #: ../src/dialog_array.tcl:291 ../src/dialog_array.tcl:293 msgid "Bezier curve" msgstr "Curva bezier" #: ../src/dialog_array.tcl:297 ../src/dialog_array.tcl:299 msgid "Put array into:" msgstr "Matty l'array in:" #: ../src/dialog_array.tcl:300 ../src/dialog_array.tcl:302 msgid "New graph" msgstr "Nuovo grafico" #: ../src/dialog_array.tcl:302 ../src/dialog_array.tcl:304 msgid "Last graph" msgstr "Ultimo grafico" #: ../src/dialog_array.tcl:306 ../src/dialog_array.tcl:308 msgid "Delete array" msgstr "Cancella array" #: ../src/dialog_array.tcl:312 ../src/dialog_array.tcl:314 msgid "Open List View..." msgstr "Apri visualizzazione lista..." #: ../src/dialog_array.tcl:319 ../src/dialog_array.tcl:321 #: ../src/dialog_audio.tcl:136 ../src/dialog_canvas.tcl:205 #: ../src/dialog_font.tcl:51 ../src/dialog_gatom.tcl:153 #: ../src/dialog_gatom.tcl:161 ../src/dialog_iemgui.tcl:742 #: ../src/dialog_iemgui.tcl:748 ../src/dialog_midi.tcl:91 #: ../src/dialog_midi.tcl:226 msgid "Cancel" msgstr "Annulla" #: ../src/dialog_array.tcl:321 ../src/dialog_array.tcl:323 #: ../src/dialog_audio.tcl:138 ../src/dialog_canvas.tcl:207 #: ../src/dialog_gatom.tcl:156 ../src/dialog_gatom.tcl:164 #: ../src/dialog_iemgui.tcl:745 ../src/dialog_iemgui.tcl:751 #: ../src/dialog_midi.tcl:93 ../src/dialog_midi.tcl:228 msgid "Apply" msgstr "Applica" #: ../src/dialog_array.tcl:323 ../src/dialog_array.tcl:325 #: ../src/dialog_audio.tcl:140 ../src/dialog_canvas.tcl:209 #: ../src/dialog_font.tcl:53 ../src/dialog_font.tcl:92 #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:101 #: ../src/dialog_gatom.tcl:159 ../src/dialog_gatom.tcl:167 #: ../src/dialog_iemgui.tcl:748 ../src/dialog_iemgui.tcl:754 #: ../src/dialog_midi.tcl:95 ../src/dialog_midi.tcl:230 msgid "OK" msgstr "OK" #: ../src/dialog_audio.tcl:130 msgid "Audio Settings" msgstr "Settaggi Audio" #: ../src/dialog_audio.tcl:142 msgid "Save All Settings" msgstr "Salva tutti i settaggi" #: ../src/dialog_audio.tcl:151 msgid "Sample rate:" msgstr "Frequenza di campionamento" #: ../src/dialog_audio.tcl:153 msgid "Delay (msec):" msgstr "Ritardo (msec):" #: ../src/dialog_audio.tcl:158 msgid "Use callbacks" msgstr "Usa callback" #: ../src/dialog_audio.tcl:166 ../src/dialog_midi.tcl:105 #: ../src/dialog_midi.tcl:241 msgid "Input device 1:" msgstr "Dispositivo di ingresso 1:" #: ../src/dialog_audio.tcl:169 ../src/dialog_audio.tcl:183 #: ../src/dialog_audio.tcl:198 ../src/dialog_audio.tcl:213 #: ../src/dialog_audio.tcl:232 ../src/dialog_audio.tcl:250 #: ../src/dialog_audio.tcl:265 ../src/dialog_audio.tcl:280 msgid "Channels:" msgstr "Canali:" #: ../src/dialog_audio.tcl:179 ../src/dialog_midi.tcl:115 #: ../src/dialog_midi.tcl:251 msgid "Input device 2:" msgstr "Dispositivo di ingresso 2:" #: ../src/dialog_audio.tcl:194 ../src/dialog_midi.tcl:127 #: ../src/dialog_midi.tcl:263 msgid "Input device 3:" msgstr "Dispositivo di ingresso 3:" #: ../src/dialog_audio.tcl:209 ../src/dialog_midi.tcl:139 #: ../src/dialog_midi.tcl:275 msgid "Input device 4:" msgstr "Dispositivo di ingresso 4:" #: ../src/dialog_audio.tcl:223 ../src/dialog_midi.tcl:150 #: ../src/dialog_midi.tcl:286 msgid "Output device 1:" msgstr "Dispositivo di uscita 1:" #: ../src/dialog_audio.tcl:226 msgid "(same as input device) .............. " msgstr "(lo stesso del dispositivo di ingresso)..........." #: ../src/dialog_audio.tcl:246 ../src/dialog_midi.tcl:160 #: ../src/dialog_midi.tcl:296 msgid "Output device 2:" msgstr "Dispositivo di uscita 2:" #: ../src/dialog_audio.tcl:261 ../src/dialog_midi.tcl:171 #: ../src/dialog_midi.tcl:307 msgid "Output device 3:" msgstr "Dispositivo di uscita 3:" #: ../src/dialog_audio.tcl:276 ../src/dialog_midi.tcl:182 #: ../src/dialog_midi.tcl:318 msgid "Output device 4:" msgstr "Dispositivo di uscita 4:" #: ../src/dialog_audio.tcl:291 ../src/dialog_midi.tcl:195 msgid "Use multiple devices" msgstr "Usa dispositivi multipli" #: ../src/dialog_canvas.tcl:142 msgid "Canvas Properties" msgstr "Proprietà Canvas" #: ../src/dialog_canvas.tcl:146 msgid "Scale" msgstr "Scala" #: ../src/dialog_canvas.tcl:150 msgid "X units per pixel:" msgstr "X unità per pixel" #: ../src/dialog_canvas.tcl:155 msgid "Y units per pixel:" msgstr "Y unità per pixel:" #: ../src/dialog_canvas.tcl:159 msgid "Appearance on parent patch" msgstr "Aspetto sulla parent patch" #: ../src/dialog_canvas.tcl:161 msgid "Graph-On-Parent" msgstr "Mostra sulla patent" #: ../src/dialog_canvas.tcl:165 msgid "Hide object name and arguments" msgstr "Nascondi il nome oggetto e gli argomenti" #: ../src/dialog_canvas.tcl:170 msgid "Range and size" msgstr "Intervallo e dimensioni" #: ../src/dialog_canvas.tcl:174 msgid "X range, from" msgstr "Intervallo X, da" #: ../src/dialog_canvas.tcl:176 ../src/dialog_canvas.tcl:191 msgid "to" msgstr "a" #: ../src/dialog_canvas.tcl:180 ../src/dialog_canvas.tcl:195 msgid "Margin:" msgstr "Margine:" #: ../src/dialog_canvas.tcl:189 msgid "Y range, from" msgstr "Intervallo Y, da" #: ../src/dialog_find.tcl:63 ../src/dialog_find.tcl:66 #: ../src/dialog_find.tcl:79 ../src/dialog_find.tcl:80 #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:85 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:101 #: ../src/dialog_find.tcl:105 ../src/dialog_find.tcl:107 #: ../src/pd_menus.tcl:45 msgid "Find" msgstr "Trova" #: ../src/dialog_find.tcl:70 ../src/dialog_find.tcl:73 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:91 #: ../src/dialog_find.tcl:93 msgid "Search in" msgstr "Cerca in" #: ../src/dialog_find.tcl:72 ../src/dialog_find.tcl:75 #: ../src/dialog_find.tcl:89 ../src/dialog_find.tcl:93 #: ../src/dialog_find.tcl:95 msgid "for:" msgstr "per:" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:90 #: ../src/dialog_find.tcl:104 ../src/dialog_find.tcl:108 #: ../src/dialog_find.tcl:110 ../src/pd_menus.tcl:86 ../src/pd_menus.tcl:87 #: ../src/pd_menus.tcl:132 ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:259 #: ../src/pd_menus.tcl:272 ../src/pd_menus.tcl:295 ../src/pd_menus.tcl:308 #: ../src/pd_menus.tcl:332 ../src/pd_menus.tcl:345 ../src/pd_menus.tcl:354 #: ../src/pd_menus.tcl:381 ../src/pd_menus.tcl:392 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:431 ../src/pd_menus.tcl:458 msgid "Close" msgstr "Chiudi" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:97 #: ../src/dialog_find.tcl:101 ../src/dialog_find.tcl:103 msgid "Match whole word only" msgstr "Solo parole intere" #: ../src/dialog_find.tcl:92 ../src/dialog_font.tcl:49 #: ../src/dialog_font.tcl:50 ../src/pd-gui.tcl:280 ../src/pd-gui.tcl:283 #: ../src/pd-gui.tcl:286 ../src/pd-gui.tcl:288 ../src/pd-gui.tcl:291 #: ../src/pd_menus.tcl:212 ../src/pd_menus.tcl:258 ../src/pd_menus.tcl:285 #: ../src/pdwindow.tcl:33 msgid "Pd window" msgstr "Finestra Pd" #: ../src/dialog_font.tcl:45 #, fuzzy msgid "Font Properties" msgstr "Proprietà" #: ../src/dialog_font.tcl:46 ../src/dialog_font.tcl:54 #: ../src/dialog_font.tcl:55 #, fuzzy, tcl-format msgid "%s Font" msgstr "Carattere" #: ../src/dialog_font.tcl:61 ../src/dialog_font.tcl:96 #: ../src/dialog_font.tcl:104 ../src/dialog_font.tcl:105 msgid "Font Size" msgstr "Dimensione carattere:" #: ../src/dialog_font.tcl:89 ../src/dialog_font.tcl:108 #: ../src/dialog_font.tcl:116 ../src/dialog_font.tcl:117 msgid "Stretch" msgstr "Allarga/riduci:" #: ../src/dialog_font.tcl:96 ../src/dialog_font.tcl:115 #: ../src/dialog_font.tcl:123 ../src/dialog_font.tcl:124 msgid "X and Y" msgstr "X e Y" #: ../src/dialog_font.tcl:98 ../src/dialog_font.tcl:117 #: ../src/dialog_font.tcl:125 ../src/dialog_font.tcl:126 msgid "X only" msgstr "Solo X" #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:119 #: ../src/dialog_font.tcl:127 ../src/dialog_font.tcl:128 msgid "Y only" msgstr "Solo Y" #: ../src/dialog_gatom.tcl:93 msgid "Atom Box Properties" msgstr "Proprietà Atom Box" #: ../src/dialog_gatom.tcl:99 msgid "Width:" msgstr "Larghezza:" #: ../src/dialog_gatom.tcl:103 msgid "Limits" msgstr "Limiti" #: ../src/dialog_gatom.tcl:107 msgid "Lower:" msgstr "Inferiore:" #: ../src/dialog_gatom.tcl:112 ../src/dialog_gatom.tcl:113 msgid "Upper:" msgstr "Superiore:" #: ../src/dialog_gatom.tcl:116 ../src/dialog_gatom.tcl:121 #: ../src/dialog_iemgui.tcl:600 ../src/dialog_iemgui.tcl:652 #: ../src/dialog_iemgui.tcl:657 msgid "Label" msgstr "Etichetta" #: ../src/dialog_gatom.tcl:124 ../src/dialog_gatom.tcl:129 msgid "Left " msgstr "Sinistra " #: ../src/dialog_gatom.tcl:126 ../src/dialog_gatom.tcl:131 msgid "Right" msgstr "Destra" #: ../src/dialog_gatom.tcl:128 ../src/dialog_gatom.tcl:133 msgid "Top" msgstr "Sopra" #: ../src/dialog_gatom.tcl:130 ../src/dialog_gatom.tcl:135 msgid "Bottom" msgstr "Sotto" #: ../src/dialog_gatom.tcl:137 ../src/dialog_gatom.tcl:145 #: ../src/dialog_iemgui.tcl:574 msgid "Messages" msgstr "Messaggi" #: ../src/dialog_gatom.tcl:141 ../src/dialog_gatom.tcl:149 #: ../src/dialog_iemgui.tcl:578 msgid "Send symbol:" msgstr "Invia simbolo:" #: ../src/dialog_gatom.tcl:147 ../src/dialog_gatom.tcl:155 #: ../src/dialog_iemgui.tcl:585 msgid "Receive symbol:" msgstr "Ricevi simbolo:" #: ../src/dialog_iemgui.tcl:197 msgid "Background color" msgstr "Colore sfondo" #: ../src/dialog_iemgui.tcl:204 msgid "Foreground color" msgstr "Colore primo piano" #: ../src/dialog_iemgui.tcl:211 msgid "Label color" msgstr "Colore etichetta" #: ../src/dialog_iemgui.tcl:272 msgid "Init" msgstr "" #: ../src/dialog_iemgui.tcl:275 ../src/dialog_iemgui.tcl:546 msgid "No init" msgstr "" #: ../src/dialog_iemgui.tcl:287 ../src/dialog_iemgui.tcl:558 msgid "Jump on click" msgstr "Click imposta il valore" #: ../src/dialog_iemgui.tcl:290 ../src/dialog_iemgui.tcl:561 msgid "Steady on click" msgstr "Click incrementa/decrementa" #: ../src/dialog_iemgui.tcl:498 #, tcl-format msgid "%s Properties" msgstr "%s Proprietà" #: ../src/dialog_iemgui.tcl:550 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:84 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:130 ../src/pd_menus.tcl:260 #: ../src/pd_menus.tcl:273 ../src/pd_menus.tcl:288 ../src/pd_menus.tcl:301 #: ../src/pd_menus.tcl:325 ../src/pd_menus.tcl:338 ../src/pd_menus.tcl:355 #: ../src/pd_menus.tcl:382 ../src/pd_menus.tcl:383 ../src/pd_menus.tcl:410 #: ../src/pd_menus.tcl:422 ../src/pd_menus.tcl:449 msgid "Save" msgstr "Salva" #: ../src/dialog_iemgui.tcl:608 msgid "X offset" msgstr "Spostamento X" #: ../src/dialog_iemgui.tcl:611 ../src/dialog_iemgui.tcl:612 msgid "Y offset" msgstr "Spostamento Y" #: ../src/dialog_iemgui.tcl:642 ../src/dialog_iemgui.tcl:645 msgid "Colors" msgstr "Colori" #: ../src/dialog_iemgui.tcl:648 ../src/dialog_iemgui.tcl:651 msgid "Background" msgstr "Colore sfondo" #: ../src/dialog_iemgui.tcl:650 ../src/dialog_iemgui.tcl:654 msgid "Front" msgstr "Primo piano" #: ../src/dialog_iemgui.tcl:662 ../src/dialog_iemgui.tcl:668 msgid "Compose color" msgstr "Crea colore" #: ../src/dialog_iemgui.tcl:682 ../src/dialog_iemgui.tcl:688 msgid "Test label" msgstr "Test etichetta" #: ../src/dialog_midi.tcl:85 msgid "MIDI Settings" msgstr "Settaggi MIDI" #: ../src/dialog_midi.tcl:220 msgid "ALSA MIDI Settings" msgstr "Settaggi ALSA MIDI" #: ../src/dialog_midi.tcl:331 msgid "Use multiple ALSA devices" msgstr "Usa dispositivi ALSA multipli" #: ../src/dialog_midi.tcl:337 msgid "In Ports:" msgstr "Porte Ingresso:" #: ../src/dialog_midi.tcl:340 msgid "Out Ports:" msgstr "Porte Uscita:" #: ../src/g_editor.c:1663 msgid "Discard changes to this window??" msgstr "Cestinare le modifiche apportate in questa finestra?" #: ../src/g_editor.c:1668 msgid "really quit?" msgstr "Uscire veramente?" #: ../src/g_editor.c:1699 msgid "Close this window??" msgstr "Chiudere questa finestra??" #: ../src/pd-gui.tcl:185 ../src/pd-gui.tcl:195 ../src/pd-gui.tcl:203 #: ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:215 ../src/pd-gui.tcl:226 msgid "Associated Files" msgstr "File associati" #: ../src/pd-gui.tcl:186 ../src/pd-gui.tcl:196 ../src/pd-gui.tcl:204 #: ../src/pd-gui.tcl:207 ../src/pd-gui.tcl:216 ../src/pd-gui.tcl:227 msgid "Pd Files" msgstr "File Pd" #: ../src/pd-gui.tcl:187 ../src/pd-gui.tcl:205 ../src/pd-gui.tcl:208 #: ../src/pd-gui.tcl:228 msgid "Max Patch Files" msgstr "Patch Max" #: ../src/pd-gui.tcl:188 ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:209 #: ../src/pd-gui.tcl:229 msgid "Max Text Files" msgstr "File di testo Max" #: ../src/pd-gui.tcl:197 ../src/pd-gui.tcl:217 msgid "Max Patch Files (.pat)" msgstr "Patch Max (.pat)" #: ../src/pd-gui.tcl:198 ../src/pd-gui.tcl:218 msgid "Max Text Files (.mxt)" msgstr "File di testo Max (.mxt)" #: ../src/pd-gui.tcl:270 ../src/pd-gui.tcl:290 #, tcl-format msgid "WARNING: Font family '%s' not found, using default (%s)" msgstr "" "ATTENZIONE: Famiglia di font '%s\" non trovata, uso quella di default (%s)" #: ../src/pd-gui.tcl:278 ../src/pd-gui.tcl:298 #, tcl-format msgid "WARNING: Font weight '%s' not found, using default (%s)" msgstr "ATTENZIONE: Peso '%s' del font non trovato, uso quello di default (%s)" #: ../src/pd-gui.tcl:303 ../src/pd-gui.tcl:323 #, tcl-format msgid "ERROR: %s failed to find font size (%s) that fits into %sx%s!" msgstr "" "ERRORE: %s impossibile trovare la dimensione del font (%s) che entra in %sx%s!" #: ../src/pd-gui.tcl:478 ../src/pd-gui.tcl:483 ../src/pd-gui.tcl:501 msgid "ERROR: 'pd' never showed up, 'pd-gui' quitting!" msgstr "ERRORE: 'pd' non è mai partito, chiudo 'pd-gui'!" #: ../src/pd_menucommands.tcl:19 msgid "Untitled" msgstr "" #: ../src/pd_menucommands.tcl:78 ../src/pd_menucommands.tcl:79 #: ../src/pd_menucommands.tcl:90 msgid "Send Message..." msgstr "Invia un Messaggio..." #: ../src/pd_menucommands.tcl:82 ../src/pd_menucommands.tcl:83 #: ../src/pd_menucommands.tcl:94 ../src/pd_menus.tcl:87 ../src/pd_menus.tcl:88 #: ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:134 ../src/pd_menus.tcl:147 #: ../src/pd_menus.tcl:192 ../src/pd_menus.tcl:193 ../src/pd_menus.tcl:265 #: ../src/pd_menus.tcl:278 ../src/pd_menus.tcl:292 ../src/pd_menus.tcl:305 #: ../src/pd_menus.tcl:329 ../src/pd_menus.tcl:342 ../src/pd_menus.tcl:360 #: ../src/pd_menus.tcl:387 ../src/pd_menus.tcl:414 ../src/pd_menus.tcl:426 #: ../src/pd_menus.tcl:453 ../startup/object_db.tcl:123 msgid "Message" msgstr "Messaggio" #: ../src/pd_menucommands.tcl:108 ../src/pd_menucommands.tcl:111 #: ../src/pd_menus.tcl:112 ../src/pd_menus.tcl:113 ../src/pd_menus.tcl:117 #: ../src/pd_menus.tcl:118 ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:159 #: ../src/pd_menus.tcl:163 ../src/pd_menus.tcl:164 msgid "Font" msgstr "Carattere" #: ../src/pd_menucommands.tcl:123 ../src/pd_menucommands.tcl:126 #: ../src/pd_menus.tcl:138 ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:184 msgid "Preferences" msgstr "Preferenze" #: ../src/pd_menus.tcl:45 msgid "Edit" msgstr "Modifica" #: ../src/pd_menus.tcl:45 msgid "File" msgstr "File" #: ../src/pd_menus.tcl:45 ../src/pdtk_canvas.tcl:48 ../src/pdtk_canvas.tcl:110 #: ../src/pdtk_canvas.tcl:113 msgid "Help" msgstr "Aiuto" #: ../src/pd_menus.tcl:45 msgid "Media" msgstr "Media" #: ../src/pd_menus.tcl:45 msgid "Put" msgstr "Inserisci" #: ../src/pd_menus.tcl:45 msgid "Window" msgstr "Finestra" #: ../src/pd_menus.tcl:81 ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:127 #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:255 ../src/pd_menus.tcl:267 #: ../src/pd_menus.tcl:285 ../src/pd_menus.tcl:298 ../src/pd_menus.tcl:322 #: ../src/pd_menus.tcl:335 ../src/pd_menus.tcl:349 ../src/pd_menus.tcl:376 #: ../src/pd_menus.tcl:380 ../src/pd_menus.tcl:407 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:446 msgid "New" msgstr "Nuovo File" #: ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:128 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:268 #: ../src/pd_menus.tcl:286 ../src/pd_menus.tcl:299 ../src/pd_menus.tcl:323 #: ../src/pd_menus.tcl:336 ../src/pd_menus.tcl:350 ../src/pd_menus.tcl:377 #: ../src/pd_menus.tcl:381 ../src/pd_menus.tcl:408 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:447 ../src/pdtk_canvas.tcl:46 #: ../src/pdtk_canvas.tcl:108 ../src/pdtk_canvas.tcl:111 #: ../src/pdtk_canvas.tcl:128 ../src/pdtk_canvas.tcl:130 #: ../src/pdtk_canvas.tcl:131 ../src/pdtk_canvas.tcl:133 msgid "Open" msgstr "Apri File..." #: ../src/pd_menus.tcl:84 ../src/pd_menus.tcl:85 ../src/pd_menus.tcl:130 #: ../src/pd_menus.tcl:131 ../src/pd_menus.tcl:261 ../src/pd_menus.tcl:274 #: ../src/pd_menus.tcl:289 ../src/pd_menus.tcl:302 ../src/pd_menus.tcl:326 #: ../src/pd_menus.tcl:339 ../src/pd_menus.tcl:356 ../src/pd_menus.tcl:383 #: ../src/pd_menus.tcl:384 ../src/pd_menus.tcl:411 ../src/pd_menus.tcl:423 #: ../src/pd_menus.tcl:450 msgid "Save As..." msgstr "Salva con nome..." #: ../src/pd_menus.tcl:88 ../src/pd_menus.tcl:89 ../src/pd_menus.tcl:134 #: ../src/pd_menus.tcl:135 ../src/pd_menus.tcl:267 ../src/pd_menus.tcl:280 #: ../src/pd_menus.tcl:293 ../src/pd_menus.tcl:306 ../src/pd_menus.tcl:330 #: ../src/pd_menus.tcl:343 ../src/pd_menus.tcl:362 ../src/pd_menus.tcl:388 #: ../src/pd_menus.tcl:389 ../src/pd_menus.tcl:415 ../src/pd_menus.tcl:427 #: ../src/pd_menus.tcl:454 msgid "Print..." msgstr "Stampa..." #: ../src/pd_menus.tcl:93 ../src/pd_menus.tcl:94 ../src/pd_menus.tcl:139 #: ../src/pd_menus.tcl:140 msgid "Undo" msgstr "Annulla" #: ../src/pd_menus.tcl:95 ../src/pd_menus.tcl:96 ../src/pd_menus.tcl:141 #: ../src/pd_menus.tcl:142 msgid "Redo" msgstr "Ripristina" #: ../src/pd_menus.tcl:98 ../src/pd_menus.tcl:99 ../src/pd_menus.tcl:144 #: ../src/pd_menus.tcl:145 msgid "Cut" msgstr "Taglia" #: ../src/pd_menus.tcl:104 ../src/pd_menus.tcl:105 ../src/pd_menus.tcl:150 #: ../src/pd_menus.tcl:151 msgid "Duplicate" msgstr "Duplica" #: ../src/pd_menus.tcl:106 ../src/pd_menus.tcl:107 ../src/pd_menus.tcl:152 #: ../src/pd_menus.tcl:153 msgid "Select All" msgstr "Seleziona tutto" #: ../src/pd_menus.tcl:110 ../src/pd_menus.tcl:111 ../src/pd_menus.tcl:115 #: ../src/pd_menus.tcl:116 ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:157 #: ../src/pd_menus.tcl:161 ../src/pd_menus.tcl:162 msgid "Text Editor" msgstr "Editor di Testo..." #: ../src/pd_menus.tcl:120 ../src/pd_menus.tcl:121 ../src/pd_menus.tcl:166 #: ../src/pd_menus.tcl:167 msgid "Tidy Up" msgstr "Allinea elementi" #: ../src/pd_menus.tcl:122 ../src/pd_menus.tcl:123 ../src/pd_menus.tcl:168 #: ../src/pd_menus.tcl:169 msgid "Toggle Console" msgstr "Mostra/Nascondi console" #: ../src/pd_menus.tcl:124 ../src/pd_menus.tcl:125 ../src/pd_menus.tcl:170 #: ../src/pd_menus.tcl:171 msgid "Clear Console" msgstr "Pulisci console" #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:174 #: ../src/pd_menus.tcl:175 msgid "Edit Mode" msgstr "Modalità modifica" #: ../src/pd_menus.tcl:145 ../src/pd_menus.tcl:190 ../src/pd_menus.tcl:191 msgid "Object" msgstr "Oggetto" #: ../src/pd_menus.tcl:149 ../src/pd_menus.tcl:194 ../src/pd_menus.tcl:195 msgid "Number" msgstr "Numero" #: ../src/pd_menus.tcl:151 ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:197 msgid "Symbol" msgstr "Simbolo" #: ../src/pd_menus.tcl:153 ../src/pd_menus.tcl:198 ../src/pd_menus.tcl:199 msgid "Comment" msgstr "Commento" #: ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:201 ../src/pd_menus.tcl:202 msgid "Bang" msgstr "Bang" #: ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:203 ../src/pd_menus.tcl:204 msgid "Toggle" msgstr "Toggle" #: ../src/pd_menus.tcl:160 ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:206 msgid "Number2" msgstr "Numero2" #: ../src/pd_menus.tcl:162 ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:208 msgid "Vslider" msgstr "Slider verticale" #: ../src/pd_menus.tcl:164 ../src/pd_menus.tcl:209 ../src/pd_menus.tcl:210 msgid "Hslider" msgstr "Slider orizzontale" #: ../src/pd_menus.tcl:166 ../src/pd_menus.tcl:211 ../src/pd_menus.tcl:212 msgid "Vradio" msgstr "Radio verticale" #: ../src/pd_menus.tcl:168 ../src/pd_menus.tcl:213 ../src/pd_menus.tcl:214 msgid "Hradio" msgstr "Radio orizzontale" #: ../src/pd_menus.tcl:170 ../src/pd_menus.tcl:215 ../src/pd_menus.tcl:216 msgid "VU Meter" msgstr "Indicatore VU" #: ../src/pd_menus.tcl:172 ../src/pd_menus.tcl:217 ../src/pd_menus.tcl:218 msgid "Canvas" msgstr "Tavolozza" #: ../src/pd_menus.tcl:175 ../src/pd_menus.tcl:220 ../src/pd_menus.tcl:221 msgid "Graph" msgstr "Grafico" #: ../src/pd_menus.tcl:176 ../src/pd_menus.tcl:221 ../src/pd_menus.tcl:222 msgid "Array" msgstr "Array" #: ../src/pd_menus.tcl:181 ../src/pd_menus.tcl:226 ../src/pd_menus.tcl:227 msgid "Find..." msgstr "Trova" #: ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:228 ../src/pd_menus.tcl:229 msgid "Find Again" msgstr "Cerca Ancora" #: ../src/pd_menus.tcl:185 ../src/pd_menus.tcl:230 ../src/pd_menus.tcl:231 msgid "Find Last Error" msgstr "Trova l'ultimo errore" #: ../src/pd_menus.tcl:191 ../src/pd_menus.tcl:236 ../src/pd_menus.tcl:237 msgid "DSP On" msgstr "" #: ../src/pd_menus.tcl:193 ../src/pd_menus.tcl:238 ../src/pd_menus.tcl:239 msgid "DSP Off" msgstr "" #: ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:242 ../src/pd_menus.tcl:269 msgid "Test Audio and MIDI..." msgstr "Test Audio e MIDI" #: ../src/pd_menus.tcl:198 ../src/pd_menus.tcl:244 ../src/pd_menus.tcl:271 msgid "Load Meter" msgstr "Misura carico cpu" #: ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:251 ../src/pd_menus.tcl:278 msgid "Minimize" msgstr "Minimizza" #: ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:253 ../src/pd_menus.tcl:280 msgid "Zoom" msgstr "" #: ../src/pd_menus.tcl:210 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:283 msgid "Parent Window" msgstr "Finestra parent" #: ../src/pd_menus.tcl:216 ../src/pd_menus.tcl:262 ../src/pd_menus.tcl:289 msgid "Bring All to Front" msgstr "Porta tutto in primo piano" #: ../src/pd_menus.tcl:224 ../src/pd_menus.tcl:241 ../src/pd_menus.tcl:253 #: ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:297 ../src/pd_menus.tcl:335 #: ../src/pd_menus.tcl:362 msgid "About Pd" msgstr "Informazioni su Pd..." #: ../src/pd_menus.tcl:227 ../src/pd_menus.tcl:273 ../src/pd_menus.tcl:300 msgid "HTML Manual..." msgstr "Manuale HTML..." #: ../src/pd_menus.tcl:229 ../src/pd_menus.tcl:275 ../src/pd_menus.tcl:302 msgid "Browser..." msgstr "" #: ../src/pd_menus.tcl:248 ../src/pd_menus.tcl:260 ../src/pd_menus.tcl:342 #: ../src/pd_menus.tcl:369 msgid "Preferences..." msgstr "Preferenze..." #: ../src/pd_menus.tcl:257 ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:352 #: ../src/pd_menus.tcl:379 msgid "Open Recent" msgstr "Apri recenti" #: ../src/pd_menus.tcl:263 msgid "Audio Settings..." msgstr "Settaggi audio..." #: ../src/pd_menus.tcl:265 msgid "MIDI Settings..." msgstr "Settaggi MIDI..." #: ../src/pd_menus.tcl:296 ../src/pd_menus.tcl:309 ../src/pd_menus.tcl:333 #: ../src/pd_menus.tcl:346 ../src/pd_menus.tcl:393 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:432 ../src/pd_menus.tcl:459 msgid "Quit" msgstr "Esci" #: ../src/pd_menus.tcl:304 ../src/pd_menus.tcl:331 msgid "Clear Menu" msgstr "Pulisci menu" #: ../src/pdtk_canvas.tcl:44 ../src/pdtk_canvas.tcl:106 #: ../src/pdtk_canvas.tcl:109 ../src/pdtk_canvas.tcl:123 #: ../src/pdtk_canvas.tcl:125 ../src/pdtk_canvas.tcl:126 #: ../src/pdtk_canvas.tcl:128 msgid "Properties" msgstr "Proprietà" #: ../src/pdwindow.tcl:43 msgid "DSP" msgstr "" #: ../startup/object_db.tcl:113 msgid "Signal" msgstr "Segnali" #: ../startup/object_db.tcl:114 msgid "Generators" msgstr "Generatori" #: ../startup/object_db.tcl:115 msgid "Filters" msgstr "Filtri" #: ../startup/object_db.tcl:116 ../startup/object_db.tcl:124 msgid "Math" msgstr "Matematica" #: ../startup/object_db.tcl:117 ../startup/object_db.tcl:125 msgid "I/O" msgstr "Input/Output" #: ../startup/object_db.tcl:118 ../startup/object_db.tcl:126 msgid "Sampling" msgstr "Campionamento" #: ../startup/object_db.tcl:119 ../startup/object_db.tcl:128 msgid "Routing" msgstr "" #: ../startup/object_db.tcl:120 ../startup/object_db.tcl:129 msgid "Others" msgstr "Altri" #: ../startup/object_db.tcl:127 msgid "GUI" msgstr "" pd-0.46-7/po/af.po0000664000175000017500000006014012160204055011734 0ustar mspmsp# Afrikaans translation of Pure Data # This file is put in the public domain. # Petri Jooste , 2004. # msgid "" msgstr "" "Project-Id-Version: Pure Data 2.0.8pre1\n" "Report-Msgid-Bugs-To: pd-dev@iem.at\n" "POT-Creation-Date: 2009-08-27 10:01-0400\n" "PO-Revision-Date: 2004-03-17 14:45+0200\n" "Last-Translator: Petri Jooste \n" "Language-Team: Afrikaans \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #, fuzzy msgid "Undo duplicate" msgstr "Datum" msgid "Undo paste" msgstr "" msgid "Undo motion" msgstr "" msgid "Undo cut" msgstr "" msgid "Undo disconnect" msgstr "" msgid "Undo connect" msgstr "" msgid "Undo clear" msgstr "" msgid "Undo typing" msgstr "" msgid "Discard changes to '%s'?" msgstr "" msgid "Do you want to save the changes you made in '%s'?" msgstr "" #: ../src/dialog_array.tcl:115 ../src/dialog_array.tcl:117 #: ../src/pd_menus.tcl:100 ../src/pd_menus.tcl:101 ../src/pd_menus.tcl:146 #: ../src/pd_menus.tcl:147 msgid "Copy" msgstr "Kopieer" #: ../src/dialog_array.tcl:118 ../src/dialog_array.tcl:120 #: ../src/pd_menus.tcl:102 ../src/pd_menus.tcl:103 ../src/pd_menus.tcl:148 #: ../src/pd_menus.tcl:149 #, fuzzy msgid "Paste" msgstr "Datum" #: ../src/dialog_array.tcl:264 ../src/dialog_array.tcl:266 msgid "Array Properties" msgstr "" #: ../src/dialog_array.tcl:270 ../src/dialog_array.tcl:272 #, fuzzy msgid "Name:" msgstr "Naam" #: ../src/dialog_array.tcl:276 ../src/dialog_array.tcl:278 #: ../src/dialog_canvas.tcl:178 ../src/dialog_canvas.tcl:193 #: ../src/dialog_iemgui.tcl:619 ../src/dialog_iemgui.tcl:621 #, fuzzy msgid "Size:" msgstr "Grootte" #: ../src/dialog_array.tcl:280 ../src/dialog_array.tcl:282 #, fuzzy msgid "Save contents" msgstr "Inhoud" #: ../src/dialog_array.tcl:284 ../src/dialog_array.tcl:286 msgid "Draw as:" msgstr "" #: ../src/dialog_array.tcl:287 ../src/dialog_array.tcl:289 #, fuzzy msgid "Points" msgstr "Poort" #: ../src/dialog_array.tcl:289 ../src/dialog_array.tcl:291 #, fuzzy msgid "Polygon" msgstr "Pole" #: ../src/dialog_array.tcl:291 ../src/dialog_array.tcl:293 msgid "Bezier curve" msgstr "" #: ../src/dialog_array.tcl:297 ../src/dialog_array.tcl:299 msgid "Put array into:" msgstr "" #: ../src/dialog_array.tcl:300 ../src/dialog_array.tcl:302 msgid "New graph" msgstr "" #: ../src/dialog_array.tcl:302 ../src/dialog_array.tcl:304 #, fuzzy msgid "Last graph" msgstr "Laaste Verander..." #: ../src/dialog_array.tcl:306 ../src/dialog_array.tcl:308 #, fuzzy msgid "Delete array" msgstr "Uitwis" #: ../src/dialog_array.tcl:312 ../src/dialog_array.tcl:314 #, fuzzy msgid "Open List View..." msgstr "/Skommel lys" #: ../src/dialog_array.tcl:319 ../src/dialog_array.tcl:321 #: ../src/dialog_audio.tcl:136 ../src/dialog_canvas.tcl:205 #: ../src/dialog_font.tcl:51 ../src/dialog_gatom.tcl:153 #: ../src/dialog_gatom.tcl:161 ../src/dialog_iemgui.tcl:742 #: ../src/dialog_iemgui.tcl:748 ../src/dialog_midi.tcl:91 #: ../src/dialog_midi.tcl:226 #, fuzzy msgid "Cancel" msgstr "Kanselleer" #: ../src/dialog_array.tcl:321 ../src/dialog_array.tcl:323 #: ../src/dialog_audio.tcl:138 ../src/dialog_canvas.tcl:207 #: ../src/dialog_gatom.tcl:156 ../src/dialog_gatom.tcl:164 #: ../src/dialog_iemgui.tcl:745 ../src/dialog_iemgui.tcl:751 #: ../src/dialog_midi.tcl:93 ../src/dialog_midi.tcl:228 #, fuzzy msgid "Apply" msgstr "Pas toe" #: ../src/dialog_array.tcl:323 ../src/dialog_array.tcl:325 #: ../src/dialog_audio.tcl:140 ../src/dialog_canvas.tcl:209 #: ../src/dialog_font.tcl:53 ../src/dialog_font.tcl:92 #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:101 #: ../src/dialog_gatom.tcl:159 ../src/dialog_gatom.tcl:167 #: ../src/dialog_iemgui.tcl:748 ../src/dialog_iemgui.tcl:754 #: ../src/dialog_midi.tcl:95 ../src/dialog_midi.tcl:230 msgid "OK" msgstr "" #: ../src/dialog_audio.tcl:130 msgid "Audio Settings" msgstr "" #: ../src/dialog_audio.tcl:142 msgid "Save All Settings" msgstr "" #: ../src/dialog_audio.tcl:151 msgid "Sample rate:" msgstr "" #: ../src/dialog_audio.tcl:153 msgid "Delay (msec):" msgstr "" #: ../src/dialog_audio.tcl:158 msgid "Use callbacks" msgstr "" #: ../src/dialog_audio.tcl:166 ../src/dialog_midi.tcl:105 #: ../src/dialog_midi.tcl:241 msgid "Input device 1:" msgstr "" #: ../src/dialog_audio.tcl:169 ../src/dialog_audio.tcl:183 #: ../src/dialog_audio.tcl:198 ../src/dialog_audio.tcl:213 #: ../src/dialog_audio.tcl:232 ../src/dialog_audio.tcl:250 #: ../src/dialog_audio.tcl:265 ../src/dialog_audio.tcl:280 #, fuzzy msgid "Channels:" msgstr "Kanselleer" #: ../src/dialog_audio.tcl:179 ../src/dialog_midi.tcl:115 #: ../src/dialog_midi.tcl:251 msgid "Input device 2:" msgstr "" #: ../src/dialog_audio.tcl:194 ../src/dialog_midi.tcl:127 #: ../src/dialog_midi.tcl:263 msgid "Input device 3:" msgstr "" #: ../src/dialog_audio.tcl:209 ../src/dialog_midi.tcl:139 #: ../src/dialog_midi.tcl:275 msgid "Input device 4:" msgstr "" #: ../src/dialog_audio.tcl:223 ../src/dialog_midi.tcl:150 #: ../src/dialog_midi.tcl:286 msgid "Output device 1:" msgstr "" #: ../src/dialog_audio.tcl:226 msgid "(same as input device) .............. " msgstr "" #: ../src/dialog_audio.tcl:246 ../src/dialog_midi.tcl:160 #: ../src/dialog_midi.tcl:296 msgid "Output device 2:" msgstr "" #: ../src/dialog_audio.tcl:261 ../src/dialog_midi.tcl:171 #: ../src/dialog_midi.tcl:307 msgid "Output device 3:" msgstr "" #: ../src/dialog_audio.tcl:276 ../src/dialog_midi.tcl:182 #: ../src/dialog_midi.tcl:318 msgid "Output device 4:" msgstr "" #: ../src/dialog_audio.tcl:291 ../src/dialog_midi.tcl:195 msgid "Use multiple devices" msgstr "" #: ../src/dialog_canvas.tcl:142 msgid "Canvas Properties" msgstr "" #: ../src/dialog_canvas.tcl:146 #, fuzzy msgid "Scale" msgstr "Stoor" #: ../src/dialog_canvas.tcl:150 msgid "X units per pixel:" msgstr "" #: ../src/dialog_canvas.tcl:155 msgid "Y units per pixel:" msgstr "" #: ../src/dialog_canvas.tcl:159 msgid "Appearance on parent patch" msgstr "" #: ../src/dialog_canvas.tcl:161 msgid "Graph-On-Parent" msgstr "" #: ../src/dialog_canvas.tcl:165 msgid "Hide object name and arguments" msgstr "" #: ../src/dialog_canvas.tcl:170 msgid "Range and size" msgstr "" #: ../src/dialog_canvas.tcl:174 msgid "X range, from" msgstr "" #: ../src/dialog_canvas.tcl:176 ../src/dialog_canvas.tcl:191 msgid "to" msgstr "" #: ../src/dialog_canvas.tcl:180 ../src/dialog_canvas.tcl:195 #, fuzzy msgid "Margin:" msgstr "Merk voor:" #: ../src/dialog_canvas.tcl:189 msgid "Y range, from" msgstr "" #: ../src/dialog_find.tcl:63 ../src/dialog_find.tcl:66 #: ../src/dialog_find.tcl:79 ../src/dialog_find.tcl:80 #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:85 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:101 #: ../src/dialog_find.tcl:105 ../src/dialog_find.tcl:107 #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Find" msgstr "Soek:" #: ../src/dialog_find.tcl:70 ../src/dialog_find.tcl:73 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:91 #: ../src/dialog_find.tcl:93 #, fuzzy msgid "Search in" msgstr "Volgrote teks soektog..." #: ../src/dialog_find.tcl:72 ../src/dialog_find.tcl:75 #: ../src/dialog_find.tcl:89 ../src/dialog_find.tcl:93 #: ../src/dialog_find.tcl:95 #, fuzzy msgid "for:" msgstr "Poort:" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:90 #: ../src/dialog_find.tcl:104 ../src/dialog_find.tcl:108 #: ../src/dialog_find.tcl:110 ../src/pd_menus.tcl:86 ../src/pd_menus.tcl:87 #: ../src/pd_menus.tcl:132 ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:259 #: ../src/pd_menus.tcl:272 ../src/pd_menus.tcl:295 ../src/pd_menus.tcl:308 #: ../src/pd_menus.tcl:332 ../src/pd_menus.tcl:345 ../src/pd_menus.tcl:354 #: ../src/pd_menus.tcl:381 ../src/pd_menus.tcl:392 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:431 ../src/pd_menus.tcl:458 #, fuzzy msgid "Close" msgstr "Toemaak" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:97 #: ../src/dialog_find.tcl:101 ../src/dialog_find.tcl:103 msgid "Match whole word only" msgstr "" #: ../src/dialog_find.tcl:92 ../src/dialog_font.tcl:49 #: ../src/dialog_font.tcl:50 ../src/pd-gui.tcl:280 ../src/pd-gui.tcl:283 #: ../src/pd-gui.tcl:286 ../src/pd-gui.tcl:288 ../src/pd-gui.tcl:291 #: ../src/pd_menus.tcl:212 ../src/pd_menus.tcl:258 ../src/pd_menus.tcl:285 #: ../src/pdwindow.tcl:33 #, fuzzy msgid "Pd window" msgstr "Description=Stuur Lêer" #: ../src/dialog_font.tcl:45 msgid "Font Properties" msgstr "" #: ../src/dialog_font.tcl:46 ../src/dialog_font.tcl:54 #: ../src/dialog_font.tcl:55 #, fuzzy, tcl-format msgid "%s Font" msgstr "Font:" #: ../src/dialog_font.tcl:61 ../src/dialog_font.tcl:96 #: ../src/dialog_font.tcl:104 ../src/dialog_font.tcl:105 #, fuzzy msgid "Font Size" msgstr "Font:" #: ../src/dialog_font.tcl:89 ../src/dialog_font.tcl:108 #: ../src/dialog_font.tcl:116 ../src/dialog_font.tcl:117 msgid "Stretch" msgstr "" #: ../src/dialog_font.tcl:96 ../src/dialog_font.tcl:115 #: ../src/dialog_font.tcl:123 ../src/dialog_font.tcl:124 msgid "X and Y" msgstr "" #: ../src/dialog_font.tcl:98 ../src/dialog_font.tcl:117 #: ../src/dialog_font.tcl:125 ../src/dialog_font.tcl:126 msgid "X only" msgstr "" #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:119 #: ../src/dialog_font.tcl:127 ../src/dialog_font.tcl:128 msgid "Y only" msgstr "" #: ../src/dialog_gatom.tcl:93 msgid "Atom Box Properties" msgstr "" #: ../src/dialog_gatom.tcl:99 msgid "Width:" msgstr "" #: ../src/dialog_gatom.tcl:103 #, fuzzy msgid "Limits" msgstr "Maatjie Lyste" #: ../src/dialog_gatom.tcl:107 msgid "Lower:" msgstr "" #: ../src/dialog_gatom.tcl:112 ../src/dialog_gatom.tcl:113 #, fuzzy msgid "Upper:" msgstr "Gebruiker" #: ../src/dialog_gatom.tcl:116 ../src/dialog_gatom.tcl:121 #: ../src/dialog_iemgui.tcl:600 ../src/dialog_iemgui.tcl:652 #: ../src/dialog_iemgui.tcl:657 msgid "Label" msgstr "" #: ../src/dialog_gatom.tcl:124 ../src/dialog_gatom.tcl:129 #, fuzzy msgid "Left " msgstr "Links" #: ../src/dialog_gatom.tcl:126 ../src/dialog_gatom.tcl:131 msgid "Right" msgstr "Regs" #: ../src/dialog_gatom.tcl:128 ../src/dialog_gatom.tcl:133 msgid "Top" msgstr "Bo" #: ../src/dialog_gatom.tcl:130 ../src/dialog_gatom.tcl:135 msgid "Bottom" msgstr "Onder" #: ../src/dialog_gatom.tcl:137 ../src/dialog_gatom.tcl:145 #: ../src/dialog_iemgui.tcl:574 #, fuzzy msgid "Messages" msgstr "Boodskap" #: ../src/dialog_gatom.tcl:141 ../src/dialog_gatom.tcl:149 #: ../src/dialog_iemgui.tcl:578 msgid "Send symbol:" msgstr "" #: ../src/dialog_gatom.tcl:147 ../src/dialog_gatom.tcl:155 #: ../src/dialog_iemgui.tcl:585 #, fuzzy msgid "Receive symbol:" msgstr "Ontvanger" #: ../src/dialog_iemgui.tcl:197 #, fuzzy msgid "Background color" msgstr "Agtergrond:" #: ../src/dialog_iemgui.tcl:204 #, fuzzy msgid "Foreground color" msgstr "Voorgrond:" #: ../src/dialog_iemgui.tcl:211 #, fuzzy msgid "Label color" msgstr "Die kleure aandui:" #: ../src/dialog_iemgui.tcl:272 #, fuzzy msgid "Init" msgstr "Nooi" #: ../src/dialog_iemgui.tcl:275 ../src/dialog_iemgui.tcl:546 msgid "No init" msgstr "" #: ../src/dialog_iemgui.tcl:287 ../src/dialog_iemgui.tcl:558 msgid "Jump on click" msgstr "" #: ../src/dialog_iemgui.tcl:290 ../src/dialog_iemgui.tcl:561 msgid "Steady on click" msgstr "" #: ../src/dialog_iemgui.tcl:498 #, tcl-format msgid "%s Properties" msgstr "" #: ../src/dialog_iemgui.tcl:550 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:84 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:130 ../src/pd_menus.tcl:260 #: ../src/pd_menus.tcl:273 ../src/pd_menus.tcl:288 ../src/pd_menus.tcl:301 #: ../src/pd_menus.tcl:325 ../src/pd_menus.tcl:338 ../src/pd_menus.tcl:355 #: ../src/pd_menus.tcl:382 ../src/pd_menus.tcl:383 ../src/pd_menus.tcl:410 #: ../src/pd_menus.tcl:422 ../src/pd_menus.tcl:449 #, fuzzy msgid "Save" msgstr "Stoor" #: ../src/dialog_iemgui.tcl:608 msgid "X offset" msgstr "" #: ../src/dialog_iemgui.tcl:611 ../src/dialog_iemgui.tcl:612 msgid "Y offset" msgstr "" #: ../src/dialog_iemgui.tcl:642 ../src/dialog_iemgui.tcl:645 msgid "Colors" msgstr "Kleure" #: ../src/dialog_iemgui.tcl:648 ../src/dialog_iemgui.tcl:651 #, fuzzy msgid "Background" msgstr "Agtergrond:" #: ../src/dialog_iemgui.tcl:650 ../src/dialog_iemgui.tcl:654 #, fuzzy msgid "Front" msgstr "Font:" #: ../src/dialog_iemgui.tcl:662 ../src/dialog_iemgui.tcl:668 msgid "Compose color" msgstr "" #: ../src/dialog_iemgui.tcl:682 ../src/dialog_iemgui.tcl:688 #, fuzzy msgid "Test label" msgstr "Toets almal" #: ../src/dialog_midi.tcl:85 msgid "MIDI Settings" msgstr "" #: ../src/dialog_midi.tcl:220 msgid "ALSA MIDI Settings" msgstr "" #: ../src/dialog_midi.tcl:331 msgid "Use multiple ALSA devices" msgstr "" #: ../src/dialog_midi.tcl:337 msgid "In Ports:" msgstr "" #: ../src/dialog_midi.tcl:340 msgid "Out Ports:" msgstr "" #: ../src/g_editor.c:1663 msgid "Discard changes to this window??" msgstr "" #: ../src/g_editor.c:1668 msgid "really quit?" msgstr "" #: ../src/g_editor.c:1699 #, fuzzy msgid "Close this window??" msgstr "Twm: Tab Vensterbestuurder" #: ../src/pd-gui.tcl:185 ../src/pd-gui.tcl:195 ../src/pd-gui.tcl:203 #: ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:215 ../src/pd-gui.tcl:226 msgid "Associated Files" msgstr "" #: ../src/pd-gui.tcl:186 ../src/pd-gui.tcl:196 ../src/pd-gui.tcl:204 #: ../src/pd-gui.tcl:207 ../src/pd-gui.tcl:216 ../src/pd-gui.tcl:227 #, fuzzy msgid "Pd Files" msgstr "Lêer" #: ../src/pd-gui.tcl:187 ../src/pd-gui.tcl:205 ../src/pd-gui.tcl:208 #: ../src/pd-gui.tcl:228 msgid "Max Patch Files" msgstr "" #: ../src/pd-gui.tcl:188 ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:209 #: ../src/pd-gui.tcl:229 msgid "Max Text Files" msgstr "" #: ../src/pd-gui.tcl:197 ../src/pd-gui.tcl:217 msgid "Max Patch Files (.pat)" msgstr "" #: ../src/pd-gui.tcl:198 ../src/pd-gui.tcl:218 msgid "Max Text Files (.mxt)" msgstr "" #: ../src/pd-gui.tcl:270 ../src/pd-gui.tcl:290 #, tcl-format msgid "WARNING: Font family '%s' not found, using default (%s)" msgstr "" #: ../src/pd-gui.tcl:278 ../src/pd-gui.tcl:298 #, tcl-format msgid "WARNING: Font weight '%s' not found, using default (%s)" msgstr "" #: ../src/pd-gui.tcl:303 ../src/pd-gui.tcl:323 #, tcl-format msgid "ERROR: %s failed to find font size (%s) that fits into %sx%s!" msgstr "" #: ../src/pd-gui.tcl:478 ../src/pd-gui.tcl:483 ../src/pd-gui.tcl:501 msgid "ERROR: 'pd' never showed up, 'pd-gui' quitting!" msgstr "" #: ../src/pd_menucommands.tcl:19 msgid "Untitled" msgstr "" #: ../src/pd_menucommands.tcl:78 ../src/pd_menucommands.tcl:79 #: ../src/pd_menucommands.tcl:90 #, fuzzy msgid "Send Message..." msgstr "Biep op fout" #: ../src/pd_menucommands.tcl:82 ../src/pd_menucommands.tcl:83 #: ../src/pd_menucommands.tcl:94 ../src/pd_menus.tcl:87 ../src/pd_menus.tcl:88 #: ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:134 ../src/pd_menus.tcl:147 #: ../src/pd_menus.tcl:192 ../src/pd_menus.tcl:193 ../src/pd_menus.tcl:265 #: ../src/pd_menus.tcl:278 ../src/pd_menus.tcl:292 ../src/pd_menus.tcl:305 #: ../src/pd_menus.tcl:329 ../src/pd_menus.tcl:342 ../src/pd_menus.tcl:360 #: ../src/pd_menus.tcl:387 ../src/pd_menus.tcl:414 ../src/pd_menus.tcl:426 #: ../src/pd_menus.tcl:453 ../startup/object_db.tcl:123 #, fuzzy msgid "Message" msgstr "Boodskap" #: ../src/pd_menucommands.tcl:108 ../src/pd_menucommands.tcl:111 #: ../src/pd_menus.tcl:112 ../src/pd_menus.tcl:113 ../src/pd_menus.tcl:117 #: ../src/pd_menus.tcl:118 ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:159 #: ../src/pd_menus.tcl:163 ../src/pd_menus.tcl:164 #, fuzzy msgid "Font" msgstr "Font:" #: ../src/pd_menucommands.tcl:123 ../src/pd_menucommands.tcl:126 #: ../src/pd_menus.tcl:138 ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:184 #, fuzzy msgid "Preferences" msgstr "Voorkeure..." #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Edit" msgstr "/Laai" #: ../src/pd_menus.tcl:45 #, fuzzy msgid "File" msgstr "Lêer" #: ../src/pd_menus.tcl:45 ../src/pdtk_canvas.tcl:48 ../src/pdtk_canvas.tcl:110 #: ../src/pdtk_canvas.tcl:113 #, fuzzy msgid "Help" msgstr "hulp" #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Media" msgstr "Name=Makedoniese" #: ../src/pd_menus.tcl:45 msgid "Put" msgstr "" #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Window" msgstr "" #: ../src/pd_menus.tcl:81 ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:127 #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:255 ../src/pd_menus.tcl:267 #: ../src/pd_menus.tcl:285 ../src/pd_menus.tcl:298 ../src/pd_menus.tcl:322 #: ../src/pd_menus.tcl:335 ../src/pd_menus.tcl:349 ../src/pd_menus.tcl:376 #: ../src/pd_menus.tcl:380 ../src/pd_menus.tcl:407 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:446 #, fuzzy msgid "New" msgstr "Nuwe" #: ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:128 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:268 #: ../src/pd_menus.tcl:286 ../src/pd_menus.tcl:299 ../src/pd_menus.tcl:323 #: ../src/pd_menus.tcl:336 ../src/pd_menus.tcl:350 ../src/pd_menus.tcl:377 #: ../src/pd_menus.tcl:381 ../src/pd_menus.tcl:408 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:447 ../src/pdtk_canvas.tcl:46 #: ../src/pdtk_canvas.tcl:108 ../src/pdtk_canvas.tcl:111 #: ../src/pdtk_canvas.tcl:128 ../src/pdtk_canvas.tcl:130 #: ../src/pdtk_canvas.tcl:131 ../src/pdtk_canvas.tcl:133 #, fuzzy msgid "Open" msgstr "Open" #: ../src/pd_menus.tcl:84 ../src/pd_menus.tcl:85 ../src/pd_menus.tcl:130 #: ../src/pd_menus.tcl:131 ../src/pd_menus.tcl:261 ../src/pd_menus.tcl:274 #: ../src/pd_menus.tcl:289 ../src/pd_menus.tcl:302 ../src/pd_menus.tcl:326 #: ../src/pd_menus.tcl:339 ../src/pd_menus.tcl:356 ../src/pd_menus.tcl:383 #: ../src/pd_menus.tcl:384 ../src/pd_menus.tcl:411 ../src/pd_menus.tcl:423 #: ../src/pd_menus.tcl:450 #, fuzzy msgid "Save As..." msgstr "Stoor As" #: ../src/pd_menus.tcl:88 ../src/pd_menus.tcl:89 ../src/pd_menus.tcl:134 #: ../src/pd_menus.tcl:135 ../src/pd_menus.tcl:267 ../src/pd_menus.tcl:280 #: ../src/pd_menus.tcl:293 ../src/pd_menus.tcl:306 ../src/pd_menus.tcl:330 #: ../src/pd_menus.tcl:343 ../src/pd_menus.tcl:362 ../src/pd_menus.tcl:388 #: ../src/pd_menus.tcl:389 ../src/pd_menus.tcl:415 ../src/pd_menus.tcl:427 #: ../src/pd_menus.tcl:454 #, fuzzy msgid "Print..." msgstr "/Laai" #: ../src/pd_menus.tcl:93 ../src/pd_menus.tcl:94 ../src/pd_menus.tcl:139 #: ../src/pd_menus.tcl:140 #, fuzzy msgid "Undo" msgstr "Uganda " #: ../src/pd_menus.tcl:95 ../src/pd_menus.tcl:96 ../src/pd_menus.tcl:141 #: ../src/pd_menus.tcl:142 #, fuzzy msgid "Redo" msgstr "Rede" #: ../src/pd_menus.tcl:98 ../src/pd_menus.tcl:99 ../src/pd_menus.tcl:144 #: ../src/pd_menus.tcl:145 msgid "Cut" msgstr "" #: ../src/pd_menus.tcl:104 ../src/pd_menus.tcl:105 ../src/pd_menus.tcl:150 #: ../src/pd_menus.tcl:151 #, fuzzy msgid "Duplicate" msgstr "Datum" #: ../src/pd_menus.tcl:106 ../src/pd_menus.tcl:107 ../src/pd_menus.tcl:152 #: ../src/pd_menus.tcl:153 #, fuzzy msgid "Select All" msgstr "Uitvee Alle" #: ../src/pd_menus.tcl:110 ../src/pd_menus.tcl:111 ../src/pd_menus.tcl:115 #: ../src/pd_menus.tcl:116 ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:157 #: ../src/pd_menus.tcl:161 ../src/pd_menus.tcl:162 #, fuzzy msgid "Text Editor" msgstr "Kleure" #: ../src/pd_menus.tcl:120 ../src/pd_menus.tcl:121 ../src/pd_menus.tcl:166 #: ../src/pd_menus.tcl:167 msgid "Tidy Up" msgstr "" #: ../src/pd_menus.tcl:122 ../src/pd_menus.tcl:123 ../src/pd_menus.tcl:168 #: ../src/pd_menus.tcl:169 msgid "Toggle Console" msgstr "" #: ../src/pd_menus.tcl:124 ../src/pd_menus.tcl:125 ../src/pd_menus.tcl:170 #: ../src/pd_menus.tcl:171 #, fuzzy msgid "Clear Console" msgstr "Maak lys skoon" #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:174 #: ../src/pd_menus.tcl:175 #, fuzzy msgid "Edit Mode" msgstr "Redigeermodus" #: ../src/pd_menus.tcl:145 ../src/pd_menus.tcl:190 ../src/pd_menus.tcl:191 msgid "Object" msgstr "" #: ../src/pd_menus.tcl:149 ../src/pd_menus.tcl:194 ../src/pd_menus.tcl:195 #, fuzzy msgid "Number" msgstr "$ Nommer" #: ../src/pd_menus.tcl:151 ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:197 msgid "Symbol" msgstr "" #: ../src/pd_menus.tcl:153 ../src/pd_menus.tcl:198 ../src/pd_menus.tcl:199 #, fuzzy msgid "Comment" msgstr "Instruksie" #: ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:201 ../src/pd_menus.tcl:202 #, fuzzy msgid "Bang" msgstr "Bhutan" #: ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:203 ../src/pd_menus.tcl:204 #, fuzzy msgid "Toggle" msgstr "Togo" #: ../src/pd_menus.tcl:160 ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:206 #, fuzzy msgid "Number2" msgstr "$ Nommer" #: ../src/pd_menus.tcl:162 ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:208 msgid "Vslider" msgstr "" #: ../src/pd_menus.tcl:164 ../src/pd_menus.tcl:209 ../src/pd_menus.tcl:210 #, fuzzy msgid "Hslider" msgstr "Weggesteek" #: ../src/pd_menus.tcl:166 ../src/pd_menus.tcl:211 ../src/pd_menus.tcl:212 #, fuzzy msgid "Vradio" msgstr "Weergawe" #: ../src/pd_menus.tcl:168 ../src/pd_menus.tcl:213 ../src/pd_menus.tcl:214 msgid "Hradio" msgstr "" #: ../src/pd_menus.tcl:170 ../src/pd_menus.tcl:215 ../src/pd_menus.tcl:216 msgid "VU Meter" msgstr "" #: ../src/pd_menus.tcl:172 ../src/pd_menus.tcl:217 ../src/pd_menus.tcl:218 #, fuzzy msgid "Canvas" msgstr "Kanada" #: ../src/pd_menus.tcl:175 ../src/pd_menus.tcl:220 ../src/pd_menus.tcl:221 msgid "Graph" msgstr "Grafiek" #: ../src/pd_menus.tcl:176 ../src/pd_menus.tcl:221 ../src/pd_menus.tcl:222 #, fuzzy msgid "Array" msgstr "Andorra" #: ../src/pd_menus.tcl:181 ../src/pd_menus.tcl:226 ../src/pd_menus.tcl:227 #, fuzzy msgid "Find..." msgstr "Description=Stuur Lêer" #: ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:228 ../src/pd_menus.tcl:229 msgid "Find Again" msgstr "" #: ../src/pd_menus.tcl:185 ../src/pd_menus.tcl:230 ../src/pd_menus.tcl:231 msgid "Find Last Error" msgstr "" #: ../src/pd_menus.tcl:191 ../src/pd_menus.tcl:236 ../src/pd_menus.tcl:237 msgid "DSP On" msgstr "" #: ../src/pd_menus.tcl:193 ../src/pd_menus.tcl:238 ../src/pd_menus.tcl:239 #, fuzzy msgid "DSP Off" msgstr "Af" #: ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:242 ../src/pd_menus.tcl:269 msgid "Test Audio and MIDI..." msgstr "" #: ../src/pd_menus.tcl:198 ../src/pd_menus.tcl:244 ../src/pd_menus.tcl:271 #, fuzzy msgid "Load Meter" msgstr "Meter Af" #: ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:251 ../src/pd_menus.tcl:278 msgid "Minimize" msgstr "" #: ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:253 ../src/pd_menus.tcl:280 #, fuzzy msgid "Zoom" msgstr "Onder" #: ../src/pd_menus.tcl:210 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:283 #, fuzzy msgid "Parent Window" msgstr "Description=Stuur Lêer" #: ../src/pd_menus.tcl:216 ../src/pd_menus.tcl:262 ../src/pd_menus.tcl:289 msgid "Bring All to Front" msgstr "" #: ../src/pd_menus.tcl:224 ../src/pd_menus.tcl:241 ../src/pd_menus.tcl:253 #: ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:297 ../src/pd_menus.tcl:335 #: ../src/pd_menus.tcl:362 #, fuzzy msgid "About Pd" msgstr "Aangaande" #: ../src/pd_menus.tcl:227 ../src/pd_menus.tcl:273 ../src/pd_menus.tcl:300 msgid "HTML Manual..." msgstr "" #: ../src/pd_menus.tcl:229 ../src/pd_menus.tcl:275 ../src/pd_menus.tcl:302 #, fuzzy msgid "Browser..." msgstr "Blaai..." #: ../src/pd_menus.tcl:248 ../src/pd_menus.tcl:260 ../src/pd_menus.tcl:342 #: ../src/pd_menus.tcl:369 #, fuzzy msgid "Preferences..." msgstr "Voorkeure..." #: ../src/pd_menus.tcl:257 ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:352 #: ../src/pd_menus.tcl:379 msgid "Open Recent" msgstr "" #: ../src/pd_menus.tcl:263 msgid "Audio Settings..." msgstr "" #: ../src/pd_menus.tcl:265 msgid "MIDI Settings..." msgstr "" #: ../src/pd_menus.tcl:296 ../src/pd_menus.tcl:309 ../src/pd_menus.tcl:333 #: ../src/pd_menus.tcl:346 ../src/pd_menus.tcl:393 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:432 ../src/pd_menus.tcl:459 #, fuzzy msgid "Quit" msgstr "Verlaat" #: ../src/pd_menus.tcl:304 ../src/pd_menus.tcl:331 #, fuzzy msgid "Clear Menu" msgstr "Maak lys skoon" #: ../src/pdtk_canvas.tcl:44 ../src/pdtk_canvas.tcl:106 #: ../src/pdtk_canvas.tcl:109 ../src/pdtk_canvas.tcl:123 #: ../src/pdtk_canvas.tcl:125 ../src/pdtk_canvas.tcl:126 #: ../src/pdtk_canvas.tcl:128 msgid "Properties" msgstr "" #: ../src/pdwindow.tcl:43 #, fuzzy msgid "DSP" msgstr "Af" #: ../startup/object_db.tcl:113 msgid "Signal" msgstr "" #: ../startup/object_db.tcl:114 msgid "Generators" msgstr "" #: ../startup/object_db.tcl:115 #, fuzzy msgid "Filters" msgstr "Lêer" #: ../startup/object_db.tcl:116 ../startup/object_db.tcl:124 msgid "Math" msgstr "" #: ../startup/object_db.tcl:117 ../startup/object_db.tcl:125 msgid "I/O" msgstr "" #: ../startup/object_db.tcl:118 ../startup/object_db.tcl:126 msgid "Sampling" msgstr "" #: ../startup/object_db.tcl:119 ../startup/object_db.tcl:128 msgid "Routing" msgstr "" #: ../startup/object_db.tcl:120 ../startup/object_db.tcl:129 msgid "Others" msgstr "" #: ../startup/object_db.tcl:127 msgid "GUI" msgstr "" pd-0.46-7/po/en_ca.po0000664000175000017500000005545412160204055012427 0ustar mspmsp# The Canadian English translation for Pure Data # This file is put in the public domain. # Ben Bogart , 2009. # msgid "" msgstr "" "Project-Id-Version: Pure Data 0.43\n" "Report-Msgid-Bugs-To: pd-dev@iem.at\n" "POT-Creation-Date: 2009-08-27 10:01-0400\n" "PO-Revision-Date: 2009-08-25 18:19-0400\n" "Last-Translator: Ben Bogart \n" "Language-Team: Canadian English \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "Undo duplicate" msgstr "" msgid "Undo paste" msgstr "" msgid "Undo motion" msgstr "" msgid "Undo cut" msgstr "" msgid "Undo disconnect" msgstr "" msgid "Undo connect" msgstr "" msgid "Undo clear" msgstr "" msgid "Undo typing" msgstr "" msgid "Discard changes to '%s'?" msgstr "" msgid "Do you want to save the changes you made in '%s'?" msgstr "" #: ../src/dialog_array.tcl:115 ../src/dialog_array.tcl:117 #: ../src/pd_menus.tcl:100 ../src/pd_menus.tcl:101 ../src/pd_menus.tcl:146 #: ../src/pd_menus.tcl:147 msgid "Copy" msgstr "" #: ../src/dialog_array.tcl:118 ../src/dialog_array.tcl:120 #: ../src/pd_menus.tcl:102 ../src/pd_menus.tcl:103 ../src/pd_menus.tcl:148 #: ../src/pd_menus.tcl:149 msgid "Paste" msgstr "" #: ../src/dialog_array.tcl:264 ../src/dialog_array.tcl:266 msgid "Array Properties" msgstr "" #: ../src/dialog_array.tcl:270 ../src/dialog_array.tcl:272 msgid "Name:" msgstr "" #: ../src/dialog_array.tcl:276 ../src/dialog_array.tcl:278 #: ../src/dialog_canvas.tcl:178 ../src/dialog_canvas.tcl:193 #: ../src/dialog_iemgui.tcl:619 ../src/dialog_iemgui.tcl:621 msgid "Size:" msgstr "" #: ../src/dialog_array.tcl:280 ../src/dialog_array.tcl:282 msgid "Save contents" msgstr "" #: ../src/dialog_array.tcl:284 ../src/dialog_array.tcl:286 msgid "Draw as:" msgstr "" #: ../src/dialog_array.tcl:287 ../src/dialog_array.tcl:289 msgid "Points" msgstr "" #: ../src/dialog_array.tcl:289 ../src/dialog_array.tcl:291 msgid "Polygon" msgstr "" #: ../src/dialog_array.tcl:291 ../src/dialog_array.tcl:293 msgid "Bezier curve" msgstr "Béziercurve" #: ../src/dialog_array.tcl:297 ../src/dialog_array.tcl:299 msgid "Put array into:" msgstr "" #: ../src/dialog_array.tcl:300 ../src/dialog_array.tcl:302 msgid "New graph" msgstr "" #: ../src/dialog_array.tcl:302 ../src/dialog_array.tcl:304 msgid "Last graph" msgstr "" #: ../src/dialog_array.tcl:306 ../src/dialog_array.tcl:308 msgid "Delete array" msgstr "" #: ../src/dialog_array.tcl:312 ../src/dialog_array.tcl:314 msgid "Open List View..." msgstr "" #: ../src/dialog_array.tcl:319 ../src/dialog_array.tcl:321 #: ../src/dialog_audio.tcl:136 ../src/dialog_canvas.tcl:205 #: ../src/dialog_font.tcl:51 ../src/dialog_gatom.tcl:153 #: ../src/dialog_gatom.tcl:161 ../src/dialog_iemgui.tcl:742 #: ../src/dialog_iemgui.tcl:748 ../src/dialog_midi.tcl:91 #: ../src/dialog_midi.tcl:226 msgid "Cancel" msgstr "" #: ../src/dialog_array.tcl:321 ../src/dialog_array.tcl:323 #: ../src/dialog_audio.tcl:138 ../src/dialog_canvas.tcl:207 #: ../src/dialog_gatom.tcl:156 ../src/dialog_gatom.tcl:164 #: ../src/dialog_iemgui.tcl:745 ../src/dialog_iemgui.tcl:751 #: ../src/dialog_midi.tcl:93 ../src/dialog_midi.tcl:228 msgid "Apply" msgstr "" #: ../src/dialog_array.tcl:323 ../src/dialog_array.tcl:325 #: ../src/dialog_audio.tcl:140 ../src/dialog_canvas.tcl:209 #: ../src/dialog_font.tcl:53 ../src/dialog_font.tcl:92 #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:101 #: ../src/dialog_gatom.tcl:159 ../src/dialog_gatom.tcl:167 #: ../src/dialog_iemgui.tcl:748 ../src/dialog_iemgui.tcl:754 #: ../src/dialog_midi.tcl:95 ../src/dialog_midi.tcl:230 msgid "OK" msgstr "" #: ../src/dialog_audio.tcl:130 msgid "Audio Settings" msgstr "" #: ../src/dialog_audio.tcl:142 msgid "Save All Settings" msgstr "" #: ../src/dialog_audio.tcl:151 msgid "Sample rate:" msgstr "" #: ../src/dialog_audio.tcl:153 msgid "Delay (msec):" msgstr "" #: ../src/dialog_audio.tcl:158 msgid "Use callbacks" msgstr "" #: ../src/dialog_audio.tcl:166 ../src/dialog_midi.tcl:105 #: ../src/dialog_midi.tcl:241 msgid "Input device 1:" msgstr "" #: ../src/dialog_audio.tcl:169 ../src/dialog_audio.tcl:183 #: ../src/dialog_audio.tcl:198 ../src/dialog_audio.tcl:213 #: ../src/dialog_audio.tcl:232 ../src/dialog_audio.tcl:250 #: ../src/dialog_audio.tcl:265 ../src/dialog_audio.tcl:280 msgid "Channels:" msgstr "" #: ../src/dialog_audio.tcl:179 ../src/dialog_midi.tcl:115 #: ../src/dialog_midi.tcl:251 msgid "Input device 2:" msgstr "" #: ../src/dialog_audio.tcl:194 ../src/dialog_midi.tcl:127 #: ../src/dialog_midi.tcl:263 msgid "Input device 3:" msgstr "" #: ../src/dialog_audio.tcl:209 ../src/dialog_midi.tcl:139 #: ../src/dialog_midi.tcl:275 msgid "Input device 4:" msgstr "" #: ../src/dialog_audio.tcl:223 ../src/dialog_midi.tcl:150 #: ../src/dialog_midi.tcl:286 msgid "Output device 1:" msgstr "" #: ../src/dialog_audio.tcl:226 msgid "(same as input device) .............. " msgstr "" #: ../src/dialog_audio.tcl:246 ../src/dialog_midi.tcl:160 #: ../src/dialog_midi.tcl:296 msgid "Output device 2:" msgstr "" #: ../src/dialog_audio.tcl:261 ../src/dialog_midi.tcl:171 #: ../src/dialog_midi.tcl:307 msgid "Output device 3:" msgstr "" #: ../src/dialog_audio.tcl:276 ../src/dialog_midi.tcl:182 #: ../src/dialog_midi.tcl:318 msgid "Output device 4:" msgstr "" #: ../src/dialog_audio.tcl:291 ../src/dialog_midi.tcl:195 msgid "Use multiple devices" msgstr "" #: ../src/dialog_canvas.tcl:142 msgid "Canvas Properties" msgstr "" #: ../src/dialog_canvas.tcl:146 msgid "Scale" msgstr "" #: ../src/dialog_canvas.tcl:150 msgid "X units per pixel:" msgstr "" #: ../src/dialog_canvas.tcl:155 msgid "Y units per pixel:" msgstr "" #: ../src/dialog_canvas.tcl:159 msgid "Appearance on parent patch" msgstr "" #: ../src/dialog_canvas.tcl:161 msgid "Graph-On-Parent" msgstr "" #: ../src/dialog_canvas.tcl:165 msgid "Hide object name and arguments" msgstr "" #: ../src/dialog_canvas.tcl:170 msgid "Range and size" msgstr "" #: ../src/dialog_canvas.tcl:174 msgid "X range, from" msgstr "" #: ../src/dialog_canvas.tcl:176 ../src/dialog_canvas.tcl:191 msgid "to" msgstr "" #: ../src/dialog_canvas.tcl:180 ../src/dialog_canvas.tcl:195 msgid "Margin:" msgstr "" #: ../src/dialog_canvas.tcl:189 msgid "Y range, from" msgstr "" #: ../src/dialog_find.tcl:63 ../src/dialog_find.tcl:66 #: ../src/dialog_find.tcl:79 ../src/dialog_find.tcl:80 #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:85 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:101 #: ../src/dialog_find.tcl:105 ../src/dialog_find.tcl:107 #: ../src/pd_menus.tcl:45 msgid "Find" msgstr "" #: ../src/dialog_find.tcl:70 ../src/dialog_find.tcl:73 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:91 #: ../src/dialog_find.tcl:93 msgid "Search in" msgstr "" #: ../src/dialog_find.tcl:72 ../src/dialog_find.tcl:75 #: ../src/dialog_find.tcl:89 ../src/dialog_find.tcl:93 #: ../src/dialog_find.tcl:95 msgid "for:" msgstr "" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:90 #: ../src/dialog_find.tcl:104 ../src/dialog_find.tcl:108 #: ../src/dialog_find.tcl:110 ../src/pd_menus.tcl:86 ../src/pd_menus.tcl:87 #: ../src/pd_menus.tcl:132 ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:259 #: ../src/pd_menus.tcl:272 ../src/pd_menus.tcl:295 ../src/pd_menus.tcl:308 #: ../src/pd_menus.tcl:332 ../src/pd_menus.tcl:345 ../src/pd_menus.tcl:354 #: ../src/pd_menus.tcl:381 ../src/pd_menus.tcl:392 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:431 ../src/pd_menus.tcl:458 msgid "Close" msgstr "" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:97 #: ../src/dialog_find.tcl:101 ../src/dialog_find.tcl:103 msgid "Match whole word only" msgstr "" #: ../src/dialog_find.tcl:92 ../src/dialog_font.tcl:49 #: ../src/dialog_font.tcl:50 ../src/pd-gui.tcl:280 ../src/pd-gui.tcl:283 #: ../src/pd-gui.tcl:286 ../src/pd-gui.tcl:288 ../src/pd-gui.tcl:291 #: ../src/pd_menus.tcl:212 ../src/pd_menus.tcl:258 ../src/pd_menus.tcl:285 #: ../src/pdwindow.tcl:33 msgid "Pd window" msgstr "" #: ../src/dialog_font.tcl:45 msgid "Font Properties" msgstr "" #: ../src/dialog_font.tcl:46 ../src/dialog_font.tcl:54 #: ../src/dialog_font.tcl:55 #, tcl-format msgid "%s Font" msgstr "" #: ../src/dialog_font.tcl:61 ../src/dialog_font.tcl:96 #: ../src/dialog_font.tcl:104 ../src/dialog_font.tcl:105 msgid "Font Size" msgstr "" #: ../src/dialog_font.tcl:89 ../src/dialog_font.tcl:108 #: ../src/dialog_font.tcl:116 ../src/dialog_font.tcl:117 msgid "Stretch" msgstr "" #: ../src/dialog_font.tcl:96 ../src/dialog_font.tcl:115 #: ../src/dialog_font.tcl:123 ../src/dialog_font.tcl:124 msgid "X and Y" msgstr "" #: ../src/dialog_font.tcl:98 ../src/dialog_font.tcl:117 #: ../src/dialog_font.tcl:125 ../src/dialog_font.tcl:126 msgid "X only" msgstr "" #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:119 #: ../src/dialog_font.tcl:127 ../src/dialog_font.tcl:128 msgid "Y only" msgstr "" #: ../src/dialog_gatom.tcl:93 msgid "Atom Box Properties" msgstr "" #: ../src/dialog_gatom.tcl:99 msgid "Width:" msgstr "" #: ../src/dialog_gatom.tcl:103 msgid "Limits" msgstr "" #: ../src/dialog_gatom.tcl:107 msgid "Lower:" msgstr "" #: ../src/dialog_gatom.tcl:112 ../src/dialog_gatom.tcl:113 msgid "Upper:" msgstr "" #: ../src/dialog_gatom.tcl:116 ../src/dialog_gatom.tcl:121 #: ../src/dialog_iemgui.tcl:600 ../src/dialog_iemgui.tcl:652 #: ../src/dialog_iemgui.tcl:657 msgid "Label" msgstr "" #: ../src/dialog_gatom.tcl:124 ../src/dialog_gatom.tcl:129 msgid "Left " msgstr "" #: ../src/dialog_gatom.tcl:126 ../src/dialog_gatom.tcl:131 msgid "Right" msgstr "" #: ../src/dialog_gatom.tcl:128 ../src/dialog_gatom.tcl:133 msgid "Top" msgstr "" #: ../src/dialog_gatom.tcl:130 ../src/dialog_gatom.tcl:135 msgid "Bottom" msgstr "" #: ../src/dialog_gatom.tcl:137 ../src/dialog_gatom.tcl:145 #: ../src/dialog_iemgui.tcl:574 msgid "Messages" msgstr "" #: ../src/dialog_gatom.tcl:141 ../src/dialog_gatom.tcl:149 #: ../src/dialog_iemgui.tcl:578 msgid "Send symbol:" msgstr "" #: ../src/dialog_gatom.tcl:147 ../src/dialog_gatom.tcl:155 #: ../src/dialog_iemgui.tcl:585 msgid "Receive symbol:" msgstr "" #: ../src/dialog_iemgui.tcl:197 msgid "Background color" msgstr "Background colour" #: ../src/dialog_iemgui.tcl:204 msgid "Foreground color" msgstr "Foreground colour" #: ../src/dialog_iemgui.tcl:211 msgid "Label color" msgstr "Label colour" #: ../src/dialog_iemgui.tcl:272 msgid "Init" msgstr "" #: ../src/dialog_iemgui.tcl:275 ../src/dialog_iemgui.tcl:546 msgid "No init" msgstr "" #: ../src/dialog_iemgui.tcl:287 ../src/dialog_iemgui.tcl:558 msgid "Jump on click" msgstr "" #: ../src/dialog_iemgui.tcl:290 ../src/dialog_iemgui.tcl:561 msgid "Steady on click" msgstr "" #: ../src/dialog_iemgui.tcl:498 #, tcl-format msgid "%s Properties" msgstr "" #: ../src/dialog_iemgui.tcl:550 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:84 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:130 ../src/pd_menus.tcl:260 #: ../src/pd_menus.tcl:273 ../src/pd_menus.tcl:288 ../src/pd_menus.tcl:301 #: ../src/pd_menus.tcl:325 ../src/pd_menus.tcl:338 ../src/pd_menus.tcl:355 #: ../src/pd_menus.tcl:382 ../src/pd_menus.tcl:383 ../src/pd_menus.tcl:410 #: ../src/pd_menus.tcl:422 ../src/pd_menus.tcl:449 msgid "Save" msgstr "" #: ../src/dialog_iemgui.tcl:608 msgid "X offset" msgstr "" #: ../src/dialog_iemgui.tcl:611 ../src/dialog_iemgui.tcl:612 msgid "Y offset" msgstr "" #: ../src/dialog_iemgui.tcl:642 ../src/dialog_iemgui.tcl:645 msgid "Colors" msgstr "Colours" #: ../src/dialog_iemgui.tcl:648 ../src/dialog_iemgui.tcl:651 msgid "Background" msgstr "" #: ../src/dialog_iemgui.tcl:650 ../src/dialog_iemgui.tcl:654 msgid "Front" msgstr "" #: ../src/dialog_iemgui.tcl:662 ../src/dialog_iemgui.tcl:668 msgid "Compose color" msgstr "Compose colour" #: ../src/dialog_iemgui.tcl:682 ../src/dialog_iemgui.tcl:688 msgid "Test label" msgstr "" #: ../src/dialog_midi.tcl:85 msgid "MIDI Settings" msgstr "" #: ../src/dialog_midi.tcl:220 msgid "ALSA MIDI Settings" msgstr "" #: ../src/dialog_midi.tcl:331 msgid "Use multiple ALSA devices" msgstr "" #: ../src/dialog_midi.tcl:337 msgid "In Ports:" msgstr "" #: ../src/dialog_midi.tcl:340 msgid "Out Ports:" msgstr "" #: ../src/g_editor.c:1663 msgid "Discard changes to this window??" msgstr "" #: ../src/g_editor.c:1668 msgid "really quit?" msgstr "" #: ../src/g_editor.c:1699 msgid "Close this window??" msgstr "" #: ../src/pd-gui.tcl:185 ../src/pd-gui.tcl:195 ../src/pd-gui.tcl:203 #: ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:215 ../src/pd-gui.tcl:226 msgid "Associated Files" msgstr "" #: ../src/pd-gui.tcl:186 ../src/pd-gui.tcl:196 ../src/pd-gui.tcl:204 #: ../src/pd-gui.tcl:207 ../src/pd-gui.tcl:216 ../src/pd-gui.tcl:227 msgid "Pd Files" msgstr "" #: ../src/pd-gui.tcl:187 ../src/pd-gui.tcl:205 ../src/pd-gui.tcl:208 #: ../src/pd-gui.tcl:228 msgid "Max Patch Files" msgstr "" #: ../src/pd-gui.tcl:188 ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:209 #: ../src/pd-gui.tcl:229 msgid "Max Text Files" msgstr "" #: ../src/pd-gui.tcl:197 ../src/pd-gui.tcl:217 msgid "Max Patch Files (.pat)" msgstr "" #: ../src/pd-gui.tcl:198 ../src/pd-gui.tcl:218 msgid "Max Text Files (.mxt)" msgstr "" #: ../src/pd-gui.tcl:270 ../src/pd-gui.tcl:290 #, tcl-format msgid "WARNING: Font family '%s' not found, using default (%s)" msgstr "" #: ../src/pd-gui.tcl:278 ../src/pd-gui.tcl:298 #, tcl-format msgid "WARNING: Font weight '%s' not found, using default (%s)" msgstr "" #: ../src/pd-gui.tcl:303 ../src/pd-gui.tcl:323 #, tcl-format msgid "ERROR: %s failed to find font size (%s) that fits into %sx%s!" msgstr "" #: ../src/pd-gui.tcl:478 ../src/pd-gui.tcl:483 ../src/pd-gui.tcl:501 msgid "ERROR: 'pd' never showed up, 'pd-gui' quitting!" msgstr "" #: ../src/pd_menucommands.tcl:19 msgid "Untitled" msgstr "" #: ../src/pd_menucommands.tcl:78 ../src/pd_menucommands.tcl:79 #: ../src/pd_menucommands.tcl:90 msgid "Send Message..." msgstr "" #: ../src/pd_menucommands.tcl:82 ../src/pd_menucommands.tcl:83 #: ../src/pd_menucommands.tcl:94 ../src/pd_menus.tcl:87 ../src/pd_menus.tcl:88 #: ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:134 ../src/pd_menus.tcl:147 #: ../src/pd_menus.tcl:192 ../src/pd_menus.tcl:193 ../src/pd_menus.tcl:265 #: ../src/pd_menus.tcl:278 ../src/pd_menus.tcl:292 ../src/pd_menus.tcl:305 #: ../src/pd_menus.tcl:329 ../src/pd_menus.tcl:342 ../src/pd_menus.tcl:360 #: ../src/pd_menus.tcl:387 ../src/pd_menus.tcl:414 ../src/pd_menus.tcl:426 #: ../src/pd_menus.tcl:453 ../startup/object_db.tcl:123 msgid "Message" msgstr "" #: ../src/pd_menucommands.tcl:108 ../src/pd_menucommands.tcl:111 #: ../src/pd_menus.tcl:112 ../src/pd_menus.tcl:113 ../src/pd_menus.tcl:117 #: ../src/pd_menus.tcl:118 ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:159 #: ../src/pd_menus.tcl:163 ../src/pd_menus.tcl:164 msgid "Font" msgstr "" #: ../src/pd_menucommands.tcl:123 ../src/pd_menucommands.tcl:126 #: ../src/pd_menus.tcl:138 ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:184 msgid "Preferences" msgstr "" #: ../src/pd_menus.tcl:45 msgid "Edit" msgstr "" #: ../src/pd_menus.tcl:45 msgid "File" msgstr "" #: ../src/pd_menus.tcl:45 ../src/pdtk_canvas.tcl:48 ../src/pdtk_canvas.tcl:110 #: ../src/pdtk_canvas.tcl:113 msgid "Help" msgstr "" #: ../src/pd_menus.tcl:45 msgid "Media" msgstr "" #: ../src/pd_menus.tcl:45 msgid "Put" msgstr "" #: ../src/pd_menus.tcl:45 msgid "Window" msgstr "" #: ../src/pd_menus.tcl:81 ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:127 #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:255 ../src/pd_menus.tcl:267 #: ../src/pd_menus.tcl:285 ../src/pd_menus.tcl:298 ../src/pd_menus.tcl:322 #: ../src/pd_menus.tcl:335 ../src/pd_menus.tcl:349 ../src/pd_menus.tcl:376 #: ../src/pd_menus.tcl:380 ../src/pd_menus.tcl:407 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:446 msgid "New" msgstr "" #: ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:128 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:268 #: ../src/pd_menus.tcl:286 ../src/pd_menus.tcl:299 ../src/pd_menus.tcl:323 #: ../src/pd_menus.tcl:336 ../src/pd_menus.tcl:350 ../src/pd_menus.tcl:377 #: ../src/pd_menus.tcl:381 ../src/pd_menus.tcl:408 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:447 ../src/pdtk_canvas.tcl:46 #: ../src/pdtk_canvas.tcl:108 ../src/pdtk_canvas.tcl:111 #: ../src/pdtk_canvas.tcl:128 ../src/pdtk_canvas.tcl:130 #: ../src/pdtk_canvas.tcl:131 ../src/pdtk_canvas.tcl:133 msgid "Open" msgstr "" #: ../src/pd_menus.tcl:84 ../src/pd_menus.tcl:85 ../src/pd_menus.tcl:130 #: ../src/pd_menus.tcl:131 ../src/pd_menus.tcl:261 ../src/pd_menus.tcl:274 #: ../src/pd_menus.tcl:289 ../src/pd_menus.tcl:302 ../src/pd_menus.tcl:326 #: ../src/pd_menus.tcl:339 ../src/pd_menus.tcl:356 ../src/pd_menus.tcl:383 #: ../src/pd_menus.tcl:384 ../src/pd_menus.tcl:411 ../src/pd_menus.tcl:423 #: ../src/pd_menus.tcl:450 msgid "Save As..." msgstr "" #: ../src/pd_menus.tcl:88 ../src/pd_menus.tcl:89 ../src/pd_menus.tcl:134 #: ../src/pd_menus.tcl:135 ../src/pd_menus.tcl:267 ../src/pd_menus.tcl:280 #: ../src/pd_menus.tcl:293 ../src/pd_menus.tcl:306 ../src/pd_menus.tcl:330 #: ../src/pd_menus.tcl:343 ../src/pd_menus.tcl:362 ../src/pd_menus.tcl:388 #: ../src/pd_menus.tcl:389 ../src/pd_menus.tcl:415 ../src/pd_menus.tcl:427 #: ../src/pd_menus.tcl:454 msgid "Print..." msgstr "" #: ../src/pd_menus.tcl:93 ../src/pd_menus.tcl:94 ../src/pd_menus.tcl:139 #: ../src/pd_menus.tcl:140 msgid "Undo" msgstr "" #: ../src/pd_menus.tcl:95 ../src/pd_menus.tcl:96 ../src/pd_menus.tcl:141 #: ../src/pd_menus.tcl:142 msgid "Redo" msgstr "" #: ../src/pd_menus.tcl:98 ../src/pd_menus.tcl:99 ../src/pd_menus.tcl:144 #: ../src/pd_menus.tcl:145 msgid "Cut" msgstr "" #: ../src/pd_menus.tcl:104 ../src/pd_menus.tcl:105 ../src/pd_menus.tcl:150 #: ../src/pd_menus.tcl:151 msgid "Duplicate" msgstr "" #: ../src/pd_menus.tcl:106 ../src/pd_menus.tcl:107 ../src/pd_menus.tcl:152 #: ../src/pd_menus.tcl:153 msgid "Select All" msgstr "" #: ../src/pd_menus.tcl:110 ../src/pd_menus.tcl:111 ../src/pd_menus.tcl:115 #: ../src/pd_menus.tcl:116 ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:157 #: ../src/pd_menus.tcl:161 ../src/pd_menus.tcl:162 msgid "Text Editor" msgstr "" #: ../src/pd_menus.tcl:120 ../src/pd_menus.tcl:121 ../src/pd_menus.tcl:166 #: ../src/pd_menus.tcl:167 msgid "Tidy Up" msgstr "" #: ../src/pd_menus.tcl:122 ../src/pd_menus.tcl:123 ../src/pd_menus.tcl:168 #: ../src/pd_menus.tcl:169 msgid "Toggle Console" msgstr "" #: ../src/pd_menus.tcl:124 ../src/pd_menus.tcl:125 ../src/pd_menus.tcl:170 #: ../src/pd_menus.tcl:171 msgid "Clear Console" msgstr "" #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:174 #: ../src/pd_menus.tcl:175 msgid "Edit Mode" msgstr "" #: ../src/pd_menus.tcl:145 ../src/pd_menus.tcl:190 ../src/pd_menus.tcl:191 msgid "Object" msgstr "" #: ../src/pd_menus.tcl:149 ../src/pd_menus.tcl:194 ../src/pd_menus.tcl:195 msgid "Number" msgstr "" #: ../src/pd_menus.tcl:151 ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:197 msgid "Symbol" msgstr "" #: ../src/pd_menus.tcl:153 ../src/pd_menus.tcl:198 ../src/pd_menus.tcl:199 msgid "Comment" msgstr "" #: ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:201 ../src/pd_menus.tcl:202 msgid "Bang" msgstr "" #: ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:203 ../src/pd_menus.tcl:204 msgid "Toggle" msgstr "" #: ../src/pd_menus.tcl:160 ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:206 msgid "Number2" msgstr "" #: ../src/pd_menus.tcl:162 ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:208 msgid "Vslider" msgstr "" #: ../src/pd_menus.tcl:164 ../src/pd_menus.tcl:209 ../src/pd_menus.tcl:210 msgid "Hslider" msgstr "" #: ../src/pd_menus.tcl:166 ../src/pd_menus.tcl:211 ../src/pd_menus.tcl:212 msgid "Vradio" msgstr "" #: ../src/pd_menus.tcl:168 ../src/pd_menus.tcl:213 ../src/pd_menus.tcl:214 msgid "Hradio" msgstr "" #: ../src/pd_menus.tcl:170 ../src/pd_menus.tcl:215 ../src/pd_menus.tcl:216 msgid "VU Meter" msgstr "" #: ../src/pd_menus.tcl:172 ../src/pd_menus.tcl:217 ../src/pd_menus.tcl:218 msgid "Canvas" msgstr "" #: ../src/pd_menus.tcl:175 ../src/pd_menus.tcl:220 ../src/pd_menus.tcl:221 msgid "Graph" msgstr "" #: ../src/pd_menus.tcl:176 ../src/pd_menus.tcl:221 ../src/pd_menus.tcl:222 msgid "Array" msgstr "" #: ../src/pd_menus.tcl:181 ../src/pd_menus.tcl:226 ../src/pd_menus.tcl:227 msgid "Find..." msgstr "" #: ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:228 ../src/pd_menus.tcl:229 msgid "Find Again" msgstr "" #: ../src/pd_menus.tcl:185 ../src/pd_menus.tcl:230 ../src/pd_menus.tcl:231 msgid "Find Last Error" msgstr "" #: ../src/pd_menus.tcl:191 ../src/pd_menus.tcl:236 ../src/pd_menus.tcl:237 msgid "DSP On" msgstr "" #: ../src/pd_menus.tcl:193 ../src/pd_menus.tcl:238 ../src/pd_menus.tcl:239 msgid "DSP Off" msgstr "" #: ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:242 ../src/pd_menus.tcl:269 msgid "Test Audio and MIDI..." msgstr "" #: ../src/pd_menus.tcl:198 ../src/pd_menus.tcl:244 ../src/pd_menus.tcl:271 msgid "Load Meter" msgstr "" #: ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:251 ../src/pd_menus.tcl:278 msgid "Minimize" msgstr "" #: ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:253 ../src/pd_menus.tcl:280 msgid "Zoom" msgstr "" #: ../src/pd_menus.tcl:210 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:283 msgid "Parent Window" msgstr "" #: ../src/pd_menus.tcl:216 ../src/pd_menus.tcl:262 ../src/pd_menus.tcl:289 msgid "Bring All to Front" msgstr "" #: ../src/pd_menus.tcl:224 ../src/pd_menus.tcl:241 ../src/pd_menus.tcl:253 #: ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:297 ../src/pd_menus.tcl:335 #: ../src/pd_menus.tcl:362 msgid "About Pd" msgstr "" #: ../src/pd_menus.tcl:227 ../src/pd_menus.tcl:273 ../src/pd_menus.tcl:300 msgid "HTML Manual..." msgstr "" #: ../src/pd_menus.tcl:229 ../src/pd_menus.tcl:275 ../src/pd_menus.tcl:302 msgid "Browser..." msgstr "" #: ../src/pd_menus.tcl:248 ../src/pd_menus.tcl:260 ../src/pd_menus.tcl:342 #: ../src/pd_menus.tcl:369 msgid "Preferences..." msgstr "" #: ../src/pd_menus.tcl:257 ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:352 #: ../src/pd_menus.tcl:379 msgid "Open Recent" msgstr "" #: ../src/pd_menus.tcl:263 msgid "Audio Settings..." msgstr "" #: ../src/pd_menus.tcl:265 msgid "MIDI Settings..." msgstr "" #: ../src/pd_menus.tcl:296 ../src/pd_menus.tcl:309 ../src/pd_menus.tcl:333 #: ../src/pd_menus.tcl:346 ../src/pd_menus.tcl:393 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:432 ../src/pd_menus.tcl:459 msgid "Quit" msgstr "" #: ../src/pd_menus.tcl:304 ../src/pd_menus.tcl:331 msgid "Clear Menu" msgstr "" #: ../src/pdtk_canvas.tcl:44 ../src/pdtk_canvas.tcl:106 #: ../src/pdtk_canvas.tcl:109 ../src/pdtk_canvas.tcl:123 #: ../src/pdtk_canvas.tcl:125 ../src/pdtk_canvas.tcl:126 #: ../src/pdtk_canvas.tcl:128 msgid "Properties" msgstr "" #: ../src/pdwindow.tcl:43 msgid "DSP" msgstr "" #: ../startup/object_db.tcl:113 msgid "Signal" msgstr "" #: ../startup/object_db.tcl:114 msgid "Generators" msgstr "" #: ../startup/object_db.tcl:115 msgid "Filters" msgstr "" #: ../startup/object_db.tcl:116 ../startup/object_db.tcl:124 msgid "Math" msgstr "" #: ../startup/object_db.tcl:117 ../startup/object_db.tcl:125 msgid "I/O" msgstr "" #: ../startup/object_db.tcl:118 ../startup/object_db.tcl:126 msgid "Sampling" msgstr "" #: ../startup/object_db.tcl:119 ../startup/object_db.tcl:128 msgid "Routing" msgstr "" #: ../startup/object_db.tcl:120 ../startup/object_db.tcl:129 msgid "Others" msgstr "" #: ../startup/object_db.tcl:127 msgid "GUI" msgstr "" pd-0.46-7/po/he.po0000664000175000017500000006031112160204055011742 0ustar mspmsp# Hebrew translation of Pure Data. # This file is put in the public domain # you can be the first! , 2009. # msgid "" msgstr "" "Project-Id-Version: Pure Data 0.43\n" "Report-Msgid-Bugs-To: pd-dev@iem.at\n" "POT-Creation-Date: 2009-08-27 10:01-0400\n" "PO-Revision-Date: 2001-10-03 15:48+02:00\n" "Last-Translator: xchat \n" "Language-Team: Hebrew \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "Undo duplicate" msgstr "" msgid "Undo paste" msgstr "" msgid "Undo motion" msgstr "" msgid "Undo cut" msgstr "" msgid "Undo disconnect" msgstr "" msgid "Undo connect" msgstr "" msgid "Undo clear" msgstr "" msgid "Undo typing" msgstr "" msgid "Discard changes to '%s'?" msgstr "" msgid "Do you want to save the changes you made in '%s'?" msgstr "" #: ../src/dialog_array.tcl:115 ../src/dialog_array.tcl:117 #: ../src/pd_menus.tcl:100 ../src/pd_menus.tcl:101 ../src/pd_menus.tcl:146 #: ../src/pd_menus.tcl:147 msgid "Copy" msgstr "" #: ../src/dialog_array.tcl:118 ../src/dialog_array.tcl:120 #: ../src/pd_menus.tcl:102 ../src/pd_menus.tcl:103 ../src/pd_menus.tcl:148 #: ../src/pd_menus.tcl:149 #, fuzzy msgid "Paste" msgstr "פאנל" #: ../src/dialog_array.tcl:264 ../src/dialog_array.tcl:266 msgid "Array Properties" msgstr "" #: ../src/dialog_array.tcl:270 ../src/dialog_array.tcl:272 #, fuzzy msgid "Name:" msgstr "כתובת איי פי של שרת הפרוקסי:" #: ../src/dialog_array.tcl:276 ../src/dialog_array.tcl:278 #: ../src/dialog_canvas.tcl:178 ../src/dialog_canvas.tcl:193 #: ../src/dialog_iemgui.tcl:619 ../src/dialog_iemgui.tcl:621 msgid "Size:" msgstr "" #: ../src/dialog_array.tcl:280 ../src/dialog_array.tcl:282 #, fuzzy msgid "Save contents" msgstr "הזדהות אוטומטית" #: ../src/dialog_array.tcl:284 ../src/dialog_array.tcl:286 msgid "Draw as:" msgstr "" #: ../src/dialog_array.tcl:287 ../src/dialog_array.tcl:289 #, fuzzy msgid "Points" msgstr "פלאגין..." #: ../src/dialog_array.tcl:289 ../src/dialog_array.tcl:291 #, fuzzy msgid "Polygon" msgstr "טען" #: ../src/dialog_array.tcl:291 ../src/dialog_array.tcl:293 msgid "Bezier curve" msgstr "" #: ../src/dialog_array.tcl:297 ../src/dialog_array.tcl:299 msgid "Put array into:" msgstr "" #: ../src/dialog_array.tcl:300 ../src/dialog_array.tcl:302 msgid "New graph" msgstr "" #: ../src/dialog_array.tcl:302 ../src/dialog_array.tcl:304 msgid "Last graph" msgstr "" #: ../src/dialog_array.tcl:306 ../src/dialog_array.tcl:308 msgid "Delete array" msgstr "" #: ../src/dialog_array.tcl:312 ../src/dialog_array.tcl:314 #, fuzzy msgid "Open List View..." msgstr "חלון רשימת ערוצים.." #: ../src/dialog_array.tcl:319 ../src/dialog_array.tcl:321 #: ../src/dialog_audio.tcl:136 ../src/dialog_canvas.tcl:205 #: ../src/dialog_font.tcl:51 ../src/dialog_gatom.tcl:153 #: ../src/dialog_gatom.tcl:161 ../src/dialog_iemgui.tcl:742 #: ../src/dialog_iemgui.tcl:748 ../src/dialog_midi.tcl:91 #: ../src/dialog_midi.tcl:226 msgid "Cancel" msgstr "ביטול" #: ../src/dialog_array.tcl:321 ../src/dialog_array.tcl:323 #: ../src/dialog_audio.tcl:138 ../src/dialog_canvas.tcl:207 #: ../src/dialog_gatom.tcl:156 ../src/dialog_gatom.tcl:164 #: ../src/dialog_iemgui.tcl:745 ../src/dialog_iemgui.tcl:751 #: ../src/dialog_midi.tcl:93 ../src/dialog_midi.tcl:228 msgid "Apply" msgstr "החל" #: ../src/dialog_array.tcl:323 ../src/dialog_array.tcl:325 #: ../src/dialog_audio.tcl:140 ../src/dialog_canvas.tcl:209 #: ../src/dialog_font.tcl:53 ../src/dialog_font.tcl:92 #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:101 #: ../src/dialog_gatom.tcl:159 ../src/dialog_gatom.tcl:167 #: ../src/dialog_iemgui.tcl:748 ../src/dialog_iemgui.tcl:754 #: ../src/dialog_midi.tcl:95 ../src/dialog_midi.tcl:230 msgid "OK" msgstr "" #: ../src/dialog_audio.tcl:130 msgid "Audio Settings" msgstr "" #: ../src/dialog_audio.tcl:142 msgid "Save All Settings" msgstr "" #: ../src/dialog_audio.tcl:151 msgid "Sample rate:" msgstr "" #: ../src/dialog_audio.tcl:153 msgid "Delay (msec):" msgstr "" #: ../src/dialog_audio.tcl:158 msgid "Use callbacks" msgstr "" #: ../src/dialog_audio.tcl:166 ../src/dialog_midi.tcl:105 #: ../src/dialog_midi.tcl:241 msgid "Input device 1:" msgstr "" #: ../src/dialog_audio.tcl:169 ../src/dialog_audio.tcl:183 #: ../src/dialog_audio.tcl:198 ../src/dialog_audio.tcl:213 #: ../src/dialog_audio.tcl:232 ../src/dialog_audio.tcl:250 #: ../src/dialog_audio.tcl:265 ../src/dialog_audio.tcl:280 #, fuzzy msgid "Channels:" msgstr "ביטול" #: ../src/dialog_audio.tcl:179 ../src/dialog_midi.tcl:115 #: ../src/dialog_midi.tcl:251 msgid "Input device 2:" msgstr "" #: ../src/dialog_audio.tcl:194 ../src/dialog_midi.tcl:127 #: ../src/dialog_midi.tcl:263 msgid "Input device 3:" msgstr "" #: ../src/dialog_audio.tcl:209 ../src/dialog_midi.tcl:139 #: ../src/dialog_midi.tcl:275 msgid "Input device 4:" msgstr "" #: ../src/dialog_audio.tcl:223 ../src/dialog_midi.tcl:150 #: ../src/dialog_midi.tcl:286 msgid "Output device 1:" msgstr "" #: ../src/dialog_audio.tcl:226 msgid "(same as input device) .............. " msgstr "" #: ../src/dialog_audio.tcl:246 ../src/dialog_midi.tcl:160 #: ../src/dialog_midi.tcl:296 msgid "Output device 2:" msgstr "" #: ../src/dialog_audio.tcl:261 ../src/dialog_midi.tcl:171 #: ../src/dialog_midi.tcl:307 msgid "Output device 3:" msgstr "" #: ../src/dialog_audio.tcl:276 ../src/dialog_midi.tcl:182 #: ../src/dialog_midi.tcl:318 msgid "Output device 4:" msgstr "" #: ../src/dialog_audio.tcl:291 ../src/dialog_midi.tcl:195 msgid "Use multiple devices" msgstr "" #: ../src/dialog_canvas.tcl:142 msgid "Canvas Properties" msgstr "" #: ../src/dialog_canvas.tcl:146 msgid "Scale" msgstr "" #: ../src/dialog_canvas.tcl:150 msgid "X units per pixel:" msgstr "" #: ../src/dialog_canvas.tcl:155 msgid "Y units per pixel:" msgstr "" #: ../src/dialog_canvas.tcl:159 msgid "Appearance on parent patch" msgstr "" #: ../src/dialog_canvas.tcl:161 msgid "Graph-On-Parent" msgstr "" #: ../src/dialog_canvas.tcl:165 msgid "Hide object name and arguments" msgstr "" #: ../src/dialog_canvas.tcl:170 msgid "Range and size" msgstr "" #: ../src/dialog_canvas.tcl:174 msgid "X range, from" msgstr "" #: ../src/dialog_canvas.tcl:176 ../src/dialog_canvas.tcl:191 msgid "to" msgstr "" #: ../src/dialog_canvas.tcl:180 ../src/dialog_canvas.tcl:195 msgid "Margin:" msgstr "" #: ../src/dialog_canvas.tcl:189 msgid "Y range, from" msgstr "" #: ../src/dialog_find.tcl:63 ../src/dialog_find.tcl:66 #: ../src/dialog_find.tcl:79 ../src/dialog_find.tcl:80 #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:85 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:101 #: ../src/dialog_find.tcl:105 ../src/dialog_find.tcl:107 #: ../src/pd_menus.tcl:45 msgid "Find" msgstr "" #: ../src/dialog_find.tcl:70 ../src/dialog_find.tcl:73 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:91 #: ../src/dialog_find.tcl:93 #, fuzzy msgid "Search in" msgstr "חפש בבאפר.." #: ../src/dialog_find.tcl:72 ../src/dialog_find.tcl:75 #: ../src/dialog_find.tcl:89 ../src/dialog_find.tcl:93 #: ../src/dialog_find.tcl:95 #, fuzzy msgid "for:" msgstr "גופן:" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:90 #: ../src/dialog_find.tcl:104 ../src/dialog_find.tcl:108 #: ../src/dialog_find.tcl:110 ../src/pd_menus.tcl:86 ../src/pd_menus.tcl:87 #: ../src/pd_menus.tcl:132 ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:259 #: ../src/pd_menus.tcl:272 ../src/pd_menus.tcl:295 ../src/pd_menus.tcl:308 #: ../src/pd_menus.tcl:332 ../src/pd_menus.tcl:345 ../src/pd_menus.tcl:354 #: ../src/pd_menus.tcl:381 ../src/pd_menus.tcl:392 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:431 ../src/pd_menus.tcl:458 msgid "Close" msgstr "סגור" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:97 #: ../src/dialog_find.tcl:101 ../src/dialog_find.tcl:103 msgid "Match whole word only" msgstr "" #: ../src/dialog_find.tcl:92 ../src/dialog_font.tcl:49 #: ../src/dialog_font.tcl:50 ../src/pd-gui.tcl:280 ../src/pd-gui.tcl:283 #: ../src/pd-gui.tcl:286 ../src/pd-gui.tcl:288 ../src/pd-gui.tcl:291 #: ../src/pd_menus.tcl:212 ../src/pd_menus.tcl:258 ../src/pd_menus.tcl:285 #: ../src/pdwindow.tcl:33 #, fuzzy msgid "Pd window" msgstr "_חלונות" #: ../src/dialog_font.tcl:45 msgid "Font Properties" msgstr "" #: ../src/dialog_font.tcl:46 ../src/dialog_font.tcl:54 #: ../src/dialog_font.tcl:55 #, fuzzy, tcl-format msgid "%s Font" msgstr "גופן:" #: ../src/dialog_font.tcl:61 ../src/dialog_font.tcl:96 #: ../src/dialog_font.tcl:104 ../src/dialog_font.tcl:105 #, fuzzy msgid "Font Size" msgstr "גודל חלון" #: ../src/dialog_font.tcl:89 ../src/dialog_font.tcl:108 #: ../src/dialog_font.tcl:116 ../src/dialog_font.tcl:117 msgid "Stretch" msgstr "" #: ../src/dialog_font.tcl:96 ../src/dialog_font.tcl:115 #: ../src/dialog_font.tcl:123 ../src/dialog_font.tcl:124 msgid "X and Y" msgstr "" #: ../src/dialog_font.tcl:98 ../src/dialog_font.tcl:117 #: ../src/dialog_font.tcl:125 ../src/dialog_font.tcl:126 msgid "X only" msgstr "" #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:119 #: ../src/dialog_font.tcl:127 ../src/dialog_font.tcl:128 msgid "Y only" msgstr "" #: ../src/dialog_gatom.tcl:93 msgid "Atom Box Properties" msgstr "" #: ../src/dialog_gatom.tcl:99 msgid "Width:" msgstr "רוחב:" #: ../src/dialog_gatom.tcl:103 #, fuzzy msgid "Limits" msgstr "רשימת פייטון" #: ../src/dialog_gatom.tcl:107 msgid "Lower:" msgstr "" #: ../src/dialog_gatom.tcl:112 ../src/dialog_gatom.tcl:113 #, fuzzy msgid "Upper:" msgstr "תפריט משתמש" #: ../src/dialog_gatom.tcl:116 ../src/dialog_gatom.tcl:121 #: ../src/dialog_iemgui.tcl:600 ../src/dialog_iemgui.tcl:652 #: ../src/dialog_iemgui.tcl:657 #, fuzzy msgid "Label" msgstr "פאנל" #: ../src/dialog_gatom.tcl:124 ../src/dialog_gatom.tcl:129 #, fuzzy msgid "Left " msgstr "שמאל" #: ../src/dialog_gatom.tcl:126 ../src/dialog_gatom.tcl:131 msgid "Right" msgstr "ימין" #: ../src/dialog_gatom.tcl:128 ../src/dialog_gatom.tcl:133 msgid "Top" msgstr "עליון" #: ../src/dialog_gatom.tcl:130 ../src/dialog_gatom.tcl:135 msgid "Bottom" msgstr "תחתון" #: ../src/dialog_gatom.tcl:137 ../src/dialog_gatom.tcl:145 #: ../src/dialog_iemgui.tcl:574 #, fuzzy msgid "Messages" msgstr "הודעת יציאה:" #: ../src/dialog_gatom.tcl:141 ../src/dialog_gatom.tcl:149 #: ../src/dialog_iemgui.tcl:578 msgid "Send symbol:" msgstr "" #: ../src/dialog_gatom.tcl:147 ../src/dialog_gatom.tcl:155 #: ../src/dialog_iemgui.tcl:585 #, fuzzy msgid "Receive symbol:" msgstr "קבצים שהתקבלו" #: ../src/dialog_iemgui.tcl:197 #, fuzzy msgid "Background color" msgstr "XPM ברקע:" #: ../src/dialog_iemgui.tcl:204 msgid "Foreground color" msgstr "" #: ../src/dialog_iemgui.tcl:211 #, fuzzy msgid "Label color" msgstr "בחר גופן" #: ../src/dialog_iemgui.tcl:272 #, fuzzy msgid "Init" msgstr "בלתי נראה" #: ../src/dialog_iemgui.tcl:275 ../src/dialog_iemgui.tcl:546 msgid "No init" msgstr "" #: ../src/dialog_iemgui.tcl:287 ../src/dialog_iemgui.tcl:558 msgid "Jump on click" msgstr "" #: ../src/dialog_iemgui.tcl:290 ../src/dialog_iemgui.tcl:561 msgid "Steady on click" msgstr "" #: ../src/dialog_iemgui.tcl:498 #, tcl-format msgid "%s Properties" msgstr "" #: ../src/dialog_iemgui.tcl:550 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:84 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:130 ../src/pd_menus.tcl:260 #: ../src/pd_menus.tcl:273 ../src/pd_menus.tcl:288 ../src/pd_menus.tcl:301 #: ../src/pd_menus.tcl:325 ../src/pd_menus.tcl:338 ../src/pd_menus.tcl:355 #: ../src/pd_menus.tcl:382 ../src/pd_menus.tcl:383 ../src/pd_menus.tcl:410 #: ../src/pd_menus.tcl:422 ../src/pd_menus.tcl:449 msgid "Save" msgstr "" #: ../src/dialog_iemgui.tcl:608 msgid "X offset" msgstr "" #: ../src/dialog_iemgui.tcl:611 ../src/dialog_iemgui.tcl:612 msgid "Y offset" msgstr "" #: ../src/dialog_iemgui.tcl:642 ../src/dialog_iemgui.tcl:645 #, fuzzy msgid "Colors" msgstr "סגור" #: ../src/dialog_iemgui.tcl:648 ../src/dialog_iemgui.tcl:651 #, fuzzy msgid "Background" msgstr "XPM ברקע:" #: ../src/dialog_iemgui.tcl:650 ../src/dialog_iemgui.tcl:654 #, fuzzy msgid "Front" msgstr "גופן:" #: ../src/dialog_iemgui.tcl:662 ../src/dialog_iemgui.tcl:668 msgid "Compose color" msgstr "" #: ../src/dialog_iemgui.tcl:682 ../src/dialog_iemgui.tcl:688 msgid "Test label" msgstr "" #: ../src/dialog_midi.tcl:85 msgid "MIDI Settings" msgstr "" #: ../src/dialog_midi.tcl:220 msgid "ALSA MIDI Settings" msgstr "" #: ../src/dialog_midi.tcl:331 msgid "Use multiple ALSA devices" msgstr "" #: ../src/dialog_midi.tcl:337 msgid "In Ports:" msgstr "" #: ../src/dialog_midi.tcl:340 msgid "Out Ports:" msgstr "" #: ../src/g_editor.c:1663 msgid "Discard changes to this window??" msgstr "" #: ../src/g_editor.c:1668 msgid "really quit?" msgstr "" #: ../src/g_editor.c:1699 msgid "Close this window??" msgstr "" #: ../src/pd-gui.tcl:185 ../src/pd-gui.tcl:195 ../src/pd-gui.tcl:203 #: ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:215 ../src/pd-gui.tcl:226 #, fuzzy msgid "Associated Files" msgstr "לאשר אוטומטית שליחות של דיסיסי" #: ../src/pd-gui.tcl:186 ../src/pd-gui.tcl:196 ../src/pd-gui.tcl:204 #: ../src/pd-gui.tcl:207 ../src/pd-gui.tcl:216 ../src/pd-gui.tcl:227 msgid "Pd Files" msgstr "" #: ../src/pd-gui.tcl:187 ../src/pd-gui.tcl:205 ../src/pd-gui.tcl:208 #: ../src/pd-gui.tcl:228 msgid "Max Patch Files" msgstr "" #: ../src/pd-gui.tcl:188 ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:209 #: ../src/pd-gui.tcl:229 msgid "Max Text Files" msgstr "" #: ../src/pd-gui.tcl:197 ../src/pd-gui.tcl:217 msgid "Max Patch Files (.pat)" msgstr "" #: ../src/pd-gui.tcl:198 ../src/pd-gui.tcl:218 msgid "Max Text Files (.mxt)" msgstr "" #: ../src/pd-gui.tcl:270 ../src/pd-gui.tcl:290 #, tcl-format msgid "WARNING: Font family '%s' not found, using default (%s)" msgstr "" #: ../src/pd-gui.tcl:278 ../src/pd-gui.tcl:298 #, tcl-format msgid "WARNING: Font weight '%s' not found, using default (%s)" msgstr "" #: ../src/pd-gui.tcl:303 ../src/pd-gui.tcl:323 #, tcl-format msgid "ERROR: %s failed to find font size (%s) that fits into %sx%s!" msgstr "" #: ../src/pd-gui.tcl:478 ../src/pd-gui.tcl:483 ../src/pd-gui.tcl:501 msgid "ERROR: 'pd' never showed up, 'pd-gui' quitting!" msgstr "" #: ../src/pd_menucommands.tcl:19 #, fuzzy msgid "Untitled" msgstr "ללא סידור" #: ../src/pd_menucommands.tcl:78 ../src/pd_menucommands.tcl:79 #: ../src/pd_menucommands.tcl:90 #, fuzzy msgid "Send Message..." msgstr "הודעת יציאה:" #: ../src/pd_menucommands.tcl:82 ../src/pd_menucommands.tcl:83 #: ../src/pd_menucommands.tcl:94 ../src/pd_menus.tcl:87 ../src/pd_menus.tcl:88 #: ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:134 ../src/pd_menus.tcl:147 #: ../src/pd_menus.tcl:192 ../src/pd_menus.tcl:193 ../src/pd_menus.tcl:265 #: ../src/pd_menus.tcl:278 ../src/pd_menus.tcl:292 ../src/pd_menus.tcl:305 #: ../src/pd_menus.tcl:329 ../src/pd_menus.tcl:342 ../src/pd_menus.tcl:360 #: ../src/pd_menus.tcl:387 ../src/pd_menus.tcl:414 ../src/pd_menus.tcl:426 #: ../src/pd_menus.tcl:453 ../startup/object_db.tcl:123 #, fuzzy msgid "Message" msgstr "הודעת יציאה:" #: ../src/pd_menucommands.tcl:108 ../src/pd_menucommands.tcl:111 #: ../src/pd_menus.tcl:112 ../src/pd_menus.tcl:113 ../src/pd_menus.tcl:117 #: ../src/pd_menus.tcl:118 ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:159 #: ../src/pd_menus.tcl:163 ../src/pd_menus.tcl:164 #, fuzzy msgid "Font" msgstr "גופן:" #: ../src/pd_menucommands.tcl:123 ../src/pd_menucommands.tcl:126 #: ../src/pd_menus.tcl:138 ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:184 #, fuzzy msgid "Preferences" msgstr "איקס-צ'אט: הגדרות" #: ../src/pd_menus.tcl:45 msgid "Edit" msgstr "" #: ../src/pd_menus.tcl:45 msgid "File" msgstr "" #: ../src/pd_menus.tcl:45 ../src/pdtk_canvas.tcl:48 ../src/pdtk_canvas.tcl:110 #: ../src/pdtk_canvas.tcl:113 msgid "Help" msgstr "עזרה" #: ../src/pd_menus.tcl:45 msgid "Media" msgstr "" #: ../src/pd_menus.tcl:45 msgid "Put" msgstr "" #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Window" msgstr "_חלונות" #: ../src/pd_menus.tcl:81 ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:127 #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:255 ../src/pd_menus.tcl:267 #: ../src/pd_menus.tcl:285 ../src/pd_menus.tcl:298 ../src/pd_menus.tcl:322 #: ../src/pd_menus.tcl:335 ../src/pd_menus.tcl:349 ../src/pd_menus.tcl:376 #: ../src/pd_menus.tcl:380 ../src/pd_menus.tcl:407 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:446 msgid "New" msgstr "" #: ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:128 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:268 #: ../src/pd_menus.tcl:286 ../src/pd_menus.tcl:299 ../src/pd_menus.tcl:323 #: ../src/pd_menus.tcl:336 ../src/pd_menus.tcl:350 ../src/pd_menus.tcl:377 #: ../src/pd_menus.tcl:381 ../src/pd_menus.tcl:408 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:447 ../src/pdtk_canvas.tcl:46 #: ../src/pdtk_canvas.tcl:108 ../src/pdtk_canvas.tcl:111 #: ../src/pdtk_canvas.tcl:128 ../src/pdtk_canvas.tcl:130 #: ../src/pdtk_canvas.tcl:131 ../src/pdtk_canvas.tcl:133 msgid "Open" msgstr "" #: ../src/pd_menus.tcl:84 ../src/pd_menus.tcl:85 ../src/pd_menus.tcl:130 #: ../src/pd_menus.tcl:131 ../src/pd_menus.tcl:261 ../src/pd_menus.tcl:274 #: ../src/pd_menus.tcl:289 ../src/pd_menus.tcl:302 ../src/pd_menus.tcl:326 #: ../src/pd_menus.tcl:339 ../src/pd_menus.tcl:356 ../src/pd_menus.tcl:383 #: ../src/pd_menus.tcl:384 ../src/pd_menus.tcl:411 ../src/pd_menus.tcl:423 #: ../src/pd_menus.tcl:450 #, fuzzy msgid "Save As..." msgstr "עריכת אירועי טקסט.." #: ../src/pd_menus.tcl:88 ../src/pd_menus.tcl:89 ../src/pd_menus.tcl:134 #: ../src/pd_menus.tcl:135 ../src/pd_menus.tcl:267 ../src/pd_menus.tcl:280 #: ../src/pd_menus.tcl:293 ../src/pd_menus.tcl:306 ../src/pd_menus.tcl:330 #: ../src/pd_menus.tcl:343 ../src/pd_menus.tcl:362 ../src/pd_menus.tcl:388 #: ../src/pd_menus.tcl:389 ../src/pd_menus.tcl:415 ../src/pd_menus.tcl:427 #: ../src/pd_menus.tcl:454 msgid "Print..." msgstr "" #: ../src/pd_menus.tcl:93 ../src/pd_menus.tcl:94 ../src/pd_menus.tcl:139 #: ../src/pd_menus.tcl:140 msgid "Undo" msgstr "" #: ../src/pd_menus.tcl:95 ../src/pd_menus.tcl:96 ../src/pd_menus.tcl:141 #: ../src/pd_menus.tcl:142 #, fuzzy msgid "Redo" msgstr "אדום:" #: ../src/pd_menus.tcl:98 ../src/pd_menus.tcl:99 ../src/pd_menus.tcl:144 #: ../src/pd_menus.tcl:145 msgid "Cut" msgstr "" #: ../src/pd_menus.tcl:104 ../src/pd_menus.tcl:105 ../src/pd_menus.tcl:150 #: ../src/pd_menus.tcl:151 msgid "Duplicate" msgstr "" #: ../src/pd_menus.tcl:106 ../src/pd_menus.tcl:107 ../src/pd_menus.tcl:152 #: ../src/pd_menus.tcl:153 #, fuzzy msgid "Select All" msgstr "בחר גופן" #: ../src/pd_menus.tcl:110 ../src/pd_menus.tcl:111 ../src/pd_menus.tcl:115 #: ../src/pd_menus.tcl:116 ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:157 #: ../src/pd_menus.tcl:161 ../src/pd_menus.tcl:162 msgid "Text Editor" msgstr "" #: ../src/pd_menus.tcl:120 ../src/pd_menus.tcl:121 ../src/pd_menus.tcl:166 #: ../src/pd_menus.tcl:167 msgid "Tidy Up" msgstr "" #: ../src/pd_menus.tcl:122 ../src/pd_menus.tcl:123 ../src/pd_menus.tcl:168 #: ../src/pd_menus.tcl:169 msgid "Toggle Console" msgstr "" #: ../src/pd_menus.tcl:124 ../src/pd_menus.tcl:125 ../src/pd_menus.tcl:170 #: ../src/pd_menus.tcl:171 msgid "Clear Console" msgstr "" #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:174 #: ../src/pd_menus.tcl:175 #, fuzzy msgid "Edit Mode" msgstr "עריכת תפריט משתמש" #: ../src/pd_menus.tcl:145 ../src/pd_menus.tcl:190 ../src/pd_menus.tcl:191 msgid "Object" msgstr "" #: ../src/pd_menus.tcl:149 ../src/pd_menus.tcl:194 ../src/pd_menus.tcl:195 msgid "Number" msgstr "" #: ../src/pd_menus.tcl:151 ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:197 msgid "Symbol" msgstr "" #: ../src/pd_menus.tcl:153 ../src/pd_menus.tcl:198 ../src/pd_menus.tcl:199 #, fuzzy msgid "Comment" msgstr "פקודה לניגון:" #: ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:201 ../src/pd_menus.tcl:202 #, fuzzy msgid "Bang" msgstr "כפתורים" #: ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:203 ../src/pd_menus.tcl:204 msgid "Toggle" msgstr "" #: ../src/pd_menus.tcl:160 ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:206 msgid "Number2" msgstr "" #: ../src/pd_menus.tcl:162 ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:208 msgid "Vslider" msgstr "" #: ../src/pd_menus.tcl:164 ../src/pd_menus.tcl:209 ../src/pd_menus.tcl:210 #, fuzzy msgid "Hslider" msgstr "מוחבא" #: ../src/pd_menus.tcl:166 ../src/pd_menus.tcl:211 ../src/pd_menus.tcl:212 #, fuzzy msgid "Vradio" msgstr "הסתר גירסה" #: ../src/pd_menus.tcl:168 ../src/pd_menus.tcl:213 ../src/pd_menus.tcl:214 msgid "Hradio" msgstr "" #: ../src/pd_menus.tcl:170 ../src/pd_menus.tcl:215 ../src/pd_menus.tcl:216 msgid "VU Meter" msgstr "" #: ../src/pd_menus.tcl:172 ../src/pd_menus.tcl:217 ../src/pd_menus.tcl:218 #, fuzzy msgid "Canvas" msgstr "איקס-צ'אט" #: ../src/pd_menus.tcl:175 ../src/pd_menus.tcl:220 ../src/pd_menus.tcl:221 msgid "Graph" msgstr "" #: ../src/pd_menus.tcl:176 ../src/pd_menus.tcl:221 ../src/pd_menus.tcl:222 #, fuzzy msgid "Array" msgstr "אוואי" #: ../src/pd_menus.tcl:181 ../src/pd_menus.tcl:226 ../src/pd_menus.tcl:227 #, fuzzy msgid "Find..." msgstr "חלון שליחות דיסיסי.." #: ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:228 ../src/pd_menus.tcl:229 msgid "Find Again" msgstr "" #: ../src/pd_menus.tcl:185 ../src/pd_menus.tcl:230 ../src/pd_menus.tcl:231 msgid "Find Last Error" msgstr "" #: ../src/pd_menus.tcl:191 ../src/pd_menus.tcl:236 ../src/pd_menus.tcl:237 msgid "DSP On" msgstr "" #: ../src/pd_menus.tcl:193 ../src/pd_menus.tcl:238 ../src/pd_menus.tcl:239 msgid "DSP Off" msgstr "" #: ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:242 ../src/pd_menus.tcl:269 msgid "Test Audio and MIDI..." msgstr "" #: ../src/pd_menus.tcl:198 ../src/pd_menus.tcl:244 ../src/pd_menus.tcl:271 #, fuzzy msgid "Load Meter" msgstr "טען" #: ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:251 ../src/pd_menus.tcl:278 msgid "Minimize" msgstr "" #: ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:253 ../src/pd_menus.tcl:280 #, fuzzy msgid "Zoom" msgstr "תחתון" #: ../src/pd_menus.tcl:210 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:283 #, fuzzy msgid "Parent Window" msgstr "חלון ראשי" #: ../src/pd_menus.tcl:216 ../src/pd_menus.tcl:262 ../src/pd_menus.tcl:289 msgid "Bring All to Front" msgstr "" #: ../src/pd_menus.tcl:224 ../src/pd_menus.tcl:241 ../src/pd_menus.tcl:253 #: ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:297 ../src/pd_menus.tcl:335 #: ../src/pd_menus.tcl:362 #, fuzzy msgid "About Pd" msgstr "אודות איקס-צ'אט" #: ../src/pd_menus.tcl:227 ../src/pd_menus.tcl:273 ../src/pd_menus.tcl:300 msgid "HTML Manual..." msgstr "" #: ../src/pd_menus.tcl:229 ../src/pd_menus.tcl:275 ../src/pd_menus.tcl:302 #, fuzzy msgid "Browser..." msgstr "דפדף..." #: ../src/pd_menus.tcl:248 ../src/pd_menus.tcl:260 ../src/pd_menus.tcl:342 #: ../src/pd_menus.tcl:369 #, fuzzy msgid "Preferences..." msgstr "איקס-צ'אט: הגדרות" #: ../src/pd_menus.tcl:257 ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:352 #: ../src/pd_menus.tcl:379 msgid "Open Recent" msgstr "" #: ../src/pd_menus.tcl:263 msgid "Audio Settings..." msgstr "" #: ../src/pd_menus.tcl:265 msgid "MIDI Settings..." msgstr "" #: ../src/pd_menus.tcl:296 ../src/pd_menus.tcl:309 ../src/pd_menus.tcl:333 #: ../src/pd_menus.tcl:346 ../src/pd_menus.tcl:393 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:432 ../src/pd_menus.tcl:459 msgid "Quit" msgstr "יציאה" #: ../src/pd_menus.tcl:304 ../src/pd_menus.tcl:331 #, fuzzy msgid "Clear Menu" msgstr "תפריט משתמש" #: ../src/pdtk_canvas.tcl:44 ../src/pdtk_canvas.tcl:106 #: ../src/pdtk_canvas.tcl:109 ../src/pdtk_canvas.tcl:123 #: ../src/pdtk_canvas.tcl:125 ../src/pdtk_canvas.tcl:126 #: ../src/pdtk_canvas.tcl:128 msgid "Properties" msgstr "" #: ../src/pdwindow.tcl:43 msgid "DSP" msgstr "" #: ../startup/object_db.tcl:113 #, fuzzy msgid "Signal" msgstr "כללי" #: ../startup/object_db.tcl:114 #, fuzzy msgid "Generators" msgstr "כללי" #: ../startup/object_db.tcl:115 #, fuzzy msgid "Filters" msgstr "פאלט.." #: ../startup/object_db.tcl:116 ../startup/object_db.tcl:124 msgid "Math" msgstr "" #: ../startup/object_db.tcl:117 ../startup/object_db.tcl:125 msgid "I/O" msgstr "" #: ../startup/object_db.tcl:118 ../startup/object_db.tcl:126 msgid "Sampling" msgstr "" #: ../startup/object_db.tcl:119 ../startup/object_db.tcl:128 msgid "Routing" msgstr "" #: ../startup/object_db.tcl:120 ../startup/object_db.tcl:129 #, fuzzy msgid "Others" msgstr "אופציות אחרות של פריסה" #: ../startup/object_db.tcl:127 msgid "GUI" msgstr "" pd-0.46-7/po/pa.po0000664000175000017500000006152212160204055011753 0ustar mspmsp# Translation of Pure Data 0.43.po to Punjabi. # This file is put in the public domain. # # Amanpreet Singh Alam , 2005. msgid "" msgstr "" "Project-Id-Version: Pure Data 0.43\n" "Report-Msgid-Bugs-To: pd-dev@iem.at\n" "POT-Creation-Date: 2009-08-27 10:01-0400\n" "PO-Revision-Date: 2005-11-04 08:04+0530\n" "Last-Translator: Amanpreet Singh Alam \n" "Language-Team: Punjabi \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: KBabel 1.9.1\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #, fuzzy msgid "Undo duplicate" msgstr "ਮਿਤੀ" msgid "Undo paste" msgstr "" msgid "Undo motion" msgstr "" #, fuzzy msgid "Undo cut" msgstr "ਯੂਗਾਂਡਾ" msgid "Undo disconnect" msgstr "" msgid "Undo connect" msgstr "" msgid "Undo clear" msgstr "" msgid "Undo typing" msgstr "" msgid "Discard changes to '%s'?" msgstr "" msgid "Do you want to save the changes you made in '%s'?" msgstr "" #: ../src/dialog_array.tcl:115 ../src/dialog_array.tcl:117 #: ../src/pd_menus.tcl:100 ../src/pd_menus.tcl:101 ../src/pd_menus.tcl:146 #: ../src/pd_menus.tcl:147 msgid "Copy" msgstr "ਨਕਲ" #: ../src/dialog_array.tcl:118 ../src/dialog_array.tcl:120 #: ../src/pd_menus.tcl:102 ../src/pd_menus.tcl:103 ../src/pd_menus.tcl:148 #: ../src/pd_menus.tcl:149 #, fuzzy msgid "Paste" msgstr "ਮਿਤੀ" #: ../src/dialog_array.tcl:264 ../src/dialog_array.tcl:266 msgid "Array Properties" msgstr "" #: ../src/dialog_array.tcl:270 ../src/dialog_array.tcl:272 #, fuzzy msgid "Name:" msgstr "ਨਾਂ" #: ../src/dialog_array.tcl:276 ../src/dialog_array.tcl:278 #: ../src/dialog_canvas.tcl:178 ../src/dialog_canvas.tcl:193 #: ../src/dialog_iemgui.tcl:619 ../src/dialog_iemgui.tcl:621 msgid "Size:" msgstr "ਅਕਾਰ:" #: ../src/dialog_array.tcl:280 ../src/dialog_array.tcl:282 #, fuzzy msgid "Save contents" msgstr "ਭਾਗ(_C)" #: ../src/dialog_array.tcl:284 ../src/dialog_array.tcl:286 msgid "Draw as:" msgstr "" #: ../src/dialog_array.tcl:287 ../src/dialog_array.tcl:289 #, fuzzy msgid "Points" msgstr "ਪੋਰਟ" #: ../src/dialog_array.tcl:289 ../src/dialog_array.tcl:291 #, fuzzy msgid "Polygon" msgstr "ਪੋਲੈਂਡ" #: ../src/dialog_array.tcl:291 ../src/dialog_array.tcl:293 msgid "Bezier curve" msgstr "" #: ../src/dialog_array.tcl:297 ../src/dialog_array.tcl:299 msgid "Put array into:" msgstr "" #: ../src/dialog_array.tcl:300 ../src/dialog_array.tcl:302 msgid "New graph" msgstr "" #: ../src/dialog_array.tcl:302 ../src/dialog_array.tcl:304 #, fuzzy msgid "Last graph" msgstr "ਆਖਰੀ ਸੁਨੇਹਾ:" #: ../src/dialog_array.tcl:306 ../src/dialog_array.tcl:308 #, fuzzy msgid "Delete array" msgstr "ਹਟਾਓ" #: ../src/dialog_array.tcl:312 ../src/dialog_array.tcl:314 #, fuzzy msgid "Open List View..." msgstr "ਪਾਬੰਦੀ ਸੂਚੀ..." #: ../src/dialog_array.tcl:319 ../src/dialog_array.tcl:321 #: ../src/dialog_audio.tcl:136 ../src/dialog_canvas.tcl:205 #: ../src/dialog_font.tcl:51 ../src/dialog_gatom.tcl:153 #: ../src/dialog_gatom.tcl:161 ../src/dialog_iemgui.tcl:742 #: ../src/dialog_iemgui.tcl:748 ../src/dialog_midi.tcl:91 #: ../src/dialog_midi.tcl:226 msgid "Cancel" msgstr "ਰੱਦ" #: ../src/dialog_array.tcl:321 ../src/dialog_array.tcl:323 #: ../src/dialog_audio.tcl:138 ../src/dialog_canvas.tcl:207 #: ../src/dialog_gatom.tcl:156 ../src/dialog_gatom.tcl:164 #: ../src/dialog_iemgui.tcl:745 ../src/dialog_iemgui.tcl:751 #: ../src/dialog_midi.tcl:93 ../src/dialog_midi.tcl:228 msgid "Apply" msgstr "ਲਾਗੂ" #: ../src/dialog_array.tcl:323 ../src/dialog_array.tcl:325 #: ../src/dialog_audio.tcl:140 ../src/dialog_canvas.tcl:209 #: ../src/dialog_font.tcl:53 ../src/dialog_font.tcl:92 #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:101 #: ../src/dialog_gatom.tcl:159 ../src/dialog_gatom.tcl:167 #: ../src/dialog_iemgui.tcl:748 ../src/dialog_iemgui.tcl:754 #: ../src/dialog_midi.tcl:95 ../src/dialog_midi.tcl:230 msgid "OK" msgstr "" #: ../src/dialog_audio.tcl:130 msgid "Audio Settings" msgstr "" #: ../src/dialog_audio.tcl:142 msgid "Save All Settings" msgstr "" #: ../src/dialog_audio.tcl:151 msgid "Sample rate:" msgstr "" #: ../src/dialog_audio.tcl:153 msgid "Delay (msec):" msgstr "" #: ../src/dialog_audio.tcl:158 msgid "Use callbacks" msgstr "" #: ../src/dialog_audio.tcl:166 ../src/dialog_midi.tcl:105 #: ../src/dialog_midi.tcl:241 msgid "Input device 1:" msgstr "" #: ../src/dialog_audio.tcl:169 ../src/dialog_audio.tcl:183 #: ../src/dialog_audio.tcl:198 ../src/dialog_audio.tcl:213 #: ../src/dialog_audio.tcl:232 ../src/dialog_audio.tcl:250 #: ../src/dialog_audio.tcl:265 ../src/dialog_audio.tcl:280 #, fuzzy msgid "Channels:" msgstr "ਰੱਦ" #: ../src/dialog_audio.tcl:179 ../src/dialog_midi.tcl:115 #: ../src/dialog_midi.tcl:251 msgid "Input device 2:" msgstr "" #: ../src/dialog_audio.tcl:194 ../src/dialog_midi.tcl:127 #: ../src/dialog_midi.tcl:263 msgid "Input device 3:" msgstr "" #: ../src/dialog_audio.tcl:209 ../src/dialog_midi.tcl:139 #: ../src/dialog_midi.tcl:275 msgid "Input device 4:" msgstr "" #: ../src/dialog_audio.tcl:223 ../src/dialog_midi.tcl:150 #: ../src/dialog_midi.tcl:286 msgid "Output device 1:" msgstr "" #: ../src/dialog_audio.tcl:226 msgid "(same as input device) .............. " msgstr "" #: ../src/dialog_audio.tcl:246 ../src/dialog_midi.tcl:160 #: ../src/dialog_midi.tcl:296 msgid "Output device 2:" msgstr "" #: ../src/dialog_audio.tcl:261 ../src/dialog_midi.tcl:171 #: ../src/dialog_midi.tcl:307 msgid "Output device 3:" msgstr "" #: ../src/dialog_audio.tcl:276 ../src/dialog_midi.tcl:182 #: ../src/dialog_midi.tcl:318 msgid "Output device 4:" msgstr "" #: ../src/dialog_audio.tcl:291 ../src/dialog_midi.tcl:195 msgid "Use multiple devices" msgstr "" #: ../src/dialog_canvas.tcl:142 msgid "Canvas Properties" msgstr "" #: ../src/dialog_canvas.tcl:146 #, fuzzy msgid "Scale" msgstr "ਸੰਭਾਲੋ" #: ../src/dialog_canvas.tcl:150 msgid "X units per pixel:" msgstr "" #: ../src/dialog_canvas.tcl:155 msgid "Y units per pixel:" msgstr "" #: ../src/dialog_canvas.tcl:159 msgid "Appearance on parent patch" msgstr "" #: ../src/dialog_canvas.tcl:161 msgid "Graph-On-Parent" msgstr "" #: ../src/dialog_canvas.tcl:165 msgid "Hide object name and arguments" msgstr "" #: ../src/dialog_canvas.tcl:170 msgid "Range and size" msgstr "" #: ../src/dialog_canvas.tcl:174 msgid "X range, from" msgstr "" #: ../src/dialog_canvas.tcl:176 ../src/dialog_canvas.tcl:191 msgid "to" msgstr "" #: ../src/dialog_canvas.tcl:180 ../src/dialog_canvas.tcl:195 #, fuzzy msgid "Margin:" msgstr "ਨਿਸ਼ਾਨ ਰੇਖਾ:" #: ../src/dialog_canvas.tcl:189 msgid "Y range, from" msgstr "" #: ../src/dialog_find.tcl:63 ../src/dialog_find.tcl:66 #: ../src/dialog_find.tcl:79 ../src/dialog_find.tcl:80 #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:85 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:101 #: ../src/dialog_find.tcl:105 ../src/dialog_find.tcl:107 #: ../src/pd_menus.tcl:45 msgid "Find" msgstr "ਖੋਜ" #: ../src/dialog_find.tcl:70 ../src/dialog_find.tcl:73 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:91 #: ../src/dialog_find.tcl:93 #, fuzzy msgid "Search in" msgstr "ਪਾਠ ਖੋਜ..." #: ../src/dialog_find.tcl:72 ../src/dialog_find.tcl:75 #: ../src/dialog_find.tcl:89 ../src/dialog_find.tcl:93 #: ../src/dialog_find.tcl:95 #, fuzzy msgid "for:" msgstr "ਪੋਰਟ:" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:90 #: ../src/dialog_find.tcl:104 ../src/dialog_find.tcl:108 #: ../src/dialog_find.tcl:110 ../src/pd_menus.tcl:86 ../src/pd_menus.tcl:87 #: ../src/pd_menus.tcl:132 ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:259 #: ../src/pd_menus.tcl:272 ../src/pd_menus.tcl:295 ../src/pd_menus.tcl:308 #: ../src/pd_menus.tcl:332 ../src/pd_menus.tcl:345 ../src/pd_menus.tcl:354 #: ../src/pd_menus.tcl:381 ../src/pd_menus.tcl:392 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:431 ../src/pd_menus.tcl:458 msgid "Close" msgstr "ਬੰਦ ਕਰੋ" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:97 #: ../src/dialog_find.tcl:101 ../src/dialog_find.tcl:103 msgid "Match whole word only" msgstr "" #: ../src/dialog_find.tcl:92 ../src/dialog_font.tcl:49 #: ../src/dialog_font.tcl:50 ../src/pd-gui.tcl:280 ../src/pd-gui.tcl:283 #: ../src/pd-gui.tcl:286 ../src/pd-gui.tcl:288 ../src/pd-gui.tcl:291 #: ../src/pd_menus.tcl:212 ../src/pd_menus.tcl:258 ../src/pd_menus.tcl:285 #: ../src/pdwindow.tcl:33 #, fuzzy msgid "Pd window" msgstr "ਭੇਜਣ ਝਰੋਖਾ" #: ../src/dialog_font.tcl:45 msgid "Font Properties" msgstr "" #: ../src/dialog_font.tcl:46 ../src/dialog_font.tcl:54 #: ../src/dialog_font.tcl:55 #, fuzzy, tcl-format msgid "%s Font" msgstr "ਫੋਂਟ:" #: ../src/dialog_font.tcl:61 ../src/dialog_font.tcl:96 #: ../src/dialog_font.tcl:104 ../src/dialog_font.tcl:105 #, fuzzy msgid "Font Size" msgstr "ਅਕਾਰ:" #: ../src/dialog_font.tcl:89 ../src/dialog_font.tcl:108 #: ../src/dialog_font.tcl:116 ../src/dialog_font.tcl:117 #, fuzzy msgid "Stretch" msgstr "ਸ਼ੁਰੂ:" #: ../src/dialog_font.tcl:96 ../src/dialog_font.tcl:115 #: ../src/dialog_font.tcl:123 ../src/dialog_font.tcl:124 msgid "X and Y" msgstr "" #: ../src/dialog_font.tcl:98 ../src/dialog_font.tcl:117 #: ../src/dialog_font.tcl:125 ../src/dialog_font.tcl:126 msgid "X only" msgstr "" #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:119 #: ../src/dialog_font.tcl:127 ../src/dialog_font.tcl:128 msgid "Y only" msgstr "" #: ../src/dialog_gatom.tcl:93 msgid "Atom Box Properties" msgstr "" #: ../src/dialog_gatom.tcl:99 msgid "Width:" msgstr "" #: ../src/dialog_gatom.tcl:103 #, fuzzy msgid "Limits" msgstr "ਉਪਭੋਗੀ ਸੀਮਾ" #: ../src/dialog_gatom.tcl:107 msgid "Lower:" msgstr "" #: ../src/dialog_gatom.tcl:112 ../src/dialog_gatom.tcl:113 #, fuzzy msgid "Upper:" msgstr "ਉਪਭੋਗੀ:" #: ../src/dialog_gatom.tcl:116 ../src/dialog_gatom.tcl:121 #: ../src/dialog_iemgui.tcl:600 ../src/dialog_iemgui.tcl:652 #: ../src/dialog_iemgui.tcl:657 msgid "Label" msgstr "" #: ../src/dialog_gatom.tcl:124 ../src/dialog_gatom.tcl:129 #, fuzzy msgid "Left " msgstr "ਖੱਬਾ" #: ../src/dialog_gatom.tcl:126 ../src/dialog_gatom.tcl:131 msgid "Right" msgstr "ਸੱਜਾ" #: ../src/dialog_gatom.tcl:128 ../src/dialog_gatom.tcl:133 msgid "Top" msgstr "ਉੱਪਰ" #: ../src/dialog_gatom.tcl:130 ../src/dialog_gatom.tcl:135 msgid "Bottom" msgstr "ਹੇਠਾਂ" #: ../src/dialog_gatom.tcl:137 ../src/dialog_gatom.tcl:145 #: ../src/dialog_iemgui.tcl:574 #, fuzzy msgid "Messages" msgstr "ਸੁਨੇਹਾ" #: ../src/dialog_gatom.tcl:141 ../src/dialog_gatom.tcl:149 #: ../src/dialog_iemgui.tcl:578 msgid "Send symbol:" msgstr "" #: ../src/dialog_gatom.tcl:147 ../src/dialog_gatom.tcl:155 #: ../src/dialog_iemgui.tcl:585 #, fuzzy msgid "Receive symbol:" msgstr "ਪ੍ਰਾਪਤੀ ਝਰੋਖਾ" #: ../src/dialog_iemgui.tcl:197 #, fuzzy msgid "Background color" msgstr "ਪਿੱਠਭੂਮੀ:" #: ../src/dialog_iemgui.tcl:204 #, fuzzy msgid "Foreground color" msgstr "ਮੁੱਖ-ਭੂਮੀ:" #: ../src/dialog_iemgui.tcl:211 #, fuzzy msgid "Label color" msgstr "ਚੋਣ ਰੰਗ" #: ../src/dialog_iemgui.tcl:272 #, fuzzy msgid "Init" msgstr "ਸੱਦਾ" #: ../src/dialog_iemgui.tcl:275 ../src/dialog_iemgui.tcl:546 msgid "No init" msgstr "" #: ../src/dialog_iemgui.tcl:287 ../src/dialog_iemgui.tcl:558 msgid "Jump on click" msgstr "" #: ../src/dialog_iemgui.tcl:290 ../src/dialog_iemgui.tcl:561 msgid "Steady on click" msgstr "" #: ../src/dialog_iemgui.tcl:498 #, tcl-format msgid "%s Properties" msgstr "" #: ../src/dialog_iemgui.tcl:550 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:84 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:130 ../src/pd_menus.tcl:260 #: ../src/pd_menus.tcl:273 ../src/pd_menus.tcl:288 ../src/pd_menus.tcl:301 #: ../src/pd_menus.tcl:325 ../src/pd_menus.tcl:338 ../src/pd_menus.tcl:355 #: ../src/pd_menus.tcl:382 ../src/pd_menus.tcl:383 ../src/pd_menus.tcl:410 #: ../src/pd_menus.tcl:422 ../src/pd_menus.tcl:449 msgid "Save" msgstr "ਸੰਭਾਲੋ" #: ../src/dialog_iemgui.tcl:608 msgid "X offset" msgstr "" #: ../src/dialog_iemgui.tcl:611 ../src/dialog_iemgui.tcl:612 msgid "Y offset" msgstr "" #: ../src/dialog_iemgui.tcl:642 ../src/dialog_iemgui.tcl:645 msgid "Colors" msgstr "ਰੰਗ" #: ../src/dialog_iemgui.tcl:648 ../src/dialog_iemgui.tcl:651 #, fuzzy msgid "Background" msgstr "ਪਿੱਠਭੂਮੀ:" #: ../src/dialog_iemgui.tcl:650 ../src/dialog_iemgui.tcl:654 #, fuzzy msgid "Front" msgstr "ਫੋਂਟ:" #: ../src/dialog_iemgui.tcl:662 ../src/dialog_iemgui.tcl:668 msgid "Compose color" msgstr "" #: ../src/dialog_iemgui.tcl:682 ../src/dialog_iemgui.tcl:688 #, fuzzy msgid "Test label" msgstr "ਸਭ ਦੀ ਜਾਂਚ" #: ../src/dialog_midi.tcl:85 msgid "MIDI Settings" msgstr "" #: ../src/dialog_midi.tcl:220 msgid "ALSA MIDI Settings" msgstr "" #: ../src/dialog_midi.tcl:331 msgid "Use multiple ALSA devices" msgstr "" #: ../src/dialog_midi.tcl:337 msgid "In Ports:" msgstr "" #: ../src/dialog_midi.tcl:340 msgid "Out Ports:" msgstr "" #: ../src/g_editor.c:1663 msgid "Discard changes to this window??" msgstr "" #: ../src/g_editor.c:1668 msgid "really quit?" msgstr "" #: ../src/g_editor.c:1699 #, fuzzy msgid "Close this window??" msgstr "ਝਰੋਖਾ ਬੰਦ(_C)" #: ../src/pd-gui.tcl:185 ../src/pd-gui.tcl:195 ../src/pd-gui.tcl:203 #: ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:215 ../src/pd-gui.tcl:226 msgid "Associated Files" msgstr "" #: ../src/pd-gui.tcl:186 ../src/pd-gui.tcl:196 ../src/pd-gui.tcl:204 #: ../src/pd-gui.tcl:207 ../src/pd-gui.tcl:216 ../src/pd-gui.tcl:227 #, fuzzy msgid "Pd Files" msgstr "ਫਾਇਲ" #: ../src/pd-gui.tcl:187 ../src/pd-gui.tcl:205 ../src/pd-gui.tcl:208 #: ../src/pd-gui.tcl:228 msgid "Max Patch Files" msgstr "" #: ../src/pd-gui.tcl:188 ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:209 #: ../src/pd-gui.tcl:229 msgid "Max Text Files" msgstr "" #: ../src/pd-gui.tcl:197 ../src/pd-gui.tcl:217 msgid "Max Patch Files (.pat)" msgstr "" #: ../src/pd-gui.tcl:198 ../src/pd-gui.tcl:218 msgid "Max Text Files (.mxt)" msgstr "" #: ../src/pd-gui.tcl:270 ../src/pd-gui.tcl:290 #, tcl-format msgid "WARNING: Font family '%s' not found, using default (%s)" msgstr "" #: ../src/pd-gui.tcl:278 ../src/pd-gui.tcl:298 #, tcl-format msgid "WARNING: Font weight '%s' not found, using default (%s)" msgstr "" #: ../src/pd-gui.tcl:303 ../src/pd-gui.tcl:323 #, tcl-format msgid "ERROR: %s failed to find font size (%s) that fits into %sx%s!" msgstr "" #: ../src/pd-gui.tcl:478 ../src/pd-gui.tcl:483 ../src/pd-gui.tcl:501 msgid "ERROR: 'pd' never showed up, 'pd-gui' quitting!" msgstr "" #: ../src/pd_menucommands.tcl:19 msgid "Untitled" msgstr "" #: ../src/pd_menucommands.tcl:78 ../src/pd_menucommands.tcl:79 #: ../src/pd_menucommands.tcl:90 #, fuzzy msgid "Send Message..." msgstr "ਸੁਨੇਹਾ" #: ../src/pd_menucommands.tcl:82 ../src/pd_menucommands.tcl:83 #: ../src/pd_menucommands.tcl:94 ../src/pd_menus.tcl:87 ../src/pd_menus.tcl:88 #: ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:134 ../src/pd_menus.tcl:147 #: ../src/pd_menus.tcl:192 ../src/pd_menus.tcl:193 ../src/pd_menus.tcl:265 #: ../src/pd_menus.tcl:278 ../src/pd_menus.tcl:292 ../src/pd_menus.tcl:305 #: ../src/pd_menus.tcl:329 ../src/pd_menus.tcl:342 ../src/pd_menus.tcl:360 #: ../src/pd_menus.tcl:387 ../src/pd_menus.tcl:414 ../src/pd_menus.tcl:426 #: ../src/pd_menus.tcl:453 ../startup/object_db.tcl:123 msgid "Message" msgstr "ਸੁਨੇਹਾ" #: ../src/pd_menucommands.tcl:108 ../src/pd_menucommands.tcl:111 #: ../src/pd_menus.tcl:112 ../src/pd_menus.tcl:113 ../src/pd_menus.tcl:117 #: ../src/pd_menus.tcl:118 ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:159 #: ../src/pd_menus.tcl:163 ../src/pd_menus.tcl:164 #, fuzzy msgid "Font" msgstr "ਫੋਂਟ:" #: ../src/pd_menucommands.tcl:123 ../src/pd_menucommands.tcl:126 #: ../src/pd_menus.tcl:138 ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:184 #, fuzzy msgid "Preferences" msgstr "ਮੇਰੀ ਪਸੰਦ..." #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Edit" msgstr "ਸੋਧ(_E)" #: ../src/pd_menus.tcl:45 msgid "File" msgstr "ਫਾਇਲ" #: ../src/pd_menus.tcl:45 ../src/pdtk_canvas.tcl:48 ../src/pdtk_canvas.tcl:110 #: ../src/pdtk_canvas.tcl:113 msgid "Help" msgstr "ਸਹਾਇਤਾ" #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Media" msgstr "ਮੈਕਡੋਨੀਆ" #: ../src/pd_menus.tcl:45 msgid "Put" msgstr "" #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Window" msgstr "ਝਰੋਖਾ(_W)" #: ../src/pd_menus.tcl:81 ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:127 #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:255 ../src/pd_menus.tcl:267 #: ../src/pd_menus.tcl:285 ../src/pd_menus.tcl:298 ../src/pd_menus.tcl:322 #: ../src/pd_menus.tcl:335 ../src/pd_menus.tcl:349 ../src/pd_menus.tcl:376 #: ../src/pd_menus.tcl:380 ../src/pd_menus.tcl:407 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:446 #, fuzzy msgid "New" msgstr "ਨਵਾਂ(_N)" #: ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:128 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:268 #: ../src/pd_menus.tcl:286 ../src/pd_menus.tcl:299 ../src/pd_menus.tcl:323 #: ../src/pd_menus.tcl:336 ../src/pd_menus.tcl:350 ../src/pd_menus.tcl:377 #: ../src/pd_menus.tcl:381 ../src/pd_menus.tcl:408 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:447 ../src/pdtk_canvas.tcl:46 #: ../src/pdtk_canvas.tcl:108 ../src/pdtk_canvas.tcl:111 #: ../src/pdtk_canvas.tcl:128 ../src/pdtk_canvas.tcl:130 #: ../src/pdtk_canvas.tcl:131 ../src/pdtk_canvas.tcl:133 msgid "Open" msgstr "ਖੋਲੋ" #: ../src/pd_menus.tcl:84 ../src/pd_menus.tcl:85 ../src/pd_menus.tcl:130 #: ../src/pd_menus.tcl:131 ../src/pd_menus.tcl:261 ../src/pd_menus.tcl:274 #: ../src/pd_menus.tcl:289 ../src/pd_menus.tcl:302 ../src/pd_menus.tcl:326 #: ../src/pd_menus.tcl:339 ../src/pd_menus.tcl:356 ../src/pd_menus.tcl:383 #: ../src/pd_menus.tcl:384 ../src/pd_menus.tcl:411 ../src/pd_menus.tcl:423 #: ../src/pd_menus.tcl:450 msgid "Save As..." msgstr "ਇੰਞ ਸੰਭਾਲੋ..." #: ../src/pd_menus.tcl:88 ../src/pd_menus.tcl:89 ../src/pd_menus.tcl:134 #: ../src/pd_menus.tcl:135 ../src/pd_menus.tcl:267 ../src/pd_menus.tcl:280 #: ../src/pd_menus.tcl:293 ../src/pd_menus.tcl:306 ../src/pd_menus.tcl:330 #: ../src/pd_menus.tcl:343 ../src/pd_menus.tcl:362 ../src/pd_menus.tcl:388 #: ../src/pd_menus.tcl:389 ../src/pd_menus.tcl:415 ../src/pd_menus.tcl:427 #: ../src/pd_menus.tcl:454 #, fuzzy msgid "Print..." msgstr "ਸੋਧ(_E)..." #: ../src/pd_menus.tcl:93 ../src/pd_menus.tcl:94 ../src/pd_menus.tcl:139 #: ../src/pd_menus.tcl:140 #, fuzzy msgid "Undo" msgstr "ਯੂਗਾਂਡਾ" #: ../src/pd_menus.tcl:95 ../src/pd_menus.tcl:96 ../src/pd_menus.tcl:141 #: ../src/pd_menus.tcl:142 #, fuzzy msgid "Redo" msgstr "ਲਾਲ:" #: ../src/pd_menus.tcl:98 ../src/pd_menus.tcl:99 ../src/pd_menus.tcl:144 #: ../src/pd_menus.tcl:145 msgid "Cut" msgstr "" #: ../src/pd_menus.tcl:104 ../src/pd_menus.tcl:105 ../src/pd_menus.tcl:150 #: ../src/pd_menus.tcl:151 #, fuzzy msgid "Duplicate" msgstr "ਮਿਤੀ" #: ../src/pd_menus.tcl:106 ../src/pd_menus.tcl:107 ../src/pd_menus.tcl:152 #: ../src/pd_menus.tcl:153 #, fuzzy msgid "Select All" msgstr "ਚੋਣ ਰੰਗ" #: ../src/pd_menus.tcl:110 ../src/pd_menus.tcl:111 ../src/pd_menus.tcl:115 #: ../src/pd_menus.tcl:116 ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:157 #: ../src/pd_menus.tcl:161 ../src/pd_menus.tcl:162 #, fuzzy msgid "Text Editor" msgstr "ਪਾਠ ਰੰਗ" #: ../src/pd_menus.tcl:120 ../src/pd_menus.tcl:121 ../src/pd_menus.tcl:166 #: ../src/pd_menus.tcl:167 msgid "Tidy Up" msgstr "" #: ../src/pd_menus.tcl:122 ../src/pd_menus.tcl:123 ../src/pd_menus.tcl:168 #: ../src/pd_menus.tcl:169 msgid "Toggle Console" msgstr "" #: ../src/pd_menus.tcl:124 ../src/pd_menus.tcl:125 ../src/pd_menus.tcl:170 #: ../src/pd_menus.tcl:171 #, fuzzy msgid "Clear Console" msgstr "ਸੂਚੀ ਸਾਫ਼" #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:174 #: ../src/pd_menus.tcl:175 #, fuzzy msgid "Edit Mode" msgstr "ਮੋਡ" #: ../src/pd_menus.tcl:145 ../src/pd_menus.tcl:190 ../src/pd_menus.tcl:191 msgid "Object" msgstr "" #: ../src/pd_menus.tcl:149 ../src/pd_menus.tcl:194 ../src/pd_menus.tcl:195 #, fuzzy msgid "Number" msgstr "$ ਅੰਕ" #: ../src/pd_menus.tcl:151 ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:197 msgid "Symbol" msgstr "" #: ../src/pd_menus.tcl:153 ../src/pd_menus.tcl:198 ../src/pd_menus.tcl:199 #, fuzzy msgid "Comment" msgstr "ਕਮਾਂਡ" #: ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:201 ../src/pd_menus.tcl:202 #, fuzzy msgid "Bang" msgstr "ਪਾਬੰਦੀ" #: ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:203 ../src/pd_menus.tcl:204 #, fuzzy msgid "Toggle" msgstr "ਟੂਗੂ" #: ../src/pd_menus.tcl:160 ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:206 #, fuzzy msgid "Number2" msgstr "$ ਅੰਕ" #: ../src/pd_menus.tcl:162 ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:208 msgid "Vslider" msgstr "" #: ../src/pd_menus.tcl:164 ../src/pd_menus.tcl:209 ../src/pd_menus.tcl:210 #, fuzzy msgid "Hslider" msgstr "ਓਹਲੇ" #: ../src/pd_menus.tcl:166 ../src/pd_menus.tcl:211 ../src/pd_menus.tcl:212 #, fuzzy msgid "Vradio" msgstr "ਵਰਜਨ" #: ../src/pd_menus.tcl:168 ../src/pd_menus.tcl:213 ../src/pd_menus.tcl:214 msgid "Hradio" msgstr "" #: ../src/pd_menus.tcl:170 ../src/pd_menus.tcl:215 ../src/pd_menus.tcl:216 msgid "VU Meter" msgstr "" #: ../src/pd_menus.tcl:172 ../src/pd_menus.tcl:217 ../src/pd_menus.tcl:218 #, fuzzy msgid "Canvas" msgstr "ਕੈਨੇਡਾ" #: ../src/pd_menus.tcl:175 ../src/pd_menus.tcl:220 ../src/pd_menus.tcl:221 msgid "Graph" msgstr "ਗਰਾਫ਼" #: ../src/pd_menus.tcl:176 ../src/pd_menus.tcl:221 ../src/pd_menus.tcl:222 #, fuzzy msgid "Array" msgstr "ਅਡੂਰਾ" #: ../src/pd_menus.tcl:181 ../src/pd_menus.tcl:226 ../src/pd_menus.tcl:227 #, fuzzy msgid "Find..." msgstr "ਖੋਜ" #: ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:228 ../src/pd_menus.tcl:229 msgid "Find Again" msgstr "" #: ../src/pd_menus.tcl:185 ../src/pd_menus.tcl:230 ../src/pd_menus.tcl:231 msgid "Find Last Error" msgstr "" #: ../src/pd_menus.tcl:191 ../src/pd_menus.tcl:236 ../src/pd_menus.tcl:237 msgid "DSP On" msgstr "" #: ../src/pd_menus.tcl:193 ../src/pd_menus.tcl:238 ../src/pd_menus.tcl:239 #, fuzzy msgid "DSP Off" msgstr "ਬੰਦ" #: ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:242 ../src/pd_menus.tcl:269 msgid "Test Audio and MIDI..." msgstr "" #: ../src/pd_menus.tcl:198 ../src/pd_menus.tcl:244 ../src/pd_menus.tcl:271 msgid "Load Meter" msgstr "" #: ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:251 ../src/pd_menus.tcl:278 msgid "Minimize" msgstr "" #: ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:253 ../src/pd_menus.tcl:280 #, fuzzy msgid "Zoom" msgstr "ਹੇਠਾਂ" #: ../src/pd_menus.tcl:210 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:283 #, fuzzy msgid "Parent Window" msgstr "ਭੇਜਣ ਝਰੋਖਾ" #: ../src/pd_menus.tcl:216 ../src/pd_menus.tcl:262 ../src/pd_menus.tcl:289 msgid "Bring All to Front" msgstr "" #: ../src/pd_menus.tcl:224 ../src/pd_menus.tcl:241 ../src/pd_menus.tcl:253 #: ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:297 ../src/pd_menus.tcl:335 #: ../src/pd_menus.tcl:362 #, fuzzy msgid "About Pd" msgstr "ਇਸ ਬਾਰੇ(_A)" #: ../src/pd_menus.tcl:227 ../src/pd_menus.tcl:273 ../src/pd_menus.tcl:300 msgid "HTML Manual..." msgstr "" #: ../src/pd_menus.tcl:229 ../src/pd_menus.tcl:275 ../src/pd_menus.tcl:302 #, fuzzy msgid "Browser..." msgstr "ਝਲਕ..." #: ../src/pd_menus.tcl:248 ../src/pd_menus.tcl:260 ../src/pd_menus.tcl:342 #: ../src/pd_menus.tcl:369 msgid "Preferences..." msgstr "ਮੇਰੀ ਪਸੰਦ..." #: ../src/pd_menus.tcl:257 ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:352 #: ../src/pd_menus.tcl:379 msgid "Open Recent" msgstr "" #: ../src/pd_menus.tcl:263 msgid "Audio Settings..." msgstr "" #: ../src/pd_menus.tcl:265 msgid "MIDI Settings..." msgstr "" #: ../src/pd_menus.tcl:296 ../src/pd_menus.tcl:309 ../src/pd_menus.tcl:333 #: ../src/pd_menus.tcl:346 ../src/pd_menus.tcl:393 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:432 ../src/pd_menus.tcl:459 #, fuzzy msgid "Quit" msgstr "ਬਾਹਰ(_Q)" #: ../src/pd_menus.tcl:304 ../src/pd_menus.tcl:331 #, fuzzy msgid "Clear Menu" msgstr "ਸੂਚੀ ਸਾਫ਼" #: ../src/pdtk_canvas.tcl:44 ../src/pdtk_canvas.tcl:106 #: ../src/pdtk_canvas.tcl:109 ../src/pdtk_canvas.tcl:123 #: ../src/pdtk_canvas.tcl:125 ../src/pdtk_canvas.tcl:126 #: ../src/pdtk_canvas.tcl:128 msgid "Properties" msgstr "" #: ../src/pdwindow.tcl:43 #, fuzzy msgid "DSP" msgstr "ਬੰਦ" #: ../startup/object_db.tcl:113 msgid "Signal" msgstr "" #: ../startup/object_db.tcl:114 msgid "Generators" msgstr "" #: ../startup/object_db.tcl:115 #, fuzzy msgid "Filters" msgstr "ਫਾਇਲ" #: ../startup/object_db.tcl:116 ../startup/object_db.tcl:124 msgid "Math" msgstr "" #: ../startup/object_db.tcl:117 ../startup/object_db.tcl:125 msgid "I/O" msgstr "" #: ../startup/object_db.tcl:118 ../startup/object_db.tcl:126 msgid "Sampling" msgstr "" #: ../startup/object_db.tcl:119 ../startup/object_db.tcl:128 msgid "Routing" msgstr "" #: ../startup/object_db.tcl:120 ../startup/object_db.tcl:129 msgid "Others" msgstr "" #: ../startup/object_db.tcl:127 msgid "GUI" msgstr "" pd-0.46-7/po/sq.po0000664000175000017500000006007212160204055011775 0ustar mspmsp# translation of Pure Data to Albanian # This file is put in the public domain. # Besnik Bleta , 2004. # msgid "" msgstr "" "Project-Id-Version: Pure Data 0.43\n" "Report-Msgid-Bugs-To: pd-dev@iem.at\n" "POT-Creation-Date: 2009-08-27 10:01-0400\n" "PO-Revision-Date: 2005-03-07 11:12+0200\n" "Last-Translator: Besnik Bleta \n" "Language-Team: Albanian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #, fuzzy msgid "Undo duplicate" msgstr "Datë" msgid "Undo paste" msgstr "" msgid "Undo motion" msgstr "" #, fuzzy msgid "Undo cut" msgstr "Uganda" msgid "Undo disconnect" msgstr "" msgid "Undo connect" msgstr "" msgid "Undo clear" msgstr "" msgid "Undo typing" msgstr "" msgid "Discard changes to '%s'?" msgstr "" msgid "Do you want to save the changes you made in '%s'?" msgstr "" #: ../src/dialog_array.tcl:115 ../src/dialog_array.tcl:117 #: ../src/pd_menus.tcl:100 ../src/pd_menus.tcl:101 ../src/pd_menus.tcl:146 #: ../src/pd_menus.tcl:147 msgid "Copy" msgstr "Kopjo" #: ../src/dialog_array.tcl:118 ../src/dialog_array.tcl:120 #: ../src/pd_menus.tcl:102 ../src/pd_menus.tcl:103 ../src/pd_menus.tcl:148 #: ../src/pd_menus.tcl:149 #, fuzzy msgid "Paste" msgstr "Datë" #: ../src/dialog_array.tcl:264 ../src/dialog_array.tcl:266 msgid "Array Properties" msgstr "" #: ../src/dialog_array.tcl:270 ../src/dialog_array.tcl:272 #, fuzzy msgid "Name:" msgstr "Emër" #: ../src/dialog_array.tcl:276 ../src/dialog_array.tcl:278 #: ../src/dialog_canvas.tcl:178 ../src/dialog_canvas.tcl:193 #: ../src/dialog_iemgui.tcl:619 ../src/dialog_iemgui.tcl:621 #, fuzzy msgid "Size:" msgstr "Madhësi" #: ../src/dialog_array.tcl:280 ../src/dialog_array.tcl:282 #, fuzzy msgid "Save contents" msgstr "_Përmbajtje" #: ../src/dialog_array.tcl:284 ../src/dialog_array.tcl:286 msgid "Draw as:" msgstr "" #: ../src/dialog_array.tcl:287 ../src/dialog_array.tcl:289 #, fuzzy msgid "Points" msgstr "Portë" #: ../src/dialog_array.tcl:289 ../src/dialog_array.tcl:291 #, fuzzy msgid "Polygon" msgstr "Poloni" #: ../src/dialog_array.tcl:291 ../src/dialog_array.tcl:293 msgid "Bezier curve" msgstr "" #: ../src/dialog_array.tcl:297 ../src/dialog_array.tcl:299 msgid "Put array into:" msgstr "" #: ../src/dialog_array.tcl:300 ../src/dialog_array.tcl:302 msgid "New graph" msgstr "" #: ../src/dialog_array.tcl:302 ../src/dialog_array.tcl:304 #, fuzzy msgid "Last graph" msgstr "Msz i Fundit: %s" #: ../src/dialog_array.tcl:306 ../src/dialog_array.tcl:308 #, fuzzy msgid "Delete array" msgstr "Fshij" #: ../src/dialog_array.tcl:312 ../src/dialog_array.tcl:314 #, fuzzy msgid "Open List View..." msgstr "Listë Ndalimesh..." #: ../src/dialog_array.tcl:319 ../src/dialog_array.tcl:321 #: ../src/dialog_audio.tcl:136 ../src/dialog_canvas.tcl:205 #: ../src/dialog_font.tcl:51 ../src/dialog_gatom.tcl:153 #: ../src/dialog_gatom.tcl:161 ../src/dialog_iemgui.tcl:742 #: ../src/dialog_iemgui.tcl:748 ../src/dialog_midi.tcl:91 #: ../src/dialog_midi.tcl:226 msgid "Cancel" msgstr "Anulo" #: ../src/dialog_array.tcl:321 ../src/dialog_array.tcl:323 #: ../src/dialog_audio.tcl:138 ../src/dialog_canvas.tcl:207 #: ../src/dialog_gatom.tcl:156 ../src/dialog_gatom.tcl:164 #: ../src/dialog_iemgui.tcl:745 ../src/dialog_iemgui.tcl:751 #: ../src/dialog_midi.tcl:93 ../src/dialog_midi.tcl:228 msgid "Apply" msgstr "Zbato" #: ../src/dialog_array.tcl:323 ../src/dialog_array.tcl:325 #: ../src/dialog_audio.tcl:140 ../src/dialog_canvas.tcl:209 #: ../src/dialog_font.tcl:53 ../src/dialog_font.tcl:92 #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:101 #: ../src/dialog_gatom.tcl:159 ../src/dialog_gatom.tcl:167 #: ../src/dialog_iemgui.tcl:748 ../src/dialog_iemgui.tcl:754 #: ../src/dialog_midi.tcl:95 ../src/dialog_midi.tcl:230 msgid "OK" msgstr "" #: ../src/dialog_audio.tcl:130 msgid "Audio Settings" msgstr "" #: ../src/dialog_audio.tcl:142 msgid "Save All Settings" msgstr "" #: ../src/dialog_audio.tcl:151 msgid "Sample rate:" msgstr "" #: ../src/dialog_audio.tcl:153 msgid "Delay (msec):" msgstr "" #: ../src/dialog_audio.tcl:158 msgid "Use callbacks" msgstr "" #: ../src/dialog_audio.tcl:166 ../src/dialog_midi.tcl:105 #: ../src/dialog_midi.tcl:241 msgid "Input device 1:" msgstr "" #: ../src/dialog_audio.tcl:169 ../src/dialog_audio.tcl:183 #: ../src/dialog_audio.tcl:198 ../src/dialog_audio.tcl:213 #: ../src/dialog_audio.tcl:232 ../src/dialog_audio.tcl:250 #: ../src/dialog_audio.tcl:265 ../src/dialog_audio.tcl:280 #, fuzzy msgid "Channels:" msgstr "Anulo" #: ../src/dialog_audio.tcl:179 ../src/dialog_midi.tcl:115 #: ../src/dialog_midi.tcl:251 msgid "Input device 2:" msgstr "" #: ../src/dialog_audio.tcl:194 ../src/dialog_midi.tcl:127 #: ../src/dialog_midi.tcl:263 msgid "Input device 3:" msgstr "" #: ../src/dialog_audio.tcl:209 ../src/dialog_midi.tcl:139 #: ../src/dialog_midi.tcl:275 msgid "Input device 4:" msgstr "" #: ../src/dialog_audio.tcl:223 ../src/dialog_midi.tcl:150 #: ../src/dialog_midi.tcl:286 msgid "Output device 1:" msgstr "" #: ../src/dialog_audio.tcl:226 msgid "(same as input device) .............. " msgstr "" #: ../src/dialog_audio.tcl:246 ../src/dialog_midi.tcl:160 #: ../src/dialog_midi.tcl:296 msgid "Output device 2:" msgstr "" #: ../src/dialog_audio.tcl:261 ../src/dialog_midi.tcl:171 #: ../src/dialog_midi.tcl:307 msgid "Output device 3:" msgstr "" #: ../src/dialog_audio.tcl:276 ../src/dialog_midi.tcl:182 #: ../src/dialog_midi.tcl:318 msgid "Output device 4:" msgstr "" #: ../src/dialog_audio.tcl:291 ../src/dialog_midi.tcl:195 msgid "Use multiple devices" msgstr "" #: ../src/dialog_canvas.tcl:142 msgid "Canvas Properties" msgstr "" #: ../src/dialog_canvas.tcl:146 #, fuzzy msgid "Scale" msgstr "Ruaj" #: ../src/dialog_canvas.tcl:150 msgid "X units per pixel:" msgstr "" #: ../src/dialog_canvas.tcl:155 msgid "Y units per pixel:" msgstr "" #: ../src/dialog_canvas.tcl:159 msgid "Appearance on parent patch" msgstr "" #: ../src/dialog_canvas.tcl:161 msgid "Graph-On-Parent" msgstr "" #: ../src/dialog_canvas.tcl:165 msgid "Hide object name and arguments" msgstr "" #: ../src/dialog_canvas.tcl:170 msgid "Range and size" msgstr "" #: ../src/dialog_canvas.tcl:174 msgid "X range, from" msgstr "" #: ../src/dialog_canvas.tcl:176 ../src/dialog_canvas.tcl:191 msgid "to" msgstr "" #: ../src/dialog_canvas.tcl:180 ../src/dialog_canvas.tcl:195 #, fuzzy msgid "Margin:" msgstr "Vijë shënimi" #: ../src/dialog_canvas.tcl:189 msgid "Y range, from" msgstr "" #: ../src/dialog_find.tcl:63 ../src/dialog_find.tcl:66 #: ../src/dialog_find.tcl:79 ../src/dialog_find.tcl:80 #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:85 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:101 #: ../src/dialog_find.tcl:105 ../src/dialog_find.tcl:107 #: ../src/pd_menus.tcl:45 msgid "Find" msgstr "Gjej" #: ../src/dialog_find.tcl:70 ../src/dialog_find.tcl:73 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:91 #: ../src/dialog_find.tcl:93 #, fuzzy msgid "Search in" msgstr "Kërko Tekst..." #: ../src/dialog_find.tcl:72 ../src/dialog_find.tcl:75 #: ../src/dialog_find.tcl:89 ../src/dialog_find.tcl:93 #: ../src/dialog_find.tcl:95 #, fuzzy msgid "for:" msgstr "Portë:" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:90 #: ../src/dialog_find.tcl:104 ../src/dialog_find.tcl:108 #: ../src/dialog_find.tcl:110 ../src/pd_menus.tcl:86 ../src/pd_menus.tcl:87 #: ../src/pd_menus.tcl:132 ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:259 #: ../src/pd_menus.tcl:272 ../src/pd_menus.tcl:295 ../src/pd_menus.tcl:308 #: ../src/pd_menus.tcl:332 ../src/pd_menus.tcl:345 ../src/pd_menus.tcl:354 #: ../src/pd_menus.tcl:381 ../src/pd_menus.tcl:392 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:431 ../src/pd_menus.tcl:458 msgid "Close" msgstr "Mbyll" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:97 #: ../src/dialog_find.tcl:101 ../src/dialog_find.tcl:103 msgid "Match whole word only" msgstr "" #: ../src/dialog_find.tcl:92 ../src/dialog_font.tcl:49 #: ../src/dialog_font.tcl:50 ../src/pd-gui.tcl:280 ../src/pd-gui.tcl:283 #: ../src/pd-gui.tcl:286 ../src/pd-gui.tcl:288 ../src/pd-gui.tcl:291 #: ../src/pd_menus.tcl:212 ../src/pd_menus.tcl:258 ../src/pd_menus.tcl:285 #: ../src/pdwindow.tcl:33 #, fuzzy msgid "Pd window" msgstr "Dritare dërgimesh" #: ../src/dialog_font.tcl:45 msgid "Font Properties" msgstr "" #: ../src/dialog_font.tcl:46 ../src/dialog_font.tcl:54 #: ../src/dialog_font.tcl:55 #, fuzzy, tcl-format msgid "%s Font" msgstr "Gërma:" #: ../src/dialog_font.tcl:61 ../src/dialog_font.tcl:96 #: ../src/dialog_font.tcl:104 ../src/dialog_font.tcl:105 #, fuzzy msgid "Font Size" msgstr "Madhësi" #: ../src/dialog_font.tcl:89 ../src/dialog_font.tcl:108 #: ../src/dialog_font.tcl:116 ../src/dialog_font.tcl:117 #, fuzzy msgid "Stretch" msgstr "KohëFillim" #: ../src/dialog_font.tcl:96 ../src/dialog_font.tcl:115 #: ../src/dialog_font.tcl:123 ../src/dialog_font.tcl:124 msgid "X and Y" msgstr "" #: ../src/dialog_font.tcl:98 ../src/dialog_font.tcl:117 #: ../src/dialog_font.tcl:125 ../src/dialog_font.tcl:126 msgid "X only" msgstr "" #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:119 #: ../src/dialog_font.tcl:127 ../src/dialog_font.tcl:128 msgid "Y only" msgstr "" #: ../src/dialog_gatom.tcl:93 msgid "Atom Box Properties" msgstr "" #: ../src/dialog_gatom.tcl:99 msgid "Width:" msgstr "" #: ../src/dialog_gatom.tcl:103 #, fuzzy msgid "Limits" msgstr "Kufi Përdoruesi" #: ../src/dialog_gatom.tcl:107 msgid "Lower:" msgstr "" #: ../src/dialog_gatom.tcl:112 ../src/dialog_gatom.tcl:113 #, fuzzy msgid "Upper:" msgstr "Përdorues" #: ../src/dialog_gatom.tcl:116 ../src/dialog_gatom.tcl:121 #: ../src/dialog_iemgui.tcl:600 ../src/dialog_iemgui.tcl:652 #: ../src/dialog_iemgui.tcl:657 msgid "Label" msgstr "" #: ../src/dialog_gatom.tcl:124 ../src/dialog_gatom.tcl:129 #, fuzzy msgid "Left " msgstr "Majtas" #: ../src/dialog_gatom.tcl:126 ../src/dialog_gatom.tcl:131 msgid "Right" msgstr "Djathtas" #: ../src/dialog_gatom.tcl:128 ../src/dialog_gatom.tcl:133 msgid "Top" msgstr "Sipër" #: ../src/dialog_gatom.tcl:130 ../src/dialog_gatom.tcl:135 msgid "Bottom" msgstr "Poshtë" #: ../src/dialog_gatom.tcl:137 ../src/dialog_gatom.tcl:145 #: ../src/dialog_iemgui.tcl:574 #, fuzzy msgid "Messages" msgstr "Mesazh" #: ../src/dialog_gatom.tcl:141 ../src/dialog_gatom.tcl:149 #: ../src/dialog_iemgui.tcl:578 msgid "Send symbol:" msgstr "" #: ../src/dialog_gatom.tcl:147 ../src/dialog_gatom.tcl:155 #: ../src/dialog_iemgui.tcl:585 #, fuzzy msgid "Receive symbol:" msgstr "Dritare marrjesh" #: ../src/dialog_iemgui.tcl:197 #, fuzzy msgid "Background color" msgstr "Sfond:" #: ../src/dialog_iemgui.tcl:204 #, fuzzy msgid "Foreground color" msgstr "Përpara:" #: ../src/dialog_iemgui.tcl:211 #, fuzzy msgid "Label color" msgstr "Përzgjidhni ngjyrë" #: ../src/dialog_iemgui.tcl:272 #, fuzzy msgid "Init" msgstr "Fto" #: ../src/dialog_iemgui.tcl:275 ../src/dialog_iemgui.tcl:546 msgid "No init" msgstr "" #: ../src/dialog_iemgui.tcl:287 ../src/dialog_iemgui.tcl:558 msgid "Jump on click" msgstr "" #: ../src/dialog_iemgui.tcl:290 ../src/dialog_iemgui.tcl:561 msgid "Steady on click" msgstr "" #: ../src/dialog_iemgui.tcl:498 #, tcl-format msgid "%s Properties" msgstr "" #: ../src/dialog_iemgui.tcl:550 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:84 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:130 ../src/pd_menus.tcl:260 #: ../src/pd_menus.tcl:273 ../src/pd_menus.tcl:288 ../src/pd_menus.tcl:301 #: ../src/pd_menus.tcl:325 ../src/pd_menus.tcl:338 ../src/pd_menus.tcl:355 #: ../src/pd_menus.tcl:382 ../src/pd_menus.tcl:383 ../src/pd_menus.tcl:410 #: ../src/pd_menus.tcl:422 ../src/pd_menus.tcl:449 msgid "Save" msgstr "Ruaj" #: ../src/dialog_iemgui.tcl:608 msgid "X offset" msgstr "" #: ../src/dialog_iemgui.tcl:611 ../src/dialog_iemgui.tcl:612 msgid "Y offset" msgstr "" #: ../src/dialog_iemgui.tcl:642 ../src/dialog_iemgui.tcl:645 msgid "Colors" msgstr "Ngjyra" #: ../src/dialog_iemgui.tcl:648 ../src/dialog_iemgui.tcl:651 #, fuzzy msgid "Background" msgstr "Sfond:" #: ../src/dialog_iemgui.tcl:650 ../src/dialog_iemgui.tcl:654 #, fuzzy msgid "Front" msgstr "Gërma:" #: ../src/dialog_iemgui.tcl:662 ../src/dialog_iemgui.tcl:668 msgid "Compose color" msgstr "" #: ../src/dialog_iemgui.tcl:682 ../src/dialog_iemgui.tcl:688 #, fuzzy msgid "Test label" msgstr "Testo Tërë" #: ../src/dialog_midi.tcl:85 msgid "MIDI Settings" msgstr "" #: ../src/dialog_midi.tcl:220 msgid "ALSA MIDI Settings" msgstr "" #: ../src/dialog_midi.tcl:331 msgid "Use multiple ALSA devices" msgstr "" #: ../src/dialog_midi.tcl:337 msgid "In Ports:" msgstr "" #: ../src/dialog_midi.tcl:340 msgid "Out Ports:" msgstr "" #: ../src/g_editor.c:1663 msgid "Discard changes to this window??" msgstr "" #: ../src/g_editor.c:1668 msgid "really quit?" msgstr "" #: ../src/g_editor.c:1699 #, fuzzy msgid "Close this window??" msgstr "Mbyll këtë skedë/dritare" #: ../src/pd-gui.tcl:185 ../src/pd-gui.tcl:195 ../src/pd-gui.tcl:203 #: ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:215 ../src/pd-gui.tcl:226 msgid "Associated Files" msgstr "" #: ../src/pd-gui.tcl:186 ../src/pd-gui.tcl:196 ../src/pd-gui.tcl:204 #: ../src/pd-gui.tcl:207 ../src/pd-gui.tcl:216 ../src/pd-gui.tcl:227 #, fuzzy msgid "Pd Files" msgstr "Kartelë" #: ../src/pd-gui.tcl:187 ../src/pd-gui.tcl:205 ../src/pd-gui.tcl:208 #: ../src/pd-gui.tcl:228 msgid "Max Patch Files" msgstr "" #: ../src/pd-gui.tcl:188 ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:209 #: ../src/pd-gui.tcl:229 msgid "Max Text Files" msgstr "" #: ../src/pd-gui.tcl:197 ../src/pd-gui.tcl:217 msgid "Max Patch Files (.pat)" msgstr "" #: ../src/pd-gui.tcl:198 ../src/pd-gui.tcl:218 msgid "Max Text Files (.mxt)" msgstr "" #: ../src/pd-gui.tcl:270 ../src/pd-gui.tcl:290 #, tcl-format msgid "WARNING: Font family '%s' not found, using default (%s)" msgstr "" #: ../src/pd-gui.tcl:278 ../src/pd-gui.tcl:298 #, tcl-format msgid "WARNING: Font weight '%s' not found, using default (%s)" msgstr "" #: ../src/pd-gui.tcl:303 ../src/pd-gui.tcl:323 #, tcl-format msgid "ERROR: %s failed to find font size (%s) that fits into %sx%s!" msgstr "" #: ../src/pd-gui.tcl:478 ../src/pd-gui.tcl:483 ../src/pd-gui.tcl:501 msgid "ERROR: 'pd' never showed up, 'pd-gui' quitting!" msgstr "" #: ../src/pd_menucommands.tcl:19 msgid "Untitled" msgstr "" #: ../src/pd_menucommands.tcl:78 ../src/pd_menucommands.tcl:79 #: ../src/pd_menucommands.tcl:90 #, fuzzy msgid "Send Message..." msgstr "Mesazh" #: ../src/pd_menucommands.tcl:82 ../src/pd_menucommands.tcl:83 #: ../src/pd_menucommands.tcl:94 ../src/pd_menus.tcl:87 ../src/pd_menus.tcl:88 #: ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:134 ../src/pd_menus.tcl:147 #: ../src/pd_menus.tcl:192 ../src/pd_menus.tcl:193 ../src/pd_menus.tcl:265 #: ../src/pd_menus.tcl:278 ../src/pd_menus.tcl:292 ../src/pd_menus.tcl:305 #: ../src/pd_menus.tcl:329 ../src/pd_menus.tcl:342 ../src/pd_menus.tcl:360 #: ../src/pd_menus.tcl:387 ../src/pd_menus.tcl:414 ../src/pd_menus.tcl:426 #: ../src/pd_menus.tcl:453 ../startup/object_db.tcl:123 msgid "Message" msgstr "Mesazh" #: ../src/pd_menucommands.tcl:108 ../src/pd_menucommands.tcl:111 #: ../src/pd_menus.tcl:112 ../src/pd_menus.tcl:113 ../src/pd_menus.tcl:117 #: ../src/pd_menus.tcl:118 ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:159 #: ../src/pd_menus.tcl:163 ../src/pd_menus.tcl:164 #, fuzzy msgid "Font" msgstr "Gërma:" #: ../src/pd_menucommands.tcl:123 ../src/pd_menucommands.tcl:126 #: ../src/pd_menus.tcl:138 ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:184 #, fuzzy msgid "Preferences" msgstr "Parapëlqime..." #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Edit" msgstr "_Përpuno" #: ../src/pd_menus.tcl:45 msgid "File" msgstr "Kartelë" #: ../src/pd_menus.tcl:45 ../src/pdtk_canvas.tcl:48 ../src/pdtk_canvas.tcl:110 #: ../src/pdtk_canvas.tcl:113 msgid "Help" msgstr "Ndihmë" #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Media" msgstr "Maqedonia" #: ../src/pd_menus.tcl:45 msgid "Put" msgstr "" #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Window" msgstr "_Dritare" #: ../src/pd_menus.tcl:81 ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:127 #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:255 ../src/pd_menus.tcl:267 #: ../src/pd_menus.tcl:285 ../src/pd_menus.tcl:298 ../src/pd_menus.tcl:322 #: ../src/pd_menus.tcl:335 ../src/pd_menus.tcl:349 ../src/pd_menus.tcl:376 #: ../src/pd_menus.tcl:380 ../src/pd_menus.tcl:407 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:446 msgid "New" msgstr "E re" #: ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:128 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:268 #: ../src/pd_menus.tcl:286 ../src/pd_menus.tcl:299 ../src/pd_menus.tcl:323 #: ../src/pd_menus.tcl:336 ../src/pd_menus.tcl:350 ../src/pd_menus.tcl:377 #: ../src/pd_menus.tcl:381 ../src/pd_menus.tcl:408 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:447 ../src/pdtk_canvas.tcl:46 #: ../src/pdtk_canvas.tcl:108 ../src/pdtk_canvas.tcl:111 #: ../src/pdtk_canvas.tcl:128 ../src/pdtk_canvas.tcl:130 #: ../src/pdtk_canvas.tcl:131 ../src/pdtk_canvas.tcl:133 msgid "Open" msgstr "Hap" #: ../src/pd_menus.tcl:84 ../src/pd_menus.tcl:85 ../src/pd_menus.tcl:130 #: ../src/pd_menus.tcl:131 ../src/pd_menus.tcl:261 ../src/pd_menus.tcl:274 #: ../src/pd_menus.tcl:289 ../src/pd_menus.tcl:302 ../src/pd_menus.tcl:326 #: ../src/pd_menus.tcl:339 ../src/pd_menus.tcl:356 ../src/pd_menus.tcl:383 #: ../src/pd_menus.tcl:384 ../src/pd_menus.tcl:411 ../src/pd_menus.tcl:423 #: ../src/pd_menus.tcl:450 #, fuzzy msgid "Save As..." msgstr "Ruaj Si" #: ../src/pd_menus.tcl:88 ../src/pd_menus.tcl:89 ../src/pd_menus.tcl:134 #: ../src/pd_menus.tcl:135 ../src/pd_menus.tcl:267 ../src/pd_menus.tcl:280 #: ../src/pd_menus.tcl:293 ../src/pd_menus.tcl:306 ../src/pd_menus.tcl:330 #: ../src/pd_menus.tcl:343 ../src/pd_menus.tcl:362 ../src/pd_menus.tcl:388 #: ../src/pd_menus.tcl:389 ../src/pd_menus.tcl:415 ../src/pd_menus.tcl:427 #: ../src/pd_menus.tcl:454 #, fuzzy msgid "Print..." msgstr "_Përpuno..." #: ../src/pd_menus.tcl:93 ../src/pd_menus.tcl:94 ../src/pd_menus.tcl:139 #: ../src/pd_menus.tcl:140 #, fuzzy msgid "Undo" msgstr "Uganda" #: ../src/pd_menus.tcl:95 ../src/pd_menus.tcl:96 ../src/pd_menus.tcl:141 #: ../src/pd_menus.tcl:142 #, fuzzy msgid "Redo" msgstr "E kuqe:" #: ../src/pd_menus.tcl:98 ../src/pd_menus.tcl:99 ../src/pd_menus.tcl:144 #: ../src/pd_menus.tcl:145 msgid "Cut" msgstr "" #: ../src/pd_menus.tcl:104 ../src/pd_menus.tcl:105 ../src/pd_menus.tcl:150 #: ../src/pd_menus.tcl:151 #, fuzzy msgid "Duplicate" msgstr "Datë" #: ../src/pd_menus.tcl:106 ../src/pd_menus.tcl:107 ../src/pd_menus.tcl:152 #: ../src/pd_menus.tcl:153 #, fuzzy msgid "Select All" msgstr "Fshij Tërë" #: ../src/pd_menus.tcl:110 ../src/pd_menus.tcl:111 ../src/pd_menus.tcl:115 #: ../src/pd_menus.tcl:116 ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:157 #: ../src/pd_menus.tcl:161 ../src/pd_menus.tcl:162 #, fuzzy msgid "Text Editor" msgstr "Ngjyra Teksti" #: ../src/pd_menus.tcl:120 ../src/pd_menus.tcl:121 ../src/pd_menus.tcl:166 #: ../src/pd_menus.tcl:167 msgid "Tidy Up" msgstr "" #: ../src/pd_menus.tcl:122 ../src/pd_menus.tcl:123 ../src/pd_menus.tcl:168 #: ../src/pd_menus.tcl:169 msgid "Toggle Console" msgstr "" #: ../src/pd_menus.tcl:124 ../src/pd_menus.tcl:125 ../src/pd_menus.tcl:170 #: ../src/pd_menus.tcl:171 #, fuzzy msgid "Clear Console" msgstr "Fshij listë" #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:174 #: ../src/pd_menus.tcl:175 #, fuzzy msgid "Edit Mode" msgstr "Mënyrë" #: ../src/pd_menus.tcl:145 ../src/pd_menus.tcl:190 ../src/pd_menus.tcl:191 msgid "Object" msgstr "" #: ../src/pd_menus.tcl:149 ../src/pd_menus.tcl:194 ../src/pd_menus.tcl:195 #, fuzzy msgid "Number" msgstr "$ Numër" #: ../src/pd_menus.tcl:151 ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:197 msgid "Symbol" msgstr "" #: ../src/pd_menus.tcl:153 ../src/pd_menus.tcl:198 ../src/pd_menus.tcl:199 #, fuzzy msgid "Comment" msgstr "Urdhër" #: ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:201 ../src/pd_menus.tcl:202 #, fuzzy msgid "Bang" msgstr "Ndalo" #: ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:203 ../src/pd_menus.tcl:204 #, fuzzy msgid "Toggle" msgstr "Togo" #: ../src/pd_menus.tcl:160 ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:206 #, fuzzy msgid "Number2" msgstr "$ Numër" #: ../src/pd_menus.tcl:162 ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:208 msgid "Vslider" msgstr "" #: ../src/pd_menus.tcl:164 ../src/pd_menus.tcl:209 ../src/pd_menus.tcl:210 #, fuzzy msgid "Hslider" msgstr "Fshehur" #: ../src/pd_menus.tcl:166 ../src/pd_menus.tcl:211 ../src/pd_menus.tcl:212 #, fuzzy msgid "Vradio" msgstr "Version" #: ../src/pd_menus.tcl:168 ../src/pd_menus.tcl:213 ../src/pd_menus.tcl:214 msgid "Hradio" msgstr "" #: ../src/pd_menus.tcl:170 ../src/pd_menus.tcl:215 ../src/pd_menus.tcl:216 msgid "VU Meter" msgstr "" #: ../src/pd_menus.tcl:172 ../src/pd_menus.tcl:217 ../src/pd_menus.tcl:218 #, fuzzy msgid "Canvas" msgstr "Kanada" #: ../src/pd_menus.tcl:175 ../src/pd_menus.tcl:220 ../src/pd_menus.tcl:221 msgid "Graph" msgstr "Grafik" #: ../src/pd_menus.tcl:176 ../src/pd_menus.tcl:221 ../src/pd_menus.tcl:222 #, fuzzy msgid "Array" msgstr "Andorra" #: ../src/pd_menus.tcl:181 ../src/pd_menus.tcl:226 ../src/pd_menus.tcl:227 #, fuzzy msgid "Find..." msgstr "Dërgo Kartelë..." #: ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:228 ../src/pd_menus.tcl:229 msgid "Find Again" msgstr "" #: ../src/pd_menus.tcl:185 ../src/pd_menus.tcl:230 ../src/pd_menus.tcl:231 msgid "Find Last Error" msgstr "" #: ../src/pd_menus.tcl:191 ../src/pd_menus.tcl:236 ../src/pd_menus.tcl:237 msgid "DSP On" msgstr "" #: ../src/pd_menus.tcl:193 ../src/pd_menus.tcl:238 ../src/pd_menus.tcl:239 #, fuzzy msgid "DSP Off" msgstr "Asnjë" #: ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:242 ../src/pd_menus.tcl:269 msgid "Test Audio and MIDI..." msgstr "" #: ../src/pd_menus.tcl:198 ../src/pd_menus.tcl:244 ../src/pd_menus.tcl:271 #, fuzzy msgid "Load Meter" msgstr "Matës vonese:" #: ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:251 ../src/pd_menus.tcl:278 msgid "Minimize" msgstr "" #: ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:253 ../src/pd_menus.tcl:280 #, fuzzy msgid "Zoom" msgstr "Poshtë" #: ../src/pd_menus.tcl:210 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:283 #, fuzzy msgid "Parent Window" msgstr "Dritare dërgimesh" #: ../src/pd_menus.tcl:216 ../src/pd_menus.tcl:262 ../src/pd_menus.tcl:289 msgid "Bring All to Front" msgstr "" #: ../src/pd_menus.tcl:224 ../src/pd_menus.tcl:241 ../src/pd_menus.tcl:253 #: ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:297 ../src/pd_menus.tcl:335 #: ../src/pd_menus.tcl:362 #, fuzzy msgid "About Pd" msgstr "_Rreth" #: ../src/pd_menus.tcl:227 ../src/pd_menus.tcl:273 ../src/pd_menus.tcl:300 msgid "HTML Manual..." msgstr "" #: ../src/pd_menus.tcl:229 ../src/pd_menus.tcl:275 ../src/pd_menus.tcl:302 #, fuzzy msgid "Browser..." msgstr "Shfleto..." #: ../src/pd_menus.tcl:248 ../src/pd_menus.tcl:260 ../src/pd_menus.tcl:342 #: ../src/pd_menus.tcl:369 msgid "Preferences..." msgstr "Parapëlqime..." #: ../src/pd_menus.tcl:257 ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:352 #: ../src/pd_menus.tcl:379 msgid "Open Recent" msgstr "" #: ../src/pd_menus.tcl:263 msgid "Audio Settings..." msgstr "" #: ../src/pd_menus.tcl:265 msgid "MIDI Settings..." msgstr "" #: ../src/pd_menus.tcl:296 ../src/pd_menus.tcl:309 ../src/pd_menus.tcl:333 #: ../src/pd_menus.tcl:346 ../src/pd_menus.tcl:393 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:432 ../src/pd_menus.tcl:459 msgid "Quit" msgstr "Lër" #: ../src/pd_menus.tcl:304 ../src/pd_menus.tcl:331 #, fuzzy msgid "Clear Menu" msgstr "Fshij listë" #: ../src/pdtk_canvas.tcl:44 ../src/pdtk_canvas.tcl:106 #: ../src/pdtk_canvas.tcl:109 ../src/pdtk_canvas.tcl:123 #: ../src/pdtk_canvas.tcl:125 ../src/pdtk_canvas.tcl:126 #: ../src/pdtk_canvas.tcl:128 msgid "Properties" msgstr "" #: ../src/pdwindow.tcl:43 #, fuzzy msgid "DSP" msgstr "Asnjë" #: ../startup/object_db.tcl:113 msgid "Signal" msgstr "" #: ../startup/object_db.tcl:114 msgid "Generators" msgstr "" #: ../startup/object_db.tcl:115 #, fuzzy msgid "Filters" msgstr "Kartelë" #: ../startup/object_db.tcl:116 ../startup/object_db.tcl:124 msgid "Math" msgstr "" #: ../startup/object_db.tcl:117 ../startup/object_db.tcl:125 msgid "I/O" msgstr "" #: ../startup/object_db.tcl:118 ../startup/object_db.tcl:126 msgid "Sampling" msgstr "" #: ../startup/object_db.tcl:119 ../startup/object_db.tcl:128 msgid "Routing" msgstr "" #: ../startup/object_db.tcl:120 ../startup/object_db.tcl:129 msgid "Others" msgstr "" #: ../startup/object_db.tcl:127 msgid "GUI" msgstr "" pd-0.46-7/po/iemgui_dynamic_strings.tcl0000664000175000017500000000210312160204055016241 0ustar mspmsp# These are strings that are passed from C to Tcl but the msgcat # procedure call '[_ $string]' is on the Tcl side, so that the # automatic parsing done by xgettext doesn't pick them up as strings # to be localized. Therefore we just list them here to make xgettext # happy. # # If these are changed in the src/g_*.c files, then need to be # manually updated here. # these are headers for the tops of the Properties panel puts [_ "-------dimensions(digits)(pix):-------"] puts [_ "--------dimensions(pix)(pix):--------"] puts [_ "----------dimensions(pix):-----------"] puts [_ "--------flash-time(ms)(ms):---------"] puts [_ "-----------output-range:-----------"] puts [_ "------selectable_dimensions(pix):------"] puts [_ "------visible_rectangle(pix)(pix):------"] # these are labels for elements of the Properties panel puts [_ "bottom:"] puts [_ "height:"] puts [_ "hold:"] puts [_ "intrrpt:"] puts [_ "left:"] puts [_ "lin"] puts [_ "log"] puts [_ "log-height:"] puts [_ "max:"] puts [_ "min:"] puts [_ "right:"] puts [_ "size:"] puts [_ "top:"] puts [_ "value:"] puts [_ "width:"] pd-0.46-7/po/Makefile.am0000664000175000017500000000421112374250720013046 0ustar mspmspAUTOMAKE_OPTIONS = foreign SUFFIXES = .po .pot .msg # this is the only way to get gettext 0.17 with Fink #UNAME := $(shell uname -s) #ifeq ($(UNAME),Darwin) if MACOSX PATH := /sw/lib/gettext-tools-0.17/bin:${PATH} endif TCLFILES = apple_events.tcl dialog_canvas.tcl dialog_gatom.tcl dialog_path.tcl pd_bindings.tcl pd_menus.tcl pdwindow.tcl scrollboxwindow.tcl AppMain.tcl dialog_data.tcl dialog_iemgui.tcl dialog_startup.tcl pd_connect.tcl pkgIndex.tcl wheredoesthisgo.tcl dialog_array.tcl dialog_find.tcl dialog_message.tcl helpbrowser.tcl pdtk_canvas.tcl pkg_mkIndex.tcl dialog_audio.tcl dialog_font.tcl dialog_midi.tcl opt_parser.tcl pd_menucommands.tcl pdtk_text.tcl scrollbox.tcl pd_guiprefs.tcl FILES = $(addprefix ../tcl/, $(TCLFILES)) iemgui_dynamic_strings.tcl pd_dynamic_strings.tcl # these are the supported languages, ALL_LINGUAS = af az be bg de el en_ca eu fr gu he hi hu it pa pt_br pt_pt sq sv vi POFILES = $(ALL_LINGUAS:=.po) MSGFILES = $(ALL_LINGUAS:=.msg) TEMPLATE = template.pot libpdpodir = $(pkglibdir)/po libpdpo_DATA = $(MSGFILES) dist_libpdpo_DATA = EXTRA_DIST = $(POFILES) \ iemgui_dynamic_strings.tcl pd_dynamic_strings.tcl \ template.pot # generate .msg files from the .po files all-local: $(MSGFILES) # refresh .po files from the template clean-local: -rm -f -- $(MSGFILES) -rm -f -- $(POFILES:=~) po: $(POFILES) # refresh the template from the source code template: $(TEMPLATE) $(TEMPLATE): $(FILES) xgettext --join-existing \ --from-code=UTF-8 --language=Tcl --keyword=_ \ --sort-by-file --output=$(TEMPLATE) \ --package-name="Pure Data" --package-version=0.43 \ --copyright-holder='This file is put in the public domain' \ --foreign-user \ --msgid-bugs-address=pd-dev@iem.at \ $(FILES) # I guess officially, the .po file should depend on the template.pot, but its # mostly annoying since it wasnts to update the template.pot and .po files any # time a .tcl file changes # $(POFILES): %.po: $(TEMPLATE) $(POFILES): %.po: msgmerge --sort-by-file --update $< $(TEMPLATE) %.msg: %.po msgfmt --check --tcl --locale=$* -d . $< etags: TAGS etags --append --language=none --regex="/proc[ \t]+\([^ \t]+\)/\1/" *.tcl pd-0.46-7/po/sv.po0000664000175000017500000006120212160204055011776 0ustar mspmsp# Swedish translation of Pure Data. # This file is put in the public domain # Johannes Burström , 2009. # msgid "" msgstr "" "Project-Id-Version: Pure Data 0.43\n" "Report-Msgid-Bugs-To: pd-dev@iem.at\n" "POT-Creation-Date: 2009-08-27 10:01-0400\n" "PO-Revision-Date: 2009-08-22 11:20+0100\n" "Last-Translator: Johannes Burström \n" "Language-Team: Johannes Burström \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-Language: Swedish\n" "X-Poedit-Country: Sweden\n" "X-Poedit-SourceCharset: utf-8\n" #, fuzzy msgid "Undo duplicate" msgstr "Duplicera" msgid "Undo paste" msgstr "" msgid "Undo motion" msgstr "" #, fuzzy msgid "Undo cut" msgstr "Ångra" msgid "Undo disconnect" msgstr "" msgid "Undo connect" msgstr "" msgid "Undo clear" msgstr "" msgid "Undo typing" msgstr "" msgid "Discard changes to '%s'?" msgstr "Förkasta ändringar i '%s'?" msgid "Do you want to save the changes you made in '%s'?" msgstr "Vill du spara dina ändringar i '%s'?" #: ../src/dialog_array.tcl:115 ../src/dialog_array.tcl:117 #: ../src/pd_menus.tcl:100 ../src/pd_menus.tcl:101 ../src/pd_menus.tcl:146 #: ../src/pd_menus.tcl:147 msgid "Copy" msgstr "Kopiera" #: ../src/dialog_array.tcl:118 ../src/dialog_array.tcl:120 #: ../src/pd_menus.tcl:102 ../src/pd_menus.tcl:103 ../src/pd_menus.tcl:148 #: ../src/pd_menus.tcl:149 msgid "Paste" msgstr "Klistra in" #: ../src/dialog_array.tcl:264 ../src/dialog_array.tcl:266 #, fuzzy msgid "Array Properties" msgstr "Egenskaper för Array" #: ../src/dialog_array.tcl:270 ../src/dialog_array.tcl:272 msgid "Name:" msgstr "Namn:" #: ../src/dialog_array.tcl:276 ../src/dialog_array.tcl:278 #: ../src/dialog_canvas.tcl:178 ../src/dialog_canvas.tcl:193 #: ../src/dialog_iemgui.tcl:619 ../src/dialog_iemgui.tcl:621 msgid "Size:" msgstr "Storlek:" #: ../src/dialog_array.tcl:280 ../src/dialog_array.tcl:282 msgid "Save contents" msgstr "Spara innehåll" #: ../src/dialog_array.tcl:284 ../src/dialog_array.tcl:286 msgid "Draw as:" msgstr "Rita som:" #: ../src/dialog_array.tcl:287 ../src/dialog_array.tcl:289 msgid "Points" msgstr "Punkter" #: ../src/dialog_array.tcl:289 ../src/dialog_array.tcl:291 msgid "Polygon" msgstr "Polygon" #: ../src/dialog_array.tcl:291 ../src/dialog_array.tcl:293 msgid "Bezier curve" msgstr "Bezier-kurva" #: ../src/dialog_array.tcl:297 ../src/dialog_array.tcl:299 #, fuzzy msgid "Put array into:" msgstr "Rita array i:" #: ../src/dialog_array.tcl:300 ../src/dialog_array.tcl:302 #, fuzzy msgid "New graph" msgstr "Ny graf" #: ../src/dialog_array.tcl:302 ../src/dialog_array.tcl:304 #, fuzzy msgid "Last graph" msgstr "Senaste graf" #: ../src/dialog_array.tcl:306 ../src/dialog_array.tcl:308 #, fuzzy msgid "Delete array" msgstr "Radera array" #: ../src/dialog_array.tcl:312 ../src/dialog_array.tcl:314 msgid "Open List View..." msgstr "Öppna listvy..." #: ../src/dialog_array.tcl:319 ../src/dialog_array.tcl:321 #: ../src/dialog_audio.tcl:136 ../src/dialog_canvas.tcl:205 #: ../src/dialog_font.tcl:51 ../src/dialog_gatom.tcl:153 #: ../src/dialog_gatom.tcl:161 ../src/dialog_iemgui.tcl:742 #: ../src/dialog_iemgui.tcl:748 ../src/dialog_midi.tcl:91 #: ../src/dialog_midi.tcl:226 msgid "Cancel" msgstr "Ångra" #: ../src/dialog_array.tcl:321 ../src/dialog_array.tcl:323 #: ../src/dialog_audio.tcl:138 ../src/dialog_canvas.tcl:207 #: ../src/dialog_gatom.tcl:156 ../src/dialog_gatom.tcl:164 #: ../src/dialog_iemgui.tcl:745 ../src/dialog_iemgui.tcl:751 #: ../src/dialog_midi.tcl:93 ../src/dialog_midi.tcl:228 msgid "Apply" msgstr "Verkställ" #: ../src/dialog_array.tcl:323 ../src/dialog_array.tcl:325 #: ../src/dialog_audio.tcl:140 ../src/dialog_canvas.tcl:209 #: ../src/dialog_font.tcl:53 ../src/dialog_font.tcl:92 #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:101 #: ../src/dialog_gatom.tcl:159 ../src/dialog_gatom.tcl:167 #: ../src/dialog_iemgui.tcl:748 ../src/dialog_iemgui.tcl:754 #: ../src/dialog_midi.tcl:95 ../src/dialog_midi.tcl:230 msgid "OK" msgstr "Ok" #: ../src/dialog_audio.tcl:130 msgid "Audio Settings" msgstr "" #: ../src/dialog_audio.tcl:142 msgid "Save All Settings" msgstr "" #: ../src/dialog_audio.tcl:151 msgid "Sample rate:" msgstr "" #: ../src/dialog_audio.tcl:153 msgid "Delay (msec):" msgstr "" #: ../src/dialog_audio.tcl:158 msgid "Use callbacks" msgstr "" #: ../src/dialog_audio.tcl:166 ../src/dialog_midi.tcl:105 #: ../src/dialog_midi.tcl:241 msgid "Input device 1:" msgstr "" #: ../src/dialog_audio.tcl:169 ../src/dialog_audio.tcl:183 #: ../src/dialog_audio.tcl:198 ../src/dialog_audio.tcl:213 #: ../src/dialog_audio.tcl:232 ../src/dialog_audio.tcl:250 #: ../src/dialog_audio.tcl:265 ../src/dialog_audio.tcl:280 #, fuzzy msgid "Channels:" msgstr "Ångra" #: ../src/dialog_audio.tcl:179 ../src/dialog_midi.tcl:115 #: ../src/dialog_midi.tcl:251 msgid "Input device 2:" msgstr "" #: ../src/dialog_audio.tcl:194 ../src/dialog_midi.tcl:127 #: ../src/dialog_midi.tcl:263 msgid "Input device 3:" msgstr "" #: ../src/dialog_audio.tcl:209 ../src/dialog_midi.tcl:139 #: ../src/dialog_midi.tcl:275 msgid "Input device 4:" msgstr "" #: ../src/dialog_audio.tcl:223 ../src/dialog_midi.tcl:150 #: ../src/dialog_midi.tcl:286 msgid "Output device 1:" msgstr "" #: ../src/dialog_audio.tcl:226 msgid "(same as input device) .............. " msgstr "" #: ../src/dialog_audio.tcl:246 ../src/dialog_midi.tcl:160 #: ../src/dialog_midi.tcl:296 msgid "Output device 2:" msgstr "" #: ../src/dialog_audio.tcl:261 ../src/dialog_midi.tcl:171 #: ../src/dialog_midi.tcl:307 msgid "Output device 3:" msgstr "" #: ../src/dialog_audio.tcl:276 ../src/dialog_midi.tcl:182 #: ../src/dialog_midi.tcl:318 msgid "Output device 4:" msgstr "" #: ../src/dialog_audio.tcl:291 ../src/dialog_midi.tcl:195 msgid "Use multiple devices" msgstr "" #: ../src/dialog_canvas.tcl:142 #, fuzzy msgid "Canvas Properties" msgstr "Egenskaper för canvas" #: ../src/dialog_canvas.tcl:146 msgid "Scale" msgstr "Skala" #: ../src/dialog_canvas.tcl:150 #, fuzzy msgid "X units per pixel:" msgstr "X enheter per pixel:" #: ../src/dialog_canvas.tcl:155 #, fuzzy msgid "Y units per pixel:" msgstr "Y enheter per pixel:" #: ../src/dialog_canvas.tcl:159 #, fuzzy msgid "Appearance on parent patch" msgstr "Utseende på föräldrapatchen" #: ../src/dialog_canvas.tcl:161 #, fuzzy msgid "Graph-On-Parent" msgstr "Graph-On-Parent" #: ../src/dialog_canvas.tcl:165 msgid "Hide object name and arguments" msgstr "Göm objektnamn och argument" #: ../src/dialog_canvas.tcl:170 msgid "Range and size" msgstr "Omfång och storlek" #: ../src/dialog_canvas.tcl:174 msgid "X range, from" msgstr "Omfång (x), från" #: ../src/dialog_canvas.tcl:176 ../src/dialog_canvas.tcl:191 msgid "to" msgstr "till" #: ../src/dialog_canvas.tcl:180 ../src/dialog_canvas.tcl:195 msgid "Margin:" msgstr "Marginal:" #: ../src/dialog_canvas.tcl:189 msgid "Y range, from" msgstr "Omfång (y), från:" #: ../src/dialog_find.tcl:63 ../src/dialog_find.tcl:66 #: ../src/dialog_find.tcl:79 ../src/dialog_find.tcl:80 #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:85 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:101 #: ../src/dialog_find.tcl:105 ../src/dialog_find.tcl:107 #: ../src/pd_menus.tcl:45 msgid "Find" msgstr "Sök" #: ../src/dialog_find.tcl:70 ../src/dialog_find.tcl:73 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:91 #: ../src/dialog_find.tcl:93 msgid "Search in" msgstr "Sök i" #: ../src/dialog_find.tcl:72 ../src/dialog_find.tcl:75 #: ../src/dialog_find.tcl:89 ../src/dialog_find.tcl:93 #: ../src/dialog_find.tcl:95 msgid "for:" msgstr "efter:" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:90 #: ../src/dialog_find.tcl:104 ../src/dialog_find.tcl:108 #: ../src/dialog_find.tcl:110 ../src/pd_menus.tcl:86 ../src/pd_menus.tcl:87 #: ../src/pd_menus.tcl:132 ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:259 #: ../src/pd_menus.tcl:272 ../src/pd_menus.tcl:295 ../src/pd_menus.tcl:308 #: ../src/pd_menus.tcl:332 ../src/pd_menus.tcl:345 ../src/pd_menus.tcl:354 #: ../src/pd_menus.tcl:381 ../src/pd_menus.tcl:392 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:431 ../src/pd_menus.tcl:458 msgid "Close" msgstr "Stäng" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:97 #: ../src/dialog_find.tcl:101 ../src/dialog_find.tcl:103 msgid "Match whole word only" msgstr "Endast hela ord" #: ../src/dialog_find.tcl:92 ../src/dialog_font.tcl:49 #: ../src/dialog_font.tcl:50 ../src/pd-gui.tcl:280 ../src/pd-gui.tcl:283 #: ../src/pd-gui.tcl:286 ../src/pd-gui.tcl:288 ../src/pd-gui.tcl:291 #: ../src/pd_menus.tcl:212 ../src/pd_menus.tcl:258 ../src/pd_menus.tcl:285 #: ../src/pdwindow.tcl:33 msgid "Pd window" msgstr "Huvudfönster" #: ../src/dialog_font.tcl:45 #, fuzzy msgid "Font Properties" msgstr "Egenskaper" #: ../src/dialog_font.tcl:46 ../src/dialog_font.tcl:54 #: ../src/dialog_font.tcl:55 #, fuzzy, tcl-format msgid "%s Font" msgstr "Typsnitt" #: ../src/dialog_font.tcl:61 ../src/dialog_font.tcl:96 #: ../src/dialog_font.tcl:104 ../src/dialog_font.tcl:105 #, fuzzy msgid "Font Size" msgstr "Typsnittsstorlek:" #: ../src/dialog_font.tcl:89 ../src/dialog_font.tcl:108 #: ../src/dialog_font.tcl:116 ../src/dialog_font.tcl:117 #, fuzzy msgid "Stretch" msgstr "Sträck:" #: ../src/dialog_font.tcl:96 ../src/dialog_font.tcl:115 #: ../src/dialog_font.tcl:123 ../src/dialog_font.tcl:124 msgid "X and Y" msgstr "X och Y" #: ../src/dialog_font.tcl:98 ../src/dialog_font.tcl:117 #: ../src/dialog_font.tcl:125 ../src/dialog_font.tcl:126 msgid "X only" msgstr "Bara X" #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:119 #: ../src/dialog_font.tcl:127 ../src/dialog_font.tcl:128 msgid "Y only" msgstr "Bara Y" #: ../src/dialog_gatom.tcl:93 msgid "Atom Box Properties" msgstr "Egenskaper för Atom" #: ../src/dialog_gatom.tcl:99 msgid "Width:" msgstr "Bredd:" #: ../src/dialog_gatom.tcl:103 #, fuzzy msgid "Limits" msgstr "Gränser" #: ../src/dialog_gatom.tcl:107 msgid "Lower:" msgstr "Lägre:" #: ../src/dialog_gatom.tcl:112 ../src/dialog_gatom.tcl:113 msgid "Upper:" msgstr "Övre" #: ../src/dialog_gatom.tcl:116 ../src/dialog_gatom.tcl:121 #: ../src/dialog_iemgui.tcl:600 ../src/dialog_iemgui.tcl:652 #: ../src/dialog_iemgui.tcl:657 #, fuzzy msgid "Label" msgstr "Text" #: ../src/dialog_gatom.tcl:124 ../src/dialog_gatom.tcl:129 msgid "Left " msgstr "Vänster" #: ../src/dialog_gatom.tcl:126 ../src/dialog_gatom.tcl:131 msgid "Right" msgstr "Höger" #: ../src/dialog_gatom.tcl:128 ../src/dialog_gatom.tcl:133 msgid "Top" msgstr "Överkant" #: ../src/dialog_gatom.tcl:130 ../src/dialog_gatom.tcl:135 msgid "Bottom" msgstr "Underkant" #: ../src/dialog_gatom.tcl:137 ../src/dialog_gatom.tcl:145 #: ../src/dialog_iemgui.tcl:574 msgid "Messages" msgstr "Meddelanden" #: ../src/dialog_gatom.tcl:141 ../src/dialog_gatom.tcl:149 #: ../src/dialog_iemgui.tcl:578 #, fuzzy msgid "Send symbol:" msgstr "Sändsymbol:" #: ../src/dialog_gatom.tcl:147 ../src/dialog_gatom.tcl:155 #: ../src/dialog_iemgui.tcl:585 msgid "Receive symbol:" msgstr "Mottagarsymbol:" #: ../src/dialog_iemgui.tcl:197 msgid "Background color" msgstr "Bakgrundsfärg" #: ../src/dialog_iemgui.tcl:204 msgid "Foreground color" msgstr "Förgrundsfärg" #: ../src/dialog_iemgui.tcl:211 msgid "Label color" msgstr "Textfärg" #: ../src/dialog_iemgui.tcl:272 msgid "Init" msgstr "Initiera" #: ../src/dialog_iemgui.tcl:275 ../src/dialog_iemgui.tcl:546 msgid "No init" msgstr "Initiera inte" #: ../src/dialog_iemgui.tcl:287 ../src/dialog_iemgui.tcl:558 msgid "Jump on click" msgstr "Ändra värde vid klick" #: ../src/dialog_iemgui.tcl:290 ../src/dialog_iemgui.tcl:561 msgid "Steady on click" msgstr "Behåll värde vid klick" #: ../src/dialog_iemgui.tcl:498 #, tcl-format msgid "%s Properties" msgstr "Egenskaper för %s" #: ../src/dialog_iemgui.tcl:550 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:84 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:130 ../src/pd_menus.tcl:260 #: ../src/pd_menus.tcl:273 ../src/pd_menus.tcl:288 ../src/pd_menus.tcl:301 #: ../src/pd_menus.tcl:325 ../src/pd_menus.tcl:338 ../src/pd_menus.tcl:355 #: ../src/pd_menus.tcl:382 ../src/pd_menus.tcl:383 ../src/pd_menus.tcl:410 #: ../src/pd_menus.tcl:422 ../src/pd_menus.tcl:449 msgid "Save" msgstr "Spara" #: ../src/dialog_iemgui.tcl:608 msgid "X offset" msgstr "x-position" #: ../src/dialog_iemgui.tcl:611 ../src/dialog_iemgui.tcl:612 msgid "Y offset" msgstr "y-position" #: ../src/dialog_iemgui.tcl:642 ../src/dialog_iemgui.tcl:645 msgid "Colors" msgstr "Färger" #: ../src/dialog_iemgui.tcl:648 ../src/dialog_iemgui.tcl:651 msgid "Background" msgstr "Bakgrund" #: ../src/dialog_iemgui.tcl:650 ../src/dialog_iemgui.tcl:654 msgid "Front" msgstr "Förgrund" #: ../src/dialog_iemgui.tcl:662 ../src/dialog_iemgui.tcl:668 msgid "Compose color" msgstr "Skapa ny färg" #: ../src/dialog_iemgui.tcl:682 ../src/dialog_iemgui.tcl:688 msgid "Test label" msgstr "Testtext" #: ../src/dialog_midi.tcl:85 msgid "MIDI Settings" msgstr "" #: ../src/dialog_midi.tcl:220 msgid "ALSA MIDI Settings" msgstr "" #: ../src/dialog_midi.tcl:331 msgid "Use multiple ALSA devices" msgstr "" #: ../src/dialog_midi.tcl:337 msgid "In Ports:" msgstr "" #: ../src/dialog_midi.tcl:340 msgid "Out Ports:" msgstr "" #: ../src/g_editor.c:1663 #, fuzzy msgid "Discard changes to this window??" msgstr "Ignorera ändringar i detta fönster?" #: ../src/g_editor.c:1668 msgid "really quit?" msgstr "Vill du avsluta?" #: ../src/g_editor.c:1699 msgid "Close this window??" msgstr "Stäng fönstret?" #: ../src/pd-gui.tcl:185 ../src/pd-gui.tcl:195 ../src/pd-gui.tcl:203 #: ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:215 ../src/pd-gui.tcl:226 msgid "Associated Files" msgstr "" #: ../src/pd-gui.tcl:186 ../src/pd-gui.tcl:196 ../src/pd-gui.tcl:204 #: ../src/pd-gui.tcl:207 ../src/pd-gui.tcl:216 ../src/pd-gui.tcl:227 #, fuzzy msgid "Pd Files" msgstr "Fil" #: ../src/pd-gui.tcl:187 ../src/pd-gui.tcl:205 ../src/pd-gui.tcl:208 #: ../src/pd-gui.tcl:228 msgid "Max Patch Files" msgstr "" #: ../src/pd-gui.tcl:188 ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:209 #: ../src/pd-gui.tcl:229 msgid "Max Text Files" msgstr "" #: ../src/pd-gui.tcl:197 ../src/pd-gui.tcl:217 msgid "Max Patch Files (.pat)" msgstr "" #: ../src/pd-gui.tcl:198 ../src/pd-gui.tcl:218 msgid "Max Text Files (.mxt)" msgstr "" #: ../src/pd-gui.tcl:270 ../src/pd-gui.tcl:290 #, tcl-format msgid "WARNING: Font family '%s' not found, using default (%s)" msgstr "" #: ../src/pd-gui.tcl:278 ../src/pd-gui.tcl:298 #, tcl-format msgid "WARNING: Font weight '%s' not found, using default (%s)" msgstr "" #: ../src/pd-gui.tcl:303 ../src/pd-gui.tcl:323 #, tcl-format msgid "ERROR: %s failed to find font size (%s) that fits into %sx%s!" msgstr "" #: ../src/pd-gui.tcl:478 ../src/pd-gui.tcl:483 ../src/pd-gui.tcl:501 msgid "ERROR: 'pd' never showed up, 'pd-gui' quitting!" msgstr "" #: ../src/pd_menucommands.tcl:19 msgid "Untitled" msgstr "" #: ../src/pd_menucommands.tcl:78 ../src/pd_menucommands.tcl:79 #: ../src/pd_menucommands.tcl:90 msgid "Send Message..." msgstr "Sänd meddelande" #: ../src/pd_menucommands.tcl:82 ../src/pd_menucommands.tcl:83 #: ../src/pd_menucommands.tcl:94 ../src/pd_menus.tcl:87 ../src/pd_menus.tcl:88 #: ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:134 ../src/pd_menus.tcl:147 #: ../src/pd_menus.tcl:192 ../src/pd_menus.tcl:193 ../src/pd_menus.tcl:265 #: ../src/pd_menus.tcl:278 ../src/pd_menus.tcl:292 ../src/pd_menus.tcl:305 #: ../src/pd_menus.tcl:329 ../src/pd_menus.tcl:342 ../src/pd_menus.tcl:360 #: ../src/pd_menus.tcl:387 ../src/pd_menus.tcl:414 ../src/pd_menus.tcl:426 #: ../src/pd_menus.tcl:453 ../startup/object_db.tcl:123 msgid "Message" msgstr "Meddelande" #: ../src/pd_menucommands.tcl:108 ../src/pd_menucommands.tcl:111 #: ../src/pd_menus.tcl:112 ../src/pd_menus.tcl:113 ../src/pd_menus.tcl:117 #: ../src/pd_menus.tcl:118 ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:159 #: ../src/pd_menus.tcl:163 ../src/pd_menus.tcl:164 msgid "Font" msgstr "Typsnitt" #: ../src/pd_menucommands.tcl:123 ../src/pd_menucommands.tcl:126 #: ../src/pd_menus.tcl:138 ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:184 msgid "Preferences" msgstr "Inställningar" #: ../src/pd_menus.tcl:45 msgid "Edit" msgstr "Redigera" #: ../src/pd_menus.tcl:45 msgid "File" msgstr "Fil" #: ../src/pd_menus.tcl:45 ../src/pdtk_canvas.tcl:48 ../src/pdtk_canvas.tcl:110 #: ../src/pdtk_canvas.tcl:113 msgid "Help" msgstr "Hjälp" #: ../src/pd_menus.tcl:45 msgid "Media" msgstr "Media" #: ../src/pd_menus.tcl:45 msgid "Put" msgstr "Placera" #: ../src/pd_menus.tcl:45 msgid "Window" msgstr "Fönster" #: ../src/pd_menus.tcl:81 ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:127 #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:255 ../src/pd_menus.tcl:267 #: ../src/pd_menus.tcl:285 ../src/pd_menus.tcl:298 ../src/pd_menus.tcl:322 #: ../src/pd_menus.tcl:335 ../src/pd_menus.tcl:349 ../src/pd_menus.tcl:376 #: ../src/pd_menus.tcl:380 ../src/pd_menus.tcl:407 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:446 msgid "New" msgstr "Ny" #: ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:128 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:268 #: ../src/pd_menus.tcl:286 ../src/pd_menus.tcl:299 ../src/pd_menus.tcl:323 #: ../src/pd_menus.tcl:336 ../src/pd_menus.tcl:350 ../src/pd_menus.tcl:377 #: ../src/pd_menus.tcl:381 ../src/pd_menus.tcl:408 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:447 ../src/pdtk_canvas.tcl:46 #: ../src/pdtk_canvas.tcl:108 ../src/pdtk_canvas.tcl:111 #: ../src/pdtk_canvas.tcl:128 ../src/pdtk_canvas.tcl:130 #: ../src/pdtk_canvas.tcl:131 ../src/pdtk_canvas.tcl:133 msgid "Open" msgstr "Öppna" #: ../src/pd_menus.tcl:84 ../src/pd_menus.tcl:85 ../src/pd_menus.tcl:130 #: ../src/pd_menus.tcl:131 ../src/pd_menus.tcl:261 ../src/pd_menus.tcl:274 #: ../src/pd_menus.tcl:289 ../src/pd_menus.tcl:302 ../src/pd_menus.tcl:326 #: ../src/pd_menus.tcl:339 ../src/pd_menus.tcl:356 ../src/pd_menus.tcl:383 #: ../src/pd_menus.tcl:384 ../src/pd_menus.tcl:411 ../src/pd_menus.tcl:423 #: ../src/pd_menus.tcl:450 msgid "Save As..." msgstr "Spara som..." #: ../src/pd_menus.tcl:88 ../src/pd_menus.tcl:89 ../src/pd_menus.tcl:134 #: ../src/pd_menus.tcl:135 ../src/pd_menus.tcl:267 ../src/pd_menus.tcl:280 #: ../src/pd_menus.tcl:293 ../src/pd_menus.tcl:306 ../src/pd_menus.tcl:330 #: ../src/pd_menus.tcl:343 ../src/pd_menus.tcl:362 ../src/pd_menus.tcl:388 #: ../src/pd_menus.tcl:389 ../src/pd_menus.tcl:415 ../src/pd_menus.tcl:427 #: ../src/pd_menus.tcl:454 msgid "Print..." msgstr "Skriv ut..." #: ../src/pd_menus.tcl:93 ../src/pd_menus.tcl:94 ../src/pd_menus.tcl:139 #: ../src/pd_menus.tcl:140 msgid "Undo" msgstr "Ångra" #: ../src/pd_menus.tcl:95 ../src/pd_menus.tcl:96 ../src/pd_menus.tcl:141 #: ../src/pd_menus.tcl:142 msgid "Redo" msgstr "Gör om" #: ../src/pd_menus.tcl:98 ../src/pd_menus.tcl:99 ../src/pd_menus.tcl:144 #: ../src/pd_menus.tcl:145 msgid "Cut" msgstr "Klipp ut" #: ../src/pd_menus.tcl:104 ../src/pd_menus.tcl:105 ../src/pd_menus.tcl:150 #: ../src/pd_menus.tcl:151 msgid "Duplicate" msgstr "Duplicera" #: ../src/pd_menus.tcl:106 ../src/pd_menus.tcl:107 ../src/pd_menus.tcl:152 #: ../src/pd_menus.tcl:153 msgid "Select All" msgstr "Markera allt" #: ../src/pd_menus.tcl:110 ../src/pd_menus.tcl:111 ../src/pd_menus.tcl:115 #: ../src/pd_menus.tcl:116 ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:157 #: ../src/pd_menus.tcl:161 ../src/pd_menus.tcl:162 msgid "Text Editor" msgstr "Textredigerare" #: ../src/pd_menus.tcl:120 ../src/pd_menus.tcl:121 ../src/pd_menus.tcl:166 #: ../src/pd_menus.tcl:167 msgid "Tidy Up" msgstr "Städa upp" #: ../src/pd_menus.tcl:122 ../src/pd_menus.tcl:123 ../src/pd_menus.tcl:168 #: ../src/pd_menus.tcl:169 #, fuzzy msgid "Toggle Console" msgstr "Växla visning av konsoll" #: ../src/pd_menus.tcl:124 ../src/pd_menus.tcl:125 ../src/pd_menus.tcl:170 #: ../src/pd_menus.tcl:171 #, fuzzy msgid "Clear Console" msgstr "Rensa konsoll" #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:174 #: ../src/pd_menus.tcl:175 msgid "Edit Mode" msgstr "Redigeringsläge" #: ../src/pd_menus.tcl:145 ../src/pd_menus.tcl:190 ../src/pd_menus.tcl:191 msgid "Object" msgstr "Objekt" #: ../src/pd_menus.tcl:149 ../src/pd_menus.tcl:194 ../src/pd_menus.tcl:195 msgid "Number" msgstr "Number" #: ../src/pd_menus.tcl:151 ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:197 msgid "Symbol" msgstr "Symbol" #: ../src/pd_menus.tcl:153 ../src/pd_menus.tcl:198 ../src/pd_menus.tcl:199 msgid "Comment" msgstr "Kommentar" #: ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:201 ../src/pd_menus.tcl:202 msgid "Bang" msgstr "Bang" #: ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:203 ../src/pd_menus.tcl:204 msgid "Toggle" msgstr "Toggle" #: ../src/pd_menus.tcl:160 ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:206 msgid "Number2" msgstr "Number2" #: ../src/pd_menus.tcl:162 ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:208 msgid "Vslider" msgstr "Vslider" #: ../src/pd_menus.tcl:164 ../src/pd_menus.tcl:209 ../src/pd_menus.tcl:210 msgid "Hslider" msgstr "Hslider" #: ../src/pd_menus.tcl:166 ../src/pd_menus.tcl:211 ../src/pd_menus.tcl:212 msgid "Vradio" msgstr "Vradio" #: ../src/pd_menus.tcl:168 ../src/pd_menus.tcl:213 ../src/pd_menus.tcl:214 msgid "Hradio" msgstr "Hradio" #: ../src/pd_menus.tcl:170 ../src/pd_menus.tcl:215 ../src/pd_menus.tcl:216 msgid "VU Meter" msgstr "VU-mätare" #: ../src/pd_menus.tcl:172 ../src/pd_menus.tcl:217 ../src/pd_menus.tcl:218 msgid "Canvas" msgstr "Canvas" #: ../src/pd_menus.tcl:175 ../src/pd_menus.tcl:220 ../src/pd_menus.tcl:221 msgid "Graph" msgstr "Graf" #: ../src/pd_menus.tcl:176 ../src/pd_menus.tcl:221 ../src/pd_menus.tcl:222 msgid "Array" msgstr "Array" #: ../src/pd_menus.tcl:181 ../src/pd_menus.tcl:226 ../src/pd_menus.tcl:227 msgid "Find..." msgstr "Sök..." #: ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:228 ../src/pd_menus.tcl:229 msgid "Find Again" msgstr "Sök igen" #: ../src/pd_menus.tcl:185 ../src/pd_menus.tcl:230 ../src/pd_menus.tcl:231 msgid "Find Last Error" msgstr "Sök senaste fel" #: ../src/pd_menus.tcl:191 ../src/pd_menus.tcl:236 ../src/pd_menus.tcl:237 msgid "DSP On" msgstr "DSP på" #: ../src/pd_menus.tcl:193 ../src/pd_menus.tcl:238 ../src/pd_menus.tcl:239 msgid "DSP Off" msgstr "DSP av" #: ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:242 ../src/pd_menus.tcl:269 msgid "Test Audio and MIDI..." msgstr "Testa ljud och MIDI..." #: ../src/pd_menus.tcl:198 ../src/pd_menus.tcl:244 ../src/pd_menus.tcl:271 #, fuzzy msgid "Load Meter" msgstr "Belastningsmätare" #: ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:251 ../src/pd_menus.tcl:278 msgid "Minimize" msgstr "Minimera" #: ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:253 ../src/pd_menus.tcl:280 msgid "Zoom" msgstr "Zooma" #: ../src/pd_menus.tcl:210 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:283 msgid "Parent Window" msgstr "Föräldrafönster" #: ../src/pd_menus.tcl:216 ../src/pd_menus.tcl:262 ../src/pd_menus.tcl:289 #, fuzzy msgid "Bring All to Front" msgstr "Lägg alla överst" #: ../src/pd_menus.tcl:224 ../src/pd_menus.tcl:241 ../src/pd_menus.tcl:253 #: ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:297 ../src/pd_menus.tcl:335 #: ../src/pd_menus.tcl:362 msgid "About Pd" msgstr "Om Pd" #: ../src/pd_menus.tcl:227 ../src/pd_menus.tcl:273 ../src/pd_menus.tcl:300 msgid "HTML Manual..." msgstr "HTML-manual..." #: ../src/pd_menus.tcl:229 ../src/pd_menus.tcl:275 ../src/pd_menus.tcl:302 msgid "Browser..." msgstr "Bläddra..." #: ../src/pd_menus.tcl:248 ../src/pd_menus.tcl:260 ../src/pd_menus.tcl:342 #: ../src/pd_menus.tcl:369 msgid "Preferences..." msgstr "Inställningar..." #: ../src/pd_menus.tcl:257 ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:352 #: ../src/pd_menus.tcl:379 msgid "Open Recent" msgstr "Öppna senaste" #: ../src/pd_menus.tcl:263 msgid "Audio Settings..." msgstr "" #: ../src/pd_menus.tcl:265 msgid "MIDI Settings..." msgstr "" #: ../src/pd_menus.tcl:296 ../src/pd_menus.tcl:309 ../src/pd_menus.tcl:333 #: ../src/pd_menus.tcl:346 ../src/pd_menus.tcl:393 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:432 ../src/pd_menus.tcl:459 msgid "Quit" msgstr "Avsluta" #: ../src/pd_menus.tcl:304 ../src/pd_menus.tcl:331 #, fuzzy msgid "Clear Menu" msgstr "Rensa konsoll" #: ../src/pdtk_canvas.tcl:44 ../src/pdtk_canvas.tcl:106 #: ../src/pdtk_canvas.tcl:109 ../src/pdtk_canvas.tcl:123 #: ../src/pdtk_canvas.tcl:125 ../src/pdtk_canvas.tcl:126 #: ../src/pdtk_canvas.tcl:128 msgid "Properties" msgstr "Egenskaper" #: ../src/pdwindow.tcl:43 #, fuzzy msgid "DSP" msgstr "DSP på" #: ../startup/object_db.tcl:113 msgid "Signal" msgstr "" #: ../startup/object_db.tcl:114 msgid "Generators" msgstr "" #: ../startup/object_db.tcl:115 #, fuzzy msgid "Filters" msgstr "Fil" #: ../startup/object_db.tcl:116 ../startup/object_db.tcl:124 msgid "Math" msgstr "" #: ../startup/object_db.tcl:117 ../startup/object_db.tcl:125 msgid "I/O" msgstr "" #: ../startup/object_db.tcl:118 ../startup/object_db.tcl:126 msgid "Sampling" msgstr "" #: ../startup/object_db.tcl:119 ../startup/object_db.tcl:128 msgid "Routing" msgstr "" #: ../startup/object_db.tcl:120 ../startup/object_db.tcl:129 msgid "Others" msgstr "" #: ../startup/object_db.tcl:127 msgid "GUI" msgstr "" #~ msgid "Patch Font" #~ msgstr "Patchtypsnitt" pd-0.46-7/po/vi.po0000664000175000017500000006045212160204055011772 0ustar mspmsp# Vietnamese translation for Pure Data-0.43. # This file is put in the public domain. # Clytie Siddall , 2005. msgid "" msgstr "" "Project-Id-Version: Pure Data 0.43\n" "Report-Msgid-Bugs-To: pd-dev@iem.at\n" "POT-Creation-Date: 2009-08-27 10:01-0400\n" "PO-Revision-Date: 2005-07-28 17:29+0930\n" "Last-Translator: Clytie Siddall \n" "Language-Team: Vietnamese \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0\n" "X-Generator: LocFactoryEditor 1.2.2\n" #, fuzzy msgid "Undo duplicate" msgstr "Ngày" msgid "Undo paste" msgstr "" msgid "Undo motion" msgstr "" #, fuzzy msgid "Undo cut" msgstr "U-gan-đa" msgid "Undo disconnect" msgstr "" msgid "Undo connect" msgstr "" msgid "Undo clear" msgstr "" msgid "Undo typing" msgstr "" msgid "Discard changes to '%s'?" msgstr "" msgid "Do you want to save the changes you made in '%s'?" msgstr "" #: ../src/dialog_array.tcl:115 ../src/dialog_array.tcl:117 #: ../src/pd_menus.tcl:100 ../src/pd_menus.tcl:101 ../src/pd_menus.tcl:146 #: ../src/pd_menus.tcl:147 msgid "Copy" msgstr "Chép" #: ../src/dialog_array.tcl:118 ../src/dialog_array.tcl:120 #: ../src/pd_menus.tcl:102 ../src/pd_menus.tcl:103 ../src/pd_menus.tcl:148 #: ../src/pd_menus.tcl:149 #, fuzzy msgid "Paste" msgstr "Ngày" #: ../src/dialog_array.tcl:264 ../src/dialog_array.tcl:266 msgid "Array Properties" msgstr "" #: ../src/dialog_array.tcl:270 ../src/dialog_array.tcl:272 #, fuzzy msgid "Name:" msgstr "Tên" #: ../src/dialog_array.tcl:276 ../src/dialog_array.tcl:278 #: ../src/dialog_canvas.tcl:178 ../src/dialog_canvas.tcl:193 #: ../src/dialog_iemgui.tcl:619 ../src/dialog_iemgui.tcl:621 msgid "Size:" msgstr "Cỡ:" #: ../src/dialog_array.tcl:280 ../src/dialog_array.tcl:282 #, fuzzy msgid "Save contents" msgstr "_Nội dụng" #: ../src/dialog_array.tcl:284 ../src/dialog_array.tcl:286 msgid "Draw as:" msgstr "" #: ../src/dialog_array.tcl:287 ../src/dialog_array.tcl:289 #, fuzzy msgid "Points" msgstr "Cổng" #: ../src/dialog_array.tcl:289 ../src/dialog_array.tcl:291 #, fuzzy msgid "Polygon" msgstr "Ba-lan" #: ../src/dialog_array.tcl:291 ../src/dialog_array.tcl:293 msgid "Bezier curve" msgstr "" #: ../src/dialog_array.tcl:297 ../src/dialog_array.tcl:299 msgid "Put array into:" msgstr "" #: ../src/dialog_array.tcl:300 ../src/dialog_array.tcl:302 msgid "New graph" msgstr "" #: ../src/dialog_array.tcl:302 ../src/dialog_array.tcl:304 #, fuzzy msgid "Last graph" msgstr "Tin nhẳn trước:" #: ../src/dialog_array.tcl:306 ../src/dialog_array.tcl:308 #, fuzzy msgid "Delete array" msgstr "Xóa bỏ" #: ../src/dialog_array.tcl:312 ../src/dialog_array.tcl:314 #, fuzzy msgid "Open List View..." msgstr "Danh sách đuổi ra..." #: ../src/dialog_array.tcl:319 ../src/dialog_array.tcl:321 #: ../src/dialog_audio.tcl:136 ../src/dialog_canvas.tcl:205 #: ../src/dialog_font.tcl:51 ../src/dialog_gatom.tcl:153 #: ../src/dialog_gatom.tcl:161 ../src/dialog_iemgui.tcl:742 #: ../src/dialog_iemgui.tcl:748 ../src/dialog_midi.tcl:91 #: ../src/dialog_midi.tcl:226 msgid "Cancel" msgstr "Thôi" #: ../src/dialog_array.tcl:321 ../src/dialog_array.tcl:323 #: ../src/dialog_audio.tcl:138 ../src/dialog_canvas.tcl:207 #: ../src/dialog_gatom.tcl:156 ../src/dialog_gatom.tcl:164 #: ../src/dialog_iemgui.tcl:745 ../src/dialog_iemgui.tcl:751 #: ../src/dialog_midi.tcl:93 ../src/dialog_midi.tcl:228 msgid "Apply" msgstr "Áp dụng" #: ../src/dialog_array.tcl:323 ../src/dialog_array.tcl:325 #: ../src/dialog_audio.tcl:140 ../src/dialog_canvas.tcl:209 #: ../src/dialog_font.tcl:53 ../src/dialog_font.tcl:92 #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:101 #: ../src/dialog_gatom.tcl:159 ../src/dialog_gatom.tcl:167 #: ../src/dialog_iemgui.tcl:748 ../src/dialog_iemgui.tcl:754 #: ../src/dialog_midi.tcl:95 ../src/dialog_midi.tcl:230 msgid "OK" msgstr "" #: ../src/dialog_audio.tcl:130 msgid "Audio Settings" msgstr "" #: ../src/dialog_audio.tcl:142 msgid "Save All Settings" msgstr "" #: ../src/dialog_audio.tcl:151 msgid "Sample rate:" msgstr "" #: ../src/dialog_audio.tcl:153 msgid "Delay (msec):" msgstr "" #: ../src/dialog_audio.tcl:158 msgid "Use callbacks" msgstr "" #: ../src/dialog_audio.tcl:166 ../src/dialog_midi.tcl:105 #: ../src/dialog_midi.tcl:241 msgid "Input device 1:" msgstr "" #: ../src/dialog_audio.tcl:169 ../src/dialog_audio.tcl:183 #: ../src/dialog_audio.tcl:198 ../src/dialog_audio.tcl:213 #: ../src/dialog_audio.tcl:232 ../src/dialog_audio.tcl:250 #: ../src/dialog_audio.tcl:265 ../src/dialog_audio.tcl:280 #, fuzzy msgid "Channels:" msgstr "Thôi" #: ../src/dialog_audio.tcl:179 ../src/dialog_midi.tcl:115 #: ../src/dialog_midi.tcl:251 msgid "Input device 2:" msgstr "" #: ../src/dialog_audio.tcl:194 ../src/dialog_midi.tcl:127 #: ../src/dialog_midi.tcl:263 msgid "Input device 3:" msgstr "" #: ../src/dialog_audio.tcl:209 ../src/dialog_midi.tcl:139 #: ../src/dialog_midi.tcl:275 msgid "Input device 4:" msgstr "" #: ../src/dialog_audio.tcl:223 ../src/dialog_midi.tcl:150 #: ../src/dialog_midi.tcl:286 msgid "Output device 1:" msgstr "" #: ../src/dialog_audio.tcl:226 msgid "(same as input device) .............. " msgstr "" #: ../src/dialog_audio.tcl:246 ../src/dialog_midi.tcl:160 #: ../src/dialog_midi.tcl:296 msgid "Output device 2:" msgstr "" #: ../src/dialog_audio.tcl:261 ../src/dialog_midi.tcl:171 #: ../src/dialog_midi.tcl:307 msgid "Output device 3:" msgstr "" #: ../src/dialog_audio.tcl:276 ../src/dialog_midi.tcl:182 #: ../src/dialog_midi.tcl:318 msgid "Output device 4:" msgstr "" #: ../src/dialog_audio.tcl:291 ../src/dialog_midi.tcl:195 msgid "Use multiple devices" msgstr "" #: ../src/dialog_canvas.tcl:142 msgid "Canvas Properties" msgstr "" #: ../src/dialog_canvas.tcl:146 #, fuzzy msgid "Scale" msgstr "Lưu" #: ../src/dialog_canvas.tcl:150 msgid "X units per pixel:" msgstr "" #: ../src/dialog_canvas.tcl:155 msgid "Y units per pixel:" msgstr "" #: ../src/dialog_canvas.tcl:159 msgid "Appearance on parent patch" msgstr "" #: ../src/dialog_canvas.tcl:161 msgid "Graph-On-Parent" msgstr "" #: ../src/dialog_canvas.tcl:165 msgid "Hide object name and arguments" msgstr "" #: ../src/dialog_canvas.tcl:170 msgid "Range and size" msgstr "" #: ../src/dialog_canvas.tcl:174 msgid "X range, from" msgstr "" #: ../src/dialog_canvas.tcl:176 ../src/dialog_canvas.tcl:191 msgid "to" msgstr "" #: ../src/dialog_canvas.tcl:180 ../src/dialog_canvas.tcl:195 #, fuzzy msgid "Margin:" msgstr "Dòng đánh dấu:" #: ../src/dialog_canvas.tcl:189 msgid "Y range, from" msgstr "" #: ../src/dialog_find.tcl:63 ../src/dialog_find.tcl:66 #: ../src/dialog_find.tcl:79 ../src/dialog_find.tcl:80 #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:85 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:101 #: ../src/dialog_find.tcl:105 ../src/dialog_find.tcl:107 #: ../src/pd_menus.tcl:45 msgid "Find" msgstr "Tìm" #: ../src/dialog_find.tcl:70 ../src/dialog_find.tcl:73 #: ../src/dialog_find.tcl:87 ../src/dialog_find.tcl:91 #: ../src/dialog_find.tcl:93 #, fuzzy msgid "Search in" msgstr "Tìm kiếm trong văn bản..." #: ../src/dialog_find.tcl:72 ../src/dialog_find.tcl:75 #: ../src/dialog_find.tcl:89 ../src/dialog_find.tcl:93 #: ../src/dialog_find.tcl:95 #, fuzzy msgid "for:" msgstr "Cổng:" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:90 #: ../src/dialog_find.tcl:104 ../src/dialog_find.tcl:108 #: ../src/dialog_find.tcl:110 ../src/pd_menus.tcl:86 ../src/pd_menus.tcl:87 #: ../src/pd_menus.tcl:132 ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:259 #: ../src/pd_menus.tcl:272 ../src/pd_menus.tcl:295 ../src/pd_menus.tcl:308 #: ../src/pd_menus.tcl:332 ../src/pd_menus.tcl:345 ../src/pd_menus.tcl:354 #: ../src/pd_menus.tcl:381 ../src/pd_menus.tcl:392 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:431 ../src/pd_menus.tcl:458 msgid "Close" msgstr "Đóng" #: ../src/dialog_find.tcl:83 ../src/dialog_find.tcl:97 #: ../src/dialog_find.tcl:101 ../src/dialog_find.tcl:103 msgid "Match whole word only" msgstr "" #: ../src/dialog_find.tcl:92 ../src/dialog_font.tcl:49 #: ../src/dialog_font.tcl:50 ../src/pd-gui.tcl:280 ../src/pd-gui.tcl:283 #: ../src/pd-gui.tcl:286 ../src/pd-gui.tcl:288 ../src/pd-gui.tcl:291 #: ../src/pd_menus.tcl:212 ../src/pd_menus.tcl:258 ../src/pd_menus.tcl:285 #: ../src/pdwindow.tcl:33 #, fuzzy msgid "Pd window" msgstr "Cửa sô Gởi" #: ../src/dialog_font.tcl:45 msgid "Font Properties" msgstr "" #: ../src/dialog_font.tcl:46 ../src/dialog_font.tcl:54 #: ../src/dialog_font.tcl:55 #, fuzzy, tcl-format msgid "%s Font" msgstr "Phông chữ:" #: ../src/dialog_font.tcl:61 ../src/dialog_font.tcl:96 #: ../src/dialog_font.tcl:104 ../src/dialog_font.tcl:105 #, fuzzy msgid "Font Size" msgstr "Cỡ:" #: ../src/dialog_font.tcl:89 ../src/dialog_font.tcl:108 #: ../src/dialog_font.tcl:116 ../src/dialog_font.tcl:117 #, fuzzy msgid "Stretch" msgstr "Bắt đầu:" #: ../src/dialog_font.tcl:96 ../src/dialog_font.tcl:115 #: ../src/dialog_font.tcl:123 ../src/dialog_font.tcl:124 msgid "X and Y" msgstr "" #: ../src/dialog_font.tcl:98 ../src/dialog_font.tcl:117 #: ../src/dialog_font.tcl:125 ../src/dialog_font.tcl:126 msgid "X only" msgstr "" #: ../src/dialog_font.tcl:100 ../src/dialog_font.tcl:119 #: ../src/dialog_font.tcl:127 ../src/dialog_font.tcl:128 msgid "Y only" msgstr "" #: ../src/dialog_gatom.tcl:93 msgid "Atom Box Properties" msgstr "" #: ../src/dialog_gatom.tcl:99 msgid "Width:" msgstr "" #: ../src/dialog_gatom.tcl:103 #, fuzzy msgid "Limits" msgstr "Giới hạn người dùng" #: ../src/dialog_gatom.tcl:107 msgid "Lower:" msgstr "" #: ../src/dialog_gatom.tcl:112 ../src/dialog_gatom.tcl:113 #, fuzzy msgid "Upper:" msgstr "Người dùng:" #: ../src/dialog_gatom.tcl:116 ../src/dialog_gatom.tcl:121 #: ../src/dialog_iemgui.tcl:600 ../src/dialog_iemgui.tcl:652 #: ../src/dialog_iemgui.tcl:657 msgid "Label" msgstr "" #: ../src/dialog_gatom.tcl:124 ../src/dialog_gatom.tcl:129 #, fuzzy msgid "Left " msgstr "Bên trái" #: ../src/dialog_gatom.tcl:126 ../src/dialog_gatom.tcl:131 msgid "Right" msgstr "Bên phải" #: ../src/dialog_gatom.tcl:128 ../src/dialog_gatom.tcl:133 msgid "Top" msgstr "Đầu" #: ../src/dialog_gatom.tcl:130 ../src/dialog_gatom.tcl:135 msgid "Bottom" msgstr "Đáy" #: ../src/dialog_gatom.tcl:137 ../src/dialog_gatom.tcl:145 #: ../src/dialog_iemgui.tcl:574 #, fuzzy msgid "Messages" msgstr "Tin nhẳn" #: ../src/dialog_gatom.tcl:141 ../src/dialog_gatom.tcl:149 #: ../src/dialog_iemgui.tcl:578 msgid "Send symbol:" msgstr "" #: ../src/dialog_gatom.tcl:147 ../src/dialog_gatom.tcl:155 #: ../src/dialog_iemgui.tcl:585 #, fuzzy msgid "Receive symbol:" msgstr "Cửa sổ Nhận" #: ../src/dialog_iemgui.tcl:197 #, fuzzy msgid "Background color" msgstr "Nền:" #: ../src/dialog_iemgui.tcl:204 #, fuzzy msgid "Foreground color" msgstr "Tiền cảnh:" #: ../src/dialog_iemgui.tcl:211 #, fuzzy msgid "Label color" msgstr "Chọn màu" #: ../src/dialog_iemgui.tcl:272 #, fuzzy msgid "Init" msgstr "Mời" #: ../src/dialog_iemgui.tcl:275 ../src/dialog_iemgui.tcl:546 msgid "No init" msgstr "" #: ../src/dialog_iemgui.tcl:287 ../src/dialog_iemgui.tcl:558 msgid "Jump on click" msgstr "" #: ../src/dialog_iemgui.tcl:290 ../src/dialog_iemgui.tcl:561 msgid "Steady on click" msgstr "" #: ../src/dialog_iemgui.tcl:498 #, tcl-format msgid "%s Properties" msgstr "" #: ../src/dialog_iemgui.tcl:550 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:84 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:130 ../src/pd_menus.tcl:260 #: ../src/pd_menus.tcl:273 ../src/pd_menus.tcl:288 ../src/pd_menus.tcl:301 #: ../src/pd_menus.tcl:325 ../src/pd_menus.tcl:338 ../src/pd_menus.tcl:355 #: ../src/pd_menus.tcl:382 ../src/pd_menus.tcl:383 ../src/pd_menus.tcl:410 #: ../src/pd_menus.tcl:422 ../src/pd_menus.tcl:449 msgid "Save" msgstr "Lưu" #: ../src/dialog_iemgui.tcl:608 msgid "X offset" msgstr "" #: ../src/dialog_iemgui.tcl:611 ../src/dialog_iemgui.tcl:612 msgid "Y offset" msgstr "" #: ../src/dialog_iemgui.tcl:642 ../src/dialog_iemgui.tcl:645 msgid "Colors" msgstr "Màu" #: ../src/dialog_iemgui.tcl:648 ../src/dialog_iemgui.tcl:651 #, fuzzy msgid "Background" msgstr "Nền:" #: ../src/dialog_iemgui.tcl:650 ../src/dialog_iemgui.tcl:654 #, fuzzy msgid "Front" msgstr "Phông chữ:" #: ../src/dialog_iemgui.tcl:662 ../src/dialog_iemgui.tcl:668 msgid "Compose color" msgstr "" #: ../src/dialog_iemgui.tcl:682 ../src/dialog_iemgui.tcl:688 #, fuzzy msgid "Test label" msgstr "Kiểm tra tất cả" #: ../src/dialog_midi.tcl:85 msgid "MIDI Settings" msgstr "" #: ../src/dialog_midi.tcl:220 msgid "ALSA MIDI Settings" msgstr "" #: ../src/dialog_midi.tcl:331 msgid "Use multiple ALSA devices" msgstr "" #: ../src/dialog_midi.tcl:337 msgid "In Ports:" msgstr "" #: ../src/dialog_midi.tcl:340 msgid "Out Ports:" msgstr "" #: ../src/g_editor.c:1663 msgid "Discard changes to this window??" msgstr "" #: ../src/g_editor.c:1668 msgid "really quit?" msgstr "" #: ../src/g_editor.c:1699 #, fuzzy msgid "Close this window??" msgstr "Đóng thanh/cửa sổ này" #: ../src/pd-gui.tcl:185 ../src/pd-gui.tcl:195 ../src/pd-gui.tcl:203 #: ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:215 ../src/pd-gui.tcl:226 msgid "Associated Files" msgstr "" #: ../src/pd-gui.tcl:186 ../src/pd-gui.tcl:196 ../src/pd-gui.tcl:204 #: ../src/pd-gui.tcl:207 ../src/pd-gui.tcl:216 ../src/pd-gui.tcl:227 #, fuzzy msgid "Pd Files" msgstr "Tập tin" #: ../src/pd-gui.tcl:187 ../src/pd-gui.tcl:205 ../src/pd-gui.tcl:208 #: ../src/pd-gui.tcl:228 msgid "Max Patch Files" msgstr "" #: ../src/pd-gui.tcl:188 ../src/pd-gui.tcl:206 ../src/pd-gui.tcl:209 #: ../src/pd-gui.tcl:229 msgid "Max Text Files" msgstr "" #: ../src/pd-gui.tcl:197 ../src/pd-gui.tcl:217 msgid "Max Patch Files (.pat)" msgstr "" #: ../src/pd-gui.tcl:198 ../src/pd-gui.tcl:218 msgid "Max Text Files (.mxt)" msgstr "" #: ../src/pd-gui.tcl:270 ../src/pd-gui.tcl:290 #, tcl-format msgid "WARNING: Font family '%s' not found, using default (%s)" msgstr "" #: ../src/pd-gui.tcl:278 ../src/pd-gui.tcl:298 #, tcl-format msgid "WARNING: Font weight '%s' not found, using default (%s)" msgstr "" #: ../src/pd-gui.tcl:303 ../src/pd-gui.tcl:323 #, tcl-format msgid "ERROR: %s failed to find font size (%s) that fits into %sx%s!" msgstr "" #: ../src/pd-gui.tcl:478 ../src/pd-gui.tcl:483 ../src/pd-gui.tcl:501 msgid "ERROR: 'pd' never showed up, 'pd-gui' quitting!" msgstr "" #: ../src/pd_menucommands.tcl:19 msgid "Untitled" msgstr "" #: ../src/pd_menucommands.tcl:78 ../src/pd_menucommands.tcl:79 #: ../src/pd_menucommands.tcl:90 #, fuzzy msgid "Send Message..." msgstr "Tin nhẳn" #: ../src/pd_menucommands.tcl:82 ../src/pd_menucommands.tcl:83 #: ../src/pd_menucommands.tcl:94 ../src/pd_menus.tcl:87 ../src/pd_menus.tcl:88 #: ../src/pd_menus.tcl:133 ../src/pd_menus.tcl:134 ../src/pd_menus.tcl:147 #: ../src/pd_menus.tcl:192 ../src/pd_menus.tcl:193 ../src/pd_menus.tcl:265 #: ../src/pd_menus.tcl:278 ../src/pd_menus.tcl:292 ../src/pd_menus.tcl:305 #: ../src/pd_menus.tcl:329 ../src/pd_menus.tcl:342 ../src/pd_menus.tcl:360 #: ../src/pd_menus.tcl:387 ../src/pd_menus.tcl:414 ../src/pd_menus.tcl:426 #: ../src/pd_menus.tcl:453 ../startup/object_db.tcl:123 msgid "Message" msgstr "Tin nhẳn" #: ../src/pd_menucommands.tcl:108 ../src/pd_menucommands.tcl:111 #: ../src/pd_menus.tcl:112 ../src/pd_menus.tcl:113 ../src/pd_menus.tcl:117 #: ../src/pd_menus.tcl:118 ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:159 #: ../src/pd_menus.tcl:163 ../src/pd_menus.tcl:164 #, fuzzy msgid "Font" msgstr "Phông chữ:" #: ../src/pd_menucommands.tcl:123 ../src/pd_menucommands.tcl:126 #: ../src/pd_menus.tcl:138 ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:184 #, fuzzy msgid "Preferences" msgstr "Sở thích..." #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Edit" msgstr "_Hiệu chỉnh" #: ../src/pd_menus.tcl:45 msgid "File" msgstr "Tập tin" #: ../src/pd_menus.tcl:45 ../src/pdtk_canvas.tcl:48 ../src/pdtk_canvas.tcl:110 #: ../src/pdtk_canvas.tcl:113 msgid "Help" msgstr "Trợ giúp" #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Media" msgstr "Maxêđôni" #: ../src/pd_menus.tcl:45 msgid "Put" msgstr "" #: ../src/pd_menus.tcl:45 #, fuzzy msgid "Window" msgstr "_Cửa sổ" #: ../src/pd_menus.tcl:81 ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:127 #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:255 ../src/pd_menus.tcl:267 #: ../src/pd_menus.tcl:285 ../src/pd_menus.tcl:298 ../src/pd_menus.tcl:322 #: ../src/pd_menus.tcl:335 ../src/pd_menus.tcl:349 ../src/pd_menus.tcl:376 #: ../src/pd_menus.tcl:380 ../src/pd_menus.tcl:407 ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:446 msgid "New" msgstr "Mới" #: ../src/pd_menus.tcl:82 ../src/pd_menus.tcl:83 ../src/pd_menus.tcl:128 #: ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:268 #: ../src/pd_menus.tcl:286 ../src/pd_menus.tcl:299 ../src/pd_menus.tcl:323 #: ../src/pd_menus.tcl:336 ../src/pd_menus.tcl:350 ../src/pd_menus.tcl:377 #: ../src/pd_menus.tcl:381 ../src/pd_menus.tcl:408 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:447 ../src/pdtk_canvas.tcl:46 #: ../src/pdtk_canvas.tcl:108 ../src/pdtk_canvas.tcl:111 #: ../src/pdtk_canvas.tcl:128 ../src/pdtk_canvas.tcl:130 #: ../src/pdtk_canvas.tcl:131 ../src/pdtk_canvas.tcl:133 msgid "Open" msgstr "Mở" #: ../src/pd_menus.tcl:84 ../src/pd_menus.tcl:85 ../src/pd_menus.tcl:130 #: ../src/pd_menus.tcl:131 ../src/pd_menus.tcl:261 ../src/pd_menus.tcl:274 #: ../src/pd_menus.tcl:289 ../src/pd_menus.tcl:302 ../src/pd_menus.tcl:326 #: ../src/pd_menus.tcl:339 ../src/pd_menus.tcl:356 ../src/pd_menus.tcl:383 #: ../src/pd_menus.tcl:384 ../src/pd_menus.tcl:411 ../src/pd_menus.tcl:423 #: ../src/pd_menus.tcl:450 #, fuzzy msgid "Save As..." msgstr "Lưu là" #: ../src/pd_menus.tcl:88 ../src/pd_menus.tcl:89 ../src/pd_menus.tcl:134 #: ../src/pd_menus.tcl:135 ../src/pd_menus.tcl:267 ../src/pd_menus.tcl:280 #: ../src/pd_menus.tcl:293 ../src/pd_menus.tcl:306 ../src/pd_menus.tcl:330 #: ../src/pd_menus.tcl:343 ../src/pd_menus.tcl:362 ../src/pd_menus.tcl:388 #: ../src/pd_menus.tcl:389 ../src/pd_menus.tcl:415 ../src/pd_menus.tcl:427 #: ../src/pd_menus.tcl:454 #, fuzzy msgid "Print..." msgstr "_Hiệu chỉnh..." #: ../src/pd_menus.tcl:93 ../src/pd_menus.tcl:94 ../src/pd_menus.tcl:139 #: ../src/pd_menus.tcl:140 #, fuzzy msgid "Undo" msgstr "U-gan-đa" #: ../src/pd_menus.tcl:95 ../src/pd_menus.tcl:96 ../src/pd_menus.tcl:141 #: ../src/pd_menus.tcl:142 #, fuzzy msgid "Redo" msgstr "Màu đỏ:" #: ../src/pd_menus.tcl:98 ../src/pd_menus.tcl:99 ../src/pd_menus.tcl:144 #: ../src/pd_menus.tcl:145 msgid "Cut" msgstr "" #: ../src/pd_menus.tcl:104 ../src/pd_menus.tcl:105 ../src/pd_menus.tcl:150 #: ../src/pd_menus.tcl:151 #, fuzzy msgid "Duplicate" msgstr "Ngày" #: ../src/pd_menus.tcl:106 ../src/pd_menus.tcl:107 ../src/pd_menus.tcl:152 #: ../src/pd_menus.tcl:153 #, fuzzy msgid "Select All" msgstr "Chọn màu" #: ../src/pd_menus.tcl:110 ../src/pd_menus.tcl:111 ../src/pd_menus.tcl:115 #: ../src/pd_menus.tcl:116 ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:157 #: ../src/pd_menus.tcl:161 ../src/pd_menus.tcl:162 #, fuzzy msgid "Text Editor" msgstr "Màu chữ" #: ../src/pd_menus.tcl:120 ../src/pd_menus.tcl:121 ../src/pd_menus.tcl:166 #: ../src/pd_menus.tcl:167 msgid "Tidy Up" msgstr "" #: ../src/pd_menus.tcl:122 ../src/pd_menus.tcl:123 ../src/pd_menus.tcl:168 #: ../src/pd_menus.tcl:169 msgid "Toggle Console" msgstr "" #: ../src/pd_menus.tcl:124 ../src/pd_menus.tcl:125 ../src/pd_menus.tcl:170 #: ../src/pd_menus.tcl:171 #, fuzzy msgid "Clear Console" msgstr "Xóa danh sách" #: ../src/pd_menus.tcl:128 ../src/pd_menus.tcl:129 ../src/pd_menus.tcl:174 #: ../src/pd_menus.tcl:175 #, fuzzy msgid "Edit Mode" msgstr "Chế độ" #: ../src/pd_menus.tcl:145 ../src/pd_menus.tcl:190 ../src/pd_menus.tcl:191 msgid "Object" msgstr "" #: ../src/pd_menus.tcl:149 ../src/pd_menus.tcl:194 ../src/pd_menus.tcl:195 #, fuzzy msgid "Number" msgstr "$ Số" #: ../src/pd_menus.tcl:151 ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:197 msgid "Symbol" msgstr "" #: ../src/pd_menus.tcl:153 ../src/pd_menus.tcl:198 ../src/pd_menus.tcl:199 #, fuzzy msgid "Comment" msgstr "Lệnh" #: ../src/pd_menus.tcl:156 ../src/pd_menus.tcl:201 ../src/pd_menus.tcl:202 #, fuzzy msgid "Bang" msgstr "Đuổi" #: ../src/pd_menus.tcl:158 ../src/pd_menus.tcl:203 ../src/pd_menus.tcl:204 #, fuzzy msgid "Toggle" msgstr "Tô-gô" #: ../src/pd_menus.tcl:160 ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:206 #, fuzzy msgid "Number2" msgstr "$ Số" #: ../src/pd_menus.tcl:162 ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:208 msgid "Vslider" msgstr "" #: ../src/pd_menus.tcl:164 ../src/pd_menus.tcl:209 ../src/pd_menus.tcl:210 #, fuzzy msgid "Hslider" msgstr "Bị ẩn" #: ../src/pd_menus.tcl:166 ../src/pd_menus.tcl:211 ../src/pd_menus.tcl:212 #, fuzzy msgid "Vradio" msgstr "Phiên bản" #: ../src/pd_menus.tcl:168 ../src/pd_menus.tcl:213 ../src/pd_menus.tcl:214 msgid "Hradio" msgstr "" #: ../src/pd_menus.tcl:170 ../src/pd_menus.tcl:215 ../src/pd_menus.tcl:216 msgid "VU Meter" msgstr "" #: ../src/pd_menus.tcl:172 ../src/pd_menus.tcl:217 ../src/pd_menus.tcl:218 #, fuzzy msgid "Canvas" msgstr "Ca-na-đa" #: ../src/pd_menus.tcl:175 ../src/pd_menus.tcl:220 ../src/pd_menus.tcl:221 msgid "Graph" msgstr "Đồ thị" #: ../src/pd_menus.tcl:176 ../src/pd_menus.tcl:221 ../src/pd_menus.tcl:222 #, fuzzy msgid "Array" msgstr "Ăn-đoa-râ" #: ../src/pd_menus.tcl:181 ../src/pd_menus.tcl:226 ../src/pd_menus.tcl:227 #, fuzzy msgid "Find..." msgstr "Gởi tâp tin..." #: ../src/pd_menus.tcl:183 ../src/pd_menus.tcl:228 ../src/pd_menus.tcl:229 msgid "Find Again" msgstr "" #: ../src/pd_menus.tcl:185 ../src/pd_menus.tcl:230 ../src/pd_menus.tcl:231 msgid "Find Last Error" msgstr "" #: ../src/pd_menus.tcl:191 ../src/pd_menus.tcl:236 ../src/pd_menus.tcl:237 msgid "DSP On" msgstr "" #: ../src/pd_menus.tcl:193 ../src/pd_menus.tcl:238 ../src/pd_menus.tcl:239 #, fuzzy msgid "DSP Off" msgstr "Tất" #: ../src/pd_menus.tcl:196 ../src/pd_menus.tcl:242 ../src/pd_menus.tcl:269 msgid "Test Audio and MIDI..." msgstr "" #: ../src/pd_menus.tcl:198 ../src/pd_menus.tcl:244 ../src/pd_menus.tcl:271 #, fuzzy msgid "Load Meter" msgstr "Bộ đo trễ:" #: ../src/pd_menus.tcl:205 ../src/pd_menus.tcl:251 ../src/pd_menus.tcl:278 msgid "Minimize" msgstr "" #: ../src/pd_menus.tcl:207 ../src/pd_menus.tcl:253 ../src/pd_menus.tcl:280 #, fuzzy msgid "Zoom" msgstr "Đáy" #: ../src/pd_menus.tcl:210 ../src/pd_menus.tcl:256 ../src/pd_menus.tcl:283 #, fuzzy msgid "Parent Window" msgstr "Cửa sô Gởi" #: ../src/pd_menus.tcl:216 ../src/pd_menus.tcl:262 ../src/pd_menus.tcl:289 msgid "Bring All to Front" msgstr "" #: ../src/pd_menus.tcl:224 ../src/pd_menus.tcl:241 ../src/pd_menus.tcl:253 #: ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:297 ../src/pd_menus.tcl:335 #: ../src/pd_menus.tcl:362 #, fuzzy msgid "About Pd" msgstr "_Giới thiệu" #: ../src/pd_menus.tcl:227 ../src/pd_menus.tcl:273 ../src/pd_menus.tcl:300 msgid "HTML Manual..." msgstr "" #: ../src/pd_menus.tcl:229 ../src/pd_menus.tcl:275 ../src/pd_menus.tcl:302 #, fuzzy msgid "Browser..." msgstr "Duyệt..." #: ../src/pd_menus.tcl:248 ../src/pd_menus.tcl:260 ../src/pd_menus.tcl:342 #: ../src/pd_menus.tcl:369 msgid "Preferences..." msgstr "Sở thích..." #: ../src/pd_menus.tcl:257 ../src/pd_menus.tcl:270 ../src/pd_menus.tcl:352 #: ../src/pd_menus.tcl:379 msgid "Open Recent" msgstr "" #: ../src/pd_menus.tcl:263 msgid "Audio Settings..." msgstr "" #: ../src/pd_menus.tcl:265 msgid "MIDI Settings..." msgstr "" #: ../src/pd_menus.tcl:296 ../src/pd_menus.tcl:309 ../src/pd_menus.tcl:333 #: ../src/pd_menus.tcl:346 ../src/pd_menus.tcl:393 ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:432 ../src/pd_menus.tcl:459 msgid "Quit" msgstr "Thoát" #: ../src/pd_menus.tcl:304 ../src/pd_menus.tcl:331 #, fuzzy msgid "Clear Menu" msgstr "Xóa danh sách" #: ../src/pdtk_canvas.tcl:44 ../src/pdtk_canvas.tcl:106 #: ../src/pdtk_canvas.tcl:109 ../src/pdtk_canvas.tcl:123 #: ../src/pdtk_canvas.tcl:125 ../src/pdtk_canvas.tcl:126 #: ../src/pdtk_canvas.tcl:128 msgid "Properties" msgstr "" #: ../src/pdwindow.tcl:43 #, fuzzy msgid "DSP" msgstr "Tất" #: ../startup/object_db.tcl:113 msgid "Signal" msgstr "" #: ../startup/object_db.tcl:114 msgid "Generators" msgstr "" #: ../startup/object_db.tcl:115 #, fuzzy msgid "Filters" msgstr "Tập tin" #: ../startup/object_db.tcl:116 ../startup/object_db.tcl:124 msgid "Math" msgstr "" #: ../startup/object_db.tcl:117 ../startup/object_db.tcl:125 msgid "I/O" msgstr "" #: ../startup/object_db.tcl:118 ../startup/object_db.tcl:126 msgid "Sampling" msgstr "" #: ../startup/object_db.tcl:119 ../startup/object_db.tcl:128 msgid "Routing" msgstr "" #: ../startup/object_db.tcl:120 ../startup/object_db.tcl:129 msgid "Others" msgstr "" #: ../startup/object_db.tcl:127 msgid "GUI" msgstr "" pd-0.46-7/po/pd_dynamic_strings.tcl0000664000175000017500000000150612160204055015373 0ustar mspmsp# These are strings that are passed from C to Tcl but the msgcat # procedure call '[_ $string]' is on the Tcl side, so that the # automatic parsing done by xgettext doesn't pick them up as strings # to be localized. Therefore we just list them here to make xgettext # happy. # # If these are changed in the src/*.c files, then need to be # manually updated here. puts [_ "Do you want to save the changes you made in '%s'?"] puts [_ "Discard changes to '%s'?"] puts [_ "Undo clear"] puts [_ "Undo connect"] puts [_ "Undo cut"] puts [_ "Undo disconnect"] puts [_ "Undo duplicate"] puts [_ "Undo motion"] puts [_ "Undo paste"] puts [_ "Undo typing"] puts [_ "Redo clear"] puts [_ "Redo connect"] puts [_ "Redo cut"] puts [_ "Redo disconnect"] puts [_ "Redo duplicate"] puts [_ "Redo motion"] puts [_ "Redo paste"] puts [_ "Redo typing"] pd-0.46-7/po/pt_pt.po0000664000175000017500000006133412160204055012502 0ustar mspmsp# Portugal Portugeuse translation for Pure Data # # msgid "" msgstr "" "Project-Id-Version: Pure Data 0.43\n" "Report-Msgid-Bugs-To: pd-dev@iem.at\n" "POT-Creation-Date: 2009-08-25 23:00-0400\n" "PO-Revision-Date: \n" "Last-Translator: João Pais \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-Language: Portuguese\n" "X-Poedit-Country: PORTUGAL\n" msgid "Discard changes to '%s'?" msgstr "Rejeitar modificações em '%s'?" msgid "Do you want to save the changes you made in '%s'?" msgstr "Quer gravar as modificações feitas em '%s'?" #: ../src/dialog_array.tcl:115 #: ../src/dialog_array.tcl:117 #: ../src/pd_menus.tcl:100 #: ../src/pd_menus.tcl:101 #: ../src/pd_menus.tcl:146 #: ../src/pd_menus.tcl:147 msgid "Copy" msgstr "Copiar" #: ../src/dialog_array.tcl:118 #: ../src/dialog_array.tcl:120 #: ../src/pd_menus.tcl:102 #: ../src/pd_menus.tcl:103 #: ../src/pd_menus.tcl:148 #: ../src/pd_menus.tcl:149 msgid "Paste" msgstr "Colar" #: ../src/dialog_array.tcl:264 #: ../src/dialog_array.tcl:266 msgid "Array Properties" msgstr "Propriedades do array" #: ../src/dialog_array.tcl:270 #: ../src/dialog_array.tcl:272 msgid "Name:" msgstr "Nome:" #: ../src/dialog_array.tcl:276 #: ../src/dialog_array.tcl:278 #: ../src/dialog_canvas.tcl:178 #: ../src/dialog_canvas.tcl:193 #: ../src/dialog_iemgui.tcl:619 #: ../src/dialog_iemgui.tcl:621 msgid "Size:" msgstr "Tamanho:" #: ../src/dialog_array.tcl:280 #: ../src/dialog_array.tcl:282 msgid "Save contents" msgstr "Guardar conteúdo" #: ../src/dialog_array.tcl:284 #: ../src/dialog_array.tcl:286 msgid "Draw as:" msgstr "Desenhar como:" #: ../src/dialog_array.tcl:287 #: ../src/dialog_array.tcl:289 msgid "Points" msgstr "Pontos" #: ../src/dialog_array.tcl:289 #: ../src/dialog_array.tcl:291 msgid "Polygon" msgstr "Polígono" #: ../src/dialog_array.tcl:291 #: ../src/dialog_array.tcl:293 msgid "Bezier curve" msgstr "Curva de Bézier" #: ../src/dialog_array.tcl:297 #: ../src/dialog_array.tcl:299 msgid "Put array into:" msgstr "Pôr array em:" #: ../src/dialog_array.tcl:300 #: ../src/dialog_array.tcl:302 msgid "New graph" msgstr "Gráfico novo" #: ../src/dialog_array.tcl:302 #: ../src/dialog_array.tcl:304 msgid "Last graph" msgstr "Gráfico precedente" #: ../src/dialog_array.tcl:306 #: ../src/dialog_array.tcl:308 msgid "Delete array" msgstr "Apagar array" #: ../src/dialog_array.tcl:312 #: ../src/dialog_array.tcl:314 msgid "Open List View..." msgstr "Ver lista" #: ../src/dialog_array.tcl:319 #: ../src/dialog_array.tcl:321 #: ../src/dialog_audio.tcl:136 #: ../src/dialog_canvas.tcl:205 #: ../src/dialog_font.tcl:51 #: ../src/dialog_gatom.tcl:153 #: ../src/dialog_gatom.tcl:161 #: ../src/dialog_iemgui.tcl:742 #: ../src/dialog_iemgui.tcl:748 #: ../src/dialog_midi.tcl:91 #: ../src/dialog_midi.tcl:226 msgid "Cancel" msgstr "Cancelar" #: ../src/dialog_array.tcl:321 #: ../src/dialog_array.tcl:323 #: ../src/dialog_audio.tcl:138 #: ../src/dialog_canvas.tcl:207 #: ../src/dialog_gatom.tcl:156 #: ../src/dialog_gatom.tcl:164 #: ../src/dialog_iemgui.tcl:745 #: ../src/dialog_iemgui.tcl:751 #: ../src/dialog_midi.tcl:93 #: ../src/dialog_midi.tcl:228 msgid "Apply" msgstr "Aplicar" #: ../src/dialog_array.tcl:323 #: ../src/dialog_array.tcl:325 #: ../src/dialog_audio.tcl:140 #: ../src/dialog_canvas.tcl:209 #: ../src/dialog_font.tcl:53 #: ../src/dialog_font.tcl:92 #: ../src/dialog_font.tcl:100 #: ../src/dialog_gatom.tcl:159 #: ../src/dialog_gatom.tcl:167 #: ../src/dialog_iemgui.tcl:748 #: ../src/dialog_iemgui.tcl:754 #: ../src/dialog_midi.tcl:95 #: ../src/dialog_midi.tcl:230 msgid "OK" msgstr "OK" #: ../src/dialog_audio.tcl:130 msgid "Audio Settings" msgstr "Configuração audio" #: ../src/dialog_audio.tcl:142 msgid "Save All Settings" msgstr "Gravar a configuração" #: ../src/dialog_audio.tcl:151 msgid "Sample rate:" msgstr "Sample rate:" #: ../src/dialog_audio.tcl:153 msgid "Delay (msec):" msgstr "Delay (mseg):" #: ../src/dialog_audio.tcl:158 msgid "Use callbacks" msgstr "Usar callbacks" #: ../src/dialog_audio.tcl:166 #: ../src/dialog_midi.tcl:105 #: ../src/dialog_midi.tcl:241 msgid "Input device 1:" msgstr "Dispositivo de entrada 1:" #: ../src/dialog_audio.tcl:169 #: ../src/dialog_audio.tcl:183 #: ../src/dialog_audio.tcl:198 #: ../src/dialog_audio.tcl:213 #: ../src/dialog_audio.tcl:232 #: ../src/dialog_audio.tcl:250 #: ../src/dialog_audio.tcl:265 #: ../src/dialog_audio.tcl:280 msgid "Channels:" msgstr "Canais:" #: ../src/dialog_audio.tcl:179 #: ../src/dialog_midi.tcl:115 #: ../src/dialog_midi.tcl:251 msgid "Input device 2:" msgstr "Dispositivo de entrada 2:" #: ../src/dialog_audio.tcl:194 #: ../src/dialog_midi.tcl:127 #: ../src/dialog_midi.tcl:263 msgid "Input device 3:" msgstr "Dispositivo de entrada 3:" #: ../src/dialog_audio.tcl:209 #: ../src/dialog_midi.tcl:139 #: ../src/dialog_midi.tcl:275 msgid "Input device 4:" msgstr "Dispositivo de entrada 4:" #: ../src/dialog_audio.tcl:223 #: ../src/dialog_midi.tcl:150 #: ../src/dialog_midi.tcl:286 msgid "Output device 1:" msgstr "Dispositivo de saída 1:" #: ../src/dialog_audio.tcl:226 msgid "(same as input device) .............. " msgstr "(igual ao dispositivo de entrada) .............." #: ../src/dialog_audio.tcl:246 #: ../src/dialog_midi.tcl:160 #: ../src/dialog_midi.tcl:296 msgid "Output device 2:" msgstr "Dispositivo de saída 2:" #: ../src/dialog_audio.tcl:261 #: ../src/dialog_midi.tcl:171 #: ../src/dialog_midi.tcl:307 msgid "Output device 3:" msgstr "Dispositivo de saída 3:" #: ../src/dialog_audio.tcl:276 #: ../src/dialog_midi.tcl:182 #: ../src/dialog_midi.tcl:318 msgid "Output device 4:" msgstr "Dispositivo de saída 4:" #: ../src/dialog_audio.tcl:291 #: ../src/dialog_midi.tcl:195 msgid "Use multiple devices" msgstr "Usar vários dispositivos" #: ../src/dialog_canvas.tcl:142 msgid "Canvas Properties" msgstr "Propriedades da tela" #: ../src/dialog_canvas.tcl:146 msgid "Scale" msgstr "Escala" #: ../src/dialog_canvas.tcl:150 msgid "X units per pixel:" msgstr "Unidades de X por pixel" #: ../src/dialog_canvas.tcl:155 msgid "Y units per pixel:" msgstr "Unidades de Y por pixel" #: ../src/dialog_canvas.tcl:159 msgid "Appearance on parent patch" msgstr "" #: ../src/dialog_canvas.tcl:161 msgid "Graph-On-Parent" msgstr "Mostrar na janela superior" #: ../src/dialog_canvas.tcl:165 msgid "Hide object name and arguments" msgstr "Esconder nome e variáveis do objecto" #: ../src/dialog_canvas.tcl:170 msgid "Range and size" msgstr "" #: ../src/dialog_canvas.tcl:174 msgid "X range, from" msgstr "Faixa X, de" #: ../src/dialog_canvas.tcl:176 #: ../src/dialog_canvas.tcl:191 msgid "to" msgstr "a" #: ../src/dialog_canvas.tcl:180 #: ../src/dialog_canvas.tcl:195 msgid "Margin:" msgstr "Margem:" #: ../src/dialog_canvas.tcl:189 msgid "Y range, from" msgstr "Faixa Y, de" #: ../src/dialog_find.tcl:63 #: ../src/dialog_find.tcl:66 #: ../src/dialog_find.tcl:79 #: ../src/dialog_find.tcl:80 #: ../src/dialog_find.tcl:85 #: ../src/dialog_find.tcl:87 #: ../src/dialog_find.tcl:101 #: ../src/dialog_find.tcl:107 #: ../src/pd_menus.tcl:45 msgid "Find" msgstr "Localizar" #: ../src/dialog_find.tcl:70 #: ../src/dialog_find.tcl:73 #: ../src/dialog_find.tcl:87 #: ../src/dialog_find.tcl:93 msgid "Search in" msgstr "Procurar em" #: ../src/dialog_find.tcl:72 #: ../src/dialog_find.tcl:75 #: ../src/dialog_find.tcl:89 #: ../src/dialog_find.tcl:95 msgid "for:" msgstr "por:" #: ../src/dialog_find.tcl:83 #: ../src/dialog_find.tcl:90 #: ../src/dialog_find.tcl:104 #: ../src/dialog_find.tcl:110 #: ../src/pd_menus.tcl:86 #: ../src/pd_menus.tcl:87 #: ../src/pd_menus.tcl:132 #: ../src/pd_menus.tcl:133 #: ../src/pd_menus.tcl:259 #: ../src/pd_menus.tcl:272 #: ../src/pd_menus.tcl:295 #: ../src/pd_menus.tcl:308 #: ../src/pd_menus.tcl:332 #: ../src/pd_menus.tcl:345 #: ../src/pd_menus.tcl:354 #: ../src/pd_menus.tcl:381 #: ../src/pd_menus.tcl:392 #: ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:431 #: ../src/pd_menus.tcl:458 msgid "Close" msgstr "Fechar" #: ../src/dialog_find.tcl:83 #: ../src/dialog_find.tcl:97 #: ../src/dialog_find.tcl:103 msgid "Match whole word only" msgstr "" #: ../src/dialog_font.tcl:45 msgid "Font Properties" msgstr "Propriedades do tipo de letra" #: ../src/dialog_font.tcl:46 #: ../src/dialog_font.tcl:54 #, tcl-format msgid "%s Font" msgstr "" #: ../src/dialog_font.tcl:49 #: ../src/pd-gui.tcl:280 #: ../src/pd-gui.tcl:283 #: ../src/pd-gui.tcl:286 #: ../src/pd-gui.tcl:288 #: ../src/pd-gui.tcl:291 #: ../src/pd_menus.tcl:212 #: ../src/pd_menus.tcl:258 #: ../src/pd_menus.tcl:285 #: ../src/pdwindow.tcl:33 msgid "Pd window" msgstr "Janela Pd" #: ../src/dialog_font.tcl:61 #: ../src/dialog_font.tcl:96 #: ../src/dialog_font.tcl:104 msgid "Font Size" msgstr "Tamanho do tipo de letra" #: ../src/dialog_font.tcl:89 #: ../src/dialog_font.tcl:108 #: ../src/dialog_font.tcl:116 msgid "Stretch" msgstr "Expandir" #: ../src/dialog_font.tcl:96 #: ../src/dialog_font.tcl:115 #: ../src/dialog_font.tcl:123 msgid "X and Y" msgstr "X e Y" #: ../src/dialog_font.tcl:98 #: ../src/dialog_font.tcl:117 #: ../src/dialog_font.tcl:125 msgid "X only" msgstr "Apenas X" #: ../src/dialog_font.tcl:100 #: ../src/dialog_font.tcl:119 #: ../src/dialog_font.tcl:127 msgid "Y only" msgstr "Apenas Y" #: ../src/dialog_gatom.tcl:93 msgid "Atom Box Properties" msgstr "Propriedades da atom box" #: ../src/dialog_gatom.tcl:99 msgid "Width:" msgstr "Largura:" #: ../src/dialog_gatom.tcl:103 msgid "Limits" msgstr "Limites" #: ../src/dialog_gatom.tcl:107 msgid "Lower:" msgstr "Inferior:" #: ../src/dialog_gatom.tcl:112 #: ../src/dialog_gatom.tcl:113 msgid "Upper:" msgstr "Superior:" #: ../src/dialog_gatom.tcl:116 #: ../src/dialog_gatom.tcl:121 #: ../src/dialog_iemgui.tcl:600 #: ../src/dialog_iemgui.tcl:652 #: ../src/dialog_iemgui.tcl:657 msgid "Label" msgstr "Legenda" #: ../src/dialog_gatom.tcl:124 #: ../src/dialog_gatom.tcl:129 msgid "Left " msgstr "Esquerda" #: ../src/dialog_gatom.tcl:126 #: ../src/dialog_gatom.tcl:131 msgid "Right" msgstr "Direita" #: ../src/dialog_gatom.tcl:128 #: ../src/dialog_gatom.tcl:133 msgid "Top" msgstr "Acima" #: ../src/dialog_gatom.tcl:130 #: ../src/dialog_gatom.tcl:135 msgid "Bottom" msgstr "Abaixo" #: ../src/dialog_gatom.tcl:137 #: ../src/dialog_gatom.tcl:145 #: ../src/dialog_iemgui.tcl:574 msgid "Messages" msgstr "" #: ../src/dialog_gatom.tcl:141 #: ../src/dialog_gatom.tcl:149 #: ../src/dialog_iemgui.tcl:578 msgid "Send symbol:" msgstr "Símbolo para enviar:" #: ../src/dialog_gatom.tcl:147 #: ../src/dialog_gatom.tcl:155 #: ../src/dialog_iemgui.tcl:585 msgid "Receive symbol:" msgstr "Símbolo para receber:" #: ../src/dialog_iemgui.tcl:197 msgid "Background color" msgstr "Cor de fundo" #: ../src/dialog_iemgui.tcl:204 msgid "Foreground color" msgstr "Cor frontal" #: ../src/dialog_iemgui.tcl:211 msgid "Label color" msgstr "Cor da legenda" #: ../src/dialog_iemgui.tcl:272 msgid "Init" msgstr "Iniciar" #: ../src/dialog_iemgui.tcl:275 #: ../src/dialog_iemgui.tcl:546 msgid "No init" msgstr "Não iniciar" #: ../src/dialog_iemgui.tcl:287 #: ../src/dialog_iemgui.tcl:558 msgid "Jump on click" msgstr "Saltar no clique" #: ../src/dialog_iemgui.tcl:290 #: ../src/dialog_iemgui.tcl:561 msgid "Steady on click" msgstr "Manter no clique" #: ../src/dialog_iemgui.tcl:498 #, tcl-format msgid "%s Properties" msgstr "Propriedades de %s" #: ../src/dialog_iemgui.tcl:550 #: ../src/pd_menus.tcl:83 #: ../src/pd_menus.tcl:84 #: ../src/pd_menus.tcl:129 #: ../src/pd_menus.tcl:130 #: ../src/pd_menus.tcl:260 #: ../src/pd_menus.tcl:273 #: ../src/pd_menus.tcl:288 #: ../src/pd_menus.tcl:301 #: ../src/pd_menus.tcl:325 #: ../src/pd_menus.tcl:338 #: ../src/pd_menus.tcl:355 #: ../src/pd_menus.tcl:382 #: ../src/pd_menus.tcl:383 #: ../src/pd_menus.tcl:410 #: ../src/pd_menus.tcl:422 #: ../src/pd_menus.tcl:449 msgid "Save" msgstr "Guardar" #: ../src/dialog_iemgui.tcl:608 msgid "X offset" msgstr "Posição X" #: ../src/dialog_iemgui.tcl:611 #: ../src/dialog_iemgui.tcl:612 msgid "Y offset" msgstr "Posição Y" #: ../src/dialog_iemgui.tcl:642 #: ../src/dialog_iemgui.tcl:645 msgid "Colors" msgstr "Cores" #: ../src/dialog_iemgui.tcl:648 #: ../src/dialog_iemgui.tcl:651 msgid "Background" msgstr "Fundo" #: ../src/dialog_iemgui.tcl:650 #: ../src/dialog_iemgui.tcl:654 msgid "Front" msgstr "Fachada" #: ../src/dialog_iemgui.tcl:662 #: ../src/dialog_iemgui.tcl:668 msgid "Compose color" msgstr "Criar uma cor" #: ../src/dialog_iemgui.tcl:682 #: ../src/dialog_iemgui.tcl:688 msgid "Test label" msgstr "teste" #: ../src/dialog_midi.tcl:85 msgid "MIDI Settings" msgstr "Configuração MIDI" #: ../src/dialog_midi.tcl:220 msgid "ALSA MIDI Settings" msgstr "Configuração MIDI ALSA" #: ../src/dialog_midi.tcl:331 msgid "Use multiple ALSA devices" msgstr "Usar vários dispositivos ALSA" #: ../src/dialog_midi.tcl:337 msgid "In Ports:" msgstr "Ports de entrada:" #: ../src/dialog_midi.tcl:340 msgid "Out Ports:" msgstr "Ports de saída:" #: ../src/g_editor.c:1663 msgid "Discard changes to this window??" msgstr "Rejeitar mudanças " #: ../src/g_editor.c:1668 msgid "really quit?" msgstr "Fechar mesmo?" #: ../src/g_editor.c:1699 msgid "Close this window??" msgstr "Fechar esta janela?" #: ../src/pd-gui.tcl:185 #: ../src/pd-gui.tcl:195 #: ../src/pd-gui.tcl:206 msgid "Associated Files" msgstr "Ficheiros associados" #: ../src/pd-gui.tcl:186 #: ../src/pd-gui.tcl:196 #: ../src/pd-gui.tcl:207 msgid "Pd Files" msgstr "Ficheiros Pd" #: ../src/pd-gui.tcl:187 #: ../src/pd-gui.tcl:208 msgid "Max Patch Files" msgstr "Ficheiros Max-Patches" #: ../src/pd-gui.tcl:188 #: ../src/pd-gui.tcl:209 msgid "Max Text Files" msgstr "Ficheiros Max-Texto" #: ../src/pd-gui.tcl:197 msgid "Max Patch Files (.pat)" msgstr "Ficheiros Max-Patches (.pat)" #: ../src/pd-gui.tcl:198 msgid "Max Text Files (.mxt)" msgstr "Ficheiros Max-Texto (.mxt)" #: ../src/pd-gui.tcl:270 #, tcl-format msgid "WARNING: Font family '%s' not found, using default (%s)" msgstr "AVISO: O tipo de letra '%s' não foi encontrado, usando o padrão (%s)" #: ../src/pd-gui.tcl:278 #, tcl-format msgid "WARNING: Font weight '%s' not found, using default (%s)" msgstr "AVISO: O formato de letra '%s' não foi encontrado, usando o padrão (%s)" #: ../src/pd-gui.tcl:303 #, tcl-format #, fuzzy # this is broken, its missing all of the formats msgid "ERROR: %s failed to find font size (%s) that fits into %sx%s!" msgstr "AVISO: O tamanho de letra '%s' não foi encontrado, usando o padrão (%s)" #: ../src/pd-gui.tcl:478 #, fuzzy msgid "ERROR: 'pd' never showed up, 'pd-gui' quitting!" msgstr "ERRO: 'pd' não apareceu, 'pd-gui' vai desligar-se!" #: ../src/pd_menucommands.tcl:19 msgid "Untitled" msgstr "Sem título" #: ../src/pd_menucommands.tcl:78 #: ../src/pd_menucommands.tcl:79 #: ../src/pd_menucommands.tcl:90 msgid "Send Message..." msgstr "Enviar mensagem..." #: ../src/pd_menucommands.tcl:82 #: ../src/pd_menucommands.tcl:83 #: ../src/pd_menucommands.tcl:94 #: ../src/pd_menus.tcl:87 #: ../src/pd_menus.tcl:88 #: ../src/pd_menus.tcl:133 #: ../src/pd_menus.tcl:134 #: ../src/pd_menus.tcl:147 #: ../src/pd_menus.tcl:192 #: ../src/pd_menus.tcl:193 #: ../src/pd_menus.tcl:265 #: ../src/pd_menus.tcl:278 #: ../src/pd_menus.tcl:292 #: ../src/pd_menus.tcl:305 #: ../src/pd_menus.tcl:329 #: ../src/pd_menus.tcl:342 #: ../src/pd_menus.tcl:360 #: ../src/pd_menus.tcl:387 #: ../src/pd_menus.tcl:414 #: ../src/pd_menus.tcl:426 #: ../src/pd_menus.tcl:453 #: ../startup/object_db.tcl:123 msgid "Message" msgstr "Mensagem" #: ../src/pd_menucommands.tcl:108 #: ../src/pd_menucommands.tcl:111 #: ../src/pd_menus.tcl:112 #: ../src/pd_menus.tcl:113 #: ../src/pd_menus.tcl:117 #: ../src/pd_menus.tcl:118 #: ../src/pd_menus.tcl:158 #: ../src/pd_menus.tcl:159 #: ../src/pd_menus.tcl:163 #: ../src/pd_menus.tcl:164 msgid "Font" msgstr "Tipo de letra" #: ../src/pd_menucommands.tcl:123 #: ../src/pd_menucommands.tcl:126 #: ../src/pd_menus.tcl:138 #: ../src/pd_menus.tcl:183 #: ../src/pd_menus.tcl:184 msgid "Preferences" msgstr "Preferências" #: ../src/pd_menus.tcl:45 msgid "Edit" msgstr "Editar" #: ../src/pd_menus.tcl:45 msgid "File" msgstr "Ficheiro" #: ../src/pd_menus.tcl:45 #: ../src/pdtk_canvas.tcl:48 #: ../src/pdtk_canvas.tcl:113 msgid "Help" msgstr "Ajuda" #: ../src/pd_menus.tcl:45 msgid "Media" msgstr "" #: ../src/pd_menus.tcl:45 msgid "Put" msgstr "Put" #: ../src/pd_menus.tcl:45 msgid "Window" msgstr "Janela" #: ../src/pd_menus.tcl:81 #: ../src/pd_menus.tcl:82 #: ../src/pd_menus.tcl:127 #: ../src/pd_menus.tcl:128 #: ../src/pd_menus.tcl:255 #: ../src/pd_menus.tcl:267 #: ../src/pd_menus.tcl:285 #: ../src/pd_menus.tcl:298 #: ../src/pd_menus.tcl:322 #: ../src/pd_menus.tcl:335 #: ../src/pd_menus.tcl:349 #: ../src/pd_menus.tcl:376 #: ../src/pd_menus.tcl:380 #: ../src/pd_menus.tcl:407 #: ../src/pd_menus.tcl:419 #: ../src/pd_menus.tcl:446 msgid "New" msgstr "Novo" #: ../src/pd_menus.tcl:82 #: ../src/pd_menus.tcl:83 #: ../src/pd_menus.tcl:128 #: ../src/pd_menus.tcl:129 #: ../src/pd_menus.tcl:256 #: ../src/pd_menus.tcl:268 #: ../src/pd_menus.tcl:286 #: ../src/pd_menus.tcl:299 #: ../src/pd_menus.tcl:323 #: ../src/pd_menus.tcl:336 #: ../src/pd_menus.tcl:350 #: ../src/pd_menus.tcl:377 #: ../src/pd_menus.tcl:381 #: ../src/pd_menus.tcl:408 #: ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:447 #: ../src/pdtk_canvas.tcl:46 #: ../src/pdtk_canvas.tcl:111 #: ../src/pdtk_canvas.tcl:131 #: ../src/pdtk_canvas.tcl:133 msgid "Open" msgstr "Abrir" #: ../src/pd_menus.tcl:84 #: ../src/pd_menus.tcl:85 #: ../src/pd_menus.tcl:130 #: ../src/pd_menus.tcl:131 #: ../src/pd_menus.tcl:261 #: ../src/pd_menus.tcl:274 #: ../src/pd_menus.tcl:289 #: ../src/pd_menus.tcl:302 #: ../src/pd_menus.tcl:326 #: ../src/pd_menus.tcl:339 #: ../src/pd_menus.tcl:356 #: ../src/pd_menus.tcl:383 #: ../src/pd_menus.tcl:384 #: ../src/pd_menus.tcl:411 #: ../src/pd_menus.tcl:423 #: ../src/pd_menus.tcl:450 msgid "Save As..." msgstr "Guardar como..." #: ../src/pd_menus.tcl:88 #: ../src/pd_menus.tcl:89 #: ../src/pd_menus.tcl:134 #: ../src/pd_menus.tcl:135 #: ../src/pd_menus.tcl:267 #: ../src/pd_menus.tcl:280 #: ../src/pd_menus.tcl:293 #: ../src/pd_menus.tcl:306 #: ../src/pd_menus.tcl:330 #: ../src/pd_menus.tcl:343 #: ../src/pd_menus.tcl:362 #: ../src/pd_menus.tcl:388 #: ../src/pd_menus.tcl:389 #: ../src/pd_menus.tcl:415 #: ../src/pd_menus.tcl:427 #: ../src/pd_menus.tcl:454 msgid "Print..." msgstr "Imprimir" #: ../src/pd_menus.tcl:93 #: ../src/pd_menus.tcl:94 #: ../src/pd_menus.tcl:139 #: ../src/pd_menus.tcl:140 msgid "Undo" msgstr "Anular" #: ../src/pd_menus.tcl:95 #: ../src/pd_menus.tcl:96 #: ../src/pd_menus.tcl:141 #: ../src/pd_menus.tcl:142 msgid "Redo" msgstr "Restaurar" #: ../src/pd_menus.tcl:98 #: ../src/pd_menus.tcl:99 #: ../src/pd_menus.tcl:144 #: ../src/pd_menus.tcl:145 msgid "Cut" msgstr "Cortar" #: ../src/pd_menus.tcl:104 #: ../src/pd_menus.tcl:105 #: ../src/pd_menus.tcl:150 #: ../src/pd_menus.tcl:151 msgid "Duplicate" msgstr "Duplicar" #: ../src/pd_menus.tcl:106 #: ../src/pd_menus.tcl:107 #: ../src/pd_menus.tcl:152 #: ../src/pd_menus.tcl:153 msgid "Select All" msgstr "Escolher tudo" #: ../src/pd_menus.tcl:110 #: ../src/pd_menus.tcl:111 #: ../src/pd_menus.tcl:115 #: ../src/pd_menus.tcl:116 #: ../src/pd_menus.tcl:156 #: ../src/pd_menus.tcl:157 #: ../src/pd_menus.tcl:161 #: ../src/pd_menus.tcl:162 msgid "Text Editor" msgstr "Editor de texto" #: ../src/pd_menus.tcl:120 #: ../src/pd_menus.tcl:121 #: ../src/pd_menus.tcl:166 #: ../src/pd_menus.tcl:167 msgid "Tidy Up" msgstr "Arrumar" #: ../src/pd_menus.tcl:122 #: ../src/pd_menus.tcl:123 #: ../src/pd_menus.tcl:168 #: ../src/pd_menus.tcl:169 msgid "Toggle Console" msgstr "Mostrar consola" #: ../src/pd_menus.tcl:124 #: ../src/pd_menus.tcl:125 #: ../src/pd_menus.tcl:170 #: ../src/pd_menus.tcl:171 msgid "Clear Console" msgstr "Limpar consola" #: ../src/pd_menus.tcl:128 #: ../src/pd_menus.tcl:129 #: ../src/pd_menus.tcl:174 #: ../src/pd_menus.tcl:175 msgid "Edit Mode" msgstr "Modo de edição" #: ../src/pd_menus.tcl:145 #: ../src/pd_menus.tcl:190 #: ../src/pd_menus.tcl:191 msgid "Object" msgstr "Object" #: ../src/pd_menus.tcl:149 #: ../src/pd_menus.tcl:194 #: ../src/pd_menus.tcl:195 msgid "Number" msgstr "Número" #: ../src/pd_menus.tcl:151 #: ../src/pd_menus.tcl:196 #: ../src/pd_menus.tcl:197 msgid "Symbol" msgstr "Symbol" #: ../src/pd_menus.tcl:153 #: ../src/pd_menus.tcl:198 #: ../src/pd_menus.tcl:199 msgid "Comment" msgstr "Comment" #: ../src/pd_menus.tcl:156 #: ../src/pd_menus.tcl:201 #: ../src/pd_menus.tcl:202 msgid "Bang" msgstr "Bang" #: ../src/pd_menus.tcl:158 #: ../src/pd_menus.tcl:203 #: ../src/pd_menus.tcl:204 msgid "Toggle" msgstr "Toggle" #: ../src/pd_menus.tcl:160 #: ../src/pd_menus.tcl:205 #: ../src/pd_menus.tcl:206 msgid "Number2" msgstr "Number2" #: ../src/pd_menus.tcl:162 #: ../src/pd_menus.tcl:207 #: ../src/pd_menus.tcl:208 msgid "Vslider" msgstr "Vslider" #: ../src/pd_menus.tcl:164 #: ../src/pd_menus.tcl:209 #: ../src/pd_menus.tcl:210 msgid "Hslider" msgstr "Hslider" #: ../src/pd_menus.tcl:166 #: ../src/pd_menus.tcl:211 #: ../src/pd_menus.tcl:212 msgid "Vradio" msgstr "Vradio" #: ../src/pd_menus.tcl:168 #: ../src/pd_menus.tcl:213 #: ../src/pd_menus.tcl:214 msgid "Hradio" msgstr "Hradio" #: ../src/pd_menus.tcl:170 #: ../src/pd_menus.tcl:215 #: ../src/pd_menus.tcl:216 msgid "VU Meter" msgstr "VU Meter" #: ../src/pd_menus.tcl:172 #: ../src/pd_menus.tcl:217 #: ../src/pd_menus.tcl:218 msgid "Canvas" msgstr "Canvas" #: ../src/pd_menus.tcl:175 #: ../src/pd_menus.tcl:220 #: ../src/pd_menus.tcl:221 msgid "Graph" msgstr "Graph" #: ../src/pd_menus.tcl:176 #: ../src/pd_menus.tcl:221 #: ../src/pd_menus.tcl:222 msgid "Array" msgstr "Array" #: ../src/pd_menus.tcl:181 #: ../src/pd_menus.tcl:226 #: ../src/pd_menus.tcl:227 msgid "Find..." msgstr "Localizar..." #: ../src/pd_menus.tcl:183 #: ../src/pd_menus.tcl:228 #: ../src/pd_menus.tcl:229 msgid "Find Again" msgstr "Localizar de novo" #: ../src/pd_menus.tcl:185 #: ../src/pd_menus.tcl:230 #: ../src/pd_menus.tcl:231 msgid "Find Last Error" msgstr "Localizar último erro" #: ../src/pd_menus.tcl:191 #: ../src/pd_menus.tcl:236 #: ../src/pd_menus.tcl:237 msgid "DSP On" msgstr "DSP Ligado" #: ../src/pd_menus.tcl:193 #: ../src/pd_menus.tcl:238 #: ../src/pd_menus.tcl:239 msgid "DSP Off" msgstr "DSP Desligado" #: ../src/pd_menus.tcl:196 #: ../src/pd_menus.tcl:242 #: ../src/pd_menus.tcl:269 msgid "Test Audio and MIDI..." msgstr "Testar audio e MIDI..." #: ../src/pd_menus.tcl:198 #: ../src/pd_menus.tcl:244 #: ../src/pd_menus.tcl:271 msgid "Load Meter" msgstr "Carregar medidor" #: ../src/pd_menus.tcl:205 #: ../src/pd_menus.tcl:251 #: ../src/pd_menus.tcl:278 msgid "Minimize" msgstr "Minimizar" #: ../src/pd_menus.tcl:207 #: ../src/pd_menus.tcl:253 #: ../src/pd_menus.tcl:280 msgid "Zoom" msgstr "Zoom" #: ../src/pd_menus.tcl:210 #: ../src/pd_menus.tcl:256 #: ../src/pd_menus.tcl:283 msgid "Parent Window" msgstr "Janela superior" #: ../src/pd_menus.tcl:216 #: ../src/pd_menus.tcl:262 #: ../src/pd_menus.tcl:289 msgid "Bring All to Front" msgstr "" #: ../src/pd_menus.tcl:224 #: ../src/pd_menus.tcl:241 #: ../src/pd_menus.tcl:253 #: ../src/pd_menus.tcl:270 #: ../src/pd_menus.tcl:297 #: ../src/pd_menus.tcl:335 #: ../src/pd_menus.tcl:362 msgid "About Pd" msgstr "Sobre o Pd" #: ../src/pd_menus.tcl:227 #: ../src/pd_menus.tcl:273 #: ../src/pd_menus.tcl:300 msgid "HTML Manual..." msgstr "Manual HTML" #: ../src/pd_menus.tcl:229 #: ../src/pd_menus.tcl:275 #: ../src/pd_menus.tcl:302 msgid "Browser..." msgstr "Navegador" #: ../src/pd_menus.tcl:248 #: ../src/pd_menus.tcl:260 #: ../src/pd_menus.tcl:342 #: ../src/pd_menus.tcl:369 msgid "Preferences..." msgstr "Preferências..." #: ../src/pd_menus.tcl:257 #: ../src/pd_menus.tcl:270 #: ../src/pd_menus.tcl:352 #: ../src/pd_menus.tcl:379 msgid "Open Recent" msgstr "Abrir recente" #: ../src/pd_menus.tcl:263 msgid "Audio Settings..." msgstr "Configuração audio..." #: ../src/pd_menus.tcl:265 msgid "MIDI Settings..." msgstr "Configuração MIDI..." #: ../src/pd_menus.tcl:296 #: ../src/pd_menus.tcl:309 #: ../src/pd_menus.tcl:333 #: ../src/pd_menus.tcl:346 #: ../src/pd_menus.tcl:393 #: ../src/pd_menus.tcl:420 #: ../src/pd_menus.tcl:432 #: ../src/pd_menus.tcl:459 msgid "Quit" msgstr "Sair" #: ../src/pd_menus.tcl:304 #: ../src/pd_menus.tcl:331 msgid "Clear Menu" msgstr "Limpar menu" #: ../src/pdtk_canvas.tcl:44 #: ../src/pdtk_canvas.tcl:109 #: ../src/pdtk_canvas.tcl:126 #: ../src/pdtk_canvas.tcl:128 msgid "Properties" msgstr "Propriedades" #: ../src/pdwindow.tcl:43 msgid "DSP" msgstr "DSP" #: ../startup/object_db.tcl:113 msgid "Signal" msgstr "Sinal" #: ../startup/object_db.tcl:114 msgid "Generators" msgstr "Geradores" #: ../startup/object_db.tcl:115 msgid "Filters" msgstr "Filtros" #: ../startup/object_db.tcl:116 #: ../startup/object_db.tcl:124 msgid "Math" msgstr "Matemática" #: ../startup/object_db.tcl:117 #: ../startup/object_db.tcl:125 msgid "I/O" msgstr "Entrada/Saída" #: ../startup/object_db.tcl:118 #: ../startup/object_db.tcl:126 msgid "Sampling" msgstr "" #: ../startup/object_db.tcl:119 #: ../startup/object_db.tcl:128 msgid "Routing" msgstr "" #: ../startup/object_db.tcl:120 #: ../startup/object_db.tcl:129 msgid "Others" msgstr "Outros" #: ../startup/object_db.tcl:127 msgid "GUI" msgstr "GUI" pd-0.46-7/po/template.pot0000664000175000017500000004311612160204055013351 0ustar mspmsp# SOME DESCRIPTIVE TITLE. # This file is put in the public domain. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Pure Data 0.43\n" "Report-Msgid-Bugs-To: pd-dev@iem.at\n" "POT-Creation-Date: 2011-03-18 09:54-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #: ../tcl/dialog_array.tcl:115 ../tcl/pd_menus.tcl:147 msgid "Copy" msgstr "" #: ../tcl/dialog_array.tcl:118 ../tcl/pd_menus.tcl:149 msgid "Paste" msgstr "" #: ../tcl/dialog_array.tcl:263 msgid "Array Properties" msgstr "" #: ../tcl/dialog_array.tcl:273 msgid "Name:" msgstr "" #: ../tcl/dialog_array.tcl:279 ../tcl/dialog_canvas.tcl:181 #: ../tcl/dialog_canvas.tcl:196 ../tcl/dialog_iemgui.tcl:630 msgid "Size:" msgstr "" #: ../tcl/dialog_array.tcl:283 msgid "Save contents" msgstr "" #: ../tcl/dialog_array.tcl:287 msgid "Draw as:" msgstr "" #: ../tcl/dialog_array.tcl:290 msgid "Points" msgstr "" #: ../tcl/dialog_array.tcl:292 msgid "Polygon" msgstr "" #: ../tcl/dialog_array.tcl:294 msgid "Bezier curve" msgstr "" #: ../tcl/dialog_array.tcl:300 msgid "Put array into:" msgstr "" #: ../tcl/dialog_array.tcl:303 msgid "New graph" msgstr "" #: ../tcl/dialog_array.tcl:305 msgid "Last graph" msgstr "" #: ../tcl/dialog_array.tcl:309 msgid "Delete array" msgstr "" #: ../tcl/dialog_array.tcl:315 msgid "Open List View..." msgstr "" #: ../tcl/dialog_array.tcl:322 ../tcl/dialog_audio.tcl:146 #: ../tcl/dialog_canvas.tcl:208 ../tcl/dialog_find.tcl:163 #: ../tcl/dialog_gatom.tcl:157 ../tcl/dialog_iemgui.tcl:751 #: ../tcl/dialog_midi.tcl:98 ../tcl/dialog_midi.tcl:233 #: ../tcl/scrollboxwindow.tcl:82 msgid "Cancel" msgstr "" #: ../tcl/dialog_array.tcl:326 ../tcl/dialog_audio.tcl:149 #: ../tcl/dialog_canvas.tcl:212 ../tcl/dialog_gatom.tcl:161 #: ../tcl/dialog_iemgui.tcl:755 ../tcl/dialog_midi.tcl:100 #: ../tcl/dialog_midi.tcl:235 ../tcl/scrollboxwindow.tcl:84 msgid "Apply" msgstr "" #: ../tcl/dialog_array.tcl:330 ../tcl/dialog_audio.tcl:152 #: ../tcl/dialog_canvas.tcl:216 ../tcl/dialog_font.tcl:103 #: ../tcl/dialog_gatom.tcl:165 ../tcl/dialog_iemgui.tcl:759 #: ../tcl/dialog_midi.tcl:102 ../tcl/dialog_midi.tcl:237 #: ../tcl/dialog_startup.tcl:29 ../tcl/dialog_startup.tcl:30 #: ../tcl/scrollboxwindow.tcl:86 msgid "OK" msgstr "" #: ../tcl/dialog_audio.tcl:134 msgid "Audio Settings" msgstr "" #: ../tcl/dialog_audio.tcl:156 msgid "Save All Settings" msgstr "" #: ../tcl/dialog_audio.tcl:164 msgid "Sample rate:" msgstr "" #: ../tcl/dialog_audio.tcl:166 msgid "Delay (msec):" msgstr "" #: ../tcl/dialog_audio.tcl:169 msgid "Block size:" msgstr "" #: ../tcl/dialog_audio.tcl:176 msgid "Use callbacks" msgstr "" #: ../tcl/dialog_audio.tcl:184 ../tcl/dialog_midi.tcl:112 #: ../tcl/dialog_midi.tcl:248 msgid "Input device 1:" msgstr "" #: ../tcl/dialog_audio.tcl:187 ../tcl/dialog_audio.tcl:202 #: ../tcl/dialog_audio.tcl:218 ../tcl/dialog_audio.tcl:233 #: ../tcl/dialog_audio.tcl:253 ../tcl/dialog_audio.tcl:272 #: ../tcl/dialog_audio.tcl:288 ../tcl/dialog_audio.tcl:304 msgid "Channels:" msgstr "" #: ../tcl/dialog_audio.tcl:198 ../tcl/dialog_midi.tcl:122 #: ../tcl/dialog_midi.tcl:258 msgid "Input device 2:" msgstr "" #: ../tcl/dialog_audio.tcl:214 ../tcl/dialog_midi.tcl:134 #: ../tcl/dialog_midi.tcl:270 msgid "Input device 3:" msgstr "" #: ../tcl/dialog_audio.tcl:229 ../tcl/dialog_midi.tcl:146 #: ../tcl/dialog_midi.tcl:282 msgid "Input device 4:" msgstr "" #: ../tcl/dialog_audio.tcl:244 ../tcl/dialog_midi.tcl:157 #: ../tcl/dialog_midi.tcl:293 msgid "Output device 1:" msgstr "" #: ../tcl/dialog_audio.tcl:247 msgid "(same as input device) .............. " msgstr "" #: ../tcl/dialog_audio.tcl:268 ../tcl/dialog_midi.tcl:167 #: ../tcl/dialog_midi.tcl:303 msgid "Output device 2:" msgstr "" #: ../tcl/dialog_audio.tcl:284 ../tcl/dialog_midi.tcl:178 #: ../tcl/dialog_midi.tcl:314 msgid "Output device 3:" msgstr "" #: ../tcl/dialog_audio.tcl:300 ../tcl/dialog_midi.tcl:189 #: ../tcl/dialog_midi.tcl:325 msgid "Output device 4:" msgstr "" #: ../tcl/dialog_audio.tcl:316 ../tcl/dialog_midi.tcl:202 msgid "Use multiple devices" msgstr "" #: ../tcl/dialog_canvas.tcl:121 msgid "WARNING: unknown graphme flags received in pdtk_canvas_dialog" msgstr "" #: ../tcl/dialog_canvas.tcl:141 msgid "Canvas Properties" msgstr "" #: ../tcl/dialog_canvas.tcl:149 msgid "Scale" msgstr "" #: ../tcl/dialog_canvas.tcl:153 msgid "X units per pixel:" msgstr "" #: ../tcl/dialog_canvas.tcl:158 msgid "Y units per pixel:" msgstr "" #: ../tcl/dialog_canvas.tcl:162 msgid "Appearance on parent patch" msgstr "" #: ../tcl/dialog_canvas.tcl:164 msgid "Graph-On-Parent" msgstr "" #: ../tcl/dialog_canvas.tcl:168 msgid "Hide object name and arguments" msgstr "" #: ../tcl/dialog_canvas.tcl:173 msgid "Range and size" msgstr "" #: ../tcl/dialog_canvas.tcl:177 msgid "X range, from" msgstr "" #: ../tcl/dialog_canvas.tcl:179 ../tcl/dialog_canvas.tcl:194 msgid "to" msgstr "" #: ../tcl/dialog_canvas.tcl:183 ../tcl/dialog_canvas.tcl:198 msgid "Margin:" msgstr "" #: ../tcl/dialog_canvas.tcl:192 msgid "Y range, from" msgstr "" #: ../tcl/dialog_data.tcl:29 msgid "Data Properties" msgstr "" #: ../tcl/dialog_data.tcl:37 msgid "Send (Ctrl s)" msgstr "" #: ../tcl/dialog_data.tcl:39 msgid "OK (Ctrl t)" msgstr "" #: ../tcl/dialog_find.tcl:108 #, tcl-format msgid "Couldn't find '%s' in %s" msgstr "" #: ../tcl/dialog_find.tcl:126 ../tcl/dialog_find.tcl:167 msgid "Find" msgstr "" #: ../tcl/dialog_find.tcl:145 msgid "Search in" msgstr "" #: ../tcl/dialog_find.tcl:146 ../tcl/pd_menus.tcl:283 msgid "Pd window" msgstr "" #: ../tcl/dialog_find.tcl:147 msgid "for:" msgstr "" #: ../tcl/dialog_find.tcl:157 msgid "Match whole word only" msgstr "" #: ../tcl/dialog_find.tcl:171 ../tcl/pd_menus.tcl:58 ../tcl/pd_menus.tcl:80 #: ../tcl/pd_menus.tcl:106 ../tcl/pd_menus.tcl:133 ../tcl/pd_menus.tcl:487 #: ../tcl/pd_menus.tcl:525 ../tcl/pd_menus.tcl:572 msgid "Close" msgstr "" #: ../tcl/dialog_font.tcl:49 #, tcl-format msgid "%s Font" msgstr "" #: ../tcl/dialog_font.tcl:107 msgid "Font Size" msgstr "" #: ../tcl/dialog_font.tcl:119 msgid "Stretch" msgstr "" #: ../tcl/dialog_font.tcl:126 msgid "X and Y" msgstr "" #: ../tcl/dialog_font.tcl:128 msgid "X only" msgstr "" #: ../tcl/dialog_font.tcl:130 msgid "Y only" msgstr "" #: ../tcl/dialog_gatom.tcl:93 msgid "Atom Box Properties" msgstr "" #: ../tcl/dialog_gatom.tcl:103 msgid "Width:" msgstr "" #: ../tcl/dialog_gatom.tcl:107 msgid "Limits" msgstr "" #: ../tcl/dialog_gatom.tcl:111 msgid "Lower:" msgstr "" #: ../tcl/dialog_gatom.tcl:116 msgid "Upper:" msgstr "" #: ../tcl/dialog_gatom.tcl:120 ../tcl/dialog_iemgui.tcl:610 #: ../tcl/dialog_iemgui.tcl:663 msgid "Label" msgstr "" #: ../tcl/dialog_gatom.tcl:128 msgid "Left " msgstr "" #: ../tcl/dialog_gatom.tcl:130 msgid "Right" msgstr "" #: ../tcl/dialog_gatom.tcl:132 msgid "Top" msgstr "" #: ../tcl/dialog_gatom.tcl:134 msgid "Bottom" msgstr "" #: ../tcl/dialog_gatom.tcl:141 ../tcl/dialog_iemgui.tcl:580 msgid "Messages" msgstr "" #: ../tcl/dialog_gatom.tcl:145 ../tcl/dialog_iemgui.tcl:584 msgid "Send symbol:" msgstr "" #: ../tcl/dialog_gatom.tcl:151 ../tcl/dialog_iemgui.tcl:593 msgid "Receive symbol:" msgstr "" #: ../tcl/dialog_iemgui.tcl:197 msgid "Background color" msgstr "" #: ../tcl/dialog_iemgui.tcl:204 msgid "Foreground color" msgstr "" #: ../tcl/dialog_iemgui.tcl:211 msgid "Label color" msgstr "" #: ../tcl/dialog_iemgui.tcl:272 msgid "Init" msgstr "" #: ../tcl/dialog_iemgui.tcl:275 ../tcl/dialog_iemgui.tcl:554 msgid "No init" msgstr "" #: ../tcl/dialog_iemgui.tcl:287 ../tcl/dialog_iemgui.tcl:564 msgid "Jump on click" msgstr "" #: ../tcl/dialog_iemgui.tcl:290 ../tcl/dialog_iemgui.tcl:567 msgid "Steady on click" msgstr "" #: ../tcl/dialog_iemgui.tcl:502 #, tcl-format msgid "%s Properties" msgstr "" #: ../tcl/dialog_iemgui.tcl:557 ../tcl/pd_menus.tcl:55 ../tcl/pd_menus.tcl:77 #: ../tcl/pd_menus.tcl:102 ../tcl/pd_menus.tcl:130 ../tcl/pd_menus.tcl:488 #: ../tcl/pd_menus.tcl:516 ../tcl/pd_menus.tcl:561 msgid "Save" msgstr "" #: ../tcl/dialog_iemgui.tcl:618 msgid "X offset" msgstr "" #: ../tcl/dialog_iemgui.tcl:621 msgid "Y offset" msgstr "" #: ../tcl/dialog_iemgui.tcl:653 msgid "Colors" msgstr "" #: ../tcl/dialog_iemgui.tcl:659 msgid "Background" msgstr "" #: ../tcl/dialog_iemgui.tcl:661 msgid "Front" msgstr "" #: ../tcl/dialog_iemgui.tcl:673 msgid "Compose color" msgstr "" #: ../tcl/dialog_iemgui.tcl:692 msgid "Test label" msgstr "" #: ../tcl/dialog_message.tcl:61 msgid "Send a Pd message" msgstr "" #: ../tcl/dialog_message.tcl:80 msgid "(use arrow keys for history)" msgstr "" #: ../tcl/dialog_midi.tcl:86 msgid "MIDI Settings" msgstr "" #: ../tcl/dialog_midi.tcl:227 msgid "ALSA MIDI Settings" msgstr "" #: ../tcl/dialog_midi.tcl:338 msgid "Use multiple ALSA devices" msgstr "" #: ../tcl/dialog_midi.tcl:344 msgid "In Ports:" msgstr "" #: ../tcl/dialog_midi.tcl:347 msgid "Out Ports:" msgstr "" #: ../tcl/dialog_path.tcl:32 msgid "Pd search path for objects, help, fonts, and other files" msgstr "" #: ../tcl/dialog_path.tcl:37 msgid "Use standard extensions" msgstr "" #: ../tcl/dialog_path.tcl:39 msgid "Verbose" msgstr "" #: ../tcl/dialog_startup.tcl:49 msgid "Add new library" msgstr "" #: ../tcl/dialog_startup.tcl:53 msgid "Edit library" msgstr "" #: ../tcl/dialog_startup.tcl:79 msgid "Pd libraries to load on startup" msgstr "" #: ../tcl/dialog_startup.tcl:82 msgid "Startup flags:" msgstr "" #: ../tcl/dialog_startup.tcl:91 msgid "Defeat real-time scheduling" msgstr "" #: ../tcl/helpbrowser.tcl:27 msgid "Help Browser" msgstr "" #: ../tcl/pd_connect.tcl:82 ../tcl/pdwindow.tcl:221 msgid "(Tcl) INVALID COMMAND NAME: " msgstr "" #: ../tcl/pd_connect.tcl:84 ../tcl/pdwindow.tcl:223 msgid "(Tcl) UNHANDLED ERROR: " msgstr "" #: ../tcl/pd_menucommands.tcl:201 ../tcl/pd_menus.tcl:292 #: ../tcl/pd_menus.tcl:470 msgid "About Pd" msgstr "" #: ../tcl/pd_menus.tcl:56 ../tcl/pd_menus.tcl:78 ../tcl/pd_menus.tcl:103 #: ../tcl/pd_menus.tcl:131 ../tcl/pd_menus.tcl:489 ../tcl/pd_menus.tcl:517 #: ../tcl/pd_menus.tcl:562 msgid "Save As..." msgstr "" #: ../tcl/pd_menus.tcl:57 ../tcl/pd_menus.tcl:79 ../tcl/pd_menus.tcl:104 #: ../tcl/pd_menus.tcl:135 ../tcl/pd_menus.tcl:495 ../tcl/pd_menus.tcl:521 #: ../tcl/pd_menus.tcl:568 msgid "Print..." msgstr "" #: ../tcl/pd_menus.tcl:60 ../tcl/pd_menus.tcl:82 ../tcl/pd_menus.tcl:108 #: ../tcl/pd_menus.tcl:151 msgid "Duplicate" msgstr "" #: ../tcl/pd_menus.tcl:61 ../tcl/pd_menus.tcl:83 ../tcl/pd_menus.tcl:109 #: ../tcl/pd_menus.tcl:167 msgid "Tidy Up" msgstr "" #: ../tcl/pd_menus.tcl:62 ../tcl/pd_menus.tcl:84 ../tcl/pd_menus.tcl:110 #: ../tcl/pd_menus.tcl:173 ../tcl/pd_menus.tcl:549 ../tcl/pdtk_canvas.tcl:270 #: ../tcl/pdtk_canvas.tcl:272 msgid "Edit Mode" msgstr "" #: ../tcl/pd_menus.tcl:65 ../tcl/pd_menus.tcl:113 ../tcl/pd_menus.tcl:140 #: ../tcl/pd_menus.tcl:318 msgid "Undo" msgstr "" #: ../tcl/pd_menus.tcl:66 ../tcl/pd_menus.tcl:114 ../tcl/pd_menus.tcl:142 #: ../tcl/pd_menus.tcl:324 msgid "Redo" msgstr "" #: ../tcl/pd_menus.tcl:128 ../tcl/pd_menus.tcl:482 ../tcl/pd_menus.tcl:513 #: ../tcl/pd_menus.tcl:558 msgid "New" msgstr "" #: ../tcl/pd_menus.tcl:129 ../tcl/pd_menus.tcl:483 ../tcl/pd_menus.tcl:514 #: ../tcl/pd_menus.tcl:559 ../tcl/pdtk_canvas.tcl:200 #: ../tcl/pdtk_canvas.tcl:220 ../tcl/pdtk_canvas.tcl:222 msgid "Open" msgstr "" #: ../tcl/pd_menus.tcl:134 ../tcl/pd_menus.tcl:493 ../tcl/pd_menus.tcl:520 #: ../tcl/pd_menus.tcl:565 msgid "Message..." msgstr "" #: ../tcl/pd_menus.tcl:145 msgid "Cut" msgstr "" #: ../tcl/pd_menus.tcl:153 msgid "Select All" msgstr "" #: ../tcl/pd_menus.tcl:159 ../tcl/pd_menus.tcl:164 msgid "Font" msgstr "" #: ../tcl/pd_menus.tcl:169 msgid "Clear Console" msgstr "" #: ../tcl/pd_menus.tcl:183 msgid "Object" msgstr "" #: ../tcl/pd_menus.tcl:185 msgid "Message" msgstr "" #: ../tcl/pd_menus.tcl:187 msgid "Number" msgstr "" #: ../tcl/pd_menus.tcl:189 msgid "Symbol" msgstr "" #: ../tcl/pd_menus.tcl:191 msgid "Comment" msgstr "" #: ../tcl/pd_menus.tcl:194 msgid "Bang" msgstr "" #: ../tcl/pd_menus.tcl:196 msgid "Toggle" msgstr "" #: ../tcl/pd_menus.tcl:198 msgid "Number2" msgstr "" #: ../tcl/pd_menus.tcl:200 msgid "Vslider" msgstr "" #: ../tcl/pd_menus.tcl:202 msgid "Hslider" msgstr "" #: ../tcl/pd_menus.tcl:204 msgid "Vradio" msgstr "" #: ../tcl/pd_menus.tcl:206 msgid "Hradio" msgstr "" #: ../tcl/pd_menus.tcl:208 msgid "VU Meter" msgstr "" #: ../tcl/pd_menus.tcl:210 msgid "Canvas" msgstr "" #: ../tcl/pd_menus.tcl:213 msgid "Graph" msgstr "" #: ../tcl/pd_menus.tcl:214 msgid "Array" msgstr "" #: ../tcl/pd_menus.tcl:219 msgid "Find..." msgstr "" #: ../tcl/pd_menus.tcl:221 msgid "Find Again" msgstr "" #: ../tcl/pd_menus.tcl:223 msgid "Find Last Error" msgstr "" #: ../tcl/pd_menus.tcl:229 msgid "DSP On" msgstr "" #: ../tcl/pd_menus.tcl:231 msgid "DSP Off" msgstr "" #: ../tcl/pd_menus.tcl:235 msgid "Test Audio and MIDI..." msgstr "" #: ../tcl/pd_menus.tcl:237 msgid "Load Meter" msgstr "" #: ../tcl/pd_menus.tcl:260 ../tcl/pd_menus.tcl:473 ../tcl/pd_menus.tcl:567 msgid "Preferences" msgstr "" #: ../tcl/pd_menus.tcl:267 msgid "Minimize" msgstr "" #: ../tcl/pd_menus.tcl:269 msgid "Zoom" msgstr "" #: ../tcl/pd_menus.tcl:272 msgid "Bring All to Front" msgstr "" #: ../tcl/pd_menus.tcl:275 msgid "Next Window" msgstr "" #: ../tcl/pd_menus.tcl:278 msgid "Previous Window" msgstr "" #: ../tcl/pd_menus.tcl:285 msgid "Parent Window" msgstr "" #: ../tcl/pd_menus.tcl:294 msgid "HTML Manual..." msgstr "" #: ../tcl/pd_menus.tcl:296 msgid "Browser..." msgstr "" #: ../tcl/pd_menus.tcl:299 msgid "puredata.info" msgstr "" #: ../tcl/pd_menus.tcl:301 msgid "Report a bug" msgstr "" #: ../tcl/pd_menus.tcl:304 msgid "Tcl prompt" msgstr "" #: ../tcl/pd_menus.tcl:348 msgid "Clear Menu" msgstr "" #: ../tcl/pd_menus.tcl:453 msgid "Path..." msgstr "" #: ../tcl/pd_menus.tcl:455 msgid "Startup..." msgstr "" #: ../tcl/pd_menus.tcl:457 msgid "Audio Settings..." msgstr "" #: ../tcl/pd_menus.tcl:459 msgid "MIDI Settings..." msgstr "" #: ../tcl/pd_menus.tcl:485 msgid "Open Recent" msgstr "" #: ../tcl/pd_menus.tcl:526 ../tcl/pd_menus.tcl:573 msgid "Quit" msgstr "" #: ../tcl/pdtk_canvas.tcl:198 ../tcl/pdtk_canvas.tcl:215 #: ../tcl/pdtk_canvas.tcl:217 msgid "Properties" msgstr "" #: ../tcl/pdtk_canvas.tcl:202 msgid "Help" msgstr "" #: ../tcl/pdwindow.tcl:217 msgid "(Tcl) MISSING CLOSE-BRACE '}': " msgstr "" #: ../tcl/pdwindow.tcl:219 msgid "(Tcl) MISSING CLOSE-BRACKET ']': " msgstr "" #: ../tcl/pdwindow.tcl:258 msgid "Tcl:" msgstr "" #: ../tcl/pdwindow.tcl:301 ../tcl/pdwindow.tcl:302 msgid "Pd" msgstr "" #: ../tcl/pdwindow.tcl:317 msgid "DSP" msgstr "" #: ../tcl/pdwindow.tcl:322 msgid "audio I/O error" msgstr "" #: ../tcl/pdwindow.tcl:328 msgid "Log:" msgstr "" #: ../tcl/pdwindow.tcl:333 msgid "fatal" msgstr "" #: ../tcl/pdwindow.tcl:334 msgid "error" msgstr "" #: ../tcl/pdwindow.tcl:335 msgid "normal" msgstr "" #: ../tcl/pdwindow.tcl:336 msgid "debug" msgstr "" #: ../tcl/pdwindow.tcl:337 msgid "all" msgstr "" #: ../tcl/wheredoesthisgo.tcl:19 #, tcl-format msgid "Ignoring '%s': doesn't look like a Pd-file" msgstr "" #: iemgui_dynamic_strings.tcl:11 msgid "-------dimensions(digits)(pix):-------" msgstr "" #: iemgui_dynamic_strings.tcl:12 msgid "--------dimensions(pix)(pix):--------" msgstr "" #: iemgui_dynamic_strings.tcl:13 msgid "----------dimensions(pix):-----------" msgstr "" #: iemgui_dynamic_strings.tcl:14 msgid "--------flash-time(ms)(ms):---------" msgstr "" #: iemgui_dynamic_strings.tcl:15 msgid "-----------output-range:-----------" msgstr "" #: iemgui_dynamic_strings.tcl:16 msgid "------selectable_dimensions(pix):------" msgstr "" #: iemgui_dynamic_strings.tcl:17 msgid "------visible_rectangle(pix)(pix):------" msgstr "" #: iemgui_dynamic_strings.tcl:20 msgid "bottom:" msgstr "" #: iemgui_dynamic_strings.tcl:21 msgid "height:" msgstr "" #: iemgui_dynamic_strings.tcl:22 msgid "hold:" msgstr "" #: iemgui_dynamic_strings.tcl:23 msgid "intrrpt:" msgstr "" #: iemgui_dynamic_strings.tcl:24 msgid "left:" msgstr "" #: iemgui_dynamic_strings.tcl:25 msgid "lin" msgstr "" #: iemgui_dynamic_strings.tcl:26 msgid "log" msgstr "" #: iemgui_dynamic_strings.tcl:27 msgid "log-height:" msgstr "" #: iemgui_dynamic_strings.tcl:28 msgid "max:" msgstr "" #: iemgui_dynamic_strings.tcl:29 msgid "min:" msgstr "" #: iemgui_dynamic_strings.tcl:30 msgid "right:" msgstr "" #: iemgui_dynamic_strings.tcl:31 msgid "size:" msgstr "" #: iemgui_dynamic_strings.tcl:32 msgid "top:" msgstr "" #: iemgui_dynamic_strings.tcl:33 msgid "value:" msgstr "" #: iemgui_dynamic_strings.tcl:34 msgid "width:" msgstr "" #: pd_dynamic_strings.tcl:10 #, tcl-format msgid "Do you want to save the changes you made in '%s'?" msgstr "" #: pd_dynamic_strings.tcl:11 #, tcl-format msgid "Discard changes to '%s'?" msgstr "" #: pd_dynamic_strings.tcl:13 msgid "Undo clear" msgstr "" #: pd_dynamic_strings.tcl:14 msgid "Undo connect" msgstr "" #: pd_dynamic_strings.tcl:15 msgid "Undo cut" msgstr "" #: pd_dynamic_strings.tcl:16 msgid "Undo disconnect" msgstr "" #: pd_dynamic_strings.tcl:17 msgid "Undo duplicate" msgstr "" #: pd_dynamic_strings.tcl:18 msgid "Undo motion" msgstr "" #: pd_dynamic_strings.tcl:19 msgid "Undo paste" msgstr "" #: pd_dynamic_strings.tcl:20 msgid "Undo typing" msgstr "" #: pd_dynamic_strings.tcl:22 msgid "Redo clear" msgstr "" #: pd_dynamic_strings.tcl:23 msgid "Redo connect" msgstr "" #: pd_dynamic_strings.tcl:24 msgid "Redo cut" msgstr "" #: pd_dynamic_strings.tcl:25 msgid "Redo disconnect" msgstr "" #: pd_dynamic_strings.tcl:26 msgid "Redo duplicate" msgstr "" #: pd_dynamic_strings.tcl:27 msgid "Redo motion" msgstr "" #: pd_dynamic_strings.tcl:28 msgid "Redo paste" msgstr "" #: pd_dynamic_strings.tcl:29 msgid "Redo typing" msgstr "" pd-0.46-7/asio/0000775000175000017500000000000012160204055011322 5ustar mspmsppd-0.46-7/asio/README.txt0000664000175000017500000000066512160204055013027 0ustar mspmsp In order to build ASIO support into Pd on Windows, you need to download the ASIO sources from Steinberg directly. Their license does not let us redistribute their source files. - Download the ASIO SDK http://www.steinberg.net/en/company/3rd_party_developer.html You have to agree to Steinberg's license, then submit an email address, then they'll send you the download URL in an email. - Uncompress asiosdk2.2.zip into pd/asio pd-0.46-7/asio/Makefile.am0000664000175000017500000000170112160204055013355 0ustar mspmsp# The ASIO sources are not free, so they are not included here. You can get # them for free (as in beer) from Steinberg: # http://www.steinberg.net/en/company/3rd_party_developer.html # First, download the ASIO SDK. You have to agree to Steinberg's license, then # submit an email address, then they'll send you the download URL in an # email. Download the asiosdk2.2.zip file to the pd/asio directory, then unzip # it right into that folder. You should have all of the ASIO files in # pd/asio/ASIOSDK2 when you are done unzipping. # this is built as a "libtool convenience library" # http://sources.redhat.com/automake/automake.html#Libtool-Convenience-Libraries AUTOMAKE_OPTIONS = foreign AM_CFLAGS = INCLUDES = -I./ASIOSDK2/host -I./ASIOSDK2/host/pc -I./ASIOSDK2/common noinst_LTLIBRARIES = libasio.la nodist_libasio_la_SOURCES = \ ASIOSDK2/common/asio.cpp \ ASIOSDK2/host/asiodrivers.cpp \ ASIOSDK2/host/pc/asiolist.cpp EXTRA_DIST = README.txt pd-0.46-7/portmidi/0000775000175000017500000000000012524735416012234 5ustar mspmsppd-0.46-7/portmidi/pm_linux/0000775000175000017500000000000012374245151014062 5ustar mspmsppd-0.46-7/portmidi/pm_linux/pmlinux.c0000775000175000017500000000402012374245151015721 0ustar mspmsp/* pmlinux.c -- PortMidi os-dependent code */ /* This file only needs to implement pm_init(), which calls various routines to register the available midi devices. This file must be separate from the main portmidi.c file because it is system dependent, and it is separate from, pmlinuxalsa.c, because it might need to register non-alsa devices as well. NOTE: if you add non-ALSA support, you need to fix :alsa_poll() in pmlinuxalsa.c, which assumes all input devices are ALSA. */ #include "stdlib.h" #include "portmidi.h" #include "pmutil.h" #include "pminternal.h" #ifdef PMALSA #include "pmlinuxalsa.h" #endif #ifdef PMNULL #include "pmlinuxnull.h" #endif PmDeviceID pm_default_input_device_id = -1; PmDeviceID pm_default_output_device_id = -1; void pm_init() { /* Note: it is not an error for PMALSA to fail to initialize. * It may be a design error that the client cannot query what subsystems * are working properly other than by looking at the list of available * devices. */ #ifdef PMALSA pm_linuxalsa_init(); #endif #ifdef PMNULL pm_linuxnull_init(); #endif // this is set when we return to Pm_Initialize, but we need it // now in order to (successfully) call Pm_CountDevices() pm_initialized = TRUE; pm_default_input_device_id = find_default_device( "/PortMidi/PM_RECOMMENDED_INPUT_DEVICE", TRUE, pm_default_input_device_id); pm_default_output_device_id = find_default_device( "/PortMidi/PM_RECOMMENDED_OUTPUT_DEVICE", FALSE, pm_default_output_device_id); } void pm_term(void) { #ifdef PMALSA pm_linuxalsa_term(); #endif } PmDeviceID Pm_GetDefaultInputDeviceID() { Pm_Initialize(); return pm_default_input_device_id; } PmDeviceID Pm_GetDefaultOutputDeviceID() { Pm_Initialize(); return pm_default_output_device_id; } void *pm_alloc(size_t s) { return malloc(s); } void pm_free(void *ptr) { free(ptr); } pd-0.46-7/portmidi/pm_linux/pmlinuxalsa.h0000775000175000017500000000017312160204055016563 0ustar mspmsp/* pmlinuxalsa.h -- system-specific definitions */ PmError pm_linuxalsa_init(void); void pm_linuxalsa_term(void); pd-0.46-7/portmidi/pm_linux/README_LINUX.txt0000775000175000017500000000737612374245151016557 0ustar mspmspREADME_LINUX.txt for PortMidi Roger Dannenberg 14 Oct 2009 To make PortMidi, you need cmake and the Java SDK. Go back up to the portmidi directory and type: ccmake . Type 'c' (configure) and then 'g' (generate). You may have to manually set JAVA_INCLUDE_PATH and JAVA_JVM_LIBRARY by typing 't' (toggle to advanced mode) and using the editor to change the fields. You can find possible values for JAVA_INCLUDE_PATH by typing "locate jni.h", and for JAVA_JVM_LIBRARY by typing locate libjvm". You also need JAVA_INCLUDE_PATH2, but this will normally be set automatically after you set JAVA_INCLUDE_PATH and run "configure" (type "c" to ccmake). Normally, JAVA_INCLUDE_PATH2 is the linux subdirectory within JAVA_INCLUDE_PATH. Notice that the CMAKE_BUILD_TYPE can be Debug or Release. Stick with Release if you are not debugging. After successfully generating make files with ccmake, you can run make: make The Makefile will build all test programs and the portmidi library. For experimental software, especially programs running from the command line, we recommend using the Debug version -- it will terminate your program and print a helpful message if any PortMidi function returns an error code. (Released software should check for error codes and handle them, but for quick, non-critical projects, the automatic "print and die" handling can save some work.) THE pmdefaults PROGRAM You should install pmdefaults. It provides a graphical interface for selecting default MIDI IN and OUT devices so that you don't have to build device selection interfaces into all your programs and so users have a single place to set a preference. Follow the instructions above to run ccmake, making sure that CMAKE_BUILD_TYPE is Release. Run make as described above. Then: sudo make install This will install PortMidi libraries and the pmdefault program. You must alos have the environment variable LD_LIBRARY_PATH set to include /usr/local/lib (where libpmjni.so is installed). Now, you can run pmdefault. SETTING LD_LIBRARY_PATH pmdefaults will not work unless LD_LIBRARY_PATH includes a directory (normally /usr/local/lib) containing libpmjni.so, installed as described above. To set LD_LIBRARY_PATH, you might want to add this to your ~/.profile (if you use the bash shell): LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib export LD_LIBRARY_PATH A NOTE ABOUT AMD64: When compiling portmidi under linux on an AMD64, I had to add the -fPIC flag to the gcc flags. Reason: when trying to build John Harrison's pyPortMidi gcc bailed out with this error: ./linux/libportmidi.a(pmlinux.o): relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC ./linux/libportmidi.a: could not read symbols: Bad value collect2: ld returned 1 exit status error: command 'gcc' failed with exit status 1 What they said: http://www.gentoo.org/proj/en/base/amd64/howtos/index.xml?part=1&chap=3 On certain architectures (AMD64 amongst them), shared libraries *must* be "PIC-enabled". CHANGELOG 22-jan-2010 Roger B. Dannenberg Updated instructions about Java paths 14-oct-2009 Roger B. Dannenberg Using CMake now for building and configuration 29-aug-2006 Roger B. Dannenberg Fixed PortTime to join with time thread for clean exit. 28-aug-2006 Roger B. Dannenberg Updated this documentation. 08-Jun-2004 Roger B. Dannenberg Updated code to use new system abstraction. 12-Apr-2003 Roger B. Dannenberg Fixed pm_test/test.c to filter clocks and active messages. Integrated changes from Clemens Ladisch: cleaned up pmlinuxalsa.c record timestamp on sysex input deallocate some resources previously left open pd-0.46-7/portmidi/pm_linux/finddefault.c0000664000175000017500000000567712374245151016532 0ustar mspmsp/* finddefault.c -- find_default_device() implementation Roger Dannenberg, Jan 2009 */ #include #include #include #include "portmidi.h" #define STRING_MAX 256 /* skip over spaces, return first non-space */ void skip_spaces(FILE *inf) { char c; while (isspace(c = getc(inf))) ; ungetc(c, inf); } /* trim leading spaces and match a string */ int match_string(FILE *inf, char *s) { skip_spaces(inf); while (*s && *s == getc(inf)) s++; return (*s == 0); } /* /* Parse preference files, find default device, search devices -- */ PmDeviceID find_default_device(char *path, int input, PmDeviceID id) /* path -- the name of the preference we are searching for input -- true iff this is an input device id -- current default device id returns matching device id if found, otherwise id */ { static char *pref_2 = "/.java/.userPrefs/"; static char *pref_3 = "prefs.xml"; char *pref_1 = getenv("HOME"); char *full_name, *path_ptr; FILE *inf; int c, i; if (!pref_1) goto nopref; // cannot find preference file // full_name will be larger than necessary full_name = malloc(strlen(pref_1) + strlen(pref_2) + strlen(pref_3) + strlen(path) + 2); strcpy(full_name, pref_1); strcat(full_name, pref_2); // copy all but last path segment to full_name if (*path == '/') path++; // skip initial slash in path path_ptr = strrchr(path, '/'); if (path_ptr) { // copy up to slash after full_name path_ptr++; int offset = strlen(full_name); memcpy(full_name + offset, path, path_ptr - path); full_name[offset + path_ptr - path] = 0; // end of string } else { path_ptr = path; } strcat(full_name, pref_3); inf = fopen(full_name, "r"); if (!inf) goto nopref; // cannot open preference file // We're not going to build or link in a full XML parser. // Instead, find the path string and quoute. Then, look for // "value", "=", quote. Then get string up to quote. while ((c = getc(inf)) != EOF) { char pref_str[STRING_MAX]; if (c != '"') continue; // scan up to quote // look for quote string quote if (!match_string(inf, path_ptr)) continue; // path not found if (getc(inf) != '"') continue; // path not found, keep scanning if (!match_string(inf, "value")) goto nopref; // value not found if (!match_string(inf, "=")) goto nopref; // = not found if (!match_string(inf, "\"")) goto nopref; // quote not found // now read the value up to the close quote for (i = 0; i < STRING_MAX; i++) { if ((c = getc(inf)) == '"') break; pref_str[i] = c; } if (i == STRING_MAX) continue; // value too long, ignore pref_str[i] == 0; i = pm_find_default_device(pref_str, input); if (i != pmNoDevice) { id = i; } break; } nopref: return id; } pd-0.46-7/portmidi/pm_linux/pmlinux.h0000775000175000017500000000016412160204055015722 0ustar mspmsp/* pmlinux.h */ extern PmDeviceID pm_default_input_device_id; extern PmDeviceID pm_default_output_device_id; pd-0.46-7/portmidi/pm_linux/pmlinuxalsa.c0000775000175000017500000006725312374245151016603 0ustar mspmsp/* * pmlinuxalsa.c -- system specific definitions * * written by: * Roger Dannenberg (port to Alsa 0.9.x) * Clemens Ladisch (provided code examples and invaluable consulting) * Jason Cohen, Rico Colon, Matt Filippone (Alsa 0.5.x implementation) */ #include "stdlib.h" #include "portmidi.h" #include "pmutil.h" #include "pminternal.h" #include "pmlinuxalsa.h" #include "string.h" #include "porttime.h" #include "pmlinux.h" #include /* I used many print statements to debug this code. I left them in the * source, and you can turn them on by changing false to true below: */ #define VERBOSE_ON 0 #define VERBOSE if (VERBOSE_ON) #define MIDI_SYSEX 0xf0 #define MIDI_EOX 0xf7 #if SND_LIB_MAJOR == 0 && SND_LIB_MINOR < 9 #error needs ALSA 0.9.0 or later #endif /* to store client/port in the device descriptor */ #define MAKE_DESCRIPTOR(client, port) ((void*)(((client) << 8) | (port))) #define GET_DESCRIPTOR_CLIENT(info) ((((int)(info)) >> 8) & 0xff) #define GET_DESCRIPTOR_PORT(info) (((int)(info)) & 0xff) #define BYTE unsigned char extern pm_fns_node pm_linuxalsa_in_dictionary; extern pm_fns_node pm_linuxalsa_out_dictionary; static snd_seq_t *seq = NULL; // all input comes here, // output queue allocated on seq static int queue, queue_used; /* one for all ports, reference counted */ typedef struct alsa_descriptor_struct { int client; int port; int this_port; int in_sysex; snd_midi_event_t *parser; int error; /* host error code */ } alsa_descriptor_node, *alsa_descriptor_type; /* get_alsa_error_text -- copy error text to potentially short string */ /**/ static void get_alsa_error_text(char *msg, int len, int err) { int errlen = strlen(snd_strerror(err)); if (errlen < len) { strcpy(msg, snd_strerror(err)); } else if (len > 20) { sprintf(msg, "Alsa error %d", err); } else if (len > 4) { strcpy(msg, "Alsa"); } else { msg[0] = 0; } } /* queue is shared by both input and output, reference counted */ static PmError alsa_use_queue(void) { if (queue_used == 0) { snd_seq_queue_tempo_t *tempo; queue = snd_seq_alloc_queue(seq); if (queue < 0) { pm_hosterror = queue; return pmHostError; } snd_seq_queue_tempo_alloca(&tempo); snd_seq_queue_tempo_set_tempo(tempo, 480000); snd_seq_queue_tempo_set_ppq(tempo, 480); pm_hosterror = snd_seq_set_queue_tempo(seq, queue, tempo); if (pm_hosterror < 0) return pmHostError; snd_seq_start_queue(seq, queue, NULL); snd_seq_drain_output(seq); } ++queue_used; return pmNoError; } static void alsa_unuse_queue(void) { if (--queue_used == 0) { snd_seq_stop_queue(seq, queue, NULL); snd_seq_drain_output(seq); snd_seq_free_queue(seq, queue); VERBOSE printf("queue freed\n"); } } /* midi_message_length -- how many bytes in a message? */ static int midi_message_length(PmMessage message) { message &= 0xff; if (message < 0x80) { return 0; } else if (message < 0xf0) { static const int length[] = {3, 3, 3, 3, 2, 2, 3}; return length[(message - 0x80) >> 4]; } else { static const int length[] = { -1, 2, 3, 2, 0, 0, 1, -1, 1, 0, 1, 1, 1, 0, 1, 1}; return length[message - 0xf0]; } } static PmError alsa_out_open(PmInternal *midi, void *driverInfo) { void *client_port = descriptors[midi->device_id].descriptor; alsa_descriptor_type desc = (alsa_descriptor_type) pm_alloc(sizeof(alsa_descriptor_node)); snd_seq_port_info_t *info; int err; if (!desc) return pmInsufficientMemory; snd_seq_port_info_alloca(&info); snd_seq_port_info_set_port(info, midi->device_id); snd_seq_port_info_set_capability(info, SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_READ); snd_seq_port_info_set_type(info, SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION); snd_seq_port_info_set_port_specified(info, 1); err = snd_seq_create_port(seq, info); if (err < 0) goto free_desc; /* fill in fields of desc, which is passed to pm_write routines */ midi->descriptor = desc; desc->client = GET_DESCRIPTOR_CLIENT(client_port); desc->port = GET_DESCRIPTOR_PORT(client_port); desc->this_port = midi->device_id; desc->in_sysex = 0; desc->error = 0; err = snd_midi_event_new(PM_DEFAULT_SYSEX_BUFFER_SIZE, &desc->parser); if (err < 0) goto free_this_port; if (midi->latency > 0) { /* must delay output using a queue */ err = alsa_use_queue(); if (err < 0) goto free_parser; err = snd_seq_connect_to(seq, desc->this_port, desc->client, desc->port); if (err < 0) goto unuse_queue; /* clean up and return on error */ } else { err = snd_seq_connect_to(seq, desc->this_port, desc->client, desc->port); if (err < 0) goto free_parser; /* clean up and return on error */ } return pmNoError; unuse_queue: alsa_unuse_queue(); free_parser: snd_midi_event_free(desc->parser); free_this_port: snd_seq_delete_port(seq, desc->this_port); free_desc: pm_free(desc); pm_hosterror = err; if (err < 0) { get_alsa_error_text(pm_hosterror_text, PM_HOST_ERROR_MSG_LEN, err); } return pmHostError; } static PmError alsa_write_byte(PmInternal *midi, unsigned char byte, PmTimestamp timestamp) { alsa_descriptor_type desc = (alsa_descriptor_type) midi->descriptor; snd_seq_event_t ev; int err; snd_seq_ev_clear(&ev); if (snd_midi_event_encode_byte(desc->parser, byte, &ev) == 1) { snd_seq_ev_set_dest(&ev, desc->client, desc->port); snd_seq_ev_set_source(&ev, desc->this_port); if (midi->latency > 0) { /* compute relative time of event = timestamp - now + latency */ PmTimestamp now = (midi->time_proc ? midi->time_proc(midi->time_info) : Pt_Time(NULL)); int when = timestamp; /* if timestamp is zero, send immediately */ /* otherwise compute time delay and use delay if positive */ if (when == 0) when = now; when = (when - now) + midi->latency; if (when < 0) when = 0; VERBOSE printf("timestamp %d now %d latency %d, ", (int) timestamp, (int) now, midi->latency); VERBOSE printf("scheduling event after %d\n", when); /* message is sent in relative ticks, where 1 tick = 1 ms */ snd_seq_ev_schedule_tick(&ev, queue, 1, when); /* NOTE: for cases where the user does not supply a time function, we could optimize the code by not starting Pt_Time and using the alsa tick time instead. I didn't do this because it would entail changing the queue management to start the queue tick count when PortMidi is initialized and keep it running until PortMidi is terminated. (This should be simple, but it's not how the code works now.) -RBD */ } else { /* send event out without queueing */ VERBOSE printf("direct\n"); /* ev.queue = SND_SEQ_QUEUE_DIRECT; ev.dest.client = SND_SEQ_ADDRESS_SUBSCRIBERS; */ snd_seq_ev_set_direct(&ev); } VERBOSE printf("sending event\n"); err = snd_seq_event_output(seq, &ev); if (err < 0) { desc->error = err; return pmHostError; } } return pmNoError; } static PmError alsa_out_close(PmInternal *midi) { alsa_descriptor_type desc = (alsa_descriptor_type) midi->descriptor; if (!desc) return pmBadPtr; if (pm_hosterror = snd_seq_disconnect_to(seq, desc->this_port, desc->client, desc->port)) { // if there's an error, try to delete the port anyway, but don't // change the pm_hosterror value so we retain the first error snd_seq_delete_port(seq, desc->this_port); } else { // if there's no error, delete the port and retain any error pm_hosterror = snd_seq_delete_port(seq, desc->this_port); } if (midi->latency > 0) alsa_unuse_queue(); snd_midi_event_free(desc->parser); midi->descriptor = NULL; /* destroy the pointer to signify "closed" */ pm_free(desc); if (pm_hosterror) { get_alsa_error_text(pm_hosterror_text, PM_HOST_ERROR_MSG_LEN, pm_hosterror); return pmHostError; } return pmNoError; } static PmError alsa_in_open(PmInternal *midi, void *driverInfo) { void *client_port = descriptors[midi->device_id].descriptor; alsa_descriptor_type desc = (alsa_descriptor_type) pm_alloc(sizeof(alsa_descriptor_node)); snd_seq_port_info_t *info; snd_seq_port_subscribe_t *sub; snd_seq_addr_t addr; int err; if (!desc) return pmInsufficientMemory; err = alsa_use_queue(); if (err < 0) goto free_desc; snd_seq_port_info_alloca(&info); snd_seq_port_info_set_port(info, midi->device_id); snd_seq_port_info_set_capability(info, SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_READ); snd_seq_port_info_set_type(info, SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION); snd_seq_port_info_set_port_specified(info, 1); err = snd_seq_create_port(seq, info); if (err < 0) goto free_queue; /* fill in fields of desc, which is passed to pm_write routines */ midi->descriptor = desc; desc->client = GET_DESCRIPTOR_CLIENT(client_port); desc->port = GET_DESCRIPTOR_PORT(client_port); desc->this_port = midi->device_id; desc->in_sysex = 0; desc->error = 0; VERBOSE printf("snd_seq_connect_from: %d %d %d\n", desc->this_port, desc->client, desc->port); snd_seq_port_subscribe_alloca(&sub); addr.client = snd_seq_client_id(seq); addr.port = desc->this_port; snd_seq_port_subscribe_set_dest(sub, &addr); addr.client = desc->client; addr.port = desc->port; snd_seq_port_subscribe_set_sender(sub, &addr); snd_seq_port_subscribe_set_time_update(sub, 1); /* this doesn't seem to work: messages come in with real timestamps */ snd_seq_port_subscribe_set_time_real(sub, 0); err = snd_seq_subscribe_port(seq, sub); /* err = snd_seq_connect_from(seq, desc->this_port, desc->client, desc->port); */ if (err < 0) goto free_this_port; /* clean up and return on error */ return pmNoError; free_this_port: snd_seq_delete_port(seq, desc->this_port); free_queue: alsa_unuse_queue(); free_desc: pm_free(desc); pm_hosterror = err; if (err < 0) { get_alsa_error_text(pm_hosterror_text, PM_HOST_ERROR_MSG_LEN, err); } return pmHostError; } static PmError alsa_in_close(PmInternal *midi) { alsa_descriptor_type desc = (alsa_descriptor_type) midi->descriptor; if (!desc) return pmBadPtr; if (pm_hosterror = snd_seq_disconnect_from(seq, desc->this_port, desc->client, desc->port)) { snd_seq_delete_port(seq, desc->this_port); /* try to close port */ } else { pm_hosterror = snd_seq_delete_port(seq, desc->this_port); } alsa_unuse_queue(); pm_free(desc); if (pm_hosterror) { get_alsa_error_text(pm_hosterror_text, PM_HOST_ERROR_MSG_LEN, pm_hosterror); return pmHostError; } return pmNoError; } static PmError alsa_abort(PmInternal *midi) { /* NOTE: ALSA documentation is vague. This is supposed to * remove any pending output messages. If you can test and * confirm this code is correct, please update this comment. -RBD */ /* Unfortunately, I can't even compile it -- my ALSA version * does not implement snd_seq_remove_events_t, so this does * not compile. I'll try again, but it looks like I'll need to * upgrade my entire Linux OS -RBD */ /* alsa_descriptor_type desc = (alsa_descriptor_type) midi->descriptor; snd_seq_remove_events_t info; snd_seq_addr_t addr; addr.client = desc->client; addr.port = desc->port; snd_seq_remove_events_set_dest(&info, &addr); snd_seq_remove_events_set_condition(&info, SND_SEQ_REMOVE_DEST); pm_hosterror = snd_seq_remove_events(seq, &info); if (pm_hosterror) { get_alsa_error_text(pm_hosterror_text, PM_HOST_ERROR_MSG_LEN, pm_hosterror); return pmHostError; } */ printf("WARNING: alsa_abort not implemented\n"); return pmNoError; } #ifdef GARBAGE This is old code here temporarily for reference static PmError alsa_write(PmInternal *midi, PmEvent *buffer, int32_t length) { alsa_descriptor_type desc = (alsa_descriptor_type) midi->descriptor; int i, bytes; unsigned char byte; PmMessage msg; desc->error = 0; for (; length > 0; length--, buffer++) { VERBOSE printf("message 0x%x\n", buffer->message); if (Pm_MessageStatus(buffer->message) == MIDI_SYSEX) desc->in_sysex = TRUE; if (desc->in_sysex) { msg = buffer->message; for (i = 0; i < 4; i++) { byte = msg; /* extract next byte to send */ alsa_write_byte(midi, byte, buffer->timestamp); if (byte == MIDI_EOX) { desc->in_sysex = FALSE; break; } if (desc->error < 0) break; msg >>= 8; /* shift next byte into position */ } } else { bytes = midi_message_length(buffer->message); msg = buffer->message; for (i = 0; i < bytes; i++) { byte = msg; /* extract next byte to send */ VERBOSE printf("sending 0x%x\n", byte); alsa_write_byte(midi, byte, buffer->timestamp); if (desc->error < 0) break; msg >>= 8; /* shift next byte into position */ } } } if (desc->error < 0) return pmHostError; VERBOSE printf("snd_seq_drain_output: 0x%x\n", (unsigned int) seq); desc->error = snd_seq_drain_output(seq); if (desc->error < 0) return pmHostError; desc->error = pmNoError; return pmNoError; } #endif static PmError alsa_write_flush(PmInternal *midi, PmTimestamp timestamp) { alsa_descriptor_type desc = (alsa_descriptor_type) midi->descriptor; VERBOSE printf("snd_seq_drain_output: 0x%x\n", (unsigned int) seq); desc->error = snd_seq_drain_output(seq); if (desc->error < 0) return pmHostError; desc->error = pmNoError; return pmNoError; } static PmError alsa_write_short(PmInternal *midi, PmEvent *event) { int bytes = midi_message_length(event->message); PmMessage msg = event->message; int i; alsa_descriptor_type desc = (alsa_descriptor_type) midi->descriptor; for (i = 0; i < bytes; i++) { unsigned char byte = msg; VERBOSE printf("sending 0x%x\n", byte); alsa_write_byte(midi, byte, event->timestamp); if (desc->error < 0) break; msg >>= 8; /* shift next byte into position */ } if (desc->error < 0) return pmHostError; desc->error = pmNoError; return pmNoError; } /* alsa_sysex -- implements begin_sysex and end_sysex */ PmError alsa_sysex(PmInternal *midi, PmTimestamp timestamp) { return pmNoError; } static PmTimestamp alsa_synchronize(PmInternal *midi) { return 0; /* linux implementation does not use this synchronize function */ /* Apparently, Alsa data is relative to the time you send it, and there is no reference. If this is true, this is a serious shortcoming of Alsa. If not true, then PortMidi has a serious shortcoming -- it should be scheduling relative to Alsa's time reference. */ } static void handle_event(snd_seq_event_t *ev) { int device_id = ev->dest.port; PmInternal *midi = descriptors[device_id].internalDescriptor; PmEvent pm_ev; PmTimeProcPtr time_proc = midi->time_proc; PmTimestamp timestamp; /* time stamp should be in ticks, using our queue where 1 tick = 1ms */ assert((ev->flags & SND_SEQ_TIME_STAMP_MASK) == SND_SEQ_TIME_STAMP_TICK); /* if no time_proc, just return "native" ticks (ms) */ if (time_proc == NULL) { timestamp = ev->time.tick; } else { /* translate time to time_proc basis */ snd_seq_queue_status_t *queue_status; snd_seq_queue_status_alloca(&queue_status); snd_seq_get_queue_status(seq, queue, queue_status); /* return (now - alsa_now) + alsa_timestamp */ timestamp = (*time_proc)(midi->time_info) + ev->time.tick - snd_seq_queue_status_get_tick_time(queue_status); } pm_ev.timestamp = timestamp; switch (ev->type) { case SND_SEQ_EVENT_NOTEON: pm_ev.message = Pm_Message(0x90 | ev->data.note.channel, ev->data.note.note & 0x7f, ev->data.note.velocity & 0x7f); pm_read_short(midi, &pm_ev); break; case SND_SEQ_EVENT_NOTEOFF: pm_ev.message = Pm_Message(0x80 | ev->data.note.channel, ev->data.note.note & 0x7f, ev->data.note.velocity & 0x7f); pm_read_short(midi, &pm_ev); break; case SND_SEQ_EVENT_KEYPRESS: pm_ev.message = Pm_Message(0xa0 | ev->data.note.channel, ev->data.note.note & 0x7f, ev->data.note.velocity & 0x7f); pm_read_short(midi, &pm_ev); break; case SND_SEQ_EVENT_CONTROLLER: pm_ev.message = Pm_Message(0xb0 | ev->data.note.channel, ev->data.control.param & 0x7f, ev->data.control.value & 0x7f); pm_read_short(midi, &pm_ev); break; case SND_SEQ_EVENT_PGMCHANGE: pm_ev.message = Pm_Message(0xc0 | ev->data.note.channel, ev->data.control.value & 0x7f, 0); pm_read_short(midi, &pm_ev); break; case SND_SEQ_EVENT_CHANPRESS: pm_ev.message = Pm_Message(0xd0 | ev->data.note.channel, ev->data.control.value & 0x7f, 0); pm_read_short(midi, &pm_ev); break; case SND_SEQ_EVENT_PITCHBEND: pm_ev.message = Pm_Message(0xe0 | ev->data.note.channel, (ev->data.control.value + 0x2000) & 0x7f, ((ev->data.control.value + 0x2000) >> 7) & 0x7f); pm_read_short(midi, &pm_ev); break; case SND_SEQ_EVENT_CONTROL14: if (ev->data.control.param < 0x20) { pm_ev.message = Pm_Message(0xb0 | ev->data.note.channel, ev->data.control.param, (ev->data.control.value >> 7) & 0x7f); pm_read_short(midi, &pm_ev); pm_ev.message = Pm_Message(0xb0 | ev->data.note.channel, ev->data.control.param + 0x20, ev->data.control.value & 0x7f); pm_read_short(midi, &pm_ev); } else { pm_ev.message = Pm_Message(0xb0 | ev->data.note.channel, ev->data.control.param & 0x7f, ev->data.control.value & 0x7f); pm_read_short(midi, &pm_ev); } break; case SND_SEQ_EVENT_SONGPOS: pm_ev.message = Pm_Message(0xf2, ev->data.control.value & 0x7f, (ev->data.control.value >> 7) & 0x7f); pm_read_short(midi, &pm_ev); break; case SND_SEQ_EVENT_SONGSEL: pm_ev.message = Pm_Message(0xf3, ev->data.control.value & 0x7f, 0); pm_read_short(midi, &pm_ev); break; case SND_SEQ_EVENT_QFRAME: pm_ev.message = Pm_Message(0xf1, ev->data.control.value & 0x7f, 0); pm_read_short(midi, &pm_ev); break; case SND_SEQ_EVENT_START: pm_ev.message = Pm_Message(0xfa, 0, 0); pm_read_short(midi, &pm_ev); break; case SND_SEQ_EVENT_CONTINUE: pm_ev.message = Pm_Message(0xfb, 0, 0); pm_read_short(midi, &pm_ev); break; case SND_SEQ_EVENT_STOP: pm_ev.message = Pm_Message(0xfc, 0, 0); pm_read_short(midi, &pm_ev); break; case SND_SEQ_EVENT_CLOCK: pm_ev.message = Pm_Message(0xf8, 0, 0); pm_read_short(midi, &pm_ev); break; case SND_SEQ_EVENT_TUNE_REQUEST: pm_ev.message = Pm_Message(0xf6, 0, 0); pm_read_short(midi, &pm_ev); break; case SND_SEQ_EVENT_RESET: pm_ev.message = Pm_Message(0xff, 0, 0); pm_read_short(midi, &pm_ev); break; case SND_SEQ_EVENT_SENSING: pm_ev.message = Pm_Message(0xfe, 0, 0); pm_read_short(midi, &pm_ev); break; case SND_SEQ_EVENT_SYSEX: { const BYTE *ptr = (const BYTE *) ev->data.ext.ptr; /* assume there is one sysex byte to process */ pm_read_bytes(midi, ptr, ev->data.ext.len, timestamp); break; } } } static PmError alsa_poll(PmInternal *midi) { snd_seq_event_t *ev; /* expensive check for input data, gets data from device: */ while (snd_seq_event_input_pending(seq, TRUE) > 0) { /* cheap check on local input buffer */ while (snd_seq_event_input_pending(seq, FALSE) > 0) { /* check for and ignore errors, e.g. input overflow */ /* note: if there's overflow, this should be reported * all the way through to client. Since input from all * devices is merged, we need to find all input devices * and set all to the overflow state. * NOTE: this assumes every input is ALSA based. */ int rslt = snd_seq_event_input(seq, &ev); if (rslt >= 0) { handle_event(ev); } else if (rslt == -ENOSPC) { int i; for (i = 0; i < pm_descriptor_index; i++) { if (descriptors[i].pub.input) { PmInternal *midi = (PmInternal *) descriptors[i].internalDescriptor; /* careful, device may not be open! */ if (midi) Pm_SetOverflow(midi->queue); } } } } } return pmNoError; } static unsigned int alsa_has_host_error(PmInternal *midi) { alsa_descriptor_type desc = (alsa_descriptor_type) midi->descriptor; return desc->error; } static void alsa_get_host_error(PmInternal *midi, char *msg, unsigned int len) { alsa_descriptor_type desc = (alsa_descriptor_type) midi->descriptor; int err = (pm_hosterror || desc->error); get_alsa_error_text(msg, len, err); } pm_fns_node pm_linuxalsa_in_dictionary = { none_write_short, none_sysex, none_sysex, none_write_byte, none_write_short, none_write_flush, alsa_synchronize, alsa_in_open, alsa_abort, alsa_in_close, alsa_poll, alsa_has_host_error, alsa_get_host_error }; pm_fns_node pm_linuxalsa_out_dictionary = { alsa_write_short, alsa_sysex, alsa_sysex, alsa_write_byte, alsa_write_short, /* short realtime message */ alsa_write_flush, alsa_synchronize, alsa_out_open, alsa_abort, alsa_out_close, none_poll, alsa_has_host_error, alsa_get_host_error }; /* pm_strdup -- copy a string to the heap. Use this rather than strdup so * that we call pm_alloc, not malloc. This allows portmidi to avoid * malloc which might cause priority inversion. Probably ALSA is going * to call malloc anyway, so this extra work here may be pointless. */ char *pm_strdup(const char *s) { int len = strlen(s); char *dup = (char *) pm_alloc(len + 1); strcpy(dup, s); return dup; } PmError pm_linuxalsa_init( void ) { int err; snd_seq_client_info_t *cinfo; snd_seq_port_info_t *pinfo; unsigned int caps; /* Previously, the last parameter was SND_SEQ_NONBLOCK, but this * would cause messages to be dropped if the ALSA buffer fills up. * The correct behavior is for writes to block until there is * room to send all the data. The client should normally allocate * a large enough buffer to avoid blocking on output. * Now that blocking is enabled, the seq_event_input() will block * if there is no input data. This is not what we want, so must * call seq_event_input_pending() to avoid blocking. */ err = snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, 0); if (err < 0) return err; snd_seq_client_info_alloca(&cinfo); snd_seq_port_info_alloca(&pinfo); snd_seq_client_info_set_client(cinfo, -1); while (snd_seq_query_next_client(seq, cinfo) == 0) { snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo)); snd_seq_port_info_set_port(pinfo, -1); while (snd_seq_query_next_port(seq, pinfo) == 0) { if (snd_seq_port_info_get_client(pinfo) == SND_SEQ_CLIENT_SYSTEM) continue; /* ignore Timer and Announce ports on client 0 */ caps = snd_seq_port_info_get_capability(pinfo); if (!(caps & (SND_SEQ_PORT_CAP_SUBS_READ | SND_SEQ_PORT_CAP_SUBS_WRITE))) continue; /* ignore if you cannot read or write port */ if (caps & SND_SEQ_PORT_CAP_SUBS_WRITE) { if (pm_default_output_device_id == -1) pm_default_output_device_id = pm_descriptor_index; pm_add_device("ALSA", pm_strdup(snd_seq_port_info_get_name(pinfo)), FALSE, MAKE_DESCRIPTOR(snd_seq_port_info_get_client(pinfo), snd_seq_port_info_get_port(pinfo)), &pm_linuxalsa_out_dictionary); } if (caps & SND_SEQ_PORT_CAP_SUBS_READ) { if (pm_default_input_device_id == -1) pm_default_input_device_id = pm_descriptor_index; pm_add_device("ALSA", pm_strdup(snd_seq_port_info_get_name(pinfo)), TRUE, MAKE_DESCRIPTOR(snd_seq_port_info_get_client(pinfo), snd_seq_port_info_get_port(pinfo)), &pm_linuxalsa_in_dictionary); } } } return pmNoError; } void pm_linuxalsa_term(void) { if (seq) { snd_seq_close(seq); pm_free(descriptors); descriptors = NULL; pm_descriptor_index = 0; pm_descriptor_max = 0; } } pd-0.46-7/portmidi/porttime/0000775000175000017500000000000012374245151014072 5ustar mspmsppd-0.46-7/portmidi/porttime/ptmacosx_cf.c0000775000175000017500000000734112374245151016554 0ustar mspmsp/* ptmacosx.c -- portable timer implementation for mac os x */ #include #include #include #include #import #import #import #import #include "porttime.h" #define THREAD_IMPORTANCE 30 #define LONG_TIME 1000000000.0 static int time_started_flag = FALSE; static CFAbsoluteTime startTime = 0.0; static CFRunLoopRef timerRunLoop; typedef struct { int resolution; PtCallback *callback; void *userData; } PtThreadParams; void Pt_CFTimerCallback(CFRunLoopTimerRef timer, void *info) { PtThreadParams *params = (PtThreadParams*)info; (*params->callback)(Pt_Time(), params->userData); } static void* Pt_Thread(void *p) { CFTimeInterval timerInterval; CFRunLoopTimerContext timerContext; CFRunLoopTimerRef timer; PtThreadParams *params = (PtThreadParams*)p; //CFTimeInterval timeout; /* raise the thread's priority */ kern_return_t error; thread_extended_policy_data_t extendedPolicy; thread_precedence_policy_data_t precedencePolicy; extendedPolicy.timeshare = 0; error = thread_policy_set(mach_thread_self(), THREAD_EXTENDED_POLICY, (thread_policy_t)&extendedPolicy, THREAD_EXTENDED_POLICY_COUNT); if (error != KERN_SUCCESS) { mach_error("Couldn't set thread timeshare policy", error); } precedencePolicy.importance = THREAD_IMPORTANCE; error = thread_policy_set(mach_thread_self(), THREAD_PRECEDENCE_POLICY, (thread_policy_t)&precedencePolicy, THREAD_PRECEDENCE_POLICY_COUNT); if (error != KERN_SUCCESS) { mach_error("Couldn't set thread precedence policy", error); } /* set up the timer context */ timerContext.version = 0; timerContext.info = params; timerContext.retain = NULL; timerContext.release = NULL; timerContext.copyDescription = NULL; /* create a new timer */ timerInterval = (double)params->resolution / 1000.0; timer = CFRunLoopTimerCreate(NULL, startTime+timerInterval, timerInterval, 0, 0, Pt_CFTimerCallback, &timerContext); timerRunLoop = CFRunLoopGetCurrent(); CFRunLoopAddTimer(timerRunLoop, timer, CFSTR("PtTimeMode")); /* run until we're told to stop by Pt_Stop() */ CFRunLoopRunInMode(CFSTR("PtTimeMode"), LONG_TIME, false); CFRunLoopRemoveTimer(CFRunLoopGetCurrent(), timer, CFSTR("PtTimeMode")); CFRelease(timer); free(params); return NULL; } PtError Pt_Start(int resolution, PtCallback *callback, void *userData) { PtThreadParams *params = (PtThreadParams*)malloc(sizeof(PtThreadParams)); pthread_t pthread_id; printf("Pt_Start() called\n"); // /* make sure we're not already playing */ if (time_started_flag) return ptAlreadyStarted; startTime = CFAbsoluteTimeGetCurrent(); if (callback) { params->resolution = resolution; params->callback = callback; params->userData = userData; pthread_create(&pthread_id, NULL, Pt_Thread, params); } time_started_flag = TRUE; return ptNoError; } PtError Pt_Stop() { printf("Pt_Stop called\n"); CFRunLoopStop(timerRunLoop); time_started_flag = FALSE; return ptNoError; } int Pt_Started() { return time_started_flag; } PtTimestamp Pt_Time() { CFAbsoluteTime now = CFAbsoluteTimeGetCurrent(); return (PtTimestamp) ((now - startTime) * 1000.0); } void Pt_Sleep(int32_t duration) { usleep(duration * 1000); } pd-0.46-7/portmidi/porttime/ptwinmm.c0000775000175000017500000000310312374245151015731 0ustar mspmsp/* ptwinmm.c -- portable timer implementation for win32 */ #include "porttime.h" #include "windows.h" #include "time.h" TIMECAPS caps; static long time_offset = 0; static int time_started_flag = FALSE; static long time_resolution; static MMRESULT timer_id; static PtCallback *time_callback; void CALLBACK winmm_time_callback(UINT uID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) { (*time_callback)(Pt_Time(), (void *) dwUser); } PMEXPORT PtError Pt_Start(int resolution, PtCallback *callback, void *userData) { if (time_started_flag) return ptAlreadyStarted; timeBeginPeriod(resolution); time_resolution = resolution; time_offset = timeGetTime(); time_started_flag = TRUE; time_callback = callback; if (callback) { timer_id = timeSetEvent(resolution, 1, winmm_time_callback, (DWORD_PTR) userData, TIME_PERIODIC | TIME_CALLBACK_FUNCTION); if (!timer_id) return ptHostError; } return ptNoError; } PMEXPORT PtError Pt_Stop() { if (!time_started_flag) return ptAlreadyStopped; if (time_callback && timer_id) { timeKillEvent(timer_id); time_callback = NULL; timer_id = 0; } time_started_flag = FALSE; timeEndPeriod(time_resolution); return ptNoError; } PMEXPORT int Pt_Started() { return time_started_flag; } PMEXPORT PtTimestamp Pt_Time() { return timeGetTime() - time_offset; } PMEXPORT void Pt_Sleep(int32_t duration) { Sleep(duration); } pd-0.46-7/portmidi/porttime/ptlinux.c0000775000175000017500000001004712374245151015746 0ustar mspmsp/* ptlinux.c -- portable timer implementation for linux */ /* IMPLEMENTATION NOTES (by Mark Nelson): Unlike Windows, Linux has no system call to request a periodic callback, so if Pt_Start() receives a callback parameter, it must create a thread that wakes up periodically and calls the provided callback function. If running as superuser, use setpriority() to renice thread to -20. One could also set the timer thread to a real-time priority (SCHED_FIFO and SCHED_RR), but this is dangerous for This is necessary because if the callback hangs it'll never return. A more serious reason is that the current scheduler implementation busy-waits instead of sleeping when realtime threads request a sleep of <=2ms (as a way to get around the 10ms granularity), which means the thread would never let anyone else on the CPU. CHANGE LOG 18-Jul-03 Roger Dannenberg -- Simplified code to set priority of timer thread. Simplified implementation notes. */ /* stdlib, stdio, unistd, and sys/types were added because they appeared * in a Gentoo patch, but I'm not sure why they are needed. -RBD */ #include #include #include #include #include "porttime.h" #include "sys/time.h" #include "sys/resource.h" #include "sys/timeb.h" #include "pthread.h" #define TRUE 1 #define FALSE 0 static int time_started_flag = FALSE; static struct timeb time_offset = {0, 0, 0, 0}; static pthread_t pt_thread_pid; static int pt_thread_created = FALSE; /* note that this is static data -- we only need one copy */ typedef struct { int id; int resolution; PtCallback *callback; void *userData; } pt_callback_parameters; static int pt_callback_proc_id = 0; static void *Pt_CallbackProc(void *p) { pt_callback_parameters *parameters = (pt_callback_parameters *) p; int mytime = 1; /* to kill a process, just increment the pt_callback_proc_id */ /* printf("pt_callback_proc_id %d, id %d\n", pt_callback_proc_id, parameters->id); */ if (geteuid() == 0) setpriority(PRIO_PROCESS, 0, -20); while (pt_callback_proc_id == parameters->id) { /* wait for a multiple of resolution ms */ struct timeval timeout; int delay = mytime++ * parameters->resolution - Pt_Time(); if (delay < 0) delay = 0; timeout.tv_sec = 0; timeout.tv_usec = delay * 1000; select(0, NULL, NULL, NULL, &timeout); (*(parameters->callback))(Pt_Time(), parameters->userData); } /* printf("Pt_CallbackProc exiting\n"); */ // free(parameters); return NULL; } PtError Pt_Start(int resolution, PtCallback *callback, void *userData) { if (time_started_flag) return ptNoError; ftime(&time_offset); /* need this set before process runs */ if (callback) { int res; pt_callback_parameters *parms = (pt_callback_parameters *) malloc(sizeof(pt_callback_parameters)); if (!parms) return ptInsufficientMemory; parms->id = pt_callback_proc_id; parms->resolution = resolution; parms->callback = callback; parms->userData = userData; res = pthread_create(&pt_thread_pid, NULL, Pt_CallbackProc, parms); if (res != 0) return ptHostError; pt_thread_created = TRUE; } time_started_flag = TRUE; return ptNoError; } PtError Pt_Stop() { /* printf("Pt_Stop called\n"); */ pt_callback_proc_id++; if (pt_thread_created) { pthread_join(pt_thread_pid, NULL); pt_thread_created = FALSE; } time_started_flag = FALSE; return ptNoError; } int Pt_Started() { return time_started_flag; } PtTimestamp Pt_Time() { long seconds, milliseconds; struct timeb now; ftime(&now); seconds = now.time - time_offset.time; milliseconds = now.millitm - time_offset.millitm; return seconds * 1000 + milliseconds; } void Pt_Sleep(int32_t duration) { usleep(duration * 1000); } pd-0.46-7/portmidi/porttime/ptmacosx_mach.c0000775000175000017500000000730612374245151017075 0ustar mspmsp/* ptmacosx.c -- portable timer implementation for mac os x */ #include #include #include #import #import #import #import #include #include "porttime.h" #include "sys/time.h" #include "pthread.h" #define NSEC_PER_MSEC 1000000 #define THREAD_IMPORTANCE 30 static int time_started_flag = FALSE; static UInt64 start_time; static pthread_t pt_thread_pid; /* note that this is static data -- we only need one copy */ typedef struct { int id; int resolution; PtCallback *callback; void *userData; } pt_callback_parameters; static int pt_callback_proc_id = 0; static void *Pt_CallbackProc(void *p) { pt_callback_parameters *parameters = (pt_callback_parameters *) p; int mytime = 1; kern_return_t error; thread_extended_policy_data_t extendedPolicy; thread_precedence_policy_data_t precedencePolicy; extendedPolicy.timeshare = 0; error = thread_policy_set(mach_thread_self(), THREAD_EXTENDED_POLICY, (thread_policy_t)&extendedPolicy, THREAD_EXTENDED_POLICY_COUNT); if (error != KERN_SUCCESS) { mach_error("Couldn't set thread timeshare policy", error); } precedencePolicy.importance = THREAD_IMPORTANCE; error = thread_policy_set(mach_thread_self(), THREAD_PRECEDENCE_POLICY, (thread_policy_t)&precedencePolicy, THREAD_PRECEDENCE_POLICY_COUNT); if (error != KERN_SUCCESS) { mach_error("Couldn't set thread precedence policy", error); } /* to kill a process, just increment the pt_callback_proc_id */ /* printf("pt_callback_proc_id %d, id %d\n", pt_callback_proc_id, parameters->id); */ while (pt_callback_proc_id == parameters->id) { /* wait for a multiple of resolution ms */ UInt64 wait_time; int delay = mytime++ * parameters->resolution - Pt_Time(); PtTimestamp timestamp; if (delay < 0) delay = 0; wait_time = AudioConvertNanosToHostTime((UInt64)delay * NSEC_PER_MSEC); wait_time += AudioGetCurrentHostTime(); error = mach_wait_until(wait_time); timestamp = Pt_Time(); (*(parameters->callback))(timestamp, parameters->userData); } free(parameters); return NULL; } PtError Pt_Start(int resolution, PtCallback *callback, void *userData) { if (time_started_flag) return ptAlreadyStarted; start_time = AudioGetCurrentHostTime(); if (callback) { int res; pt_callback_parameters *parms; parms = (pt_callback_parameters *) malloc(sizeof(pt_callback_parameters)); if (!parms) return ptInsufficientMemory; parms->id = pt_callback_proc_id; parms->resolution = resolution; parms->callback = callback; parms->userData = userData; res = pthread_create(&pt_thread_pid, NULL, Pt_CallbackProc, parms); if (res != 0) return ptHostError; } time_started_flag = TRUE; return ptNoError; } PtError Pt_Stop() { /* printf("Pt_Stop called\n"); */ pt_callback_proc_id++; pthread_join(pt_thread_pid, NULL); time_started_flag = FALSE; return ptNoError; } int Pt_Started() { return time_started_flag; } PtTimestamp Pt_Time() { UInt64 clock_time, nsec_time; clock_time = AudioGetCurrentHostTime() - start_time; nsec_time = AudioConvertHostTimeToNanos(clock_time); return (PtTimestamp)(nsec_time / NSEC_PER_MSEC); } void Pt_Sleep(int32_t duration) { usleep(duration * 1000); } pd-0.46-7/portmidi/porttime/porttime.h0000775000175000017500000000440412374245151016113 0ustar mspmsp/* porttime.h -- portable interface to millisecond timer */ /* CHANGE LOG FOR PORTTIME 10-Jun-03 Mark Nelson & RBD boost priority of timer thread in ptlinux.c implementation */ /* Should there be a way to choose the source of time here? */ #ifdef WIN32 #ifndef INT32_DEFINED // rather than having users install a special .h file for windows, // just put the required definitions inline here. portmidi.h uses // these too, so the definitions are (unfortunately) duplicated there typedef int int32_t; typedef unsigned int uint32_t; #define INT32_DEFINED #endif #else #include // needed for int32_t #endif #ifdef __cplusplus extern "C" { #endif #ifndef PMEXPORT #ifdef _WINDLL #define PMEXPORT __declspec(dllexport) #else #define PMEXPORT #endif #endif typedef enum { ptNoError = 0, /* success */ ptHostError = -10000, /* a system-specific error occurred */ ptAlreadyStarted, /* cannot start timer because it is already started */ ptAlreadyStopped, /* cannot stop timer because it is already stopped */ ptInsufficientMemory /* memory could not be allocated */ } PtError; typedef int32_t PtTimestamp; typedef void (PtCallback)( PtTimestamp timestamp, void *userData ); /* Pt_Start() starts a real-time service. resolution is the timer resolution in ms. The time will advance every resolution ms. callback is a function pointer to be called every resolution ms. userData is passed to callback as a parameter. return value: Upon success, returns ptNoError. See PtError for other values. */ PMEXPORT PtError Pt_Start(int resolution, PtCallback *callback, void *userData); /* Pt_Stop() stops the timer. return value: Upon success, returns ptNoError. See PtError for other values. */ PMEXPORT PtError Pt_Stop(); /* Pt_Started() returns true iff the timer is running. */ PMEXPORT int Pt_Started(); /* Pt_Time() returns the current time in ms. */ PMEXPORT PtTimestamp Pt_Time(); /* Pt_Sleep() pauses, allowing other threads to run. duration is the length of the pause in ms. The true duration of the pause may be rounded to the nearest or next clock tick as determined by resolution in Pt_Start(). */ PMEXPORT void Pt_Sleep(int32_t duration); #ifdef __cplusplus } #endif pd-0.46-7/portmidi/porttime/porttime.c0000775000175000017500000000020112160204055016064 0ustar mspmsp/* porttime.c -- portable API for millisecond timer */ /* There is no machine-independent implementation code to put here */ pd-0.46-7/portmidi/pm_mac/0000775000175000017500000000000012374245151013463 5ustar mspmsppd-0.46-7/portmidi/pm_mac/pmmac.c0000775000175000017500000000274012374245151014732 0ustar mspmsp/* pmmac.c -- PortMidi os-dependent code */ /* This file only needs to implement: pm_init(), which calls various routines to register the available midi devices, Pm_GetDefaultInputDeviceID(), and Pm_GetDefaultOutputDeviceID(). It is seperate from pmmacosxcm because we might want to register non-CoreMIDI devices. */ #include "stdlib.h" #include "portmidi.h" #include "pmutil.h" #include "pminternal.h" #include "pmmacosxcm.h" PmDeviceID pm_default_input_device_id = -1; PmDeviceID pm_default_output_device_id = -1; void pm_init() { PmError err = pm_macosxcm_init(); // this is set when we return to Pm_Initialize, but we need it // now in order to (successfully) call Pm_CountDevices() pm_initialized = TRUE; if (!err) { pm_default_input_device_id = find_default_device( "/PortMidi/PM_RECOMMENDED_INPUT_DEVICE", TRUE, pm_default_input_device_id); pm_default_output_device_id = find_default_device( "/PortMidi/PM_RECOMMENDED_OUTPUT_DEVICE", FALSE, pm_default_output_device_id); } } void pm_term(void) { pm_macosxcm_term(); } PmDeviceID Pm_GetDefaultInputDeviceID() { Pm_Initialize(); return pm_default_input_device_id; } PmDeviceID Pm_GetDefaultOutputDeviceID() { Pm_Initialize(); return pm_default_output_device_id; } void *pm_alloc(size_t s) { return malloc(s); } void pm_free(void *ptr) { free(ptr); } pd-0.46-7/portmidi/pm_mac/pmmacosxcm.h0000775000175000017500000000025512374245151016010 0ustar mspmsp/* system-specific definitions */ PmError pm_macosxcm_init(void); void pm_macosxcm_term(void); PmDeviceID find_default_device(char *path, int input, PmDeviceID id); pd-0.46-7/portmidi/pm_mac/pmmacosxcm.c0000775000175000017500000010023112374245151015776 0ustar mspmsp/* * Platform interface to the MacOS X CoreMIDI framework * * Jon Parise * and subsequent work by Andrew Zeldis and Zico Kolter * and Roger B. Dannenberg * * $Id: pmmacosx.c,v 1.17 2002/01/27 02:40:40 jon Exp $ */ /* Notes: since the input and output streams are represented by MIDIEndpointRef values and almost no other state, we store the MIDIEndpointRef on descriptors[midi->device_id].descriptor. The only other state we need is for errors: we need to know if there is an error and if so, what is the error text. We use a structure with two kinds of host error: "error" and "callback_error". That way, asynchronous callbacks do not interfere with other error information. OS X does not seem to have an error-code-to-text function, so we will just use text messages instead of error codes. */ #include //#define CM_DEBUG 1 #include "portmidi.h" #include "pmutil.h" #include "pminternal.h" #include "porttime.h" #include "pmmac.h" #include "pmmacosxcm.h" #include #include #include #include #include #include #define PACKET_BUFFER_SIZE 1024 /* maximum overall data rate (OS X limit is 15000 bytes/second) */ #define MAX_BYTES_PER_S 14000 /* Apple reports that packets are dropped when the MIDI bytes/sec exceeds 15000. This is computed by "tracking the number of MIDI bytes scheduled into 1-second buckets over the last six seconds and averaging these counts." This is apparently based on timestamps, not on real time, so we have to avoid constructing packets that schedule high speed output even if the actual writes are delayed (which was my first solution). The LIMIT_RATE symbol, if defined, enables code to modify timestamps as follows: After each packet is formed, the next allowable timestamp is computed as this_packet_time + this_packet_len * delay_per_byte This is the minimum timestamp allowed in the next packet. Note that this distorts accurate timestamps somewhat. */ #define LIMIT_RATE 1 #define SYSEX_BUFFER_SIZE 128 #define VERBOSE_ON 1 #define VERBOSE if (VERBOSE_ON) #define MIDI_SYSEX 0xf0 #define MIDI_EOX 0xf7 #define MIDI_STATUS_MASK 0x80 // "Ref"s are pointers on 32-bit machines and ints on 64 bit machines // NULL_REF is our representation of either 0 or NULL #ifdef __LP64__ #define NULL_REF 0 #else #define NULL_REF NULL #endif static MIDIClientRef client = NULL_REF; /* Client handle to the MIDI server */ static MIDIPortRef portIn = NULL_REF; /* Input port handle */ static MIDIPortRef portOut = NULL_REF; /* Output port handle */ extern pm_fns_node pm_macosx_in_dictionary; extern pm_fns_node pm_macosx_out_dictionary; typedef struct midi_macosxcm_struct { PmTimestamp sync_time; /* when did we last determine delta? */ UInt64 delta; /* difference between stream time and real time in ns */ UInt64 last_time; /* last output time in host units*/ int first_message; /* tells midi_write to sychronize timestamps */ int sysex_mode; /* middle of sending sysex */ uint32_t sysex_word; /* accumulate data when receiving sysex */ uint32_t sysex_byte_count; /* count how many received */ char error[PM_HOST_ERROR_MSG_LEN]; char callback_error[PM_HOST_ERROR_MSG_LEN]; Byte packetBuffer[PACKET_BUFFER_SIZE]; MIDIPacketList *packetList; /* a pointer to packetBuffer */ MIDIPacket *packet; Byte sysex_buffer[SYSEX_BUFFER_SIZE]; /* temp storage for sysex data */ MIDITimeStamp sysex_timestamp; /* timestamp to use with sysex data */ /* allow for running status (is running status possible here? -rbd): -cpr */ unsigned char last_command; int32_t last_msg_length; /* limit midi data rate (a CoreMidi requirement): */ UInt64 min_next_time; /* when can the next send take place? */ int byte_count; /* how many bytes in the next packet list? */ Float64 us_per_host_tick; /* host clock frequency, units of min_next_time */ UInt64 host_ticks_per_byte; /* host clock units per byte at maximum rate */ } midi_macosxcm_node, *midi_macosxcm_type; /* private function declarations */ MIDITimeStamp timestamp_pm_to_cm(PmTimestamp timestamp); PmTimestamp timestamp_cm_to_pm(MIDITimeStamp timestamp); char* cm_get_full_endpoint_name(MIDIEndpointRef endpoint); static int midi_length(int32_t msg) { int status, high, low; static int high_lengths[] = { 1, 1, 1, 1, 1, 1, 1, 1, /* 0x00 through 0x70 */ 3, 3, 3, 3, 2, 2, 3, 1 /* 0x80 through 0xf0 */ }; static int low_lengths[] = { 1, 2, 3, 2, 1, 1, 1, 1, /* 0xf0 through 0xf8 */ 1, 1, 1, 1, 1, 1, 1, 1 /* 0xf9 through 0xff */ }; status = msg & 0xFF; high = status >> 4; low = status & 15; return (high != 0xF) ? high_lengths[high] : low_lengths[low]; } static PmTimestamp midi_synchronize(PmInternal *midi) { midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; UInt64 pm_stream_time_2 = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()); PmTimestamp real_time; UInt64 pm_stream_time; /* if latency is zero and this is an output, there is no time reference and midi_synchronize should never be called */ assert(midi->time_proc); assert(!(midi->write_flag && midi->latency == 0)); do { /* read real_time between two reads of stream time */ pm_stream_time = pm_stream_time_2; real_time = (*midi->time_proc)(midi->time_info); pm_stream_time_2 = AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()); /* repeat if more than 0.5 ms has elapsed */ } while (pm_stream_time_2 > pm_stream_time + 500000); m->delta = pm_stream_time - ((UInt64) real_time * (UInt64) 1000000); m->sync_time = real_time; return real_time; } static void process_packet(MIDIPacket *packet, PmEvent *event, PmInternal *midi, midi_macosxcm_type m) { /* handle a packet of MIDI messages from CoreMIDI */ /* there may be multiple short messages in one packet (!) */ unsigned int remaining_length = packet->length; unsigned char *cur_packet_data = packet->data; while (remaining_length > 0) { if (cur_packet_data[0] == MIDI_SYSEX || /* are we in the middle of a sysex message? */ (m->last_command == 0 && !(cur_packet_data[0] & MIDI_STATUS_MASK))) { m->last_command = 0; /* no running status */ unsigned int amt = pm_read_bytes(midi, cur_packet_data, remaining_length, event->timestamp); remaining_length -= amt; cur_packet_data += amt; } else if (cur_packet_data[0] == MIDI_EOX) { /* this should never happen, because pm_read_bytes should * get and read all EOX bytes*/ midi->sysex_in_progress = FALSE; m->last_command = 0; } else if (cur_packet_data[0] & MIDI_STATUS_MASK) { /* compute the length of the next (short) msg in packet */ unsigned int cur_message_length = midi_length(cur_packet_data[0]); if (cur_message_length > remaining_length) { #ifdef DEBUG printf("PortMidi debug msg: not enough data"); #endif /* since there's no more data, we're done */ return; } m->last_msg_length = cur_message_length; m->last_command = cur_packet_data[0]; switch (cur_message_length) { case 1: event->message = Pm_Message(cur_packet_data[0], 0, 0); break; case 2: event->message = Pm_Message(cur_packet_data[0], cur_packet_data[1], 0); break; case 3: event->message = Pm_Message(cur_packet_data[0], cur_packet_data[1], cur_packet_data[2]); break; default: /* PortMIDI internal error; should never happen */ assert(cur_message_length == 1); return; /* give up on packet if continued after assert */ } pm_read_short(midi, event); remaining_length -= m->last_msg_length; cur_packet_data += m->last_msg_length; } else if (m->last_msg_length > remaining_length + 1) { /* we have running status, but not enough data */ #ifdef DEBUG printf("PortMidi debug msg: not enough data in CoreMIDI packet"); #endif /* since there's no more data, we're done */ return; } else { /* output message using running status */ switch (m->last_msg_length) { case 1: event->message = Pm_Message(m->last_command, 0, 0); break; case 2: event->message = Pm_Message(m->last_command, cur_packet_data[0], 0); break; case 3: event->message = Pm_Message(m->last_command, cur_packet_data[0], cur_packet_data[1]); break; default: /* last_msg_length is invalid -- internal PortMIDI error */ assert(m->last_msg_length == 1); } pm_read_short(midi, event); remaining_length -= (m->last_msg_length - 1); cur_packet_data += (m->last_msg_length - 1); } } } /* called when MIDI packets are received */ static void readProc(const MIDIPacketList *newPackets, void *refCon, void *connRefCon) { PmInternal *midi; midi_macosxcm_type m; PmEvent event; MIDIPacket *packet; unsigned int packetIndex; uint32_t now; unsigned int status; #ifdef CM_DEBUG printf("readProc: numPackets %d: ", newPackets->numPackets); #endif /* Retrieve the context for this connection */ midi = (PmInternal *) connRefCon; m = (midi_macosxcm_type) midi->descriptor; assert(m); /* synchronize time references every 100ms */ now = (*midi->time_proc)(midi->time_info); if (m->first_message || m->sync_time + 100 /*ms*/ < now) { /* time to resync */ now = midi_synchronize(midi); m->first_message = FALSE; } packet = (MIDIPacket *) &newPackets->packet[0]; /* printf("readproc packet status %x length %d\n", packet->data[0], packet->length); */ for (packetIndex = 0; packetIndex < newPackets->numPackets; packetIndex++) { /* Set the timestamp and dispatch this message */ event.timestamp = (PmTimestamp) /* explicit conversion */ ( (AudioConvertHostTimeToNanos(packet->timeStamp) - m->delta) / (UInt64) 1000000); status = packet->data[0]; /* process packet as sysex data if it begins with MIDI_SYSEX, or MIDI_EOX or non-status byte with no running status */ #ifdef CM_DEBUG printf(" %d", packet->length); #endif if (status == MIDI_SYSEX || status == MIDI_EOX || ((!(status & MIDI_STATUS_MASK)) && !m->last_command)) { /* previously was: !(status & MIDI_STATUS_MASK)) { * but this could mistake running status for sysex data */ /* reset running status data -cpr */ m->last_command = 0; m->last_msg_length = 0; /* printf("sysex packet length: %d\n", packet->length); */ pm_read_bytes(midi, packet->data, packet->length, event.timestamp); } else { process_packet(packet, &event, midi, m); } packet = MIDIPacketNext(packet); } #ifdef CM_DEBUG printf("\n"); #endif } static PmError midi_in_open(PmInternal *midi, void *driverInfo) { MIDIEndpointRef endpoint; midi_macosxcm_type m; OSStatus macHostError; /* insure that we have a time_proc for timing */ if (midi->time_proc == NULL) { if (!Pt_Started()) Pt_Start(1, 0, 0); /* time_get does not take a parameter, so coerce */ midi->time_proc = (PmTimeProcPtr) Pt_Time; } endpoint = (MIDIEndpointRef) (long) descriptors[midi->device_id].descriptor; if (endpoint == NULL_REF) { return pmInvalidDeviceId; } m = (midi_macosxcm_type) pm_alloc(sizeof(midi_macosxcm_node)); /* create */ midi->descriptor = m; if (!m) { return pmInsufficientMemory; } m->error[0] = 0; m->callback_error[0] = 0; m->sync_time = 0; m->delta = 0; m->last_time = 0; m->first_message = TRUE; m->sysex_mode = FALSE; m->sysex_word = 0; m->sysex_byte_count = 0; m->packetList = NULL; m->packet = NULL; m->last_command = 0; m->last_msg_length = 0; macHostError = MIDIPortConnectSource(portIn, endpoint, midi); if (macHostError != noErr) { pm_hosterror = macHostError; sprintf(pm_hosterror_text, "Host error %ld: MIDIPortConnectSource() in midi_in_open()", (long) macHostError); midi->descriptor = NULL; pm_free(m); return pmHostError; } return pmNoError; } static PmError midi_in_close(PmInternal *midi) { MIDIEndpointRef endpoint; OSStatus macHostError; PmError err = pmNoError; midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; if (!m) return pmBadPtr; endpoint = (MIDIEndpointRef) (long) descriptors[midi->device_id].descriptor; if (endpoint == NULL_REF) { pm_hosterror = pmBadPtr; } /* shut off the incoming messages before freeing data structures */ macHostError = MIDIPortDisconnectSource(portIn, endpoint); if (macHostError != noErr) { pm_hosterror = macHostError; sprintf(pm_hosterror_text, "Host error %ld: MIDIPortDisconnectSource() in midi_in_close()", (long) macHostError); err = pmHostError; } midi->descriptor = NULL; pm_free(midi->descriptor); return err; } static PmError midi_out_open(PmInternal *midi, void *driverInfo) { midi_macosxcm_type m; m = (midi_macosxcm_type) pm_alloc(sizeof(midi_macosxcm_node)); /* create */ midi->descriptor = m; if (!m) { return pmInsufficientMemory; } m->error[0] = 0; m->callback_error[0] = 0; m->sync_time = 0; m->delta = 0; m->last_time = 0; m->first_message = TRUE; m->sysex_mode = FALSE; m->sysex_word = 0; m->sysex_byte_count = 0; m->packetList = (MIDIPacketList *) m->packetBuffer; m->packet = NULL; m->last_command = 0; m->last_msg_length = 0; m->min_next_time = 0; m->byte_count = 0; m->us_per_host_tick = 1000000.0 / AudioGetHostClockFrequency(); m->host_ticks_per_byte = (UInt64) (1000000.0 / (m->us_per_host_tick * MAX_BYTES_PER_S)); return pmNoError; } static PmError midi_out_close(PmInternal *midi) { midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; if (!m) return pmBadPtr; midi->descriptor = NULL; pm_free(midi->descriptor); return pmNoError; } static PmError midi_abort(PmInternal *midi) { PmError err = pmNoError; OSStatus macHostError; MIDIEndpointRef endpoint = (MIDIEndpointRef) (long) descriptors[midi->device_id].descriptor; macHostError = MIDIFlushOutput(endpoint); if (macHostError != noErr) { pm_hosterror = macHostError; sprintf(pm_hosterror_text, "Host error %ld: MIDIFlushOutput()", (long) macHostError); err = pmHostError; } return err; } static PmError midi_write_flush(PmInternal *midi, PmTimestamp timestamp) { OSStatus macHostError; midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; MIDIEndpointRef endpoint = (MIDIEndpointRef) (long) descriptors[midi->device_id].descriptor; assert(m); assert(endpoint); if (m->packet != NULL) { /* out of space, send the buffer and start refilling it */ /* before we can send, maybe delay to limit data rate. OS X allows * 15KB/s. */ UInt64 now = AudioGetCurrentHostTime(); if (now < m->min_next_time) { usleep((useconds_t) ((m->min_next_time - now) * m->us_per_host_tick)); } macHostError = MIDISend(portOut, endpoint, m->packetList); m->packet = NULL; /* indicate no data in packetList now */ m->min_next_time = now + m->byte_count * m->host_ticks_per_byte; m->byte_count = 0; if (macHostError != noErr) goto send_packet_error; } return pmNoError; send_packet_error: pm_hosterror = macHostError; sprintf(pm_hosterror_text, "Host error %ld: MIDISend() in midi_write()", (long) macHostError); return pmHostError; } static PmError send_packet(PmInternal *midi, Byte *message, unsigned int messageLength, MIDITimeStamp timestamp) { PmError err; midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; assert(m); /* printf("add %d to packet %p len %d\n", message[0], m->packet, messageLength); */ m->packet = MIDIPacketListAdd(m->packetList, sizeof(m->packetBuffer), m->packet, timestamp, messageLength, message); m->byte_count += messageLength; if (m->packet == NULL) { /* out of space, send the buffer and start refilling it */ /* make midi->packet non-null to fool midi_write_flush into sending */ m->packet = (MIDIPacket *) 4; /* timestamp is 0 because midi_write_flush ignores timestamp since * timestamps are already in packets. The timestamp parameter is here * because other API's need it. midi_write_flush can be called * from system-independent code that must be cross-API. */ if ((err = midi_write_flush(midi, 0)) != pmNoError) return err; m->packet = MIDIPacketListInit(m->packetList); assert(m->packet); /* if this fails, it's a programming error */ m->packet = MIDIPacketListAdd(m->packetList, sizeof(m->packetBuffer), m->packet, timestamp, messageLength, message); assert(m->packet); /* can't run out of space on first message */ } return pmNoError; } static PmError midi_write_short(PmInternal *midi, PmEvent *event) { PmTimestamp when = event->timestamp; PmMessage what = event->message; MIDITimeStamp timestamp; UInt64 when_ns; midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; Byte message[4]; unsigned int messageLength; if (m->packet == NULL) { m->packet = MIDIPacketListInit(m->packetList); /* this can never fail, right? failure would indicate something unrecoverable */ assert(m->packet); } /* compute timestamp */ if (when == 0) when = midi->now; /* if latency == 0, midi->now is not valid. We will just set it to zero */ if (midi->latency == 0) when = 0; when_ns = ((UInt64) (when + midi->latency) * (UInt64) 1000000) + m->delta; timestamp = (MIDITimeStamp) AudioConvertNanosToHostTime(when_ns); message[0] = Pm_MessageStatus(what); message[1] = Pm_MessageData1(what); message[2] = Pm_MessageData2(what); messageLength = midi_length(what); /* make sure we go foreward in time */ if (timestamp < m->min_next_time) timestamp = m->min_next_time; #ifdef LIMIT_RATE if (timestamp < m->last_time) timestamp = m->last_time; m->last_time = timestamp + messageLength * m->host_ticks_per_byte; #endif /* Add this message to the packet list */ return send_packet(midi, message, messageLength, timestamp); } static PmError midi_begin_sysex(PmInternal *midi, PmTimestamp when) { UInt64 when_ns; midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; assert(m); m->sysex_byte_count = 0; /* compute timestamp */ if (when == 0) when = midi->now; /* if latency == 0, midi->now is not valid. We will just set it to zero */ if (midi->latency == 0) when = 0; when_ns = ((UInt64) (when + midi->latency) * (UInt64) 1000000) + m->delta; m->sysex_timestamp = (MIDITimeStamp) AudioConvertNanosToHostTime(when_ns); if (m->packet == NULL) { m->packet = MIDIPacketListInit(m->packetList); /* this can never fail, right? failure would indicate something unrecoverable */ assert(m->packet); } return pmNoError; } static PmError midi_end_sysex(PmInternal *midi, PmTimestamp when) { PmError err; midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; assert(m); /* make sure we go foreward in time */ if (m->sysex_timestamp < m->min_next_time) m->sysex_timestamp = m->min_next_time; #ifdef LIMIT_RATE if (m->sysex_timestamp < m->last_time) m->sysex_timestamp = m->last_time; m->last_time = m->sysex_timestamp + m->sysex_byte_count * m->host_ticks_per_byte; #endif /* now send what's in the buffer */ err = send_packet(midi, m->sysex_buffer, m->sysex_byte_count, m->sysex_timestamp); m->sysex_byte_count = 0; if (err != pmNoError) { m->packet = NULL; /* flush everything in the packet list */ return err; } return pmNoError; } static PmError midi_write_byte(PmInternal *midi, unsigned char byte, PmTimestamp timestamp) { midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; assert(m); if (m->sysex_byte_count >= SYSEX_BUFFER_SIZE) { PmError err = midi_end_sysex(midi, timestamp); if (err != pmNoError) return err; } m->sysex_buffer[m->sysex_byte_count++] = byte; return pmNoError; } static PmError midi_write_realtime(PmInternal *midi, PmEvent *event) { /* to send a realtime message during a sysex message, first flush all pending sysex bytes into packet list */ PmError err = midi_end_sysex(midi, 0); if (err != pmNoError) return err; /* then we can just do a normal midi_write_short */ return midi_write_short(midi, event); } static unsigned int midi_has_host_error(PmInternal *midi) { midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; return (m->callback_error[0] != 0) || (m->error[0] != 0); } static void midi_get_host_error(PmInternal *midi, char *msg, unsigned int len) { midi_macosxcm_type m = (midi_macosxcm_type) midi->descriptor; msg[0] = 0; /* initialize to empty string */ if (m) { /* make sure there is an open device to examine */ if (m->error[0]) { strncpy(msg, m->error, len); m->error[0] = 0; /* clear the error */ } else if (m->callback_error[0]) { strncpy(msg, m->callback_error, len); m->callback_error[0] = 0; /* clear the error */ } msg[len - 1] = 0; /* make sure string is terminated */ } } MIDITimeStamp timestamp_pm_to_cm(PmTimestamp timestamp) { UInt64 nanos; if (timestamp <= 0) { return (MIDITimeStamp)0; } else { nanos = (UInt64)timestamp * (UInt64)1000000; return (MIDITimeStamp)AudioConvertNanosToHostTime(nanos); } } PmTimestamp timestamp_cm_to_pm(MIDITimeStamp timestamp) { UInt64 nanos; nanos = AudioConvertHostTimeToNanos(timestamp); return (PmTimestamp)(nanos / (UInt64)1000000); } // // Code taken from http://developer.apple.com/qa/qa2004/qa1374.html ////////////////////////////////////// // Obtain the name of an endpoint without regard for whether it has connections. // The result should be released by the caller. CFStringRef EndpointName(MIDIEndpointRef endpoint, bool isExternal) { CFMutableStringRef result = CFStringCreateMutable(NULL, 0); CFStringRef str; // begin with the endpoint's name str = NULL; MIDIObjectGetStringProperty(endpoint, kMIDIPropertyName, &str); if (str != NULL) { CFStringAppend(result, str); CFRelease(str); } MIDIEntityRef entity = NULL_REF; MIDIEndpointGetEntity(endpoint, &entity); if (entity == NULL_REF) // probably virtual return result; if (CFStringGetLength(result) == 0) { // endpoint name has zero length -- try the entity str = NULL; MIDIObjectGetStringProperty(entity, kMIDIPropertyName, &str); if (str != NULL) { CFStringAppend(result, str); CFRelease(str); } } // now consider the device's name MIDIDeviceRef device = NULL_REF; MIDIEntityGetDevice(entity, &device); if (device == NULL_REF) return result; str = NULL; MIDIObjectGetStringProperty(device, kMIDIPropertyName, &str); if (CFStringGetLength(result) == 0) { CFRelease(result); return str; } if (str != NULL) { // if an external device has only one entity, throw away // the endpoint name and just use the device name if (isExternal && MIDIDeviceGetNumberOfEntities(device) < 2) { CFRelease(result); return str; } else { if (CFStringGetLength(str) == 0) { CFRelease(str); return result; } // does the entity name already start with the device name? // (some drivers do this though they shouldn't) // if so, do not prepend if (CFStringCompareWithOptions( result, /* endpoint name */ str /* device name */, CFRangeMake(0, CFStringGetLength(str)), 0) != kCFCompareEqualTo) { // prepend the device name to the entity name if (CFStringGetLength(result) > 0) CFStringInsert(result, 0, CFSTR(" ")); CFStringInsert(result, 0, str); } CFRelease(str); } } return result; } // Obtain the name of an endpoint, following connections. // The result should be released by the caller. static CFStringRef ConnectedEndpointName(MIDIEndpointRef endpoint) { CFMutableStringRef result = CFStringCreateMutable(NULL, 0); CFStringRef str; OSStatus err; long i; // Does the endpoint have connections? CFDataRef connections = NULL; long nConnected = 0; bool anyStrings = false; err = MIDIObjectGetDataProperty(endpoint, kMIDIPropertyConnectionUniqueID, &connections); if (connections != NULL) { // It has connections, follow them // Concatenate the names of all connected devices nConnected = CFDataGetLength(connections) / (int32_t) sizeof(MIDIUniqueID); if (nConnected) { const SInt32 *pid = (const SInt32 *)(CFDataGetBytePtr(connections)); for (i = 0; i < nConnected; ++i, ++pid) { MIDIUniqueID id = EndianS32_BtoN(*pid); MIDIObjectRef connObject; MIDIObjectType connObjectType; err = MIDIObjectFindByUniqueID(id, &connObject, &connObjectType); if (err == noErr) { if (connObjectType == kMIDIObjectType_ExternalSource || connObjectType == kMIDIObjectType_ExternalDestination) { // Connected to an external device's endpoint (10.3 and later). str = EndpointName((MIDIEndpointRef)(connObject), true); } else { // Connected to an external device (10.2) (or something else, catch-all) str = NULL; MIDIObjectGetStringProperty(connObject, kMIDIPropertyName, &str); } if (str != NULL) { if (anyStrings) CFStringAppend(result, CFSTR(", ")); else anyStrings = true; CFStringAppend(result, str); CFRelease(str); } } } } CFRelease(connections); } if (anyStrings) return result; // Here, either the endpoint had no connections, or we failed to obtain names for any of them. return EndpointName(endpoint, false); } char* cm_get_full_endpoint_name(MIDIEndpointRef endpoint) { #ifdef OLDCODE MIDIEntityRef entity; MIDIDeviceRef device; CFStringRef endpointName = NULL; CFStringRef deviceName = NULL; #endif CFStringRef fullName = NULL; CFStringEncoding defaultEncoding; char* newName; /* get the default string encoding */ defaultEncoding = CFStringGetSystemEncoding(); fullName = ConnectedEndpointName(endpoint); #ifdef OLDCODE /* get the entity and device info */ MIDIEndpointGetEntity(endpoint, &entity); MIDIEntityGetDevice(entity, &device); /* create the nicely formated name */ MIDIObjectGetStringProperty(endpoint, kMIDIPropertyName, &endpointName); MIDIObjectGetStringProperty(device, kMIDIPropertyName, &deviceName); if (deviceName != NULL) { fullName = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@: %@"), deviceName, endpointName); } else { fullName = endpointName; } #endif /* copy the string into our buffer */ newName = (char *) malloc(CFStringGetLength(fullName) + 1); CFStringGetCString(fullName, newName, CFStringGetLength(fullName) + 1, defaultEncoding); /* clean up */ #ifdef OLDCODE if (endpointName) CFRelease(endpointName); if (deviceName) CFRelease(deviceName); #endif if (fullName) CFRelease(fullName); return newName; } pm_fns_node pm_macosx_in_dictionary = { none_write_short, none_sysex, none_sysex, none_write_byte, none_write_short, none_write_flush, none_synchronize, midi_in_open, midi_abort, midi_in_close, success_poll, midi_has_host_error, midi_get_host_error, }; pm_fns_node pm_macosx_out_dictionary = { midi_write_short, midi_begin_sysex, midi_end_sysex, midi_write_byte, midi_write_realtime, midi_write_flush, midi_synchronize, midi_out_open, midi_abort, midi_out_close, success_poll, midi_has_host_error, midi_get_host_error, }; PmError pm_macosxcm_init(void) { ItemCount numInputs, numOutputs, numDevices; MIDIEndpointRef endpoint; int i; OSStatus macHostError; char *error_text; /* Determine the number of MIDI devices on the system */ numDevices = MIDIGetNumberOfDevices(); numInputs = MIDIGetNumberOfSources(); numOutputs = MIDIGetNumberOfDestinations(); /* Return prematurely if no devices exist on the system Note that this is not an error. There may be no devices. Pm_CountDevices() will return zero, which is correct and useful information */ if (numDevices <= 0) { return pmNoError; } /* Initialize the client handle */ macHostError = MIDIClientCreate(CFSTR("PortMidi"), NULL, NULL, &client); if (macHostError != noErr) { error_text = "MIDIClientCreate() in pm_macosxcm_init()"; goto error_return; } /* Create the input port */ macHostError = MIDIInputPortCreate(client, CFSTR("Input port"), readProc, NULL, &portIn); if (macHostError != noErr) { error_text = "MIDIInputPortCreate() in pm_macosxcm_init()"; goto error_return; } /* Create the output port */ macHostError = MIDIOutputPortCreate(client, CFSTR("Output port"), &portOut); if (macHostError != noErr) { error_text = "MIDIOutputPortCreate() in pm_macosxcm_init()"; goto error_return; } /* Iterate over the MIDI input devices */ for (i = 0; i < numInputs; i++) { endpoint = MIDIGetSource(i); if (endpoint == NULL_REF) { continue; } /* set the first input we see to the default */ if (pm_default_input_device_id == -1) pm_default_input_device_id = pm_descriptor_index; /* Register this device with PortMidi */ pm_add_device("CoreMIDI", cm_get_full_endpoint_name(endpoint), TRUE, (void *) (long) endpoint, &pm_macosx_in_dictionary); } /* Iterate over the MIDI output devices */ for (i = 0; i < numOutputs; i++) { endpoint = MIDIGetDestination(i); if (endpoint == NULL_REF) { continue; } /* set the first output we see to the default */ if (pm_default_output_device_id == -1) pm_default_output_device_id = pm_descriptor_index; /* Register this device with PortMidi */ pm_add_device("CoreMIDI", cm_get_full_endpoint_name(endpoint), FALSE, (void *) (long) endpoint, &pm_macosx_out_dictionary); } return pmNoError; error_return: pm_hosterror = macHostError; sprintf(pm_hosterror_text, "Host error %ld: %s\n", (long) macHostError, error_text); pm_macosxcm_term(); /* clear out any opened ports */ return pmHostError; } void pm_macosxcm_term(void) { if (client != NULL_REF) MIDIClientDispose(client); if (portIn != NULL_REF) MIDIPortDispose(portIn); if (portOut != NULL_REF) MIDIPortDispose(portOut); } pd-0.46-7/portmidi/pm_mac/readbinaryplist.h0000664000175000017500000000372312374245151017035 0ustar mspmsp/* readbinaryplist.h -- header to read preference files Roger B. Dannenberg, Jun 2008 */ #include /* for uint8_t ... */ #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif #define MAX_KEY_SIZE 256 enum { // Object tags (high nybble) kTAG_SIMPLE = 0x00, // Null, true, false, filler, or invalid kTAG_INT = 0x10, kTAG_REAL = 0x20, kTAG_DATE = 0x30, kTAG_DATA = 0x40, kTAG_ASCIISTRING = 0x50, kTAG_UNICODESTRING = 0x60, kTAG_UID = 0x80, kTAG_ARRAY = 0xA0, kTAG_DICTIONARY = 0xD0, // "simple" object values kVALUE_NULL = 0x00, kVALUE_FALSE = 0x08, kVALUE_TRUE = 0x09, kVALUE_FILLER = 0x0F, kVALUE_FULLDATETAG = 0x33 // Dates are tagged with a whole byte. }; typedef struct pldata_struct { uint8_t *data; size_t len; } pldata_node, *pldata_ptr; typedef struct array_struct { struct value_struct **array; uint64_t length; } array_node, *array_ptr; // a dict_node is a list of pairs typedef struct dict_struct { struct value_struct *key; struct value_struct *value; struct dict_struct *next; } dict_node, *dict_ptr; // an value_node is a value with a tag telling the type typedef struct value_struct { int tag; union { int64_t integer; uint64_t uinteger; double real; char *string; pldata_ptr data; array_ptr array; struct dict_struct *dict; }; } value_node, *value_ptr; value_ptr bplist_read_file(char *filename); value_ptr bplist_read_user_pref(char *filename); value_ptr bplist_read_system_pref(char *filename); void bplist_free_data(); /*************** functions for accessing values ****************/ char *value_get_asciistring(value_ptr v); value_ptr value_dict_lookup_using_string(value_ptr v, char *key); value_ptr value_dict_lookup_using_path(value_ptr v, char *path); /*************** functions for debugging ***************/ void plist_print(value_ptr v); pd-0.46-7/portmidi/pm_mac/finddefault.c0000664000175000017500000000342312374245151016116 0ustar mspmsp/* finddefault.c -- find_default_device() implementation Roger Dannenberg, June 2008 */ #include #include #include "portmidi.h" #include "pmutil.h" #include "pminternal.h" #include "pmmacosxcm.h" #include "readbinaryplist.h" /* Parse preference files, find default device, search devices -- This parses the preference file(s) once for input and once for output, which is inefficient but much simpler to manage. Note that using the readbinaryplist.c module, you cannot keep two plist files (user and system) open at once (due to a simple memory management scheme). */ PmDeviceID find_default_device(char *path, int input, PmDeviceID id) /* path -- the name of the preference we are searching for input -- true iff this is an input device id -- current default device id returns matching device id if found, otherwise id */ { static char *pref_file = "com.apple.java.util.prefs.plist"; char *pref_str = NULL; // read device preferences value_ptr prefs = bplist_read_user_pref(pref_file); if (prefs) { value_ptr pref_val = value_dict_lookup_using_path(prefs, path); if (pref_val) { pref_str = value_get_asciistring(pref_val); } } if (!pref_str) { bplist_free_data(); /* look elsewhere */ prefs = bplist_read_system_pref(pref_file); if (prefs) { value_ptr pref_val = value_dict_lookup_using_path(prefs, path); if (pref_val) { pref_str = value_get_asciistring(pref_val); } } } if (pref_str) { /* search devices for match */ int i = pm_find_default_device(pref_str, input); if (i != pmNoDevice) { id = i; } } if (prefs) { bplist_free_data(); } return id; } pd-0.46-7/portmidi/pm_mac/readbinaryplist.c0000664000175000017500000010446712374245151017037 0ustar mspmsp/* readbinaryplist.c -- Roger B. Dannenberg, Jun 2008 Based on ReadBinaryPList.m by Jens Ayton, 2007 Note that this code is intended to read preference files and has an upper bound on file size (currently 100MB) and assumes in some places that 32 bit offsets are sufficient. Here are his comments: Reader for binary property list files (version 00). This has been found to work on all 566 binary plists in my ~/Library/Preferences/ and /Library/Preferences/ directories. This probably does not provide full test coverage. It has also been found to provide different data to Apple's implementation when presented with a key-value archive. This is because Apple's implementation produces undocumented CFKeyArchiverUID objects. My implementation produces dictionaries instead, matching the in-file representation used in XML and OpenStep plists. See extract_uid(). Full disclosure: in implementing this software, I read one comment and one struct defintion in CFLite, Apple's implementation, which is under the APSL license. I also deduced the information about CFKeyArchiverUID from that code. However, none of the implementation was copied. Copyright (C) 2007 Jens Ayton Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* A note about memory management: Strings and possibly other values are unique and because the values associated with IDs are cached, you end up with a directed graph rather than a tree. It is tricky to free the data because if you do a simple depth-first search to free nodes, you will free nodes twice. I decided to allocate memory from blocks of 1024 bytes and keep the blocks in a list associated with but private to this module. So the user should access this module by calling: bplist_read_file() or bplist_read_user_pref() or bplist_read_system_pref() which returns a value. When you are done with the value, call bplist_free_data() This will of course free the value_ptr returned by bplist_read_*() To deal with memory exhaustion (what happens when malloc returns NULL?), use setjmp/longjmp -- a single setjmp protects the whole parser, and allocate uses longjmp to abort. After abort, memory is freed and NULL is returned to caller. There is not much here in the way of error reporting. Memory is obtained by calling allocate which either returns the memory requested or calls longjmp, so callers don't have to check. */ #include #include #include #include #include #include #include "readbinaryplist.h" #include #define NO 0 #define YES 1 #define BOOL int #define MAXPATHLEN 256 /* there are 2 levels of error logging/printing: * BPLIST_LOG and BPLIST_LOG_VERBOSE * either or both can be set to non-zero to turn on * If BPLIST_LOG_VERBOSE is true, then BPLIST_LOG * is also true. * * In the code, logging is done by calling either * bplist_log() or bplist_log_verbose(), which take * parameters like printf but might be a no-op. */ /* #define BPLIST_LOG_VERBOSE 1 */ #if BPLIST_LOG_VERBOSE #ifndef BPLIST_LOG #define BPLIST_LOG 1 #endif #endif #if BPLIST_LOG #define bplist_log printf #else #define bplist_log(...) #endif #if BPLIST_LOG_VERBOSE #define bplist_log_verbose bplist_log #else #define bplist_log_verbose(...) #endif /********* MEMORY MANAGEMENT ********/ #define BLOCK_SIZE 1024 // memory is aligned to multiples of this; assume malloc automatically // aligns to this number and assume this number is > sizeof(void *) #define ALIGNMENT 8 static void *block_list = NULL; static char *free_ptr = NULL; static char *end_ptr = NULL; static jmp_buf abort_parsing; static void *allocate(size_t size) { void *result; if (free_ptr + size > end_ptr) { size_t how_much = BLOCK_SIZE; // align everything to 8 bytes if (size > BLOCK_SIZE - ALIGNMENT) { how_much = size + ALIGNMENT; } result = malloc(how_much); if (result == NULL) { /* serious problem */ longjmp(abort_parsing, 1); } *((void **)result) = block_list; block_list = result; free_ptr = ((char *) result) + ALIGNMENT; end_ptr = ((char *) result) + how_much; } // now, there is enough rooom at free_ptr result = free_ptr; free_ptr += size; return result; } void bplist_free_data() { while (block_list) { void *next = *(void **)block_list; free(block_list); block_list = next; } free_ptr = NULL; end_ptr = NULL; } // layout of trailer -- last 32 bytes in plist data uint8_t unused[6]; uint8_t offset_int_size; uint8_t object_ref_size; uint64_t object_count; uint64_t top_level_object; uint64_t offset_table_offset; enum { kHEADER_SIZE = 8, kTRAILER_SIZE = 32, //sizeof(bplist_trailer_node), kMINIMUM_SANE_SIZE = kHEADER_SIZE + kTRAILER_SIZE }; static const char kHEADER_BYTES[kHEADER_SIZE] = "bplist00"; // map from UID key to previously parsed value typedef struct cache_struct { uint64_t key; value_ptr value; struct cache_struct *next; } cache_node, *cache_ptr; typedef struct bplist_info { uint64_t object_count; const uint8_t *data_bytes; uint64_t length; uint64_t offset_table_offset; uint8_t offset_int_size; uint8_t object_ref_size; cache_ptr cache; } bplist_info_node, *bplist_info_ptr; static value_ptr bplist_read_pldata(pldata_ptr data); static value_ptr bplist_read_pref(char *filename, OSType folder_type); static uint64_t read_sized_int(bplist_info_ptr bplist, uint64_t offset, uint8_t size); static uint64_t read_offset(bplist_info_ptr bplist, uint64_t index); static BOOL read_self_sized_int(bplist_info_ptr bplist, uint64_t offset, uint64_t *outValue, size_t *outSize); static value_ptr extract_object(bplist_info_ptr bplist, uint64_t objectRef); static value_ptr extract_simple(bplist_info_ptr bplist, uint64_t offset); static value_ptr extract_int(bplist_info_ptr bplist, uint64_t offset); static value_ptr extract_real(bplist_info_ptr bplist, uint64_t offset); static value_ptr extract_date(bplist_info_ptr bplist, uint64_t offset); static value_ptr extract_data(bplist_info_ptr bplist, uint64_t offset); static value_ptr extract_ascii_string(bplist_info_ptr bplist, uint64_t offset); static value_ptr extract_unicode_string(bplist_info_ptr bplist, uint64_t offset); static value_ptr extract_uid(bplist_info_ptr bplist, uint64_t offset); static value_ptr extract_array(bplist_info_ptr bplist, uint64_t offset); static value_ptr extract_dictionary(bplist_info_ptr bplist, uint64_t offset); value_ptr value_create() { value_ptr value = (value_ptr) allocate(sizeof(value_node)); return value; } void value_set_integer(value_ptr v, int64_t i) { v->tag = kTAG_INT; v->integer = i; } void value_set_real(value_ptr v, double d) { v->tag = kTAG_REAL; v->real = d; } // d is seconds since 1 January 2001 void value_set_date(value_ptr v, double d) { v->tag = kTAG_DATE; v->real = d; } void value_set_ascii_string(value_ptr v, const uint8_t *s, size_t len) { v->tag = kTAG_ASCIISTRING; v->string = (char *) allocate(len + 1); memcpy(v->string, s, len); v->string[len] = 0; } void value_set_unicode_string(value_ptr v, const uint8_t *s, size_t len) { v->tag = kTAG_UNICODESTRING; v->string = (char *) allocate(len + 1); memcpy(v->string, s, len); v->string[len] = 0; } void value_set_uid(value_ptr v, uint64_t uid) { v->tag = kTAG_UID; v->uinteger = uid; } // v->data points to a pldata that points to the actual bytes // the bytes are copied, so caller must free byte source (*data) void value_set_data(value_ptr v, const uint8_t *data, size_t len) { v->tag = kTAG_DATA; pldata_ptr pldata = (pldata_ptr) allocate(sizeof(pldata_node)); pldata->data = (uint8_t *) allocate(len); memcpy(pldata->data, data, len); pldata->len = len; v->data = pldata; printf("value at %p gets data at %p\n", v, pldata); } // caller releases ownership of array to value_ptr v void value_set_array(value_ptr v, value_ptr *array, size_t length) { array_ptr a = (array_ptr) allocate(sizeof(array_node)); a->array = array; a->length = length; v->tag = kTAG_ARRAY; v->array = a; } // caller releases ownership of dict to value_ptr v void value_set_dict(value_ptr v, dict_ptr dict) { v->tag = kTAG_DICTIONARY; v->dict = dict; } // look up an objectref in the cache, a ref->value_ptr mapping value_ptr cache_lookup(cache_ptr cache, uint64_t ref) { while (cache) { if (cache->key == ref) { return cache->value; } cache = cache->next; } return NULL; } // insert an objectref and value in the cache void cache_insert(cache_ptr *cache, uint64_t ref, value_ptr value) { cache_ptr c = (cache_ptr) allocate(sizeof(cache_node)); c->key = ref; c->value = value; c->next = *cache; *cache = c; } // insert an objectref and value in a dictionary void dict_insert(dict_ptr *dict, value_ptr key, value_ptr value) { dict_ptr d = (dict_ptr) allocate(sizeof(dict_node)); d->key = key; d->value = value; d->next = *dict; *dict = d; } BOOL is_binary_plist(pldata_ptr data) { if (data->len < kMINIMUM_SANE_SIZE) return NO; return memcmp(data->data, kHEADER_BYTES, kHEADER_SIZE) == 0; } value_ptr bplist_read_file(char *filename) { struct stat stbuf; pldata_node pldata; FILE *file; size_t n; value_ptr value; int rslt = stat(filename, &stbuf); if (rslt) { #if BPLIST_LOG perror("in stat"); #endif bplist_log("Could not stat %s, error %d\n", filename, rslt); return NULL; } // if file is >100MB, assume it is not a preferences file and give up if (stbuf.st_size > 100000000) { bplist_log("Large file %s encountered (%llu bytes) -- not read\n", filename, stbuf.st_size); return NULL; } pldata.len = (size_t) stbuf.st_size; // note: this is supposed to be malloc, not allocate. It is separate // from the graph structure, large, and easy to free right after // parsing. pldata.data = (uint8_t *) malloc(pldata.len); if (!pldata.data) { bplist_log("Could not allocate %lu bytes for %s\n", (unsigned long) pldata.len, filename); return NULL; } file = fopen(filename, "rb"); if (!file) { bplist_log("Could not open %s\n", filename); return NULL; } n = fread(pldata.data, 1, pldata.len, file); if (n != pldata.len) { bplist_log("Error reading from %s\n", filename); return NULL; } value = bplist_read_pldata(&pldata); free(pldata.data); return value; } value_ptr bplist_read_pref(char *filename, OSType folder_type) { FSRef prefdir; char cstr[MAXPATHLEN]; OSErr err = FSFindFolder(kOnAppropriateDisk, folder_type, FALSE, &prefdir); if (err) { bplist_log("Error finding preferences folder: %d\n", err); return NULL; } err = FSRefMakePath(&prefdir, (UInt8 *) cstr, (UInt32) (MAXPATHLEN - 1)); if (err) { bplist_log("Error making path name for preferences folder: %d\n", err); return NULL; } strlcat(cstr, "/", MAXPATHLEN); strlcat(cstr, filename, MAXPATHLEN); return bplist_read_file(cstr); } value_ptr bplist_read_system_pref(char *filename) { return bplist_read_pref(filename, kSystemPreferencesFolderType); } value_ptr bplist_read_user_pref(char *filename) { return bplist_read_pref(filename, kPreferencesFolderType); } // data is stored with high-order bytes first. // read from plist data in a machine-independent fashion // uint64_t convert_uint64(uint8_t *ptr) { uint64_t rslt = 0; int i; // shift in bytes, high-order first for (i = 0; i < sizeof(uint64_t); i++) { rslt <<= 8; rslt += ptr[i]; } return rslt; } value_ptr bplist_read_pldata(pldata_ptr data) { value_ptr result = NULL; bplist_info_node bplist; uint8_t *ptr; uint64_t top_level_object; int i; if (data == NULL) return NULL; if (!is_binary_plist(data)) { bplist_log("Bad binary plist: too short or invalid header.\n"); return NULL; } // read trailer ptr = (uint8_t *) (data->data + data->len - kTRAILER_SIZE); bplist.offset_int_size = ptr[6]; bplist.object_ref_size = ptr[7]; bplist.object_count = convert_uint64(ptr + 8); top_level_object = convert_uint64(ptr + 16); bplist.offset_table_offset = convert_uint64(ptr + 24); // Basic sanity checks if (bplist.offset_int_size < 1 || bplist.offset_int_size > 8 || bplist.object_ref_size < 1 || bplist.object_ref_size > 8 || bplist.offset_table_offset < kHEADER_SIZE) { bplist_log("Bad binary plist: trailer declared insane.\n"); return NULL; } // Ensure offset table is inside file uint64_t offsetTableSize = bplist.offset_int_size * bplist.object_count; if (offsetTableSize + bplist.offset_table_offset + kTRAILER_SIZE > data->len) { bplist_log("Bad binary plist: offset table overlaps end of container.\n"); return NULL; } bplist.data_bytes = data->data; bplist.length = data->len; bplist.cache = NULL; /* dictionary is empty */ bplist_log_verbose("Got a sane bplist with %llu items, offset_int_size: %u, object_ref_size: %u\n", bplist.object_count, bplist.offset_int_size, bplist.object_ref_size); /* at this point, we are ready to do some parsing which allocates memory for the result data structure. If memory allocation (using allocate fails, a longjmp will return to here and we simply give up */ i = setjmp(abort_parsing); if (i == 0) { result = extract_object(&bplist, top_level_object); } else { bplist_log("allocate() failed to allocate memory. Giving up.\n"); result = NULL; } if (!result) { bplist_free_data(); } return result; } static value_ptr extract_object(bplist_info_ptr bplist, uint64_t objectRef) { uint64_t offset; value_ptr result = NULL; uint8_t objectTag; if (objectRef >= bplist->object_count) { // Out-of-range object reference. bplist_log("Bad binary plist: object index is out of range.\n"); return NULL; } // Use cached object if it exists result = cache_lookup(bplist->cache, objectRef); if (result != NULL) return result; // Otherwise, find object in file. offset = read_offset(bplist, objectRef); if (offset > bplist->length) { // Out-of-range offset. bplist_log("Bad binary plist: object outside container.\n"); return NULL; } objectTag = *(bplist->data_bytes + offset); switch (objectTag & 0xF0) { case kTAG_SIMPLE: result = extract_simple(bplist, offset); break; case kTAG_INT: result = extract_int(bplist, offset); break; case kTAG_REAL: result = extract_real(bplist, offset); break; case kTAG_DATE: result = extract_date(bplist, offset); break; case kTAG_DATA: result = extract_data(bplist, offset); break; case kTAG_ASCIISTRING: result = extract_ascii_string(bplist, offset); break; case kTAG_UNICODESTRING: result = extract_unicode_string(bplist, offset); break; case kTAG_UID: result = extract_uid(bplist, offset); break; case kTAG_ARRAY: result = extract_array(bplist, offset); break; case kTAG_DICTIONARY: result = extract_dictionary(bplist, offset); break; default: // Unknown tag. bplist_log("Bad binary plist: unknown tag 0x%X.\n", (objectTag & 0x0F) >> 4); result = NULL; } // Cache and return result. if (result != NULL) cache_insert(&bplist->cache, objectRef, result); return result; } static uint64_t read_sized_int(bplist_info_ptr bplist, uint64_t offset, uint8_t size) { assert(bplist->data_bytes != NULL && size >= 1 && size <= 8 && offset + size <= bplist->length); uint64_t result = 0; const uint8_t *byte = bplist->data_bytes + offset; do { // note that ints seem to be high-order first result = (result << 8) | *byte++; } while (--size); return result; } static uint64_t read_offset(bplist_info_ptr bplist, uint64_t index) { assert(index < bplist->object_count); return read_sized_int(bplist, bplist->offset_table_offset + bplist->offset_int_size * index, bplist->offset_int_size); } static BOOL read_self_sized_int(bplist_info_ptr bplist, uint64_t offset, uint64_t *outValue, size_t *outSize) { uint32_t size; int64_t value; assert(bplist->data_bytes != NULL && offset < bplist->length); size = 1 << (bplist->data_bytes[offset] & 0x0F); if (size > 8) { // Maximum allowable size in this implementation is 1<<3 = 8 bytes. // This also happens to be the biggest we can handle. return NO; } if (offset + 1 + size > bplist->length) { // Out of range. return NO; } value = read_sized_int(bplist, offset + 1, size); if (outValue != NULL) *outValue = value; if (outSize != NULL) *outSize = size + 1; // +1 for tag byte. return YES; } static value_ptr extract_simple(bplist_info_ptr bplist, uint64_t offset) { assert(bplist->data_bytes != NULL && offset < bplist->length); value_ptr value = value_create(); switch (bplist->data_bytes[offset]) { case kVALUE_NULL: value->tag = kVALUE_NULL; return value; case kVALUE_TRUE: value->tag = kVALUE_TRUE; return value; case kVALUE_FALSE: value->tag = kVALUE_FALSE; return value; } // Note: kVALUE_FILLER is treated as invalid, because it, er, is. bplist_log("Bad binary plist: invalid atom.\n"); free(value); return NULL; } static value_ptr extract_int(bplist_info_ptr bplist, uint64_t offset) { value_ptr value = value_create(); value->tag = kTAG_INT; if (!read_self_sized_int(bplist, offset, &value->uinteger, NULL)) { bplist_log("Bad binary plist: invalid integer object.\n"); } /* NOTE: originally, I sign-extended here. This was the wrong thing; it turns out that negative ints are always stored as 64-bit, and smaller ints are unsigned. */ return value; } static value_ptr extract_real(bplist_info_ptr bplist, uint64_t offset) { value_ptr value = value_create(); uint32_t size; assert(bplist->data_bytes != NULL && offset < bplist->length); size = 1 << (bplist->data_bytes[offset] & 0x0F); // FIXME: what to do if faced with other sizes for float/double? assert (sizeof (float) == sizeof (uint32_t) && sizeof (double) == sizeof (uint64_t)); if (offset + 1 + size > bplist->length) { bplist_log("Bad binary plist: %s object overlaps end of container.\n", "floating-point number"); free(value); return NULL; } if (size == sizeof (float)) { // cast is ok because we know size is 4 bytes uint32_t i = (uint32_t) read_sized_int(bplist, offset + 1, size); // Note that this handles byte swapping. value_set_real(value, *(float *)&i); return value; } else if (size == sizeof (double)) { uint64_t i = read_sized_int(bplist, offset + 1, size); // Note that this handles byte swapping. value_set_real(value, *(double *)&i); return value; } else { // Can't handle floats of other sizes. bplist_log("Bad binary plist: can't handle %u-byte float.\n", size); free(value); return NULL; } } static value_ptr extract_date(bplist_info_ptr bplist, uint64_t offset) { value_ptr value; assert(bplist->data_bytes != NULL && offset < bplist->length); // Data has size code like int and real, but only 3 (meaning 8 bytes) is valid. if (bplist->data_bytes[offset] != kVALUE_FULLDATETAG) { bplist_log("Bad binary plist: invalid size for date object.\n"); return NULL; } if (offset + 1 + sizeof (double) > bplist->length) { bplist_log("Bad binary plist: %s object overlaps end of container.\n", "date"); return NULL; } // FIXME: what to do if faced with other sizes for double? assert (sizeof (double) == sizeof (uint64_t)); uint64_t date = read_sized_int(bplist, offset + 1, sizeof(double)); // Note that this handles byte swapping. value = value_create(); value_set_date(value, *(double *)&date); return value; } uint64_t bplist_get_a_size(bplist_info_ptr bplist, uint64_t *offset_ptr, char *msg) { uint64_t size = bplist->data_bytes[*offset_ptr] & 0x0F; (*offset_ptr)++; if (size == 0x0F) { // 0x0F means separate int size follows. // Smaller values are used for short data. size_t extra; // the length of the data size we are about to read if ((bplist->data_bytes[*offset_ptr] & 0xF0) != kTAG_INT) { // Bad data, mistagged size int bplist_log("Bad binary plist: %s object size is not tagged as int.\n", msg); return UINT64_MAX; // error } // read integer data as size, extra tells how many bytes to skip if (!read_self_sized_int(bplist, *offset_ptr, &size, &extra)) { bplist_log("Bad binary plist: invalid %s object size tag.\n", "data"); return UINT64_MAX; // error } (*offset_ptr) += extra; } if (*offset_ptr + size > bplist->length) { bplist_log("Bad binary plist: %s object overlaps end of container.\n", "data"); return UINT64_MAX; // error } return size; } static value_ptr extract_data(bplist_info_ptr bplist, uint64_t offset) { uint64_t size; value_ptr value; assert(bplist->data_bytes != NULL && offset < bplist->length); if ((size = bplist_get_a_size(bplist, &offset, "data")) == UINT64_MAX) return NULL; value = value_create(); // cast is ok because we only allow files up to 100MB: value_set_data(value, bplist->data_bytes + (size_t) offset, (size_t) size); return value; } static value_ptr extract_ascii_string(bplist_info_ptr bplist, uint64_t offset) { uint64_t size; value_ptr value; // return value assert(bplist->data_bytes != NULL && offset < bplist->length); if ((size = bplist_get_a_size(bplist, &offset, "ascii string")) == UINT64_MAX) return NULL; value = value_create(); // cast is ok because we only allow 100MB files value_set_ascii_string(value, bplist->data_bytes + (size_t) offset, (size_t) size); return value; } static value_ptr extract_unicode_string(bplist_info_ptr bplist, uint64_t offset) { uint64_t size; value_ptr value; assert(bplist->data_bytes != NULL && offset < bplist->length); if ((size = bplist_get_a_size(bplist, &offset, "unicode string")) == UINT64_MAX) return NULL; value = value_create(); // cast is ok because we only allow 100MB files value_set_unicode_string(value, bplist->data_bytes + (size_t) offset, (size_t) size); return value; } static value_ptr extract_uid(bplist_info_ptr bplist, uint64_t offset) { /* UIDs are used by Cocoa's key-value coder. When writing other plist formats, they are expanded to dictionaries of the form CF$UIDvalue, so we do the same here on reading. This results in plists identical to what running plutil -convert xml1 gives us. However, this is not the same result as [Core]Foundation's plist parser, which extracts them as un- introspectable CF objects. In fact, it even seems to convert the CF$UID dictionaries from XML plists on the fly. */ value_ptr value; uint64_t uid; if (!read_self_sized_int(bplist, offset, &uid, NULL)) { bplist_log("Bad binary plist: invalid UID object.\n"); return NULL; } // assert(NO); // original code suggests using a string for a key // but our dictionaries all use big ints for keys, so I don't know // what to do here // In practice, I believe this code is never executed by PortMidi. // I changed it to do something and not raise compiler warnings, but // not sure what the code should do. value = value_create(); value_set_uid(value, uid); // return [NSDictionary dictionaryWithObject: // [NSNumber numberWithUnsignedLongLong:value] // forKey:"CF$UID"]; return value; } static value_ptr extract_array(bplist_info_ptr bplist, uint64_t offset) { uint64_t i, count; uint64_t size; uint64_t elementID; value_ptr element = NULL; value_ptr *array = NULL; value_ptr value = NULL; BOOL ok = YES; assert(bplist->data_bytes != NULL && offset < bplist->length); if ((count = bplist_get_a_size(bplist, &offset, "array")) == UINT64_MAX) return NULL; if (count > UINT64_MAX / bplist->object_ref_size - offset) { // Offset overflow. bplist_log("Bad binary plist: %s object overlaps end of container.\n", "array"); return NULL; } size = bplist->object_ref_size * count; if (size + offset > bplist->length) { bplist_log("Bad binary plist: %s object overlaps end of container.\n", "array"); return NULL; } // got count, the number of array elements value = value_create(); assert(value); if (count == 0) { // count must be size_t or smaller because max file size is 100MB value_set_array(value, array, (size_t) count); return value; } array = allocate(sizeof(value_ptr) * (size_t) count); for (i = 0; i != count; ++i) { bplist_log_verbose("[%u]\n", i); elementID = read_sized_int(bplist, offset + i * bplist->object_ref_size, bplist->object_ref_size); element = extract_object(bplist, elementID); if (element != NULL) { array[i] = element; } else { ok = NO; break; } } if (ok) { // count is smaller than size_t max because of 100MB file limit value_set_array(value, array, (size_t) count); } return value; } static value_ptr extract_dictionary(bplist_info_ptr bplist, uint64_t offset) { uint64_t i, count; uint64_t size; uint64_t elementID; value_ptr value = NULL; dict_ptr dict = NULL; BOOL ok = YES; assert(bplist->data_bytes != NULL && offset < bplist->length); if ((count = bplist_get_a_size(bplist, &offset, "array")) == UINT64_MAX) return NULL; if (count > UINT64_MAX / (bplist->object_ref_size * 2) - offset) { // Offset overflow. bplist_log("Bad binary plist: %s object overlaps end of container.\n", "dictionary"); return NULL; } size = bplist->object_ref_size * count * 2; if (size + offset > bplist->length) { bplist_log("Bad binary plist: %s object overlaps end of container.\n", "dictionary"); return NULL; } value = value_create(); if (count == 0) { value_set_dict(value, NULL); return value; } for (i = 0; i != count; ++i) { value_ptr key; value_ptr val; elementID = read_sized_int(bplist, offset + i * bplist->object_ref_size, bplist->object_ref_size); key = extract_object(bplist, elementID); if (key != NULL) { bplist_log_verbose("key: %p\n", key); } else { ok = NO; break; } elementID = read_sized_int(bplist, offset + (i + count) * bplist->object_ref_size, bplist->object_ref_size); val = extract_object(bplist, elementID); if (val != NULL) { dict_insert(&dict, key, val); } else { ok = NO; break; } } if (ok) { value_set_dict(value, dict); } return value; } /*************** functions for accessing values ****************/ char *value_get_asciistring(value_ptr v) { if (v->tag != kTAG_ASCIISTRING) return NULL; return v->string; } value_ptr value_dict_lookup_using_string(value_ptr v, char *key) { dict_ptr dict; if (v->tag != kTAG_DICTIONARY) return NULL; // not a dictionary dict = v->dict; /* search for key */ while (dict) { if (dict->key && dict->key->tag == kTAG_ASCIISTRING && strcmp(key, dict->key->string) == 0) { // found it return dict->value; } dict = dict->next; } return NULL; /* not found */ } value_ptr value_dict_lookup_using_path(value_ptr v, char *path) { char key[MAX_KEY_SIZE]; while (*path) { /* more to the path */ int i = 0; while (i < MAX_KEY_SIZE - 1) { key[i] = *path++; if (key[i] == '/') { /* end of entry in path */ key[i + 1] = 0; break; } if (!key[i]) { path--; /* back up to end of string char */ break; /* this will cause outer loop to exit */ } i++; } if (!v || v->tag != kTAG_DICTIONARY) return NULL; /* now, look up the key to get next value */ v = value_dict_lookup_using_string(v, key); if (v == NULL) return NULL; } return v; } /*************** functions for debugging ***************/ void plist_print(value_ptr v) { size_t i; int comma_needed; dict_ptr dict; if (!v) { printf("NULL"); return; } switch (v->tag & 0xF0) { case kTAG_SIMPLE: switch (v->tag) { case kVALUE_NULL: printf("NULL@%p", v); break; case kVALUE_FALSE: printf("FALSE@%p", v); break; case kVALUE_TRUE: printf("TRUE@%p", v); break; default: printf("UNKNOWN tag=%x@%p", v->tag, v); break; } break; case kTAG_INT: printf("%lld@%p", v->integer, v); break; case kTAG_REAL: printf("%g@%p", v->real, v); break; case kTAG_DATE: printf("date:%g@%p", v->real, v); break; case kTAG_DATA: printf("data@%p->%p:[%p:", v, v->data, v->data->data); for (i = 0; i < v->data->len; i++) { printf(" %2x", v->data->data[i]); } printf("]"); break; case kTAG_ASCIISTRING: printf("%p:\"%s\"@%p", v->string, v->string, v); break; case kTAG_UNICODESTRING: printf("unicode:%p:\"%s\"@%p", v->string, v->string, v); break; case kTAG_UID: printf("UID:%llu@%p", v->uinteger, v); break; case kTAG_ARRAY: comma_needed = FALSE; printf("%p->%p:[%p:", v, v->array, v->array->array); for (i = 0; i < v->array->length; i++) { if (comma_needed) printf(", "); plist_print(v->array->array[i]); comma_needed = TRUE; } printf("]"); break; case kTAG_DICTIONARY: comma_needed = FALSE; printf("%p:[", v); dict = v->dict; while (dict) { if (comma_needed) printf(", "); printf("%p:", dict); plist_print(dict->key); printf("->"); plist_print(dict->value); comma_needed = TRUE; dict = dict->next; } printf("]"); break; default: printf("UNKNOWN tag=%x", v->tag); break; } } pd-0.46-7/portmidi/pm_mac/pmmac.h0000775000175000017500000000015612160204055014725 0ustar mspmsp/* pmmac.h */ extern PmDeviceID pm_default_input_device_id; extern PmDeviceID pm_default_output_device_id;pd-0.46-7/portmidi/pm_common/0000775000175000017500000000000012374245151014213 5ustar mspmsppd-0.46-7/portmidi/pm_common/portmidi.c0000775000175000017500000011445012374245151016216 0ustar mspmsp#ifdef _MSC_VER #pragma warning(disable: 4244) // stop warnings about downsize typecasts #pragma warning(disable: 4018) // stop warnings about signed/unsigned #endif #include "stdlib.h" #include "string.h" #include "portmidi.h" #include "porttime.h" #include "pmutil.h" #include "pminternal.h" #include #define MIDI_CLOCK 0xf8 #define MIDI_ACTIVE 0xfe #define MIDI_STATUS_MASK 0x80 #define MIDI_SYSEX 0xf0 #define MIDI_EOX 0xf7 #define MIDI_START 0xFA #define MIDI_STOP 0xFC #define MIDI_CONTINUE 0xFB #define MIDI_F9 0xF9 #define MIDI_FD 0xFD #define MIDI_RESET 0xFF #define MIDI_NOTE_ON 0x90 #define MIDI_NOTE_OFF 0x80 #define MIDI_CHANNEL_AT 0xD0 #define MIDI_POLY_AT 0xA0 #define MIDI_PROGRAM 0xC0 #define MIDI_CONTROL 0xB0 #define MIDI_PITCHBEND 0xE0 #define MIDI_MTC 0xF1 #define MIDI_SONGPOS 0xF2 #define MIDI_SONGSEL 0xF3 #define MIDI_TUNE 0xF6 #define is_empty(midi) ((midi)->tail == (midi)->head) /* this is not static so that pm_init can set it directly if * (see pmmac.c:pm_init()) */ int pm_initialized = FALSE; int pm_hosterror; char pm_hosterror_text[PM_HOST_ERROR_MSG_LEN]; #ifdef PM_CHECK_ERRORS #include #define STRING_MAX 80 static void prompt_and_exit(void) { char line[STRING_MAX]; printf("type ENTER..."); fgets(line, STRING_MAX, stdin); /* this will clean up open ports: */ exit(-1); } static PmError pm_errmsg(PmError err) { if (err == pmHostError) { /* it seems pointless to allocate memory and copy the string, * so I will do the work of Pm_GetHostErrorText directly */ printf("PortMidi found host error...\n %s\n", pm_hosterror_text); pm_hosterror = FALSE; pm_hosterror_text[0] = 0; /* clear the message */ prompt_and_exit(); } else if (err < 0) { printf("PortMidi call failed...\n %s\n", Pm_GetErrorText(err)); prompt_and_exit(); } return err; } #else #define pm_errmsg(err) err #endif /* ==================================================================== system implementation of portmidi interface ==================================================================== */ int pm_descriptor_max = 0; int pm_descriptor_index = 0; descriptor_type descriptors = NULL; /* pm_add_device -- describe interface/device pair to library * * This is called at intialization time, once for each * interface (e.g. DirectSound) and device (e.g. SoundBlaster 1) * The strings are retained but NOT COPIED, so do not destroy them! * * returns pmInvalidDeviceId if device memory is exceeded * otherwise returns pmNoError */ PmError pm_add_device(char *interf, char *name, int input, void *descriptor, pm_fns_type dictionary) { if (pm_descriptor_index >= pm_descriptor_max) { // expand descriptors descriptor_type new_descriptors = (descriptor_type) pm_alloc(sizeof(descriptor_node) * (pm_descriptor_max + 32)); if (!new_descriptors) return pmInsufficientMemory; if (descriptors) { memcpy(new_descriptors, descriptors, sizeof(descriptor_node) * pm_descriptor_max); free(descriptors); } pm_descriptor_max += 32; descriptors = new_descriptors; } descriptors[pm_descriptor_index].pub.interf = interf; descriptors[pm_descriptor_index].pub.name = name; descriptors[pm_descriptor_index].pub.input = input; descriptors[pm_descriptor_index].pub.output = !input; /* default state: nothing to close (for automatic device closing) */ descriptors[pm_descriptor_index].pub.opened = FALSE; /* ID number passed to win32 multimedia API open */ descriptors[pm_descriptor_index].descriptor = descriptor; /* points to PmInternal, allows automatic device closing */ descriptors[pm_descriptor_index].internalDescriptor = NULL; descriptors[pm_descriptor_index].dictionary = dictionary; pm_descriptor_index++; return pmNoError; } /* utility to look up device, given a pattern, note: pattern is modified */ int pm_find_default_device(char *pattern, int is_input) { int id = pmNoDevice; int i; /* first parse pattern into name, interf parts */ char *interf_pref = ""; /* initially assume it is not there */ char *name_pref = strstr(pattern, ", "); if (name_pref) { /* found separator, adjust the pointer */ interf_pref = pattern; name_pref[0] = 0; name_pref += 2; } else { name_pref = pattern; /* whole string is the name pattern */ } for (i = 0; i < pm_descriptor_index; i++) { const PmDeviceInfo *info = Pm_GetDeviceInfo(i); if (info->input == is_input && strstr(info->name, name_pref) && strstr(info->interf, interf_pref)) { id = i; break; } } return id; } /* ==================================================================== portmidi implementation ==================================================================== */ PMEXPORT int Pm_CountDevices( void ) { Pm_Initialize(); /* no error checking -- Pm_Initialize() does not fail */ return pm_descriptor_index; } PMEXPORT const PmDeviceInfo* Pm_GetDeviceInfo( PmDeviceID id ) { Pm_Initialize(); /* no error check needed */ if (id >= 0 && id < pm_descriptor_index) { return &descriptors[id].pub; } return NULL; } /* pm_success_fn -- "noop" function pointer */ PmError pm_success_fn(PmInternal *midi) { return pmNoError; } /* none_write -- returns an error if called */ PmError none_write_short(PmInternal *midi, PmEvent *buffer) { return pmBadPtr; } /* pm_fail_timestamp_fn -- placeholder for begin_sysex and flush */ PmError pm_fail_timestamp_fn(PmInternal *midi, PmTimestamp timestamp) { return pmBadPtr; } PmError none_write_byte(PmInternal *midi, unsigned char byte, PmTimestamp timestamp) { return pmBadPtr; } /* pm_fail_fn -- generic function, returns error if called */ PmError pm_fail_fn(PmInternal *midi) { return pmBadPtr; } static PmError none_open(PmInternal *midi, void *driverInfo) { return pmBadPtr; } static void none_get_host_error(PmInternal * midi, char * msg, unsigned int len) { *msg = 0; // empty string } static unsigned int none_has_host_error(PmInternal * midi) { return FALSE; } PmTimestamp none_synchronize(PmInternal *midi) { return 0; } #define none_abort pm_fail_fn #define none_close pm_fail_fn pm_fns_node pm_none_dictionary = { none_write_short, none_sysex, none_sysex, none_write_byte, none_write_short, none_write_flush, none_synchronize, none_open, none_abort, none_close, none_poll, none_has_host_error, none_get_host_error }; PMEXPORT const char *Pm_GetErrorText( PmError errnum ) { const char *msg; switch(errnum) { case pmNoError: msg = ""; break; case pmHostError: msg = "PortMidi: `Host error'"; break; case pmInvalidDeviceId: msg = "PortMidi: `Invalid device ID'"; break; case pmInsufficientMemory: msg = "PortMidi: `Insufficient memory'"; break; case pmBufferTooSmall: msg = "PortMidi: `Buffer too small'"; break; case pmBadPtr: msg = "PortMidi: `Bad pointer'"; break; case pmInternalError: msg = "PortMidi: `Internal PortMidi Error'"; break; case pmBufferOverflow: msg = "PortMidi: `Buffer overflow'"; break; case pmBadData: msg = "PortMidi: `Invalid MIDI message Data'"; break; case pmBufferMaxSize: msg = "PortMidi: `Buffer cannot be made larger'"; break; default: msg = "PortMidi: `Illegal error number'"; break; } return msg; } /* This can be called whenever you get a pmHostError return value. * The error will always be in the global pm_hosterror_text. */ PMEXPORT void Pm_GetHostErrorText(char * msg, unsigned int len) { assert(msg); assert(len > 0); if (pm_hosterror) { strncpy(msg, (char *) pm_hosterror_text, len); pm_hosterror = FALSE; pm_hosterror_text[0] = 0; /* clear the message; not necessary, but it might help with debugging */ msg[len - 1] = 0; /* make sure string is terminated */ } else { msg[0] = 0; /* no string to return */ } } PMEXPORT int Pm_HasHostError(PortMidiStream * stream) { if (pm_hosterror) return TRUE; if (stream) { PmInternal * midi = (PmInternal *) stream; pm_hosterror = (*midi->dictionary->has_host_error)(midi); if (pm_hosterror) { midi->dictionary->host_error(midi, pm_hosterror_text, PM_HOST_ERROR_MSG_LEN); /* now error message is global */ return TRUE; } } return FALSE; } PMEXPORT PmError Pm_Initialize( void ) { if (!pm_initialized) { pm_hosterror = FALSE; pm_hosterror_text[0] = 0; /* the null string */ pm_init(); pm_initialized = TRUE; } return pmNoError; } PMEXPORT PmError Pm_Terminate( void ) { if (pm_initialized) { pm_term(); // if there are no devices, descriptors might still be NULL if (descriptors != NULL) { free(descriptors); descriptors = NULL; } pm_descriptor_index = 0; pm_descriptor_max = 0; pm_initialized = FALSE; } return pmNoError; } /* Pm_Read -- read up to length messages from source into buffer */ /* * returns number of messages actually read, or error code */ PMEXPORT int Pm_Read(PortMidiStream *stream, PmEvent *buffer, int32_t length) { PmInternal *midi = (PmInternal *) stream; int n = 0; PmError err = pmNoError; pm_hosterror = FALSE; /* arg checking */ if(midi == NULL) err = pmBadPtr; else if(!descriptors[midi->device_id].pub.opened) err = pmBadPtr; else if(!descriptors[midi->device_id].pub.input) err = pmBadPtr; /* First poll for data in the buffer... * This either simply checks for data, or attempts first to fill the buffer * with data from the MIDI hardware; this depends on the implementation. * We could call Pm_Poll here, but that would redo a lot of redundant * parameter checking, so I copied some code from Pm_Poll to here: */ else err = (*(midi->dictionary->poll))(midi); if (err != pmNoError) { if (err == pmHostError) { midi->dictionary->host_error(midi, pm_hosterror_text, PM_HOST_ERROR_MSG_LEN); pm_hosterror = TRUE; } return pm_errmsg(err); } while (n < length) { PmError err = Pm_Dequeue(midi->queue, buffer++); if (err == pmBufferOverflow) { /* ignore the data we have retreived so far */ return pm_errmsg(pmBufferOverflow); } else if (err == 0) { /* empty queue */ break; } n++; } return n; } PMEXPORT PmError Pm_Poll( PortMidiStream *stream ) { PmInternal *midi = (PmInternal *) stream; PmError err; pm_hosterror = FALSE; /* arg checking */ if(midi == NULL) err = pmBadPtr; else if (!descriptors[midi->device_id].pub.opened) err = pmBadPtr; else if (!descriptors[midi->device_id].pub.input) err = pmBadPtr; else err = (*(midi->dictionary->poll))(midi); if (err != pmNoError) { if (err == pmHostError) { midi->dictionary->host_error(midi, pm_hosterror_text, PM_HOST_ERROR_MSG_LEN); pm_hosterror = TRUE; } return pm_errmsg(err); } return !Pm_QueueEmpty(midi->queue); } /* this is called from Pm_Write and Pm_WriteSysEx to issue a * call to the system-dependent end_sysex function and handle * the error return */ static PmError pm_end_sysex(PmInternal *midi) { PmError err = (*midi->dictionary->end_sysex)(midi, 0); midi->sysex_in_progress = FALSE; if (err == pmHostError) { midi->dictionary->host_error(midi, pm_hosterror_text, PM_HOST_ERROR_MSG_LEN); pm_hosterror = TRUE; } return err; } /* to facilitate correct error-handling, Pm_Write, Pm_WriteShort, and Pm_WriteSysEx all operate a state machine that "outputs" calls to write_short, begin_sysex, write_byte, end_sysex, and write_realtime */ PMEXPORT PmError Pm_Write( PortMidiStream *stream, PmEvent *buffer, int32_t length) { PmInternal *midi = (PmInternal *) stream; PmError err = pmNoError; int i; int bits; pm_hosterror = FALSE; /* arg checking */ if(midi == NULL) err = pmBadPtr; else if(!descriptors[midi->device_id].pub.opened) err = pmBadPtr; else if(!descriptors[midi->device_id].pub.output) err = pmBadPtr; else err = pmNoError; if (err != pmNoError) goto pm_write_error; if (midi->latency == 0) { midi->now = 0; } else { midi->now = (*(midi->time_proc))(midi->time_info); if (midi->first_message || midi->sync_time + 100 /*ms*/ < midi->now) { /* time to resync */ midi->now = (*midi->dictionary->synchronize)(midi); midi->first_message = FALSE; } } /* error recovery: when a sysex is detected, we call * dictionary->begin_sysex() followed by calls to * dictionary->write_byte() and dictionary->write_realtime() * until an end-of-sysex is detected, when we call * dictionary->end_sysex(). After an error occurs, * Pm_Write() continues to call functions. For example, * it will continue to call write_byte() even after * an error sending a sysex message, and end_sysex() will be * called when an EOX or non-real-time status is found. * When errors are detected, Pm_Write() returns immediately, * so it is possible that this will drop data and leave * sysex messages in a partially transmitted state. */ for (i = 0; i < length; i++) { uint32_t msg = buffer[i].message; bits = 0; /* is this a sysex message? */ if (Pm_MessageStatus(msg) == MIDI_SYSEX) { if (midi->sysex_in_progress) { /* error: previous sysex was not terminated by EOX */ midi->sysex_in_progress = FALSE; err = pmBadData; goto pm_write_error; } midi->sysex_in_progress = TRUE; if ((err = (*midi->dictionary->begin_sysex)(midi, buffer[i].timestamp)) != pmNoError) goto pm_write_error; if ((err = (*midi->dictionary->write_byte)(midi, MIDI_SYSEX, buffer[i].timestamp)) != pmNoError) goto pm_write_error; bits = 8; /* fall through to continue sysex processing */ } else if ((msg & MIDI_STATUS_MASK) && (Pm_MessageStatus(msg) != MIDI_EOX)) { /* a non-sysex message */ if (midi->sysex_in_progress) { /* this should be a realtime message */ if (is_real_time(msg)) { if ((err = (*midi->dictionary->write_realtime)(midi, &(buffer[i]))) != pmNoError) goto pm_write_error; } else { midi->sysex_in_progress = FALSE; err = pmBadData; /* ignore any error from this, because we already have one */ /* pass 0 as timestamp -- it's ignored */ (*midi->dictionary->end_sysex)(midi, 0); goto pm_write_error; } } else { /* regular short midi message */ if ((err = (*midi->dictionary->write_short)(midi, &(buffer[i]))) != pmNoError) goto pm_write_error; continue; } } if (midi->sysex_in_progress) { /* send sysex bytes until EOX */ /* see if we can accelerate data transfer */ if (bits == 0 && midi->fill_base && /* 4 bytes to copy */ (*midi->fill_offset_ptr) + 4 <= midi->fill_length && (msg & 0x80808080) == 0) { /* all data */ /* copy 4 bytes from msg to fill_base + fill_offset */ unsigned char *ptr = midi->fill_base + *(midi->fill_offset_ptr); ptr[0] = msg; ptr[1] = msg >> 8; ptr[2] = msg >> 16; ptr[3] = msg >> 24; (*midi->fill_offset_ptr) += 4; continue; } /* no acceleration, so do byte-by-byte copying */ while (bits < 32) { unsigned char midi_byte = (unsigned char) (msg >> bits); if ((err = (*midi->dictionary->write_byte)(midi, midi_byte, buffer[i].timestamp)) != pmNoError) goto pm_write_error; if (midi_byte == MIDI_EOX) { err = pm_end_sysex(midi); if (err != pmNoError) goto error_exit; break; /* from while loop */ } bits += 8; } } else { /* not in sysex mode, but message did not start with status */ err = pmBadData; goto pm_write_error; } } /* after all messages are processed, send the data */ if (!midi->sysex_in_progress) err = (*midi->dictionary->write_flush)(midi, 0); pm_write_error: if (err == pmHostError) { midi->dictionary->host_error(midi, pm_hosterror_text, PM_HOST_ERROR_MSG_LEN); pm_hosterror = TRUE; } error_exit: return pm_errmsg(err); } PMEXPORT PmError Pm_WriteShort(PortMidiStream *stream, PmTimestamp when, PmMessage msg) { PmEvent event; event.timestamp = when; event.message = msg; return Pm_Write(stream, &event, 1); } PMEXPORT PmError Pm_WriteSysEx(PortMidiStream *stream, PmTimestamp when, unsigned char *msg) { /* allocate buffer space for PM_DEFAULT_SYSEX_BUFFER_SIZE bytes */ /* each PmEvent holds sizeof(PmMessage) bytes of sysex data */ #define BUFLEN ((int) (PM_DEFAULT_SYSEX_BUFFER_SIZE / sizeof(PmMessage))) PmEvent buffer[BUFLEN]; int buffer_size = 1; /* first time, send 1. After that, it's BUFLEN */ PmInternal *midi = (PmInternal *) stream; /* the next byte in the buffer is represented by an index, bufx, and a shift in bits */ int shift = 0; int bufx = 0; buffer[0].message = 0; buffer[0].timestamp = when; while (1) { /* insert next byte into buffer */ buffer[bufx].message |= ((*msg) << shift); shift += 8; if (*msg++ == MIDI_EOX) break; if (shift == 32) { shift = 0; bufx++; if (bufx == buffer_size) { PmError err = Pm_Write(stream, buffer, buffer_size); /* note: Pm_Write has already called errmsg() */ if (err) return err; /* prepare to fill another buffer */ bufx = 0; buffer_size = BUFLEN; /* optimization: maybe we can just copy bytes */ if (midi->fill_base) { PmError err; while (*(midi->fill_offset_ptr) < midi->fill_length) { midi->fill_base[(*midi->fill_offset_ptr)++] = *msg; if (*msg++ == MIDI_EOX) { err = pm_end_sysex(midi); if (err != pmNoError) return pm_errmsg(err); goto end_of_sysex; } } /* I thought that I could do a pm_Write here and * change this if to a loop, avoiding calls in Pm_Write * to the slower write_byte, but since * sysex_in_progress is true, this will not flush * the buffer, and we'll infinite loop: */ /* err = Pm_Write(stream, buffer, 0); if (err) return err; */ /* instead, the way this works is that Pm_Write calls * write_byte on 4 bytes. The first, since the buffer * is full, will flush the buffer and allocate a new * one. This primes the buffer so * that we can return to the loop above and fill it * efficiently without a lot of function calls. */ buffer_size = 1; /* get another message started */ } } buffer[bufx].message = 0; buffer[bufx].timestamp = when; } /* keep inserting bytes until you find MIDI_EOX */ } end_of_sysex: /* we're finished sending full buffers, but there may * be a partial one left. */ if (shift != 0) bufx++; /* add partial message to buffer len */ if (bufx) { /* bufx is number of PmEvents to send from buffer */ PmError err = Pm_Write(stream, buffer, bufx); if (err) return err; } return pmNoError; } PMEXPORT PmError Pm_OpenInput(PortMidiStream** stream, PmDeviceID inputDevice, void *inputDriverInfo, int32_t bufferSize, PmTimeProcPtr time_proc, void *time_info) { PmInternal *midi; PmError err = pmNoError; pm_hosterror = FALSE; *stream = NULL; /* arg checking */ if (inputDevice < 0 || inputDevice >= pm_descriptor_index) err = pmInvalidDeviceId; else if (!descriptors[inputDevice].pub.input) err = pmInvalidDeviceId; else if(descriptors[inputDevice].pub.opened) err = pmInvalidDeviceId; if (err != pmNoError) goto error_return; /* create portMidi internal data */ midi = (PmInternal *) pm_alloc(sizeof(PmInternal)); *stream = midi; if (!midi) { err = pmInsufficientMemory; goto error_return; } midi->device_id = inputDevice; midi->write_flag = FALSE; midi->time_proc = time_proc; midi->time_info = time_info; /* windows adds timestamps in the driver and these are more accurate than using a time_proc, so do not automatically provide a time proc. Non-win implementations may want to provide a default time_proc in their system-specific midi_out_open() method. */ if (bufferSize <= 0) bufferSize = 256; /* default buffer size */ midi->queue = Pm_QueueCreate(bufferSize, (int32_t) sizeof(PmEvent)); if (!midi->queue) { /* free portMidi data */ *stream = NULL; pm_free(midi); err = pmInsufficientMemory; goto error_return; } midi->buffer_len = bufferSize; /* portMidi input storage */ midi->latency = 0; /* not used */ midi->sysex_in_progress = FALSE; midi->sysex_message = 0; midi->sysex_message_count = 0; midi->filters = PM_FILT_ACTIVE; midi->channel_mask = 0xFFFF; midi->sync_time = 0; midi->first_message = TRUE; midi->dictionary = descriptors[inputDevice].dictionary; midi->fill_base = NULL; midi->fill_offset_ptr = NULL; midi->fill_length = 0; descriptors[inputDevice].internalDescriptor = midi; /* open system dependent input device */ err = (*midi->dictionary->open)(midi, inputDriverInfo); if (err) { *stream = NULL; descriptors[inputDevice].internalDescriptor = NULL; /* free portMidi data */ Pm_QueueDestroy(midi->queue); pm_free(midi); } else { /* portMidi input open successful */ descriptors[inputDevice].pub.opened = TRUE; } error_return: /* note: if there is a pmHostError, it is the responsibility * of the system-dependent code (*midi->dictionary->open)() * to set pm_hosterror and pm_hosterror_text */ return pm_errmsg(err); } PMEXPORT PmError Pm_OpenOutput(PortMidiStream** stream, PmDeviceID outputDevice, void *outputDriverInfo, int32_t bufferSize, PmTimeProcPtr time_proc, void *time_info, int32_t latency ) { PmInternal *midi; PmError err = pmNoError; pm_hosterror = FALSE; *stream = NULL; /* arg checking */ if (outputDevice < 0 || outputDevice >= pm_descriptor_index) err = pmInvalidDeviceId; else if (!descriptors[outputDevice].pub.output) err = pmInvalidDeviceId; else if (descriptors[outputDevice].pub.opened) err = pmInvalidDeviceId; if (err != pmNoError) goto error_return; /* create portMidi internal data */ midi = (PmInternal *) pm_alloc(sizeof(PmInternal)); *stream = midi; if (!midi) { err = pmInsufficientMemory; goto error_return; } midi->device_id = outputDevice; midi->write_flag = TRUE; midi->time_proc = time_proc; /* if latency > 0, we need a time reference. If none is provided, use PortTime library */ if (time_proc == NULL && latency != 0) { if (!Pt_Started()) Pt_Start(1, 0, 0); /* time_get does not take a parameter, so coerce */ midi->time_proc = (PmTimeProcPtr) Pt_Time; } midi->time_info = time_info; midi->buffer_len = bufferSize; midi->queue = NULL; /* unused by output */ /* if latency zero, output immediate (timestamps ignored) */ /* if latency < 0, use 0 but don't return an error */ if (latency < 0) latency = 0; midi->latency = latency; midi->sysex_in_progress = FALSE; midi->sysex_message = 0; /* unused by output */ midi->sysex_message_count = 0; /* unused by output */ midi->filters = 0; /* not used for output */ midi->channel_mask = 0xFFFF; midi->sync_time = 0; midi->first_message = TRUE; midi->dictionary = descriptors[outputDevice].dictionary; midi->fill_base = NULL; midi->fill_offset_ptr = NULL; midi->fill_length = 0; descriptors[outputDevice].internalDescriptor = midi; /* open system dependent output device */ err = (*midi->dictionary->open)(midi, outputDriverInfo); if (err) { *stream = NULL; descriptors[outputDevice].internalDescriptor = NULL; /* free portMidi data */ pm_free(midi); } else { /* portMidi input open successful */ descriptors[outputDevice].pub.opened = TRUE; } error_return: /* note: system-dependent code must set pm_hosterror and * pm_hosterror_text if a pmHostError occurs */ return pm_errmsg(err); } PMEXPORT PmError Pm_SetChannelMask(PortMidiStream *stream, int mask) { PmInternal *midi = (PmInternal *) stream; PmError err = pmNoError; if (midi == NULL) err = pmBadPtr; else midi->channel_mask = mask; return pm_errmsg(err); } PMEXPORT PmError Pm_SetFilter(PortMidiStream *stream, int32_t filters) { PmInternal *midi = (PmInternal *) stream; PmError err = pmNoError; /* arg checking */ if (midi == NULL) err = pmBadPtr; else if (!descriptors[midi->device_id].pub.opened) err = pmBadPtr; else midi->filters = filters; return pm_errmsg(err); } PMEXPORT PmError Pm_Close( PortMidiStream *stream ) { PmInternal *midi = (PmInternal *) stream; PmError err = pmNoError; pm_hosterror = FALSE; /* arg checking */ if (midi == NULL) /* midi must point to something */ err = pmBadPtr; /* if it is an open device, the device_id will be valid */ else if (midi->device_id < 0 || midi->device_id >= pm_descriptor_index) err = pmBadPtr; /* and the device should be in the opened state */ else if (!descriptors[midi->device_id].pub.opened) err = pmBadPtr; if (err != pmNoError) goto error_return; /* close the device */ err = (*midi->dictionary->close)(midi); /* even if an error occurred, continue with cleanup */ descriptors[midi->device_id].internalDescriptor = NULL; descriptors[midi->device_id].pub.opened = FALSE; if (midi->queue) Pm_QueueDestroy(midi->queue); pm_free(midi); error_return: /* system dependent code must set pm_hosterror and * pm_hosterror_text if a pmHostError occurs. */ return pm_errmsg(err); } PmError Pm_Synchronize( PortMidiStream* stream ) { PmInternal *midi = (PmInternal *) stream; PmError err = pmNoError; if (midi == NULL) err = pmBadPtr; else if (!descriptors[midi->device_id].pub.output) err = pmBadPtr; else if (!descriptors[midi->device_id].pub.opened) err = pmBadPtr; else midi->first_message = TRUE; return err; } PMEXPORT PmError Pm_Abort( PortMidiStream* stream ) { PmInternal *midi = (PmInternal *) stream; PmError err; /* arg checking */ if (midi == NULL) err = pmBadPtr; else if (!descriptors[midi->device_id].pub.output) err = pmBadPtr; else if (!descriptors[midi->device_id].pub.opened) err = pmBadPtr; else err = (*midi->dictionary->abort)(midi); if (err == pmHostError) { midi->dictionary->host_error(midi, pm_hosterror_text, PM_HOST_ERROR_MSG_LEN); pm_hosterror = TRUE; } return pm_errmsg(err); } /* pm_channel_filtered returns non-zero if the channel mask is blocking the current channel */ #define pm_channel_filtered(status, mask) \ ((((status) & 0xF0) != 0xF0) && (!(Pm_Channel((status) & 0x0F) & (mask)))) /* The following two functions will checks to see if a MIDI message matches the filtering criteria. Since the sysex routines only want to filter realtime messages, we need to have separate routines. */ /* pm_realtime_filtered returns non-zero if the filter will kill the current message. Note that only realtime messages are checked here. */ #define pm_realtime_filtered(status, filters) \ ((((status) & 0xF0) == 0xF0) && ((1 << ((status) & 0xF)) & (filters))) /* return ((status == MIDI_ACTIVE) && (filters & PM_FILT_ACTIVE)) || ((status == MIDI_CLOCK) && (filters & PM_FILT_CLOCK)) || ((status == MIDI_START) && (filters & PM_FILT_PLAY)) || ((status == MIDI_STOP) && (filters & PM_FILT_PLAY)) || ((status == MIDI_CONTINUE) && (filters & PM_FILT_PLAY)) || ((status == MIDI_F9) && (filters & PM_FILT_F9)) || ((status == MIDI_FD) && (filters & PM_FILT_FD)) || ((status == MIDI_RESET) && (filters & PM_FILT_RESET)) || ((status == MIDI_MTC) && (filters & PM_FILT_MTC)) || ((status == MIDI_SONGPOS) && (filters & PM_FILT_SONG_POSITION)) || ((status == MIDI_SONGSEL) && (filters & PM_FILT_SONG_SELECT)) || ((status == MIDI_TUNE) && (filters & PM_FILT_TUNE)); }*/ /* pm_status_filtered returns non-zero if a filter will kill the current message, based on status. Note that sysex and real time are not checked. It is up to the subsystem (winmm, core midi, alsa) to filter sysex, as it is handled more easily and efficiently at that level. Realtime message are filtered in pm_realtime_filtered. */ #define pm_status_filtered(status, filters) ((1 << (16 + ((status) >> 4))) & (filters)) /* return ((status == MIDI_NOTE_ON) && (filters & PM_FILT_NOTE)) || ((status == MIDI_NOTE_OFF) && (filters & PM_FILT_NOTE)) || ((status == MIDI_CHANNEL_AT) && (filters & PM_FILT_CHANNEL_AFTERTOUCH)) || ((status == MIDI_POLY_AT) && (filters & PM_FILT_POLY_AFTERTOUCH)) || ((status == MIDI_PROGRAM) && (filters & PM_FILT_PROGRAM)) || ((status == MIDI_CONTROL) && (filters & PM_FILT_CONTROL)) || ((status == MIDI_PITCHBEND) && (filters & PM_FILT_PITCHBEND)); } */ static void pm_flush_sysex(PmInternal *midi, PmTimestamp timestamp) { PmEvent event; /* there may be nothing in the buffer */ if (midi->sysex_message_count == 0) return; /* nothing to flush */ event.message = midi->sysex_message; event.timestamp = timestamp; /* copied from pm_read_short, avoids filtering */ if (Pm_Enqueue(midi->queue, &event) == pmBufferOverflow) { midi->sysex_in_progress = FALSE; } midi->sysex_message_count = 0; midi->sysex_message = 0; } /* pm_read_short and pm_read_bytes are the interface between system-dependent MIDI input handlers and the system-independent PortMIDI code. The input handler MUST obey these rules: 1) all short input messages must be sent to pm_read_short, which enqueues them to a FIFO for the application. 2) each buffer of sysex bytes should be reported by calling pm_read_bytes (which sets midi->sysex_in_progress). After the eox byte, pm_read_bytes will clear sysex_in_progress */ /* pm_read_short is the place where all input messages arrive from system-dependent code such as pmwinmm.c. Here, the messages are entered into the PortMidi input buffer. */ void pm_read_short(PmInternal *midi, PmEvent *event) { int status; /* arg checking */ assert(midi != NULL); /* midi filtering is applied here */ status = Pm_MessageStatus(event->message); if (!pm_status_filtered(status, midi->filters) && (!is_real_time(status) || !pm_realtime_filtered(status, midi->filters)) && !pm_channel_filtered(status, midi->channel_mask)) { /* if sysex is in progress and we get a status byte, it had better be a realtime message or the starting SYSEX byte; otherwise, we exit the sysex_in_progress state */ if (midi->sysex_in_progress && (status & MIDI_STATUS_MASK)) { /* two choices: real-time or not. If it's real-time, then * this should be delivered as a sysex byte because it is * embedded in a sysex message */ if (is_real_time(status)) { midi->sysex_message |= (status << (8 * midi->sysex_message_count++)); if (midi->sysex_message_count == 4) { pm_flush_sysex(midi, event->timestamp); } } else { /* otherwise, it's not real-time. This interrupts * a sysex message in progress */ midi->sysex_in_progress = FALSE; } } else if (Pm_Enqueue(midi->queue, event) == pmBufferOverflow) { midi->sysex_in_progress = FALSE; } } } /* pm_read_bytes -- read one (partial) sysex msg from MIDI data */ /* * returns how many bytes processed */ unsigned int pm_read_bytes(PmInternal *midi, const unsigned char *data, int len, PmTimestamp timestamp) { int i = 0; /* index into data, must not be unsigned (!) */ PmEvent event; event.timestamp = timestamp; assert(midi); /* note that since buffers may not have multiples of 4 bytes, * pm_read_bytes may be called in the middle of an outgoing * 4-byte PortMidi message. sysex_in_progress indicates that * a sysex has been sent but no eox. */ if (len == 0) return 0; /* sanity check */ if (!midi->sysex_in_progress) { while (i < len) { /* process all data */ unsigned char byte = data[i++]; if (byte == MIDI_SYSEX && !pm_realtime_filtered(byte, midi->filters)) { midi->sysex_in_progress = TRUE; i--; /* back up so code below will get SYSEX byte */ break; /* continue looping below to process msg */ } else if (byte == MIDI_EOX) { midi->sysex_in_progress = FALSE; return i; /* done with one message */ } else if (byte & MIDI_STATUS_MASK) { /* We're getting MIDI but no sysex in progress. * Either the SYSEX status byte was dropped or * the message was filtered. Drop the data, but * send any embedded realtime bytes. */ /* assume that this is a real-time message: * it is an error to pass non-real-time messages * to pm_read_bytes */ event.message = byte; pm_read_short(midi, &event); } } /* all bytes in the buffer are processed */ } /* Now, isysex_in_progress) { if (midi->sysex_message_count == 0 && i <= len - 4 && ((event.message = (((PmMessage) data[i]) | (((PmMessage) data[i+1]) << 8) | (((PmMessage) data[i+2]) << 16) | (((PmMessage) data[i+3]) << 24))) & 0x80808080) == 0) { /* all data, no status */ if (Pm_Enqueue(midi->queue, &event) == pmBufferOverflow) { midi->sysex_in_progress = FALSE; } i += 4; } else { while (i < len) { /* send one byte at a time */ unsigned char byte = data[i++]; if (is_real_time(byte) && pm_realtime_filtered(byte, midi->filters)) { continue; /* real-time data is filtered, so omit */ } midi->sysex_message |= (byte << (8 * midi->sysex_message_count++)); if (byte == MIDI_EOX) { midi->sysex_in_progress = FALSE; pm_flush_sysex(midi, event.timestamp); return i; } else if (midi->sysex_message_count == 4) { pm_flush_sysex(midi, event.timestamp); /* after handling at least one non-data byte * and reaching a 4-byte message boundary, * resume trying to send 4 at a time in outer loop */ break; } } } } return i; } pd-0.46-7/portmidi/pm_common/portmidi.h0000775000175000017500000006740512374245151016232 0ustar mspmsp#ifndef PORT_MIDI_H #define PORT_MIDI_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* * PortMidi Portable Real-Time MIDI Library * PortMidi API Header File * Latest version available at: http://sourceforge.net/projects/portmedia * * Copyright (c) 1999-2000 Ross Bencina and Phil Burk * Copyright (c) 2001-2006 Roger B. Dannenberg * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortMidi license; however, * the PortMusic community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /* CHANGELOG FOR PORTMIDI * (see ../CHANGELOG.txt) * * NOTES ON HOST ERROR REPORTING: * * PortMidi errors (of type PmError) are generic, system-independent errors. * When an error does not map to one of the more specific PmErrors, the * catch-all code pmHostError is returned. This means that PortMidi has * retained a more specific system-dependent error code. The caller can * get more information by calling Pm_HasHostError() to test if there is * a pending host error, and Pm_GetHostErrorText() to get a text string * describing the error. Host errors are reported on a per-device basis * because only after you open a device does PortMidi have a place to * record the host error code. I.e. only * those routines that receive a (PortMidiStream *) argument check and * report errors. One exception to this is that Pm_OpenInput() and * Pm_OpenOutput() can report errors even though when an error occurs, * there is no PortMidiStream* to hold the error. Fortunately, both * of these functions return any error immediately, so we do not really * need per-device error memory. Instead, any host error code is stored * in a global, pmHostError is returned, and the user can call * Pm_GetHostErrorText() to get the error message (and the invalid stream * parameter will be ignored.) The functions * pm_init and pm_term do not fail or raise * errors. The job of pm_init is to locate all available devices so that * the caller can get information via PmDeviceInfo(). If an error occurs, * the device is simply not listed as available. * * Host errors come in two flavors: * a) host error * b) host error during callback * These can occur w/midi input or output devices. (b) can only happen * asynchronously (during callback routines), whereas (a) only occurs while * synchronously running PortMidi and any resulting system dependent calls. * Both (a) and (b) are reported by the next read or write call. You can * also query for asynchronous errors (b) at any time by calling * Pm_HasHostError(). * * NOTES ON COMPILE-TIME SWITCHES * * DEBUG assumes stdio and a console. Use this if you want automatic, simple * error reporting, e.g. for prototyping. If you are using MFC or some * other graphical interface with no console, DEBUG probably should be * undefined. * PM_CHECK_ERRORS more-or-less takes over error checking for return values, * stopping your program and printing error messages when an error * occurs. This also uses stdio for console text I/O. */ #ifndef WIN32 // Linux and OS X have stdint.h #include #else #ifndef INT32_DEFINED // rather than having users install a special .h file for windows, // just put the required definitions inline here. porttime.h uses // these too, so the definitions are (unfortunately) duplicated there typedef int int32_t; typedef unsigned int uint32_t; #define INT32_DEFINED #endif #endif #ifdef _WINDLL #define PMEXPORT __declspec(dllexport) #else #define PMEXPORT #endif #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif /* default size of buffers for sysex transmission: */ #define PM_DEFAULT_SYSEX_BUFFER_SIZE 1024 /** List of portmidi errors.*/ typedef enum { pmNoError = 0, pmNoData = 0, /**< A "no error" return that also indicates no data avail. */ pmGotData = 1, /**< A "no error" return that also indicates data available */ pmHostError = -10000, pmInvalidDeviceId, /** out of range or * output device when input is requested or * input device when output is requested or * device is already opened */ pmInsufficientMemory, pmBufferTooSmall, pmBufferOverflow, pmBadPtr, /* PortMidiStream parameter is NULL or * stream is not opened or * stream is output when input is required or * stream is input when output is required */ pmBadData, /** illegal midi data, e.g. missing EOX */ pmInternalError, pmBufferMaxSize /** buffer is already as large as it can be */ /* NOTE: If you add a new error type, be sure to update Pm_GetErrorText() */ } PmError; /** Pm_Initialize() is the library initialisation function - call this before using the library. */ PMEXPORT PmError Pm_Initialize( void ); /** Pm_Terminate() is the library termination function - call this after using the library. */ PMEXPORT PmError Pm_Terminate( void ); /** A single PortMidiStream is a descriptor for an open MIDI device. */ typedef void PortMidiStream; #define PmStream PortMidiStream /** Test whether stream has a pending host error. Normally, the client finds out about errors through returned error codes, but some errors can occur asynchronously where the client does not explicitly call a function, and therefore cannot receive an error code. The client can test for a pending error using Pm_HasHostError(). If true, the error can be accessed and cleared by calling Pm_GetErrorText(). Errors are also cleared by calling other functions that can return errors, e.g. Pm_OpenInput(), Pm_OpenOutput(), Pm_Read(), Pm_Write(). The client does not need to call Pm_HasHostError(). Any pending error will be reported the next time the client performs an explicit function call on the stream, e.g. an input or output operation. Until the error is cleared, no new error codes will be obtained, even for a different stream. */ PMEXPORT int Pm_HasHostError( PortMidiStream * stream ); /** Translate portmidi error number into human readable message. These strings are constants (set at compile time) so client has no need to allocate storage */ PMEXPORT const char *Pm_GetErrorText( PmError errnum ); /** Translate portmidi host error into human readable message. These strings are computed at run time, so client has to allocate storage. After this routine executes, the host error is cleared. */ PMEXPORT void Pm_GetHostErrorText(char * msg, unsigned int len); #define HDRLENGTH 50 #define PM_HOST_ERROR_MSG_LEN 256u /* any host error msg will occupy less than this number of characters */ /** Device enumeration mechanism. Device ids range from 0 to Pm_CountDevices()-1. */ typedef int PmDeviceID; #define pmNoDevice -1 typedef struct { int structVersion; /**< this internal structure version */ const char *interf; /**< underlying MIDI API, e.g. MMSystem or DirectX */ const char *name; /**< device name, e.g. USB MidiSport 1x1 */ int input; /**< true iff input is available */ int output; /**< true iff output is available */ int opened; /**< used by generic PortMidi code to do error checking on arguments */ } PmDeviceInfo; /** Get devices count, ids range from 0 to Pm_CountDevices()-1. */ PMEXPORT int Pm_CountDevices( void ); /** Pm_GetDefaultInputDeviceID(), Pm_GetDefaultOutputDeviceID() Return the default device ID or pmNoDevice if there are no devices. The result (but not pmNoDevice) can be passed to Pm_OpenMidi(). The default device can be specified using a small application named pmdefaults that is part of the PortMidi distribution. This program in turn uses the Java Preferences object created by java.util.prefs.Preferences.userRoot().node("/PortMidi"); the preference is set by calling prefs.put("PM_RECOMMENDED_OUTPUT_DEVICE", prefName); or prefs.put("PM_RECOMMENDED_INPUT_DEVICE", prefName); In the statements above, prefName is a string describing the MIDI device in the form "interf, name" where interf identifies the underlying software system or API used by PortMdi to access devices and name is the name of the device. These correspond to the interf and name fields of a PmDeviceInfo. (Currently supported interfaces are "MMSystem" for Win32, "ALSA" for Linux, and "CoreMIDI" for OS X, so in fact, there is no choice of interface.) In "interf, name", the strings are actually substrings of the full interface and name strings. For example, the preference "Core, Sport" will match a device with interface "CoreMIDI" and name "In USB MidiSport 1x1". It will also match "CoreMIDI" and "In USB MidiSport 2x2". The devices are enumerated in device ID order, so the lowest device ID that matches the pattern becomes the default device. Finally, if the comma-space (", ") separator between interface and name parts of the preference is not found, the entire preference string is interpreted as a name, and the interface part is the empty string, which matches anything. On the MAC, preferences are stored in /Users/$NAME/Library/Preferences/com.apple.java.util.prefs.plist which is a binary file. In addition to the pmdefaults program, there are utilities that can read and edit this preference file. On the PC, On Linux, */ PMEXPORT PmDeviceID Pm_GetDefaultInputDeviceID( void ); /** see PmDeviceID Pm_GetDefaultInputDeviceID() */ PMEXPORT PmDeviceID Pm_GetDefaultOutputDeviceID( void ); /** PmTimestamp is used to represent a millisecond clock with arbitrary start time. The type is used for all MIDI timestampes and clocks. */ typedef int32_t PmTimestamp; typedef PmTimestamp (*PmTimeProcPtr)(void *time_info); /** TRUE if t1 before t2 */ #define PmBefore(t1,t2) ((t1-t2) < 0) /** \defgroup grp_device Input/Output Devices Handling @{ */ /** Pm_GetDeviceInfo() returns a pointer to a PmDeviceInfo structure referring to the device specified by id. If id is out of range the function returns NULL. The returned structure is owned by the PortMidi implementation and must not be manipulated or freed. The pointer is guaranteed to be valid between calls to Pm_Initialize() and Pm_Terminate(). */ PMEXPORT const PmDeviceInfo* Pm_GetDeviceInfo( PmDeviceID id ); /** Pm_OpenInput() and Pm_OpenOutput() open devices. stream is the address of a PortMidiStream pointer which will receive a pointer to the newly opened stream. inputDevice is the id of the device used for input (see PmDeviceID above). inputDriverInfo is a pointer to an optional driver specific data structure containing additional information for device setup or handle processing. inputDriverInfo is never required for correct operation. If not used inputDriverInfo should be NULL. outputDevice is the id of the device used for output (see PmDeviceID above.) outputDriverInfo is a pointer to an optional driver specific data structure containing additional information for device setup or handle processing. outputDriverInfo is never required for correct operation. If not used outputDriverInfo should be NULL. For input, the buffersize specifies the number of input events to be buffered waiting to be read using Pm_Read(). For output, buffersize specifies the number of output events to be buffered waiting for output. (In some cases -- see below -- PortMidi does not buffer output at all and merely passes data to a lower-level API, in which case buffersize is ignored.) latency is the delay in milliseconds applied to timestamps to determine when the output should actually occur. (If latency is < 0, 0 is assumed.) If latency is zero, timestamps are ignored and all output is delivered immediately. If latency is greater than zero, output is delayed until the message timestamp plus the latency. (NOTE: the time is measured relative to the time source indicated by time_proc. Timestamps are absolute, not relative delays or offsets.) In some cases, PortMidi can obtain better timing than your application by passing timestamps along to the device driver or hardware. Latency may also help you to synchronize midi data to audio data by matching midi latency to the audio buffer latency. time_proc is a pointer to a procedure that returns time in milliseconds. It may be NULL, in which case a default millisecond timebase (PortTime) is used. If the application wants to use PortTime, it should start the timer (call Pt_Start) before calling Pm_OpenInput or Pm_OpenOutput. If the application tries to start the timer *after* Pm_OpenInput or Pm_OpenOutput, it may get a ptAlreadyStarted error from Pt_Start, and the application's preferred time resolution and callback function will be ignored. time_proc result values are appended to incoming MIDI data, and time_proc times are used to schedule outgoing MIDI data (when latency is non-zero). time_info is a pointer passed to time_proc. Example: If I provide a timestamp of 5000, latency is 1, and time_proc returns 4990, then the desired output time will be when time_proc returns timestamp+latency = 5001. This will be 5001-4990 = 11ms from now. return value: Upon success Pm_Open() returns PmNoError and places a pointer to a valid PortMidiStream in the stream argument. If a call to Pm_Open() fails a nonzero error code is returned (see PMError above) and the value of port is invalid. Any stream that is successfully opened should eventually be closed by calling Pm_Close(). */ PMEXPORT PmError Pm_OpenInput( PortMidiStream** stream, PmDeviceID inputDevice, void *inputDriverInfo, int32_t bufferSize, PmTimeProcPtr time_proc, void *time_info ); PMEXPORT PmError Pm_OpenOutput( PortMidiStream** stream, PmDeviceID outputDevice, void *outputDriverInfo, int32_t bufferSize, PmTimeProcPtr time_proc, void *time_info, int32_t latency ); /** @} */ /** \defgroup grp_events_filters Events and Filters Handling @{ */ /* \function PmError Pm_SetFilter( PortMidiStream* stream, int32_t filters ) Pm_SetFilter() sets filters on an open input stream to drop selected input types. By default, only active sensing messages are filtered. To prohibit, say, active sensing and sysex messages, call Pm_SetFilter(stream, PM_FILT_ACTIVE | PM_FILT_SYSEX); Filtering is useful when midi routing or midi thru functionality is being provided by the user application. For example, you may want to exclude timing messages (clock, MTC, start/stop/continue), while allowing note-related messages to pass. Or you may be using a sequencer or drum-machine for MIDI clock information but want to exclude any notes it may play. */ /* Filter bit-mask definitions */ /** filter active sensing messages (0xFE): */ #define PM_FILT_ACTIVE (1 << 0x0E) /** filter system exclusive messages (0xF0): */ #define PM_FILT_SYSEX (1 << 0x00) /** filter MIDI clock message (0xF8) */ #define PM_FILT_CLOCK (1 << 0x08) /** filter play messages (start 0xFA, stop 0xFC, continue 0xFB) */ #define PM_FILT_PLAY ((1 << 0x0A) | (1 << 0x0C) | (1 << 0x0B)) /** filter tick messages (0xF9) */ #define PM_FILT_TICK (1 << 0x09) /** filter undefined FD messages */ #define PM_FILT_FD (1 << 0x0D) /** filter undefined real-time messages */ #define PM_FILT_UNDEFINED PM_FILT_FD /** filter reset messages (0xFF) */ #define PM_FILT_RESET (1 << 0x0F) /** filter all real-time messages */ #define PM_FILT_REALTIME (PM_FILT_ACTIVE | PM_FILT_SYSEX | PM_FILT_CLOCK | \ PM_FILT_PLAY | PM_FILT_UNDEFINED | PM_FILT_RESET | PM_FILT_TICK) /** filter note-on and note-off (0x90-0x9F and 0x80-0x8F */ #define PM_FILT_NOTE ((1 << 0x19) | (1 << 0x18)) /** filter channel aftertouch (most midi controllers use this) (0xD0-0xDF)*/ #define PM_FILT_CHANNEL_AFTERTOUCH (1 << 0x1D) /** per-note aftertouch (0xA0-0xAF) */ #define PM_FILT_POLY_AFTERTOUCH (1 << 0x1A) /** filter both channel and poly aftertouch */ #define PM_FILT_AFTERTOUCH (PM_FILT_CHANNEL_AFTERTOUCH | PM_FILT_POLY_AFTERTOUCH) /** Program changes (0xC0-0xCF) */ #define PM_FILT_PROGRAM (1 << 0x1C) /** Control Changes (CC's) (0xB0-0xBF)*/ #define PM_FILT_CONTROL (1 << 0x1B) /** Pitch Bender (0xE0-0xEF*/ #define PM_FILT_PITCHBEND (1 << 0x1E) /** MIDI Time Code (0xF1)*/ #define PM_FILT_MTC (1 << 0x01) /** Song Position (0xF2) */ #define PM_FILT_SONG_POSITION (1 << 0x02) /** Song Select (0xF3)*/ #define PM_FILT_SONG_SELECT (1 << 0x03) /** Tuning request (0xF6)*/ #define PM_FILT_TUNE (1 << 0x06) /** All System Common messages (mtc, song position, song select, tune request) */ #define PM_FILT_SYSTEMCOMMON (PM_FILT_MTC | PM_FILT_SONG_POSITION | PM_FILT_SONG_SELECT | PM_FILT_TUNE) PMEXPORT PmError Pm_SetFilter( PortMidiStream* stream, int32_t filters ); #define Pm_Channel(channel) (1<<(channel)) /** Pm_SetChannelMask() filters incoming messages based on channel. The mask is a 16-bit bitfield corresponding to appropriate channels. The Pm_Channel macro can assist in calling this function. i.e. to set receive only input on channel 1, call with Pm_SetChannelMask(Pm_Channel(1)); Multiple channels should be OR'd together, like Pm_SetChannelMask(Pm_Channel(10) | Pm_Channel(11)) Note that channels are numbered 0 to 15 (not 1 to 16). Most synthesizer and interfaces number channels starting at 1, but PortMidi numbers channels starting at 0. All channels are allowed by default */ PMEXPORT PmError Pm_SetChannelMask(PortMidiStream *stream, int mask); /** Pm_Abort() terminates outgoing messages immediately The caller should immediately close the output port; this call may result in transmission of a partial midi message. There is no abort for Midi input because the user can simply ignore messages in the buffer and close an input device at any time. */ PMEXPORT PmError Pm_Abort( PortMidiStream* stream ); /** Pm_Close() closes a midi stream, flushing any pending buffers. (PortMidi attempts to close open streams when the application exits -- this is particularly difficult under Windows.) */ PMEXPORT PmError Pm_Close( PortMidiStream* stream ); /** Pm_Synchronize() instructs PortMidi to (re)synchronize to the time_proc passed when the stream was opened. Typically, this is used when the stream must be opened before the time_proc reference is actually advancing. In this case, message timing may be erratic, but since timestamps of zero mean "send immediately," initialization messages with zero timestamps can be written without a functioning time reference and without problems. Before the first MIDI message with a non-zero timestamp is written to the stream, the time reference must begin to advance (for example, if the time_proc computes time based on audio samples, time might begin to advance when an audio stream becomes active). After time_proc return values become valid, and BEFORE writing the first non-zero timestamped MIDI message, call Pm_Synchronize() so that PortMidi can observe the difference between the current time_proc value and its MIDI stream time. In the more normal case where time_proc values advance continuously, there is no need to call Pm_Synchronize. PortMidi will always synchronize at the first output message and periodically thereafter. */ PmError Pm_Synchronize( PortMidiStream* stream ); /** Pm_Message() encodes a short Midi message into a 32-bit word. If data1 and/or data2 are not present, use zero. Pm_MessageStatus(), Pm_MessageData1(), and Pm_MessageData2() extract fields from a 32-bit midi message. */ #define Pm_Message(status, data1, data2) \ ((((data2) << 16) & 0xFF0000) | \ (((data1) << 8) & 0xFF00) | \ ((status) & 0xFF)) #define Pm_MessageStatus(msg) ((msg) & 0xFF) #define Pm_MessageData1(msg) (((msg) >> 8) & 0xFF) #define Pm_MessageData2(msg) (((msg) >> 16) & 0xFF) typedef int32_t PmMessage; /**< see PmEvent */ /** All midi data comes in the form of PmEvent structures. A sysex message is encoded as a sequence of PmEvent structures, with each structure carrying 4 bytes of the message, i.e. only the first PmEvent carries the status byte. Note that MIDI allows nested messages: the so-called "real-time" MIDI messages can be inserted into the MIDI byte stream at any location, including within a sysex message. MIDI real-time messages are one-byte messages used mainly for timing (see the MIDI spec). PortMidi retains the order of non-real-time MIDI messages on both input and output, but it does not specify exactly how real-time messages are processed. This is particulary problematic for MIDI input, because the input parser must either prepare to buffer an unlimited number of sysex message bytes or to buffer an unlimited number of real-time messages that arrive embedded in a long sysex message. To simplify things, the input parser is allowed to pass real-time MIDI messages embedded within a sysex message, and it is up to the client to detect, process, and remove these messages as they arrive. When receiving sysex messages, the sysex message is terminated by either an EOX status byte (anywhere in the 4 byte messages) or by a non-real-time status byte in the low order byte of the message. If you get a non-real-time status byte but there was no EOX byte, it means the sysex message was somehow truncated. This is not considered an error; e.g., a missing EOX can result from the user disconnecting a MIDI cable during sysex transmission. A real-time message can occur within a sysex message. A real-time message will always occupy a full PmEvent with the status byte in the low-order byte of the PmEvent message field. (This implies that the byte-order of sysex bytes and real-time message bytes may not be preserved -- for example, if a real-time message arrives after 3 bytes of a sysex message, the real-time message will be delivered first. The first word of the sysex message will be delivered only after the 4th byte arrives, filling the 4-byte PmEvent message field. The timestamp field is observed when the output port is opened with a non-zero latency. A timestamp of zero means "use the current time", which in turn means to deliver the message with a delay of latency (the latency parameter used when opening the output port.) Do not expect PortMidi to sort data according to timestamps -- messages should be sent in the correct order, and timestamps MUST be non-decreasing. See also "Example" for Pm_OpenOutput() above. A sysex message will generally fill many PmEvent structures. On output to a PortMidiStream with non-zero latency, the first timestamp on sysex message data will determine the time to begin sending the message. PortMidi implementations may ignore timestamps for the remainder of the sysex message. On input, the timestamp ideally denotes the arrival time of the status byte of the message. The first timestamp on sysex message data will be valid. Subsequent timestamps may denote when message bytes were actually received, or they may be simply copies of the first timestamp. Timestamps for nested messages: If a real-time message arrives in the middle of some other message, it is enqueued immediately with the timestamp corresponding to its arrival time. The interrupted non-real-time message or 4-byte packet of sysex data will be enqueued later. The timestamp of interrupted data will be equal to that of the interrupting real-time message to insure that timestamps are non-decreasing. */ typedef struct { PmMessage message; PmTimestamp timestamp; } PmEvent; /** @} */ /** \defgroup grp_io Reading and Writing Midi Messages @{ */ /** Pm_Read() retrieves midi data into a buffer, and returns the number of events read. Result is a non-negative number unless an error occurs, in which case a PmError value will be returned. Buffer Overflow The problem: if an input overflow occurs, data will be lost, ultimately because there is no flow control all the way back to the data source. When data is lost, the receiver should be notified and some sort of graceful recovery should take place, e.g. you shouldn't resume receiving in the middle of a long sysex message. With a lock-free fifo, which is pretty much what we're stuck with to enable portability to the Mac, it's tricky for the producer and consumer to synchronously reset the buffer and resume normal operation. Solution: the buffer managed by PortMidi will be flushed when an overflow occurs. The consumer (Pm_Read()) gets an error message (pmBufferOverflow) and ordinary processing resumes as soon as a new message arrives. The remainder of a partial sysex message is not considered to be a "new message" and will be flushed as well. */ PMEXPORT int Pm_Read( PortMidiStream *stream, PmEvent *buffer, int32_t length ); /** Pm_Poll() tests whether input is available, returning TRUE, FALSE, or an error value. */ PMEXPORT PmError Pm_Poll( PortMidiStream *stream); /** Pm_Write() writes midi data from a buffer. This may contain: - short messages or - sysex messages that are converted into a sequence of PmEvent structures, e.g. sending data from a file or forwarding them from midi input. Use Pm_WriteSysEx() to write a sysex message stored as a contiguous array of bytes. Sysex data may contain embedded real-time messages. */ PMEXPORT PmError Pm_Write( PortMidiStream *stream, PmEvent *buffer, int32_t length ); /** Pm_WriteShort() writes a timestamped non-system-exclusive midi message. Messages are delivered in order as received, and timestamps must be non-decreasing. (But timestamps are ignored if the stream was opened with latency = 0.) */ PMEXPORT PmError Pm_WriteShort( PortMidiStream *stream, PmTimestamp when, int32_t msg); /** Pm_WriteSysEx() writes a timestamped system-exclusive midi message. */ PMEXPORT PmError Pm_WriteSysEx( PortMidiStream *stream, PmTimestamp when, unsigned char *msg); /** @} */ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PORT_MIDI_H */ pd-0.46-7/portmidi/pm_common/pmutil.h0000775000175000017500000001342212374245151015703 0ustar mspmsp/* pmutil.h -- some helpful utilities for building midi applications that use PortMidi */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ typedef void PmQueue; /* A single-reader, single-writer queue is created by Pm_QueueCreate(), which takes the number of messages and the message size as parameters. The queue only accepts fixed sized messages. Returns NULL if memory cannot be allocated. This queue implementation uses the "light pipe" algorithm which operates correctly even with multi-processors and out-of-order memory writes. (see Alexander Dokumentov, "Lock-free Interprocess Communication," Dr. Dobbs Portal, http://www.ddj.com/, articleID=189401457, June 15, 2006. This algorithm requires that messages be translated to a form where no words contain zeros. Each word becomes its own "data valid" tag. Because of this translation, we cannot return a pointer to data still in the queue when the "peek" method is called. Instead, a buffer is preallocated so that data can be copied there. Pm_QueuePeek() dequeues a message into this buffer and returns a pointer to it. A subsequent Pm_Dequeue() will copy from this buffer. This implementation does not try to keep reader/writer data in separate cache lines or prevent thrashing on cache lines. However, this algorithm differs by doing inserts/removals in units of messages rather than units of machine words. Some performance improvement might be obtained by not clearing data immediately after a read, but instead by waiting for the end of the cache line, especially if messages are smaller than cache lines. See the Dokumentov article for explanation. The algorithm is extended to handle "overflow" reporting. To report an overflow, the sender writes the current tail position to a field. The receiver must acknowlege receipt by zeroing the field. The sender will not send more until the field is zeroed. Pm_QueueDestroy() destroys the queue and frees its storage. */ PMEXPORT PmQueue *Pm_QueueCreate(long num_msgs, int32_t bytes_per_msg); PMEXPORT PmError Pm_QueueDestroy(PmQueue *queue); /* Pm_Dequeue() removes one item from the queue, copying it into msg. Returns 1 if successful, and 0 if the queue is empty. Returns pmBufferOverflow if what would have been the next thing in the queue was dropped due to overflow. (So when overflow occurs, the receiver can receive a queue full of messages before getting the overflow report. This protocol ensures that the reader will be notified when data is lost due to overflow. */ PMEXPORT PmError Pm_Dequeue(PmQueue *queue, void *msg); /* Pm_Enqueue() inserts one item into the queue, copying it from msg. Returns pmNoError if successful and pmBufferOverflow if the queue was already full. If pmBufferOverflow is returned, the overflow flag is set. */ PMEXPORT PmError Pm_Enqueue(PmQueue *queue, void *msg); /* Pm_QueueFull() returns non-zero if the queue is full Pm_QueueEmpty() returns non-zero if the queue is empty Either condition may change immediately because a parallel enqueue or dequeue operation could be in progress. Furthermore, Pm_QueueEmpty() is optimistic: it may say false, when due to out-of-order writes, the full message has not arrived. Therefore, Pm_Dequeue() could still return 0 after Pm_QueueEmpty() returns false. On the other hand, Pm_QueueFull() is pessimistic: if it returns false, then Pm_Enqueue() is guaranteed to succeed. Error conditions: Pm_QueueFull() returns pmBadPtr if queue is NULL. Pm_QueueEmpty() returns FALSE if queue is NULL. */ PMEXPORT int Pm_QueueFull(PmQueue *queue); PMEXPORT int Pm_QueueEmpty(PmQueue *queue); /* Pm_QueuePeek() returns a pointer to the item at the head of the queue, or NULL if the queue is empty. The item is not removed from the queue. Pm_QueuePeek() will not indicate when an overflow occurs. If you want to get and check pmBufferOverflow messages, use the return value of Pm_QueuePeek() *only* as an indication that you should call Pm_Dequeue(). At the point where a direct call to Pm_Dequeue() would return pmBufferOverflow, Pm_QueuePeek() will return NULL but internally clear the pmBufferOverflow flag, enabling Pm_Enqueue() to resume enqueuing messages. A subsequent call to Pm_QueuePeek() will return a pointer to the first message *after* the overflow. Using this as an indication to call Pm_Dequeue(), the first call to Pm_Dequeue() will return pmBufferOverflow. The second call will return success, copying the same message pointed to by the previous Pm_QueuePeek(). When to use Pm_QueuePeek(): (1) when you need to look at the message data to decide who should be called to receive it. (2) when you need to know a message is ready but cannot accept the message. Note that Pm_QueuePeek() is not a fast check, so if possible, you might as well just call Pm_Dequeue() and accept the data if it is there. */ PMEXPORT void *Pm_QueuePeek(PmQueue *queue); /* Pm_SetOverflow() allows the writer (enqueuer) to signal an overflow condition to the reader (dequeuer). E.g. when transfering data from the OS to an application, if the OS indicates a buffer overrun, Pm_SetOverflow() can be used to insure that the reader receives a pmBufferOverflow result from Pm_Dequeue(). Returns pmBadPtr if queue is NULL, returns pmBufferOverflow if buffer is already in an overflow state, returns pmNoError if successfully set overflow state. */ PMEXPORT PmError Pm_SetOverflow(PmQueue *queue); #ifdef __cplusplus } #endif /* __cplusplus */ pd-0.46-7/portmidi/pm_common/pmutil.c0000775000175000017500000002034712374245151015702 0ustar mspmsp/* pmutil.c -- some helpful utilities for building midi applications that use PortMidi */ #include #include #include #include "portmidi.h" #include "pmutil.h" #include "pminternal.h" #ifdef WIN32 #define bzero(addr, siz) memset(addr, 0, siz) #endif // #define QUEUE_DEBUG 1 #ifdef QUEUE_DEBUG #include "stdio.h" #endif typedef struct { long head; long tail; long len; long overflow; int32_t msg_size; /* number of int32_t in a message including extra word */ int32_t peek_overflow; int32_t *buffer; int32_t *peek; int32_t peek_flag; } PmQueueRep; PMEXPORT PmQueue *Pm_QueueCreate(long num_msgs, int32_t bytes_per_msg) { int32_t int32s_per_msg = (int32_t) (((bytes_per_msg + sizeof(int32_t) - 1) & ~(sizeof(int32_t) - 1)) / sizeof(int32_t)); PmQueueRep *queue = (PmQueueRep *) pm_alloc(sizeof(PmQueueRep)); if (!queue) /* memory allocation failed */ return NULL; /* need extra word per message for non-zero encoding */ queue->len = num_msgs * (int32s_per_msg + 1); queue->buffer = (int32_t *) pm_alloc(queue->len * sizeof(int32_t)); bzero(queue->buffer, queue->len * sizeof(int32_t)); if (!queue->buffer) { pm_free(queue); return NULL; } else { /* allocate the "peek" buffer */ queue->peek = (int32_t *) pm_alloc(int32s_per_msg * sizeof(int32_t)); if (!queue->peek) { /* free everything allocated so far and return */ pm_free(queue->buffer); pm_free(queue); return NULL; } } bzero(queue->buffer, queue->len * sizeof(int32_t)); queue->head = 0; queue->tail = 0; /* msg_size is in words */ queue->msg_size = int32s_per_msg + 1; /* note extra word is counted */ queue->overflow = FALSE; queue->peek_overflow = FALSE; queue->peek_flag = FALSE; return queue; } PMEXPORT PmError Pm_QueueDestroy(PmQueue *q) { PmQueueRep *queue = (PmQueueRep *) q; /* arg checking */ if (!queue || !queue->buffer || !queue->peek) return pmBadPtr; pm_free(queue->peek); pm_free(queue->buffer); pm_free(queue); return pmNoError; } PMEXPORT PmError Pm_Dequeue(PmQueue *q, void *msg) { long head; PmQueueRep *queue = (PmQueueRep *) q; int i; int32_t *msg_as_int32 = (int32_t *) msg; /* arg checking */ if (!queue) return pmBadPtr; /* a previous peek operation encountered an overflow, but the overflow * has not yet been reported to client, so do it now. No message is * returned, but on the next call, we will return the peek buffer. */ if (queue->peek_overflow) { queue->peek_overflow = FALSE; return pmBufferOverflow; } if (queue->peek_flag) { memcpy(msg, queue->peek, (queue->msg_size - 1) * sizeof(int32_t)); queue->peek_flag = FALSE; return pmGotData; } head = queue->head; /* if writer overflows, it writes queue->overflow = tail+1 so that * when the reader gets to that position in the buffer, it can * return the overflow condition to the reader. The problem is that * at overflow, things have wrapped around, so tail == head, and the * reader will detect overflow immediately instead of waiting until * it reads everything in the buffer, wrapping around again to the * point where tail == head. So the condition also checks that * queue->buffer[head] is zero -- if so, then the buffer is now * empty, and we're at the point in the msg stream where overflow * occurred. It's time to signal overflow to the reader. If * queue->buffer[head] is non-zero, there's a message there and we * should read all the way around the buffer before signalling overflow. * There is a write-order dependency here, but to fail, the overflow * field would have to be written while an entire buffer full of * writes are still pending. I'm assuming out-of-order writes are * possible, but not that many. */ if (queue->overflow == head + 1 && !queue->buffer[head]) { queue->overflow = 0; /* non-overflow condition */ return pmBufferOverflow; } /* test to see if there is data in the queue -- test from back * to front so if writer is simultaneously writing, we don't * waste time discovering the write is not finished */ for (i = queue->msg_size - 1; i >= 0; i--) { if (!queue->buffer[head + i]) { return pmNoData; } } memcpy(msg, (char *) &queue->buffer[head + 1], sizeof(int32_t) * (queue->msg_size - 1)); /* fix up zeros */ i = queue->buffer[head]; while (i < queue->msg_size) { int32_t j; i--; /* msg does not have extra word so shift down */ j = msg_as_int32[i]; msg_as_int32[i] = 0; i = j; } /* signal that data has been removed by zeroing: */ bzero((char *) &queue->buffer[head], sizeof(int32_t) * queue->msg_size); /* update head */ head += queue->msg_size; if (head == queue->len) head = 0; queue->head = head; return pmGotData; /* success */ } PMEXPORT PmError Pm_SetOverflow(PmQueue *q) { PmQueueRep *queue = (PmQueueRep *) q; long tail; /* arg checking */ if (!queue) return pmBadPtr; /* no more enqueue until receiver acknowledges overflow */ if (queue->overflow) return pmBufferOverflow; tail = queue->tail; queue->overflow = tail + 1; return pmBufferOverflow; } PMEXPORT PmError Pm_Enqueue(PmQueue *q, void *msg) { PmQueueRep *queue = (PmQueueRep *) q; long tail; int i; int32_t *src = (int32_t *) msg; int32_t *ptr; int32_t *dest; int rslt; if (!queue) return pmBadPtr; /* no more enqueue until receiver acknowledges overflow */ if (queue->overflow) return pmBufferOverflow; rslt = Pm_QueueFull(q); /* already checked above: if (rslt == pmBadPtr) return rslt; */ tail = queue->tail; if (rslt) { queue->overflow = tail + 1; return pmBufferOverflow; } /* queue is has room for message, and overflow flag is cleared */ ptr = &queue->buffer[tail]; dest = ptr + 1; for (i = 1; i < queue->msg_size; i++) { int32_t j = src[i - 1]; if (!j) { *ptr = i; ptr = dest; } else { *dest = j; } dest++; } *ptr = i; tail += queue->msg_size; if (tail == queue->len) tail = 0; queue->tail = tail; return pmNoError; } PMEXPORT int Pm_QueueEmpty(PmQueue *q) { PmQueueRep *queue = (PmQueueRep *) q; return (!queue) || /* null pointer -> return "empty" */ (queue->buffer[queue->head] == 0 && !queue->peek_flag); } PMEXPORT int Pm_QueueFull(PmQueue *q) { long tail; int i; PmQueueRep *queue = (PmQueueRep *) q; /* arg checking */ if (!queue) return pmBadPtr; tail = queue->tail; /* test to see if there is space in the queue */ for (i = 0; i < queue->msg_size; i++) { if (queue->buffer[tail + i]) { return TRUE; } } return FALSE; } PMEXPORT void *Pm_QueuePeek(PmQueue *q) { PmError rslt; int32_t temp; PmQueueRep *queue = (PmQueueRep *) q; /* arg checking */ if (!queue) return NULL; if (queue->peek_flag) { return queue->peek; } /* this is ugly: if peek_overflow is set, then Pm_Dequeue() * returns immediately with pmBufferOverflow, but here, we * want Pm_Dequeue() to really check for data. If data is * there, we can return it */ temp = queue->peek_overflow; queue->peek_overflow = FALSE; rslt = Pm_Dequeue(q, queue->peek); queue->peek_overflow = temp; if (rslt == 1) { queue->peek_flag = TRUE; return queue->peek; } else if (rslt == pmBufferOverflow) { /* when overflow is indicated, the queue is empty and the * first message that was dropped by Enqueue (signalling * pmBufferOverflow to its caller) would have been the next * message in the queue. Pm_QueuePeek will return NULL, but * remember that an overflow occurred. (see Pm_Dequeue) */ queue->peek_overflow = TRUE; } return NULL; } pd-0.46-7/portmidi/pm_common/pminternal.h0000775000175000017500000002043712374245151016546 0ustar mspmsp/* pminternal.h -- header for interface implementations */ /* this file is included by files that implement library internals */ /* Here is a guide to implementers: provide an initialization function similar to pm_winmm_init() add your initialization function to pm_init() Note that your init function should never require not-standard libraries or fail in any way. If the interface is not available, simply do not call pm_add_device. This means that non-standard libraries should try to do dynamic linking at runtime using a DLL and return without error if the DLL cannot be found or if there is any other failure. implement functions as indicated in pm_fns_type to open, read, write, close, etc. call pm_add_device() for each input and output device, passing it a pm_fns_type structure. assumptions about pm_fns_type functions are given below. */ #ifdef __cplusplus extern "C" { #endif extern int pm_initialized; /* see note in portmidi.c */ /* these are defined in system-specific file */ void *pm_alloc(size_t s); void pm_free(void *ptr); /* if an error occurs while opening or closing a midi stream, set these: */ extern int pm_hosterror; extern char pm_hosterror_text[PM_HOST_ERROR_MSG_LEN]; struct pm_internal_struct; /* these do not use PmInternal because it is not defined yet... */ typedef PmError (*pm_write_short_fn)(struct pm_internal_struct *midi, PmEvent *buffer); typedef PmError (*pm_begin_sysex_fn)(struct pm_internal_struct *midi, PmTimestamp timestamp); typedef PmError (*pm_end_sysex_fn)(struct pm_internal_struct *midi, PmTimestamp timestamp); typedef PmError (*pm_write_byte_fn)(struct pm_internal_struct *midi, unsigned char byte, PmTimestamp timestamp); typedef PmError (*pm_write_realtime_fn)(struct pm_internal_struct *midi, PmEvent *buffer); typedef PmError (*pm_write_flush_fn)(struct pm_internal_struct *midi, PmTimestamp timestamp); typedef PmTimestamp (*pm_synchronize_fn)(struct pm_internal_struct *midi); /* pm_open_fn should clean up all memory and close the device if any part of the open fails */ typedef PmError (*pm_open_fn)(struct pm_internal_struct *midi, void *driverInfo); typedef PmError (*pm_abort_fn)(struct pm_internal_struct *midi); /* pm_close_fn should clean up all memory and close the device if any part of the close fails. */ typedef PmError (*pm_close_fn)(struct pm_internal_struct *midi); typedef PmError (*pm_poll_fn)(struct pm_internal_struct *midi); typedef void (*pm_host_error_fn)(struct pm_internal_struct *midi, char * msg, unsigned int len); typedef unsigned int (*pm_has_host_error_fn)(struct pm_internal_struct *midi); typedef struct { pm_write_short_fn write_short; /* output short MIDI msg */ pm_begin_sysex_fn begin_sysex; /* prepare to send a sysex message */ pm_end_sysex_fn end_sysex; /* marks end of sysex message */ pm_write_byte_fn write_byte; /* accumulate one more sysex byte */ pm_write_realtime_fn write_realtime; /* send real-time message within sysex */ pm_write_flush_fn write_flush; /* send any accumulated but unsent data */ pm_synchronize_fn synchronize; /* synchronize portmidi time to stream time */ pm_open_fn open; /* open MIDI device */ pm_abort_fn abort; /* abort */ pm_close_fn close; /* close device */ pm_poll_fn poll; /* read pending midi events into portmidi buffer */ pm_has_host_error_fn has_host_error; /* true when device has had host error message */ pm_host_error_fn host_error; /* provide text readable host error message for device (clears and resets) */ } pm_fns_node, *pm_fns_type; /* when open fails, the dictionary gets this set of functions: */ extern pm_fns_node pm_none_dictionary; typedef struct { PmDeviceInfo pub; /* some portmidi state also saved in here (for autmatic device closing (see PmDeviceInfo struct) */ void *descriptor; /* ID number passed to win32 multimedia API open */ void *internalDescriptor; /* points to PmInternal device, allows automatic device closing */ pm_fns_type dictionary; } descriptor_node, *descriptor_type; extern int pm_descriptor_max; extern descriptor_type descriptors; extern int pm_descriptor_index; typedef uint32_t (*time_get_proc_type)(void *time_info); typedef struct pm_internal_struct { int device_id; /* which device is open (index to descriptors) */ short write_flag; /* MIDI_IN, or MIDI_OUT */ PmTimeProcPtr time_proc; /* where to get the time */ void *time_info; /* pass this to get_time() */ int32_t buffer_len; /* how big is the buffer or queue? */ PmQueue *queue; int32_t latency; /* time delay in ms between timestamps and actual output */ /* set to zero to get immediate, simple blocking output */ /* if latency is zero, timestamps will be ignored; */ /* if midi input device, this field ignored */ int sysex_in_progress; /* when sysex status is seen, this flag becomes * true until EOX is seen. When true, new data is appended to the * stream of outgoing bytes. When overflow occurs, sysex data is * dropped (until an EOX or non-real-timei status byte is seen) so * that, if the overflow condition is cleared, we don't start * sending data from the middle of a sysex message. If a sysex * message is filtered, sysex_in_progress is false, causing the * message to be dropped. */ PmMessage sysex_message; /* buffer for 4 bytes of sysex data */ int sysex_message_count; /* how many bytes in sysex_message so far */ int32_t filters; /* flags that filter incoming message classes */ int32_t channel_mask; /* filter incoming messages based on channel */ PmTimestamp last_msg_time; /* timestamp of last message */ PmTimestamp sync_time; /* time of last synchronization */ PmTimestamp now; /* set by PmWrite to current time */ int first_message; /* initially true, used to run first synchronization */ pm_fns_type dictionary; /* implementation functions */ void *descriptor; /* system-dependent state */ /* the following are used to expedite sysex data */ /* on windows, in debug mode, based on some profiling, these optimizations * cut the time to process sysex bytes from about 7.5 to 0.26 usec/byte, * but this does not count time in the driver, so I don't know if it is * important */ unsigned char *fill_base; /* addr of ptr to sysex data */ uint32_t *fill_offset_ptr; /* offset of next sysex byte */ int32_t fill_length; /* how many sysex bytes to write */ } PmInternal; /* defined by system specific implementation, e.g. pmwinmm, used by PortMidi */ void pm_init(void); void pm_term(void); /* defined by portMidi, used by pmwinmm */ PmError none_write_short(PmInternal *midi, PmEvent *buffer); PmError none_write_byte(PmInternal *midi, unsigned char byte, PmTimestamp timestamp); PmTimestamp none_synchronize(PmInternal *midi); PmError pm_fail_fn(PmInternal *midi); PmError pm_fail_timestamp_fn(PmInternal *midi, PmTimestamp timestamp); PmError pm_success_fn(PmInternal *midi); PmError pm_add_device(char *interf, char *name, int input, void *descriptor, pm_fns_type dictionary); uint32_t pm_read_bytes(PmInternal *midi, const unsigned char *data, int len, PmTimestamp timestamp); void pm_read_short(PmInternal *midi, PmEvent *event); #define none_write_flush pm_fail_timestamp_fn #define none_sysex pm_fail_timestamp_fn #define none_poll pm_fail_fn #define success_poll pm_success_fn #define MIDI_REALTIME_MASK 0xf8 #define is_real_time(msg) \ ((Pm_MessageStatus(msg) & MIDI_REALTIME_MASK) == MIDI_REALTIME_MASK) int pm_find_default_device(char *pattern, int is_input); #ifdef __cplusplus } #endif pd-0.46-7/portmidi/README.txt0000775000175000017500000000734012374245151013734 0ustar mspmspREADME for PortMidi Roger B. Dannenberg VERSION: please use "svn info" to get info. Documentation for PortMidi is found in pm_common/portmidi.h. Additional documentation: - Windows: see pm_win/README_WIN.txt and pm_win/debugging_dlls.txt - Linux: see pm_linux/README_LINUX.txt - Mac OSX: see pm_mac/README_MAC.txt - Common Lisp: see pm_cl/README_CL.txt - Eclipse: see portmidi_cdt.zip (this was contributed as is; the dlls here are now -- Sep 09 -- out of date. What is really needed is a script to generate this release automatically so we can maintain it.) - C-Sharp: see pm_csharp.zip (also contributed as is) ---------- some notes on the design of PortMidi ---------- POINTERS VS DEVICE NUMBERS When you open a MIDI port, PortMidi allocates a structure to maintain the state of the open device. Since every device is also listed in a table, you might think it would be simpler to use the table index rather than a pointer to identify a device. This would also help with error checking (it's hard to make sure a pointer is valid). PortMidi's design parallels that of PortAudio. ERROR HANDLING Error handling turned out to be much more complicated than expected. PortMidi functions return error codes that the caller can check. In addition, errors may occur asynchronously due to MIDI input. However, for Windows, there are virtually no errors that can occur if the code is correct and not passing bogus values. One exception is an error that the system is out of memory, but my guess is that one is unlikely to recover gracefully from that. Therefore, all errors in callbacks are guarded by assert(), which means not guarded at all in release configurations. Ordinarily, the caller checks for an error code. If the error is system-dependent, pmHostError is returned and the caller can call Pm_GetHostErrorText to get a text description of the error. Host error codes are system-specific and are recorded in the system-specific data allocated for each open MIDI port. However, if an error occurs on open or close, we cannot store the error with the device because there will be no device data (assuming PortMidi cleans up after devices that are not open). For open and close, we will convert the error to text, copy it to a global string, and set pm_hosterror, a global flag. Similarly, whenever a Read or Write operation returns pmHostError, the corresponding error string is copied to a global string and pm_hosterror is set. This makes getting error strings simple and uniform, although it does cost a string copy and some overhead even if the user does not want to look at the error data. The system-specific Read, Write, Poll, etc. implementations should check for asynchronous errors and return immediately if one is found so that these get reported. This happens in the Mac OS X code, where lots of things are happening in callbacks, but again, in Windows, there are no error codes recorded in callbacks. DEBUGGING If you are building a console application for research, we suggest compiling with the option PM_CHECK_ERRORS. This will insert a check for error return values at the end of each PortMidi function. If an error is encountered, a text message is printed using printf(), the user is asked to type ENTER, and then exit(-1) is called to clean up and terminate the program. You should not use PM_CHECK_ERRORS if printf() does not work (e.g. this is not a console application under Windows, or there is no visible console on some other OS), and you should not use PM_CHECK_ERRORS if you intend to recover from errors rather than abruptly terminate the program. The Windows version (and perhaps others) also offers a DEBUG compile-time option. See README_WIN.txt. pd-0.46-7/portmidi/pm_win/0000775000175000017500000000000012374245151013520 5ustar mspmsppd-0.46-7/portmidi/pm_win/pmwinmm.h0000775000175000017500000000016012160204055015344 0ustar mspmsp/* midiwin32.h -- system-specific definitions */ void pm_winmm_init( void ); void pm_winmm_term( void ); pd-0.46-7/portmidi/pm_win/pmwinmm.c0000775000175000017500000015245712374245151015371 0ustar mspmsp/* pmwinmm.c -- system specific definitions */ #ifdef _MSC_VER #pragma warning(disable: 4133) // stop warnings about implicit typecasts #endif #ifndef _WIN32_WINNT /* without this define, InitializeCriticalSectionAndSpinCount is * undefined. This version level means "Windows 2000 and higher" */ #define _WIN32_WINNT 0x0500 #endif #include "windows.h" #include "mmsystem.h" #include "portmidi.h" #include "pmutil.h" #include "pminternal.h" #include "pmwinmm.h" #include #include "porttime.h" /* asserts used to verify portMidi code logic is sound; later may want something more graceful */ #include #ifdef DEBUG /* this printf stuff really important for debugging client app w/host errors. probably want to do something else besides read/write from/to console for portability, however */ #define STRING_MAX 80 #include "stdio.h" #endif #define streql(x, y) (strcmp(x, y) == 0) #define MIDI_SYSEX 0xf0 #define MIDI_EOX 0xf7 /* callback routines */ static void CALLBACK winmm_in_callback(HMIDIIN hMidiIn, WORD wMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2); static void CALLBACK winmm_streamout_callback(HMIDIOUT hmo, UINT wMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2); #ifdef USE_SYSEX_BUFFERS static void CALLBACK winmm_out_callback(HMIDIOUT hmo, UINT wMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2); #endif extern pm_fns_node pm_winmm_in_dictionary; extern pm_fns_node pm_winmm_out_dictionary; static void winmm_out_delete(PmInternal *midi); /* forward reference */ /* A note about buffers: WinMM seems to hold onto buffers longer than one would expect, e.g. when I tried using 2 small buffers to send long sysex messages, at some point WinMM held both buffers. This problem was fixed by making buffers bigger. Therefore, it seems that there should be enough buffer space to hold a whole sysex message. The bufferSize passed into Pm_OpenInput (passed into here as buffer_len) will be used to estimate the largest sysex message (= buffer_len * 4 bytes). Call that the max_sysex_len = buffer_len * 4. For simple midi output (latency == 0), allocate 3 buffers, each with half the size of max_sysex_len, but each at least 256 bytes. For stream output, there will already be enough space in very short buffers, so use them, but make sure there are at least 16. For input, use many small buffers rather than 2 large ones so that when there are short sysex messages arriving frequently (as in control surfaces) there will be more free buffers to fill. Use max_sysex_len / 64 buffers, but at least 16, of size 64 bytes each. The following constants help to represent these design parameters: */ #define NUM_SIMPLE_SYSEX_BUFFERS 3 #define MIN_SIMPLE_SYSEX_LEN 256 #define MIN_STREAM_BUFFERS 16 #define STREAM_BUFFER_LEN 24 #define INPUT_SYSEX_LEN 64 #define MIN_INPUT_BUFFERS 16 /* if we run out of space for output (assume this is due to a sysex msg, expand by up to NUM_EXPANSION_BUFFERS in increments of EXPANSION_BUFFER_LEN */ #define NUM_EXPANSION_BUFFERS 128 #define EXPANSION_BUFFER_LEN 1024 /* A sysex buffer has 3 DWORDS as a header plus the actual message size */ #define MIDIHDR_SYSEX_BUFFER_LENGTH(x) ((x) + sizeof(long)*3) /* A MIDIHDR with a sysex message is the buffer length plus the header size */ #define MIDIHDR_SYSEX_SIZE(x) (MIDIHDR_SYSEX_BUFFER_LENGTH(x) + sizeof(MIDIHDR)) #ifdef USE_SYSEX_BUFFERS /* Size of a MIDIHDR with a buffer contaning multiple MIDIEVENT structures */ #define MIDIHDR_SIZE(x) ((x) + sizeof(MIDIHDR)) #endif /* ============================================================================== win32 mmedia system specific structure passed to midi callbacks ============================================================================== */ /* global winmm device info */ MIDIINCAPS *midi_in_caps = NULL; MIDIINCAPS midi_in_mapper_caps; UINT midi_num_inputs = 0; MIDIOUTCAPS *midi_out_caps = NULL; MIDIOUTCAPS midi_out_mapper_caps; UINT midi_num_outputs = 0; /* per device info */ typedef struct midiwinmm_struct { union { HMIDISTRM stream; /* windows handle for stream */ HMIDIOUT out; /* windows handle for out calls */ HMIDIIN in; /* windows handle for in calls */ } handle; /* midi output messages are sent in these buffers, which are allocated * in a round-robin fashion, using next_buffer as an index */ LPMIDIHDR *buffers; /* pool of buffers for midi in or out data */ int max_buffers; /* length of buffers array */ int buffers_expanded; /* buffers array expanded for extra msgs? */ int num_buffers; /* how many buffers allocated in buffers array */ int next_buffer; /* index of next buffer to send */ HANDLE buffer_signal; /* used to wait for buffer to become free */ #ifdef USE_SYSEX_BUFFERS /* sysex buffers will be allocated only when * a sysex message is sent. The size of the buffer is fixed. */ LPMIDIHDR sysex_buffers[NUM_SYSEX_BUFFERS]; /* pool of buffers for sysex data */ int next_sysex_buffer; /* index of next sysexbuffer to send */ #endif unsigned long last_time; /* last output time */ int first_message; /* flag: treat first message differently */ int sysex_mode; /* middle of sending sysex */ unsigned long sysex_word; /* accumulate data when receiving sysex */ unsigned int sysex_byte_count; /* count how many received */ LPMIDIHDR hdr; /* the message accumulating sysex to send */ unsigned long sync_time; /* when did we last determine delta? */ long delta; /* difference between stream time and real time */ int error; /* host error from doing port midi call */ CRITICAL_SECTION lock; /* prevents reentrant callbacks (input only) */ } midiwinmm_node, *midiwinmm_type; /* ============================================================================= general MIDI device queries ============================================================================= */ static void pm_winmm_general_inputs() { UINT i; WORD wRtn; midi_num_inputs = midiInGetNumDevs(); midi_in_caps = (MIDIINCAPS *) pm_alloc(sizeof(MIDIINCAPS) * midi_num_inputs); if (midi_in_caps == NULL) { /* if you can't open a particular system-level midi interface * (such as winmm), we just consider that system or API to be * unavailable and move on without reporting an error. */ return; } for (i = 0; i < midi_num_inputs; i++) { wRtn = midiInGetDevCaps(i, (LPMIDIINCAPS) & midi_in_caps[i], sizeof(MIDIINCAPS)); if (wRtn == MMSYSERR_NOERROR) { /* ignore errors here -- if pm_descriptor_max is exceeded, some devices will not be accessible. */ pm_add_device("MMSystem", midi_in_caps[i].szPname, TRUE, (void *) i, &pm_winmm_in_dictionary); } } } static void pm_winmm_mapper_input() { WORD wRtn; /* Note: if MIDIMAPPER opened as input (documentation implies you can, but current system fails to retrieve input mapper capabilities) then you still should retrieve some formof setup info. */ wRtn = midiInGetDevCaps((UINT) MIDIMAPPER, (LPMIDIINCAPS) & midi_in_mapper_caps, sizeof(MIDIINCAPS)); if (wRtn == MMSYSERR_NOERROR) { pm_add_device("MMSystem", midi_in_mapper_caps.szPname, TRUE, (void *) MIDIMAPPER, &pm_winmm_in_dictionary); } } static void pm_winmm_general_outputs() { UINT i; DWORD wRtn; midi_num_outputs = midiOutGetNumDevs(); midi_out_caps = pm_alloc( sizeof(MIDIOUTCAPS) * midi_num_outputs ); if (midi_out_caps == NULL) { /* no error is reported -- see pm_winmm_general_inputs */ return ; } for (i = 0; i < midi_num_outputs; i++) { wRtn = midiOutGetDevCaps(i, (LPMIDIOUTCAPS) & midi_out_caps[i], sizeof(MIDIOUTCAPS)); if (wRtn == MMSYSERR_NOERROR) { pm_add_device("MMSystem", midi_out_caps[i].szPname, FALSE, (void *) i, &pm_winmm_out_dictionary); } } } static void pm_winmm_mapper_output() { WORD wRtn; /* Note: if MIDIMAPPER opened as output (pseudo MIDI device maps device independent messages into device dependant ones, via NT midimapper program) you still should get some setup info */ wRtn = midiOutGetDevCaps((UINT) MIDIMAPPER, (LPMIDIOUTCAPS) & midi_out_mapper_caps, sizeof(MIDIOUTCAPS)); if (wRtn == MMSYSERR_NOERROR) { pm_add_device("MMSystem", midi_out_mapper_caps.szPname, FALSE, (void *) MIDIMAPPER, &pm_winmm_out_dictionary); } } /* ========================================================================================= host error handling ========================================================================================= */ static unsigned int winmm_has_host_error(PmInternal * midi) { midiwinmm_type m = (midiwinmm_type)midi->descriptor; return m->error; } /* str_copy_len -- like strcat, but won't overrun the destination string */ /* * returns length of resulting string */ static int str_copy_len(char *dst, char *src, int len) { strncpy(dst, src, len); /* just in case suffex is greater then len, terminate with zero */ dst[len - 1] = 0; return strlen(dst); } static void winmm_get_host_error(PmInternal * midi, char * msg, UINT len) { /* precondition: midi != NULL */ midiwinmm_node * m = (midiwinmm_node *) midi->descriptor; char *hdr1 = "Host error: "; char *hdr2 = "Host callback error: "; msg[0] = 0; /* initialize result string to empty */ if (descriptors[midi->device_id].pub.input) { /* input and output use different winmm API calls */ if (m) { /* make sure there is an open device to examine */ if (m->error != MMSYSERR_NOERROR) { int n = str_copy_len(msg, hdr1, len); /* read and record host error */ int err = midiInGetErrorText(m->error, msg + n, len - n); assert(err == MMSYSERR_NOERROR); m->error = MMSYSERR_NOERROR; } } } else { /* output port */ if (m) { if (m->error != MMSYSERR_NOERROR) { int n = str_copy_len(msg, hdr1, len); int err = midiOutGetErrorText(m->error, msg + n, len - n); assert(err == MMSYSERR_NOERROR); m->error = MMSYSERR_NOERROR; } } } } /* ============================================================================= buffer handling ============================================================================= */ static MIDIHDR *allocate_buffer(long data_size) { LPMIDIHDR hdr = (LPMIDIHDR) pm_alloc(MIDIHDR_SYSEX_SIZE(data_size)); MIDIEVENT *evt; if (!hdr) return NULL; evt = (MIDIEVENT *) (hdr + 1); /* place MIDIEVENT after header */ hdr->lpData = (LPSTR) evt; hdr->dwBufferLength = MIDIHDR_SYSEX_BUFFER_LENGTH(data_size); hdr->dwBytesRecorded = 0; hdr->dwFlags = 0; hdr->dwUser = hdr->dwBufferLength; return hdr; } #ifdef USE_SYSEX_BUFFERS static MIDIHDR *allocate_sysex_buffer(long data_size) { /* we're actually allocating more than data_size because the buffer * will include the MIDIEVENT header in addition to the data */ LPMIDIHDR hdr = (LPMIDIHDR) pm_alloc(MIDIHDR_SYSEX_SIZE(data_size)); MIDIEVENT *evt; if (!hdr) return NULL; evt = (MIDIEVENT *) (hdr + 1); /* place MIDIEVENT after header */ hdr->lpData = (LPSTR) evt; hdr->dwFlags = 0; hdr->dwUser = 0; return hdr; } #endif static PmError allocate_buffers(midiwinmm_type m, long data_size, long count) { int i; /* buffers is an array of count pointers to MIDIHDR/MIDIEVENT struct */ m->num_buffers = 0; /* in case no memory can be allocated */ m->buffers = (LPMIDIHDR *) pm_alloc(sizeof(LPMIDIHDR) * count); if (!m->buffers) return pmInsufficientMemory; m->max_buffers = count; for (i = 0; i < count; i++) { LPMIDIHDR hdr = allocate_buffer(data_size); if (!hdr) { /* free everything allocated so far and return */ for (i = i - 1; i >= 0; i--) pm_free(m->buffers[i]); pm_free(m->buffers); m->max_buffers = 0; return pmInsufficientMemory; } m->buffers[i] = hdr; /* this may be NULL if allocation fails */ } m->num_buffers = count; return pmNoError; } #ifdef USE_SYSEX_BUFFERS static PmError allocate_sysex_buffers(midiwinmm_type m, long data_size) { PmError rslt = pmNoError; /* sysex_buffers is an array of count pointers to MIDIHDR/MIDIEVENT struct */ int i; for (i = 0; i < NUM_SYSEX_BUFFERS; i++) { LPMIDIHDR hdr = allocate_sysex_buffer(data_size); if (!hdr) rslt = pmInsufficientMemory; m->sysex_buffers[i] = hdr; /* this may be NULL if allocation fails */ hdr->dwFlags = 0; /* mark as free */ } return rslt; } #endif #ifdef USE_SYSEX_BUFFERS static LPMIDIHDR get_free_sysex_buffer(PmInternal *midi) { LPMIDIHDR r = NULL; midiwinmm_type m = (midiwinmm_type) midi->descriptor; if (!m->sysex_buffers[0]) { if (allocate_sysex_buffers(m, SYSEX_BYTES_PER_BUFFER)) { return NULL; } } /* busy wait until we find a free buffer */ while (TRUE) { int i; for (i = 0; i < NUM_SYSEX_BUFFERS; i++) { /* cycle through buffers, modulo NUM_SYSEX_BUFFERS */ m->next_sysex_buffer++; if (m->next_sysex_buffer >= NUM_SYSEX_BUFFERS) m->next_sysex_buffer = 0; r = m->sysex_buffers[m->next_sysex_buffer]; if ((r->dwFlags & MHDR_PREPARED) == 0) goto found_sysex_buffer; } /* after scanning every buffer and not finding anything, block */ if (WaitForSingleObject(m->buffer_signal, 1000) == WAIT_TIMEOUT) { #ifdef DEBUG printf("PortMidi warning: get_free_sysex_buffer() wait timed out after 1000ms\n"); #endif } } found_sysex_buffer: r->dwBytesRecorded = 0; r->dwBufferLength = 0; /* changed to correct value later */ return r; } #endif static LPMIDIHDR get_free_output_buffer(PmInternal *midi) { LPMIDIHDR r = NULL; midiwinmm_type m = (midiwinmm_type) midi->descriptor; while (TRUE) { int i; for (i = 0; i < m->num_buffers; i++) { /* cycle through buffers, modulo m->num_buffers */ m->next_buffer++; if (m->next_buffer >= m->num_buffers) m->next_buffer = 0; r = m->buffers[m->next_buffer]; if ((r->dwFlags & MHDR_PREPARED) == 0) goto found_buffer; } /* after scanning every buffer and not finding anything, block */ if (WaitForSingleObject(m->buffer_signal, 1000) == WAIT_TIMEOUT) { #ifdef DEBUG printf("PortMidi warning: get_free_output_buffer() wait timed out after 1000ms\n"); #endif /* if we're trying to send a sysex message, maybe the * message is too big and we need more message buffers. * Expand the buffer pool by 128KB using 1024-byte buffers. */ /* first, expand the buffers array if necessary */ if (!m->buffers_expanded) { LPMIDIHDR *new_buffers = (LPMIDIHDR *) pm_alloc( (m->num_buffers + NUM_EXPANSION_BUFFERS) * sizeof(LPMIDIHDR)); /* if no memory, we could return a no-memory error, but user * probably will be unprepared to deal with it. Maybe the * MIDI driver is temporarily hung so we should just wait. * I don't know the right answer, but waiting is easier. */ if (!new_buffers) continue; /* copy buffers to new_buffers and replace buffers */ memcpy(new_buffers, m->buffers, m->num_buffers * sizeof(LPMIDIHDR)); pm_free(m->buffers); m->buffers = new_buffers; m->max_buffers = m->num_buffers + NUM_EXPANSION_BUFFERS; m->buffers_expanded = TRUE; } /* next, add one buffer and return it */ if (m->num_buffers < m->max_buffers) { r = allocate_buffer(EXPANSION_BUFFER_LEN); /* again, if there's no memory, we may not really be * dead -- maybe the system is temporarily hung and * we can just wait longer for a message buffer */ if (!r) continue; m->buffers[m->num_buffers++] = r; goto found_buffer; /* break out of 2 loops */ } /* else, we've allocated all NUM_EXPANSION_BUFFERS buffers, * and we have no free buffers to send. We'll just keep * polling to see if any buffers show up. */ } } found_buffer: r->dwBytesRecorded = 0; /* actual buffer length is saved in dwUser field */ r->dwBufferLength = (DWORD) r->dwUser; return r; } #ifdef EXPANDING_SYSEX_BUFFERS note: this is not working code, but might be useful if you want to grow sysex buffers. static PmError resize_sysex_buffer(PmInternal *midi, long old_size, long new_size) { LPMIDIHDR big; int i; midiwinmm_type m = (midiwinmm_type) midi->descriptor; /* buffer must be smaller than 64k, but be also a multiple of 4 */ if (new_size > 65520) { if (old_size >= 65520) return pmBufferMaxSize; else new_size = 65520; } /* allocate a bigger message */ big = allocate_sysex_buffer(new_size); /* printf("expand to %d bytes\n", new_size);*/ if (!big) return pmInsufficientMemory; m->error = midiOutPrepareHeader(m->handle.out, big, sizeof(MIDIHDR)); if (m->error) { pm_free(big); return pmHostError; } /* make sure we're not going to overwrite any memory */ assert(old_size <= new_size); memcpy(big->lpData, m->hdr->lpData, old_size); /* keep track of how many sysex bytes are in message so far */ big->dwBytesRecorded = m->hdr->dwBytesRecorded; big->dwBufferLength = new_size; /* find which buffer this was, and replace it */ for (i = 0; i < NUM_SYSEX_BUFFERS; i++) { if (m->sysex_buffers[i] == m->hdr) { m->sysex_buffers[i] = big; m->sysex_buffer_size[i] = new_size; pm_free(m->hdr); m->hdr = big; break; } } assert(i != NUM_SYSEX_BUFFERS); return pmNoError; } #endif /* ========================================================================================= begin midi input implementation ========================================================================================= */ static PmError allocate_input_buffer(HMIDIIN h, long buffer_len) { LPMIDIHDR hdr = allocate_buffer(buffer_len); if (!hdr) return pmInsufficientMemory; pm_hosterror = midiInPrepareHeader(h, hdr, sizeof(MIDIHDR)); if (pm_hosterror) { pm_free(hdr); return pm_hosterror; } pm_hosterror = midiInAddBuffer(h, hdr, sizeof(MIDIHDR)); return pm_hosterror; } static PmError winmm_in_open(PmInternal *midi, void *driverInfo) { DWORD dwDevice; int i = midi->device_id; int max_sysex_len = midi->buffer_len * 4; int num_input_buffers = max_sysex_len / INPUT_SYSEX_LEN; midiwinmm_type m; dwDevice = (DWORD) descriptors[i].descriptor; /* create system dependent device data */ m = (midiwinmm_type) pm_alloc(sizeof(midiwinmm_node)); /* create */ midi->descriptor = m; if (!m) goto no_memory; m->handle.in = NULL; m->buffers = NULL; /* not used for input */ m->num_buffers = 0; /* not used for input */ m->max_buffers = FALSE; /* not used for input */ m->buffers_expanded = 0; /* not used for input */ m->next_buffer = 0; /* not used for input */ m->buffer_signal = 0; /* not used for input */ #ifdef USE_SYSEX_BUFFERS for (i = 0; i < NUM_SYSEX_BUFFERS; i++) m->sysex_buffers[i] = NULL; /* not used for input */ m->next_sysex_buffer = 0; /* not used for input */ #endif m->last_time = 0; m->first_message = TRUE; /* not used for input */ m->sysex_mode = FALSE; m->sysex_word = 0; m->sysex_byte_count = 0; m->hdr = NULL; /* not used for input */ m->sync_time = 0; m->delta = 0; m->error = MMSYSERR_NOERROR; /* 4000 is based on Windows documentation -- that's the value used in the memory manager. It's small enough that it should not hurt performance even if it's not optimal. */ InitializeCriticalSectionAndSpinCount(&m->lock, 4000); /* open device */ pm_hosterror = midiInOpen( &(m->handle.in), /* input device handle */ dwDevice, /* device ID */ (DWORD_PTR) winmm_in_callback, /* callback address */ (DWORD_PTR) midi, /* callback instance data */ CALLBACK_FUNCTION); /* callback is a procedure */ if (pm_hosterror) goto free_descriptor; if (num_input_buffers < MIN_INPUT_BUFFERS) num_input_buffers = MIN_INPUT_BUFFERS; for (i = 0; i < num_input_buffers; i++) { if (allocate_input_buffer(m->handle.in, INPUT_SYSEX_LEN)) { /* either pm_hosterror was set, or the proper return code is pmInsufficientMemory */ goto close_device; } } /* start device */ pm_hosterror = midiInStart(m->handle.in); if (pm_hosterror) goto reset_device; return pmNoError; /* undo steps leading up to the detected error */ reset_device: /* ignore return code (we already have an error to report) */ midiInReset(m->handle.in); close_device: midiInClose(m->handle.in); /* ignore return code */ free_descriptor: midi->descriptor = NULL; pm_free(m); no_memory: if (pm_hosterror) { int err = midiInGetErrorText(pm_hosterror, (char *) pm_hosterror_text, PM_HOST_ERROR_MSG_LEN); assert(err == MMSYSERR_NOERROR); return pmHostError; } /* if !pm_hosterror, then the error must be pmInsufficientMemory */ return pmInsufficientMemory; /* note: if we return an error code, the device will be closed and memory will be freed. It's up to the caller to free the parameter midi */ } static PmError winmm_in_poll(PmInternal *midi) { midiwinmm_type m = (midiwinmm_type) midi->descriptor; return m->error; } /* winmm_in_close -- close an open midi input device */ /* * assume midi is non-null (checked by caller) */ static PmError winmm_in_close(PmInternal *midi) { midiwinmm_type m = (midiwinmm_type) midi->descriptor; if (!m) return pmBadPtr; /* device to close */ if (pm_hosterror = midiInStop(m->handle.in)) { midiInReset(m->handle.in); /* try to reset and close port */ midiInClose(m->handle.in); } else if (pm_hosterror = midiInReset(m->handle.in)) { midiInClose(m->handle.in); /* best effort to close midi port */ } else { pm_hosterror = midiInClose(m->handle.in); } midi->descriptor = NULL; DeleteCriticalSection(&m->lock); pm_free(m); /* delete */ if (pm_hosterror) { int err = midiInGetErrorText(pm_hosterror, (char *) pm_hosterror_text, PM_HOST_ERROR_MSG_LEN); assert(err == MMSYSERR_NOERROR); return pmHostError; } return pmNoError; } /* Callback function executed via midiInput SW interrupt (via midiInOpen). */ static void FAR PASCAL winmm_in_callback( HMIDIIN hMidiIn, /* midiInput device Handle */ WORD wMsg, /* midi msg */ DWORD dwInstance, /* application data */ DWORD dwParam1, /* MIDI data */ DWORD dwParam2) /* device timestamp (wrt most recent midiInStart) */ { static int entry = 0; PmInternal *midi = (PmInternal *) dwInstance; midiwinmm_type m = (midiwinmm_type) midi->descriptor; /* NOTE: we do not just EnterCriticalSection() here because an * MIM_CLOSE message arrives when the port is closed, but then * the m->lock has been destroyed. */ switch (wMsg) { case MIM_DATA: { /* if this callback is reentered with data, we're in trouble. * It's hard to imagine that Microsoft would allow callbacks * to be reentrant -- isn't the model that this is like a * hardware interrupt? -- but I've seen reentrant behavior * using a debugger, so it happens. */ long new_driver_time; EnterCriticalSection(&m->lock); /* dwParam1 is MIDI data received, packed into DWORD w/ 1st byte of message LOB; dwParam2 is time message received by input device driver, specified in [ms] from when midiInStart called. each message is expanded to include the status byte */ new_driver_time = dwParam2; if ((dwParam1 & 0x80) == 0) { /* not a status byte -- ignore it. This happened running the sysex.c test under Win2K with MidiMan USB 1x1 interface, but I can't reproduce it. -RBD */ /* printf("non-status byte found\n"); */ } else { /* data to process */ PmEvent event; if (midi->time_proc) dwParam2 = (*midi->time_proc)(midi->time_info); event.timestamp = dwParam2; event.message = dwParam1; pm_read_short(midi, &event); } LeaveCriticalSection(&m->lock); break; } case MIM_LONGDATA: { MIDIHDR *lpMidiHdr = (MIDIHDR *) dwParam1; unsigned char *data = (unsigned char *) lpMidiHdr->lpData; unsigned int processed = 0; int remaining = lpMidiHdr->dwBytesRecorded; EnterCriticalSection(&m->lock); /* printf("midi_in_callback -- lpMidiHdr %x, %d bytes, %2x...\n", lpMidiHdr, lpMidiHdr->dwBytesRecorded, *data); */ if (midi->time_proc) dwParam2 = (*midi->time_proc)(midi->time_info); /* can there be more than one message in one buffer? */ /* assume yes and iterate through them */ while (remaining > 0) { unsigned int amt = pm_read_bytes(midi, data + processed, remaining, dwParam2); remaining -= amt; processed += amt; } /* when a device is closed, the pending MIM_LONGDATA buffers are returned to this callback with dwBytesRecorded == 0. In this case, we do not want to send them back to the interface (if we do, the interface will not close, and Windows OS may hang). */ if (lpMidiHdr->dwBytesRecorded > 0) { MMRESULT rslt; lpMidiHdr->dwBytesRecorded = 0; lpMidiHdr->dwFlags = 0; /* note: no error checking -- can this actually fail? */ rslt = midiInPrepareHeader(hMidiIn, lpMidiHdr, sizeof(MIDIHDR)); assert(rslt == MMSYSERR_NOERROR); /* note: I don't think this can fail except possibly for * MMSYSERR_NOMEM, but the pain of reporting this * unlikely but probably catastrophic error does not seem * worth it. */ rslt = midiInAddBuffer(hMidiIn, lpMidiHdr, sizeof(MIDIHDR)); assert(rslt == MMSYSERR_NOERROR); LeaveCriticalSection(&m->lock); } else { midiInUnprepareHeader(hMidiIn,lpMidiHdr,sizeof(MIDIHDR)); LeaveCriticalSection(&m->lock); pm_free(lpMidiHdr); } break; } case MIM_OPEN: break; case MIM_CLOSE: break; case MIM_ERROR: /* printf("MIM_ERROR\n"); */ break; case MIM_LONGERROR: /* printf("MIM_LONGERROR\n"); */ break; default: break; } } /* ========================================================================================= begin midi output implementation ========================================================================================= */ /* begin helper routines used by midiOutStream interface */ /* add_to_buffer -- adds timestamped short msg to buffer, returns fullp */ static int add_to_buffer(midiwinmm_type m, LPMIDIHDR hdr, unsigned long delta, unsigned long msg) { unsigned long *ptr = (unsigned long *) (hdr->lpData + hdr->dwBytesRecorded); *ptr++ = delta; /* dwDeltaTime */ *ptr++ = 0; /* dwStream */ *ptr++ = msg; /* dwEvent */ hdr->dwBytesRecorded += 3 * sizeof(long); /* if the addition of three more words (a message) would extend beyond the buffer length, then return TRUE (full) */ return hdr->dwBytesRecorded + 3 * sizeof(long) > hdr->dwBufferLength; } static PmTimestamp pm_time_get(midiwinmm_type m) { MMTIME mmtime; MMRESULT wRtn; mmtime.wType = TIME_TICKS; mmtime.u.ticks = 0; wRtn = midiStreamPosition(m->handle.stream, &mmtime, sizeof(mmtime)); assert(wRtn == MMSYSERR_NOERROR); return mmtime.u.ticks; } /* end helper routines used by midiOutStream interface */ static PmError winmm_out_open(PmInternal *midi, void *driverInfo) { DWORD dwDevice; int i = midi->device_id; midiwinmm_type m; MIDIPROPTEMPO propdata; MIDIPROPTIMEDIV divdata; int max_sysex_len = midi->buffer_len * 4; int output_buffer_len; int num_buffers; dwDevice = (DWORD) descriptors[i].descriptor; /* create system dependent device data */ m = (midiwinmm_type) pm_alloc(sizeof(midiwinmm_node)); /* create */ midi->descriptor = m; if (!m) goto no_memory; m->handle.out = NULL; m->buffers = NULL; m->num_buffers = 0; m->max_buffers = 0; m->buffers_expanded = FALSE; m->next_buffer = 0; #ifdef USE_SYSEX_BUFFERS m->sysex_buffers[0] = NULL; m->sysex_buffers[1] = NULL; m->next_sysex_buffer = 0; #endif m->last_time = 0; m->first_message = TRUE; /* we treat first message as special case */ m->sysex_mode = FALSE; m->sysex_word = 0; m->sysex_byte_count = 0; m->hdr = NULL; m->sync_time = 0; m->delta = 0; m->error = MMSYSERR_NOERROR; /* create a signal */ m->buffer_signal = CreateEvent(NULL, FALSE, FALSE, NULL); /* this should only fail when there are very serious problems */ assert(m->buffer_signal); /* open device */ if (midi->latency == 0) { /* use simple midi out calls */ pm_hosterror = midiOutOpen( (LPHMIDIOUT) & m->handle.out, /* device Handle */ dwDevice, /* device ID */ /* note: same callback fn as for StreamOpen: */ (DWORD_PTR) winmm_streamout_callback, /* callback fn */ (DWORD_PTR) midi, /* callback instance data */ CALLBACK_FUNCTION); /* callback type */ } else { /* use stream-based midi output (schedulable in future) */ pm_hosterror = midiStreamOpen( &m->handle.stream, /* device Handle */ (LPUINT) & dwDevice, /* device ID pointer */ 1, /* reserved, must be 1 */ (DWORD_PTR) winmm_streamout_callback, (DWORD_PTR) midi, /* callback instance data */ CALLBACK_FUNCTION); } if (pm_hosterror != MMSYSERR_NOERROR) { goto free_descriptor; } if (midi->latency == 0) { num_buffers = NUM_SIMPLE_SYSEX_BUFFERS; output_buffer_len = max_sysex_len / num_buffers; if (output_buffer_len < MIN_SIMPLE_SYSEX_LEN) output_buffer_len = MIN_SIMPLE_SYSEX_LEN; } else { long dur = 0; num_buffers = max(midi->buffer_len, midi->latency / 2); if (num_buffers < MIN_STREAM_BUFFERS) num_buffers = MIN_STREAM_BUFFERS; output_buffer_len = STREAM_BUFFER_LEN; propdata.cbStruct = sizeof(MIDIPROPTEMPO); propdata.dwTempo = 480000; /* microseconds per quarter */ pm_hosterror = midiStreamProperty(m->handle.stream, (LPBYTE) & propdata, MIDIPROP_SET | MIDIPROP_TEMPO); if (pm_hosterror) goto close_device; divdata.cbStruct = sizeof(MIDIPROPTEMPO); divdata.dwTimeDiv = 480; /* divisions per quarter */ pm_hosterror = midiStreamProperty(m->handle.stream, (LPBYTE) & divdata, MIDIPROP_SET | MIDIPROP_TIMEDIV); if (pm_hosterror) goto close_device; } /* allocate buffers */ if (allocate_buffers(m, output_buffer_len, num_buffers)) goto free_buffers; /* start device */ if (midi->latency != 0) { pm_hosterror = midiStreamRestart(m->handle.stream); if (pm_hosterror != MMSYSERR_NOERROR) goto free_buffers; } return pmNoError; free_buffers: /* buffers are freed below by winmm_out_delete */ close_device: midiOutClose(m->handle.out); free_descriptor: midi->descriptor = NULL; winmm_out_delete(midi); /* frees buffers and m */ no_memory: if (pm_hosterror) { int err = midiOutGetErrorText(pm_hosterror, (char *) pm_hosterror_text, PM_HOST_ERROR_MSG_LEN); assert(err == MMSYSERR_NOERROR); return pmHostError; } return pmInsufficientMemory; } /* winmm_out_delete -- carefully free data associated with midi */ /**/ static void winmm_out_delete(PmInternal *midi) { int i; /* delete system dependent device data */ midiwinmm_type m = (midiwinmm_type) midi->descriptor; if (m) { if (m->buffer_signal) { /* don't report errors -- better not to stop cleanup */ CloseHandle(m->buffer_signal); } /* if using stream output, free buffers */ for (i = 0; i < m->num_buffers; i++) { if (m->buffers[i]) pm_free(m->buffers[i]); } m->num_buffers = 0; pm_free(m->buffers); m->max_buffers = 0; #ifdef USE_SYSEX_BUFFERS /* free sysex buffers */ for (i = 0; i < NUM_SYSEX_BUFFERS; i++) { if (m->sysex_buffers[i]) pm_free(m->sysex_buffers[i]); } #endif } midi->descriptor = NULL; pm_free(m); /* delete */ } /* see comments for winmm_in_close */ static PmError winmm_out_close(PmInternal *midi) { midiwinmm_type m = (midiwinmm_type) midi->descriptor; if (m->handle.out) { /* device to close */ if (midi->latency == 0) { pm_hosterror = midiOutClose(m->handle.out); } else { pm_hosterror = midiStreamClose(m->handle.stream); } /* regardless of outcome, free memory */ winmm_out_delete(midi); } if (pm_hosterror) { int err = midiOutGetErrorText(pm_hosterror, (char *) pm_hosterror_text, PM_HOST_ERROR_MSG_LEN); assert(err == MMSYSERR_NOERROR); return pmHostError; } return pmNoError; } static PmError winmm_out_abort(PmInternal *midi) { midiwinmm_type m = (midiwinmm_type) midi->descriptor; m->error = MMSYSERR_NOERROR; /* only stop output streams */ if (midi->latency > 0) { m->error = midiStreamStop(m->handle.stream); } return m->error ? pmHostError : pmNoError; } static PmError winmm_write_flush(PmInternal *midi, PmTimestamp timestamp) { midiwinmm_type m = (midiwinmm_type) midi->descriptor; assert(m); if (m->hdr) { m->error = midiOutPrepareHeader(m->handle.out, m->hdr, sizeof(MIDIHDR)); if (m->error) { /* do not send message */ } else if (midi->latency == 0) { /* As pointed out by Nigel Brown, 20Sep06, dwBytesRecorded * should be zero. This is set in get_free_sysex_buffer(). * The msg length goes in dwBufferLength in spite of what * Microsoft documentation says (or doesn't say). */ m->hdr->dwBufferLength = m->hdr->dwBytesRecorded; m->hdr->dwBytesRecorded = 0; m->error = midiOutLongMsg(m->handle.out, m->hdr, sizeof(MIDIHDR)); } else { m->error = midiStreamOut(m->handle.stream, m->hdr, sizeof(MIDIHDR)); } midi->fill_base = NULL; m->hdr = NULL; if (m->error) { m->hdr->dwFlags = 0; /* release the buffer */ return pmHostError; } } return pmNoError; } #ifdef GARBAGE static PmError winmm_write_sysex_byte(PmInternal *midi, unsigned char byte) { midiwinmm_type m = (midiwinmm_type) midi->descriptor; unsigned char *msg_buffer; /* at the beginning of sysex, m->hdr is NULL */ if (!m->hdr) { /* allocate a buffer if none allocated yet */ m->hdr = get_free_output_buffer(midi); if (!m->hdr) return pmInsufficientMemory; m->sysex_byte_count = 0; } /* figure out where to write byte */ msg_buffer = (unsigned char *) (m->hdr->lpData); assert(m->hdr->lpData == (char *) (m->hdr + 1)); /* check for overflow */ if (m->sysex_byte_count >= m->hdr->dwBufferLength) { /* allocate a bigger message -- double it every time */ LPMIDIHDR big = allocate_buffer(m->sysex_byte_count * 2); /* printf("expand to %d bytes\n", m->sysex_byte_count * 2); */ if (!big) return pmInsufficientMemory; m->error = midiOutPrepareHeader(m->handle.out, big, sizeof(MIDIHDR)); if (m->error) { m->hdr = NULL; return pmHostError; } memcpy(big->lpData, msg_buffer, m->sysex_byte_count); msg_buffer = (unsigned char *) (big->lpData); if (m->buffers[0] == m->hdr) { m->buffers[0] = big; pm_free(m->hdr); /* printf("freed m->hdr\n"); */ } else if (m->buffers[1] == m->hdr) { m->buffers[1] = big; pm_free(m->hdr); /* printf("freed m->hdr\n"); */ } m->hdr = big; } /* append byte to message */ msg_buffer[m->sysex_byte_count++] = byte; /* see if we have a complete message */ if (byte == MIDI_EOX) { m->hdr->dwBytesRecorded = m->sysex_byte_count; /* { int i; int len = m->hdr->dwBytesRecorded; printf("OutLongMsg %d ", len); for (i = 0; i < len; i++) { printf("%2x ", msg_buffer[i]); } } */ m->error = midiOutLongMsg(m->handle.out, m->hdr, sizeof(MIDIHDR)); m->hdr = NULL; /* stop using this message buffer */ if (m->error) return pmHostError; } return pmNoError; } #endif static PmError winmm_write_short(PmInternal *midi, PmEvent *event) { midiwinmm_type m = (midiwinmm_type) midi->descriptor; PmError rslt = pmNoError; assert(m); if (midi->latency == 0) { /* use midiOut interface, ignore timestamps */ m->error = midiOutShortMsg(m->handle.out, event->message); if (m->error) rslt = pmHostError; } else { /* use midiStream interface -- pass data through buffers */ unsigned long when = event->timestamp; unsigned long delta; int full; if (when == 0) when = midi->now; /* when is in real_time; translate to intended stream time */ when = when + m->delta + midi->latency; /* make sure we don't go backward in time */ if (when < m->last_time) when = m->last_time; delta = when - m->last_time; m->last_time = when; /* before we insert any data, we must have a buffer */ if (m->hdr == NULL) { /* stream interface: buffers allocated when stream is opened */ m->hdr = get_free_output_buffer(midi); } full = add_to_buffer(m, m->hdr, delta, event->message); if (full) rslt = winmm_write_flush(midi, when); } return rslt; } #define winmm_begin_sysex winmm_write_flush #ifndef winmm_begin_sysex static PmError winmm_begin_sysex(PmInternal *midi, PmTimestamp timestamp) { midiwinmm_type m = (midiwinmm_type) midi->descriptor; PmError rslt = pmNoError; if (midi->latency == 0) { /* do nothing -- it's handled in winmm_write_byte */ } else { /* sysex expects an empty sysex buffer, so send whatever is here */ rslt = winmm_write_flush(midi); } return rslt; } #endif static PmError winmm_end_sysex(PmInternal *midi, PmTimestamp timestamp) { /* could check for callback_error here, but I haven't checked * what happens if we exit early and don't finish the sysex msg * and clean up */ midiwinmm_type m = (midiwinmm_type) midi->descriptor; PmError rslt = pmNoError; LPMIDIHDR hdr = m->hdr; if (!hdr) return rslt; /* something bad happened earlier, do not report an error because it would have been reported (at least) once already */ /* a(n old) version of MIDI YOKE requires a zero byte after * the sysex message, but do not increment dwBytesRecorded: */ hdr->lpData[hdr->dwBytesRecorded] = 0; if (midi->latency == 0) { #ifdef DEBUG_PRINT_BEFORE_SENDING_SYSEX /* DEBUG CODE: */ { int i; int len = m->hdr->dwBufferLength; printf("OutLongMsg %d ", len); for (i = 0; i < len; i++) { printf("%2x ", (unsigned char) (m->hdr->lpData[i])); } } #endif } else { /* Using stream interface. There are accumulated bytes in m->hdr to send using midiStreamOut */ /* add bytes recorded to MIDIEVENT length, but don't count the MIDIEVENT data (3 longs) */ MIDIEVENT *evt = (MIDIEVENT *) (hdr->lpData); evt->dwEvent += hdr->dwBytesRecorded - 3 * sizeof(long); /* round up BytesRecorded to multiple of 4 */ hdr->dwBytesRecorded = (hdr->dwBytesRecorded + 3) & ~3; } rslt = winmm_write_flush(midi, timestamp); return rslt; } static PmError winmm_write_byte(PmInternal *midi, unsigned char byte, PmTimestamp timestamp) { /* write a sysex byte */ PmError rslt = pmNoError; midiwinmm_type m = (midiwinmm_type) midi->descriptor; LPMIDIHDR hdr = m->hdr; unsigned char *msg_buffer; assert(m); if (!hdr) { m->hdr = hdr = get_free_output_buffer(midi); assert(hdr); midi->fill_base = (unsigned char *) m->hdr->lpData; midi->fill_offset_ptr = &(hdr->dwBytesRecorded); /* when buffer fills, Pm_WriteSysEx will revert to calling * pmwin_write_byte, which expect to have space, so leave * one byte free for pmwin_write_byte. Leave another byte * of space for zero after message to make early version of * MIDI YOKE driver happy -- therefore dwBufferLength - 2 */ midi->fill_length = hdr->dwBufferLength - 2; if (midi->latency != 0) { unsigned long when = (unsigned long) timestamp; unsigned long delta; unsigned long *ptr; if (when == 0) when = midi->now; /* when is in real_time; translate to intended stream time */ when = when + m->delta + midi->latency; /* make sure we don't go backward in time */ if (when < m->last_time) when = m->last_time; delta = when - m->last_time; m->last_time = when; ptr = (unsigned long *) hdr->lpData; *ptr++ = delta; *ptr++ = 0; *ptr = MEVT_F_LONG; hdr->dwBytesRecorded = 3 * sizeof(long); /* data will be added at an offset of dwBytesRecorded ... */ } } /* add the data byte */ msg_buffer = (unsigned char *) (hdr->lpData); msg_buffer[hdr->dwBytesRecorded++] = byte; /* see if buffer is full, leave one byte extra for pad */ if (hdr->dwBytesRecorded >= hdr->dwBufferLength - 1) { /* write what we've got and continue */ rslt = winmm_end_sysex(midi, timestamp); } return rslt; } #ifdef EXPANDING_SYSEX_BUFFERS note: this code is here as an aid in case you want sysex buffers to expand to hold large messages completely. If so, you will want to change SYSEX_BYTES_PER_BUFFER above to some variable that remembers the buffer size. A good place to put this value would be in the hdr->dwUser field. rslt = resize_sysex_buffer(midi, m->sysex_byte_count, m->sysex_byte_count * 2); if (rslt == pmBufferMaxSize) /* if the buffer can't be resized */ #endif #ifdef EXPANDING_SYSEX_BUFFERS int bytesRecorded = hdr->dwBytesRecorded; /* this field gets wiped out, so we'll save it */ rslt = resize_sysex_buffer(midi, bytesRecorded, 2 * bytesRecorded); hdr->dwBytesRecorded = bytesRecorded; if (rslt == pmBufferMaxSize) /* if buffer can't be resized */ #endif static PmTimestamp winmm_synchronize(PmInternal *midi) { midiwinmm_type m; unsigned long pm_stream_time_2; unsigned long real_time; unsigned long pm_stream_time; /* only synchronize if we are using stream interface */ if (midi->latency == 0) return 0; /* figure out the time */ m = (midiwinmm_type) midi->descriptor; pm_stream_time_2 = pm_time_get(m); do { /* read real_time between two reads of stream time */ pm_stream_time = pm_stream_time_2; real_time = (*midi->time_proc)(midi->time_info); pm_stream_time_2 = pm_time_get(m); /* repeat if more than 1ms elapsed */ } while (pm_stream_time_2 > pm_stream_time + 1); m->delta = pm_stream_time - real_time; m->sync_time = real_time; return real_time; } #ifdef USE_SYSEX_BUFFERS /* winmm_out_callback -- recycle sysex buffers */ static void CALLBACK winmm_out_callback(HMIDIOUT hmo, UINT wMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) { PmInternal *midi = (PmInternal *) dwInstance; midiwinmm_type m = (midiwinmm_type) midi->descriptor; LPMIDIHDR hdr = (LPMIDIHDR) dwParam1; int err = 0; /* set to 0 so that no buffer match will also be an error */ /* Future optimization: eliminate UnprepareHeader calls -- they aren't necessary; however, this code uses the prepared-flag to indicate which buffers are free, so we need to do something to flag empty buffers if we leave them prepared */ /* printf("out_callback: hdr %x, wMsg %x, MOM_DONE %x\n", hdr, wMsg, MOM_DONE); */ if (wMsg == MOM_DONE) { MMRESULT ret = midiOutUnprepareHeader(m->handle.out, hdr, sizeof(MIDIHDR)); assert(ret == MMSYSERR_NOERROR); } /* notify waiting sender that a buffer is available */ err = SetEvent(m->buffer_signal); assert(err); /* false -> error */ } #endif /* winmm_streamout_callback -- unprepare (free) buffer header */ static void CALLBACK winmm_streamout_callback(HMIDIOUT hmo, UINT wMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) { PmInternal *midi = (PmInternal *) dwInstance; midiwinmm_type m = (midiwinmm_type) midi->descriptor; LPMIDIHDR hdr = (LPMIDIHDR) dwParam1; int err; /* Even if an error is pending, I think we should unprepare msgs and signal their arrival */ /* printf("streamout_callback: hdr %x, wMsg %x, MOM_DONE %x\n", hdr, wMsg, MOM_DONE); */ if (wMsg == MOM_DONE) { MMRESULT ret = midiOutUnprepareHeader(m->handle.out, hdr, sizeof(MIDIHDR)); assert(ret == MMSYSERR_NOERROR); } /* signal client in case it is blocked waiting for buffer */ err = SetEvent(m->buffer_signal); assert(err); /* false -> error */ } /* ========================================================================================= begin exported functions ========================================================================================= */ #define winmm_in_abort pm_fail_fn pm_fns_node pm_winmm_in_dictionary = { none_write_short, none_sysex, none_sysex, none_write_byte, none_write_short, none_write_flush, winmm_synchronize, winmm_in_open, winmm_in_abort, winmm_in_close, winmm_in_poll, winmm_has_host_error, winmm_get_host_error }; pm_fns_node pm_winmm_out_dictionary = { winmm_write_short, winmm_begin_sysex, winmm_end_sysex, winmm_write_byte, winmm_write_short, /* short realtime message */ winmm_write_flush, winmm_synchronize, winmm_out_open, winmm_out_abort, winmm_out_close, none_poll, winmm_has_host_error, winmm_get_host_error }; /* initialize winmm interface. Note that if there is something wrong with winmm (e.g. it is not supported or installed), it is not an error. We should simply return without having added any devices to the table. Hence, no error code is returned. Furthermore, this init code is called along with every other supported interface, so the user would have a very hard time figuring out what hardware and API generated the error. Finally, it would add complexity to pmwin.c to remember where the error code came from in order to convert to text. */ void pm_winmm_init( void ) { pm_winmm_mapper_input(); pm_winmm_mapper_output(); pm_winmm_general_inputs(); pm_winmm_general_outputs(); } /* no error codes are returned, even if errors are encountered, because there is probably nothing the user could do (e.g. it would be an error to retry. */ void pm_winmm_term( void ) { int i; #ifdef DEBUG char msg[PM_HOST_ERROR_MSG_LEN]; #endif int doneAny = 0; #ifdef DEBUG printf("pm_winmm_term called\n"); #endif for (i = 0; i < pm_descriptor_index; i++) { PmInternal * midi = descriptors[i].internalDescriptor; if (midi) { midiwinmm_type m = (midiwinmm_type) midi->descriptor; if (m->handle.out) { /* close next open device*/ #ifdef DEBUG if (doneAny == 0) { printf("begin closing open devices...\n"); doneAny = 1; } /* report any host errors; this EXTEREMELY useful when trying to debug client app */ if (winmm_has_host_error(midi)) { winmm_get_host_error(midi, msg, PM_HOST_ERROR_MSG_LEN); printf("%s\n", msg); } #endif /* close all open ports */ (*midi->dictionary->close)(midi); } } } if (midi_in_caps) { pm_free(midi_in_caps); midi_in_caps = NULL; } if (midi_out_caps) { pm_free(midi_out_caps); midi_out_caps = NULL; } #ifdef DEBUG if (doneAny) { printf("warning: devices were left open. They have been closed.\n"); } printf("pm_winmm_term exiting\n"); #endif pm_descriptor_index = 0; } pd-0.46-7/portmidi/pm_win/pmdll.c0000775000175000017500000000173412160204055014773 0ustar mspmsp/* ==================================================================== DLL to perform action when program shuts down ==================================================================== */ #include "windows.h" #include "pmdll.h" static close_fn_ptr_type close_function = NULL; DLL_EXPORT pm_set_close_function(close_fn_ptr_type close_fn_ptr) { close_function = close_fn_ptr; } static void Initialize( void ) { return; } static void Terminate( void ) { if (close_function) { (*close_function)(); } } BOOL WINAPI DllMain(HINSTANCE hinstDLL, //DLL module handle DWORD fdwReason, //for calling function LPVOID lbpvReserved)//reserved { switch(fdwReason) { case DLL_PROCESS_ATTACH: /* when DLL starts, run this */ Initialize(); break; case DLL_PROCESS_DETACH: /* when DLL ends, this run (note: verified this run */ Terminate(); break; default: break; } return TRUE; } pd-0.46-7/portmidi/pm_win/pmdll.h0000775000175000017500000000023112160204055014767 0ustar mspmsp#define DLL_EXPORT __declspec( dllexport ) typedef void (*close_fn_ptr_type)(); DLL_EXPORT pm_set_close_function(close_fn_ptr_type close_fn_ptr); pd-0.46-7/portmidi/pm_win/README_WIN.txt0000775000175000017500000003767712374245151015762 0ustar mspmspFile: PortMidi Win32 Readme Author: Belinda Thom, June 16 2002 Revised by: Roger Dannenberg, June 2002, May 2004, June 2007, Umpei Kurokawa, June 2007 Roger Dannenberg Sep 2009 Contents: Using Portmidi To Install Portmidi To Compile Portmidi About Cmake Using other versions of Visual C++ To Create Your Own Portmidi Client Application ============================================================================= USING PORTMIDI: ============================================================================= Using Microsoft Visual C++ project files (provided with PortMidi), there are two configurations of the PortMidi library. The Debug version is intended for debugging, especially in a console application. The Debug version enables some extra error checking and outputs some text as well as a prompt to type ENTER so that you don't lose any debugging text when the program exits. You can turn off this extra debugging info by taking out the compile-time definition for DEBUG. (But leave _DEBUG, which I think is important for compiling in Debug mode.) This debugging version also defines PM_CHECK_ERRORS, which forces a check for error return codes from every call to PortMidi. You can disable this checking (especially if you want to handle error codes in your own way) by removing PM_CHECK_ERRORS from the predefined symbols list in the Settings dialog box. PortMidi is designed to run without a console and should work perfectly well within a graphical user interface application. The Release version is both optimized and lacking the debugging printout code of the Debug version. Read the portmidi.h file for PortMidi API details on using the PortMidi API. See <...>\pm_test\test.c and other files in pm_test for usage examples. ============================================================================= TO INSTALL PORTMIDI: ============================================================================= 1) get current source from the portmedia project at SourceForge.net 2) copy source into directory: <...>\portmidi ============================================================================= TO COMPILE PORTMIDI: ============================================================================= 3) cd to or open the portmidi directory 4) start or click on the portmidi.sln workspace (note, all Visual Studio files are built by CMake. If you need a different version or have problems with paths, try rebuilding the Visual Studio project files using CMake -- See "Using other versions of visual C++" below.) 5) the following projects exist within this workspace: - portmidi-static, portmidi-dynamic (versions of the PortMidi library) - test (simple midi I/O testing) - midithread (an example illustrating low-latency MIDI processing using a dedicated low-latency thread) - sysex (simple sysex message I/O testing) - latency (uses porttime to measure system latency) - midithru (an example illustrating software MIDI THRU) - qtest (a test of the new multicore-safe queue implementation) - mm (allows monitoring of midi messages) - pmjni (a dll to provide an interface to PortMidi for Java) 6) set the Java SDK path using one of two methods: Method 1: open portmidi/CMakeLists.txt with CMake, configure, and generate -- this should find the Java SDK path and update your solution and project files Method 2: (does not require CMake): - open the pmjni project properties - visit Configuration Properties, C/C++, General - find Additional Include Directories property and open the editor (...) - at the end of the list, you will find two paths mentioning Java - these are absolute paths to the Java SDK; you'll need to install the Java SDK (from Sun) and update these directories in order to build this project. - similarly, the Linker->Input->Additional Dependencies list has a path to the jvm.lib file, which needs to be correct(ed). 6) use Build->Batch Build ... to build everything in the project. If a build fails, try building again. There seem to be some missing dependencies, so you may have to "ALL_BUILD" several times before everything builds successfully. 7) The settings for these projects were distributed in the zip file, so compile should just work. 8) run test project; use the menu that shows up from the command prompt to test that portMidi works on your system. tests include: - verify midi output works - verify midi input works 9) run other projects if you wish: sysex, latency, midithread, mm, qtest, midithru 10) compile the java code: - cd pm_java - make.bat + If there is a problem running javac, note that you must have a path to javac.exe on your PATH environment variable. Edit your path (in Vista) using Control Panel > User Accounts > User Accounts > Change my environment variables; then select Path and click Edit... After changing, you will have to restart the command window to see any effect. + In Vista, you may get a warning about running UpdateRsrcJavaExe.exe. This is called by make.bat, and you should allow the program to run. + Note that make.bat does not build pmjni\jportmidi_JPortMidiApi.h because it is included in the distribution. You can rebuild it from sources as follows: cd pm_java javah jportmidi.JPortMidiApi move jportmidi_JPortMidiApi pmjni\jportmidi_JPortMidiApi.h 11) you might wish to move pm_java/win32 to another location; run the pmdefaults.exe program from the (entire) win32 directory to use PmDefaults. This program let's you select default input/output midi devices for PortMidi applications. ============================================================================ ABOUT CMAKE ============================================================================ cmake was used to generate .vcproj files. cmake embeds absolute paths into .vcproj files, which makes the files non-portable to other systems. To work around this problem, pm_win\clean_up_vcproj.bat can be used to replace absolute paths with relative paths. To use it, you will need to install gawk and set your search path to allow you to execute gawk, e.g. my path includes "C:\Program Files\GnuWin32\bin;". You will also need to edit pm_win\clean_up_vcproj.awk, replacing C:\Users\rbd\portmidi with whatever absolute path cmake uses in your vcproj files. This is not a general or robust fix, but it seems to work with the vcproj files currently created by CMake. ============================================================================ USING OTHER VERSIONS OF VISUAL C++ ============================================================================ You can use cmake to make Visual Studio solution and project files. If you do not want to use the provided Version 9 project files, install cmake, run it, set the "Where is the source code" box to your portmidi directory, and click on Configure. A menu will allow you to choose the Visual Studio project version you want. Click Configure once again, then Generate, and you should be all set to open portmidi.sln. ============================================================================ TO CREATE YOUR OWN PORTMIDI CLIENT APPLICATION: ============================================================================ NOTE: this section needs to be reviewed and tested. My suggestion would be to copy the test project file (test.dsp) and modify it. -RBD The easiest way is to start a new project w/in the portMidi workspace: 1) To open new project: - File->New->Projects - Location: <...>\portmidi\ - check Add to current workspace - select Win32 Console Application (recommended for now) - do *NOT* select the "make dependency" box (you will explicitly do this in the next step) - Click OK - Select "An Empty Project" and click Finish In Visual C++ 2005 Express Edition, - File->New->Projects - Location: <...>\portmidi\ - select Add to solution - select CLR Empty project in CLR - select Win32 Console Application in Win32 - select Empty project in General 2) Now this project will be the active project. Make it explicitly depend on PortMidi dll: - Project->Dependencies - Click pm_dll 3) add whatever files you wish to add to your new project, using portMidi calls as desired (see USING PORTMIDI at top of this readme) 4) when you include portMidi files, do so like this: - #include "..\pm_common\portmidi.h" - etc. 5) build and run your project ============================================================================ DESIGN NOTES ============================================================================ PortMidi for Win32 exists as a simple static library, with Win32-specific code in pmwin.c and MM-specific code in pmwinmm.c. Orderly cleanup after errors are encountered is based on a fixed order of steps and state changes to reflect each step. Here's the order: To open input: initialize return value to NULL - allocate the PmInternal strucure (representation of PortMidiStream) return value is (non-null) PmInternal structure - allocate midi buffer set buffer field of PmInternal structure - call system-dependent open code - allocate midiwinmm_type for winmm dependent data set descriptor field of PmInternal structure - open device set handle field of midiwinmm_type structure - allocate buffers - start device - return - return SYSEX HANDLING -- the most complex, least exercised, and therefore most buggy part of PortMidi (but maybe bugs are finally gone) There are three cases: simple output, stream output, input Each must deal with: 1. Buffer Initialization (creating buffers) 2. Buffer Allocation (finding a free buffer) 3. Buffer Fill (putting bytes in the buffer) 4. Buffer Preparation (midiOutPrepare, etc.) 5. Buffer Send (to Midi device) 6. Buffer Receive (in callback) 7. Buffer Empty (removing bytes from buffer) 8. Buffer Free (returning to the buffer pool) 9. Buffer Finalization (returning to heap) Here's how simple output handles sysex: 1. Buffer Initialization (creating buffers) allocated when code tries to write first byte to a buffer the test is "if (!m->sysex_buffers[0]) { ... }" this field is initialized to NULL when device is opened the size is SYSEX_BYTES_PER_BUFFER allocate_sysex_buffers() does the initialization note that the actual size of the allocation includes additional space for a MIDIEVENT (3 longs) which are not used in this case 2. Buffer Allocation (finding a free buffer) see get_free_sysex_buffer() cycle through m->sysex_buffers[] using m->next_sysex_buffer to determine where to look next if nothing is found, wait by blocking on m->sysex_buffer_signal this is signaled by the callback every time a message is received 3. Buffer Fill (putting bytes in the buffer) essentially a state machine approach hdr->dwBytesRecorded is a position in message pointed to by m->hdr keep appending bytes until dwBytesRecorded >= SYSEX_BYTES_PER_BUFFER then send the message, reseting the state to initial values 4. Buffer Preparation (midiOutPrepare, etc.) just before sending in winmm_end_sysex() 5. Buffer Send (to Midi device) message is padded with zero at end (since extra space was allocated this is ok) -- the zero works around a bug in (an old version of) MIDI YOKE drivers dwBufferLength gets dwBytesRecorded, and dwBytesRecorded gets 0 uses midiOutLongMsg() 6. Buffer Receive (in callback) 7. Buffer Empty (removing bytes from buffer) not applicable for output 8. Buffer Free (returning to the buffer pool) unprepare message to indicate that it is free SetEvent on m->buffer_signal in case client is waiting 9. Buffer Finalization (returning to heap) when device is closed, winmm_out_delete frees all sysex buffers Here's how stream output handles sysex: 1. Buffer Initialization (creating buffers) same code as simple output (see above) 2. Buffer Allocation (finding a free buffer) same code as simple output (see above) 3. Buffer Fill (putting bytes in the buffer) essentially a state machine approach m->dwBytesRecorded is a position in message keep appending bytes until buffer is full (one byte to spare) 4. Buffer Preparation (midiOutPrepare, etc.) done before sending message dwBytesRecorded and dwBufferLength are set in winmm_end_sysex 5. Buffer Send (to Midi device) uses midiStreamOutMsg() 6. Buffer Receive (in callback) 7. Buffer Empty (removing bytes from buffer) not applicable for output 8. Buffer Free (returning to the buffer pool) unprepare message to indicate that it is free SetEvent on m->buffer_signal in case client is waiting 9. Buffer Finalization (returning to heap) when device is closed, winmm_out_delete frees all sysex buffers Here's how input handles sysex: 1. Buffer Initialization (creating buffers) two buffers are allocated in winmm_in_open 2. Buffer Allocation (finding a free buffer) same code as simple output (see above) 3. Buffer Fill (putting bytes in the buffer) not applicable for input 4. Buffer Preparation (midiOutPrepare, etc.) done before sending message -- in winmm_in_open and in callback 5. Buffer Send (to Midi device) uses midiInAddbuffer in allocate_sysex_input_buffer (called from winmm_in_open) and callback 6. Buffer Receive (in callback) 7. Buffer Empty (removing bytes from buffer) done without pause in loop in callback 8. Buffer Free (returning to the buffer pool) done by midiInAddBuffer in callback, no pointer to buffers is retained except by device 9. Buffer Finalization (returning to heap) when device is closed, empty buffers are delivered to callback, which frees them IMPORTANT: In addition to the above, PortMidi now has "shortcuts" to optimize the transfer of sysex data. To enable the optimization for sysex output, the system-dependent code sets fields in the pmInternal structure: fill_base, fill_offset_ptr, and fill_length. When fill_base is non-null, the system-independent part of PortMidi is allowed to directly copy sysex bytes to "fill_base[*fill_offset_ptr++]" until *fill_offset_ptr reaches fill_length. See the code for details. ----------- Additional notes on using VS 2005 (maybe this is obsolete now?): 1) Make sure "Configuration: All Configurations" is selected in all of the following Properties modifications! 2) In my case the project defaulted to compiling all .c files with the C++ compiler, which was disastrous. I had to go to set Properties for each file, to wit: Expand Configuration Properties, Expand C/C++, Select Advanced, set the Compile As popup to Compile as C Code (/TC). (For better or worse, the project I inherited has a bunch of .c files that rely on C++ features, so I couldn't reliably set this the project properties level.) 3) While you're there, make sure that the C/C++ -> General -> "Compile with Common Language Runtime support" is set to "No Common Language Runtime support" (the C compiler *can't* support CLR, but VS won't do anything useful like automatically set the two options to match)-. 4) I never got VS precompiled header thing to work sensibly, so I took the path of least resistance and turned PCH's off for all my files. Properties -> Configuration Properties -> C/C++ -> Precompiled Headers -> Create/Use Precompiled Header popup set to "Not Using Precompiled Headers". The compiler is reasonably fast even if it has to parse all the header files, so unless someone wants to explain VS's PCHs to me, the hell with it, I say. pd-0.46-7/portmidi/pm_win/pmwin.c0000775000175000017500000000716012374245151015025 0ustar mspmsp/* pmwin.c -- PortMidi os-dependent code */ /* This file only needs to implement: pm_init(), which calls various routines to register the available midi devices, Pm_GetDefaultInputDeviceID(), and Pm_GetDefaultOutputDeviceID(). This file must be separate from the main portmidi.c file because it is system dependent, and it is separate from, say, pmwinmm.c, because it might need to register devices for winmm, directx, and others. */ #include "stdlib.h" #include "portmidi.h" #include "pmutil.h" #include "pminternal.h" #include "pmwinmm.h" #ifdef DEBUG #include "stdio.h" #endif #include /* pm_exit is called when the program exits. It calls pm_term to make sure PortMidi is properly closed. If DEBUG is on, we prompt for input to avoid losing error messages. */ static void pm_exit(void) { pm_term(); #ifdef DEBUG #define STRING_MAX 80 { char line[STRING_MAX]; printf("Type ENTER...\n"); /* note, w/o this prompting, client console application can not see one of its errors before closing. */ fgets(line, STRING_MAX, stdin); } #endif } /* pm_init is the windows-dependent initialization.*/ void pm_init(void) { atexit(pm_exit); #ifdef DEBUG printf("registered pm_exit with atexit()\n"); #endif pm_winmm_init(); /* initialize other APIs (DirectX?) here */ } void pm_term(void) { pm_winmm_term(); } static PmDeviceID pm_get_default_device_id(int is_input, char *key) { HKEY hkey; #define PATTERN_MAX 256 char pattern[PATTERN_MAX]; long pattern_max = PATTERN_MAX; DWORD dwType; /* Find first input or device -- this is the default. */ PmDeviceID id = pmNoDevice; int i, j; Pm_Initialize(); /* make sure descriptors exist! */ for (i = 0; i < pm_descriptor_index; i++) { if (descriptors[i].pub.input == is_input) { id = i; break; } } /* Look in registry for a default device name pattern. */ if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software", 0, KEY_READ, &hkey) != ERROR_SUCCESS) { return id; } if (RegOpenKeyEx(hkey, "JavaSoft", 0, KEY_READ, &hkey) != ERROR_SUCCESS) { return id; } if (RegOpenKeyEx(hkey, "Prefs", 0, KEY_READ, &hkey) != ERROR_SUCCESS) { return id; } if (RegOpenKeyEx(hkey, "/Port/Midi", 0, KEY_READ, &hkey) != ERROR_SUCCESS) { return id; } if (RegQueryValueEx(hkey, key, NULL, &dwType, pattern, &pattern_max) != ERROR_SUCCESS) { return id; } /* decode pattern: upper case encoded with "/" prefix */ i = j = 0; while (pattern[i]) { if (pattern[i] == '/' && pattern[i + 1]) { pattern[j++] = toupper(pattern[++i]); } else { pattern[j++] = tolower(pattern[i]); } i++; } pattern[j] = 0; /* end of string */ /* now pattern is the string from the registry; search for match */ i = pm_find_default_device(pattern, is_input); if (i != pmNoDevice) { id = i; } return id; } PmDeviceID Pm_GetDefaultInputDeviceID() { return pm_get_default_device_id(TRUE, "/P/M_/R/E/C/O/M/M/E/N/D/E/D_/I/N/P/U/T_/D/E/V/I/C/E"); } PmDeviceID Pm_GetDefaultOutputDeviceID() { return pm_get_default_device_id(FALSE, "/P/M_/R/E/C/O/M/M/E/N/D/E/D_/O/U/T/P/U/T_/D/E/V/I/C/E"); } #include "stdio.h" void *pm_alloc(size_t s) { return malloc(s); } void pm_free(void *ptr) { free(ptr); } pd-0.46-7/portmidi/Makefile.am0000664000175000017500000000215112524735416014267 0ustar mspmsp# this is built as a "libtool convenience library" # http://sources.redhat.com/automake/automake.html#Libtool-Convenience-Libraries AUTOMAKE_OPTIONS = foreign AM_CFLAGS = -DNEWBUFFER INCLUDES = -Ipm_common -Iporttime noinst_LTLIBRARIES = libportmidi.la libportmidi_la_SOURCES = pm_common/pmutil.c pm_common/portmidi.c if LINUX INCLUDES += -Ipm_linux libportmidi_la_SOURCES += porttime/ptlinux.c \ pm_linux/pmlinux.c \ pm_linux/pmlinuxalsa.c endif if MACOSX INCLUDES += -Ipm_mac libportmidi_la_SOURCES += porttime/ptmacosx_cf.c \ pm_mac/pmmac.c \ pm_mac/pmmacosxcm.c \ pm_mac/finddefault.c \ pm_mac/readbinaryplist.c endif if WINDOWS INCLUDES += -Ipm_win libportmidi_la_SOURCES += porttime/porttime.c \ porttime/ptwinmm.c \ pm_win/pmwin.c \ pm_win/pmwinmm.c endif # include the headers in the dist so you can build nobase_noinst_HEADERS = \ pm_common/pminternal.h \ pm_common/pmutil.h \ pm_common/portmidi.h \ pm_linux/pmlinux.h \ pm_linux/pmlinuxalsa.h \ pm_mac/pmmac.h \ pm_mac/pmmacosxcm.h \ pm_win/pmdll.h \ pm_win/pmwinmm.h \ porttime/porttime.h pd-0.46-7/portmidi/license.txt0000664000175000017500000000347112374245151014417 0ustar mspmsp/* * PortMidi Portable Real-Time MIDI Library * * license.txt -- a copy of the PortMidi copyright notice and license information * * Latest version available at: http://sourceforge.net/projects/portmedia * * Copyright (c) 1999-2000 Ross Bencina and Phil Burk * Copyright (c) 2001-2009 Roger B. Dannenberg * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortMidi license; however, * the PortMusic community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ pd-0.46-7/portmidi/CHANGELOG.txt0000664000175000017500000002242612374245151014265 0ustar mspmsp/* CHANGELOG FOR PORTMIDI * * 19Oct09 Roger Dannenberg * - Changes dynamic library names from portmidi_d to portmidi to * be backward-compatible with programs expecting a library by * the old name. * * 04Oct09 Roger Dannenberg * - Converted to using Cmake. * - Renamed static and dynamic library files to portmidi_s and portmidi_d * - Eliminated VC9 and VC8 files (went back to simply test.vcproj, etc., * use Cmake to switch from the provided VC9 files to VC8 or other) * - Many small changes to prepare for 64-bit architectures (but only * tested on 32-bit machines) * * 16Jun09 Roger Dannenberg * - Started using Microsoft Visual C++ Version 9 (Express). Converted * all *-VC9.vcproj file to *.vcproj and renamed old project files to * *-VC8.proj. Previously, output from VC9 went to special VC9 files, * that breaks any program or script looking for output in release or * debug files, so now both compiler version output to the same folders. * Now, debug version uses static linking with debug DLL runtime, and * release version uses static linking with statically linked runtime. * Converted to Inno Setup and worked on scripts to make things build * properly, especially pmdefaults. * * 02Jan09 Roger Dannenberg * - Created Java interface and wrote PmDefaults application to set * values for Pm_GetDefaultInputDeviceID() and * Pm_GetDefaultOutputDeviceID(). Other fixes. * * 19Jun08 Roger Dannenberg and Austin Sung * - Removed USE_DLL_FOR_CLEANUP -- Windows 2000 through Vista seem to be * fixed now, and can recover if MIDI ports are left open * - Various other minor patches * * 17Jan07 Roger Dannenberg * - Lots more help for Common Lisp user in pm_cl * - Minor fix to eliminate a compiler warning * - Went back to single library in OS X for both portmidi and porttime * * 16Jan07 Roger Dannenberg * - OOPS! fixed bug where short messages all had zero data * - Makefile.osx static library build now makes universal (i386 + ppc) * binaries * * 15Jan07 Roger Dannenberg * - multiple rewrites of sysex handling code to take care of * error-handling, embedded messages, message filtering, * driver bugs, and host limitations. * - fixed windows to use dwBufferLength rather than * dwBytesRecorded for long buffer output (fix by Nigel Brown) * - Win32 MME code always appends an extra zero to long buffer * output to work around a problem with earlier versions of Midi Yoke * - Added mm, a command line Midi Monitor to pm_test suite * - Revised copyright notice to match PortAudio/MIT license (requests * are moved out of the license proper and into a separate paragraph) * * 18Oct06 Roger Dannenberg * - replace FIFO in pmutil with Light Pipe-based multiprocessor-safe alg. * - replace FIFO in portmidi.c with PmQueue from pmutil * * 07Oct06 cpr & Roger Dannenberg * - overhaul of CoreMIDI input to handle running status and multiple * - messages per packet, with additional error detection * - added Leigh Smith and Rick Taube support for Common Lisp and * - dynamic link libraries in OSX * - initialize static global seq = NULL in pmlinuxalsa.c * * 05Sep06 Sebastien Frippiat * - check if (ALSA) seq exists before closing it in pm_linuxalsa_term() * * 05Sep06 Andreas Micheler and Cecilio * - fixed memory leak by freeing someo objects in pm_winmm_term() * - and another leak by freeing descriptors in Pm_Terminate() * * 23Aug06 RBD * - various minor fixes * * 04Nov05 Olivier Tristan * - changes to OS X to properly retrieve real device name on CoreMidi * * 19Jul05 Roger Dannenberg * - included pmBufferMaxSize in Pm_GetErrorText() * * 23Mar05 Torgier Strand Henriksen * - cleaner termination of porttime thread under Linux * * 15Nov04 Ben Allison * - sysex output now uses one buffer/message and reallocates buffer * - if needed * - filters expanded for many message types and channels * - detailed changes are as follows: * ------------- in pmwinmm.c -------------- * - new #define symbol: OUTPUT_BYTES_PER_BUFFER * - change SYSEX_BYTES_PER_BUFFER to 1024 * - added MIDIHDR_BUFFER_LENGTH(x) to correctly count midihdr buffer length * - change MIDIHDR_SIZE(x) to (MIDIHDR_BUFFER_LENGTH(x) + sizeof(MIDIHDR)) * - change allocate_buffer to use new MIDIHDR_BUFFER_LENGTH macro * - new macros for MIDIHDR_SYSEX_SIZE and MIDIHDR_SYSEX_BUFFER_LENGTH * - similar to above, but counts appropriately for sysex messages * - added the following members to midiwinmm_struct for sysex data: * - LPMIDIHDR *sysex_buffers; ** pool of buffers for sysex data ** * - int num_sysex_buffers; ** how many sysex buffers ** * - int next_sysex_buffer; ** index of next sysexbuffer to send ** * - HANDLE sysex_buffer_signal; ** to wait for free sysex buffer ** * - duplicated allocate_buffer, alocate_buffers and get_free_output_buffer * - into equivalent sysex_buffer form * - changed winmm_in_open to initialize new midiwinmm_struct members and * - to use the new allocate_sysex_buffer() function instead of * - allocate_buffer() * - changed winmm_out_open to initialize new members, create sysex buffer * - signal, and allocate 2 sysex buffers * - changed winmm_out_delete to free sysex buffers and shut down the sysex * - buffer signal * - create new function resize_sysex_buffer which resizes m->hdr to the * - passed size, and corrects the midiwinmm_struct accordingly. * - changed winmm_write_byte to use new resize_sysex_buffer function, * - if resize fails, write current buffer to output and continue * - changed winmm_out_callback to use buffer_signal or sysex_buffer_signal * - depending on which buffer was finished * ------------- in portmidi.h -------------- * - added pmBufferMaxSize to PmError to indicate that the buffer would be * - too large for the underlying API * - added additional filters * - added prototype, documentation, and helper macro for Pm_SetChannelMask * ------------- in portmidi.c -------------- * - added pm_status_filtered() and pm_realtime_filtered() functions to * separate filtering logic from buffer logic in pm_read_short * - added Pm_SetChannelMask function * - added pm_channel_filtered() function * ------------- in pminternal.h -------------- * - added member to PortMidiStream for channel mask * * 25May04 RBD * - removed support for MIDI THRU * - moved filtering from Pm_Read to pm_enqueue to avoid buffer ovfl * - extensive work on Mac OS X port, especially sysex and error handling * * 18May04 RBD * - removed side-effects from assert() calls. Now you can disable assert(). * - no longer check pm_hosterror everywhere, fixing a bug where an open * failure could cause a write not to work on a previously opened port * until you call Pm_GetHostErrorText(). * 16May04 RBD and Chris Roberts * - Some documentation wordsmithing in portmidi.h * - Dynamically allocate port descriptor structures * - Fixed parameter error in midiInPrepareBuffer and midiInAddBuffer. * * 09Oct03 RBD * - Changed Thru handling. Now the client does all the work and the client * must poll or read to keep thru messages flowing. * * 31May03 RBD * - Fixed various bugs. * - Added linux ALSA support with help from Clemens Ladisch * - Added Mac OS X support, implemented by Jon Parise, updated and * integrated by Andrew Zeldis and Zico Kolter * - Added latency program to build histogram of system latency using PortTime. * * 30Jun02 RBD Extensive rewrite of sysex handling. It works now. * Extensive reworking of error reporting and error text -- no * longer use dictionary call to delete data; instead, Pm_Open * and Pm_Close clean up before returning an error code, and * error text is saved in a system-independent location. * Wrote sysex.c to test sysex message handling. * * 15Jun02 BCT changes: * - Added pmHostError text handling. * - For robustness, check PortMidi stream args not NULL. * - Re-C-ANSI-fied code (changed many C++ comments to C style) * - Reorganized code in pmwinmm according to input/output functionality (made * cleanup handling easier to reason about) * - Fixed Pm_Write calls (portmidi.h says these should not return length but Pm_Error) * - Cleaned up memory handling (now system specific data deleted via dictionary * call in PortMidi, allows client to query host errors). * - Added explicit asserts to verify various aspects of pmwinmm implementation behaves as * logic implies it should. Specifically: verified callback routines not reentrant and * all verified status for all unchecked Win32 MMedia API calls perform successfully * - Moved portmidi initialization and clean-up routines into DLL to fix Win32 MMedia API * bug (i.e. if devices not explicitly closed, must reboot to debug application further). * With this change, clients no longer need explicitly call Pm_Initialize, Pm_Terminate, or * explicitly Pm_Close open devices when using WinMM version of PortMidi. * * 23Jan02 RBD Fixed bug in pmwinmm.c thru handling * * 21Jan02 RBD Added tests in Pm_OpenInput() and Pm_OpenOutput() to prevent * opening an input as output and vice versa. * Added comments and documentation. * Implemented Pm_Terminate(). * */ pd-0.46-7/portaudio/0000775000175000017500000000000012374250720012404 5ustar mspmsppd-0.46-7/portaudio/config.sub0000775000175000017500000010460612374245151014400 0ustar mspmsp#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011 Free Software Foundation, Inc. timestamp='2011-03-23' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file 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 2 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, write to the Free Software # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to . Submit a context # diff and a properly formatted GNU ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 \ | ns16k | ns32k \ | open8 \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; m6811 | m68hc11 | m6812 | m68hc12 | picochip) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile-* | tilegx-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze) basic_machine=microblaze-xilinx ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; mvs) basic_machine=i370-ibm os=-mvs ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; # This must be matched before tile*. tilegx*) basic_machine=tilegx-unknown os=-linux-gnu ;; tile*) basic_machine=tile-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: pd-0.46-7/portaudio/include/0000775000175000017500000000000012222201037014014 5ustar mspmsppd-0.46-7/portaudio/include/pa_win_waveformat.h0000664000175000017500000002151412222201037017700 0ustar mspmsp#ifndef PA_WIN_WAVEFORMAT_H #define PA_WIN_WAVEFORMAT_H /* * PortAudio Portable Real-Time Audio Library * Windows WAVEFORMAT* data structure utilities * portaudio.h should be included before this file. * * Copyright (c) 2007 Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup public_header @brief Windows specific PortAudio API extension and utilities header file. */ #ifdef __cplusplus extern "C" { #endif /* The following #defines for speaker channel masks are the same as those in ksmedia.h, except with PAWIN_ prepended, KSAUDIO_ removed in some cases, and casts to PaWinWaveFormatChannelMask added. */ typedef unsigned long PaWinWaveFormatChannelMask; /* Speaker Positions: */ #define PAWIN_SPEAKER_FRONT_LEFT ((PaWinWaveFormatChannelMask)0x1) #define PAWIN_SPEAKER_FRONT_RIGHT ((PaWinWaveFormatChannelMask)0x2) #define PAWIN_SPEAKER_FRONT_CENTER ((PaWinWaveFormatChannelMask)0x4) #define PAWIN_SPEAKER_LOW_FREQUENCY ((PaWinWaveFormatChannelMask)0x8) #define PAWIN_SPEAKER_BACK_LEFT ((PaWinWaveFormatChannelMask)0x10) #define PAWIN_SPEAKER_BACK_RIGHT ((PaWinWaveFormatChannelMask)0x20) #define PAWIN_SPEAKER_FRONT_LEFT_OF_CENTER ((PaWinWaveFormatChannelMask)0x40) #define PAWIN_SPEAKER_FRONT_RIGHT_OF_CENTER ((PaWinWaveFormatChannelMask)0x80) #define PAWIN_SPEAKER_BACK_CENTER ((PaWinWaveFormatChannelMask)0x100) #define PAWIN_SPEAKER_SIDE_LEFT ((PaWinWaveFormatChannelMask)0x200) #define PAWIN_SPEAKER_SIDE_RIGHT ((PaWinWaveFormatChannelMask)0x400) #define PAWIN_SPEAKER_TOP_CENTER ((PaWinWaveFormatChannelMask)0x800) #define PAWIN_SPEAKER_TOP_FRONT_LEFT ((PaWinWaveFormatChannelMask)0x1000) #define PAWIN_SPEAKER_TOP_FRONT_CENTER ((PaWinWaveFormatChannelMask)0x2000) #define PAWIN_SPEAKER_TOP_FRONT_RIGHT ((PaWinWaveFormatChannelMask)0x4000) #define PAWIN_SPEAKER_TOP_BACK_LEFT ((PaWinWaveFormatChannelMask)0x8000) #define PAWIN_SPEAKER_TOP_BACK_CENTER ((PaWinWaveFormatChannelMask)0x10000) #define PAWIN_SPEAKER_TOP_BACK_RIGHT ((PaWinWaveFormatChannelMask)0x20000) /* Bit mask locations reserved for future use */ #define PAWIN_SPEAKER_RESERVED ((PaWinWaveFormatChannelMask)0x7FFC0000) /* Used to specify that any possible permutation of speaker configurations */ #define PAWIN_SPEAKER_ALL ((PaWinWaveFormatChannelMask)0x80000000) /* DirectSound Speaker Config */ #define PAWIN_SPEAKER_DIRECTOUT 0 #define PAWIN_SPEAKER_MONO (PAWIN_SPEAKER_FRONT_CENTER) #define PAWIN_SPEAKER_STEREO (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT) #define PAWIN_SPEAKER_QUAD (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \ PAWIN_SPEAKER_BACK_LEFT | PAWIN_SPEAKER_BACK_RIGHT) #define PAWIN_SPEAKER_SURROUND (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \ PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_BACK_CENTER) #define PAWIN_SPEAKER_5POINT1 (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \ PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_LOW_FREQUENCY | \ PAWIN_SPEAKER_BACK_LEFT | PAWIN_SPEAKER_BACK_RIGHT) #define PAWIN_SPEAKER_7POINT1 (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \ PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_LOW_FREQUENCY | \ PAWIN_SPEAKER_BACK_LEFT | PAWIN_SPEAKER_BACK_RIGHT | \ PAWIN_SPEAKER_FRONT_LEFT_OF_CENTER | PAWIN_SPEAKER_FRONT_RIGHT_OF_CENTER) #define PAWIN_SPEAKER_5POINT1_SURROUND (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \ PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_LOW_FREQUENCY | \ PAWIN_SPEAKER_SIDE_LEFT | PAWIN_SPEAKER_SIDE_RIGHT) #define PAWIN_SPEAKER_7POINT1_SURROUND (PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_RIGHT | \ PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_LOW_FREQUENCY | \ PAWIN_SPEAKER_BACK_LEFT | PAWIN_SPEAKER_BACK_RIGHT | \ PAWIN_SPEAKER_SIDE_LEFT | PAWIN_SPEAKER_SIDE_RIGHT) /* According to the Microsoft documentation: The following are obsolete 5.1 and 7.1 settings (they lack side speakers). Note this means that the default 5.1 and 7.1 settings (KSAUDIO_SPEAKER_5POINT1 and KSAUDIO_SPEAKER_7POINT1 are similarly obsolete but are unchanged for compatibility reasons). */ #define PAWIN_SPEAKER_5POINT1_BACK PAWIN_SPEAKER_5POINT1 #define PAWIN_SPEAKER_7POINT1_WIDE PAWIN_SPEAKER_7POINT1 /* DVD Speaker Positions */ #define PAWIN_SPEAKER_GROUND_FRONT_LEFT PAWIN_SPEAKER_FRONT_LEFT #define PAWIN_SPEAKER_GROUND_FRONT_CENTER PAWIN_SPEAKER_FRONT_CENTER #define PAWIN_SPEAKER_GROUND_FRONT_RIGHT PAWIN_SPEAKER_FRONT_RIGHT #define PAWIN_SPEAKER_GROUND_REAR_LEFT PAWIN_SPEAKER_BACK_LEFT #define PAWIN_SPEAKER_GROUND_REAR_RIGHT PAWIN_SPEAKER_BACK_RIGHT #define PAWIN_SPEAKER_TOP_MIDDLE PAWIN_SPEAKER_TOP_CENTER #define PAWIN_SPEAKER_SUPER_WOOFER PAWIN_SPEAKER_LOW_FREQUENCY /* PaWinWaveFormat is defined here to provide compatibility with compilation environments which don't have headers defining WAVEFORMATEXTENSIBLE (e.g. older versions of MSVC, Borland C++ etc. The fields for WAVEFORMATEX and WAVEFORMATEXTENSIBLE are declared as an unsigned char array here to avoid clients who include this file having a dependency on windows.h and mmsystem.h, and also to to avoid having to write separate packing pragmas for each compiler. */ #define PAWIN_SIZEOF_WAVEFORMATEX 18 #define PAWIN_SIZEOF_WAVEFORMATEXTENSIBLE (PAWIN_SIZEOF_WAVEFORMATEX + 22) typedef struct{ unsigned char fields[ PAWIN_SIZEOF_WAVEFORMATEXTENSIBLE ]; unsigned long extraLongForAlignment; /* ensure that compiler aligns struct to DWORD */ } PaWinWaveFormat; /* WAVEFORMATEXTENSIBLE fields: union { WORD wValidBitsPerSample; WORD wSamplesPerBlock; WORD wReserved; } Samples; DWORD dwChannelMask; GUID SubFormat; */ #define PAWIN_INDEXOF_WVALIDBITSPERSAMPLE (PAWIN_SIZEOF_WAVEFORMATEX+0) #define PAWIN_INDEXOF_DWCHANNELMASK (PAWIN_SIZEOF_WAVEFORMATEX+2) #define PAWIN_INDEXOF_SUBFORMAT (PAWIN_SIZEOF_WAVEFORMATEX+6) /* Valid values to pass for the waveFormatTag PaWin_InitializeWaveFormatEx and PaWin_InitializeWaveFormatExtensible functions below. These must match the standard Windows WAVE_FORMAT_* values. */ #define PAWIN_WAVE_FORMAT_PCM (1) #define PAWIN_WAVE_FORMAT_IEEE_FLOAT (3) #define PAWIN_WAVE_FORMAT_DOLBY_AC3_SPDIF (0x0092) #define PAWIN_WAVE_FORMAT_WMA_SPDIF (0x0164) /* returns PAWIN_WAVE_FORMAT_PCM or PAWIN_WAVE_FORMAT_IEEE_FLOAT depending on the sampleFormat parameter. */ int PaWin_SampleFormatToLinearWaveFormatTag( PaSampleFormat sampleFormat ); /* Use the following two functions to initialize the waveformat structure. */ void PaWin_InitializeWaveFormatEx( PaWinWaveFormat *waveFormat, int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate ); void PaWin_InitializeWaveFormatExtensible( PaWinWaveFormat *waveFormat, int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate, PaWinWaveFormatChannelMask channelMask ); /* Map a channel count to a speaker channel mask */ PaWinWaveFormatChannelMask PaWin_DefaultChannelMask( int numChannels ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_WIN_WAVEFORMAT_H */pd-0.46-7/portaudio/include/pa_mac_core.h0000664000175000017500000001657712222201037016435 0ustar mspmsp#ifndef PA_MAC_CORE_H #define PA_MAC_CORE_H /* * PortAudio Portable Real-Time Audio Library * Macintosh Core Audio specific extensions * portaudio.h should be included before this file. * * Copyright (c) 2005-2006 Bjorn Roche * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file * @ingroup public_header * @brief CoreAudio-specific PortAudio API extension header file. */ #include "portaudio.h" #include #include #ifdef __cplusplus extern "C" { #endif /** * A pointer to a paMacCoreStreamInfo may be passed as * the hostApiSpecificStreamInfo in the PaStreamParameters struct * when opening a stream or querying the format. Use NULL, for the * defaults. Note that for duplex streams, flags for input and output * should be the same or behaviour is undefined. */ typedef struct { unsigned long size; /**size of whole structure including this header */ PaHostApiTypeId hostApiType; /**host API for which this data is intended */ unsigned long version; /**structure version */ unsigned long flags; /** flags to modify behaviour */ SInt32 const * channelMap; /** Channel map for HAL channel mapping , if not needed, use NULL;*/ unsigned long channelMapSize; /** Channel map size for HAL channel mapping , if not needed, use 0;*/ } PaMacCoreStreamInfo; /** * Functions */ /** Use this function to initialize a paMacCoreStreamInfo struct * using the requested flags. Note that channel mapping is turned * off after a call to this function. * @param data The datastructure to initialize * @param flags The flags to initialize the datastructure with. */ void PaMacCore_SetupStreamInfo( PaMacCoreStreamInfo *data, unsigned long flags ); /** call this after pa_SetupMacCoreStreamInfo to use channel mapping as described in notes.txt. * @param data The stream info structure to assign a channel mapping to * @param channelMap The channel map array, as described in notes.txt. This array pointer will be used directly (ie the underlying data will not be copied), so the caller should not free the array until after the stream has been opened. * @param channelMapSize The size of the channel map array. */ void PaMacCore_SetupChannelMap( PaMacCoreStreamInfo *data, const SInt32 * const channelMap, unsigned long channelMapSize ); /** * Retrieve the AudioDeviceID of the input device assigned to an open stream * * @param s The stream to query. * * @return A valid AudioDeviceID, or NULL if an error occurred. */ AudioDeviceID PaMacCore_GetStreamInputDevice( PaStream* s ); /** * Retrieve the AudioDeviceID of the output device assigned to an open stream * * @param s The stream to query. * * @return A valid AudioDeviceID, or NULL if an error occurred. */ AudioDeviceID PaMacCore_GetStreamOutputDevice( PaStream* s ); /** * Returns a statically allocated string with the device's name * for the given channel. NULL will be returned on failure. * * This function's implemenation is not complete! * * @param device The PortAudio device index. * @param channel The channel number who's name is requested. * @return a statically allocated string with the name of the device. * Because this string is statically allocated, it must be * coppied if it is to be saved and used by the user after * another call to this function. * */ const char *PaMacCore_GetChannelName( int device, int channelIndex, bool input ); /** Retrieve the range of legal native buffer sizes for the specificed device, in sample frames. @param device The global index of the PortAudio device about which the query is being made. @param minBufferSizeFrames A pointer to the location which will receive the minimum buffer size value. @param maxBufferSizeFrames A pointer to the location which will receive the maximum buffer size value. @see kAudioDevicePropertyBufferFrameSizeRange in the CoreAudio SDK. */ PaError PaMacCore_GetBufferSizeRange( PaDeviceIndex device, long *minBufferSizeFrames, long *maxBufferSizeFrames ); /** * Flags */ /** * The following flags alter the behaviour of PA on the mac platform. * they can be ORed together. These should work both for opening and * checking a device. */ /** Allows PortAudio to change things like the device's frame size, * which allows for much lower latency, but might disrupt the device * if other programs are using it, even when you are just Querying * the device. */ #define paMacCoreChangeDeviceParameters (0x01) /** In combination with the above flag, * causes the stream opening to fail, unless the exact sample rates * are supported by the device. */ #define paMacCoreFailIfConversionRequired (0x02) /** These flags set the SR conversion quality, if required. The wierd ordering * allows Maximum Quality to be the default.*/ #define paMacCoreConversionQualityMin (0x0100) #define paMacCoreConversionQualityMedium (0x0200) #define paMacCoreConversionQualityLow (0x0300) #define paMacCoreConversionQualityHigh (0x0400) #define paMacCoreConversionQualityMax (0x0000) /** * Here are some "preset" combinations of flags (above) to get to some * common configurations. THIS IS OVERKILL, but if more flags are added * it won't be. */ /**This is the default setting: do as much sample rate conversion as possible * and as little mucking with the device as possible. */ #define paMacCorePlayNice (0x00) /**This setting is tuned for pro audio apps. It allows SR conversion on input and output, but it tries to set the appropriate SR on the device.*/ #define paMacCorePro (0x01) /**This is a setting to minimize CPU usage and still play nice.*/ #define paMacCoreMinimizeCPUButPlayNice (0x0100) /**This is a setting to minimize CPU usage, even if that means interrupting the device. */ #define paMacCoreMinimizeCPU (0x0101) #ifdef __cplusplus } #endif /** __cplusplus */ #endif /** PA_MAC_CORE_H */ pd-0.46-7/portaudio/include/portaudio.h0000664000175000017500000013141712222201037016202 0ustar mspmsp#ifndef PORTAUDIO_H #define PORTAUDIO_H /* * $Id: portaudio.h 1859 2012-09-01 00:10:13Z philburk $ * PortAudio Portable Real-Time Audio Library * PortAudio API Header File * Latest version available at: http://www.portaudio.com/ * * Copyright (c) 1999-2002 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup public_header @brief The portable PortAudio API. */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** Retrieve the release number of the currently running PortAudio build, eg 1900. */ int Pa_GetVersion( void ); /** Retrieve a textual description of the current PortAudio build, eg "PortAudio V19-devel 13 October 2002". */ const char* Pa_GetVersionText( void ); /** Error codes returned by PortAudio functions. Note that with the exception of paNoError, all PaErrorCodes are negative. */ typedef int PaError; typedef enum PaErrorCode { paNoError = 0, paNotInitialized = -10000, paUnanticipatedHostError, paInvalidChannelCount, paInvalidSampleRate, paInvalidDevice, paInvalidFlag, paSampleFormatNotSupported, paBadIODeviceCombination, paInsufficientMemory, paBufferTooBig, paBufferTooSmall, paNullCallback, paBadStreamPtr, paTimedOut, paInternalError, paDeviceUnavailable, paIncompatibleHostApiSpecificStreamInfo, paStreamIsStopped, paStreamIsNotStopped, paInputOverflowed, paOutputUnderflowed, paHostApiNotFound, paInvalidHostApi, paCanNotReadFromACallbackStream, paCanNotWriteToACallbackStream, paCanNotReadFromAnOutputOnlyStream, paCanNotWriteToAnInputOnlyStream, paIncompatibleStreamHostApi, paBadBufferPtr } PaErrorCode; /** Translate the supplied PortAudio error code into a human readable message. */ const char *Pa_GetErrorText( PaError errorCode ); /** Library initialization function - call this before using PortAudio. This function initializes internal data structures and prepares underlying host APIs for use. With the exception of Pa_GetVersion(), Pa_GetVersionText(), and Pa_GetErrorText(), this function MUST be called before using any other PortAudio API functions. If Pa_Initialize() is called multiple times, each successful call must be matched with a corresponding call to Pa_Terminate(). Pairs of calls to Pa_Initialize()/Pa_Terminate() may overlap, and are not required to be fully nested. Note that if Pa_Initialize() returns an error code, Pa_Terminate() should NOT be called. @return paNoError if successful, otherwise an error code indicating the cause of failure. @see Pa_Terminate */ PaError Pa_Initialize( void ); /** Library termination function - call this when finished using PortAudio. This function deallocates all resources allocated by PortAudio since it was initialized by a call to Pa_Initialize(). In cases where Pa_Initialise() has been called multiple times, each call must be matched with a corresponding call to Pa_Terminate(). The final matching call to Pa_Terminate() will automatically close any PortAudio streams that are still open. Pa_Terminate() MUST be called before exiting a program which uses PortAudio. Failure to do so may result in serious resource leaks, such as audio devices not being available until the next reboot. @return paNoError if successful, otherwise an error code indicating the cause of failure. @see Pa_Initialize */ PaError Pa_Terminate( void ); /** The type used to refer to audio devices. Values of this type usually range from 0 to (Pa_GetDeviceCount()-1), and may also take on the PaNoDevice and paUseHostApiSpecificDeviceSpecification values. @see Pa_GetDeviceCount, paNoDevice, paUseHostApiSpecificDeviceSpecification */ typedef int PaDeviceIndex; /** A special PaDeviceIndex value indicating that no device is available, or should be used. @see PaDeviceIndex */ #define paNoDevice ((PaDeviceIndex)-1) /** A special PaDeviceIndex value indicating that the device(s) to be used are specified in the host api specific stream info structure. @see PaDeviceIndex */ #define paUseHostApiSpecificDeviceSpecification ((PaDeviceIndex)-2) /* Host API enumeration mechanism */ /** The type used to enumerate to host APIs at runtime. Values of this type range from 0 to (Pa_GetHostApiCount()-1). @see Pa_GetHostApiCount */ typedef int PaHostApiIndex; /** Retrieve the number of available host APIs. Even if a host API is available it may have no devices available. @return A non-negative value indicating the number of available host APIs or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. @see PaHostApiIndex */ PaHostApiIndex Pa_GetHostApiCount( void ); /** Retrieve the index of the default host API. The default host API will be the lowest common denominator host API on the current platform and is unlikely to provide the best performance. @return A non-negative value ranging from 0 to (Pa_GetHostApiCount()-1) indicating the default host API index or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. */ PaHostApiIndex Pa_GetDefaultHostApi( void ); /** Unchanging unique identifiers for each supported host API. This type is used in the PaHostApiInfo structure. The values are guaranteed to be unique and to never change, thus allowing code to be written that conditionally uses host API specific extensions. New type ids will be allocated when support for a host API reaches "public alpha" status, prior to that developers should use the paInDevelopment type id. @see PaHostApiInfo */ typedef enum PaHostApiTypeId { paInDevelopment=0, /* use while developing support for a new host API */ paDirectSound=1, paMME=2, paASIO=3, paSoundManager=4, paCoreAudio=5, paOSS=7, paALSA=8, paAL=9, paBeOS=10, paWDMKS=11, paJACK=12, paWASAPI=13, paAudioScienceHPI=14 } PaHostApiTypeId; /** A structure containing information about a particular host API. */ typedef struct PaHostApiInfo { /** this is struct version 1 */ int structVersion; /** The well known unique identifier of this host API @see PaHostApiTypeId */ PaHostApiTypeId type; /** A textual description of the host API for display on user interfaces. */ const char *name; /** The number of devices belonging to this host API. This field may be used in conjunction with Pa_HostApiDeviceIndexToDeviceIndex() to enumerate all devices for this host API. @see Pa_HostApiDeviceIndexToDeviceIndex */ int deviceCount; /** The default input device for this host API. The value will be a device index ranging from 0 to (Pa_GetDeviceCount()-1), or paNoDevice if no default input device is available. */ PaDeviceIndex defaultInputDevice; /** The default output device for this host API. The value will be a device index ranging from 0 to (Pa_GetDeviceCount()-1), or paNoDevice if no default output device is available. */ PaDeviceIndex defaultOutputDevice; } PaHostApiInfo; /** Retrieve a pointer to a structure containing information about a specific host Api. @param hostApi A valid host API index ranging from 0 to (Pa_GetHostApiCount()-1) @return A pointer to an immutable PaHostApiInfo structure describing a specific host API. If the hostApi parameter is out of range or an error is encountered, the function returns NULL. The returned structure is owned by the PortAudio implementation and must not be manipulated or freed. The pointer is only guaranteed to be valid between calls to Pa_Initialize() and Pa_Terminate(). */ const PaHostApiInfo * Pa_GetHostApiInfo( PaHostApiIndex hostApi ); /** Convert a static host API unique identifier, into a runtime host API index. @param type A unique host API identifier belonging to the PaHostApiTypeId enumeration. @return A valid PaHostApiIndex ranging from 0 to (Pa_GetHostApiCount()-1) or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. The paHostApiNotFound error code indicates that the host API specified by the type parameter is not available. @see PaHostApiTypeId */ PaHostApiIndex Pa_HostApiTypeIdToHostApiIndex( PaHostApiTypeId type ); /** Convert a host-API-specific device index to standard PortAudio device index. This function may be used in conjunction with the deviceCount field of PaHostApiInfo to enumerate all devices for the specified host API. @param hostApi A valid host API index ranging from 0 to (Pa_GetHostApiCount()-1) @param hostApiDeviceIndex A valid per-host device index in the range 0 to (Pa_GetHostApiInfo(hostApi)->deviceCount-1) @return A non-negative PaDeviceIndex ranging from 0 to (Pa_GetDeviceCount()-1) or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. A paInvalidHostApi error code indicates that the host API index specified by the hostApi parameter is out of range. A paInvalidDevice error code indicates that the hostApiDeviceIndex parameter is out of range. @see PaHostApiInfo */ PaDeviceIndex Pa_HostApiDeviceIndexToDeviceIndex( PaHostApiIndex hostApi, int hostApiDeviceIndex ); /** Structure used to return information about a host error condition. */ typedef struct PaHostErrorInfo{ PaHostApiTypeId hostApiType; /**< the host API which returned the error code */ long errorCode; /**< the error code returned */ const char *errorText; /**< a textual description of the error if available, otherwise a zero-length string */ }PaHostErrorInfo; /** Return information about the last host error encountered. The error information returned by Pa_GetLastHostErrorInfo() will never be modified asynchronously by errors occurring in other PortAudio owned threads (such as the thread that manages the stream callback.) This function is provided as a last resort, primarily to enhance debugging by providing clients with access to all available error information. @return A pointer to an immutable structure constraining information about the host error. The values in this structure will only be valid if a PortAudio function has previously returned the paUnanticipatedHostError error code. */ const PaHostErrorInfo* Pa_GetLastHostErrorInfo( void ); /* Device enumeration and capabilities */ /** Retrieve the number of available devices. The number of available devices may be zero. @return A non-negative value indicating the number of available devices or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. */ PaDeviceIndex Pa_GetDeviceCount( void ); /** Retrieve the index of the default input device. The result can be used in the inputDevice parameter to Pa_OpenStream(). @return The default input device index for the default host API, or paNoDevice if no default input device is available or an error was encountered. */ PaDeviceIndex Pa_GetDefaultInputDevice( void ); /** Retrieve the index of the default output device. The result can be used in the outputDevice parameter to Pa_OpenStream(). @return The default output device index for the default host API, or paNoDevice if no default output device is available or an error was encountered. @note On the PC, the user can specify a default device by setting an environment variable. For example, to use device #1.
 set PA_RECOMMENDED_OUTPUT_DEVICE=1
The user should first determine the available device ids by using the supplied application "pa_devs". */ PaDeviceIndex Pa_GetDefaultOutputDevice( void ); /** The type used to represent monotonic time in seconds. PaTime is used for the fields of the PaStreamCallbackTimeInfo argument to the PaStreamCallback and as the result of Pa_GetStreamTime(). PaTime values have unspecified origin. @see PaStreamCallback, PaStreamCallbackTimeInfo, Pa_GetStreamTime */ typedef double PaTime; /** A type used to specify one or more sample formats. Each value indicates a possible format for sound data passed to and from the stream callback, Pa_ReadStream and Pa_WriteStream. The standard formats paFloat32, paInt16, paInt32, paInt24, paInt8 and aUInt8 are usually implemented by all implementations. The floating point representation (paFloat32) uses +1.0 and -1.0 as the maximum and minimum respectively. paUInt8 is an unsigned 8 bit format where 128 is considered "ground" The paNonInterleaved flag indicates that audio data is passed as an array of pointers to separate buffers, one buffer for each channel. Usually, when this flag is not used, audio data is passed as a single buffer with all channels interleaved. @see Pa_OpenStream, Pa_OpenDefaultStream, PaDeviceInfo @see paFloat32, paInt16, paInt32, paInt24, paInt8 @see paUInt8, paCustomFormat, paNonInterleaved */ typedef unsigned long PaSampleFormat; #define paFloat32 ((PaSampleFormat) 0x00000001) /**< @see PaSampleFormat */ #define paInt32 ((PaSampleFormat) 0x00000002) /**< @see PaSampleFormat */ #define paInt24 ((PaSampleFormat) 0x00000004) /**< Packed 24 bit format. @see PaSampleFormat */ #define paInt16 ((PaSampleFormat) 0x00000008) /**< @see PaSampleFormat */ #define paInt8 ((PaSampleFormat) 0x00000010) /**< @see PaSampleFormat */ #define paUInt8 ((PaSampleFormat) 0x00000020) /**< @see PaSampleFormat */ #define paCustomFormat ((PaSampleFormat) 0x00010000) /**< @see PaSampleFormat */ #define paNonInterleaved ((PaSampleFormat) 0x80000000) /**< @see PaSampleFormat */ /** A structure providing information and capabilities of PortAudio devices. Devices may support input, output or both input and output. */ typedef struct PaDeviceInfo { int structVersion; /* this is struct version 2 */ const char *name; PaHostApiIndex hostApi; /**< note this is a host API index, not a type id*/ int maxInputChannels; int maxOutputChannels; /** Default latency values for interactive performance. */ PaTime defaultLowInputLatency; PaTime defaultLowOutputLatency; /** Default latency values for robust non-interactive applications (eg. playing sound files). */ PaTime defaultHighInputLatency; PaTime defaultHighOutputLatency; double defaultSampleRate; } PaDeviceInfo; /** Retrieve a pointer to a PaDeviceInfo structure containing information about the specified device. @return A pointer to an immutable PaDeviceInfo structure. If the device parameter is out of range the function returns NULL. @param device A valid device index in the range 0 to (Pa_GetDeviceCount()-1) @note PortAudio manages the memory referenced by the returned pointer, the client must not manipulate or free the memory. The pointer is only guaranteed to be valid between calls to Pa_Initialize() and Pa_Terminate(). @see PaDeviceInfo, PaDeviceIndex */ const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceIndex device ); /** Parameters for one direction (input or output) of a stream. */ typedef struct PaStreamParameters { /** A valid device index in the range 0 to (Pa_GetDeviceCount()-1) specifying the device to be used or the special constant paUseHostApiSpecificDeviceSpecification which indicates that the actual device(s) to use are specified in hostApiSpecificStreamInfo. This field must not be set to paNoDevice. */ PaDeviceIndex device; /** The number of channels of sound to be delivered to the stream callback or accessed by Pa_ReadStream() or Pa_WriteStream(). It can range from 1 to the value of maxInputChannels in the PaDeviceInfo record for the device specified by the device parameter. */ int channelCount; /** The sample format of the buffer provided to the stream callback, a_ReadStream() or Pa_WriteStream(). It may be any of the formats described by the PaSampleFormat enumeration. */ PaSampleFormat sampleFormat; /** The desired latency in seconds. Where practical, implementations should configure their latency based on these parameters, otherwise they may choose the closest viable latency instead. Unless the suggested latency is greater than the absolute upper limit for the device implementations should round the suggestedLatency up to the next practical value - ie to provide an equal or higher latency than suggestedLatency wherever possible. Actual latency values for an open stream may be retrieved using the inputLatency and outputLatency fields of the PaStreamInfo structure returned by Pa_GetStreamInfo(). @see default*Latency in PaDeviceInfo, *Latency in PaStreamInfo */ PaTime suggestedLatency; /** An optional pointer to a host api specific data structure containing additional information for device setup and/or stream processing. hostApiSpecificStreamInfo is never required for correct operation, if not used it should be set to NULL. */ void *hostApiSpecificStreamInfo; } PaStreamParameters; /** Return code for Pa_IsFormatSupported indicating success. */ #define paFormatIsSupported (0) /** Determine whether it would be possible to open a stream with the specified parameters. @param inputParameters A structure that describes the input parameters used to open a stream. The suggestedLatency field is ignored. See PaStreamParameters for a description of these parameters. inputParameters must be NULL for output-only streams. @param outputParameters A structure that describes the output parameters used to open a stream. The suggestedLatency field is ignored. See PaStreamParameters for a description of these parameters. outputParameters must be NULL for input-only streams. @param sampleRate The required sampleRate. For full-duplex streams it is the sample rate for both input and output @return Returns 0 if the format is supported, and an error code indicating why the format is not supported otherwise. The constant paFormatIsSupported is provided to compare with the return value for success. @see paFormatIsSupported, PaStreamParameters */ PaError Pa_IsFormatSupported( const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ); /* Streaming types and functions */ /** A single PaStream can provide multiple channels of real-time streaming audio input and output to a client application. A stream provides access to audio hardware represented by one or more PaDevices. Depending on the underlying Host API, it may be possible to open multiple streams using the same device, however this behavior is implementation defined. Portable applications should assume that a PaDevice may be simultaneously used by at most one PaStream. Pointers to PaStream objects are passed between PortAudio functions that operate on streams. @see Pa_OpenStream, Pa_OpenDefaultStream, Pa_OpenDefaultStream, Pa_CloseStream, Pa_StartStream, Pa_StopStream, Pa_AbortStream, Pa_IsStreamActive, Pa_GetStreamTime, Pa_GetStreamCpuLoad */ typedef void PaStream; /** Can be passed as the framesPerBuffer parameter to Pa_OpenStream() or Pa_OpenDefaultStream() to indicate that the stream callback will accept buffers of any size. */ #define paFramesPerBufferUnspecified (0) /** Flags used to control the behavior of a stream. They are passed as parameters to Pa_OpenStream or Pa_OpenDefaultStream. Multiple flags may be ORed together. @see Pa_OpenStream, Pa_OpenDefaultStream @see paNoFlag, paClipOff, paDitherOff, paNeverDropInput, paPrimeOutputBuffersUsingStreamCallback, paPlatformSpecificFlags */ typedef unsigned long PaStreamFlags; /** @see PaStreamFlags */ #define paNoFlag ((PaStreamFlags) 0) /** Disable default clipping of out of range samples. @see PaStreamFlags */ #define paClipOff ((PaStreamFlags) 0x00000001) /** Disable default dithering. @see PaStreamFlags */ #define paDitherOff ((PaStreamFlags) 0x00000002) /** Flag requests that where possible a full duplex stream will not discard overflowed input samples without calling the stream callback. This flag is only valid for full duplex callback streams and only when used in combination with the paFramesPerBufferUnspecified (0) framesPerBuffer parameter. Using this flag incorrectly results in a paInvalidFlag error being returned from Pa_OpenStream and Pa_OpenDefaultStream. @see PaStreamFlags, paFramesPerBufferUnspecified */ #define paNeverDropInput ((PaStreamFlags) 0x00000004) /** Call the stream callback to fill initial output buffers, rather than the default behavior of priming the buffers with zeros (silence). This flag has no effect for input-only and blocking read/write streams. @see PaStreamFlags */ #define paPrimeOutputBuffersUsingStreamCallback ((PaStreamFlags) 0x00000008) /** A mask specifying the platform specific bits. @see PaStreamFlags */ #define paPlatformSpecificFlags ((PaStreamFlags)0xFFFF0000) /** Timing information for the buffers passed to the stream callback. Time values are expressed in seconds and are synchronised with the time base used by Pa_GetStreamTime() for the associated stream. @see PaStreamCallback, Pa_GetStreamTime */ typedef struct PaStreamCallbackTimeInfo{ PaTime inputBufferAdcTime; /**< The time when the first sample of the input buffer was captured at the ADC input */ PaTime currentTime; /**< The time when the stream callback was invoked */ PaTime outputBufferDacTime; /**< The time when the first sample of the output buffer will output the DAC */ } PaStreamCallbackTimeInfo; /** Flag bit constants for the statusFlags to PaStreamCallback. @see paInputUnderflow, paInputOverflow, paOutputUnderflow, paOutputOverflow, paPrimingOutput */ typedef unsigned long PaStreamCallbackFlags; /** In a stream opened with paFramesPerBufferUnspecified, indicates that input data is all silence (zeros) because no real data is available. In a stream opened without paFramesPerBufferUnspecified, it indicates that one or more zero samples have been inserted into the input buffer to compensate for an input underflow. @see PaStreamCallbackFlags */ #define paInputUnderflow ((PaStreamCallbackFlags) 0x00000001) /** In a stream opened with paFramesPerBufferUnspecified, indicates that data prior to the first sample of the input buffer was discarded due to an overflow, possibly because the stream callback is using too much CPU time. Otherwise indicates that data prior to one or more samples in the input buffer was discarded. @see PaStreamCallbackFlags */ #define paInputOverflow ((PaStreamCallbackFlags) 0x00000002) /** Indicates that output data (or a gap) was inserted, possibly because the stream callback is using too much CPU time. @see PaStreamCallbackFlags */ #define paOutputUnderflow ((PaStreamCallbackFlags) 0x00000004) /** Indicates that output data will be discarded because no room is available. @see PaStreamCallbackFlags */ #define paOutputOverflow ((PaStreamCallbackFlags) 0x00000008) /** Some of all of the output data will be used to prime the stream, input data may be zero. @see PaStreamCallbackFlags */ #define paPrimingOutput ((PaStreamCallbackFlags) 0x00000010) /** Allowable return values for the PaStreamCallback. @see PaStreamCallback */ typedef enum PaStreamCallbackResult { paContinue=0, /**< Signal that the stream should continue invoking the callback and processing audio. */ paComplete=1, /**< Signal that the stream should stop invoking the callback and finish once all output samples have played. */ paAbort=2 /**< Signal that the stream should stop invoking the callback and finish as soon as possible. */ } PaStreamCallbackResult; /** Functions of type PaStreamCallback are implemented by PortAudio clients. They consume, process or generate audio in response to requests from an active PortAudio stream. When a stream is running, PortAudio calls the stream callback periodically. The callback function is responsible for processing buffers of audio samples passed via the input and output parameters. The PortAudio stream callback runs at very high or real-time priority. It is required to consistently meet its time deadlines. Do not allocate memory, access the file system, call library functions or call other functions from the stream callback that may block or take an unpredictable amount of time to complete. In order for a stream to maintain glitch-free operation the callback must consume and return audio data faster than it is recorded and/or played. PortAudio anticipates that each callback invocation may execute for a duration approaching the duration of frameCount audio frames at the stream sample rate. It is reasonable to expect to be able to utilise 70% or more of the available CPU time in the PortAudio callback. However, due to buffer size adaption and other factors, not all host APIs are able to guarantee audio stability under heavy CPU load with arbitrary fixed callback buffer sizes. When high callback CPU utilisation is required the most robust behavior can be achieved by using paFramesPerBufferUnspecified as the Pa_OpenStream() framesPerBuffer parameter. @param input and @param output are either arrays of interleaved samples or; if non-interleaved samples were requested using the paNonInterleaved sample format flag, an array of buffer pointers, one non-interleaved buffer for each channel. The format, packing and number of channels used by the buffers are determined by parameters to Pa_OpenStream(). @param frameCount The number of sample frames to be processed by the stream callback. @param timeInfo Timestamps indicating the ADC capture time of the first sample in the input buffer, the DAC output time of the first sample in the output buffer and the time the callback was invoked. See PaStreamCallbackTimeInfo and Pa_GetStreamTime() @param statusFlags Flags indicating whether input and/or output buffers have been inserted or will be dropped to overcome underflow or overflow conditions. @param userData The value of a user supplied pointer passed to Pa_OpenStream() intended for storing synthesis data etc. @return The stream callback should return one of the values in the ::PaStreamCallbackResult enumeration. To ensure that the callback continues to be called, it should return paContinue (0). Either paComplete or paAbort can be returned to finish stream processing, after either of these values is returned the callback will not be called again. If paAbort is returned the stream will finish as soon as possible. If paComplete is returned, the stream will continue until all buffers generated by the callback have been played. This may be useful in applications such as soundfile players where a specific duration of output is required. However, it is not necessary to utilize this mechanism as Pa_StopStream(), Pa_AbortStream() or Pa_CloseStream() can also be used to stop the stream. The callback must always fill the entire output buffer irrespective of its return value. @see Pa_OpenStream, Pa_OpenDefaultStream @note With the exception of Pa_GetStreamCpuLoad() it is not permissible to call PortAudio API functions from within the stream callback. */ typedef int PaStreamCallback( const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData ); /** Opens a stream for either input, output or both. @param stream The address of a PaStream pointer which will receive a pointer to the newly opened stream. @param inputParameters A structure that describes the input parameters used by the opened stream. See PaStreamParameters for a description of these parameters. inputParameters must be NULL for output-only streams. @param outputParameters A structure that describes the output parameters used by the opened stream. See PaStreamParameters for a description of these parameters. outputParameters must be NULL for input-only streams. @param sampleRate The desired sampleRate. For full-duplex streams it is the sample rate for both input and output @param framesPerBuffer The number of frames passed to the stream callback function, or the preferred block granularity for a blocking read/write stream. The special value paFramesPerBufferUnspecified (0) may be used to request that the stream callback will receive an optimal (and possibly varying) number of frames based on host requirements and the requested latency settings. Note: With some host APIs, the use of non-zero framesPerBuffer for a callback stream may introduce an additional layer of buffering which could introduce additional latency. PortAudio guarantees that the additional latency will be kept to the theoretical minimum however, it is strongly recommended that a non-zero framesPerBuffer value only be used when your algorithm requires a fixed number of frames per stream callback. @param streamFlags Flags which modify the behavior of the streaming process. This parameter may contain a combination of flags ORed together. Some flags may only be relevant to certain buffer formats. @param streamCallback A pointer to a client supplied function that is responsible for processing and filling input and output buffers. If this parameter is NULL the stream will be opened in 'blocking read/write' mode. In blocking mode, the client can receive sample data using Pa_ReadStream and write sample data using Pa_WriteStream, the number of samples that may be read or written without blocking is returned by Pa_GetStreamReadAvailable and Pa_GetStreamWriteAvailable respectively. @param userData A client supplied pointer which is passed to the stream callback function. It could for example, contain a pointer to instance data necessary for processing the audio buffers. This parameter is ignored if streamCallback is NULL. @return Upon success Pa_OpenStream() returns paNoError and places a pointer to a valid PaStream in the stream argument. The stream is inactive (stopped). If a call to Pa_OpenStream() fails, a non-zero error code is returned (see PaError for possible error codes) and the value of stream is invalid. @see PaStreamParameters, PaStreamCallback, Pa_ReadStream, Pa_WriteStream, Pa_GetStreamReadAvailable, Pa_GetStreamWriteAvailable */ PaError Pa_OpenStream( PaStream** stream, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ); /** A simplified version of Pa_OpenStream() that opens the default input and/or output devices. @param stream The address of a PaStream pointer which will receive a pointer to the newly opened stream. @param numInputChannels The number of channels of sound that will be supplied to the stream callback or returned by Pa_ReadStream. It can range from 1 to the value of maxInputChannels in the PaDeviceInfo record for the default input device. If 0 the stream is opened as an output-only stream. @param numOutputChannels The number of channels of sound to be delivered to the stream callback or passed to Pa_WriteStream. It can range from 1 to the value of maxOutputChannels in the PaDeviceInfo record for the default output device. If 0 the stream is opened as an output-only stream. @param sampleFormat The sample format of both the input and output buffers provided to the callback or passed to and from Pa_ReadStream and Pa_WriteStream. sampleFormat may be any of the formats described by the PaSampleFormat enumeration. @param sampleRate Same as Pa_OpenStream parameter of the same name. @param framesPerBuffer Same as Pa_OpenStream parameter of the same name. @param streamCallback Same as Pa_OpenStream parameter of the same name. @param userData Same as Pa_OpenStream parameter of the same name. @return As for Pa_OpenStream @see Pa_OpenStream, PaStreamCallback */ PaError Pa_OpenDefaultStream( PaStream** stream, int numInputChannels, int numOutputChannels, PaSampleFormat sampleFormat, double sampleRate, unsigned long framesPerBuffer, PaStreamCallback *streamCallback, void *userData ); /** Closes an audio stream. If the audio stream is active it discards any pending buffers as if Pa_AbortStream() had been called. */ PaError Pa_CloseStream( PaStream *stream ); /** Functions of type PaStreamFinishedCallback are implemented by PortAudio clients. They can be registered with a stream using the Pa_SetStreamFinishedCallback function. Once registered they are called when the stream becomes inactive (ie once a call to Pa_StopStream() will not block). A stream will become inactive after the stream callback returns non-zero, or when Pa_StopStream or Pa_AbortStream is called. For a stream providing audio output, if the stream callback returns paComplete, or Pa_StopStream is called, the stream finished callback will not be called until all generated sample data has been played. @param userData The userData parameter supplied to Pa_OpenStream() @see Pa_SetStreamFinishedCallback */ typedef void PaStreamFinishedCallback( void *userData ); /** Register a stream finished callback function which will be called when the stream becomes inactive. See the description of PaStreamFinishedCallback for further details about when the callback will be called. @param stream a pointer to a PaStream that is in the stopped state - if the stream is not stopped, the stream's finished callback will remain unchanged and an error code will be returned. @param streamFinishedCallback a pointer to a function with the same signature as PaStreamFinishedCallback, that will be called when the stream becomes inactive. Passing NULL for this parameter will un-register a previously registered stream finished callback function. @return on success returns paNoError, otherwise an error code indicating the cause of the error. @see PaStreamFinishedCallback */ PaError Pa_SetStreamFinishedCallback( PaStream *stream, PaStreamFinishedCallback* streamFinishedCallback ); /** Commences audio processing. */ PaError Pa_StartStream( PaStream *stream ); /** Terminates audio processing. It waits until all pending audio buffers have been played before it returns. */ PaError Pa_StopStream( PaStream *stream ); /** Terminates audio processing immediately without waiting for pending buffers to complete. */ PaError Pa_AbortStream( PaStream *stream ); /** Determine whether the stream is stopped. A stream is considered to be stopped prior to a successful call to Pa_StartStream and after a successful call to Pa_StopStream or Pa_AbortStream. If a stream callback returns a value other than paContinue the stream is NOT considered to be stopped. @return Returns one (1) when the stream is stopped, zero (0) when the stream is running or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. @see Pa_StopStream, Pa_AbortStream, Pa_IsStreamActive */ PaError Pa_IsStreamStopped( PaStream *stream ); /** Determine whether the stream is active. A stream is active after a successful call to Pa_StartStream(), until it becomes inactive either as a result of a call to Pa_StopStream() or Pa_AbortStream(), or as a result of a return value other than paContinue from the stream callback. In the latter case, the stream is considered inactive after the last buffer has finished playing. @return Returns one (1) when the stream is active (ie playing or recording audio), zero (0) when not playing or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. @see Pa_StopStream, Pa_AbortStream, Pa_IsStreamStopped */ PaError Pa_IsStreamActive( PaStream *stream ); /** A structure containing unchanging information about an open stream. @see Pa_GetStreamInfo */ typedef struct PaStreamInfo { /** this is struct version 1 */ int structVersion; /** The input latency of the stream in seconds. This value provides the most accurate estimate of input latency available to the implementation. It may differ significantly from the suggestedLatency value passed to Pa_OpenStream(). The value of this field will be zero (0.) for output-only streams. @see PaTime */ PaTime inputLatency; /** The output latency of the stream in seconds. This value provides the most accurate estimate of output latency available to the implementation. It may differ significantly from the suggestedLatency value passed to Pa_OpenStream(). The value of this field will be zero (0.) for input-only streams. @see PaTime */ PaTime outputLatency; /** The sample rate of the stream in Hertz (samples per second). In cases where the hardware sample rate is inaccurate and PortAudio is aware of it, the value of this field may be different from the sampleRate parameter passed to Pa_OpenStream(). If information about the actual hardware sample rate is not available, this field will have the same value as the sampleRate parameter passed to Pa_OpenStream(). */ double sampleRate; } PaStreamInfo; /** Retrieve a pointer to a PaStreamInfo structure containing information about the specified stream. @return A pointer to an immutable PaStreamInfo structure. If the stream parameter is invalid, or an error is encountered, the function returns NULL. @param stream A pointer to an open stream previously created with Pa_OpenStream. @note PortAudio manages the memory referenced by the returned pointer, the client must not manipulate or free the memory. The pointer is only guaranteed to be valid until the specified stream is closed. @see PaStreamInfo */ const PaStreamInfo* Pa_GetStreamInfo( PaStream *stream ); /** Returns the current time in seconds for a stream according to the same clock used to generate callback PaStreamCallbackTimeInfo timestamps. The time values are monotonically increasing and have unspecified origin. Pa_GetStreamTime returns valid time values for the entire life of the stream, from when the stream is opened until it is closed. Starting and stopping the stream does not affect the passage of time returned by Pa_GetStreamTime. This time may be used for synchronizing other events to the audio stream, for example synchronizing audio to MIDI. @return The stream's current time in seconds, or 0 if an error occurred. @see PaTime, PaStreamCallback, PaStreamCallbackTimeInfo */ PaTime Pa_GetStreamTime( PaStream *stream ); /** Retrieve CPU usage information for the specified stream. The "CPU Load" is a fraction of total CPU time consumed by a callback stream's audio processing routines including, but not limited to the client supplied stream callback. This function does not work with blocking read/write streams. This function may be called from the stream callback function or the application. @return A floating point value, typically between 0.0 and 1.0, where 1.0 indicates that the stream callback is consuming the maximum number of CPU cycles possible to maintain real-time operation. A value of 0.5 would imply that PortAudio and the stream callback was consuming roughly 50% of the available CPU time. The return value may exceed 1.0. A value of 0.0 will always be returned for a blocking read/write stream, or if an error occurs. */ double Pa_GetStreamCpuLoad( PaStream* stream ); /** Read samples from an input stream. The function doesn't return until the entire buffer has been filled - this may involve waiting for the operating system to supply the data. @param stream A pointer to an open stream previously created with Pa_OpenStream. @param buffer A pointer to a buffer of sample frames. The buffer contains samples in the format specified by the inputParameters->sampleFormat field used to open the stream, and the number of channels specified by inputParameters->numChannels. If non-interleaved samples were requested using the paNonInterleaved sample format flag, buffer is a pointer to the first element of an array of buffer pointers, one non-interleaved buffer for each channel. @param frames The number of frames to be read into buffer. This parameter is not constrained to a specific range, however high performance applications will want to match this parameter to the framesPerBuffer parameter used when opening the stream. @return On success PaNoError will be returned, or PaInputOverflowed if input data was discarded by PortAudio after the previous call and before this call. */ PaError Pa_ReadStream( PaStream* stream, void *buffer, unsigned long frames ); /** Write samples to an output stream. This function doesn't return until the entire buffer has been consumed - this may involve waiting for the operating system to consume the data. @param stream A pointer to an open stream previously created with Pa_OpenStream. @param buffer A pointer to a buffer of sample frames. The buffer contains samples in the format specified by the outputParameters->sampleFormat field used to open the stream, and the number of channels specified by outputParameters->numChannels. If non-interleaved samples were requested using the paNonInterleaved sample format flag, buffer is a pointer to the first element of an array of buffer pointers, one non-interleaved buffer for each channel. @param frames The number of frames to be written from buffer. This parameter is not constrained to a specific range, however high performance applications will want to match this parameter to the framesPerBuffer parameter used when opening the stream. @return On success PaNoError will be returned, or paOutputUnderflowed if additional output data was inserted after the previous call and before this call. */ PaError Pa_WriteStream( PaStream* stream, const void *buffer, unsigned long frames ); /** Retrieve the number of frames that can be read from the stream without waiting. @return Returns a non-negative value representing the maximum number of frames that can be read from the stream without blocking or busy waiting or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. */ signed long Pa_GetStreamReadAvailable( PaStream* stream ); /** Retrieve the number of frames that can be written to the stream without waiting. @return Returns a non-negative value representing the maximum number of frames that can be written to the stream without blocking or busy waiting or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. */ signed long Pa_GetStreamWriteAvailable( PaStream* stream ); /* Miscellaneous utilities */ /** Retrieve the size of a given sample format in bytes. @return The size in bytes of a single sample in the specified format, or paSampleFormatNotSupported if the format is not supported. */ PaError Pa_GetSampleSize( PaSampleFormat format ); /** Put the caller to sleep for at least 'msec' milliseconds. This function is provided only as a convenience for authors of portable code (such as the tests and examples in the PortAudio distribution.) The function may sleep longer than requested so don't rely on this for accurate musical timing. */ void Pa_Sleep( long msec ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PORTAUDIO_H */ pd-0.46-7/portaudio/include/pa_asio.h0000664000175000017500000001316512222201037015606 0ustar mspmsp#ifndef PA_ASIO_H #define PA_ASIO_H /* * $Id: pa_asio.h 1667 2011-05-02 15:49:20Z rossb $ * PortAudio Portable Real-Time Audio Library * ASIO specific extensions * * Copyright (c) 1999-2000 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup public_header @brief ASIO-specific PortAudio API extension header file. */ #include "portaudio.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** Retrieve legal native buffer sizes for the specificed device, in sample frames. @param device The global index of the device about which the query is being made. @param minBufferSizeFrames A pointer to the location which will receive the minimum buffer size value. @param maxBufferSizeFrames A pointer to the location which will receive the maximum buffer size value. @param preferredBufferSizeFrames A pointer to the location which will receive the preferred buffer size value. @param granularity A pointer to the location which will receive the "granularity". This value determines the step size used to compute the legal values between minBufferSizeFrames and maxBufferSizeFrames. If granularity is -1 then available buffer size values are powers of two. @see ASIOGetBufferSize in the ASIO SDK. @note: this function used to be called PaAsio_GetAvailableLatencyValues. There is a #define that maps PaAsio_GetAvailableLatencyValues to this function for backwards compatibility. */ PaError PaAsio_GetAvailableBufferSizes( PaDeviceIndex device, long *minBufferSizeFrames, long *maxBufferSizeFrames, long *preferredBufferSizeFrames, long *granularity ); /** Backwards compatibility alias for PaAsio_GetAvailableBufferSizes @see PaAsio_GetAvailableBufferSizes */ #define PaAsio_GetAvailableLatencyValues PaAsio_GetAvailableBufferSizes /** Display the ASIO control panel for the specified device. @param device The global index of the device whose control panel is to be displayed. @param systemSpecific On Windows, the calling application's main window handle, on Macintosh this value should be zero. */ PaError PaAsio_ShowControlPanel( PaDeviceIndex device, void* systemSpecific ); /** Retrieve a pointer to a string containing the name of the specified input channel. The string is valid until Pa_Terminate is called. The string will be no longer than 32 characters including the null terminator. */ PaError PaAsio_GetInputChannelName( PaDeviceIndex device, int channelIndex, const char** channelName ); /** Retrieve a pointer to a string containing the name of the specified input channel. The string is valid until Pa_Terminate is called. The string will be no longer than 32 characters including the null terminator. */ PaError PaAsio_GetOutputChannelName( PaDeviceIndex device, int channelIndex, const char** channelName ); /** Set the sample rate of an open paASIO stream. @param stream The stream to operate on. @param sampleRate The new sample rate. Note that this function may fail if the stream is alredy running and the ASIO driver does not support switching the sample rate of a running stream. Returns paIncompatibleStreamHostApi if stream is not a paASIO stream. */ PaError PaAsio_SetStreamSampleRate( PaStream* stream, double sampleRate ); #define paAsioUseChannelSelectors (0x01) typedef struct PaAsioStreamInfo{ unsigned long size; /**< sizeof(PaAsioStreamInfo) */ PaHostApiTypeId hostApiType; /**< paASIO */ unsigned long version; /**< 1 */ unsigned long flags; /* Support for opening only specific channels of an ASIO device. If the paAsioUseChannelSelectors flag is set, channelSelectors is a pointer to an array of integers specifying the device channels to use. When used, the length of the channelSelectors array must match the corresponding channelCount parameter to Pa_OpenStream() otherwise a crash may result. The values in the selectors array must specify channels within the range of supported channels for the device or paInvalidChannelCount will result. */ int *channelSelectors; }PaAsioStreamInfo; #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_ASIO_H */ pd-0.46-7/portaudio/include/pa_win_wmme.h0000664000175000017500000001535412222201037016477 0ustar mspmsp#ifndef PA_WIN_WMME_H #define PA_WIN_WMME_H /* * $Id: pa_win_wmme.h 1592 2011-02-04 10:41:58Z rossb $ * PortAudio Portable Real-Time Audio Library * MME specific extensions * * Copyright (c) 1999-2000 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup public_header @brief WMME-specific PortAudio API extension header file. */ #include "portaudio.h" #include "pa_win_waveformat.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* The following are flags which can be set in PaWinMmeStreamInfo's flags field. */ #define paWinMmeUseLowLevelLatencyParameters (0x01) #define paWinMmeUseMultipleDevices (0x02) /* use mme specific multiple device feature */ #define paWinMmeUseChannelMask (0x04) /* By default, the mme implementation drops the processing thread's priority to THREAD_PRIORITY_NORMAL and sleeps the thread if the CPU load exceeds 100% This flag disables any priority throttling. The processing thread will always run at THREAD_PRIORITY_TIME_CRITICAL. */ #define paWinMmeDontThrottleOverloadedProcessingThread (0x08) /* Flags for non-PCM spdif passthrough. */ #define paWinMmeWaveFormatDolbyAc3Spdif (0x10) #define paWinMmeWaveFormatWmaSpdif (0x20) typedef struct PaWinMmeDeviceAndChannelCount{ PaDeviceIndex device; int channelCount; }PaWinMmeDeviceAndChannelCount; typedef struct PaWinMmeStreamInfo{ unsigned long size; /**< sizeof(PaWinMmeStreamInfo) */ PaHostApiTypeId hostApiType; /**< paMME */ unsigned long version; /**< 1 */ unsigned long flags; /* low-level latency setting support These settings control the number and size of host buffers in order to set latency. They will be used instead of the generic parameters to Pa_OpenStream() if flags contains the PaWinMmeUseLowLevelLatencyParameters flag. If PaWinMmeStreamInfo structures with PaWinMmeUseLowLevelLatencyParameters are supplied for both input and output in a full duplex stream, then the input and output framesPerBuffer must be the same, or the larger of the two must be a multiple of the smaller, otherwise a paIncompatibleHostApiSpecificStreamInfo error will be returned from Pa_OpenStream(). */ unsigned long framesPerBuffer; unsigned long bufferCount; /* formerly numBuffers */ /* multiple devices per direction support If flags contains the PaWinMmeUseMultipleDevices flag, this functionality will be used, otherwise the device parameter to Pa_OpenStream() will be used instead. If devices are specified here, the corresponding device parameter to Pa_OpenStream() should be set to paUseHostApiSpecificDeviceSpecification, otherwise an paInvalidDevice error will result. The total number of channels accross all specified devices must agree with the corresponding channelCount parameter to Pa_OpenStream() otherwise a paInvalidChannelCount error will result. */ PaWinMmeDeviceAndChannelCount *devices; unsigned long deviceCount; /* support for WAVEFORMATEXTENSIBLE channel masks. If flags contains paWinMmeUseChannelMask this allows you to specify which speakers to address in a multichannel stream. Constants for channelMask are specified in pa_win_waveformat.h */ PaWinWaveFormatChannelMask channelMask; }PaWinMmeStreamInfo; /** Retrieve the number of wave in handles used by a PortAudio WinMME stream. Returns zero if the stream is output only. @return A non-negative value indicating the number of wave in handles or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. @see PaWinMME_GetStreamInputHandle */ int PaWinMME_GetStreamInputHandleCount( PaStream* stream ); /** Retrieve a wave in handle used by a PortAudio WinMME stream. @param stream The stream to query. @param handleIndex The zero based index of the wave in handle to retrieve. This should be in the range [0, PaWinMME_GetStreamInputHandleCount(stream)-1]. @return A valid wave in handle, or NULL if an error occurred. @see PaWinMME_GetStreamInputHandle */ HWAVEIN PaWinMME_GetStreamInputHandle( PaStream* stream, int handleIndex ); /** Retrieve the number of wave out handles used by a PortAudio WinMME stream. Returns zero if the stream is input only. @return A non-negative value indicating the number of wave out handles or, a PaErrorCode (which are always negative) if PortAudio is not initialized or an error is encountered. @see PaWinMME_GetStreamOutputHandle */ int PaWinMME_GetStreamOutputHandleCount( PaStream* stream ); /** Retrieve a wave out handle used by a PortAudio WinMME stream. @param stream The stream to query. @param handleIndex The zero based index of the wave out handle to retrieve. This should be in the range [0, PaWinMME_GetStreamOutputHandleCount(stream)-1]. @return A valid wave out handle, or NULL if an error occurred. @see PaWinMME_GetStreamOutputHandleCount */ HWAVEOUT PaWinMME_GetStreamOutputHandle( PaStream* stream, int handleIndex ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_WIN_WMME_H */ pd-0.46-7/portaudio/include/pa_linux_alsa.h0000664000175000017500000000743412222201037017014 0ustar mspmsp#ifndef PA_LINUX_ALSA_H #define PA_LINUX_ALSA_H /* * $Id: pa_linux_alsa.h 1597 2011-02-11 00:15:51Z dmitrykos $ * PortAudio Portable Real-Time Audio Library * ALSA-specific extensions * * Copyright (c) 1999-2000 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file * @ingroup public_header * @brief ALSA-specific PortAudio API extension header file. */ #include "portaudio.h" #ifdef __cplusplus extern "C" { #endif typedef struct PaAlsaStreamInfo { unsigned long size; PaHostApiTypeId hostApiType; unsigned long version; const char *deviceString; } PaAlsaStreamInfo; /** Initialize host API specific structure, call this before setting relevant attributes. */ void PaAlsa_InitializeStreamInfo( PaAlsaStreamInfo *info ); /** Instruct whether to enable real-time priority when starting the audio thread. * * If this is turned on by the stream is started, the audio callback thread will be created * with the FIFO scheduling policy, which is suitable for realtime operation. **/ void PaAlsa_EnableRealtimeScheduling( PaStream *s, int enable ); #if 0 void PaAlsa_EnableWatchdog( PaStream *s, int enable ); #endif /** Get the ALSA-lib card index of this stream's input device. */ PaError PaAlsa_GetStreamInputCard( PaStream *s, int *card ); /** Get the ALSA-lib card index of this stream's output device. */ PaError PaAlsa_GetStreamOutputCard( PaStream *s, int *card ); /** Set the number of periods (buffer fragments) to configure devices with. * * By default the number of periods is 4, this is the lowest number of periods that works well on * the author's soundcard. * @param numPeriods The number of periods. */ PaError PaAlsa_SetNumPeriods( int numPeriods ); /** Set the maximum number of times to retry opening busy device (sleeping for a * short interval inbetween). */ PaError PaAlsa_SetRetriesBusy( int retries ); /** Set the path and name of ALSA library file if PortAudio is configured to load it dynamically (see * PA_ALSA_DYNAMIC). This setting will overwrite the default name set by PA_ALSA_PATHNAME define. * @param pathName Full path with filename. Only filename can be used, but dlopen() will lookup default * searchable directories (/usr/lib;/usr/local/lib) then. */ void PaAlsa_SetLibraryPathName( const char *pathName ); #ifdef __cplusplus } #endif #endif pd-0.46-7/portaudio/include/pa_jack.h0000664000175000017500000000536512222201037015566 0ustar mspmsp#ifndef PA_JACK_H #define PA_JACK_H /* * $Id: * PortAudio Portable Real-Time Audio Library * JACK-specific extensions * * Copyright (c) 1999-2000 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file * @ingroup public_header * @brief JACK-specific PortAudio API extension header file. */ #include "portaudio.h" #ifdef __cplusplus extern "C" { #endif /** Set the JACK client name. * * During Pa_Initialize, When PA JACK connects as a client of the JACK server, it requests a certain * name, which is for instance prepended to port names. By default this name is "PortAudio". The * JACK server may append a suffix to the client name, in order to avoid clashes among clients that * try to connect with the same name (e.g., different PA JACK clients). * * This function must be called before Pa_Initialize, otherwise it won't have any effect. Note that * the string is not copied, but instead referenced directly, so it must not be freed for as long as * PA might need it. * @sa PaJack_GetClientName */ PaError PaJack_SetClientName( const char* name ); /** Get the JACK client name used by PA JACK. * * The caller is responsible for freeing the returned pointer. */ PaError PaJack_GetClientName(const char** clientName); #ifdef __cplusplus } #endif #endif pd-0.46-7/portaudio/install-sh0000775000175000017500000003253712374245151014424 0ustar mspmsp#!/bin/sh # install - install a program, script, or datafile scriptversion=2009-04-28.21; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. nl=' ' IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} if test -z "$doit"; then doit_exec=exec else doit_exec=$doit fi # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_glob='?' initialize_posix_glob=' test "$posix_glob" != "?" || { if (set -f) 2>/dev/null; then posix_glob= else posix_glob=: fi } ' posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false no_target_directory= usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *' '* | *' '* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) dst_arg=$2 shift;; -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call `install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then trap '(exit $?); exit' 1 2 13 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names starting with `-'. case $src in -*) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # Protect names starting with `-'. case $dst in -*) dst=./$dst;; esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else # Prefer dirname, but fall back on a substitute if dirname fails. dstdir=` (dirname "$dst") 2>/dev/null || expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$dst" : 'X\(//\)[^/]' \| \ X"$dst" : 'X\(//\)$' \| \ X"$dst" : 'X\(/\)' \| . 2>/dev/null || echo X"$dst" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q' ` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writeable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; -*) prefix='./';; *) prefix='';; esac eval "$initialize_posix_glob" oIFS=$IFS IFS=/ $posix_glob set -f set fnord $dstdir shift $posix_glob set +f IFS=$oIFS prefixes= for d do test -z "$d" && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && eval "$initialize_posix_glob" && $posix_glob set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && $posix_glob set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: pd-0.46-7/portaudio/src/0000775000175000017500000000000012160204055013164 5ustar mspmsppd-0.46-7/portaudio/src/os/0000775000175000017500000000000012160204055013605 5ustar mspmsppd-0.46-7/portaudio/src/os/mac_osx/0000775000175000017500000000000012222201037015232 5ustar mspmsppd-0.46-7/portaudio/src/os/mac_osx/pa_mac_hostapis.c0000664000175000017500000000551412222201037020535 0ustar mspmsp/* * $Id: pa_mac_hostapis.c 1097 2006-08-26 08:27:53Z rossb $ * Portable Audio I/O Library Macintosh initialization table * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup macosx_src Mac OS host API initialization function table. */ #include "pa_hostapi.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaMacSm_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaJack_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaMacAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); #ifdef __cplusplus } #endif /* __cplusplus */ PaUtilHostApiInitializer *paHostApiInitializers[] = { #if PA_USE_COREAUDIO PaMacCore_Initialize, #endif #if PA_USE_SM PaMacSm_Initialize, #endif #if PA_USE_JACK PaJack_Initialize, #endif #if PA_USE_ASIO PaMacAsio_Initialize, #endif #if PA_USE_SKELETON PaSkeleton_Initialize, /* just for testing */ #endif 0 /* NULL terminated array */ }; int paDefaultHostApiIndex = 0; pd-0.46-7/portaudio/src/os/unix/0000775000175000017500000000000012222201037014564 5ustar mspmsppd-0.46-7/portaudio/src/os/unix/pa_unix_hostapis.c0000664000175000017500000000643212222201037020312 0ustar mspmsp/* * $Id: pa_unix_hostapis.c 1740 2011-08-25 07:17:48Z philburk $ * Portable Audio I/O Library UNIX initialization table * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup unix_src */ #include "pa_hostapi.h" PaError PaJack_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaAlsa_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaOSS_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); /* Added for IRIX, Pieter, oct 2, 2003: */ PaError PaSGI_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); /* Linux AudioScience HPI */ PaError PaAsiHpi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); /** Note that on Linux, ALSA is placed before OSS so that the former is preferred over the latter. */ PaUtilHostApiInitializer *paHostApiInitializers[] = { #ifdef __linux__ #if PA_USE_ALSA PaAlsa_Initialize, #endif #if PA_USE_OSS PaOSS_Initialize, #endif #else /* __linux__ */ #if PA_USE_OSS PaOSS_Initialize, #endif #if PA_USE_ALSA PaAlsa_Initialize, #endif #endif /* __linux__ */ #if PA_USE_JACK PaJack_Initialize, #endif /* Added for IRIX, Pieter, oct 2, 2003: */ #if PA_USE_SGI PaSGI_Initialize, #endif #if PA_USE_ASIHPI PaAsiHpi_Initialize, #endif #if PA_USE_COREAUDIO PaMacCore_Initialize, #endif #if PA_USE_SKELETON PaSkeleton_Initialize, #endif 0 /* NULL terminated array */ }; pd-0.46-7/portaudio/src/os/unix/pa_unix_util.c0000664000175000017500000005030512222201037017433 0ustar mspmsp/* * $Id: pa_unix_util.c 1510 2010-06-10 08:05:29Z dmitrykos $ * Portable Audio I/O Library * UNIX platform-specific support functions * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2000 Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup unix_src */ #include #include #include #include #include #include #include /* For memset */ #include #include #if defined(__APPLE__) && !defined(HAVE_MACH_ABSOLUTE_TIME) #define HAVE_MACH_ABSOLUTE_TIME #endif #ifdef HAVE_MACH_ABSOLUTE_TIME #include #endif #include "pa_util.h" #include "pa_unix_util.h" #include "pa_debugprint.h" /* Track memory allocations to avoid leaks. */ #if PA_TRACK_MEMORY static int numAllocations_ = 0; #endif void *PaUtil_AllocateMemory( long size ) { void *result = malloc( size ); #if PA_TRACK_MEMORY if( result != NULL ) numAllocations_ += 1; #endif return result; } void PaUtil_FreeMemory( void *block ) { if( block != NULL ) { free( block ); #if PA_TRACK_MEMORY numAllocations_ -= 1; #endif } } int PaUtil_CountCurrentlyAllocatedBlocks( void ) { #if PA_TRACK_MEMORY return numAllocations_; #else return 0; #endif } void Pa_Sleep( long msec ) { #ifdef HAVE_NANOSLEEP struct timespec req = {0}, rem = {0}; PaTime time = msec / 1.e3; req.tv_sec = (time_t)time; assert(time - req.tv_sec < 1.0); req.tv_nsec = (long)((time - req.tv_sec) * 1.e9); nanosleep(&req, &rem); /* XXX: Try sleeping the remaining time (contained in rem) if interrupted by a signal? */ #else while( msec > 999 ) /* For OpenBSD and IRIX, argument */ { /* to usleep must be < 1000000. */ usleep( 999000 ); msec -= 999; } usleep( msec * 1000 ); #endif } #ifdef HAVE_MACH_ABSOLUTE_TIME /* Discussion on the CoreAudio mailing list suggests that calling gettimeofday (or anything else in the BSD layer) is not real-time safe, so we use mach_absolute_time on OSX. This implementation is based on these two links: Technical Q&A QA1398 - Mach Absolute Time Units http://developer.apple.com/mac/library/qa/qa2004/qa1398.html Tutorial: Performance and Time. http://www.macresearch.org/tutorial_performance_and_time */ /* Scaler to convert the result of mach_absolute_time to seconds */ static double machSecondsConversionScaler_ = 0.0; #endif void PaUtil_InitializeClock( void ) { #ifdef HAVE_MACH_ABSOLUTE_TIME mach_timebase_info_data_t info; kern_return_t err = mach_timebase_info( &info ); if( err == 0 ) machSecondsConversionScaler_ = 1e-9 * (double) info.numer / (double) info.denom; #endif } PaTime PaUtil_GetTime( void ) { #ifdef HAVE_MACH_ABSOLUTE_TIME return mach_absolute_time() * machSecondsConversionScaler_; #elif defined(HAVE_CLOCK_GETTIME) struct timespec tp; clock_gettime(CLOCK_REALTIME, &tp); return (PaTime)(tp.tv_sec + tp.tv_nsec * 1e-9); #else struct timeval tv; gettimeofday( &tv, NULL ); return (PaTime) tv.tv_usec * 1e-6 + tv.tv_sec; #endif } PaError PaUtil_InitializeThreading( PaUtilThreading *threading ) { (void) paUtilErr_; return paNoError; } void PaUtil_TerminateThreading( PaUtilThreading *threading ) { } PaError PaUtil_StartThreading( PaUtilThreading *threading, void *(*threadRoutine)(void *), void *data ) { pthread_create( &threading->callbackThread, NULL, threadRoutine, data ); return paNoError; } PaError PaUtil_CancelThreading( PaUtilThreading *threading, int wait, PaError *exitResult ) { PaError result = paNoError; void *pret; if( exitResult ) *exitResult = paNoError; /* If pthread_cancel is not supported (Android platform) whole this function can lead to indefinite waiting if working thread (callbackThread) has'n received any stop signals from outside, please keep this in mind when considering using PaUtil_CancelThreading */ #ifdef PTHREAD_CANCELED /* Only kill the thread if it isn't in the process of stopping (flushing adaptation buffers) */ if( !wait ) pthread_cancel( threading->callbackThread ); /* XXX: Safe to call this if the thread has exited on its own? */ #endif pthread_join( threading->callbackThread, &pret ); #ifdef PTHREAD_CANCELED if( pret && PTHREAD_CANCELED != pret ) #else /* !wait means the thread may have been canceled */ if( pret && wait ) #endif { if( exitResult ) *exitResult = *(PaError *) pret; free( pret ); } return result; } /* Threading */ /* paUnixMainThread * We have to be a bit careful with defining this global variable, * as explained below. */ #ifdef __APPLE__ /* apple/gcc has a "problem" with global vars and dynamic libs. Initializing it seems to fix the problem. Described a bit in this thread: http://gcc.gnu.org/ml/gcc/2005-06/msg00179.html */ pthread_t paUnixMainThread = 0; #else /*pthreads are opaque. We don't know that asigning it an int value always makes sense, so we don't initialize it unless we have to.*/ pthread_t paUnixMainThread = 0; #endif PaError PaUnixThreading_Initialize() { paUnixMainThread = pthread_self(); return paNoError; } static PaError BoostPriority( PaUnixThread* self ) { PaError result = paNoError; struct sched_param spm = { 0 }; /* Priority should only matter between contending FIFO threads? */ spm.sched_priority = 1; assert( self ); if( pthread_setschedparam( self->thread, SCHED_FIFO, &spm ) != 0 ) { PA_UNLESS( errno == EPERM, paInternalError ); /* Lack permission to raise priority */ PA_DEBUG(( "Failed bumping priority\n" )); result = 0; } else { result = 1; /* Success */ } error: return result; } PaError PaUnixThread_New( PaUnixThread* self, void* (*threadFunc)( void* ), void* threadArg, PaTime waitForChild, int rtSched ) { PaError result = paNoError; pthread_attr_t attr; int started = 0; memset( self, 0, sizeof (PaUnixThread) ); PaUnixMutex_Initialize( &self->mtx ); PA_ASSERT_CALL( pthread_cond_init( &self->cond, NULL ), 0 ); self->parentWaiting = 0 != waitForChild; /* Spawn thread */ /* Temporarily disabled since we should test during configuration for presence of required mman.h header */ #if 0 #if defined _POSIX_MEMLOCK && (_POSIX_MEMLOCK != -1) if( rtSched ) { if( mlockall( MCL_CURRENT | MCL_FUTURE ) < 0 ) { int savedErrno = errno; /* In case errno gets overwritten */ assert( savedErrno != EINVAL ); /* Most likely a programmer error */ PA_UNLESS( (savedErrno == EPERM), paInternalError ); PA_DEBUG(( "%s: Failed locking memory\n", __FUNCTION__ )); } else PA_DEBUG(( "%s: Successfully locked memory\n", __FUNCTION__ )); } #endif #endif PA_UNLESS( !pthread_attr_init( &attr ), paInternalError ); /* Priority relative to other processes */ PA_UNLESS( !pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM ), paInternalError ); PA_UNLESS( !pthread_create( &self->thread, &attr, threadFunc, threadArg ), paInternalError ); started = 1; if( rtSched ) { #if 0 if( self->useWatchdog ) { int err; struct sched_param wdSpm = { 0 }; /* Launch watchdog, watchdog sets callback thread priority */ int prio = PA_MIN( self->rtPrio + 4, sched_get_priority_max( SCHED_FIFO ) ); wdSpm.sched_priority = prio; PA_UNLESS( !pthread_attr_init( &attr ), paInternalError ); PA_UNLESS( !pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED ), paInternalError ); PA_UNLESS( !pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM ), paInternalError ); PA_UNLESS( !pthread_attr_setschedpolicy( &attr, SCHED_FIFO ), paInternalError ); PA_UNLESS( !pthread_attr_setschedparam( &attr, &wdSpm ), paInternalError ); if( (err = pthread_create( &self->watchdogThread, &attr, &WatchdogFunc, self )) ) { PA_UNLESS( err == EPERM, paInternalError ); /* Permission error, go on without realtime privileges */ PA_DEBUG(( "Failed bumping priority\n" )); } else { int policy; self->watchdogRunning = 1; PA_ENSURE_SYSTEM( pthread_getschedparam( self->watchdogThread, &policy, &wdSpm ), 0 ); /* Check if priority is right, policy could potentially differ from SCHED_FIFO (but that's alright) */ if( wdSpm.sched_priority != prio ) { PA_DEBUG(( "Watchdog priority not set correctly (%d)\n", wdSpm.sched_priority )); PA_ENSURE( paInternalError ); } } } else #endif PA_ENSURE( BoostPriority( self ) ); { int policy; struct sched_param spm; pthread_getschedparam(self->thread, &policy, &spm); } } if( self->parentWaiting ) { PaTime till; struct timespec ts; int res = 0; PaTime now; PA_ENSURE( PaUnixMutex_Lock( &self->mtx ) ); /* Wait for stream to be started */ now = PaUtil_GetTime(); till = now + waitForChild; while( self->parentWaiting && !res ) { if( waitForChild > 0 ) { ts.tv_sec = (time_t) floor( till ); ts.tv_nsec = (long) ((till - floor( till )) * 1e9); res = pthread_cond_timedwait( &self->cond, &self->mtx.mtx, &ts ); } else { res = pthread_cond_wait( &self->cond, &self->mtx.mtx ); } } PA_ENSURE( PaUnixMutex_Unlock( &self->mtx ) ); PA_UNLESS( !res || ETIMEDOUT == res, paInternalError ); PA_DEBUG(( "%s: Waited for %g seconds for stream to start\n", __FUNCTION__, PaUtil_GetTime() - now )); if( ETIMEDOUT == res ) { PA_ENSURE( paTimedOut ); } } end: return result; error: if( started ) { PaUnixThread_Terminate( self, 0, NULL ); } goto end; } PaError PaUnixThread_Terminate( PaUnixThread* self, int wait, PaError* exitResult ) { PaError result = paNoError; void* pret; if( exitResult ) { *exitResult = paNoError; } #if 0 if( watchdogExitResult ) *watchdogExitResult = paNoError; if( th->watchdogRunning ) { pthread_cancel( th->watchdogThread ); PA_ENSURE_SYSTEM( pthread_join( th->watchdogThread, &pret ), 0 ); if( pret && pret != PTHREAD_CANCELED ) { if( watchdogExitResult ) *watchdogExitResult = *(PaError *) pret; free( pret ); } } #endif /* Only kill the thread if it isn't in the process of stopping (flushing adaptation buffers) */ /* TODO: Make join time out */ self->stopRequested = wait; if( !wait ) { PA_DEBUG(( "%s: Canceling thread %d\n", __FUNCTION__, self->thread )); /* XXX: Safe to call this if the thread has exited on its own? */ #ifdef PTHREAD_CANCELED pthread_cancel( self->thread ); #endif } PA_DEBUG(( "%s: Joining thread %d\n", __FUNCTION__, self->thread )); PA_ENSURE_SYSTEM( pthread_join( self->thread, &pret ), 0 ); #ifdef PTHREAD_CANCELED if( pret && PTHREAD_CANCELED != pret ) #else /* !wait means the thread may have been canceled */ if( pret && wait ) #endif { if( exitResult ) { *exitResult = *(PaError*)pret; } free( pret ); } error: PA_ASSERT_CALL( PaUnixMutex_Terminate( &self->mtx ), paNoError ); PA_ASSERT_CALL( pthread_cond_destroy( &self->cond ), 0 ); return result; } PaError PaUnixThread_PrepareNotify( PaUnixThread* self ) { PaError result = paNoError; PA_UNLESS( self->parentWaiting, paInternalError ); PA_ENSURE( PaUnixMutex_Lock( &self->mtx ) ); self->locked = 1; error: return result; } PaError PaUnixThread_NotifyParent( PaUnixThread* self ) { PaError result = paNoError; PA_UNLESS( self->parentWaiting, paInternalError ); if( !self->locked ) { PA_ENSURE( PaUnixMutex_Lock( &self->mtx ) ); self->locked = 1; } self->parentWaiting = 0; pthread_cond_signal( &self->cond ); PA_ENSURE( PaUnixMutex_Unlock( &self->mtx ) ); self->locked = 0; error: return result; } int PaUnixThread_StopRequested( PaUnixThread* self ) { return self->stopRequested; } PaError PaUnixMutex_Initialize( PaUnixMutex* self ) { PaError result = paNoError; PA_ASSERT_CALL( pthread_mutex_init( &self->mtx, NULL ), 0 ); return result; } PaError PaUnixMutex_Terminate( PaUnixMutex* self ) { PaError result = paNoError; PA_ASSERT_CALL( pthread_mutex_destroy( &self->mtx ), 0 ); return result; } /** Lock mutex. * * We're disabling thread cancellation while the thread is holding a lock, so mutexes are * properly unlocked at termination time. */ PaError PaUnixMutex_Lock( PaUnixMutex* self ) { PaError result = paNoError; #ifdef PTHREAD_CANCEL int oldState; PA_ENSURE_SYSTEM( pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &oldState ), 0 ); #endif PA_ENSURE_SYSTEM( pthread_mutex_lock( &self->mtx ), 0 ); error: return result; } /** Unlock mutex. * * Thread cancellation is enabled again after the mutex is properly unlocked. */ PaError PaUnixMutex_Unlock( PaUnixMutex* self ) { PaError result = paNoError; PA_ENSURE_SYSTEM( pthread_mutex_unlock( &self->mtx ), 0 ); #ifdef PTHREAD_CANCEL int oldState; PA_ENSURE_SYSTEM( pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, &oldState ), 0 ); #endif error: return result; } #if 0 static void OnWatchdogExit( void *userData ) { PaAlsaThreading *th = (PaAlsaThreading *) userData; struct sched_param spm = { 0 }; assert( th ); PA_ASSERT_CALL( pthread_setschedparam( th->callbackThread, SCHED_OTHER, &spm ), 0 ); /* Lower before exiting */ PA_DEBUG(( "Watchdog exiting\n" )); } static void *WatchdogFunc( void *userData ) { PaError result = paNoError, *pres = NULL; int err; PaAlsaThreading *th = (PaAlsaThreading *) userData; unsigned intervalMsec = 500; const PaTime maxSeconds = 3.; /* Max seconds between callbacks */ PaTime timeThen = PaUtil_GetTime(), timeNow, timeElapsed, cpuTimeThen, cpuTimeNow, cpuTimeElapsed; double cpuLoad, avgCpuLoad = 0.; int throttled = 0; assert( th ); /* Execute OnWatchdogExit when exiting */ pthread_cleanup_push( &OnWatchdogExit, th ); /* Boost priority of callback thread */ PA_ENSURE( result = BoostPriority( th ) ); if( !result ) { /* Boost failed, might as well exit */ pthread_exit( NULL ); } cpuTimeThen = th->callbackCpuTime; { int policy; struct sched_param spm = { 0 }; pthread_getschedparam( pthread_self(), &policy, &spm ); PA_DEBUG(( "%s: Watchdog priority is %d\n", __FUNCTION__, spm.sched_priority )); } while( 1 ) { double lowpassCoeff = 0.9, lowpassCoeff1 = 0.99999 - lowpassCoeff; /* Test before and after in case whatever underlying sleep call isn't interrupted by pthread_cancel */ pthread_testcancel(); Pa_Sleep( intervalMsec ); pthread_testcancel(); if( PaUtil_GetTime() - th->callbackTime > maxSeconds ) { PA_DEBUG(( "Watchdog: Terminating callback thread\n" )); /* Tell thread to terminate */ err = pthread_kill( th->callbackThread, SIGKILL ); pthread_exit( NULL ); } PA_DEBUG(( "%s: PortAudio reports CPU load: %g\n", __FUNCTION__, PaUtil_GetCpuLoad( th->cpuLoadMeasurer ) )); /* Check if we should throttle, or unthrottle :P */ cpuTimeNow = th->callbackCpuTime; cpuTimeElapsed = cpuTimeNow - cpuTimeThen; cpuTimeThen = cpuTimeNow; timeNow = PaUtil_GetTime(); timeElapsed = timeNow - timeThen; timeThen = timeNow; cpuLoad = cpuTimeElapsed / timeElapsed; avgCpuLoad = avgCpuLoad * lowpassCoeff + cpuLoad * lowpassCoeff1; /* if( throttled ) PA_DEBUG(( "Watchdog: CPU load: %g, %g\n", avgCpuLoad, cpuTimeElapsed )); */ if( PaUtil_GetCpuLoad( th->cpuLoadMeasurer ) > .925 ) { static int policy; static struct sched_param spm = { 0 }; static const struct sched_param defaultSpm = { 0 }; PA_DEBUG(( "%s: Throttling audio thread, priority %d\n", __FUNCTION__, spm.sched_priority )); pthread_getschedparam( th->callbackThread, &policy, &spm ); if( !pthread_setschedparam( th->callbackThread, SCHED_OTHER, &defaultSpm ) ) { throttled = 1; } else PA_DEBUG(( "Watchdog: Couldn't lower priority of audio thread: %s\n", strerror( errno ) )); /* Give other processes a go, before raising priority again */ PA_DEBUG(( "%s: Watchdog sleeping for %lu msecs before unthrottling\n", __FUNCTION__, th->throttledSleepTime )); Pa_Sleep( th->throttledSleepTime ); /* Reset callback priority */ if( pthread_setschedparam( th->callbackThread, SCHED_FIFO, &spm ) != 0 ) { PA_DEBUG(( "%s: Couldn't raise priority of audio thread: %s\n", __FUNCTION__, strerror( errno ) )); } if( PaUtil_GetCpuLoad( th->cpuLoadMeasurer ) >= .99 ) intervalMsec = 50; else intervalMsec = 100; /* lowpassCoeff = .97; lowpassCoeff1 = .99999 - lowpassCoeff; */ } else if( throttled && avgCpuLoad < .8 ) { intervalMsec = 500; throttled = 0; /* lowpassCoeff = .9; lowpassCoeff1 = .99999 - lowpassCoeff; */ } } pthread_cleanup_pop( 1 ); /* Execute cleanup on exit */ error: /* Shouldn't get here in the normal case */ /* Pass on error code */ pres = malloc( sizeof (PaError) ); *pres = result; pthread_exit( pres ); } static void CallbackUpdate( PaAlsaThreading *th ) { th->callbackTime = PaUtil_GetTime(); th->callbackCpuTime = PaUtil_GetCpuLoad( th->cpuLoadMeasurer ); } /* static void *CanaryFunc( void *userData ) { const unsigned intervalMsec = 1000; PaUtilThreading *th = (PaUtilThreading *) userData; while( 1 ) { th->canaryTime = PaUtil_GetTime(); pthread_testcancel(); Pa_Sleep( intervalMsec ); } pthread_exit( NULL ); } */ #endif pd-0.46-7/portaudio/src/os/unix/pa_unix_util.h0000664000175000017500000001737012160204055017451 0ustar mspmsp/* * $Id: pa_unix_util.h 1241 2007-07-23 20:08:31Z aknudsen $ * Portable Audio I/O Library * UNIX platform-specific support functions * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2000 Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup unix_src */ #ifndef PA_UNIX_UTIL_H #define PA_UNIX_UTIL_H #include "pa_cpuload.h" #include #include #include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define PA_MIN(x,y) ( (x) < (y) ? (x) : (y) ) #define PA_MAX(x,y) ( (x) > (y) ? (x) : (y) ) /* Utilize GCC branch prediction for error tests */ #if defined __GNUC__ && __GNUC__ >= 3 #define UNLIKELY(expr) __builtin_expect( (expr), 0 ) #else #define UNLIKELY(expr) (expr) #endif #define STRINGIZE_HELPER(expr) #expr #define STRINGIZE(expr) STRINGIZE_HELPER(expr) #define PA_UNLESS(expr, code) \ do { \ if( UNLIKELY( (expr) == 0 ) ) \ { \ PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \ result = (code); \ goto error; \ } \ } while (0); static PaError paUtilErr_; /* Used with PA_ENSURE */ /* Check PaError */ #define PA_ENSURE(expr) \ do { \ if( UNLIKELY( (paUtilErr_ = (expr)) < paNoError ) ) \ { \ PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \ result = paUtilErr_; \ goto error; \ } \ } while (0); #define PA_ASSERT_CALL(expr, success) \ paUtilErr_ = (expr); \ assert( success == paUtilErr_ ); #define PA_ENSURE_SYSTEM(expr, success) \ do { \ if( UNLIKELY( (paUtilErr_ = (expr)) != success ) ) \ { \ /* PaUtil_SetLastHostErrorInfo should only be used in the main thread */ \ if( pthread_equal(pthread_self(), paUnixMainThread) ) \ { \ PaUtil_SetLastHostErrorInfo( paALSA, paUtilErr_, strerror( paUtilErr_ ) ); \ } \ PaUtil_DebugPrint( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" ); \ result = paUnanticipatedHostError; \ goto error; \ } \ } while( 0 ); typedef struct { pthread_t callbackThread; } PaUtilThreading; PaError PaUtil_InitializeThreading( PaUtilThreading *threading ); void PaUtil_TerminateThreading( PaUtilThreading *threading ); PaError PaUtil_StartThreading( PaUtilThreading *threading, void *(*threadRoutine)(void *), void *data ); PaError PaUtil_CancelThreading( PaUtilThreading *threading, int wait, PaError *exitResult ); /* State accessed by utility functions */ /* void PaUnix_SetRealtimeScheduling( int rt ); void PaUtil_InitializeThreading( PaUtilThreading *th, PaUtilCpuLoadMeasurer *clm ); PaError PaUtil_CreateCallbackThread( PaUtilThreading *th, void *(*CallbackThreadFunc)( void * ), PaStream *s ); PaError PaUtil_KillCallbackThread( PaUtilThreading *th, PaError *exitResult ); void PaUtil_CallbackUpdate( PaUtilThreading *th ); */ extern pthread_t paUnixMainThread; typedef struct { pthread_mutex_t mtx; } PaUnixMutex; PaError PaUnixMutex_Initialize( PaUnixMutex* self ); PaError PaUnixMutex_Terminate( PaUnixMutex* self ); PaError PaUnixMutex_Lock( PaUnixMutex* self ); PaError PaUnixMutex_Unlock( PaUnixMutex* self ); typedef struct { pthread_t thread; int parentWaiting; int stopRequested; int locked; PaUnixMutex mtx; pthread_cond_t cond; volatile sig_atomic_t stopRequest; } PaUnixThread; /** Initialize global threading state. */ PaError PaUnixThreading_Initialize(); /** Perish, passing on eventual error code. * * A thin wrapper around pthread_exit, will automatically pass on any error code to the joining thread. * If the result indicates an error, i.e. it is not equal to paNoError, this function will automatically * allocate a pointer so the error is passed on with pthread_exit. If the result indicates that all is * well however, only a NULL pointer will be handed to pthread_exit. Thus, the joining thread should * check whether a non-NULL result pointer is obtained from pthread_join and make sure to free it. * @param result: The error code to pass on to the joining thread. */ #define PaUnixThreading_EXIT(result) \ do { \ PaError* pres = NULL; \ if( paNoError != (result) ) \ { \ pres = malloc( sizeof (PaError) ); \ *pres = (result); \ } \ pthread_exit( pres ); \ } while (0); /** Spawn a thread. * * Intended for spawning the callback thread from the main thread. This function can even block (for a certain * time or indefinitely) untill notified by the callback thread (using PaUnixThread_NotifyParent), which can be * useful in order to make sure that callback has commenced before returning from Pa_StartStream. * @param threadFunc: The function to be executed in the child thread. * @param waitForChild: If not 0, wait for child thread to call PaUnixThread_NotifyParent. Less than 0 means * wait for ever, greater than 0 wait for the specified time. * @param rtSched: Enable realtime scheduling? * @return: If timed out waiting on child, paTimedOut. */ PaError PaUnixThread_New( PaUnixThread* self, void* (*threadFunc)( void* ), void* threadArg, PaTime waitForChild, int rtSched ); /** Terminate thread. * * @param wait: If true, request that background thread stop and wait untill it does, else cancel it. * @param exitResult: If non-null this will upon return contain the exit status of the thread. */ PaError PaUnixThread_Terminate( PaUnixThread* self, int wait, PaError* exitResult ); /** Prepare to notify waiting parent thread. * * An internal lock must be held before the parent is notified in PaUnixThread_NotifyParent, call this to * acquire it beforehand. * @return: If parent is not waiting, paInternalError. */ PaError PaUnixThread_PrepareNotify( PaUnixThread* self ); /** Notify waiting parent thread. * * @return: If parent timed out waiting, paTimedOut. If parent was never waiting, paInternalError. */ PaError PaUnixThread_NotifyParent( PaUnixThread* self ); /** Has the parent thread requested this thread to stop? */ int PaUnixThread_StopRequested( PaUnixThread* self ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif pd-0.46-7/portaudio/src/os/win/0000775000175000017500000000000012374245151014413 5ustar mspmsppd-0.46-7/portaudio/src/os/win/pa_win_waveformat.c0000664000175000017500000001442612374245151020276 0ustar mspmsp/* * PortAudio Portable Real-Time Audio Library * Windows WAVEFORMAT* data structure utilities * portaudio.h should be included before this file. * * Copyright (c) 2007 Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ #include #include #include "portaudio.h" #include "pa_win_waveformat.h" #if !defined(WAVE_FORMAT_EXTENSIBLE) #define WAVE_FORMAT_EXTENSIBLE 0xFFFE #endif static GUID pawin_ksDataFormatSubtypeGuidBase = { (USHORT)(WAVE_FORMAT_PCM), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }; int PaWin_SampleFormatToLinearWaveFormatTag( PaSampleFormat sampleFormat ) { if( sampleFormat == paFloat32 ) return PAWIN_WAVE_FORMAT_IEEE_FLOAT; return PAWIN_WAVE_FORMAT_PCM; } void PaWin_InitializeWaveFormatEx( PaWinWaveFormat *waveFormat, int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate ) { WAVEFORMATEX *waveFormatEx = (WAVEFORMATEX*)waveFormat; int bytesPerSample = Pa_GetSampleSize(sampleFormat); unsigned long bytesPerFrame = numChannels * bytesPerSample; waveFormatEx->wFormatTag = waveFormatTag; waveFormatEx->nChannels = (WORD)numChannels; waveFormatEx->nSamplesPerSec = (DWORD)sampleRate; waveFormatEx->nAvgBytesPerSec = waveFormatEx->nSamplesPerSec * bytesPerFrame; waveFormatEx->nBlockAlign = (WORD)bytesPerFrame; waveFormatEx->wBitsPerSample = bytesPerSample * 8; waveFormatEx->cbSize = 0; } void PaWin_InitializeWaveFormatExtensible( PaWinWaveFormat *waveFormat, int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate, PaWinWaveFormatChannelMask channelMask ) { WAVEFORMATEX *waveFormatEx = (WAVEFORMATEX*)waveFormat; int bytesPerSample = Pa_GetSampleSize(sampleFormat); unsigned long bytesPerFrame = numChannels * bytesPerSample; GUID guid; waveFormatEx->wFormatTag = WAVE_FORMAT_EXTENSIBLE; waveFormatEx->nChannels = (WORD)numChannels; waveFormatEx->nSamplesPerSec = (DWORD)sampleRate; waveFormatEx->nAvgBytesPerSec = waveFormatEx->nSamplesPerSec * bytesPerFrame; waveFormatEx->nBlockAlign = (WORD)bytesPerFrame; waveFormatEx->wBitsPerSample = bytesPerSample * 8; waveFormatEx->cbSize = 22; *((WORD*)&waveFormat->fields[PAWIN_INDEXOF_WVALIDBITSPERSAMPLE]) = waveFormatEx->wBitsPerSample; *((DWORD*)&waveFormat->fields[PAWIN_INDEXOF_DWCHANNELMASK]) = channelMask; guid = pawin_ksDataFormatSubtypeGuidBase; guid.Data1 = (USHORT)waveFormatTag; *((GUID*)&waveFormat->fields[PAWIN_INDEXOF_SUBFORMAT]) = guid; } PaWinWaveFormatChannelMask PaWin_DefaultChannelMask( int numChannels ) { switch( numChannels ){ case 1: return PAWIN_SPEAKER_MONO; case 2: return PAWIN_SPEAKER_STEREO; case 3: return PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_FRONT_RIGHT; case 4: return PAWIN_SPEAKER_QUAD; case 5: return PAWIN_SPEAKER_QUAD | PAWIN_SPEAKER_FRONT_CENTER; case 6: /* The meaning of the PAWIN_SPEAKER_5POINT1 flag has changed over time: http://msdn2.microsoft.com/en-us/library/aa474707.aspx We use PAWIN_SPEAKER_5POINT1 (not PAWIN_SPEAKER_5POINT1_SURROUND) because on some cards (eg Audigy) PAWIN_SPEAKER_5POINT1_SURROUND results in a virtual mixdown placing the rear output in the front _and_ rear speakers. */ return PAWIN_SPEAKER_5POINT1; /* case 7: */ case 8: /* RoBi: PAWIN_SPEAKER_7POINT1_SURROUND fits normal surround sound setups better than PAWIN_SPEAKER_7POINT1, f.i. NVidia HDMI Audio output is silent on channels 5&6 with NVidia drivers, and channel 7&8 with Micrsoft HD Audio driver using PAWIN_SPEAKER_7POINT1. With PAWIN_SPEAKER_7POINT1_SURROUND both setups work OK. */ return PAWIN_SPEAKER_7POINT1_SURROUND; } /* Apparently some Audigy drivers will output silence if the direct-out constant (0) is used. So this is not ideal. RoBi 2012-12-19: Also, NVidia driver seem to output garbage instead. Again not very ideal. */ return PAWIN_SPEAKER_DIRECTOUT; /* Note that Alec Rogers proposed the following as an alternate method to generate the default channel mask, however it doesn't seem to be an improvement over the above, since some drivers will matrix outputs mapping to non-present speakers accross multiple physical speakers. if(nChannels==1) { pwfFormat->dwChannelMask = SPEAKER_FRONT_CENTER; } else { pwfFormat->dwChannelMask = 0; for(i=0; idwChannelMask = (pwfFormat->dwChannelMask << 1) | 0x1; } */ } pd-0.46-7/portaudio/src/os/win/pa_win_coinitialize.h0000664000175000017500000000677612222201037020607 0ustar mspmsp/* * Microsoft COM initialization routines * Copyright (c) 1999-2011 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup win_src @brief Microsoft COM initialization routines. */ #ifndef PA_WIN_COINITIALIZE_H #define PA_WIN_COINITIALIZE_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** @brief Data type used to hold the result of an attempt to initialize COM using PaWinUtil_CoInitialize. Must be retained between a call to PaWinUtil_CoInitialize and a matching call to PaWinUtil_CoUninitialize. */ typedef struct PaWinUtilComInitializationResult{ int state; int initializingThreadId; } PaWinUtilComInitializationResult; /** @brief Initialize Microsoft COM subsystem on the current thread. @param hostApiType the host API type id of the caller. Used for error reporting. @param comInitializationResult An output parameter. The value pointed to by this parameter stores information required by PaWinUtil_CoUninitialize to correctly uninitialize COM. The value should be retained and later passed to PaWinUtil_CoUninitialize. If PaWinUtil_CoInitialize returns paNoError, the caller must later call PaWinUtil_CoUninitialize once. */ PaError PaWinUtil_CoInitialize( PaHostApiTypeId hostApiType, PaWinUtilComInitializationResult *comInitializationResult ); /** @brief Uninitialize the Microsoft COM subsystem on the current thread using the result of a previous call to PaWinUtil_CoInitialize. Must be called on the same thread as PaWinUtil_CoInitialize. @param hostApiType the host API type id of the caller. Used for error reporting. @param comInitializationResult An input parameter. A pointer to a value previously initialized by a call to PaWinUtil_CoInitialize. */ void PaWinUtil_CoUninitialize( PaHostApiTypeId hostApiType, PaWinUtilComInitializationResult *comInitializationResult ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_WIN_COINITIALIZE_H */ pd-0.46-7/portaudio/src/os/win/pa_win_coinitialize.c0000664000175000017500000001206112222201037020562 0ustar mspmsp/* * Microsoft COM initialization routines * Copyright (c) 1999-2011 Ross Bencina, Dmitry Kostjuchenko * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2011 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup win_src @brief Microsoft COM initialization routines. */ #include #include #include "portaudio.h" #include "pa_util.h" #include "pa_debugprint.h" #include "pa_win_coinitialize.h" #if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) && !defined(_WIN32_WCE) /* MSC version 6 and above */ #pragma comment( lib, "ole32.lib" ) #endif /* use some special bit patterns here to try to guard against uninitialized memory errors */ #define PAWINUTIL_COM_INITIALIZED (0xb38f) #define PAWINUTIL_COM_NOT_INITIALIZED (0xf1cd) PaError PaWinUtil_CoInitialize( PaHostApiTypeId hostApiType, PaWinUtilComInitializationResult *comInitializationResult ) { HRESULT hr; comInitializationResult->state = PAWINUTIL_COM_NOT_INITIALIZED; /* If COM is already initialized CoInitialize will either return FALSE, or RPC_E_CHANGED_MODE if it was initialised in a different threading mode. In either case we shouldn't consider it an error but we need to be careful to not call CoUninitialize() if RPC_E_CHANGED_MODE was returned. */ hr = CoInitialize(0); /* use legacy-safe equivalent to CoInitializeEx(NULL, COINIT_APARTMENTTHREADED) */ if( FAILED(hr) && hr != RPC_E_CHANGED_MODE ) { PA_DEBUG(("CoInitialize(0) failed. hr=%d\n", hr)); if( hr == E_OUTOFMEMORY ) return paInsufficientMemory; { char *lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); PaUtil_SetLastHostErrorInfo( hostApiType, hr, lpMsgBuf ); LocalFree( lpMsgBuf ); } return paUnanticipatedHostError; } if( hr != RPC_E_CHANGED_MODE ) { comInitializationResult->state = PAWINUTIL_COM_INITIALIZED; /* Memorize calling thread id and report warning on Uninitialize if calling thread is different as CoInitialize must match CoUninitialize in the same thread. */ comInitializationResult->initializingThreadId = GetCurrentThreadId(); } return paNoError; } void PaWinUtil_CoUninitialize( PaHostApiTypeId hostApiType, PaWinUtilComInitializationResult *comInitializationResult ) { if( comInitializationResult->state != PAWINUTIL_COM_NOT_INITIALIZED && comInitializationResult->state != PAWINUTIL_COM_INITIALIZED ){ PA_DEBUG(("ERROR: PaWinUtil_CoUninitialize called without calling PaWinUtil_CoInitialize\n")); } if( comInitializationResult->state == PAWINUTIL_COM_INITIALIZED ) { DWORD currentThreadId = GetCurrentThreadId(); if( comInitializationResult->initializingThreadId != currentThreadId ) { PA_DEBUG(("ERROR: failed PaWinUtil_CoUninitialize calling thread[%d] does not match initializing thread[%d]\n", currentThreadId, comInitializationResult->initializingThreadId)); } else { CoUninitialize(); comInitializationResult->state = PAWINUTIL_COM_NOT_INITIALIZED; } } }pd-0.46-7/portaudio/src/os/win/pa_win_hostapis.c0000664000175000017500000000627012222201037017736 0ustar mspmsp/* * $Id: pa_win_hostapis.c 1728 2011-08-18 03:31:51Z rossb $ * Portable Audio I/O Library Windows initialization table * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2008 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup win_src @brief Win32 host API initialization function table. */ /* This is needed to make this source file depend on CMake option changes and at the same time make it transparent for clients not using CMake. */ #ifdef PORTAUDIO_CMAKE_GENERATED #include "options_cmake.h" #endif #include "pa_hostapi.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaWinDs_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaWinWdm_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); #ifdef __cplusplus } #endif /* __cplusplus */ PaUtilHostApiInitializer *paHostApiInitializers[] = { #if PA_USE_WMME PaWinMme_Initialize, #endif #if PA_USE_DS PaWinDs_Initialize, #endif #if PA_USE_ASIO PaAsio_Initialize, #endif #if PA_USE_WASAPI PaWasapi_Initialize, #endif #if PA_USE_WDMKS PaWinWdm_Initialize, #endif #if PA_USE_SKELETON PaSkeleton_Initialize, /* just for testing. last in list so it isn't marked as default. */ #endif 0 /* NULL terminated array */ }; pd-0.46-7/portaudio/src/os/win/pa_x86_plain_converters.h0000664000175000017500000000415512222201037021316 0ustar mspmsp/* * Plain Intel IA32 assembly implementations of PortAudio sample converter functions. * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup win_src */ #ifndef PA_X86_PLAIN_CONVERTERS_H #define PA_X86_PLAIN_CONVERTERS_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** @brief Install optimized converter functions suitable for all IA32 processors It is recommended to call PaUtil_InitializeX86PlainConverters prior to calling Pa_Initialize */ void PaUtil_InitializeX86PlainConverters( void ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_X86_PLAIN_CONVERTERS_H */ pd-0.46-7/portaudio/src/os/win/pa_win_util.c0000664000175000017500000000777112222201037017070 0ustar mspmsp/* * $Id: pa_win_util.c 1584 2011-02-02 18:58:17Z rossb $ * Portable Audio I/O Library * Win32 platform-specific support functions * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2008 Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup win_src @brief Win32 implementation of platform-specific PaUtil support functions. */ #include #include /* for timeGetTime() */ #include "pa_util.h" #if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) && !defined(_WIN32_WCE) /* MSC version 6 and above */ #pragma comment( lib, "winmm.lib" ) #endif /* Track memory allocations to avoid leaks. */ #if PA_TRACK_MEMORY static int numAllocations_ = 0; #endif void *PaUtil_AllocateMemory( long size ) { void *result = GlobalAlloc( GPTR, size ); #if PA_TRACK_MEMORY if( result != NULL ) numAllocations_ += 1; #endif return result; } void PaUtil_FreeMemory( void *block ) { if( block != NULL ) { GlobalFree( block ); #if PA_TRACK_MEMORY numAllocations_ -= 1; #endif } } int PaUtil_CountCurrentlyAllocatedBlocks( void ) { #if PA_TRACK_MEMORY return numAllocations_; #else return 0; #endif } void Pa_Sleep( long msec ) { Sleep( msec ); } static int usePerformanceCounter_; static double secondsPerTick_; void PaUtil_InitializeClock( void ) { LARGE_INTEGER ticksPerSecond; if( QueryPerformanceFrequency( &ticksPerSecond ) != 0 ) { usePerformanceCounter_ = 1; secondsPerTick_ = 1.0 / (double)ticksPerSecond.QuadPart; } else { usePerformanceCounter_ = 0; } } double PaUtil_GetTime( void ) { LARGE_INTEGER time; if( usePerformanceCounter_ ) { /* Note: QueryPerformanceCounter has a known issue where it can skip forward by a few seconds (!) due to a hardware bug on some PCI-ISA bridge hardware. This is documented here: http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q274323& The work-arounds are not very paletable and involve querying GetTickCount at every time step. Using rdtsc is not a good option on multi-core systems. For now we just use QueryPerformanceCounter(). It's good, most of the time. */ QueryPerformanceCounter( &time ); return time.QuadPart * secondsPerTick_; } else { #ifndef UNDER_CE return timeGetTime() * .001; #else return GetTickCount() * .001; #endif } } pd-0.46-7/portaudio/src/os/win/pa_win_wdmks_utils.h0000664000175000017500000000470512160204055020463 0ustar mspmsp#ifndef PA_WIN_WDMKS_UTILS_H #define PA_WIN_WDMKS_UTILS_H /* * PortAudio Portable Real-Time Audio Library * Windows WDM KS utilities * * Copyright (c) 1999 - 2007 Ross Bencina, Andrew Baldwin * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @brief Utilities for working with the Windows WDM KS API */ #ifdef __cplusplus extern "C" { #endif /** Query for the maximum number of channels supported by any pin of the specified device. Returns 0 if the query fails for any reason. @param wcharDevicePath A system level PnP interface path, supplied as a WCHAR unicode string. Declard as void* to avoid introducing a dependency on wchar_t here. @param isInput A flag specifying whether to query for input (non-zero) or output (zero) channels. */ int PaWin_WDMKS_QueryFilterMaximumChannelCount( void *wcharDevicePath, int isInput ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_WIN_WDMKS_UTILS_H */pd-0.46-7/portaudio/src/os/win/pa_win_wdmks_utils.c0000664000175000017500000003020612222201037020445 0ustar mspmsp/* * PortAudio Portable Real-Time Audio Library * Windows WDM KS utilities * * Copyright (c) 1999 - 2007 Andrew Baldwin, Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ #include #include #ifndef WAVE_FORMAT_IEEE_FLOAT #define WAVE_FORMAT_IEEE_FLOAT 0x0003 // MinGW32 does not define this #endif #ifndef _WAVEFORMATEXTENSIBLE_ #define _WAVEFORMATEXTENSIBLE_ // MinGW32 does not define this #endif #ifndef _INC_MMREG #define _INC_MMREG // for STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT #endif #include // MinGW32 does not define this automatically #if defined(__GNUC__) #include "../../hostapi/wasapi/mingw-include/ks.h" #include "../../hostapi/wasapi/mingw-include/ksmedia.h" #else #include #include #endif #include // just for some development printfs #include "portaudio.h" #include "pa_util.h" #include "pa_win_wdmks_utils.h" #if !defined(PA_WDMKS_NO_KSGUID_LIB) && !defined(PAWIN_WDMKS_NO_KSGUID_LIB) && !defined(__GNUC__) #if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) /* MSC version 6 and above */ #pragma comment( lib, "ksguid.lib" ) #endif #define pa_KSDATAFORMAT_TYPE_AUDIO KSDATAFORMAT_TYPE_AUDIO #define pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT KSDATAFORMAT_SUBTYPE_IEEE_FLOAT #define pa_KSDATAFORMAT_SUBTYPE_PCM KSDATAFORMAT_SUBTYPE_PCM #define pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX KSDATAFORMAT_SUBTYPE_WAVEFORMATEX #define pa_KSMEDIUMSETID_Standard KSMEDIUMSETID_Standard #define pa_KSINTERFACESETID_Standard KSINTERFACESETID_Standard #define pa_KSPROPSETID_Pin KSPROPSETID_Pin #else static const GUID pa_KSDATAFORMAT_TYPE_AUDIO = { STATIC_KSDATAFORMAT_TYPE_AUDIO }; static const GUID pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT }; static const GUID pa_KSDATAFORMAT_SUBTYPE_PCM = { STATIC_KSDATAFORMAT_SUBTYPE_PCM }; static const GUID pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX = { STATIC_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX }; static const GUID pa_KSMEDIUMSETID_Standard = { STATIC_KSMEDIUMSETID_Standard }; static const GUID pa_KSINTERFACESETID_Standard = { STATIC_KSINTERFACESETID_Standard }; static const GUID pa_KSPROPSETID_Pin = { STATIC_KSPROPSETID_Pin }; #endif #define pa_IS_VALID_WAVEFORMATEX_GUID(Guid)\ (!memcmp(((PUSHORT)&pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX) + 1, ((PUSHORT)(Guid)) + 1, sizeof(GUID) - sizeof(USHORT))) static PaError WdmGetPinPropertySimple( HANDLE handle, unsigned long pinId, unsigned long property, void* value, unsigned long valueSize ) { DWORD bytesReturned; KSP_PIN ksPProp; ksPProp.Property.Set = pa_KSPROPSETID_Pin; ksPProp.Property.Id = property; ksPProp.Property.Flags = KSPROPERTY_TYPE_GET; ksPProp.PinId = pinId; ksPProp.Reserved = 0; if( DeviceIoControl( handle, IOCTL_KS_PROPERTY, &ksPProp, sizeof(KSP_PIN), value, valueSize, &bytesReturned, NULL ) == 0 || bytesReturned != valueSize ) { return paUnanticipatedHostError; } else { return paNoError; } } static PaError WdmGetPinPropertyMulti( HANDLE handle, unsigned long pinId, unsigned long property, KSMULTIPLE_ITEM** ksMultipleItem) { unsigned long multipleItemSize = 0; KSP_PIN ksPProp; DWORD bytesReturned; *ksMultipleItem = 0; ksPProp.Property.Set = pa_KSPROPSETID_Pin; ksPProp.Property.Id = property; ksPProp.Property.Flags = KSPROPERTY_TYPE_GET; ksPProp.PinId = pinId; ksPProp.Reserved = 0; if( DeviceIoControl( handle, IOCTL_KS_PROPERTY, &ksPProp.Property, sizeof(KSP_PIN), NULL, 0, &multipleItemSize, NULL ) == 0 && GetLastError() != ERROR_MORE_DATA ) { return paUnanticipatedHostError; } *ksMultipleItem = (KSMULTIPLE_ITEM*)PaUtil_AllocateMemory( multipleItemSize ); if( !*ksMultipleItem ) { return paInsufficientMemory; } if( DeviceIoControl( handle, IOCTL_KS_PROPERTY, &ksPProp, sizeof(KSP_PIN), (void*)*ksMultipleItem, multipleItemSize, &bytesReturned, NULL ) == 0 || bytesReturned != multipleItemSize ) { PaUtil_FreeMemory( ksMultipleItem ); return paUnanticipatedHostError; } return paNoError; } static int GetKSFilterPinCount( HANDLE deviceHandle ) { DWORD result; if( WdmGetPinPropertySimple( deviceHandle, 0, KSPROPERTY_PIN_CTYPES, &result, sizeof(result) ) == paNoError ){ return result; }else{ return 0; } } static KSPIN_COMMUNICATION GetKSFilterPinPropertyCommunication( HANDLE deviceHandle, int pinId ) { KSPIN_COMMUNICATION result; if( WdmGetPinPropertySimple( deviceHandle, pinId, KSPROPERTY_PIN_COMMUNICATION, &result, sizeof(result) ) == paNoError ){ return result; }else{ return KSPIN_COMMUNICATION_NONE; } } static KSPIN_DATAFLOW GetKSFilterPinPropertyDataflow( HANDLE deviceHandle, int pinId ) { KSPIN_DATAFLOW result; if( WdmGetPinPropertySimple( deviceHandle, pinId, KSPROPERTY_PIN_DATAFLOW, &result, sizeof(result) ) == paNoError ){ return result; }else{ return (KSPIN_DATAFLOW)0; } } static int KSFilterPinPropertyIdentifiersInclude( HANDLE deviceHandle, int pinId, unsigned long property, const GUID *identifierSet, unsigned long identifierId ) { KSMULTIPLE_ITEM* item = NULL; KSIDENTIFIER* identifier; int i; int result = 0; if( WdmGetPinPropertyMulti( deviceHandle, pinId, property, &item) != paNoError ) return 0; identifier = (KSIDENTIFIER*)(item+1); for( i = 0; i < (int)item->Count; i++ ) { if( !memcmp( (void*)&identifier[i].Set, (void*)identifierSet, sizeof( GUID ) ) && ( identifier[i].Id == identifierId ) ) { result = 1; break; } } PaUtil_FreeMemory( item ); return result; } /* return the maximum channel count supported by any pin on the device. if isInput is non-zero we query input pins, otherwise output pins. */ int PaWin_WDMKS_QueryFilterMaximumChannelCount( void *wcharDevicePath, int isInput ) { HANDLE deviceHandle; ULONG i; int pinCount, pinId; int result = 0; KSPIN_DATAFLOW requiredDataflowDirection = (isInput ? KSPIN_DATAFLOW_OUT : KSPIN_DATAFLOW_IN ); if( !wcharDevicePath ) return 0; deviceHandle = CreateFileW( (LPCWSTR)wcharDevicePath, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL ); if( deviceHandle == INVALID_HANDLE_VALUE ) return 0; pinCount = GetKSFilterPinCount( deviceHandle ); for( pinId = 0; pinId < pinCount; ++pinId ) { KSPIN_COMMUNICATION communication = GetKSFilterPinPropertyCommunication( deviceHandle, pinId ); KSPIN_DATAFLOW dataflow = GetKSFilterPinPropertyDataflow( deviceHandle, pinId ); if( ( dataflow == requiredDataflowDirection ) && (( communication == KSPIN_COMMUNICATION_SINK) || ( communication == KSPIN_COMMUNICATION_BOTH)) && ( KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId, KSPROPERTY_PIN_INTERFACES, &pa_KSINTERFACESETID_Standard, KSINTERFACE_STANDARD_STREAMING ) || KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId, KSPROPERTY_PIN_INTERFACES, &pa_KSINTERFACESETID_Standard, KSINTERFACE_STANDARD_LOOPED_STREAMING ) ) && KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId, KSPROPERTY_PIN_MEDIUMS, &pa_KSMEDIUMSETID_Standard, KSMEDIUM_STANDARD_DEVIO ) ) { KSMULTIPLE_ITEM* item = NULL; if( WdmGetPinPropertyMulti( deviceHandle, pinId, KSPROPERTY_PIN_DATARANGES, &item ) == paNoError ) { KSDATARANGE *dataRange = (KSDATARANGE*)(item+1); for( i=0; i < item->Count; ++i ){ if( pa_IS_VALID_WAVEFORMATEX_GUID(&dataRange->SubFormat) || memcmp( (void*)&dataRange->SubFormat, (void*)&pa_KSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID) ) == 0 || memcmp( (void*)&dataRange->SubFormat, (void*)&pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, sizeof(GUID) ) == 0 || ( ( memcmp( (void*)&dataRange->MajorFormat, (void*)&pa_KSDATAFORMAT_TYPE_AUDIO, sizeof(GUID) ) == 0 ) && ( memcmp( (void*)&dataRange->SubFormat, (void*)&KSDATAFORMAT_SUBTYPE_WILDCARD, sizeof(GUID) ) == 0 ) ) ) { KSDATARANGE_AUDIO *dataRangeAudio = (KSDATARANGE_AUDIO*)dataRange; /* printf( ">>> %d %d %d %d %S\n", isInput, dataflow, communication, dataRangeAudio->MaximumChannels, devicePath ); if( memcmp((void*)&dataRange->Specifier, (void*)&KSDATAFORMAT_SPECIFIER_WAVEFORMATEX, sizeof(GUID) ) == 0 ) printf( "\tspecifier: KSDATAFORMAT_SPECIFIER_WAVEFORMATEX\n" ); else if( memcmp((void*)&dataRange->Specifier, (void*)&KSDATAFORMAT_SPECIFIER_DSOUND, sizeof(GUID) ) == 0 ) printf( "\tspecifier: KSDATAFORMAT_SPECIFIER_DSOUND\n" ); else if( memcmp((void*)&dataRange->Specifier, (void*)&KSDATAFORMAT_SPECIFIER_WILDCARD, sizeof(GUID) ) == 0 ) printf( "\tspecifier: KSDATAFORMAT_SPECIFIER_WILDCARD\n" ); else printf( "\tspecifier: ?\n" ); */ /* We assume that very high values for MaximumChannels are not useful and indicate that the driver isn't prepared to tell us the real number of channels which it supports. */ if( dataRangeAudio->MaximumChannels < 0xFFFFUL && (int)dataRangeAudio->MaximumChannels > result ) result = (int)dataRangeAudio->MaximumChannels; } dataRange = (KSDATARANGE*)( ((char*)dataRange) + dataRange->FormatSize); } PaUtil_FreeMemory( item ); } } } CloseHandle( deviceHandle ); return result; } pd-0.46-7/portaudio/src/os/win/pa_x86_plain_converters.c0000664000175000017500000011621712374245151021331 0ustar mspmsp/* * Plain Intel IA32 assembly implementations of PortAudio sample converter functions. * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup win_src */ #include "pa_x86_plain_converters.h" #include "pa_converters.h" #include "pa_dither.h" /* the main reason these versions are faster than the equivalent C versions is that float -> int casting is expensive in C on x86 because the rounding mode needs to be changed for every cast. these versions only set the rounding mode once outside the loop. small additional speed gains are made by the way that clamping is implemented. TODO: o- inline dither code o- implement Dither only (no-clip) versions o- implement int8 and uint8 versions o- test thouroughly o- the packed 24 bit functions could benefit from unrolling and avoiding byte and word sized register access. */ /* -------------------------------------------------------------------------- */ /* #define PA_CLIP_( val, min, max )\ { val = ((val) < (min)) ? (min) : (((val) > (max)) ? (max) : (val)); } */ /* the following notes were used to determine whether a floating point value should be saturated (ie >1 or <-1) by loading it into an integer register. these should be rewritten so that they make sense. an ieee floating point value 1.xxxxxxxxxxxxxxxxxxxx? is less than or equal to 1 and greater than or equal to -1 either: if the mantissa is 0 and the unbiased exponent is 0 OR if the unbiased exponent < 0 this translates to: if the mantissa is 0 and the biased exponent is 7F or if the biased exponent is less than 7F therefore the value is greater than 1 or less than -1 if the mantissa is not 0 and the biased exponent is 7F or if the biased exponent is greater than 7F in other words, if we mask out the sign bit, the value is greater than 1 or less than -1 if its integer representation is greater than: 0 01111111 0000 0000 0000 0000 0000 000 0011 1111 1000 0000 0000 0000 0000 0000 => 0x3F800000 */ #if defined(_WIN64) || defined(_WIN32_WCE) /* -EMT64/AMD64 uses different asm -VC2005 doesnt allow _WIN64 with inline assembly either! */ void PaUtil_InitializeX86PlainConverters( void ) { } #else /* -------------------------------------------------------------------------- */ static const short fpuControlWord_ = 0x033F; /*round to nearest, 64 bit precision, all exceptions masked*/ static const double int32Scaler_ = 0x7FFFFFFF; static const double ditheredInt32Scaler_ = 0x7FFFFFFE; static const double int24Scaler_ = 0x7FFFFF; static const double ditheredInt24Scaler_ = 0x7FFFFE; static const double int16Scaler_ = 0x7FFF; static const double ditheredInt16Scaler_ = 0x7FFE; #define PA_DITHER_BITS_ (15) /* Multiply by PA_FLOAT_DITHER_SCALE_ to get a float between -2.0 and +1.99999 */ #define PA_FLOAT_DITHER_SCALE_ (1.0F / ((1< source ptr // eax -> source byte stride // edi -> destination ptr // ebx -> destination byte stride // ecx -> source end ptr // edx -> temp mov esi, sourceBuffer mov edx, 4 // sizeof float32 and int32 mov eax, sourceStride imul eax, edx mov ecx, count imul ecx, eax add ecx, esi mov edi, destinationBuffer mov ebx, destinationStride imul ebx, edx fwait fstcw savedFpuControlWord fldcw fpuControlWord_ fld int32Scaler_ // stack: (int)0x7FFFFFFF Float32_To_Int32_loop: // load unscaled value into st(0) fld dword ptr [esi] // stack: value, (int)0x7FFFFFFF add esi, eax // increment source ptr //lea esi, [esi+eax] fmul st(0), st(1) // st(0) *= st(1), stack: value*0x7FFFFFFF, (int)0x7FFFFFFF /* note: we could store to a temporary qword here which would cause wraparound distortion instead of int indefinite 0x10. that would be more work, and given that not enabling clipping is only advisable when you know that your signal isn't going to clip it isn't worth it. */ fistp dword ptr [edi] // pop st(0) into dest, stack: (int)0x7FFFFFFF add edi, ebx // increment destination ptr //lea edi, [edi+ebx] cmp esi, ecx // has src ptr reached end? jne Float32_To_Int32_loop ffree st(0) fincstp fwait fnclex fldcw savedFpuControlWord } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int32_Clip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator ) { /* float *src = (float*)sourceBuffer; signed long *dest = (signed long*)destinationBuffer; (void) ditherGenerator; // unused parameter while( count-- ) { // REVIEW double scaled = *src * 0x7FFFFFFF; PA_CLIP_( scaled, -2147483648., 2147483647. ); *dest = (signed long) scaled; src += sourceStride; dest += destinationStride; } */ short savedFpuControlWord; (void) ditherGenerator; /* unused parameter */ __asm{ // esi -> source ptr // eax -> source byte stride // edi -> destination ptr // ebx -> destination byte stride // ecx -> source end ptr // edx -> temp mov esi, sourceBuffer mov edx, 4 // sizeof float32 and int32 mov eax, sourceStride imul eax, edx mov ecx, count imul ecx, eax add ecx, esi mov edi, destinationBuffer mov ebx, destinationStride imul ebx, edx fwait fstcw savedFpuControlWord fldcw fpuControlWord_ fld int32Scaler_ // stack: (int)0x7FFFFFFF Float32_To_Int32_Clip_loop: mov edx, dword ptr [esi] // load floating point value into integer register and edx, 0x7FFFFFFF // mask off sign cmp edx, 0x3F800000 // greater than 1.0 or less than -1.0 jg Float32_To_Int32_Clip_clamp // load unscaled value into st(0) fld dword ptr [esi] // stack: value, (int)0x7FFFFFFF add esi, eax // increment source ptr //lea esi, [esi+eax] fmul st(0), st(1) // st(0) *= st(1), stack: value*0x7FFFFFFF, (int)0x7FFFFFFF fistp dword ptr [edi] // pop st(0) into dest, stack: (int)0x7FFFFFFF jmp Float32_To_Int32_Clip_stored Float32_To_Int32_Clip_clamp: mov edx, dword ptr [esi] // load floating point value into integer register shr edx, 31 // move sign bit into bit 0 add esi, eax // increment source ptr //lea esi, [esi+eax] add edx, 0x7FFFFFFF // convert to maximum range integers mov dword ptr [edi], edx Float32_To_Int32_Clip_stored: //add edi, ebx // increment destination ptr lea edi, [edi+ebx] cmp esi, ecx // has src ptr reached end? jne Float32_To_Int32_Clip_loop ffree st(0) fincstp fwait fnclex fldcw savedFpuControlWord } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int32_DitherClip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator ) { /* float *src = (float*)sourceBuffer; signed long *dest = (signed long*)destinationBuffer; while( count-- ) { // REVIEW double dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); // use smaller scaler to prevent overflow when we add the dither double dithered = ((double)*src * (2147483646.0)) + dither; PA_CLIP_( dithered, -2147483648., 2147483647. ); *dest = (signed long) dithered; src += sourceStride; dest += destinationStride; } */ short savedFpuControlWord; // spill storage: signed long sourceByteStride; signed long highpassedDither; // dither state: unsigned long ditherPrevious = ditherGenerator->previous; unsigned long ditherRandSeed1 = ditherGenerator->randSeed1; unsigned long ditherRandSeed2 = ditherGenerator->randSeed2; __asm{ // esi -> source ptr // eax -> source byte stride // edi -> destination ptr // ebx -> destination byte stride // ecx -> source end ptr // edx -> temp mov esi, sourceBuffer mov edx, 4 // sizeof float32 and int32 mov eax, sourceStride imul eax, edx mov ecx, count imul ecx, eax add ecx, esi mov edi, destinationBuffer mov ebx, destinationStride imul ebx, edx fwait fstcw savedFpuControlWord fldcw fpuControlWord_ fld ditheredInt32Scaler_ // stack: int scaler Float32_To_Int32_DitherClip_loop: mov edx, dword ptr [esi] // load floating point value into integer register and edx, 0x7FFFFFFF // mask off sign cmp edx, 0x3F800000 // greater than 1.0 or less than -1.0 jg Float32_To_Int32_DitherClip_clamp // load unscaled value into st(0) fld dword ptr [esi] // stack: value, int scaler add esi, eax // increment source ptr //lea esi, [esi+eax] fmul st(0), st(1) // st(0) *= st(1), stack: value*(int scaler), int scaler /* // call PaUtil_GenerateFloatTriangularDither with C calling convention mov sourceByteStride, eax // save eax mov sourceEnd, ecx // save ecx push ditherGenerator // pass ditherGenerator parameter on stack call PaUtil_GenerateFloatTriangularDither // stack: dither, value*(int scaler), int scaler pop edx // clear parameter off stack mov ecx, sourceEnd // restore ecx mov eax, sourceByteStride // restore eax */ // generate dither mov sourceByteStride, eax // save eax mov edx, 196314165 mov eax, ditherRandSeed1 mul edx // eax:edx = eax * 196314165 //add eax, 907633515 lea eax, [eax+907633515] mov ditherRandSeed1, eax mov edx, 196314165 mov eax, ditherRandSeed2 mul edx // eax:edx = eax * 196314165 //add eax, 907633515 lea eax, [eax+907633515] mov edx, ditherRandSeed1 shr edx, PA_DITHER_SHIFT_ mov ditherRandSeed2, eax shr eax, PA_DITHER_SHIFT_ //add eax, edx // eax -> current lea eax, [eax+edx] mov edx, ditherPrevious neg edx lea edx, [eax+edx] // highpass = current - previous mov highpassedDither, edx mov ditherPrevious, eax // previous = current mov eax, sourceByteStride // restore eax fild highpassedDither fmul const_float_dither_scale_ // end generate dither, dither signal in st(0) faddp st(1), st(0) // stack: dither + value*(int scaler), int scaler fistp dword ptr [edi] // pop st(0) into dest, stack: int scaler jmp Float32_To_Int32_DitherClip_stored Float32_To_Int32_DitherClip_clamp: mov edx, dword ptr [esi] // load floating point value into integer register shr edx, 31 // move sign bit into bit 0 add esi, eax // increment source ptr //lea esi, [esi+eax] add edx, 0x7FFFFFFF // convert to maximum range integers mov dword ptr [edi], edx Float32_To_Int32_DitherClip_stored: //add edi, ebx // increment destination ptr lea edi, [edi+ebx] cmp esi, ecx // has src ptr reached end? jne Float32_To_Int32_DitherClip_loop ffree st(0) fincstp fwait fnclex fldcw savedFpuControlWord } ditherGenerator->previous = ditherPrevious; ditherGenerator->randSeed1 = ditherRandSeed1; ditherGenerator->randSeed2 = ditherRandSeed2; } /* -------------------------------------------------------------------------- */ static void Float32_To_Int24( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator ) { /* float *src = (float*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; signed long temp; (void) ditherGenerator; // unused parameter while( count-- ) { // convert to 32 bit and drop the low 8 bits double scaled = *src * 0x7FFFFFFF; temp = (signed long) scaled; dest[0] = (unsigned char)(temp >> 8); dest[1] = (unsigned char)(temp >> 16); dest[2] = (unsigned char)(temp >> 24); src += sourceStride; dest += destinationStride * 3; } */ short savedFpuControlWord; signed long tempInt32; (void) ditherGenerator; /* unused parameter */ __asm{ // esi -> source ptr // eax -> source byte stride // edi -> destination ptr // ebx -> destination byte stride // ecx -> source end ptr // edx -> temp mov esi, sourceBuffer mov edx, 4 // sizeof float32 mov eax, sourceStride imul eax, edx mov ecx, count imul ecx, eax add ecx, esi mov edi, destinationBuffer mov edx, 3 // sizeof int24 mov ebx, destinationStride imul ebx, edx fwait fstcw savedFpuControlWord fldcw fpuControlWord_ fld int24Scaler_ // stack: (int)0x7FFFFF Float32_To_Int24_loop: // load unscaled value into st(0) fld dword ptr [esi] // stack: value, (int)0x7FFFFF add esi, eax // increment source ptr //lea esi, [esi+eax] fmul st(0), st(1) // st(0) *= st(1), stack: value*0x7FFFFF, (int)0x7FFFFF fistp tempInt32 // pop st(0) into tempInt32, stack: (int)0x7FFFFF mov edx, tempInt32 mov byte ptr [edi], DL shr edx, 8 //mov byte ptr [edi+1], DL //mov byte ptr [edi+2], DH mov word ptr [edi+1], DX //add edi, ebx // increment destination ptr lea edi, [edi+ebx] cmp esi, ecx // has src ptr reached end? jne Float32_To_Int24_loop ffree st(0) fincstp fwait fnclex fldcw savedFpuControlWord } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int24_Clip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator ) { /* float *src = (float*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; signed long temp; (void) ditherGenerator; // unused parameter while( count-- ) { // convert to 32 bit and drop the low 8 bits double scaled = *src * 0x7FFFFFFF; PA_CLIP_( scaled, -2147483648., 2147483647. ); temp = (signed long) scaled; dest[0] = (unsigned char)(temp >> 8); dest[1] = (unsigned char)(temp >> 16); dest[2] = (unsigned char)(temp >> 24); src += sourceStride; dest += destinationStride * 3; } */ short savedFpuControlWord; signed long tempInt32; (void) ditherGenerator; /* unused parameter */ __asm{ // esi -> source ptr // eax -> source byte stride // edi -> destination ptr // ebx -> destination byte stride // ecx -> source end ptr // edx -> temp mov esi, sourceBuffer mov edx, 4 // sizeof float32 mov eax, sourceStride imul eax, edx mov ecx, count imul ecx, eax add ecx, esi mov edi, destinationBuffer mov edx, 3 // sizeof int24 mov ebx, destinationStride imul ebx, edx fwait fstcw savedFpuControlWord fldcw fpuControlWord_ fld int24Scaler_ // stack: (int)0x7FFFFF Float32_To_Int24_Clip_loop: mov edx, dword ptr [esi] // load floating point value into integer register and edx, 0x7FFFFFFF // mask off sign cmp edx, 0x3F800000 // greater than 1.0 or less than -1.0 jg Float32_To_Int24_Clip_clamp // load unscaled value into st(0) fld dword ptr [esi] // stack: value, (int)0x7FFFFF add esi, eax // increment source ptr //lea esi, [esi+eax] fmul st(0), st(1) // st(0) *= st(1), stack: value*0x7FFFFF, (int)0x7FFFFF fistp tempInt32 // pop st(0) into tempInt32, stack: (int)0x7FFFFF mov edx, tempInt32 jmp Float32_To_Int24_Clip_store Float32_To_Int24_Clip_clamp: mov edx, dword ptr [esi] // load floating point value into integer register shr edx, 31 // move sign bit into bit 0 add esi, eax // increment source ptr //lea esi, [esi+eax] add edx, 0x7FFFFF // convert to maximum range integers Float32_To_Int24_Clip_store: mov byte ptr [edi], DL shr edx, 8 //mov byte ptr [edi+1], DL //mov byte ptr [edi+2], DH mov word ptr [edi+1], DX //add edi, ebx // increment destination ptr lea edi, [edi+ebx] cmp esi, ecx // has src ptr reached end? jne Float32_To_Int24_Clip_loop ffree st(0) fincstp fwait fnclex fldcw savedFpuControlWord } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int24_DitherClip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator ) { /* float *src = (float*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; signed long temp; while( count-- ) { // convert to 32 bit and drop the low 8 bits // FIXME: the dither amplitude here appears to be too small by 8 bits double dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); // use smaller scaler to prevent overflow when we add the dither double dithered = ((double)*src * (2147483646.0)) + dither; PA_CLIP_( dithered, -2147483648., 2147483647. ); temp = (signed long) dithered; dest[0] = (unsigned char)(temp >> 8); dest[1] = (unsigned char)(temp >> 16); dest[2] = (unsigned char)(temp >> 24); src += sourceStride; dest += destinationStride * 3; } */ short savedFpuControlWord; // spill storage: signed long sourceByteStride; signed long highpassedDither; // dither state: unsigned long ditherPrevious = ditherGenerator->previous; unsigned long ditherRandSeed1 = ditherGenerator->randSeed1; unsigned long ditherRandSeed2 = ditherGenerator->randSeed2; signed long tempInt32; __asm{ // esi -> source ptr // eax -> source byte stride // edi -> destination ptr // ebx -> destination byte stride // ecx -> source end ptr // edx -> temp mov esi, sourceBuffer mov edx, 4 // sizeof float32 mov eax, sourceStride imul eax, edx mov ecx, count imul ecx, eax add ecx, esi mov edi, destinationBuffer mov edx, 3 // sizeof int24 mov ebx, destinationStride imul ebx, edx fwait fstcw savedFpuControlWord fldcw fpuControlWord_ fld ditheredInt24Scaler_ // stack: int scaler Float32_To_Int24_DitherClip_loop: mov edx, dword ptr [esi] // load floating point value into integer register and edx, 0x7FFFFFFF // mask off sign cmp edx, 0x3F800000 // greater than 1.0 or less than -1.0 jg Float32_To_Int24_DitherClip_clamp // load unscaled value into st(0) fld dword ptr [esi] // stack: value, int scaler add esi, eax // increment source ptr //lea esi, [esi+eax] fmul st(0), st(1) // st(0) *= st(1), stack: value*(int scaler), int scaler /* // call PaUtil_GenerateFloatTriangularDither with C calling convention mov sourceByteStride, eax // save eax mov sourceEnd, ecx // save ecx push ditherGenerator // pass ditherGenerator parameter on stack call PaUtil_GenerateFloatTriangularDither // stack: dither, value*(int scaler), int scaler pop edx // clear parameter off stack mov ecx, sourceEnd // restore ecx mov eax, sourceByteStride // restore eax */ // generate dither mov sourceByteStride, eax // save eax mov edx, 196314165 mov eax, ditherRandSeed1 mul edx // eax:edx = eax * 196314165 //add eax, 907633515 lea eax, [eax+907633515] mov ditherRandSeed1, eax mov edx, 196314165 mov eax, ditherRandSeed2 mul edx // eax:edx = eax * 196314165 //add eax, 907633515 lea eax, [eax+907633515] mov edx, ditherRandSeed1 shr edx, PA_DITHER_SHIFT_ mov ditherRandSeed2, eax shr eax, PA_DITHER_SHIFT_ //add eax, edx // eax -> current lea eax, [eax+edx] mov edx, ditherPrevious neg edx lea edx, [eax+edx] // highpass = current - previous mov highpassedDither, edx mov ditherPrevious, eax // previous = current mov eax, sourceByteStride // restore eax fild highpassedDither fmul const_float_dither_scale_ // end generate dither, dither signal in st(0) faddp st(1), st(0) // stack: dither * value*(int scaler), int scaler fistp tempInt32 // pop st(0) into tempInt32, stack: int scaler mov edx, tempInt32 jmp Float32_To_Int24_DitherClip_store Float32_To_Int24_DitherClip_clamp: mov edx, dword ptr [esi] // load floating point value into integer register shr edx, 31 // move sign bit into bit 0 add esi, eax // increment source ptr //lea esi, [esi+eax] add edx, 0x7FFFFF // convert to maximum range integers Float32_To_Int24_DitherClip_store: mov byte ptr [edi], DL shr edx, 8 //mov byte ptr [edi+1], DL //mov byte ptr [edi+2], DH mov word ptr [edi+1], DX //add edi, ebx // increment destination ptr lea edi, [edi+ebx] cmp esi, ecx // has src ptr reached end? jne Float32_To_Int24_DitherClip_loop ffree st(0) fincstp fwait fnclex fldcw savedFpuControlWord } ditherGenerator->previous = ditherPrevious; ditherGenerator->randSeed1 = ditherRandSeed1; ditherGenerator->randSeed2 = ditherRandSeed2; } /* -------------------------------------------------------------------------- */ static void Float32_To_Int16( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator ) { /* float *src = (float*)sourceBuffer; signed short *dest = (signed short*)destinationBuffer; (void)ditherGenerator; // unused parameter while( count-- ) { short samp = (short) (*src * (32767.0f)); *dest = samp; src += sourceStride; dest += destinationStride; } */ short savedFpuControlWord; (void) ditherGenerator; /* unused parameter */ __asm{ // esi -> source ptr // eax -> source byte stride // edi -> destination ptr // ebx -> destination byte stride // ecx -> source end ptr // edx -> temp mov esi, sourceBuffer mov edx, 4 // sizeof float32 mov eax, sourceStride imul eax, edx // source byte stride mov ecx, count imul ecx, eax add ecx, esi // source end ptr = count * source byte stride + source ptr mov edi, destinationBuffer mov edx, 2 // sizeof int16 mov ebx, destinationStride imul ebx, edx // destination byte stride fwait fstcw savedFpuControlWord fldcw fpuControlWord_ fld int16Scaler_ // stack: (int)0x7FFF Float32_To_Int16_loop: // load unscaled value into st(0) fld dword ptr [esi] // stack: value, (int)0x7FFF add esi, eax // increment source ptr //lea esi, [esi+eax] fmul st(0), st(1) // st(0) *= st(1), stack: value*0x7FFF, (int)0x7FFF fistp word ptr [edi] // store scaled int into dest, stack: (int)0x7FFF add edi, ebx // increment destination ptr //lea edi, [edi+ebx] cmp esi, ecx // has src ptr reached end? jne Float32_To_Int16_loop ffree st(0) fincstp fwait fnclex fldcw savedFpuControlWord } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int16_Clip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator ) { /* float *src = (float*)sourceBuffer; signed short *dest = (signed short*)destinationBuffer; (void)ditherGenerator; // unused parameter while( count-- ) { long samp = (signed long) (*src * (32767.0f)); PA_CLIP_( samp, -0x8000, 0x7FFF ); *dest = (signed short) samp; src += sourceStride; dest += destinationStride; } */ short savedFpuControlWord; (void) ditherGenerator; /* unused parameter */ __asm{ // esi -> source ptr // eax -> source byte stride // edi -> destination ptr // ebx -> destination byte stride // ecx -> source end ptr // edx -> temp mov esi, sourceBuffer mov edx, 4 // sizeof float32 mov eax, sourceStride imul eax, edx // source byte stride mov ecx, count imul ecx, eax add ecx, esi // source end ptr = count * source byte stride + source ptr mov edi, destinationBuffer mov edx, 2 // sizeof int16 mov ebx, destinationStride imul ebx, edx // destination byte stride fwait fstcw savedFpuControlWord fldcw fpuControlWord_ fld int16Scaler_ // stack: (int)0x7FFF Float32_To_Int16_Clip_loop: mov edx, dword ptr [esi] // load floating point value into integer register and edx, 0x7FFFFFFF // mask off sign cmp edx, 0x3F800000 // greater than 1.0 or less than -1.0 jg Float32_To_Int16_Clip_clamp // load unscaled value into st(0) fld dword ptr [esi] // stack: value, (int)0x7FFF add esi, eax // increment source ptr //lea esi, [esi+eax] fmul st(0), st(1) // st(0) *= st(1), stack: value*0x7FFF, (int)0x7FFF fistp word ptr [edi] // store scaled int into dest, stack: (int)0x7FFF jmp Float32_To_Int16_Clip_stored Float32_To_Int16_Clip_clamp: mov edx, dword ptr [esi] // load floating point value into integer register shr edx, 31 // move sign bit into bit 0 add esi, eax // increment source ptr //lea esi, [esi+eax] add dx, 0x7FFF // convert to maximum range integers mov word ptr [edi], dx // store clamped into into dest Float32_To_Int16_Clip_stored: add edi, ebx // increment destination ptr //lea edi, [edi+ebx] cmp esi, ecx // has src ptr reached end? jne Float32_To_Int16_Clip_loop ffree st(0) fincstp fwait fnclex fldcw savedFpuControlWord } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int16_DitherClip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator ) { /* float *src = (float*)sourceBuffer; signed short *dest = (signed short*)destinationBuffer; (void)ditherGenerator; // unused parameter while( count-- ) { float dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); // use smaller scaler to prevent overflow when we add the dither float dithered = (*src * (32766.0f)) + dither; signed long samp = (signed long) dithered; PA_CLIP_( samp, -0x8000, 0x7FFF ); *dest = (signed short) samp; src += sourceStride; dest += destinationStride; } */ short savedFpuControlWord; // spill storage: signed long sourceByteStride; signed long highpassedDither; // dither state: unsigned long ditherPrevious = ditherGenerator->previous; unsigned long ditherRandSeed1 = ditherGenerator->randSeed1; unsigned long ditherRandSeed2 = ditherGenerator->randSeed2; __asm{ // esi -> source ptr // eax -> source byte stride // edi -> destination ptr // ebx -> destination byte stride // ecx -> source end ptr // edx -> temp mov esi, sourceBuffer mov edx, 4 // sizeof float32 mov eax, sourceStride imul eax, edx // source byte stride mov ecx, count imul ecx, eax add ecx, esi // source end ptr = count * source byte stride + source ptr mov edi, destinationBuffer mov edx, 2 // sizeof int16 mov ebx, destinationStride imul ebx, edx // destination byte stride fwait fstcw savedFpuControlWord fldcw fpuControlWord_ fld ditheredInt16Scaler_ // stack: int scaler Float32_To_Int16_DitherClip_loop: mov edx, dword ptr [esi] // load floating point value into integer register and edx, 0x7FFFFFFF // mask off sign cmp edx, 0x3F800000 // greater than 1.0 or less than -1.0 jg Float32_To_Int16_DitherClip_clamp // load unscaled value into st(0) fld dword ptr [esi] // stack: value, int scaler add esi, eax // increment source ptr //lea esi, [esi+eax] fmul st(0), st(1) // st(0) *= st(1), stack: value*(int scaler), int scaler /* // call PaUtil_GenerateFloatTriangularDither with C calling convention mov sourceByteStride, eax // save eax mov sourceEnd, ecx // save ecx push ditherGenerator // pass ditherGenerator parameter on stack call PaUtil_GenerateFloatTriangularDither // stack: dither, value*(int scaler), int scaler pop edx // clear parameter off stack mov ecx, sourceEnd // restore ecx mov eax, sourceByteStride // restore eax */ // generate dither mov sourceByteStride, eax // save eax mov edx, 196314165 mov eax, ditherRandSeed1 mul edx // eax:edx = eax * 196314165 //add eax, 907633515 lea eax, [eax+907633515] mov ditherRandSeed1, eax mov edx, 196314165 mov eax, ditherRandSeed2 mul edx // eax:edx = eax * 196314165 //add eax, 907633515 lea eax, [eax+907633515] mov edx, ditherRandSeed1 shr edx, PA_DITHER_SHIFT_ mov ditherRandSeed2, eax shr eax, PA_DITHER_SHIFT_ //add eax, edx // eax -> current lea eax, [eax+edx] // current = randSeed1>>x + randSeed2>>x mov edx, ditherPrevious neg edx lea edx, [eax+edx] // highpass = current - previous mov highpassedDither, edx mov ditherPrevious, eax // previous = current mov eax, sourceByteStride // restore eax fild highpassedDither fmul const_float_dither_scale_ // end generate dither, dither signal in st(0) faddp st(1), st(0) // stack: dither * value*(int scaler), int scaler fistp word ptr [edi] // store scaled int into dest, stack: int scaler jmp Float32_To_Int16_DitherClip_stored Float32_To_Int16_DitherClip_clamp: mov edx, dword ptr [esi] // load floating point value into integer register shr edx, 31 // move sign bit into bit 0 add esi, eax // increment source ptr //lea esi, [esi+eax] add dx, 0x7FFF // convert to maximum range integers mov word ptr [edi], dx // store clamped into into dest Float32_To_Int16_DitherClip_stored: add edi, ebx // increment destination ptr //lea edi, [edi+ebx] cmp esi, ecx // has src ptr reached end? jne Float32_To_Int16_DitherClip_loop ffree st(0) fincstp fwait fnclex fldcw savedFpuControlWord } ditherGenerator->previous = ditherPrevious; ditherGenerator->randSeed1 = ditherRandSeed1; ditherGenerator->randSeed2 = ditherRandSeed2; } /* -------------------------------------------------------------------------- */ void PaUtil_InitializeX86PlainConverters( void ) { paConverters.Float32_To_Int32 = Float32_To_Int32; paConverters.Float32_To_Int32_Clip = Float32_To_Int32_Clip; paConverters.Float32_To_Int32_DitherClip = Float32_To_Int32_DitherClip; paConverters.Float32_To_Int24 = Float32_To_Int24; paConverters.Float32_To_Int24_Clip = Float32_To_Int24_Clip; paConverters.Float32_To_Int24_DitherClip = Float32_To_Int24_DitherClip; paConverters.Float32_To_Int16 = Float32_To_Int16; paConverters.Float32_To_Int16_Clip = Float32_To_Int16_Clip; paConverters.Float32_To_Int16_DitherClip = Float32_To_Int16_DitherClip; } #endif /* -------------------------------------------------------------------------- */ pd-0.46-7/portaudio/src/common/0000775000175000017500000000000012374245151014465 5ustar mspmsppd-0.46-7/portaudio/src/common/pa_types.h0000664000175000017500000000733012160204055016454 0ustar mspmsp#ifndef PA_TYPES_H #define PA_TYPES_H /* * Portable Audio I/O Library * integer type definitions * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2006 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Definition of 16 and 32 bit integer types (PaInt16, PaInt32 etc) SIZEOF_SHORT, SIZEOF_INT and SIZEOF_LONG are set by the configure script when it is used. Otherwise we default to the common 32 bit values, if your platform doesn't use configure, and doesn't use the default values below you will need to explicitly define these symbols in your make file. A PA_VALIDATE_SIZES macro is provided to assert that the values set in this file are correct. */ #ifndef SIZEOF_SHORT #define SIZEOF_SHORT 2 #endif #ifndef SIZEOF_INT #define SIZEOF_INT 4 #endif #ifndef SIZEOF_LONG #define SIZEOF_LONG 4 #endif #if SIZEOF_SHORT == 2 typedef signed short PaInt16; typedef unsigned short PaUint16; #elif SIZEOF_INT == 2 typedef signed int PaInt16; typedef unsigned int PaUint16; #else #error pa_types.h was unable to determine which type to use for 16bit integers on the target platform #endif #if SIZEOF_SHORT == 4 typedef signed short PaInt32; typedef unsigned short PaUint32; #elif SIZEOF_INT == 4 typedef signed int PaInt32; typedef unsigned int PaUint32; #elif SIZEOF_LONG == 4 typedef signed long PaInt32; typedef unsigned long PaUint32; #else #error pa_types.h was unable to determine which type to use for 32bit integers on the target platform #endif /* PA_VALIDATE_TYPE_SIZES compares the size of the integer types at runtime to ensure that PortAudio was configured correctly, and raises an assertion if they don't match the expected values. must be included in the context in which this macro is used. */ #define PA_VALIDATE_TYPE_SIZES \ { \ assert( "PortAudio: type sizes are not correct in pa_types.h" && sizeof( PaUint16 ) == 2 ); \ assert( "PortAudio: type sizes are not correct in pa_types.h" && sizeof( PaInt16 ) == 2 ); \ assert( "PortAudio: type sizes are not correct in pa_types.h" && sizeof( PaUint32 ) == 4 ); \ assert( "PortAudio: type sizes are not correct in pa_types.h" && sizeof( PaInt32 ) == 4 ); \ } #endif /* PA_TYPES_H */ pd-0.46-7/portaudio/src/common/pa_stream.h0000664000175000017500000001617512160204055016612 0ustar mspmsp#ifndef PA_STREAM_H #define PA_STREAM_H /* * $Id: pa_stream.h 1339 2008-02-15 07:50:33Z rossb $ * Portable Audio I/O Library * stream interface * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2008 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Stream interfaces, representation structures and helper functions used to interface between pa_front.c host API implementations. */ #include "portaudio.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define PA_STREAM_MAGIC (0x18273645) /** A structure representing an (abstract) interface to a host API. Contains pointers to functions which implement the interface. All PaStreamInterface functions are guaranteed to be called with a non-null, valid stream parameter. */ typedef struct { PaError (*Close)( PaStream* stream ); PaError (*Start)( PaStream *stream ); PaError (*Stop)( PaStream *stream ); PaError (*Abort)( PaStream *stream ); PaError (*IsStopped)( PaStream *stream ); PaError (*IsActive)( PaStream *stream ); PaTime (*GetTime)( PaStream *stream ); double (*GetCpuLoad)( PaStream* stream ); PaError (*Read)( PaStream* stream, void *buffer, unsigned long frames ); PaError (*Write)( PaStream* stream, const void *buffer, unsigned long frames ); signed long (*GetReadAvailable)( PaStream* stream ); signed long (*GetWriteAvailable)( PaStream* stream ); } PaUtilStreamInterface; /** Initialize the fields of a PaUtilStreamInterface structure. */ void PaUtil_InitializeStreamInterface( PaUtilStreamInterface *streamInterface, PaError (*Close)( PaStream* ), PaError (*Start)( PaStream* ), PaError (*Stop)( PaStream* ), PaError (*Abort)( PaStream* ), PaError (*IsStopped)( PaStream* ), PaError (*IsActive)( PaStream* ), PaTime (*GetTime)( PaStream* ), double (*GetCpuLoad)( PaStream* ), PaError (*Read)( PaStream* stream, void *buffer, unsigned long frames ), PaError (*Write)( PaStream* stream, const void *buffer, unsigned long frames ), signed long (*GetReadAvailable)( PaStream* stream ), signed long (*GetWriteAvailable)( PaStream* stream ) ); /** Dummy Read function for use in interfaces to a callback based streams. Pass to the Read parameter of PaUtil_InitializeStreamInterface. @return An error code indicating that the function has no effect because the stream is a callback stream. */ PaError PaUtil_DummyRead( PaStream* stream, void *buffer, unsigned long frames ); /** Dummy Write function for use in an interfaces to callback based streams. Pass to the Write parameter of PaUtil_InitializeStreamInterface. @return An error code indicating that the function has no effect because the stream is a callback stream. */ PaError PaUtil_DummyWrite( PaStream* stream, const void *buffer, unsigned long frames ); /** Dummy GetReadAvailable function for use in interfaces to callback based streams. Pass to the GetReadAvailable parameter of PaUtil_InitializeStreamInterface. @return An error code indicating that the function has no effect because the stream is a callback stream. */ signed long PaUtil_DummyGetReadAvailable( PaStream* stream ); /** Dummy GetWriteAvailable function for use in interfaces to callback based streams. Pass to the GetWriteAvailable parameter of PaUtil_InitializeStreamInterface. @return An error code indicating that the function has no effect because the stream is a callback stream. */ signed long PaUtil_DummyGetWriteAvailable( PaStream* stream ); /** Dummy GetCpuLoad function for use in an interface to a read/write stream. Pass to the GetCpuLoad parameter of PaUtil_InitializeStreamInterface. @return Returns 0. */ double PaUtil_DummyGetCpuLoad( PaStream* stream ); /** Non host specific data for a stream. This data is used by pa_front to forward to the appropriate functions in the streamInterface structure. */ typedef struct PaUtilStreamRepresentation { unsigned long magic; /**< set to PA_STREAM_MAGIC */ struct PaUtilStreamRepresentation *nextOpenStream; /**< field used by multi-api code */ PaUtilStreamInterface *streamInterface; PaStreamCallback *streamCallback; PaStreamFinishedCallback *streamFinishedCallback; void *userData; PaStreamInfo streamInfo; } PaUtilStreamRepresentation; /** Initialize a PaUtilStreamRepresentation structure. @see PaUtil_InitializeStreamRepresentation */ void PaUtil_InitializeStreamRepresentation( PaUtilStreamRepresentation *streamRepresentation, PaUtilStreamInterface *streamInterface, PaStreamCallback *streamCallback, void *userData ); /** Clean up a PaUtilStreamRepresentation structure previously initialized by a call to PaUtil_InitializeStreamRepresentation. @see PaUtil_InitializeStreamRepresentation */ void PaUtil_TerminateStreamRepresentation( PaUtilStreamRepresentation *streamRepresentation ); /** Check that the stream pointer is valid. @return Returns paNoError if the stream pointer appears to be OK, otherwise returns an error indicating the cause of failure. */ PaError PaUtil_ValidateStreamPointer( PaStream *stream ); /** Cast an opaque stream pointer into a pointer to a PaUtilStreamRepresentation. @see PaUtilStreamRepresentation */ #define PA_STREAM_REP( stream )\ ((PaUtilStreamRepresentation*) (stream) ) /** Cast an opaque stream pointer into a pointer to a PaUtilStreamInterface. @see PaUtilStreamRepresentation, PaUtilStreamInterface */ #define PA_STREAM_INTERFACE( stream )\ PA_STREAM_REP( (stream) )->streamInterface #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_STREAM_H */ pd-0.46-7/portaudio/src/common/pa_endianness.h0000664000175000017500000001262012160204055017435 0ustar mspmsp#ifndef PA_ENDIANNESS_H #define PA_ENDIANNESS_H /* * $Id: pa_endianness.h 1324 2008-01-27 02:03:30Z bjornroche $ * Portable Audio I/O Library current platform endianness macros * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Phil Burk, Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Configure endianness symbols for the target processor. Arrange for either the PA_LITTLE_ENDIAN or PA_BIG_ENDIAN preprocessor symbols to be defined. The one that is defined reflects the endianness of the target platform and may be used to implement conditional compilation of byte-order dependent code. If either PA_LITTLE_ENDIAN or PA_BIG_ENDIAN is defined already, then no attempt is made to override that setting. This may be useful if you have a better way of determining the platform's endianness. The autoconf mechanism uses this for example. A PA_VALIDATE_ENDIANNESS macro is provided to compare the compile time and runtime endiannes and raise an assertion if they don't match. */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* If this is an apple, we need to do detect endianness this way */ #if defined(__APPLE__) /* we need to do some endian detection that is sensitive to harware arch */ #if defined(__LITTLE_ENDIAN__) #if !defined( PA_LITTLE_ENDIAN ) #define PA_LITTLE_ENDIAN #endif #if defined( PA_BIG_ENDIAN ) #undef PA_BIG_ENDIAN #endif #else #if !defined( PA_BIG_ENDIAN ) #define PA_BIG_ENDIAN #endif #if defined( PA_LITTLE_ENDIAN ) #undef PA_LITTLE_ENDIAN #endif #endif #else /* this is not an apple, so first check the existing defines, and, failing that, detect well-known architechtures. */ #if defined(PA_LITTLE_ENDIAN) || defined(PA_BIG_ENDIAN) /* endianness define has been set externally, such as by autoconf */ #if defined(PA_LITTLE_ENDIAN) && defined(PA_BIG_ENDIAN) #error both PA_LITTLE_ENDIAN and PA_BIG_ENDIAN have been defined externally to pa_endianness.h - only one endianness at a time please #endif #else /* endianness define has not been set externally */ /* set PA_LITTLE_ENDIAN or PA_BIG_ENDIAN by testing well known platform specific defines */ #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(LITTLE_ENDIAN) || defined(__i386) || defined(_M_IX86) || defined(__x86_64__) #define PA_LITTLE_ENDIAN /* win32, assume intel byte order */ #else #define PA_BIG_ENDIAN #endif #endif #if !defined(PA_LITTLE_ENDIAN) && !defined(PA_BIG_ENDIAN) /* If the following error is raised, you either need to modify the code above to automatically determine the endianness from other symbols defined on your platform, or define either PA_LITTLE_ENDIAN or PA_BIG_ENDIAN externally. */ #error pa_endianness.h was unable to automatically determine the endianness of the target platform #endif #endif /* PA_VALIDATE_ENDIANNESS compares the compile time and runtime endianness, and raises an assertion if they don't match. must be included in the context in which this macro is used. */ #if defined(NDEBUG) #define PA_VALIDATE_ENDIANNESS #else #if defined(PA_LITTLE_ENDIAN) #define PA_VALIDATE_ENDIANNESS \ { \ const long nativeOne = 1; \ assert( "PortAudio: compile time and runtime endianness don't match" && (((char *)&nativeOne)[0]) == 1 ); \ } #elif defined(PA_BIG_ENDIAN) #define PA_VALIDATE_ENDIANNESS \ { \ const long nativeOne = 1; \ assert( "PortAudio: compile time and runtime endianness don't match" && (((char *)&nativeOne)[0]) == 0 ); \ } #endif #endif #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_ENDIANNESS_H */ pd-0.46-7/portaudio/src/common/pa_trace.h0000664000175000017500000001010112222201037016370 0ustar mspmsp#ifndef PA_TRACE_H #define PA_TRACE_H /* * $Id: pa_trace.h 1812 2012-02-14 09:32:57Z robiwan $ * Portable Audio I/O Library Trace Facility * Store trace information in real-time for later printing. * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2000 Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Real-time safe event trace logging facility for debugging. Allows data to be logged to a fixed size trace buffer in a real-time execution context (such as at interrupt time). Each log entry consists of a message comprising a string pointer and an int. The trace buffer may be dumped to stdout later. This facility is only active if PA_TRACE_REALTIME_EVENTS is set to 1, otherwise the trace functions expand to no-ops. @fn PaUtil_ResetTraceMessages @brief Clear the trace buffer. @fn PaUtil_AddTraceMessage @brief Add a message to the trace buffer. A message consists of string and an int. @param msg The string pointer must remain valid until PaUtil_DumpTraceMessages is called. As a result, usually only string literals should be passed as the msg parameter. @fn PaUtil_DumpTraceMessages @brief Print all messages in the trace buffer to stdout and clear the trace buffer. */ #ifndef PA_TRACE_REALTIME_EVENTS #define PA_TRACE_REALTIME_EVENTS (0) /**< Set to 1 to enable logging using the trace functions defined below */ #endif #ifndef PA_MAX_TRACE_RECORDS #define PA_MAX_TRACE_RECORDS (2048) /**< Maximum number of records stored in trace buffer */ #endif #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #if PA_TRACE_REALTIME_EVENTS void PaUtil_ResetTraceMessages(); void PaUtil_AddTraceMessage( const char *msg, int data ); void PaUtil_DumpTraceMessages(); /* Alternative interface */ typedef void* LogHandle; int PaUtil_InitializeHighSpeedLog(LogHandle* phLog, unsigned maxSizeInBytes); void PaUtil_ResetHighSpeedLogTimeRef(LogHandle hLog); int PaUtil_AddHighSpeedLogMessage(LogHandle hLog, const char* fmt, ...); void PaUtil_DumpHighSpeedLog(LogHandle hLog, const char* fileName); void PaUtil_DiscardHighSpeedLog(LogHandle hLog); #else #define PaUtil_ResetTraceMessages() /* noop */ #define PaUtil_AddTraceMessage(msg,data) /* noop */ #define PaUtil_DumpTraceMessages() /* noop */ #define PaUtil_InitializeHighSpeedLog(phLog, maxSizeInBytes) (0) #define PaUtil_ResetHighSpeedLogTimeRef(hLog) #define PaUtil_AddHighSpeedLogMessage(...) (0) #define PaUtil_DumpHighSpeedLog(hLog, fileName) #define PaUtil_DiscardHighSpeedLog(hLog) #endif #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_TRACE_H */ pd-0.46-7/portaudio/src/common/pa_trace.c0000664000175000017500000001566412222201037016406 0ustar mspmsp/* * $Id: pa_trace.c 1812 2012-02-14 09:32:57Z robiwan $ * Portable Audio I/O Library Trace Facility * Store trace information in real-time for later printing. * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2000 Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Real-time safe event trace logging facility for debugging. */ #include #include #include #include #include #include "pa_trace.h" #include "pa_util.h" #include "pa_debugprint.h" #if PA_TRACE_REALTIME_EVENTS static char const *traceTextArray[PA_MAX_TRACE_RECORDS]; static int traceIntArray[PA_MAX_TRACE_RECORDS]; static int traceIndex = 0; static int traceBlock = 0; /*********************************************************************/ void PaUtil_ResetTraceMessages() { traceIndex = 0; } /*********************************************************************/ void PaUtil_DumpTraceMessages() { int i; int messageCount = (traceIndex < PA_MAX_TRACE_RECORDS) ? traceIndex : PA_MAX_TRACE_RECORDS; printf("DumpTraceMessages: traceIndex = %d\n", traceIndex ); for( i=0; idata = (char*)PaUtil_AllocateMemory(maxSizeInBytes); if (pLog->data == 0) { PaUtil_FreeMemory(pLog); return paInsufficientMemory; } pLog->magik = kMagik; pLog->size = maxSizeInBytes; pLog->refTime = PaUtil_GetTime(); return paNoError; } void PaUtil_ResetHighSpeedLogTimeRef( LogHandle hLog ) { PaHighPerformanceLog* pLog = (PaHighPerformanceLog*)hLog; assert(pLog->magik == kMagik); pLog->refTime = PaUtil_GetTime(); } typedef struct __PaLogEntryHeader { int size; double timeStamp; } PaLogEntryHeader; #ifdef __APPLE__ #define _vsnprintf vsnprintf #define min(a,b) ((a)<(b)?(a):(b)) #endif int PaUtil_AddHighSpeedLogMessage( LogHandle hLog, const char* fmt, ... ) { va_list l; int n = 0; PaHighPerformanceLog* pLog = (PaHighPerformanceLog*)hLog; if (pLog != 0) { PaLogEntryHeader* pHeader; char* p; int maxN; assert(pLog->magik == kMagik); pHeader = (PaLogEntryHeader*)( pLog->data + pLog->writePtr ); p = (char*)( pHeader + 1 ); maxN = pLog->size - pLog->writePtr - 2 * sizeof(PaLogEntryHeader); pHeader->timeStamp = PaUtil_GetTime() - pLog->refTime; if (maxN > 0) { if (maxN > 32) { va_start(l, fmt); n = _vsnprintf(p, min(1024, maxN), fmt, l); va_end(l); } else { n = sprintf(p, "End of log..."); } n = ((n + sizeof(unsigned)) & ~(sizeof(unsigned)-1)) + sizeof(PaLogEntryHeader); pHeader->size = n; #if 0 PaUtil_DebugPrint("%05u.%03u: %s\n", pHeader->timeStamp/1000, pHeader->timeStamp%1000, p); #endif pLog->writePtr += n; } } return n; } void PaUtil_DumpHighSpeedLog( LogHandle hLog, const char* fileName ) { FILE* f = (fileName != NULL) ? fopen(fileName, "w") : stdout; unsigned localWritePtr; PaHighPerformanceLog* pLog = (PaHighPerformanceLog*)hLog; assert(pLog->magik == kMagik); localWritePtr = pLog->writePtr; while (pLog->readPtr != localWritePtr) { const PaLogEntryHeader* pHeader = (const PaLogEntryHeader*)( pLog->data + pLog->readPtr ); const char* p = (const char*)( pHeader + 1 ); const PaUint64 ts = (const PaUint64)( pHeader->timeStamp * USEC_PER_SEC ); assert(pHeader->size < (1024+sizeof(unsigned)+sizeof(PaLogEntryHeader))); fprintf(f, "%05u.%03u: %s\n", (unsigned)(ts/1000), (unsigned)(ts%1000), p); pLog->readPtr += pHeader->size; } if (f != stdout) { fclose(f); } } void PaUtil_DiscardHighSpeedLog( LogHandle hLog ) { PaHighPerformanceLog* pLog = (PaHighPerformanceLog*)hLog; assert(pLog->magik == kMagik); PaUtil_FreeMemory(pLog->data); PaUtil_FreeMemory(pLog); } #endif /* TRACE_REALTIME_EVENTS */ pd-0.46-7/portaudio/src/common/pa_ringbuffer.h0000664000175000017500000002130512222201037017433 0ustar mspmsp#ifndef PA_RINGBUFFER_H #define PA_RINGBUFFER_H /* * $Id: pa_ringbuffer.h 1873 2012-10-07 19:00:11Z philburk $ * Portable Audio I/O Library * Ring Buffer utility. * * Author: Phil Burk, http://www.softsynth.com * modified for SMP safety on OS X by Bjorn Roche. * also allowed for const where possible. * modified for multiple-byte-sized data elements by Sven Fischer * * Note that this is safe only for a single-thread reader * and a single-thread writer. * * This program is distributed with the PortAudio Portable Audio Library. * For more information see: http://www.portaudio.com * Copyright (c) 1999-2000 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Single-reader single-writer lock-free ring buffer PaUtilRingBuffer is a ring buffer used to transport samples between different execution contexts (threads, OS callbacks, interrupt handlers) without requiring the use of any locks. This only works when there is a single reader and a single writer (ie. one thread or callback writes to the ring buffer, another thread or callback reads from it). The PaUtilRingBuffer structure manages a ring buffer containing N elements, where N must be a power of two. An element may be any size (specified in bytes). The memory area used to store the buffer elements must be allocated by the client prior to calling PaUtil_InitializeRingBuffer() and must outlive the use of the ring buffer. @note The ring buffer functions are not normally exposed in the PortAudio libraries. If you want to call them then you will need to add pa_ringbuffer.c to your application source code. */ #if defined(__APPLE__) #include typedef int32_t ring_buffer_size_t; #elif defined( __GNUC__ ) typedef long ring_buffer_size_t; #elif (_MSC_VER >= 1400) typedef long ring_buffer_size_t; #elif defined(_MSC_VER) || defined(__BORLANDC__) typedef long ring_buffer_size_t; #else typedef long ring_buffer_size_t; #endif #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ typedef struct PaUtilRingBuffer { ring_buffer_size_t bufferSize; /**< Number of elements in FIFO. Power of 2. Set by PaUtil_InitRingBuffer. */ volatile ring_buffer_size_t writeIndex; /**< Index of next writable element. Set by PaUtil_AdvanceRingBufferWriteIndex. */ volatile ring_buffer_size_t readIndex; /**< Index of next readable element. Set by PaUtil_AdvanceRingBufferReadIndex. */ ring_buffer_size_t bigMask; /**< Used for wrapping indices with extra bit to distinguish full/empty. */ ring_buffer_size_t smallMask; /**< Used for fitting indices to buffer. */ ring_buffer_size_t elementSizeBytes; /**< Number of bytes per element. */ char *buffer; /**< Pointer to the buffer containing the actual data. */ }PaUtilRingBuffer; /** Initialize Ring Buffer to empty state ready to have elements written to it. @param rbuf The ring buffer. @param elementSizeBytes The size of a single data element in bytes. @param elementCount The number of elements in the buffer (must be a power of 2). @param dataPtr A pointer to a previously allocated area where the data will be maintained. It must be elementCount*elementSizeBytes long. @return -1 if elementCount is not a power of 2, otherwise 0. */ ring_buffer_size_t PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementSizeBytes, ring_buffer_size_t elementCount, void *dataPtr ); /** Reset buffer to empty. Should only be called when buffer is NOT being read or written. @param rbuf The ring buffer. */ void PaUtil_FlushRingBuffer( PaUtilRingBuffer *rbuf ); /** Retrieve the number of elements available in the ring buffer for writing. @param rbuf The ring buffer. @return The number of elements available for writing. */ ring_buffer_size_t PaUtil_GetRingBufferWriteAvailable( const PaUtilRingBuffer *rbuf ); /** Retrieve the number of elements available in the ring buffer for reading. @param rbuf The ring buffer. @return The number of elements available for reading. */ ring_buffer_size_t PaUtil_GetRingBufferReadAvailable( const PaUtilRingBuffer *rbuf ); /** Write data to the ring buffer. @param rbuf The ring buffer. @param data The address of new data to write to the buffer. @param elementCount The number of elements to be written. @return The number of elements written. */ ring_buffer_size_t PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, ring_buffer_size_t elementCount ); /** Read data from the ring buffer. @param rbuf The ring buffer. @param data The address where the data should be stored. @param elementCount The number of elements to be read. @return The number of elements read. */ ring_buffer_size_t PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, ring_buffer_size_t elementCount ); /** Get address of region(s) to which we can write data. @param rbuf The ring buffer. @param elementCount The number of elements desired. @param dataPtr1 The address where the first (or only) region pointer will be stored. @param sizePtr1 The address where the first (or only) region length will be stored. @param dataPtr2 The address where the second region pointer will be stored if the first region is too small to satisfy elementCount. @param sizePtr2 The address where the second region length will be stored if the first region is too small to satisfy elementCount. @return The room available to be written or elementCount, whichever is smaller. */ ring_buffer_size_t PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount, void **dataPtr1, ring_buffer_size_t *sizePtr1, void **dataPtr2, ring_buffer_size_t *sizePtr2 ); /** Advance the write index to the next location to be written. @param rbuf The ring buffer. @param elementCount The number of elements to advance. @return The new position. */ ring_buffer_size_t PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount ); /** Get address of region(s) from which we can read data. @param rbuf The ring buffer. @param elementCount The number of elements desired. @param dataPtr1 The address where the first (or only) region pointer will be stored. @param sizePtr1 The address where the first (or only) region length will be stored. @param dataPtr2 The address where the second region pointer will be stored if the first region is too small to satisfy elementCount. @param sizePtr2 The address where the second region length will be stored if the first region is too small to satisfy elementCount. @return The number of elements available for reading. */ ring_buffer_size_t PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount, void **dataPtr1, ring_buffer_size_t *sizePtr1, void **dataPtr2, ring_buffer_size_t *sizePtr2 ); /** Advance the read index to the next location to be read. @param rbuf The ring buffer. @param elementCount The number of elements to advance. @return The new position. */ ring_buffer_size_t PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_RINGBUFFER_H */ pd-0.46-7/portaudio/src/common/pa_front.c0000664000175000017500000015360412374245151016452 0ustar mspmsp/* * $Id: pa_front.c 1880 2012-12-04 18:39:48Z rbencina $ * Portable Audio I/O Library Multi-Host API front end * Validate function parameters and manage multiple host APIs. * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2008 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Implements PortAudio API functions defined in portaudio.h, checks some errors, delegates platform-specific behavior to host API implementations. Implements the functions defined in the PortAudio API (portaudio.h), validates some parameters and checks for state inconsistencies before forwarding API requests to specific Host API implementations (via the interface declared in pa_hostapi.h), and Streams (via the interface declared in pa_stream.h). This file manages initialization and termination of Host API implementations via initializer functions stored in the paHostApiInitializers global array (usually defined in an os-specific pa_[os]_hostapis.c file). This file maintains a list of all open streams and closes them at Pa_Terminate(). Some utility functions declared in pa_util.h are implemented in this file. All PortAudio API functions can be conditionally compiled with logging code. To compile with logging, define the PA_LOG_API_CALLS precompiler symbol. */ #include #include #include #include /* needed by PA_VALIDATE_ENDIANNESS */ #include "portaudio.h" #include "pa_util.h" #include "pa_endianness.h" #include "pa_types.h" #include "pa_hostapi.h" #include "pa_stream.h" #include "pa_trace.h" /* still usefull?*/ #include "pa_debugprint.h" #define PA_VERSION_ 1899 #define PA_VERSION_TEXT_ "PortAudio V19-devel (built " __DATE__ " " __TIME__ ")" int Pa_GetVersion( void ) { return PA_VERSION_; } const char* Pa_GetVersionText( void ) { return PA_VERSION_TEXT_; } #define PA_LAST_HOST_ERROR_TEXT_LENGTH_ 1024 static char lastHostErrorText_[ PA_LAST_HOST_ERROR_TEXT_LENGTH_ + 1 ] = {0}; static PaHostErrorInfo lastHostErrorInfo_ = { (PaHostApiTypeId)-1, 0, lastHostErrorText_ }; void PaUtil_SetLastHostErrorInfo( PaHostApiTypeId hostApiType, long errorCode, const char *errorText ) { lastHostErrorInfo_.hostApiType = hostApiType; lastHostErrorInfo_.errorCode = errorCode; strncpy( lastHostErrorText_, errorText, PA_LAST_HOST_ERROR_TEXT_LENGTH_ ); } static PaUtilHostApiRepresentation **hostApis_ = 0; static int hostApisCount_ = 0; static int defaultHostApiIndex_ = 0; static int initializationCount_ = 0; static int deviceCount_ = 0; PaUtilStreamRepresentation *firstOpenStream_ = NULL; #define PA_IS_INITIALISED_ (initializationCount_ != 0) static int CountHostApiInitializers( void ) { int result = 0; while( paHostApiInitializers[ result ] != 0 ) ++result; return result; } static void TerminateHostApis( void ) { /* terminate in reverse order from initialization */ PA_DEBUG(("TerminateHostApis in \n")); while( hostApisCount_ > 0 ) { --hostApisCount_; hostApis_[hostApisCount_]->Terminate( hostApis_[hostApisCount_] ); } hostApisCount_ = 0; defaultHostApiIndex_ = 0; deviceCount_ = 0; if( hostApis_ != 0 ) PaUtil_FreeMemory( hostApis_ ); hostApis_ = 0; PA_DEBUG(("TerminateHostApis out\n")); } static PaError InitializeHostApis( void ) { PaError result = paNoError; int i, initializerCount, baseDeviceIndex; initializerCount = CountHostApiInitializers(); hostApis_ = (PaUtilHostApiRepresentation**)PaUtil_AllocateMemory( sizeof(PaUtilHostApiRepresentation*) * initializerCount ); if( !hostApis_ ) { result = paInsufficientMemory; goto error; } hostApisCount_ = 0; defaultHostApiIndex_ = -1; /* indicates that we haven't determined the default host API yet */ deviceCount_ = 0; baseDeviceIndex = 0; for( i=0; i< initializerCount; ++i ) { hostApis_[hostApisCount_] = NULL; PA_DEBUG(( "before paHostApiInitializers[%d].\n",i)); result = paHostApiInitializers[i]( &hostApis_[hostApisCount_], hostApisCount_ ); if( result != paNoError ) goto error; PA_DEBUG(( "after paHostApiInitializers[%d].\n",i)); if( hostApis_[hostApisCount_] ) { PaUtilHostApiRepresentation* hostApi = hostApis_[hostApisCount_]; assert( hostApi->info.defaultInputDevice < hostApi->info.deviceCount ); assert( hostApi->info.defaultOutputDevice < hostApi->info.deviceCount ); /* the first successfully initialized host API with a default input *or* output device is used as the default host API. */ if( (defaultHostApiIndex_ == -1) && ( hostApi->info.defaultInputDevice != paNoDevice || hostApi->info.defaultOutputDevice != paNoDevice ) ) { defaultHostApiIndex_ = hostApisCount_; } hostApi->privatePaFrontInfo.baseDeviceIndex = baseDeviceIndex; if( hostApi->info.defaultInputDevice != paNoDevice ) hostApi->info.defaultInputDevice += baseDeviceIndex; if( hostApi->info.defaultOutputDevice != paNoDevice ) hostApi->info.defaultOutputDevice += baseDeviceIndex; baseDeviceIndex += hostApi->info.deviceCount; deviceCount_ += hostApi->info.deviceCount; ++hostApisCount_; } } /* if no host APIs have devices, the default host API is the first initialized host API */ if( defaultHostApiIndex_ == -1 ) defaultHostApiIndex_ = 0; return result; error: TerminateHostApis(); return result; } /* FindHostApi() finds the index of the host api to which belongs and returns it. if is non-null, the host specific device index is returned in it. returns -1 if is out of range. */ static int FindHostApi( PaDeviceIndex device, int *hostSpecificDeviceIndex ) { int i=0; if( !PA_IS_INITIALISED_ ) return -1; if( device < 0 ) return -1; while( i < hostApisCount_ && device >= hostApis_[i]->info.deviceCount ) { device -= hostApis_[i]->info.deviceCount; ++i; } if( i >= hostApisCount_ ) return -1; if( hostSpecificDeviceIndex ) *hostSpecificDeviceIndex = device; return i; } static void AddOpenStream( PaStream* stream ) { ((PaUtilStreamRepresentation*)stream)->nextOpenStream = firstOpenStream_; firstOpenStream_ = (PaUtilStreamRepresentation*)stream; } static void RemoveOpenStream( PaStream* stream ) { PaUtilStreamRepresentation *previous = NULL; PaUtilStreamRepresentation *current = firstOpenStream_; while( current != NULL ) { if( ((PaStream*)current) == stream ) { if( previous == NULL ) { firstOpenStream_ = current->nextOpenStream; } else { previous->nextOpenStream = current->nextOpenStream; } return; } else { previous = current; current = current->nextOpenStream; } } } static void CloseOpenStreams( void ) { /* we call Pa_CloseStream() here to ensure that the same destruction logic is used for automatically closed streams */ while( firstOpenStream_ != NULL ) Pa_CloseStream( firstOpenStream_ ); } PaError Pa_Initialize( void ) { PaError result; PA_LOGAPI_ENTER( "Pa_Initialize" ); if( PA_IS_INITIALISED_ ) { ++initializationCount_; result = paNoError; } else { PA_VALIDATE_TYPE_SIZES; PA_VALIDATE_ENDIANNESS; PaUtil_InitializeClock(); PaUtil_ResetTraceMessages(); result = InitializeHostApis(); if( result == paNoError ) ++initializationCount_; } PA_LOGAPI_EXIT_PAERROR( "Pa_Initialize", result ); return result; } PaError Pa_Terminate( void ) { PaError result; PA_LOGAPI_ENTER( "Pa_Terminate" ); if( PA_IS_INITIALISED_ ) { if( --initializationCount_ == 0 ) { CloseOpenStreams(); TerminateHostApis(); PaUtil_DumpTraceMessages(); } result = paNoError; } else { result= paNotInitialized; } PA_LOGAPI_EXIT_PAERROR( "Pa_Terminate", result ); return result; } const PaHostErrorInfo* Pa_GetLastHostErrorInfo( void ) { return &lastHostErrorInfo_; } const char *Pa_GetErrorText( PaError errorCode ) { const char *result; switch( errorCode ) { case paNoError: result = "Success"; break; case paNotInitialized: result = "PortAudio not initialized"; break; /** @todo could catenate the last host error text to result in the case of paUnanticipatedHostError. see: http://www.portaudio.com/trac/ticket/114 */ case paUnanticipatedHostError: result = "Unanticipated host error"; break; case paInvalidChannelCount: result = "Invalid number of channels"; break; case paInvalidSampleRate: result = "Invalid sample rate"; break; case paInvalidDevice: result = "Invalid device"; break; case paInvalidFlag: result = "Invalid flag"; break; case paSampleFormatNotSupported: result = "Sample format not supported"; break; case paBadIODeviceCombination: result = "Illegal combination of I/O devices"; break; case paInsufficientMemory: result = "Insufficient memory"; break; case paBufferTooBig: result = "Buffer too big"; break; case paBufferTooSmall: result = "Buffer too small"; break; case paNullCallback: result = "No callback routine specified"; break; case paBadStreamPtr: result = "Invalid stream pointer"; break; case paTimedOut: result = "Wait timed out"; break; case paInternalError: result = "Internal PortAudio error"; break; case paDeviceUnavailable: result = "Device unavailable"; break; case paIncompatibleHostApiSpecificStreamInfo: result = "Incompatible host API specific stream info"; break; case paStreamIsStopped: result = "Stream is stopped"; break; case paStreamIsNotStopped: result = "Stream is not stopped"; break; case paInputOverflowed: result = "Input overflowed"; break; case paOutputUnderflowed: result = "Output underflowed"; break; case paHostApiNotFound: result = "Host API not found"; break; case paInvalidHostApi: result = "Invalid host API"; break; case paCanNotReadFromACallbackStream: result = "Can't read from a callback stream"; break; case paCanNotWriteToACallbackStream: result = "Can't write to a callback stream"; break; case paCanNotReadFromAnOutputOnlyStream: result = "Can't read from an output only stream"; break; case paCanNotWriteToAnInputOnlyStream: result = "Can't write to an input only stream"; break; case paIncompatibleStreamHostApi: result = "Incompatible stream host API"; break; case paBadBufferPtr: result = "Bad buffer pointer"; break; default: if( errorCode > 0 ) result = "Invalid error code (value greater than zero)"; else result = "Invalid error code"; break; } return result; } PaHostApiIndex Pa_HostApiTypeIdToHostApiIndex( PaHostApiTypeId type ) { PaHostApiIndex result; int i; PA_LOGAPI_ENTER_PARAMS( "Pa_HostApiTypeIdToHostApiIndex" ); PA_LOGAPI(("\tPaHostApiTypeId type: %d\n", type )); if( !PA_IS_INITIALISED_ ) { result = paNotInitialized; } else { result = paHostApiNotFound; for( i=0; i < hostApisCount_; ++i ) { if( hostApis_[i]->info.type == type ) { result = i; break; } } } PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_HostApiTypeIdToHostApiIndex", "PaHostApiIndex: %d", result ); return result; } PaError PaUtil_GetHostApiRepresentation( struct PaUtilHostApiRepresentation **hostApi, PaHostApiTypeId type ) { PaError result; int i; if( !PA_IS_INITIALISED_ ) { result = paNotInitialized; } else { result = paHostApiNotFound; for( i=0; i < hostApisCount_; ++i ) { if( hostApis_[i]->info.type == type ) { *hostApi = hostApis_[i]; result = paNoError; break; } } } return result; } PaError PaUtil_DeviceIndexToHostApiDeviceIndex( PaDeviceIndex *hostApiDevice, PaDeviceIndex device, struct PaUtilHostApiRepresentation *hostApi ) { PaError result; PaDeviceIndex x; x = device - hostApi->privatePaFrontInfo.baseDeviceIndex; if( x < 0 || x >= hostApi->info.deviceCount ) { result = paInvalidDevice; } else { *hostApiDevice = x; result = paNoError; } return result; } PaHostApiIndex Pa_GetHostApiCount( void ) { int result; PA_LOGAPI_ENTER( "Pa_GetHostApiCount" ); if( !PA_IS_INITIALISED_ ) { result = paNotInitialized; } else { result = hostApisCount_; } PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_GetHostApiCount", "PaHostApiIndex: %d", result ); return result; } PaHostApiIndex Pa_GetDefaultHostApi( void ) { int result; PA_LOGAPI_ENTER( "Pa_GetDefaultHostApi" ); if( !PA_IS_INITIALISED_ ) { result = paNotInitialized; } else { result = defaultHostApiIndex_; /* internal consistency check: make sure that the default host api index is within range */ if( result < 0 || result >= hostApisCount_ ) { result = paInternalError; } } PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_GetDefaultHostApi", "PaHostApiIndex: %d", result ); return result; } const PaHostApiInfo* Pa_GetHostApiInfo( PaHostApiIndex hostApi ) { PaHostApiInfo *info; PA_LOGAPI_ENTER_PARAMS( "Pa_GetHostApiInfo" ); PA_LOGAPI(("\tPaHostApiIndex hostApi: %d\n", hostApi )); if( !PA_IS_INITIALISED_ ) { info = NULL; PA_LOGAPI(("Pa_GetHostApiInfo returned:\n" )); PA_LOGAPI(("\tPaHostApiInfo*: NULL [ PortAudio not initialized ]\n" )); } else if( hostApi < 0 || hostApi >= hostApisCount_ ) { info = NULL; PA_LOGAPI(("Pa_GetHostApiInfo returned:\n" )); PA_LOGAPI(("\tPaHostApiInfo*: NULL [ hostApi out of range ]\n" )); } else { info = &hostApis_[hostApi]->info; PA_LOGAPI(("Pa_GetHostApiInfo returned:\n" )); PA_LOGAPI(("\tPaHostApiInfo*: 0x%p\n", info )); PA_LOGAPI(("\t{\n" )); PA_LOGAPI(("\t\tint structVersion: %d\n", info->structVersion )); PA_LOGAPI(("\t\tPaHostApiTypeId type: %d\n", info->type )); PA_LOGAPI(("\t\tconst char *name: %s\n", info->name )); PA_LOGAPI(("\t}\n" )); } return info; } PaDeviceIndex Pa_HostApiDeviceIndexToDeviceIndex( PaHostApiIndex hostApi, int hostApiDeviceIndex ) { PaDeviceIndex result; PA_LOGAPI_ENTER_PARAMS( "Pa_HostApiDeviceIndexToPaDeviceIndex" ); PA_LOGAPI(("\tPaHostApiIndex hostApi: %d\n", hostApi )); PA_LOGAPI(("\tint hostApiDeviceIndex: %d\n", hostApiDeviceIndex )); if( !PA_IS_INITIALISED_ ) { result = paNotInitialized; } else { if( hostApi < 0 || hostApi >= hostApisCount_ ) { result = paInvalidHostApi; } else { if( hostApiDeviceIndex < 0 || hostApiDeviceIndex >= hostApis_[hostApi]->info.deviceCount ) { result = paInvalidDevice; } else { result = hostApis_[hostApi]->privatePaFrontInfo.baseDeviceIndex + hostApiDeviceIndex; } } } PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_HostApiDeviceIndexToPaDeviceIndex", "PaDeviceIndex: %d", result ); return result; } PaDeviceIndex Pa_GetDeviceCount( void ) { PaDeviceIndex result; PA_LOGAPI_ENTER( "Pa_GetDeviceCount" ); if( !PA_IS_INITIALISED_ ) { result = paNotInitialized; } else { result = deviceCount_; } PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_GetDeviceCount", "PaDeviceIndex: %d", result ); return result; } PaDeviceIndex Pa_GetDefaultInputDevice( void ) { PaHostApiIndex hostApi; PaDeviceIndex result; PA_LOGAPI_ENTER( "Pa_GetDefaultInputDevice" ); hostApi = Pa_GetDefaultHostApi(); if( hostApi < 0 ) { result = paNoDevice; } else { result = hostApis_[hostApi]->info.defaultInputDevice; } PA_LOGAPI_EXIT_T( "Pa_GetDefaultInputDevice", "PaDeviceIndex: %d", result ); return result; } PaDeviceIndex Pa_GetDefaultOutputDevice( void ) { PaHostApiIndex hostApi; PaDeviceIndex result; PA_LOGAPI_ENTER( "Pa_GetDefaultOutputDevice" ); hostApi = Pa_GetDefaultHostApi(); if( hostApi < 0 ) { result = paNoDevice; } else { result = hostApis_[hostApi]->info.defaultOutputDevice; } PA_LOGAPI_EXIT_T( "Pa_GetDefaultOutputDevice", "PaDeviceIndex: %d", result ); return result; } const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceIndex device ) { int hostSpecificDeviceIndex; int hostApiIndex = FindHostApi( device, &hostSpecificDeviceIndex ); PaDeviceInfo *result; PA_LOGAPI_ENTER_PARAMS( "Pa_GetDeviceInfo" ); PA_LOGAPI(("\tPaDeviceIndex device: %d\n", device )); if( hostApiIndex < 0 ) { result = NULL; PA_LOGAPI(("Pa_GetDeviceInfo returned:\n" )); PA_LOGAPI(("\tPaDeviceInfo* NULL [ invalid device index ]\n" )); } else { result = hostApis_[hostApiIndex]->deviceInfos[ hostSpecificDeviceIndex ]; PA_LOGAPI(("Pa_GetDeviceInfo returned:\n" )); PA_LOGAPI(("\tPaDeviceInfo*: 0x%p:\n", result )); PA_LOGAPI(("\t{\n" )); PA_LOGAPI(("\t\tint structVersion: %d\n", result->structVersion )); PA_LOGAPI(("\t\tconst char *name: %s\n", result->name )); PA_LOGAPI(("\t\tPaHostApiIndex hostApi: %d\n", result->hostApi )); PA_LOGAPI(("\t\tint maxInputChannels: %d\n", result->maxInputChannels )); PA_LOGAPI(("\t\tint maxOutputChannels: %d\n", result->maxOutputChannels )); PA_LOGAPI(("\t}\n" )); } return result; } /* SampleFormatIsValid() returns 1 if sampleFormat is a sample format defined in portaudio.h, or 0 otherwise. */ static int SampleFormatIsValid( PaSampleFormat format ) { switch( format & ~paNonInterleaved ) { case paFloat32: return 1; case paInt16: return 1; case paInt32: return 1; case paInt24: return 1; case paInt8: return 1; case paUInt8: return 1; case paCustomFormat: return 1; default: return 0; } } /* NOTE: make sure this validation list is kept syncronised with the one in pa_hostapi.h ValidateOpenStreamParameters() checks that parameters to Pa_OpenStream() conform to the expected values as described below. This function is also designed to be used with the proposed Pa_IsFormatSupported() function. There are basically two types of validation that could be performed: Generic conformance validation, and device capability mismatch validation. This function performs only generic conformance validation. Validation that would require knowledge of device capabilities is not performed because of potentially complex relationships between combinations of parameters - for example, even if the sampleRate seems ok, it might not be for a duplex stream - we have no way of checking this in an API-neutral way, so we don't try. On success the function returns PaNoError and fills in hostApi, hostApiInputDeviceID, and hostApiOutputDeviceID fields. On failure the function returns an error code indicating the first encountered parameter error. If ValidateOpenStreamParameters() returns paNoError, the following assertions are guaranteed to be true. - at least one of inputParameters & outputParmeters is valid (not NULL) - if inputParameters & outputParameters are both valid, that inputParameters->device & outputParameters->device both use the same host api PaDeviceIndex inputParameters->device - is within range (0 to Pa_GetDeviceCount-1) Or: - is paUseHostApiSpecificDeviceSpecification and inputParameters->hostApiSpecificStreamInfo is non-NULL and refers to a valid host api int inputParameters->channelCount - if inputParameters->device is not paUseHostApiSpecificDeviceSpecification, channelCount is > 0 - upper bound is NOT validated against device capabilities PaSampleFormat inputParameters->sampleFormat - is one of the sample formats defined in portaudio.h void *inputParameters->hostApiSpecificStreamInfo - if supplied its hostApi field matches the input device's host Api PaDeviceIndex outputParmeters->device - is within range (0 to Pa_GetDeviceCount-1) int outputParmeters->channelCount - if inputDevice is valid, channelCount is > 0 - upper bound is NOT validated against device capabilities PaSampleFormat outputParmeters->sampleFormat - is one of the sample formats defined in portaudio.h void *outputParmeters->hostApiSpecificStreamInfo - if supplied its hostApi field matches the output device's host Api double sampleRate - is not an 'absurd' rate (less than 1000. or greater than 384000.) - sampleRate is NOT validated against device capabilities PaStreamFlags streamFlags - unused platform neutral flags are zero - paNeverDropInput is only used for full-duplex callback streams with variable buffer size (paFramesPerBufferUnspecified) */ static PaError ValidateOpenStreamParameters( const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, PaUtilHostApiRepresentation **hostApi, PaDeviceIndex *hostApiInputDevice, PaDeviceIndex *hostApiOutputDevice ) { int inputHostApiIndex = -1, /* Surpress uninitialised var warnings: compiler does */ outputHostApiIndex = -1; /* not see that if inputParameters and outputParame- */ /* ters are both nonzero, these indices are set. */ if( (inputParameters == NULL) && (outputParameters == NULL) ) { return paInvalidDevice; /** @todo should be a new error code "invalid device parameters" or something */ } else { if( inputParameters == NULL ) { *hostApiInputDevice = paNoDevice; } else if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) { if( inputParameters->hostApiSpecificStreamInfo ) { inputHostApiIndex = Pa_HostApiTypeIdToHostApiIndex( ((PaUtilHostApiSpecificStreamInfoHeader*)inputParameters->hostApiSpecificStreamInfo)->hostApiType ); if( inputHostApiIndex != -1 ) { *hostApiInputDevice = paUseHostApiSpecificDeviceSpecification; *hostApi = hostApis_[inputHostApiIndex]; } else { return paInvalidDevice; } } else { return paInvalidDevice; } } else { if( inputParameters->device < 0 || inputParameters->device >= deviceCount_ ) return paInvalidDevice; inputHostApiIndex = FindHostApi( inputParameters->device, hostApiInputDevice ); if( inputHostApiIndex < 0 ) return paInternalError; *hostApi = hostApis_[inputHostApiIndex]; if( inputParameters->channelCount <= 0 ) return paInvalidChannelCount; if( !SampleFormatIsValid( inputParameters->sampleFormat ) ) return paSampleFormatNotSupported; if( inputParameters->hostApiSpecificStreamInfo != NULL ) { if( ((PaUtilHostApiSpecificStreamInfoHeader*)inputParameters->hostApiSpecificStreamInfo)->hostApiType != (*hostApi)->info.type ) return paIncompatibleHostApiSpecificStreamInfo; } } if( outputParameters == NULL ) { *hostApiOutputDevice = paNoDevice; } else if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) { if( outputParameters->hostApiSpecificStreamInfo ) { outputHostApiIndex = Pa_HostApiTypeIdToHostApiIndex( ((PaUtilHostApiSpecificStreamInfoHeader*)outputParameters->hostApiSpecificStreamInfo)->hostApiType ); if( outputHostApiIndex != -1 ) { *hostApiOutputDevice = paUseHostApiSpecificDeviceSpecification; *hostApi = hostApis_[outputHostApiIndex]; } else { return paInvalidDevice; } } else { return paInvalidDevice; } } else { if( outputParameters->device < 0 || outputParameters->device >= deviceCount_ ) return paInvalidDevice; outputHostApiIndex = FindHostApi( outputParameters->device, hostApiOutputDevice ); if( outputHostApiIndex < 0 ) return paInternalError; *hostApi = hostApis_[outputHostApiIndex]; if( outputParameters->channelCount <= 0 ) return paInvalidChannelCount; if( !SampleFormatIsValid( outputParameters->sampleFormat ) ) return paSampleFormatNotSupported; if( outputParameters->hostApiSpecificStreamInfo != NULL ) { if( ((PaUtilHostApiSpecificStreamInfoHeader*)outputParameters->hostApiSpecificStreamInfo)->hostApiType != (*hostApi)->info.type ) return paIncompatibleHostApiSpecificStreamInfo; } } if( (inputParameters != NULL) && (outputParameters != NULL) ) { /* ensure that both devices use the same API */ if( inputHostApiIndex != outputHostApiIndex ) return paBadIODeviceCombination; } } /* Check for absurd sample rates. */ if( (sampleRate < 1000.0) || (sampleRate > 384000.0) ) return paInvalidSampleRate; if( ((streamFlags & ~paPlatformSpecificFlags) & ~(paClipOff | paDitherOff | paNeverDropInput | paPrimeOutputBuffersUsingStreamCallback ) ) != 0 ) return paInvalidFlag; if( streamFlags & paNeverDropInput ) { /* must be a callback stream */ if( !streamCallback ) return paInvalidFlag; /* must be a full duplex stream */ if( (inputParameters == NULL) || (outputParameters == NULL) ) return paInvalidFlag; /* must use paFramesPerBufferUnspecified */ if( framesPerBuffer != paFramesPerBufferUnspecified ) return paInvalidFlag; } return paNoError; } PaError Pa_IsFormatSupported( const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ) { PaError result; PaUtilHostApiRepresentation *hostApi = 0; PaDeviceIndex hostApiInputDevice = paNoDevice, hostApiOutputDevice = paNoDevice; PaStreamParameters hostApiInputParameters, hostApiOutputParameters; PaStreamParameters *hostApiInputParametersPtr, *hostApiOutputParametersPtr; #ifdef PA_LOG_API_CALLS PA_LOGAPI_ENTER_PARAMS( "Pa_IsFormatSupported" ); if( inputParameters == NULL ){ PA_LOGAPI(("\tPaStreamParameters *inputParameters: NULL\n" )); }else{ PA_LOGAPI(("\tPaStreamParameters *inputParameters: 0x%p\n", inputParameters )); PA_LOGAPI(("\tPaDeviceIndex inputParameters->device: %d\n", inputParameters->device )); PA_LOGAPI(("\tint inputParameters->channelCount: %d\n", inputParameters->channelCount )); PA_LOGAPI(("\tPaSampleFormat inputParameters->sampleFormat: %d\n", inputParameters->sampleFormat )); PA_LOGAPI(("\tPaTime inputParameters->suggestedLatency: %f\n", inputParameters->suggestedLatency )); PA_LOGAPI(("\tvoid *inputParameters->hostApiSpecificStreamInfo: 0x%p\n", inputParameters->hostApiSpecificStreamInfo )); } if( outputParameters == NULL ){ PA_LOGAPI(("\tPaStreamParameters *outputParameters: NULL\n" )); }else{ PA_LOGAPI(("\tPaStreamParameters *outputParameters: 0x%p\n", outputParameters )); PA_LOGAPI(("\tPaDeviceIndex outputParameters->device: %d\n", outputParameters->device )); PA_LOGAPI(("\tint outputParameters->channelCount: %d\n", outputParameters->channelCount )); PA_LOGAPI(("\tPaSampleFormat outputParameters->sampleFormat: %d\n", outputParameters->sampleFormat )); PA_LOGAPI(("\tPaTime outputParameters->suggestedLatency: %f\n", outputParameters->suggestedLatency )); PA_LOGAPI(("\tvoid *outputParameters->hostApiSpecificStreamInfo: 0x%p\n", outputParameters->hostApiSpecificStreamInfo )); } PA_LOGAPI(("\tdouble sampleRate: %g\n", sampleRate )); #endif if( !PA_IS_INITIALISED_ ) { result = paNotInitialized; PA_LOGAPI_EXIT_PAERROR( "Pa_IsFormatSupported", result ); return result; } result = ValidateOpenStreamParameters( inputParameters, outputParameters, sampleRate, 0, paNoFlag, 0, &hostApi, &hostApiInputDevice, &hostApiOutputDevice ); if( result != paNoError ) { PA_LOGAPI_EXIT_PAERROR( "Pa_IsFormatSupported", result ); return result; } if( inputParameters ) { hostApiInputParameters.device = hostApiInputDevice; hostApiInputParameters.channelCount = inputParameters->channelCount; hostApiInputParameters.sampleFormat = inputParameters->sampleFormat; hostApiInputParameters.suggestedLatency = inputParameters->suggestedLatency; hostApiInputParameters.hostApiSpecificStreamInfo = inputParameters->hostApiSpecificStreamInfo; hostApiInputParametersPtr = &hostApiInputParameters; } else { hostApiInputParametersPtr = NULL; } if( outputParameters ) { hostApiOutputParameters.device = hostApiOutputDevice; hostApiOutputParameters.channelCount = outputParameters->channelCount; hostApiOutputParameters.sampleFormat = outputParameters->sampleFormat; hostApiOutputParameters.suggestedLatency = outputParameters->suggestedLatency; hostApiOutputParameters.hostApiSpecificStreamInfo = outputParameters->hostApiSpecificStreamInfo; hostApiOutputParametersPtr = &hostApiOutputParameters; } else { hostApiOutputParametersPtr = NULL; } result = hostApi->IsFormatSupported( hostApi, hostApiInputParametersPtr, hostApiOutputParametersPtr, sampleRate ); #ifdef PA_LOG_API_CALLS PA_LOGAPI(("Pa_OpenStream returned:\n" )); if( result == paFormatIsSupported ) PA_LOGAPI(("\tPaError: 0 [ paFormatIsSupported ]\n" )); else PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); #endif return result; } PaError Pa_OpenStream( PaStream** stream, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ) { PaError result; PaUtilHostApiRepresentation *hostApi = 0; PaDeviceIndex hostApiInputDevice = paNoDevice, hostApiOutputDevice = paNoDevice; PaStreamParameters hostApiInputParameters, hostApiOutputParameters; PaStreamParameters *hostApiInputParametersPtr, *hostApiOutputParametersPtr; #ifdef PA_LOG_API_CALLS PA_LOGAPI_ENTER_PARAMS( "Pa_OpenStream" ); PA_LOGAPI(("\tPaStream** stream: 0x%p\n", stream )); if( inputParameters == NULL ){ PA_LOGAPI(("\tPaStreamParameters *inputParameters: NULL\n" )); }else{ PA_LOGAPI(("\tPaStreamParameters *inputParameters: 0x%p\n", inputParameters )); PA_LOGAPI(("\tPaDeviceIndex inputParameters->device: %d\n", inputParameters->device )); PA_LOGAPI(("\tint inputParameters->channelCount: %d\n", inputParameters->channelCount )); PA_LOGAPI(("\tPaSampleFormat inputParameters->sampleFormat: %d\n", inputParameters->sampleFormat )); PA_LOGAPI(("\tPaTime inputParameters->suggestedLatency: %f\n", inputParameters->suggestedLatency )); PA_LOGAPI(("\tvoid *inputParameters->hostApiSpecificStreamInfo: 0x%p\n", inputParameters->hostApiSpecificStreamInfo )); } if( outputParameters == NULL ){ PA_LOGAPI(("\tPaStreamParameters *outputParameters: NULL\n" )); }else{ PA_LOGAPI(("\tPaStreamParameters *outputParameters: 0x%p\n", outputParameters )); PA_LOGAPI(("\tPaDeviceIndex outputParameters->device: %d\n", outputParameters->device )); PA_LOGAPI(("\tint outputParameters->channelCount: %d\n", outputParameters->channelCount )); PA_LOGAPI(("\tPaSampleFormat outputParameters->sampleFormat: %d\n", outputParameters->sampleFormat )); PA_LOGAPI(("\tPaTime outputParameters->suggestedLatency: %f\n", outputParameters->suggestedLatency )); PA_LOGAPI(("\tvoid *outputParameters->hostApiSpecificStreamInfo: 0x%p\n", outputParameters->hostApiSpecificStreamInfo )); } PA_LOGAPI(("\tdouble sampleRate: %g\n", sampleRate )); PA_LOGAPI(("\tunsigned long framesPerBuffer: %d\n", framesPerBuffer )); PA_LOGAPI(("\tPaStreamFlags streamFlags: 0x%x\n", streamFlags )); PA_LOGAPI(("\tPaStreamCallback *streamCallback: 0x%p\n", streamCallback )); PA_LOGAPI(("\tvoid *userData: 0x%p\n", userData )); #endif if( !PA_IS_INITIALISED_ ) { result = paNotInitialized; PA_LOGAPI(("Pa_OpenStream returned:\n" )); PA_LOGAPI(("\t*(PaStream** stream): undefined\n" )); PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); return result; } /* Check for parameter errors. NOTE: make sure this validation list is kept syncronised with the one in pa_hostapi.h */ if( stream == NULL ) { result = paBadStreamPtr; PA_LOGAPI(("Pa_OpenStream returned:\n" )); PA_LOGAPI(("\t*(PaStream** stream): undefined\n" )); PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); return result; } result = ValidateOpenStreamParameters( inputParameters, outputParameters, sampleRate, framesPerBuffer, streamFlags, streamCallback, &hostApi, &hostApiInputDevice, &hostApiOutputDevice ); if( result != paNoError ) { PA_LOGAPI(("Pa_OpenStream returned:\n" )); PA_LOGAPI(("\t*(PaStream** stream): undefined\n" )); PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); return result; } if( inputParameters ) { hostApiInputParameters.device = hostApiInputDevice; hostApiInputParameters.channelCount = inputParameters->channelCount; hostApiInputParameters.sampleFormat = inputParameters->sampleFormat; hostApiInputParameters.suggestedLatency = inputParameters->suggestedLatency; hostApiInputParameters.hostApiSpecificStreamInfo = inputParameters->hostApiSpecificStreamInfo; hostApiInputParametersPtr = &hostApiInputParameters; } else { hostApiInputParametersPtr = NULL; } if( outputParameters ) { hostApiOutputParameters.device = hostApiOutputDevice; hostApiOutputParameters.channelCount = outputParameters->channelCount; hostApiOutputParameters.sampleFormat = outputParameters->sampleFormat; hostApiOutputParameters.suggestedLatency = outputParameters->suggestedLatency; hostApiOutputParameters.hostApiSpecificStreamInfo = outputParameters->hostApiSpecificStreamInfo; hostApiOutputParametersPtr = &hostApiOutputParameters; } else { hostApiOutputParametersPtr = NULL; } result = hostApi->OpenStream( hostApi, stream, hostApiInputParametersPtr, hostApiOutputParametersPtr, sampleRate, framesPerBuffer, streamFlags, streamCallback, userData ); if( result == paNoError ) AddOpenStream( *stream ); PA_LOGAPI(("Pa_OpenStream returned:\n" )); PA_LOGAPI(("\t*(PaStream** stream): 0x%p\n", *stream )); PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); return result; } PaError Pa_OpenDefaultStream( PaStream** stream, int inputChannelCount, int outputChannelCount, PaSampleFormat sampleFormat, double sampleRate, unsigned long framesPerBuffer, PaStreamCallback *streamCallback, void *userData ) { PaError result; PaStreamParameters hostApiInputParameters, hostApiOutputParameters; PaStreamParameters *hostApiInputParametersPtr, *hostApiOutputParametersPtr; PA_LOGAPI_ENTER_PARAMS( "Pa_OpenDefaultStream" ); PA_LOGAPI(("\tPaStream** stream: 0x%p\n", stream )); PA_LOGAPI(("\tint inputChannelCount: %d\n", inputChannelCount )); PA_LOGAPI(("\tint outputChannelCount: %d\n", outputChannelCount )); PA_LOGAPI(("\tPaSampleFormat sampleFormat: %d\n", sampleFormat )); PA_LOGAPI(("\tdouble sampleRate: %g\n", sampleRate )); PA_LOGAPI(("\tunsigned long framesPerBuffer: %d\n", framesPerBuffer )); PA_LOGAPI(("\tPaStreamCallback *streamCallback: 0x%p\n", streamCallback )); PA_LOGAPI(("\tvoid *userData: 0x%p\n", userData )); if( inputChannelCount > 0 ) { hostApiInputParameters.device = Pa_GetDefaultInputDevice(); if( hostApiInputParameters.device == paNoDevice ) return paDeviceUnavailable; hostApiInputParameters.channelCount = inputChannelCount; hostApiInputParameters.sampleFormat = sampleFormat; /* defaultHighInputLatency is used below instead of defaultLowInputLatency because it is more important for the default stream to work reliably than it is for it to work with the lowest latency. */ hostApiInputParameters.suggestedLatency = Pa_GetDeviceInfo( hostApiInputParameters.device )->defaultHighInputLatency; hostApiInputParameters.hostApiSpecificStreamInfo = NULL; hostApiInputParametersPtr = &hostApiInputParameters; } else { hostApiInputParametersPtr = NULL; } if( outputChannelCount > 0 ) { hostApiOutputParameters.device = Pa_GetDefaultOutputDevice(); if( hostApiOutputParameters.device == paNoDevice ) return paDeviceUnavailable; hostApiOutputParameters.channelCount = outputChannelCount; hostApiOutputParameters.sampleFormat = sampleFormat; /* defaultHighOutputLatency is used below instead of defaultLowOutputLatency because it is more important for the default stream to work reliably than it is for it to work with the lowest latency. */ hostApiOutputParameters.suggestedLatency = Pa_GetDeviceInfo( hostApiOutputParameters.device )->defaultHighOutputLatency; hostApiOutputParameters.hostApiSpecificStreamInfo = NULL; hostApiOutputParametersPtr = &hostApiOutputParameters; } else { hostApiOutputParametersPtr = NULL; } result = Pa_OpenStream( stream, hostApiInputParametersPtr, hostApiOutputParametersPtr, sampleRate, framesPerBuffer, paNoFlag, streamCallback, userData ); PA_LOGAPI(("Pa_OpenDefaultStream returned:\n" )); PA_LOGAPI(("\t*(PaStream** stream): 0x%p", *stream )); PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); return result; } PaError PaUtil_ValidateStreamPointer( PaStream* stream ) { if( !PA_IS_INITIALISED_ ) return paNotInitialized; if( stream == NULL ) return paBadStreamPtr; if( ((PaUtilStreamRepresentation*)stream)->magic != PA_STREAM_MAGIC ) return paBadStreamPtr; return paNoError; } PaError Pa_CloseStream( PaStream* stream ) { PaUtilStreamInterface *interface; PaError result = PaUtil_ValidateStreamPointer( stream ); PA_LOGAPI_ENTER_PARAMS( "Pa_CloseStream" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); /* always remove the open stream from our list, even if this function eventually returns an error. Otherwise CloseOpenStreams() will get stuck in an infinite loop */ RemoveOpenStream( stream ); /* be sure to call this _before_ closing the stream */ if( result == paNoError ) { interface = PA_STREAM_INTERFACE(stream); /* abort the stream if it isn't stopped */ result = interface->IsStopped( stream ); if( result == 1 ) result = paNoError; else if( result == 0 ) result = interface->Abort( stream ); if( result == paNoError ) /** @todo REVIEW: shouldn't we close anyway? see: http://www.portaudio.com/trac/ticket/115 */ result = interface->Close( stream ); } PA_LOGAPI_EXIT_PAERROR( "Pa_CloseStream", result ); return result; } PaError Pa_SetStreamFinishedCallback( PaStream *stream, PaStreamFinishedCallback* streamFinishedCallback ) { PaError result = PaUtil_ValidateStreamPointer( stream ); PA_LOGAPI_ENTER_PARAMS( "Pa_SetStreamFinishedCallback" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); PA_LOGAPI(("\tPaStreamFinishedCallback* streamFinishedCallback: 0x%p\n", streamFinishedCallback )); if( result == paNoError ) { result = PA_STREAM_INTERFACE(stream)->IsStopped( stream ); if( result == 0 ) { result = paStreamIsNotStopped ; } if( result == 1 ) { PA_STREAM_REP( stream )->streamFinishedCallback = streamFinishedCallback; result = paNoError; } } PA_LOGAPI_EXIT_PAERROR( "Pa_SetStreamFinishedCallback", result ); return result; } PaError Pa_StartStream( PaStream *stream ) { PaError result = PaUtil_ValidateStreamPointer( stream ); PA_LOGAPI_ENTER_PARAMS( "Pa_StartStream" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( result == paNoError ) { result = PA_STREAM_INTERFACE(stream)->IsStopped( stream ); if( result == 0 ) { result = paStreamIsNotStopped ; } else if( result == 1 ) { result = PA_STREAM_INTERFACE(stream)->Start( stream ); } } PA_LOGAPI_EXIT_PAERROR( "Pa_StartStream", result ); return result; } PaError Pa_StopStream( PaStream *stream ) { PaError result = PaUtil_ValidateStreamPointer( stream ); PA_LOGAPI_ENTER_PARAMS( "Pa_StopStream" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( result == paNoError ) { result = PA_STREAM_INTERFACE(stream)->IsStopped( stream ); if( result == 0 ) { result = PA_STREAM_INTERFACE(stream)->Stop( stream ); } else if( result == 1 ) { result = paStreamIsStopped; } } PA_LOGAPI_EXIT_PAERROR( "Pa_StopStream", result ); return result; } PaError Pa_AbortStream( PaStream *stream ) { PaError result = PaUtil_ValidateStreamPointer( stream ); PA_LOGAPI_ENTER_PARAMS( "Pa_AbortStream" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( result == paNoError ) { result = PA_STREAM_INTERFACE(stream)->IsStopped( stream ); if( result == 0 ) { result = PA_STREAM_INTERFACE(stream)->Abort( stream ); } else if( result == 1 ) { result = paStreamIsStopped; } } PA_LOGAPI_EXIT_PAERROR( "Pa_AbortStream", result ); return result; } PaError Pa_IsStreamStopped( PaStream *stream ) { PaError result = PaUtil_ValidateStreamPointer( stream ); PA_LOGAPI_ENTER_PARAMS( "Pa_IsStreamStopped" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( result == paNoError ) result = PA_STREAM_INTERFACE(stream)->IsStopped( stream ); PA_LOGAPI_EXIT_PAERROR( "Pa_IsStreamStopped", result ); return result; } PaError Pa_IsStreamActive( PaStream *stream ) { PaError result = PaUtil_ValidateStreamPointer( stream ); PA_LOGAPI_ENTER_PARAMS( "Pa_IsStreamActive" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( result == paNoError ) result = PA_STREAM_INTERFACE(stream)->IsActive( stream ); PA_LOGAPI_EXIT_PAERROR( "Pa_IsStreamActive", result ); return result; } const PaStreamInfo* Pa_GetStreamInfo( PaStream *stream ) { PaError error = PaUtil_ValidateStreamPointer( stream ); const PaStreamInfo *result; PA_LOGAPI_ENTER_PARAMS( "Pa_GetStreamInfo" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( error != paNoError ) { result = 0; PA_LOGAPI(("Pa_GetStreamInfo returned:\n" )); PA_LOGAPI(("\tconst PaStreamInfo*: 0 [PaError error:%d ( %s )]\n", error, Pa_GetErrorText( error ) )); } else { result = &PA_STREAM_REP( stream )->streamInfo; PA_LOGAPI(("Pa_GetStreamInfo returned:\n" )); PA_LOGAPI(("\tconst PaStreamInfo*: 0x%p:\n", result )); PA_LOGAPI(("\t{" )); PA_LOGAPI(("\t\tint structVersion: %d\n", result->structVersion )); PA_LOGAPI(("\t\tPaTime inputLatency: %f\n", result->inputLatency )); PA_LOGAPI(("\t\tPaTime outputLatency: %f\n", result->outputLatency )); PA_LOGAPI(("\t\tdouble sampleRate: %f\n", result->sampleRate )); PA_LOGAPI(("\t}\n" )); } return result; } PaTime Pa_GetStreamTime( PaStream *stream ) { PaError error = PaUtil_ValidateStreamPointer( stream ); PaTime result; PA_LOGAPI_ENTER_PARAMS( "Pa_GetStreamTime" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( error != paNoError ) { result = 0; PA_LOGAPI(("Pa_GetStreamTime returned:\n" )); PA_LOGAPI(("\tPaTime: 0 [PaError error:%d ( %s )]\n", result, error, Pa_GetErrorText( error ) )); } else { result = PA_STREAM_INTERFACE(stream)->GetTime( stream ); PA_LOGAPI(("Pa_GetStreamTime returned:\n" )); PA_LOGAPI(("\tPaTime: %g\n", result )); } return result; } double Pa_GetStreamCpuLoad( PaStream* stream ) { PaError error = PaUtil_ValidateStreamPointer( stream ); double result; PA_LOGAPI_ENTER_PARAMS( "Pa_GetStreamCpuLoad" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( error != paNoError ) { result = 0.0; PA_LOGAPI(("Pa_GetStreamCpuLoad returned:\n" )); PA_LOGAPI(("\tdouble: 0.0 [PaError error: %d ( %s )]\n", error, Pa_GetErrorText( error ) )); } else { result = PA_STREAM_INTERFACE(stream)->GetCpuLoad( stream ); PA_LOGAPI(("Pa_GetStreamCpuLoad returned:\n" )); PA_LOGAPI(("\tdouble: %g\n", result )); } return result; } PaError Pa_ReadStream( PaStream* stream, void *buffer, unsigned long frames ) { PaError result = PaUtil_ValidateStreamPointer( stream ); PA_LOGAPI_ENTER_PARAMS( "Pa_ReadStream" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( result == paNoError ) { if( frames == 0 ) { /* @todo Should we not allow the implementation to signal any overflow condition? see: http://www.portaudio.com/trac/ticket/116*/ result = paNoError; } else if( buffer == 0 ) { result = paBadBufferPtr; } else { result = PA_STREAM_INTERFACE(stream)->IsStopped( stream ); if( result == 0 ) { result = PA_STREAM_INTERFACE(stream)->Read( stream, buffer, frames ); } else if( result == 1 ) { result = paStreamIsStopped; } } } PA_LOGAPI_EXIT_PAERROR( "Pa_ReadStream", result ); return result; } PaError Pa_WriteStream( PaStream* stream, const void *buffer, unsigned long frames ) { PaError result = PaUtil_ValidateStreamPointer( stream ); PA_LOGAPI_ENTER_PARAMS( "Pa_WriteStream" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( result == paNoError ) { if( frames == 0 ) { /* @todo Should we not allow the implementation to signal any underflow condition? see: http://www.portaudio.com/trac/ticket/116*/ result = paNoError; } else if( buffer == 0 ) { result = paBadBufferPtr; } else { result = PA_STREAM_INTERFACE(stream)->IsStopped( stream ); if( result == 0 ) { result = PA_STREAM_INTERFACE(stream)->Write( stream, buffer, frames ); } else if( result == 1 ) { result = paStreamIsStopped; } } } PA_LOGAPI_EXIT_PAERROR( "Pa_WriteStream", result ); return result; } signed long Pa_GetStreamReadAvailable( PaStream* stream ) { PaError error = PaUtil_ValidateStreamPointer( stream ); signed long result; PA_LOGAPI_ENTER_PARAMS( "Pa_GetStreamReadAvailable" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( error != paNoError ) { result = 0; PA_LOGAPI(("Pa_GetStreamReadAvailable returned:\n" )); PA_LOGAPI(("\tunsigned long: 0 [ PaError error: %d ( %s ) ]\n", error, Pa_GetErrorText( error ) )); } else { result = PA_STREAM_INTERFACE(stream)->GetReadAvailable( stream ); PA_LOGAPI(("Pa_GetStreamReadAvailable returned:\n" )); PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); } return result; } signed long Pa_GetStreamWriteAvailable( PaStream* stream ) { PaError error = PaUtil_ValidateStreamPointer( stream ); signed long result; PA_LOGAPI_ENTER_PARAMS( "Pa_GetStreamWriteAvailable" ); PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); if( error != paNoError ) { result = 0; PA_LOGAPI(("Pa_GetStreamWriteAvailable returned:\n" )); PA_LOGAPI(("\tunsigned long: 0 [ PaError error: %d ( %s ) ]\n", error, Pa_GetErrorText( error ) )); } else { result = PA_STREAM_INTERFACE(stream)->GetWriteAvailable( stream ); PA_LOGAPI(("Pa_GetStreamWriteAvailable returned:\n" )); PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); } return result; } PaError Pa_GetSampleSize( PaSampleFormat format ) { int result; PA_LOGAPI_ENTER_PARAMS( "Pa_GetSampleSize" ); PA_LOGAPI(("\tPaSampleFormat format: %d\n", format )); switch( format & ~paNonInterleaved ) { case paUInt8: case paInt8: result = 1; break; case paInt16: result = 2; break; case paInt24: result = 3; break; case paFloat32: case paInt32: result = 4; break; default: result = paSampleFormatNotSupported; break; } PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_GetSampleSize", "int: %d", result ); return (PaError) result; } pd-0.46-7/portaudio/src/common/pa_debugprint.h0000664000175000017500000001166112160204055017455 0ustar mspmsp#ifndef PA_LOG_H #define PA_LOG_H /* * Log file redirector function * Copyright (c) 1999-2006 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ void PaUtil_DebugPrint( const char *format, ... ); /* The basic format for log messages is described below. If you need to add any log messages, please follow this format. Function entry (void function): "FunctionName called.\n" Function entry (non void function): "FunctionName called:\n" "\tParam1Type param1: param1Value\n" "\tParam2Type param2: param2Value\n" (etc...) Function exit (no return value): "FunctionName returned.\n" Function exit (simple return value): "FunctionName returned:\n" "\tReturnType: returnValue\n" If the return type is an error code, the error text is displayed in () If the return type is not an error code, but has taken a special value because an error occurred, then the reason for the error is shown in [] If the return type is a struct ptr, the struct is dumped. See the code below for examples */ /** PA_DEBUG() provides a simple debug message printing facility. The macro passes it's argument to a printf-like function called PaUtil_DebugPrint() which prints to stderr and always flushes the stream after printing. Because preprocessor macros cannot directly accept variable length argument lists, calls to the macro must include an additional set of parenthesis, eg: PA_DEBUG(("errorno: %d", 1001 )); */ #ifdef PA_ENABLE_DEBUG_OUTPUT #define PA_DEBUG(x) PaUtil_DebugPrint x ; #else #define PA_DEBUG(x) #endif #ifdef PA_LOG_API_CALLS #define PA_LOGAPI(x) PaUtil_DebugPrint x #define PA_LOGAPI_ENTER(functionName) PaUtil_DebugPrint( functionName " called.\n" ) #define PA_LOGAPI_ENTER_PARAMS(functionName) PaUtil_DebugPrint( functionName " called:\n" ) #define PA_LOGAPI_EXIT(functionName) PaUtil_DebugPrint( functionName " returned.\n" ) #define PA_LOGAPI_EXIT_PAERROR( functionName, result ) \ PaUtil_DebugPrint( functionName " returned:\n" ); \ PaUtil_DebugPrint("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) ) #define PA_LOGAPI_EXIT_T( functionName, resultFormatString, result ) \ PaUtil_DebugPrint( functionName " returned:\n" ); \ PaUtil_DebugPrint("\t" resultFormatString "\n", result ) #define PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( functionName, positiveResultFormatString, result ) \ PaUtil_DebugPrint( functionName " returned:\n" ); \ if( result > 0 ) \ PaUtil_DebugPrint("\t" positiveResultFormatString "\n", result ); \ else \ PaUtil_DebugPrint("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) ) #else #define PA_LOGAPI(x) #define PA_LOGAPI_ENTER(functionName) #define PA_LOGAPI_ENTER_PARAMS(functionName) #define PA_LOGAPI_EXIT(functionName) #define PA_LOGAPI_EXIT_PAERROR( functionName, result ) #define PA_LOGAPI_EXIT_T( functionName, resultFormatString, result ) #define PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( functionName, positiveResultFormatString, result ) #endif typedef void (*PaUtilLogCallback ) (const char *log); /** Install user provided log function */ void PaUtil_SetDebugPrintFunction(PaUtilLogCallback cb); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_LOG_H */ pd-0.46-7/portaudio/src/common/pa_cpuload.h0000664000175000017500000000523712160204055016743 0ustar mspmsp#ifndef PA_CPULOAD_H #define PA_CPULOAD_H /* * $Id: pa_cpuload.h 1097 2006-08-26 08:27:53Z rossb $ * Portable Audio I/O Library CPU Load measurement functions * Portable CPU load measurement facility. * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 2002 Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Functions to assist in measuring the CPU utilization of a callback stream. Used to implement the Pa_GetStreamCpuLoad() function. */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ typedef struct { double samplingPeriod; double measurementStartTime; double averageLoad; } PaUtilCpuLoadMeasurer; /**< @todo need better name than measurer */ void PaUtil_InitializeCpuLoadMeasurer( PaUtilCpuLoadMeasurer* measurer, double sampleRate ); void PaUtil_BeginCpuLoadMeasurement( PaUtilCpuLoadMeasurer* measurer ); void PaUtil_EndCpuLoadMeasurement( PaUtilCpuLoadMeasurer* measurer, unsigned long framesProcessed ); void PaUtil_ResetCpuLoadMeasurer( PaUtilCpuLoadMeasurer* measurer ); double PaUtil_GetCpuLoad( PaUtilCpuLoadMeasurer* measurer ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_CPULOAD_H */ pd-0.46-7/portaudio/src/common/pa_converters.h0000664000175000017500000002376012160204055017507 0ustar mspmsp#ifndef PA_CONVERTERS_H #define PA_CONVERTERS_H /* * $Id: pa_converters.h 1097 2006-08-26 08:27:53Z rossb $ * Portable Audio I/O Library sample conversion mechanism * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Phil Burk, Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Conversion functions used to convert buffers of samples from one format to another. */ #include "portaudio.h" /* for PaSampleFormat */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ struct PaUtilTriangularDitherGenerator; /** Choose an available sample format which is most appropriate for representing the requested format. If the requested format is not available higher quality formats are considered before lower quality formates. @param availableFormats A variable containing the logical OR of all available formats. @param format The desired format. @return The most appropriate available format for representing the requested format. */ PaSampleFormat PaUtil_SelectClosestAvailableFormat( PaSampleFormat availableFormats, PaSampleFormat format ); /* high level conversions functions for use by implementations */ /** The generic sample converter prototype. Sample converters convert count samples from sourceBuffer to destinationBuffer. The actual type of the data pointed to by these parameters varys for different converter functions. @param destinationBuffer A pointer to the first sample of the destination. @param destinationStride An offset between successive destination samples expressed in samples (not bytes.) It may be negative. @param sourceBuffer A pointer to the first sample of the source. @param sourceStride An offset between successive source samples expressed in samples (not bytes.) It may be negative. @param count The number of samples to convert. @param ditherState State information used to calculate dither. Converters that do not perform dithering will ignore this parameter, in which case NULL or invalid dither state may be passed. */ typedef void PaUtilConverter( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ); /** Find a sample converter function for the given source and destinations formats and flags (clip and dither.) @return A pointer to a PaUtilConverter which will perform the requested conversion, or NULL if the given format conversion is not supported. For conversions where clipping or dithering is not necessary, the clip and dither flags are ignored and a non-clipping or dithering version is returned. If the source and destination formats are the same, a function which copies data of the appropriate size will be returned. */ PaUtilConverter* PaUtil_SelectConverter( PaSampleFormat sourceFormat, PaSampleFormat destinationFormat, PaStreamFlags flags ); /** The generic buffer zeroer prototype. Buffer zeroers copy count zeros to destinationBuffer. The actual type of the data pointed to varys for different zeroer functions. @param destinationBuffer A pointer to the first sample of the destination. @param destinationStride An offset between successive destination samples expressed in samples (not bytes.) It may be negative. @param count The number of samples to zero. */ typedef void PaUtilZeroer( void *destinationBuffer, signed int destinationStride, unsigned int count ); /** Find a buffer zeroer function for the given destination format. @return A pointer to a PaUtilZeroer which will perform the requested zeroing. */ PaUtilZeroer* PaUtil_SelectZeroer( PaSampleFormat destinationFormat ); /*----------------------------------------------------------------------------*/ /* low level functions and data structures which may be used for substituting conversion functions */ /** The type used to store all sample conversion functions. @see paConverters; */ typedef struct{ PaUtilConverter *Float32_To_Int32; PaUtilConverter *Float32_To_Int32_Dither; PaUtilConverter *Float32_To_Int32_Clip; PaUtilConverter *Float32_To_Int32_DitherClip; PaUtilConverter *Float32_To_Int24; PaUtilConverter *Float32_To_Int24_Dither; PaUtilConverter *Float32_To_Int24_Clip; PaUtilConverter *Float32_To_Int24_DitherClip; PaUtilConverter *Float32_To_Int16; PaUtilConverter *Float32_To_Int16_Dither; PaUtilConverter *Float32_To_Int16_Clip; PaUtilConverter *Float32_To_Int16_DitherClip; PaUtilConverter *Float32_To_Int8; PaUtilConverter *Float32_To_Int8_Dither; PaUtilConverter *Float32_To_Int8_Clip; PaUtilConverter *Float32_To_Int8_DitherClip; PaUtilConverter *Float32_To_UInt8; PaUtilConverter *Float32_To_UInt8_Dither; PaUtilConverter *Float32_To_UInt8_Clip; PaUtilConverter *Float32_To_UInt8_DitherClip; PaUtilConverter *Int32_To_Float32; PaUtilConverter *Int32_To_Int24; PaUtilConverter *Int32_To_Int24_Dither; PaUtilConverter *Int32_To_Int16; PaUtilConverter *Int32_To_Int16_Dither; PaUtilConverter *Int32_To_Int8; PaUtilConverter *Int32_To_Int8_Dither; PaUtilConverter *Int32_To_UInt8; PaUtilConverter *Int32_To_UInt8_Dither; PaUtilConverter *Int24_To_Float32; PaUtilConverter *Int24_To_Int32; PaUtilConverter *Int24_To_Int16; PaUtilConverter *Int24_To_Int16_Dither; PaUtilConverter *Int24_To_Int8; PaUtilConverter *Int24_To_Int8_Dither; PaUtilConverter *Int24_To_UInt8; PaUtilConverter *Int24_To_UInt8_Dither; PaUtilConverter *Int16_To_Float32; PaUtilConverter *Int16_To_Int32; PaUtilConverter *Int16_To_Int24; PaUtilConverter *Int16_To_Int8; PaUtilConverter *Int16_To_Int8_Dither; PaUtilConverter *Int16_To_UInt8; PaUtilConverter *Int16_To_UInt8_Dither; PaUtilConverter *Int8_To_Float32; PaUtilConverter *Int8_To_Int32; PaUtilConverter *Int8_To_Int24; PaUtilConverter *Int8_To_Int16; PaUtilConverter *Int8_To_UInt8; PaUtilConverter *UInt8_To_Float32; PaUtilConverter *UInt8_To_Int32; PaUtilConverter *UInt8_To_Int24; PaUtilConverter *UInt8_To_Int16; PaUtilConverter *UInt8_To_Int8; PaUtilConverter *Copy_8_To_8; /* copy without any conversion */ PaUtilConverter *Copy_16_To_16; /* copy without any conversion */ PaUtilConverter *Copy_24_To_24; /* copy without any conversion */ PaUtilConverter *Copy_32_To_32; /* copy without any conversion */ } PaUtilConverterTable; /** A table of pointers to all required converter functions. PaUtil_SelectConverter() uses this table to lookup the appropriate conversion functions. The fields of this structure are initialized with default conversion functions. Fields may be NULL, indicating that no conversion function is available. User code may substitue optimised conversion functions by assigning different function pointers to these fields. @note If the PA_NO_STANDARD_CONVERTERS preprocessor variable is defined, PortAudio's standard converters will not be compiled, and all fields of this structure will be initialized to NULL. In such cases, users should supply their own conversion functions if the require PortAudio to open a stream that requires sample conversion. @see PaUtilConverterTable, PaUtilConverter, PaUtil_SelectConverter */ extern PaUtilConverterTable paConverters; /** The type used to store all buffer zeroing functions. @see paZeroers; */ typedef struct{ PaUtilZeroer *ZeroU8; /* unsigned 8 bit, zero == 128 */ PaUtilZeroer *Zero8; PaUtilZeroer *Zero16; PaUtilZeroer *Zero24; PaUtilZeroer *Zero32; } PaUtilZeroerTable; /** A table of pointers to all required zeroer functions. PaUtil_SelectZeroer() uses this table to lookup the appropriate conversion functions. The fields of this structure are initialized with default conversion functions. User code may substitue optimised conversion functions by assigning different function pointers to these fields. @note If the PA_NO_STANDARD_ZEROERS preprocessor variable is defined, PortAudio's standard zeroers will not be compiled, and all fields of this structure will be initialized to NULL. In such cases, users should supply their own zeroing functions for the sample sizes which they intend to use. @see PaUtilZeroerTable, PaUtilZeroer, PaUtil_SelectZeroer */ extern PaUtilZeroerTable paZeroers; #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_CONVERTERS_H */ pd-0.46-7/portaudio/src/common/pa_hostapi.h0000664000175000017500000003207112374245151016770 0ustar mspmsp#ifndef PA_HOSTAPI_H #define PA_HOSTAPI_H /* * $Id: pa_hostapi.h 1880 2012-12-04 18:39:48Z rbencina $ * Portable Audio I/O Library * host api representation * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2008 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Interfaces and representation structures used by pa_front.c to manage and communicate with host API implementations. */ #include "portaudio.h" /** The PA_NO_* host API macros are now deprecated in favor of PA_USE_* macros. PA_USE_* indicates whether a particular host API will be initialized by PortAudio. An undefined or 0 value indicates that the host API will not be used. A value of 1 indicates that the host API will be used. PA_USE_* macros should be left undefined or defined to either 0 or 1. The code below ensures that PA_USE_* macros are always defined and have value 0 or 1. Undefined symbols are defaulted to 0. Symbols that are neither 0 nor 1 are defaulted to 1. */ #ifndef PA_USE_SKELETON #define PA_USE_SKELETON 0 #elif (PA_USE_SKELETON != 0) && (PA_USE_SKELETON != 1) #undef PA_USE_SKELETON #define PA_USE_SKELETON 1 #endif #if defined(PA_NO_ASIO) || defined(PA_NO_DS) || defined(PA_NO_WMME) || defined(PA_NO_WASAPI) || defined(PA_NO_WDMKS) #error "Portaudio: PA_NO_ is no longer supported, please remove definition and use PA_USE_ instead" #endif #ifndef PA_USE_ASIO #define PA_USE_ASIO 0 #elif (PA_USE_ASIO != 0) && (PA_USE_ASIO != 1) #undef PA_USE_ASIO #define PA_USE_ASIO 1 #endif #ifndef PA_USE_DS #define PA_USE_DS 0 #elif (PA_USE_DS != 0) && (PA_USE_DS != 1) #undef PA_USE_DS #define PA_USE_DS 1 #endif #ifndef PA_USE_WMME #define PA_USE_WMME 0 #elif (PA_USE_WMME != 0) && (PA_USE_WMME != 1) #undef PA_USE_WMME #define PA_USE_WMME 1 #endif #ifndef PA_USE_WASAPI #define PA_USE_WASAPI 0 #elif (PA_USE_WASAPI != 0) && (PA_USE_WASAPI != 1) #undef PA_USE_WASAPI #define PA_USE_WASAPI 1 #endif #ifndef PA_USE_WDMKS #define PA_USE_WDMKS 0 #elif (PA_USE_WDMKS != 0) && (PA_USE_WDMKS != 1) #undef PA_USE_WDMKS #define PA_USE_WDMKS 1 #endif /* Set default values for Unix based APIs. */ #if defined(PA_NO_OSS) || defined(PA_NO_ALSA) || defined(PA_NO_JACK) || defined(PA_NO_COREAUDIO) || defined(PA_NO_SGI) || defined(PA_NO_ASIHPI) #error "Portaudio: PA_NO_ is no longer supported, please remove definition and use PA_USE_ instead" #endif #ifndef PA_USE_OSS #define PA_USE_OSS 0 #elif (PA_USE_OSS != 0) && (PA_USE_OSS != 1) #undef PA_USE_OSS #define PA_USE_OSS 1 #endif #ifndef PA_USE_ALSA #define PA_USE_ALSA 0 #elif (PA_USE_ALSA != 0) && (PA_USE_ALSA != 1) #undef PA_USE_ALSA #define PA_USE_ALSA 1 #endif #ifndef PA_USE_JACK #define PA_USE_JACK 0 #elif (PA_USE_JACK != 0) && (PA_USE_JACK != 1) #undef PA_USE_JACK #define PA_USE_JACK 1 #endif #ifndef PA_USE_SGI #define PA_USE_SGI 0 #elif (PA_USE_SGI != 0) && (PA_USE_SGI != 1) #undef PA_USE_SGI #define PA_USE_SGI 1 #endif #ifndef PA_USE_COREAUDIO #define PA_USE_COREAUDIO 0 #elif (PA_USE_COREAUDIO != 0) && (PA_USE_COREAUDIO != 1) #undef PA_USE_COREAUDIO #define PA_USE_COREAUDIO 1 #endif #ifndef PA_USE_ASIHPI #define PA_USE_ASIHPI 0 #elif (PA_USE_ASIHPI != 0) && (PA_USE_ASIHPI != 1) #undef PA_USE_ASIHPI #define PA_USE_ASIHPI 1 #endif #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** **FOR THE USE OF pa_front.c ONLY** Do NOT use fields in this structure, they my change at any time. Use functions defined in pa_util.h if you think you need functionality which can be derived from here. */ typedef struct PaUtilPrivatePaFrontHostApiInfo { unsigned long baseDeviceIndex; }PaUtilPrivatePaFrontHostApiInfo; /** The common header for all data structures whose pointers are passed through the hostApiSpecificStreamInfo field of the PaStreamParameters structure. Note that in order to keep the public PortAudio interface clean, this structure is not used explicitly when declaring hostApiSpecificStreamInfo data structures. However, some code in pa_front depends on the first 3 members being equivalent with this structure. @see PaStreamParameters */ typedef struct PaUtilHostApiSpecificStreamInfoHeader { unsigned long size; /**< size of whole structure including this header */ PaHostApiTypeId hostApiType; /**< host API for which this data is intended */ unsigned long version; /**< structure version */ } PaUtilHostApiSpecificStreamInfoHeader; /** A structure representing the interface to a host API. Contains both concrete data and pointers to functions which implement the interface. */ typedef struct PaUtilHostApiRepresentation { PaUtilPrivatePaFrontHostApiInfo privatePaFrontInfo; /** The host api implementation should populate the info field. In the case of info.defaultInputDevice and info.defaultOutputDevice the values stored should be 0 based indices within the host api's own device index range (0 to deviceCount). These values will be converted to global device indices by pa_front after PaUtilHostApiInitializer() returns. */ PaHostApiInfo info; PaDeviceInfo** deviceInfos; /** (*Terminate)() is guaranteed to be called with a valid parameter, which was previously returned from the same implementation's initializer. */ void (*Terminate)( struct PaUtilHostApiRepresentation *hostApi ); /** The inputParameters and outputParameters pointers should not be saved as they will not remain valid after OpenStream is called. The following guarantees are made about parameters to (*OpenStream)(): [NOTE: the following list up to *END PA FRONT VALIDATIONS* should be kept in sync with the one for ValidateOpenStreamParameters and Pa_OpenStream in pa_front.c] PaHostApiRepresentation *hostApi - is valid for this implementation PaStream** stream - is non-null - at least one of inputParameters & outputParmeters is valid (not NULL) - if inputParameters & outputParmeters are both valid, that inputParameters->device & outputParmeters->device both use the same host api PaDeviceIndex inputParameters->device - is within range (0 to Pa_CountDevices-1) Or: - is paUseHostApiSpecificDeviceSpecification and inputParameters->hostApiSpecificStreamInfo is non-NULL and refers to a valid host api int inputParameters->numChannels - if inputParameters->device is not paUseHostApiSpecificDeviceSpecification, numInputChannels is > 0 - upper bound is NOT validated against device capabilities PaSampleFormat inputParameters->sampleFormat - is one of the sample formats defined in portaudio.h void *inputParameters->hostApiSpecificStreamInfo - if supplied its hostApi field matches the input device's host Api PaDeviceIndex outputParmeters->device - is within range (0 to Pa_CountDevices-1) int outputParmeters->numChannels - if inputDevice is valid, numInputChannels is > 0 - upper bound is NOT validated against device capabilities PaSampleFormat outputParmeters->sampleFormat - is one of the sample formats defined in portaudio.h void *outputParmeters->hostApiSpecificStreamInfo - if supplied its hostApi field matches the output device's host Api double sampleRate - is not an 'absurd' rate (less than 1000. or greater than 384000.) - sampleRate is NOT validated against device capabilities PaStreamFlags streamFlags - unused platform neutral flags are zero - paNeverDropInput is only used for full-duplex callback streams with variable buffer size (paFramesPerBufferUnspecified) [*END PA FRONT VALIDATIONS*] The following validations MUST be performed by (*OpenStream)(): - check that input device can support numInputChannels - check that input device can support inputSampleFormat, or that we have the capability to convert from outputSampleFormat to a native format - if inputStreamInfo is supplied, validate its contents, or return an error if no inputStreamInfo is expected - check that output device can support numOutputChannels - check that output device can support outputSampleFormat, or that we have the capability to convert from outputSampleFormat to a native format - if outputStreamInfo is supplied, validate its contents, or return an error if no outputStreamInfo is expected - if a full duplex stream is requested, check that the combination of input and output parameters is supported - check that the device supports sampleRate - alter sampleRate to a close allowable rate if necessary - validate inputLatency and outputLatency - validate any platform specific flags, if flags are supplied they must be valid. */ PaError (*OpenStream)( struct PaUtilHostApiRepresentation *hostApi, PaStream** stream, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerCallback, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ); PaError (*IsFormatSupported)( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ); } PaUtilHostApiRepresentation; /** Prototype for the initialization function which must be implemented by every host API. This function should only return an error other than paNoError if it encounters an unexpected and fatal error (memory allocation error for example). In general, there may be conditions under which it returns a NULL interface pointer and also returns paNoError. For example, if the ASIO implementation detects that ASIO is not installed, it should return a NULL interface, and paNoError. @see paHostApiInitializers */ typedef PaError PaUtilHostApiInitializer( PaUtilHostApiRepresentation**, PaHostApiIndex ); /** paHostApiInitializers is a NULL-terminated array of host API initialization functions. These functions are called by pa_front.c to initialize the host APIs when the client calls Pa_Initialize(). The initialization functions are invoked in order. The first successfully initialized host API that has a default input *or* output device is used as the default PortAudio host API. This is based on the logic that there is only one default host API, and it must contain the default input and output devices (if defined). There is a platform specific file that defines paHostApiInitializers for that platform, pa_win/pa_win_hostapis.c contains the Win32 definitions for example. */ extern PaUtilHostApiInitializer *paHostApiInitializers[]; #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_HOSTAPI_H */ pd-0.46-7/portaudio/src/common/pa_stream.c0000664000175000017500000001236012160204055016575 0ustar mspmsp/* * $Id: pa_stream.c 1339 2008-02-15 07:50:33Z rossb $ * Portable Audio I/O Library * stream interface * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 2008 Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Stream interfaces, representation structures and helper functions used to interface between pa_front.c host API implementations. */ #include "pa_stream.h" void PaUtil_InitializeStreamInterface( PaUtilStreamInterface *streamInterface, PaError (*Close)( PaStream* ), PaError (*Start)( PaStream* ), PaError (*Stop)( PaStream* ), PaError (*Abort)( PaStream* ), PaError (*IsStopped)( PaStream* ), PaError (*IsActive)( PaStream* ), PaTime (*GetTime)( PaStream* ), double (*GetCpuLoad)( PaStream* ), PaError (*Read)( PaStream*, void *, unsigned long ), PaError (*Write)( PaStream*, const void *, unsigned long ), signed long (*GetReadAvailable)( PaStream* ), signed long (*GetWriteAvailable)( PaStream* ) ) { streamInterface->Close = Close; streamInterface->Start = Start; streamInterface->Stop = Stop; streamInterface->Abort = Abort; streamInterface->IsStopped = IsStopped; streamInterface->IsActive = IsActive; streamInterface->GetTime = GetTime; streamInterface->GetCpuLoad = GetCpuLoad; streamInterface->Read = Read; streamInterface->Write = Write; streamInterface->GetReadAvailable = GetReadAvailable; streamInterface->GetWriteAvailable = GetWriteAvailable; } void PaUtil_InitializeStreamRepresentation( PaUtilStreamRepresentation *streamRepresentation, PaUtilStreamInterface *streamInterface, PaStreamCallback *streamCallback, void *userData ) { streamRepresentation->magic = PA_STREAM_MAGIC; streamRepresentation->nextOpenStream = 0; streamRepresentation->streamInterface = streamInterface; streamRepresentation->streamCallback = streamCallback; streamRepresentation->streamFinishedCallback = 0; streamRepresentation->userData = userData; streamRepresentation->streamInfo.inputLatency = 0.; streamRepresentation->streamInfo.outputLatency = 0.; streamRepresentation->streamInfo.sampleRate = 0.; } void PaUtil_TerminateStreamRepresentation( PaUtilStreamRepresentation *streamRepresentation ) { streamRepresentation->magic = 0; } PaError PaUtil_DummyRead( PaStream* stream, void *buffer, unsigned long frames ) { (void)stream; /* unused parameter */ (void)buffer; /* unused parameter */ (void)frames; /* unused parameter */ return paCanNotReadFromACallbackStream; } PaError PaUtil_DummyWrite( PaStream* stream, const void *buffer, unsigned long frames ) { (void)stream; /* unused parameter */ (void)buffer; /* unused parameter */ (void)frames; /* unused parameter */ return paCanNotWriteToACallbackStream; } signed long PaUtil_DummyGetReadAvailable( PaStream* stream ) { (void)stream; /* unused parameter */ return paCanNotReadFromACallbackStream; } signed long PaUtil_DummyGetWriteAvailable( PaStream* stream ) { (void)stream; /* unused parameter */ return paCanNotWriteToACallbackStream; } double PaUtil_DummyGetCpuLoad( PaStream* stream ) { (void)stream; /* unused parameter */ return 0.0; } pd-0.46-7/portaudio/src/common/pa_cpuload.c0000664000175000017500000000743312222201037016732 0ustar mspmsp/* * $Id: pa_cpuload.c 1577 2011-02-01 13:03:45Z rossb $ * Portable Audio I/O Library CPU Load measurement functions * Portable CPU load measurement facility. * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 2002 Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Functions to assist in measuring the CPU utilization of a callback stream. Used to implement the Pa_GetStreamCpuLoad() function. @todo Dynamically calculate the coefficients used to smooth the CPU Load Measurements over time to provide a uniform characterisation of CPU Load independent of rate at which PaUtil_BeginCpuLoadMeasurement / PaUtil_EndCpuLoadMeasurement are called. see http://www.portaudio.com/trac/ticket/113 */ #include "pa_cpuload.h" #include #include "pa_util.h" /* for PaUtil_GetTime() */ void PaUtil_InitializeCpuLoadMeasurer( PaUtilCpuLoadMeasurer* measurer, double sampleRate ) { assert( sampleRate > 0 ); measurer->samplingPeriod = 1. / sampleRate; measurer->averageLoad = 0.; } void PaUtil_ResetCpuLoadMeasurer( PaUtilCpuLoadMeasurer* measurer ) { measurer->averageLoad = 0.; } void PaUtil_BeginCpuLoadMeasurement( PaUtilCpuLoadMeasurer* measurer ) { measurer->measurementStartTime = PaUtil_GetTime(); } void PaUtil_EndCpuLoadMeasurement( PaUtilCpuLoadMeasurer* measurer, unsigned long framesProcessed ) { double measurementEndTime, secondsFor100Percent, measuredLoad; if( framesProcessed > 0 ){ measurementEndTime = PaUtil_GetTime(); assert( framesProcessed > 0 ); secondsFor100Percent = framesProcessed * measurer->samplingPeriod; measuredLoad = (measurementEndTime - measurer->measurementStartTime) / secondsFor100Percent; /* Low pass filter the calculated CPU load to reduce jitter using a simple IIR low pass filter. */ /** FIXME @todo these coefficients shouldn't be hardwired see: http://www.portaudio.com/trac/ticket/113 */ #define LOWPASS_COEFFICIENT_0 (0.9) #define LOWPASS_COEFFICIENT_1 (0.99999 - LOWPASS_COEFFICIENT_0) measurer->averageLoad = (LOWPASS_COEFFICIENT_0 * measurer->averageLoad) + (LOWPASS_COEFFICIENT_1 * measuredLoad); } } double PaUtil_GetCpuLoad( PaUtilCpuLoadMeasurer* measurer ) { return measurer->averageLoad; } pd-0.46-7/portaudio/src/common/pa_converters.c0000664000175000017500000020706112222201037017474 0ustar mspmsp/* * $Id: pa_converters.c 1748 2011-09-01 22:08:32Z philburk $ * Portable Audio I/O Library sample conversion mechanism * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Phil Burk, Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Conversion function implementations. If the C9x function lrintf() is available, define PA_USE_C99_LRINTF to use it @todo Consider whether functions which dither but don't clip should exist, V18 automatically enabled clipping whenever dithering was selected. Perhaps we should do the same. see: "require clipping for dithering sample conversion functions?" http://www.portaudio.com/trac/ticket/112 @todo implement the converters marked IMPLEMENT ME: Int32_To_Int24_Dither, Int32_To_UInt8_Dither, Int24_To_Int16_Dither, Int24_To_Int8_Dither, Int24_To_UInt8_Dither, Int16_To_Int8_Dither, Int16_To_UInt8_Dither see: "some conversion functions are not implemented in pa_converters.c" http://www.portaudio.com/trac/ticket/35 @todo review the converters marked REVIEW: Float32_To_Int32, Float32_To_Int32_Dither, Float32_To_Int32_Clip, Float32_To_Int32_DitherClip, Int32_To_Int16_Dither, Int32_To_Int8_Dither, Int16_To_Int32 */ #include "pa_converters.h" #include "pa_dither.h" #include "pa_endianness.h" #include "pa_types.h" PaSampleFormat PaUtil_SelectClosestAvailableFormat( PaSampleFormat availableFormats, PaSampleFormat format ) { PaSampleFormat result; format &= ~paNonInterleaved; availableFormats &= ~paNonInterleaved; if( (format & availableFormats) == 0 ) { /* NOTE: this code depends on the sample format constants being in descending order of quality - ie best quality is 0 FIXME: should write an assert which checks that all of the known constants conform to that requirement. */ if( format != 0x01 ) { /* scan for better formats */ result = format; do { result >>= 1; } while( (result & availableFormats) == 0 && result != 0 ); } else { result = 0; } if( result == 0 ){ /* scan for worse formats */ result = format; do { result <<= 1; } while( (result & availableFormats) == 0 && result != paCustomFormat ); if( (result & availableFormats) == 0 ) result = paSampleFormatNotSupported; } }else{ result = format; } return result; } /* -------------------------------------------------------------------------- */ #define PA_SELECT_FORMAT_( format, float32, int32, int24, int16, int8, uint8 ) \ switch( format & ~paNonInterleaved ){ \ case paFloat32: \ float32 \ case paInt32: \ int32 \ case paInt24: \ int24 \ case paInt16: \ int16 \ case paInt8: \ int8 \ case paUInt8: \ uint8 \ default: return 0; \ } /* -------------------------------------------------------------------------- */ #define PA_SELECT_CONVERTER_DITHER_CLIP_( flags, source, destination ) \ if( flags & paClipOff ){ /* no clip */ \ if( flags & paDitherOff ){ /* no dither */ \ return paConverters. source ## _To_ ## destination; \ }else{ /* dither */ \ return paConverters. source ## _To_ ## destination ## _Dither; \ } \ }else{ /* clip */ \ if( flags & paDitherOff ){ /* no dither */ \ return paConverters. source ## _To_ ## destination ## _Clip; \ }else{ /* dither */ \ return paConverters. source ## _To_ ## destination ## _DitherClip; \ } \ } /* -------------------------------------------------------------------------- */ #define PA_SELECT_CONVERTER_DITHER_( flags, source, destination ) \ if( flags & paDitherOff ){ /* no dither */ \ return paConverters. source ## _To_ ## destination; \ }else{ /* dither */ \ return paConverters. source ## _To_ ## destination ## _Dither; \ } /* -------------------------------------------------------------------------- */ #define PA_USE_CONVERTER_( source, destination )\ return paConverters. source ## _To_ ## destination; /* -------------------------------------------------------------------------- */ #define PA_UNITY_CONVERSION_( wordlength )\ return paConverters. Copy_ ## wordlength ## _To_ ## wordlength; /* -------------------------------------------------------------------------- */ PaUtilConverter* PaUtil_SelectConverter( PaSampleFormat sourceFormat, PaSampleFormat destinationFormat, PaStreamFlags flags ) { PA_SELECT_FORMAT_( sourceFormat, /* paFloat32: */ PA_SELECT_FORMAT_( destinationFormat, /* paFloat32: */ PA_UNITY_CONVERSION_( 32 ), /* paInt32: */ PA_SELECT_CONVERTER_DITHER_CLIP_( flags, Float32, Int32 ), /* paInt24: */ PA_SELECT_CONVERTER_DITHER_CLIP_( flags, Float32, Int24 ), /* paInt16: */ PA_SELECT_CONVERTER_DITHER_CLIP_( flags, Float32, Int16 ), /* paInt8: */ PA_SELECT_CONVERTER_DITHER_CLIP_( flags, Float32, Int8 ), /* paUInt8: */ PA_SELECT_CONVERTER_DITHER_CLIP_( flags, Float32, UInt8 ) ), /* paInt32: */ PA_SELECT_FORMAT_( destinationFormat, /* paFloat32: */ PA_USE_CONVERTER_( Int32, Float32 ), /* paInt32: */ PA_UNITY_CONVERSION_( 32 ), /* paInt24: */ PA_SELECT_CONVERTER_DITHER_( flags, Int32, Int24 ), /* paInt16: */ PA_SELECT_CONVERTER_DITHER_( flags, Int32, Int16 ), /* paInt8: */ PA_SELECT_CONVERTER_DITHER_( flags, Int32, Int8 ), /* paUInt8: */ PA_SELECT_CONVERTER_DITHER_( flags, Int32, UInt8 ) ), /* paInt24: */ PA_SELECT_FORMAT_( destinationFormat, /* paFloat32: */ PA_USE_CONVERTER_( Int24, Float32 ), /* paInt32: */ PA_USE_CONVERTER_( Int24, Int32 ), /* paInt24: */ PA_UNITY_CONVERSION_( 24 ), /* paInt16: */ PA_SELECT_CONVERTER_DITHER_( flags, Int24, Int16 ), /* paInt8: */ PA_SELECT_CONVERTER_DITHER_( flags, Int24, Int8 ), /* paUInt8: */ PA_SELECT_CONVERTER_DITHER_( flags, Int24, UInt8 ) ), /* paInt16: */ PA_SELECT_FORMAT_( destinationFormat, /* paFloat32: */ PA_USE_CONVERTER_( Int16, Float32 ), /* paInt32: */ PA_USE_CONVERTER_( Int16, Int32 ), /* paInt24: */ PA_USE_CONVERTER_( Int16, Int24 ), /* paInt16: */ PA_UNITY_CONVERSION_( 16 ), /* paInt8: */ PA_SELECT_CONVERTER_DITHER_( flags, Int16, Int8 ), /* paUInt8: */ PA_SELECT_CONVERTER_DITHER_( flags, Int16, UInt8 ) ), /* paInt8: */ PA_SELECT_FORMAT_( destinationFormat, /* paFloat32: */ PA_USE_CONVERTER_( Int8, Float32 ), /* paInt32: */ PA_USE_CONVERTER_( Int8, Int32 ), /* paInt24: */ PA_USE_CONVERTER_( Int8, Int24 ), /* paInt16: */ PA_USE_CONVERTER_( Int8, Int16 ), /* paInt8: */ PA_UNITY_CONVERSION_( 8 ), /* paUInt8: */ PA_USE_CONVERTER_( Int8, UInt8 ) ), /* paUInt8: */ PA_SELECT_FORMAT_( destinationFormat, /* paFloat32: */ PA_USE_CONVERTER_( UInt8, Float32 ), /* paInt32: */ PA_USE_CONVERTER_( UInt8, Int32 ), /* paInt24: */ PA_USE_CONVERTER_( UInt8, Int24 ), /* paInt16: */ PA_USE_CONVERTER_( UInt8, Int16 ), /* paInt8: */ PA_USE_CONVERTER_( UInt8, Int8 ), /* paUInt8: */ PA_UNITY_CONVERSION_( 8 ) ) ) } /* -------------------------------------------------------------------------- */ #ifdef PA_NO_STANDARD_CONVERTERS /* -------------------------------------------------------------------------- */ PaUtilConverterTable paConverters = { 0, /* PaUtilConverter *Float32_To_Int32; */ 0, /* PaUtilConverter *Float32_To_Int32_Dither; */ 0, /* PaUtilConverter *Float32_To_Int32_Clip; */ 0, /* PaUtilConverter *Float32_To_Int32_DitherClip; */ 0, /* PaUtilConverter *Float32_To_Int24; */ 0, /* PaUtilConverter *Float32_To_Int24_Dither; */ 0, /* PaUtilConverter *Float32_To_Int24_Clip; */ 0, /* PaUtilConverter *Float32_To_Int24_DitherClip; */ 0, /* PaUtilConverter *Float32_To_Int16; */ 0, /* PaUtilConverter *Float32_To_Int16_Dither; */ 0, /* PaUtilConverter *Float32_To_Int16_Clip; */ 0, /* PaUtilConverter *Float32_To_Int16_DitherClip; */ 0, /* PaUtilConverter *Float32_To_Int8; */ 0, /* PaUtilConverter *Float32_To_Int8_Dither; */ 0, /* PaUtilConverter *Float32_To_Int8_Clip; */ 0, /* PaUtilConverter *Float32_To_Int8_DitherClip; */ 0, /* PaUtilConverter *Float32_To_UInt8; */ 0, /* PaUtilConverter *Float32_To_UInt8_Dither; */ 0, /* PaUtilConverter *Float32_To_UInt8_Clip; */ 0, /* PaUtilConverter *Float32_To_UInt8_DitherClip; */ 0, /* PaUtilConverter *Int32_To_Float32; */ 0, /* PaUtilConverter *Int32_To_Int24; */ 0, /* PaUtilConverter *Int32_To_Int24_Dither; */ 0, /* PaUtilConverter *Int32_To_Int16; */ 0, /* PaUtilConverter *Int32_To_Int16_Dither; */ 0, /* PaUtilConverter *Int32_To_Int8; */ 0, /* PaUtilConverter *Int32_To_Int8_Dither; */ 0, /* PaUtilConverter *Int32_To_UInt8; */ 0, /* PaUtilConverter *Int32_To_UInt8_Dither; */ 0, /* PaUtilConverter *Int24_To_Float32; */ 0, /* PaUtilConverter *Int24_To_Int32; */ 0, /* PaUtilConverter *Int24_To_Int16; */ 0, /* PaUtilConverter *Int24_To_Int16_Dither; */ 0, /* PaUtilConverter *Int24_To_Int8; */ 0, /* PaUtilConverter *Int24_To_Int8_Dither; */ 0, /* PaUtilConverter *Int24_To_UInt8; */ 0, /* PaUtilConverter *Int24_To_UInt8_Dither; */ 0, /* PaUtilConverter *Int16_To_Float32; */ 0, /* PaUtilConverter *Int16_To_Int32; */ 0, /* PaUtilConverter *Int16_To_Int24; */ 0, /* PaUtilConverter *Int16_To_Int8; */ 0, /* PaUtilConverter *Int16_To_Int8_Dither; */ 0, /* PaUtilConverter *Int16_To_UInt8; */ 0, /* PaUtilConverter *Int16_To_UInt8_Dither; */ 0, /* PaUtilConverter *Int8_To_Float32; */ 0, /* PaUtilConverter *Int8_To_Int32; */ 0, /* PaUtilConverter *Int8_To_Int24 */ 0, /* PaUtilConverter *Int8_To_Int16; */ 0, /* PaUtilConverter *Int8_To_UInt8; */ 0, /* PaUtilConverter *UInt8_To_Float32; */ 0, /* PaUtilConverter *UInt8_To_Int32; */ 0, /* PaUtilConverter *UInt8_To_Int24; */ 0, /* PaUtilConverter *UInt8_To_Int16; */ 0, /* PaUtilConverter *UInt8_To_Int8; */ 0, /* PaUtilConverter *Copy_8_To_8; */ 0, /* PaUtilConverter *Copy_16_To_16; */ 0, /* PaUtilConverter *Copy_24_To_24; */ 0 /* PaUtilConverter *Copy_32_To_32; */ }; /* -------------------------------------------------------------------------- */ #else /* PA_NO_STANDARD_CONVERTERS is not defined */ /* -------------------------------------------------------------------------- */ #define PA_CLIP_( val, min, max )\ { val = ((val) < (min)) ? (min) : (((val) > (max)) ? (max) : (val)); } static const float const_1_div_128_ = 1.0f / 128.0f; /* 8 bit multiplier */ static const float const_1_div_32768_ = 1.0f / 32768.f; /* 16 bit multiplier */ static const double const_1_div_2147483648_ = 1.0 / 2147483648.0; /* 32 bit multiplier */ /* -------------------------------------------------------------------------- */ static void Float32_To_Int32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; PaInt32 *dest = (PaInt32*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { /* REVIEW */ #ifdef PA_USE_C99_LRINTF float scaled = *src * 0x7FFFFFFF; *dest = lrintf(scaled-0.5f); #else double scaled = *src * 0x7FFFFFFF; *dest = (PaInt32) scaled; #endif src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int32_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; PaInt32 *dest = (PaInt32*)destinationBuffer; while( count-- ) { /* REVIEW */ #ifdef PA_USE_C99_LRINTF float dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ float dithered = ((float)*src * (2147483646.0f)) + dither; *dest = lrintf(dithered - 0.5f); #else double dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ double dithered = ((double)*src * (2147483646.0)) + dither; *dest = (PaInt32) dithered; #endif src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int32_Clip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; PaInt32 *dest = (PaInt32*)destinationBuffer; (void) ditherGenerator; /* unused parameter */ while( count-- ) { /* REVIEW */ #ifdef PA_USE_C99_LRINTF float scaled = *src * 0x7FFFFFFF; PA_CLIP_( scaled, -2147483648.f, 2147483647.f ); *dest = lrintf(scaled-0.5f); #else double scaled = *src * 0x7FFFFFFF; PA_CLIP_( scaled, -2147483648., 2147483647. ); *dest = (PaInt32) scaled; #endif src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int32_DitherClip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; PaInt32 *dest = (PaInt32*)destinationBuffer; while( count-- ) { /* REVIEW */ #ifdef PA_USE_C99_LRINTF float dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ float dithered = ((float)*src * (2147483646.0f)) + dither; PA_CLIP_( dithered, -2147483648.f, 2147483647.f ); *dest = lrintf(dithered-0.5f); #else double dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ double dithered = ((double)*src * (2147483646.0)) + dither; PA_CLIP_( dithered, -2147483648., 2147483647. ); *dest = (PaInt32) dithered; #endif src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int24( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; PaInt32 temp; (void) ditherGenerator; /* unused parameter */ while( count-- ) { /* convert to 32 bit and drop the low 8 bits */ double scaled = (double)(*src) * 2147483647.0; temp = (PaInt32) scaled; #if defined(PA_LITTLE_ENDIAN) dest[0] = (unsigned char)(temp >> 8); dest[1] = (unsigned char)(temp >> 16); dest[2] = (unsigned char)(temp >> 24); #elif defined(PA_BIG_ENDIAN) dest[0] = (unsigned char)(temp >> 24); dest[1] = (unsigned char)(temp >> 16); dest[2] = (unsigned char)(temp >> 8); #endif src += sourceStride; dest += destinationStride * 3; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int24_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; PaInt32 temp; while( count-- ) { /* convert to 32 bit and drop the low 8 bits */ double dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ double dithered = ((double)*src * (2147483646.0)) + dither; temp = (PaInt32) dithered; #if defined(PA_LITTLE_ENDIAN) dest[0] = (unsigned char)(temp >> 8); dest[1] = (unsigned char)(temp >> 16); dest[2] = (unsigned char)(temp >> 24); #elif defined(PA_BIG_ENDIAN) dest[0] = (unsigned char)(temp >> 24); dest[1] = (unsigned char)(temp >> 16); dest[2] = (unsigned char)(temp >> 8); #endif src += sourceStride; dest += destinationStride * 3; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int24_Clip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; PaInt32 temp; (void) ditherGenerator; /* unused parameter */ while( count-- ) { /* convert to 32 bit and drop the low 8 bits */ double scaled = *src * 0x7FFFFFFF; PA_CLIP_( scaled, -2147483648., 2147483647. ); temp = (PaInt32) scaled; #if defined(PA_LITTLE_ENDIAN) dest[0] = (unsigned char)(temp >> 8); dest[1] = (unsigned char)(temp >> 16); dest[2] = (unsigned char)(temp >> 24); #elif defined(PA_BIG_ENDIAN) dest[0] = (unsigned char)(temp >> 24); dest[1] = (unsigned char)(temp >> 16); dest[2] = (unsigned char)(temp >> 8); #endif src += sourceStride; dest += destinationStride * 3; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int24_DitherClip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; PaInt32 temp; while( count-- ) { /* convert to 32 bit and drop the low 8 bits */ double dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ double dithered = ((double)*src * (2147483646.0)) + dither; PA_CLIP_( dithered, -2147483648., 2147483647. ); temp = (PaInt32) dithered; #if defined(PA_LITTLE_ENDIAN) dest[0] = (unsigned char)(temp >> 8); dest[1] = (unsigned char)(temp >> 16); dest[2] = (unsigned char)(temp >> 24); #elif defined(PA_BIG_ENDIAN) dest[0] = (unsigned char)(temp >> 24); dest[1] = (unsigned char)(temp >> 16); dest[2] = (unsigned char)(temp >> 8); #endif src += sourceStride; dest += destinationStride * 3; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int16( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; PaInt16 *dest = (PaInt16*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { #ifdef PA_USE_C99_LRINTF float tempf = (*src * (32767.0f)) ; *dest = lrintf(tempf-0.5f); #else short samp = (short) (*src * (32767.0f)); *dest = samp; #endif src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int16_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; PaInt16 *dest = (PaInt16*)destinationBuffer; while( count-- ) { float dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ float dithered = (*src * (32766.0f)) + dither; #ifdef PA_USE_C99_LRINTF *dest = lrintf(dithered-0.5f); #else *dest = (PaInt16) dithered; #endif src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int16_Clip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; PaInt16 *dest = (PaInt16*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { #ifdef PA_USE_C99_LRINTF long samp = lrintf((*src * (32767.0f)) -0.5f); #else long samp = (PaInt32) (*src * (32767.0f)); #endif PA_CLIP_( samp, -0x8000, 0x7FFF ); *dest = (PaInt16) samp; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int16_DitherClip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; PaInt16 *dest = (PaInt16*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { float dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ float dithered = (*src * (32766.0f)) + dither; PaInt32 samp = (PaInt32) dithered; PA_CLIP_( samp, -0x8000, 0x7FFF ); #ifdef PA_USE_C99_LRINTF *dest = lrintf(samp-0.5f); #else *dest = (PaInt16) samp; #endif src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { signed char samp = (signed char) (*src * (127.0f)); *dest = samp; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int8_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; while( count-- ) { float dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ float dithered = (*src * (126.0f)) + dither; PaInt32 samp = (PaInt32) dithered; *dest = (signed char) samp; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int8_Clip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { PaInt32 samp = (PaInt32)(*src * (127.0f)); PA_CLIP_( samp, -0x80, 0x7F ); *dest = (signed char) samp; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_Int8_DitherClip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { float dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ float dithered = (*src * (126.0f)) + dither; PaInt32 samp = (PaInt32) dithered; PA_CLIP_( samp, -0x80, 0x7F ); *dest = (signed char) samp; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_UInt8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { unsigned char samp = (unsigned char)(128 + ((unsigned char) (*src * (127.0f)))); *dest = samp; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_UInt8_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; while( count-- ) { float dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ float dithered = (*src * (126.0f)) + dither; PaInt32 samp = (PaInt32) dithered; *dest = (unsigned char) (128 + samp); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_UInt8_Clip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { PaInt32 samp = 128 + (PaInt32)(*src * (127.0f)); PA_CLIP_( samp, 0x0000, 0x00FF ); *dest = (unsigned char) samp; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Float32_To_UInt8_DitherClip( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { float *src = (float*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { float dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); /* use smaller scaler to prevent overflow when we add the dither */ float dithered = (*src * (126.0f)) + dither; PaInt32 samp = 128 + (PaInt32) dithered; PA_CLIP_( samp, 0x0000, 0x00FF ); *dest = (unsigned char) samp; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int32_To_Float32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt32 *src = (PaInt32*)sourceBuffer; float *dest = (float*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { *dest = (float) ((double)*src * const_1_div_2147483648_); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int32_To_Int24( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt32 *src = (PaInt32*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void) ditherGenerator; /* unused parameter */ while( count-- ) { /* REVIEW */ #if defined(PA_LITTLE_ENDIAN) dest[0] = (unsigned char)(*src >> 8); dest[1] = (unsigned char)(*src >> 16); dest[2] = (unsigned char)(*src >> 24); #elif defined(PA_BIG_ENDIAN) dest[0] = (unsigned char)(*src >> 24); dest[1] = (unsigned char)(*src >> 16); dest[2] = (unsigned char)(*src >> 8); #endif src += sourceStride; dest += destinationStride * 3; } } /* -------------------------------------------------------------------------- */ static void Int32_To_Int24_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { (void) destinationBuffer; /* unused parameters */ (void) destinationStride; /* unused parameters */ (void) sourceBuffer; /* unused parameters */ (void) sourceStride; /* unused parameters */ (void) count; /* unused parameters */ (void) ditherGenerator; /* unused parameters */ /* IMPLEMENT ME */ } /* -------------------------------------------------------------------------- */ static void Int32_To_Int16( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt32 *src = (PaInt32*)sourceBuffer; PaInt16 *dest = (PaInt16*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { *dest = (PaInt16) ((*src) >> 16); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int32_To_Int16_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt32 *src = (PaInt32*)sourceBuffer; PaInt16 *dest = (PaInt16*)destinationBuffer; PaInt32 dither; while( count-- ) { /* REVIEW */ dither = PaUtil_Generate16BitTriangularDither( ditherGenerator ); *dest = (PaInt16) ((((*src)>>1) + dither) >> 15); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int32_To_Int8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt32 *src = (PaInt32*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { *dest = (signed char) ((*src) >> 24); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int32_To_Int8_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt32 *src = (PaInt32*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; PaInt32 dither; while( count-- ) { /* REVIEW */ dither = PaUtil_Generate16BitTriangularDither( ditherGenerator ); *dest = (signed char) ((((*src)>>1) + dither) >> 23); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int32_To_UInt8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt32 *src = (PaInt32*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { (*dest) = (unsigned char)(((*src) >> 24) + 128); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int32_To_UInt8_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt32 *src = (PaInt32*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { /* IMPLEMENT ME */ src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int24_To_Float32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; float *dest = (float*)destinationBuffer; PaInt32 temp; (void) ditherGenerator; /* unused parameter */ while( count-- ) { #if defined(PA_LITTLE_ENDIAN) temp = (((PaInt32)src[0]) << 8); temp = temp | (((PaInt32)src[1]) << 16); temp = temp | (((PaInt32)src[2]) << 24); #elif defined(PA_BIG_ENDIAN) temp = (((PaInt32)src[0]) << 24); temp = temp | (((PaInt32)src[1]) << 16); temp = temp | (((PaInt32)src[2]) << 8); #endif *dest = (float) ((double)temp * const_1_div_2147483648_); src += sourceStride * 3; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int24_To_Int32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; PaInt32 *dest = (PaInt32*) destinationBuffer; PaInt32 temp; (void) ditherGenerator; /* unused parameter */ while( count-- ) { #if defined(PA_LITTLE_ENDIAN) temp = (((PaInt32)src[0]) << 8); temp = temp | (((PaInt32)src[1]) << 16); temp = temp | (((PaInt32)src[2]) << 24); #elif defined(PA_BIG_ENDIAN) temp = (((PaInt32)src[0]) << 24); temp = temp | (((PaInt32)src[1]) << 16); temp = temp | (((PaInt32)src[2]) << 8); #endif *dest = temp; src += sourceStride * 3; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int24_To_Int16( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; PaInt16 *dest = (PaInt16*)destinationBuffer; PaInt16 temp; (void) ditherGenerator; /* unused parameter */ while( count-- ) { #if defined(PA_LITTLE_ENDIAN) /* src[0] is discarded */ temp = (((PaInt16)src[1])); temp = temp | (PaInt16)(((PaInt16)src[2]) << 8); #elif defined(PA_BIG_ENDIAN) /* src[2] is discarded */ temp = (PaInt16)(((PaInt16)src[0]) << 8); temp = temp | (((PaInt16)src[1])); #endif *dest = temp; src += sourceStride * 3; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int24_To_Int16_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; PaInt16 *dest = (PaInt16*)destinationBuffer; PaInt32 temp, dither; while( count-- ) { #if defined(PA_LITTLE_ENDIAN) temp = (((PaInt32)src[0]) << 8); temp = temp | (((PaInt32)src[1]) << 16); temp = temp | (((PaInt32)src[2]) << 24); #elif defined(PA_BIG_ENDIAN) temp = (((PaInt32)src[0]) << 24); temp = temp | (((PaInt32)src[1]) << 16); temp = temp | (((PaInt32)src[2]) << 8); #endif /* REVIEW */ dither = PaUtil_Generate16BitTriangularDither( ditherGenerator ); *dest = (PaInt16) (((temp >> 1) + dither) >> 15); src += sourceStride * 3; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int24_To_Int8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; (void) ditherGenerator; /* unused parameter */ while( count-- ) { #if defined(PA_LITTLE_ENDIAN) /* src[0] is discarded */ /* src[1] is discarded */ *dest = src[2]; #elif defined(PA_BIG_ENDIAN) /* src[2] is discarded */ /* src[1] is discarded */ *dest = src[0]; #endif src += sourceStride * 3; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int24_To_Int8_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; PaInt32 temp, dither; while( count-- ) { #if defined(PA_LITTLE_ENDIAN) temp = (((PaInt32)src[0]) << 8); temp = temp | (((PaInt32)src[1]) << 16); temp = temp | (((PaInt32)src[2]) << 24); #elif defined(PA_BIG_ENDIAN) temp = (((PaInt32)src[0]) << 24); temp = temp | (((PaInt32)src[1]) << 16); temp = temp | (((PaInt32)src[2]) << 8); #endif /* REVIEW */ dither = PaUtil_Generate16BitTriangularDither( ditherGenerator ); *dest = (signed char) (((temp >> 1) + dither) >> 23); src += sourceStride * 3; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int24_To_UInt8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void) ditherGenerator; /* unused parameter */ while( count-- ) { #if defined(PA_LITTLE_ENDIAN) /* src[0] is discarded */ /* src[1] is discarded */ *dest = (unsigned char)(src[2] + 128); #elif defined(PA_BIG_ENDIAN) *dest = (unsigned char)(src[0] + 128); /* src[1] is discarded */ /* src[2] is discarded */ #endif src += sourceStride * 3; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int24_To_UInt8_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { (void) destinationBuffer; /* unused parameters */ (void) destinationStride; /* unused parameters */ (void) sourceBuffer; /* unused parameters */ (void) sourceStride; /* unused parameters */ (void) count; /* unused parameters */ (void) ditherGenerator; /* unused parameters */ /* IMPLEMENT ME */ } /* -------------------------------------------------------------------------- */ static void Int16_To_Float32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt16 *src = (PaInt16*)sourceBuffer; float *dest = (float*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { float samp = *src * const_1_div_32768_; /* FIXME: i'm concerned about this being asymetrical with float->int16 -rb */ *dest = samp; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int16_To_Int32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt16 *src = (PaInt16*)sourceBuffer; PaInt32 *dest = (PaInt32*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { /* REVIEW: we should consider something like (*src << 16) | (*src & 0xFFFF) */ *dest = *src << 16; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int16_To_Int24( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt16 *src = (PaInt16*) sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; PaInt16 temp; (void) ditherGenerator; /* unused parameter */ while( count-- ) { temp = *src; #if defined(PA_LITTLE_ENDIAN) dest[0] = 0; dest[1] = (unsigned char)(temp); dest[2] = (unsigned char)(temp >> 8); #elif defined(PA_BIG_ENDIAN) dest[0] = (unsigned char)(temp >> 8); dest[1] = (unsigned char)(temp); dest[2] = 0; #endif src += sourceStride; dest += destinationStride * 3; } } /* -------------------------------------------------------------------------- */ static void Int16_To_Int8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt16 *src = (PaInt16*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { (*dest) = (signed char)((*src) >> 8); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int16_To_Int8_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt16 *src = (PaInt16*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { /* IMPLEMENT ME */ src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int16_To_UInt8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt16 *src = (PaInt16*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { (*dest) = (unsigned char)(((*src) >> 8) + 128); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int16_To_UInt8_Dither( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaInt16 *src = (PaInt16*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { /* IMPLEMENT ME */ src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int8_To_Float32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { signed char *src = (signed char*)sourceBuffer; float *dest = (float*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { float samp = *src * const_1_div_128_; *dest = samp; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int8_To_Int32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { signed char *src = (signed char*)sourceBuffer; PaInt32 *dest = (PaInt32*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { (*dest) = (*src) << 24; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int8_To_Int24( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { signed char *src = (signed char*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { #if defined(PA_LITTLE_ENDIAN) dest[0] = 0; dest[1] = 0; dest[2] = (*src); #elif defined(PA_BIG_ENDIAN) dest[0] = (*src); dest[1] = 0; dest[2] = 0; #endif src += sourceStride; dest += destinationStride * 3; } } /* -------------------------------------------------------------------------- */ static void Int8_To_Int16( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { signed char *src = (signed char*)sourceBuffer; PaInt16 *dest = (PaInt16*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { (*dest) = (PaInt16)((*src) << 8); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Int8_To_UInt8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { signed char *src = (signed char*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { (*dest) = (unsigned char)(*src + 128); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void UInt8_To_Float32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; float *dest = (float*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { float samp = (*src - 128) * const_1_div_128_; *dest = samp; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void UInt8_To_Int32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; PaInt32 *dest = (PaInt32*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { (*dest) = (*src - 128) << 24; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void UInt8_To_Int24( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void) ditherGenerator; /* unused parameters */ while( count-- ) { #if defined(PA_LITTLE_ENDIAN) dest[0] = 0; dest[1] = 0; dest[2] = (unsigned char)(*src - 128); #elif defined(PA_BIG_ENDIAN) dest[0] = (unsigned char)(*src - 128); dest[1] = 0; dest[2] = 0; #endif src += sourceStride; dest += destinationStride * 3; } } /* -------------------------------------------------------------------------- */ static void UInt8_To_Int16( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; PaInt16 *dest = (PaInt16*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { (*dest) = (PaInt16)((*src - 128) << 8); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void UInt8_To_Int8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; signed char *dest = (signed char*)destinationBuffer; (void)ditherGenerator; /* unused parameter */ while( count-- ) { (*dest) = (signed char)(*src - 128); src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Copy_8_To_8( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void) ditherGenerator; /* unused parameter */ while( count-- ) { *dest = *src; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Copy_16_To_16( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaUint16 *src = (PaUint16 *)sourceBuffer; PaUint16 *dest = (PaUint16 *)destinationBuffer; (void) ditherGenerator; /* unused parameter */ while( count-- ) { *dest = *src; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Copy_24_To_24( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { unsigned char *src = (unsigned char*)sourceBuffer; unsigned char *dest = (unsigned char*)destinationBuffer; (void) ditherGenerator; /* unused parameter */ while( count-- ) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; src += sourceStride * 3; dest += destinationStride * 3; } } /* -------------------------------------------------------------------------- */ static void Copy_32_To_32( void *destinationBuffer, signed int destinationStride, void *sourceBuffer, signed int sourceStride, unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator ) { PaUint32 *dest = (PaUint32 *)destinationBuffer; PaUint32 *src = (PaUint32 *)sourceBuffer; (void) ditherGenerator; /* unused parameter */ while( count-- ) { *dest = *src; src += sourceStride; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ PaUtilConverterTable paConverters = { Float32_To_Int32, /* PaUtilConverter *Float32_To_Int32; */ Float32_To_Int32_Dither, /* PaUtilConverter *Float32_To_Int32_Dither; */ Float32_To_Int32_Clip, /* PaUtilConverter *Float32_To_Int32_Clip; */ Float32_To_Int32_DitherClip, /* PaUtilConverter *Float32_To_Int32_DitherClip; */ Float32_To_Int24, /* PaUtilConverter *Float32_To_Int24; */ Float32_To_Int24_Dither, /* PaUtilConverter *Float32_To_Int24_Dither; */ Float32_To_Int24_Clip, /* PaUtilConverter *Float32_To_Int24_Clip; */ Float32_To_Int24_DitherClip, /* PaUtilConverter *Float32_To_Int24_DitherClip; */ Float32_To_Int16, /* PaUtilConverter *Float32_To_Int16; */ Float32_To_Int16_Dither, /* PaUtilConverter *Float32_To_Int16_Dither; */ Float32_To_Int16_Clip, /* PaUtilConverter *Float32_To_Int16_Clip; */ Float32_To_Int16_DitherClip, /* PaUtilConverter *Float32_To_Int16_DitherClip; */ Float32_To_Int8, /* PaUtilConverter *Float32_To_Int8; */ Float32_To_Int8_Dither, /* PaUtilConverter *Float32_To_Int8_Dither; */ Float32_To_Int8_Clip, /* PaUtilConverter *Float32_To_Int8_Clip; */ Float32_To_Int8_DitherClip, /* PaUtilConverter *Float32_To_Int8_DitherClip; */ Float32_To_UInt8, /* PaUtilConverter *Float32_To_UInt8; */ Float32_To_UInt8_Dither, /* PaUtilConverter *Float32_To_UInt8_Dither; */ Float32_To_UInt8_Clip, /* PaUtilConverter *Float32_To_UInt8_Clip; */ Float32_To_UInt8_DitherClip, /* PaUtilConverter *Float32_To_UInt8_DitherClip; */ Int32_To_Float32, /* PaUtilConverter *Int32_To_Float32; */ Int32_To_Int24, /* PaUtilConverter *Int32_To_Int24; */ Int32_To_Int24_Dither, /* PaUtilConverter *Int32_To_Int24_Dither; */ Int32_To_Int16, /* PaUtilConverter *Int32_To_Int16; */ Int32_To_Int16_Dither, /* PaUtilConverter *Int32_To_Int16_Dither; */ Int32_To_Int8, /* PaUtilConverter *Int32_To_Int8; */ Int32_To_Int8_Dither, /* PaUtilConverter *Int32_To_Int8_Dither; */ Int32_To_UInt8, /* PaUtilConverter *Int32_To_UInt8; */ Int32_To_UInt8_Dither, /* PaUtilConverter *Int32_To_UInt8_Dither; */ Int24_To_Float32, /* PaUtilConverter *Int24_To_Float32; */ Int24_To_Int32, /* PaUtilConverter *Int24_To_Int32; */ Int24_To_Int16, /* PaUtilConverter *Int24_To_Int16; */ Int24_To_Int16_Dither, /* PaUtilConverter *Int24_To_Int16_Dither; */ Int24_To_Int8, /* PaUtilConverter *Int24_To_Int8; */ Int24_To_Int8_Dither, /* PaUtilConverter *Int24_To_Int8_Dither; */ Int24_To_UInt8, /* PaUtilConverter *Int24_To_UInt8; */ Int24_To_UInt8_Dither, /* PaUtilConverter *Int24_To_UInt8_Dither; */ Int16_To_Float32, /* PaUtilConverter *Int16_To_Float32; */ Int16_To_Int32, /* PaUtilConverter *Int16_To_Int32; */ Int16_To_Int24, /* PaUtilConverter *Int16_To_Int24; */ Int16_To_Int8, /* PaUtilConverter *Int16_To_Int8; */ Int16_To_Int8_Dither, /* PaUtilConverter *Int16_To_Int8_Dither; */ Int16_To_UInt8, /* PaUtilConverter *Int16_To_UInt8; */ Int16_To_UInt8_Dither, /* PaUtilConverter *Int16_To_UInt8_Dither; */ Int8_To_Float32, /* PaUtilConverter *Int8_To_Float32; */ Int8_To_Int32, /* PaUtilConverter *Int8_To_Int32; */ Int8_To_Int24, /* PaUtilConverter *Int8_To_Int24 */ Int8_To_Int16, /* PaUtilConverter *Int8_To_Int16; */ Int8_To_UInt8, /* PaUtilConverter *Int8_To_UInt8; */ UInt8_To_Float32, /* PaUtilConverter *UInt8_To_Float32; */ UInt8_To_Int32, /* PaUtilConverter *UInt8_To_Int32; */ UInt8_To_Int24, /* PaUtilConverter *UInt8_To_Int24; */ UInt8_To_Int16, /* PaUtilConverter *UInt8_To_Int16; */ UInt8_To_Int8, /* PaUtilConverter *UInt8_To_Int8; */ Copy_8_To_8, /* PaUtilConverter *Copy_8_To_8; */ Copy_16_To_16, /* PaUtilConverter *Copy_16_To_16; */ Copy_24_To_24, /* PaUtilConverter *Copy_24_To_24; */ Copy_32_To_32 /* PaUtilConverter *Copy_32_To_32; */ }; /* -------------------------------------------------------------------------- */ #endif /* PA_NO_STANDARD_CONVERTERS */ /* -------------------------------------------------------------------------- */ PaUtilZeroer* PaUtil_SelectZeroer( PaSampleFormat destinationFormat ) { switch( destinationFormat & ~paNonInterleaved ){ case paFloat32: return paZeroers.Zero32; case paInt32: return paZeroers.Zero32; case paInt24: return paZeroers.Zero24; case paInt16: return paZeroers.Zero16; case paInt8: return paZeroers.Zero8; case paUInt8: return paZeroers.ZeroU8; default: return 0; } } /* -------------------------------------------------------------------------- */ #ifdef PA_NO_STANDARD_ZEROERS /* -------------------------------------------------------------------------- */ PaUtilZeroerTable paZeroers = { 0, /* PaUtilZeroer *ZeroU8; */ 0, /* PaUtilZeroer *Zero8; */ 0, /* PaUtilZeroer *Zero16; */ 0, /* PaUtilZeroer *Zero24; */ 0, /* PaUtilZeroer *Zero32; */ }; /* -------------------------------------------------------------------------- */ #else /* PA_NO_STANDARD_ZEROERS is not defined */ /* -------------------------------------------------------------------------- */ static void ZeroU8( void *destinationBuffer, signed int destinationStride, unsigned int count ) { unsigned char *dest = (unsigned char*)destinationBuffer; while( count-- ) { *dest = 128; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Zero8( void *destinationBuffer, signed int destinationStride, unsigned int count ) { unsigned char *dest = (unsigned char*)destinationBuffer; while( count-- ) { *dest = 0; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Zero16( void *destinationBuffer, signed int destinationStride, unsigned int count ) { PaUint16 *dest = (PaUint16 *)destinationBuffer; while( count-- ) { *dest = 0; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ static void Zero24( void *destinationBuffer, signed int destinationStride, unsigned int count ) { unsigned char *dest = (unsigned char*)destinationBuffer; while( count-- ) { dest[0] = 0; dest[1] = 0; dest[2] = 0; dest += destinationStride * 3; } } /* -------------------------------------------------------------------------- */ static void Zero32( void *destinationBuffer, signed int destinationStride, unsigned int count ) { PaUint32 *dest = (PaUint32 *)destinationBuffer; while( count-- ) { *dest = 0; dest += destinationStride; } } /* -------------------------------------------------------------------------- */ PaUtilZeroerTable paZeroers = { ZeroU8, /* PaUtilZeroer *ZeroU8; */ Zero8, /* PaUtilZeroer *Zero8; */ Zero16, /* PaUtilZeroer *Zero16; */ Zero24, /* PaUtilZeroer *Zero24; */ Zero32, /* PaUtilZeroer *Zero32; */ }; /* -------------------------------------------------------------------------- */ #endif /* PA_NO_STANDARD_ZEROERS */ pd-0.46-7/portaudio/src/common/pa_process.h0000664000175000017500000007654412222201037016777 0ustar mspmsp#ifndef PA_PROCESS_H #define PA_PROCESS_H /* * $Id: pa_process.h 1668 2011-05-02 17:07:11Z rossb $ * Portable Audio I/O Library callback buffer processing adapters * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Phil Burk, Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Buffer Processor prototypes. A Buffer Processor performs buffer length adaption, coordinates sample format conversion, and interleaves/deinterleaves channels.

Overview

The "Buffer Processor" (PaUtilBufferProcessor) manages conversion of audio data from host buffers to user buffers and back again. Where required, the buffer processor takes care of converting between host and user sample formats, interleaving and deinterleaving multichannel buffers, and adapting between host and user buffers with different lengths. The buffer processor may be used with full and half duplex streams, for both callback streams and blocking read/write streams. One of the important capabilities provided by the buffer processor is the ability to adapt between user and host buffer sizes of different lengths with minimum latency. Although this task is relatively easy to perform when the host buffer size is an integer multiple of the user buffer size, the problem is more complicated when this is not the case - especially for full-duplex callback streams. Where necessary the adaption is implemented by internally buffering some input and/or output data. The buffer adation algorithm used by the buffer processor was originally implemented by Stephan Letz for the ASIO version of PortAudio, and is described in his Callback_adaption_.pdf which is included in the distribution. The buffer processor performs sample conversion using the functions provided by pa_converters.c. The following sections provide an overview of how to use the buffer processor. Interested readers are advised to consult the host API implementations for examples of buffer processor usage.

Initialization, resetting and termination

When a stream is opened, the buffer processor should be initialized using PaUtil_InitializeBufferProcessor. This function initializes internal state and allocates temporary buffers as neccesary according to the supplied configuration parameters. Some of the parameters correspond to those requested by the user in their call to Pa_OpenStream(), others reflect the requirements of the host API implementation - they indicate host buffer sizes, formats, and the type of buffering which the Host API uses. The buffer processor should be initialized for callback streams and blocking read/write streams. Call PaUtil_ResetBufferProcessor to clear any sample data which is present in the buffer processor before starting to use it (for example when Pa_StartStream is called). When the buffer processor is no longer used call PaUtil_TerminateBufferProcessor.

Using the buffer processor for a callback stream

The buffer processor's role in a callback stream is to take host input buffers process them with the stream callback, and fill host output buffers. For a full duplex stream, the buffer processor handles input and output simultaneously due to the requirements of the minimum-latency buffer adation algorithm. When a host buffer becomes available, the implementation should call the buffer processor to process the buffer. The buffer processor calls the stream callback to consume and/or produce audio data as necessary. The buffer processor will convert sample formats, interleave/deinterleave channels, and slice or chunk the data to the appropriate buffer lengths according to the requirements of the stream callback and the host API. To process a host buffer (or a pair of host buffers for a full-duplex stream) use the following calling sequence: -# Call PaUtil_BeginBufferProcessing -# For a stream which takes input: - Call PaUtil_SetInputFrameCount with the number of frames in the host input buffer. - Call one of the following functions one or more times to tell the buffer processor about the host input buffer(s): PaUtil_SetInputChannel, PaUtil_SetInterleavedInputChannels, PaUtil_SetNonInterleavedInputChannel. Which function you call will depend on whether the host buffer(s) are interleaved or not. - If the available host data is split accross two buffers (for example a data range at the end of a circular buffer and another range at the beginning of the circular buffer), also call PaUtil_Set2ndInputFrameCount, PaUtil_Set2ndInputChannel, PaUtil_Set2ndInterleavedInputChannels, PaUtil_Set2ndNonInterleavedInputChannel as necessary to tell the buffer processor about the second buffer. -# For a stream which generates output: - Call PaUtil_SetOutputFrameCount with the number of frames in the host output buffer. - Call one of the following functions one or more times to tell the buffer processor about the host output buffer(s): PaUtil_SetOutputChannel, PaUtil_SetInterleavedOutputChannels, PaUtil_SetNonInterleavedOutputChannel. Which function you call will depend on whether the host buffer(s) are interleaved or not. - If the available host output buffer space is split accross two buffers (for example a data range at the end of a circular buffer and another range at the beginning of the circular buffer), call PaUtil_Set2ndOutputFrameCount, PaUtil_Set2ndOutputChannel, PaUtil_Set2ndInterleavedOutputChannels, PaUtil_Set2ndNonInterleavedOutputChannel as necessary to tell the buffer processor about the second buffer. -# Call PaUtil_EndBufferProcessing, this function performs the actual data conversion and processing.

Using the buffer processor for a blocking read/write stream

Blocking read/write streams use the buffer processor to convert and copy user output data to a host buffer, and to convert and copy host input data to the user's buffer. The buffer processor does not perform any buffer adaption. When using the buffer processor in a blocking read/write stream the input and output conversion are performed separately by the PaUtil_CopyInput and PaUtil_CopyOutput functions. To copy data from a host input buffer to the buffer(s) which the user supplies to Pa_ReadStream, use the following calling sequence. - Repeat the following three steps until the user buffer(s) have been filled with samples from the host input buffers: -# Call PaUtil_SetInputFrameCount with the number of frames in the host input buffer. -# Call one of the following functions one or more times to tell the buffer processor about the host input buffer(s): PaUtil_SetInputChannel, PaUtil_SetInterleavedInputChannels, PaUtil_SetNonInterleavedInputChannel. Which function you call will depend on whether the host buffer(s) are interleaved or not. -# Call PaUtil_CopyInput with the user buffer pointer (or a copy of the array of buffer pointers for a non-interleaved stream) passed to Pa_ReadStream, along with the number of frames in the user buffer(s). Be careful to pass a copy of the user buffer pointers to PaUtil_CopyInput because PaUtil_CopyInput advances the pointers to the start of the next region to copy. - PaUtil_CopyInput will not copy more data than is available in the host buffer(s), so the above steps need to be repeated until the user buffer(s) are full. To copy data to the host output buffer from the user buffers(s) supplied to Pa_WriteStream use the following calling sequence. - Repeat the following three steps until all frames from the user buffer(s) have been copied to the host API: -# Call PaUtil_SetOutputFrameCount with the number of frames in the host output buffer. -# Call one of the following functions one or more times to tell the buffer processor about the host output buffer(s): PaUtil_SetOutputChannel, PaUtil_SetInterleavedOutputChannels, PaUtil_SetNonInterleavedOutputChannel. Which function you call will depend on whether the host buffer(s) are interleaved or not. -# Call PaUtil_CopyOutput with the user buffer pointer (or a copy of the array of buffer pointers for a non-interleaved stream) passed to Pa_WriteStream, along with the number of frames in the user buffer(s). Be careful to pass a copy of the user buffer pointers to PaUtil_CopyOutput because PaUtil_CopyOutput advances the pointers to the start of the next region to copy. - PaUtil_CopyOutput will not copy more data than fits in the host buffer(s), so the above steps need to be repeated until all user data is copied. */ #include "portaudio.h" #include "pa_converters.h" #include "pa_dither.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** @brief Mode flag passed to PaUtil_InitializeBufferProcessor indicating the type of buffering that the host API uses. The mode used depends on whether the host API or the implementation manages the buffers, and how these buffers are used (scatter gather, circular buffer). */ typedef enum { /** The host buffer size is a fixed known size. */ paUtilFixedHostBufferSize, /** The host buffer size may vary, but has a known maximum size. */ paUtilBoundedHostBufferSize, /** Nothing is known about the host buffer size. */ paUtilUnknownHostBufferSize, /** The host buffer size varies, and the client does not require the buffer processor to consume all of the input and fill all of the output buffer. This is useful when the implementation has access to the host API's circular buffer and only needs to consume/fill some of it, not necessarily all of it, with each call to the buffer processor. This is the only mode where PaUtil_EndBufferProcessing() may not consume the whole buffer. */ paUtilVariableHostBufferSizePartialUsageAllowed }PaUtilHostBufferSizeMode; /** @brief An auxilliary data structure used internally by the buffer processor to represent host input and output buffers. */ typedef struct PaUtilChannelDescriptor{ void *data; unsigned int stride; /**< stride in samples, not bytes */ }PaUtilChannelDescriptor; /** @brief The main buffer processor data structure. Allocate one of these, initialize it with PaUtil_InitializeBufferProcessor and terminate it with PaUtil_TerminateBufferProcessor. */ typedef struct { unsigned long framesPerUserBuffer; unsigned long framesPerHostBuffer; PaUtilHostBufferSizeMode hostBufferSizeMode; int useNonAdaptingProcess; int userOutputSampleFormatIsEqualToHost; int userInputSampleFormatIsEqualToHost; unsigned long framesPerTempBuffer; unsigned int inputChannelCount; unsigned int bytesPerHostInputSample; unsigned int bytesPerUserInputSample; int userInputIsInterleaved; PaUtilConverter *inputConverter; PaUtilZeroer *inputZeroer; unsigned int outputChannelCount; unsigned int bytesPerHostOutputSample; unsigned int bytesPerUserOutputSample; int userOutputIsInterleaved; PaUtilConverter *outputConverter; PaUtilZeroer *outputZeroer; unsigned long initialFramesInTempInputBuffer; unsigned long initialFramesInTempOutputBuffer; void *tempInputBuffer; /**< used for slips, block adaption, and conversion. */ void **tempInputBufferPtrs; /**< storage for non-interleaved buffer pointers, NULL for interleaved user input */ unsigned long framesInTempInputBuffer; /**< frames remaining in input buffer from previous adaption iteration */ void *tempOutputBuffer; /**< used for slips, block adaption, and conversion. */ void **tempOutputBufferPtrs; /**< storage for non-interleaved buffer pointers, NULL for interleaved user output */ unsigned long framesInTempOutputBuffer; /**< frames remaining in input buffer from previous adaption iteration */ PaStreamCallbackTimeInfo *timeInfo; PaStreamCallbackFlags callbackStatusFlags; int hostInputIsInterleaved; unsigned long hostInputFrameCount[2]; PaUtilChannelDescriptor *hostInputChannels[2]; /**< pointers to arrays of channel descriptors. pointers are NULL for half-duplex output processing. hostInputChannels[i].data is NULL when the caller calls PaUtil_SetNoInput() */ int hostOutputIsInterleaved; unsigned long hostOutputFrameCount[2]; PaUtilChannelDescriptor *hostOutputChannels[2]; /**< pointers to arrays of channel descriptors. pointers are NULL for half-duplex input processing. hostOutputChannels[i].data is NULL when the caller calls PaUtil_SetNoOutput() */ PaUtilTriangularDitherGenerator ditherGenerator; double samplePeriod; PaStreamCallback *streamCallback; void *userData; } PaUtilBufferProcessor; /** @name Initialization, termination, resetting and info */ /*@{*/ /** Initialize a buffer processor's representation stored in a PaUtilBufferProcessor structure. Be sure to call PaUtil_TerminateBufferProcessor after finishing with a buffer processor. @param bufferProcessor The buffer processor structure to initialize. @param inputChannelCount The number of input channels as passed to Pa_OpenStream or 0 for an output-only stream. @param userInputSampleFormat Format of user input samples, as passed to Pa_OpenStream. This parameter is ignored for ouput-only streams. @param hostInputSampleFormat Format of host input samples. This parameter is ignored for output-only streams. See note about host buffer interleave below. @param outputChannelCount The number of output channels as passed to Pa_OpenStream or 0 for an input-only stream. @param userOutputSampleFormat Format of user output samples, as passed to Pa_OpenStream. This parameter is ignored for input-only streams. @param hostOutputSampleFormat Format of host output samples. This parameter is ignored for input-only streams. See note about host buffer interleave below. @param sampleRate Sample rate of the stream. The more accurate this is the better - it is used for updating time stamps when adapting buffers. @param streamFlags Stream flags as passed to Pa_OpenStream, this parameter is used for selecting special sample conversion options such as clipping and dithering. @param framesPerUserBuffer Number of frames per user buffer, as requested by the framesPerBuffer parameter to Pa_OpenStream. This parameter may be zero to indicate that the user will accept any (and varying) buffer sizes. @param framesPerHostBuffer Specifies the number of frames per host buffer for the fixed buffer size mode, and the maximum number of frames per host buffer for the bounded host buffer size mode. It is ignored for the other modes. @param hostBufferSizeMode A mode flag indicating the size variability of host buffers that will be passed to the buffer processor. See PaUtilHostBufferSizeMode for further details. @param streamCallback The user stream callback passed to Pa_OpenStream. @param userData The user data field passed to Pa_OpenStream. @note The interleave flag is ignored for host buffer formats. Host interleave is determined by the use of different SetInput and SetOutput functions. @return An error code indicating whether the initialization was successful. If the error code is not PaNoError, the buffer processor was not initialized and should not be used. @see Pa_OpenStream, PaUtilHostBufferSizeMode, PaUtil_TerminateBufferProcessor */ PaError PaUtil_InitializeBufferProcessor( PaUtilBufferProcessor* bufferProcessor, int inputChannelCount, PaSampleFormat userInputSampleFormat, PaSampleFormat hostInputSampleFormat, int outputChannelCount, PaSampleFormat userOutputSampleFormat, PaSampleFormat hostOutputSampleFormat, double sampleRate, PaStreamFlags streamFlags, unsigned long framesPerUserBuffer, /* 0 indicates don't care */ unsigned long framesPerHostBuffer, PaUtilHostBufferSizeMode hostBufferSizeMode, PaStreamCallback *streamCallback, void *userData ); /** Terminate a buffer processor's representation. Deallocates any temporary buffers allocated by PaUtil_InitializeBufferProcessor. @param bufferProcessor The buffer processor structure to terminate. @see PaUtil_InitializeBufferProcessor. */ void PaUtil_TerminateBufferProcessor( PaUtilBufferProcessor* bufferProcessor ); /** Clear any internally buffered data. If you call PaUtil_InitializeBufferProcessor in your OpenStream routine, make sure you call PaUtil_ResetBufferProcessor in your StartStream call. @param bufferProcessor The buffer processor to reset. */ void PaUtil_ResetBufferProcessor( PaUtilBufferProcessor* bufferProcessor ); /** Retrieve the input latency of a buffer processor, in frames. @param bufferProcessor The buffer processor examine. @return The input latency introduced by the buffer processor, in frames. @see PaUtil_GetBufferProcessorOutputLatencyFrames */ unsigned long PaUtil_GetBufferProcessorInputLatencyFrames( PaUtilBufferProcessor* bufferProcessor ); /** Retrieve the output latency of a buffer processor, in frames. @param bufferProcessor The buffer processor examine. @return The output latency introduced by the buffer processor, in frames. @see PaUtil_GetBufferProcessorInputLatencyFrames */ unsigned long PaUtil_GetBufferProcessorOutputLatencyFrames( PaUtilBufferProcessor* bufferProcessor ); /*@}*/ /** @name Host buffer pointer configuration Functions to set host input and output buffers, used by both callback streams and blocking read/write streams. */ /*@{*/ /** Set the number of frames in the input host buffer(s) specified by the PaUtil_Set*InputChannel functions. @param bufferProcessor The buffer processor. @param frameCount The number of host input frames. A 0 frameCount indicates to use the framesPerHostBuffer value passed to PaUtil_InitializeBufferProcessor. @see PaUtil_SetNoInput, PaUtil_SetInputChannel, PaUtil_SetInterleavedInputChannels, PaUtil_SetNonInterleavedInputChannel */ void PaUtil_SetInputFrameCount( PaUtilBufferProcessor* bufferProcessor, unsigned long frameCount ); /** Indicate that no input is avalable. This function should be used when priming the output of a full-duplex stream opened with the paPrimeOutputBuffersUsingStreamCallback flag. Note that it is not necessary to call this or any othe PaUtil_Set*Input* functions for ouput-only streams. @param bufferProcessor The buffer processor. */ void PaUtil_SetNoInput( PaUtilBufferProcessor* bufferProcessor ); /** Provide the buffer processor with a pointer to a host input channel. @param bufferProcessor The buffer processor. @param channel The channel number. @param data The buffer. @param stride The stride from one sample to the next, in samples. For interleaved host buffers, the stride will usually be the same as the number of channels in the buffer. */ void PaUtil_SetInputChannel( PaUtilBufferProcessor* bufferProcessor, unsigned int channel, void *data, unsigned int stride ); /** Provide the buffer processor with a pointer to an number of interleaved host input channels. @param bufferProcessor The buffer processor. @param firstChannel The first channel number. @param data The buffer. @param channelCount The number of interleaved channels in the buffer. If channelCount is zero, the number of channels specified to PaUtil_InitializeBufferProcessor will be used. */ void PaUtil_SetInterleavedInputChannels( PaUtilBufferProcessor* bufferProcessor, unsigned int firstChannel, void *data, unsigned int channelCount ); /** Provide the buffer processor with a pointer to one non-interleaved host output channel. @param bufferProcessor The buffer processor. @param channel The channel number. @param data The buffer. */ void PaUtil_SetNonInterleavedInputChannel( PaUtilBufferProcessor* bufferProcessor, unsigned int channel, void *data ); /** Use for the second buffer half when the input buffer is split in two halves. @see PaUtil_SetInputFrameCount */ void PaUtil_Set2ndInputFrameCount( PaUtilBufferProcessor* bufferProcessor, unsigned long frameCount ); /** Use for the second buffer half when the input buffer is split in two halves. @see PaUtil_SetInputChannel */ void PaUtil_Set2ndInputChannel( PaUtilBufferProcessor* bufferProcessor, unsigned int channel, void *data, unsigned int stride ); /** Use for the second buffer half when the input buffer is split in two halves. @see PaUtil_SetInterleavedInputChannels */ void PaUtil_Set2ndInterleavedInputChannels( PaUtilBufferProcessor* bufferProcessor, unsigned int firstChannel, void *data, unsigned int channelCount ); /** Use for the second buffer half when the input buffer is split in two halves. @see PaUtil_SetNonInterleavedInputChannel */ void PaUtil_Set2ndNonInterleavedInputChannel( PaUtilBufferProcessor* bufferProcessor, unsigned int channel, void *data ); /** Set the number of frames in the output host buffer(s) specified by the PaUtil_Set*OutputChannel functions. @param bufferProcessor The buffer processor. @param frameCount The number of host output frames. A 0 frameCount indicates to use the framesPerHostBuffer value passed to PaUtil_InitializeBufferProcessor. @see PaUtil_SetOutputChannel, PaUtil_SetInterleavedOutputChannels, PaUtil_SetNonInterleavedOutputChannel */ void PaUtil_SetOutputFrameCount( PaUtilBufferProcessor* bufferProcessor, unsigned long frameCount ); /** Indicate that the output will be discarded. This function should be used when implementing the paNeverDropInput mode for full duplex streams. @param bufferProcessor The buffer processor. */ void PaUtil_SetNoOutput( PaUtilBufferProcessor* bufferProcessor ); /** Provide the buffer processor with a pointer to a host output channel. @param bufferProcessor The buffer processor. @param channel The channel number. @param data The buffer. @param stride The stride from one sample to the next, in samples. For interleaved host buffers, the stride will usually be the same as the number of channels in the buffer. */ void PaUtil_SetOutputChannel( PaUtilBufferProcessor* bufferProcessor, unsigned int channel, void *data, unsigned int stride ); /** Provide the buffer processor with a pointer to a number of interleaved host output channels. @param bufferProcessor The buffer processor. @param firstChannel The first channel number. @param data The buffer. @param channelCount The number of interleaved channels in the buffer. If channelCount is zero, the number of channels specified to PaUtil_InitializeBufferProcessor will be used. */ void PaUtil_SetInterleavedOutputChannels( PaUtilBufferProcessor* bufferProcessor, unsigned int firstChannel, void *data, unsigned int channelCount ); /** Provide the buffer processor with a pointer to one non-interleaved host output channel. @param bufferProcessor The buffer processor. @param channel The channel number. @param data The buffer. */ void PaUtil_SetNonInterleavedOutputChannel( PaUtilBufferProcessor* bufferProcessor, unsigned int channel, void *data ); /** Use for the second buffer half when the output buffer is split in two halves. @see PaUtil_SetOutputFrameCount */ void PaUtil_Set2ndOutputFrameCount( PaUtilBufferProcessor* bufferProcessor, unsigned long frameCount ); /** Use for the second buffer half when the output buffer is split in two halves. @see PaUtil_SetOutputChannel */ void PaUtil_Set2ndOutputChannel( PaUtilBufferProcessor* bufferProcessor, unsigned int channel, void *data, unsigned int stride ); /** Use for the second buffer half when the output buffer is split in two halves. @see PaUtil_SetInterleavedOutputChannels */ void PaUtil_Set2ndInterleavedOutputChannels( PaUtilBufferProcessor* bufferProcessor, unsigned int firstChannel, void *data, unsigned int channelCount ); /** Use for the second buffer half when the output buffer is split in two halves. @see PaUtil_SetNonInterleavedOutputChannel */ void PaUtil_Set2ndNonInterleavedOutputChannel( PaUtilBufferProcessor* bufferProcessor, unsigned int channel, void *data ); /*@}*/ /** @name Buffer processing functions for callback streams */ /*@{*/ /** Commence processing a host buffer (or a pair of host buffers in the full-duplex case) for a callback stream. @param bufferProcessor The buffer processor. @param timeInfo Timing information for the first sample of the host buffer(s). This information may be adjusted when buffer adaption is being performed. @param callbackStatusFlags Flags indicating whether underruns and overruns have occurred since the last time the buffer processor was called. */ void PaUtil_BeginBufferProcessing( PaUtilBufferProcessor* bufferProcessor, PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags callbackStatusFlags ); /** Finish processing a host buffer (or a pair of host buffers in the full-duplex case) for a callback stream. @param bufferProcessor The buffer processor. @param callbackResult On input, indicates a previous callback result, and on exit, the result of the user stream callback, if it is called. On entry callbackResult should contain one of { paContinue, paComplete, or paAbort}. If paComplete is passed, the stream callback will not be called but any audio that was generated by previous stream callbacks will be copied to the output buffer(s). You can check whether the buffer processor's internal buffer is empty by calling PaUtil_IsBufferProcessorOutputEmpty. If the stream callback is called its result is stored in *callbackResult. If the stream callback returns paComplete or paAbort, all output buffers will be full of valid data - some of which may be zeros to acount for data that wasn't generated by the terminating callback. @return The number of frames processed. This usually corresponds to the number of frames specified by the PaUtil_Set*FrameCount functions, exept in the paUtilVariableHostBufferSizePartialUsageAllowed buffer size mode when a smaller value may be returned. */ unsigned long PaUtil_EndBufferProcessing( PaUtilBufferProcessor* bufferProcessor, int *callbackResult ); /** Determine whether any callback generated output remains in the bufffer processor's internal buffers. This method may be used to determine when to continue calling PaUtil_EndBufferProcessing() after the callback has returned a callbackResult of paComplete. @param bufferProcessor The buffer processor. @return Returns non-zero when callback generated output remains in the internal buffer and zero (0) when there internal buffer contains no callback generated data. */ int PaUtil_IsBufferProcessorOutputEmpty( PaUtilBufferProcessor* bufferProcessor ); /*@}*/ /** @name Buffer processing functions for blocking read/write streams */ /*@{*/ /** Copy samples from host input channels set up by the PaUtil_Set*InputChannels functions to a user supplied buffer. This function is intended for use with blocking read/write streams. Copies the minimum of the number of user frames (specified by the frameCount parameter) and the number of available host frames (specified in a previous call to SetInputFrameCount()). @param bufferProcessor The buffer processor. @param buffer A pointer to the user buffer pointer, or a pointer to a pointer to an array of user buffer pointers for a non-interleaved stream. It is important that this parameter points to a copy of the user buffer pointers, not to the actual user buffer pointers, because this function updates the pointers before returning. @param frameCount The number of frames of data in the buffer(s) pointed to by the buffer parameter. @return The number of frames copied. The buffer pointer(s) pointed to by the buffer parameter are advanced to point to the frame(s) following the last one filled. */ unsigned long PaUtil_CopyInput( PaUtilBufferProcessor* bufferProcessor, void **buffer, unsigned long frameCount ); /* Copy samples from a user supplied buffer to host output channels set up by the PaUtil_Set*OutputChannels functions. This function is intended for use with blocking read/write streams. Copies the minimum of the number of user frames (specified by the frameCount parameter) and the number of host frames (specified in a previous call to SetOutputFrameCount()). @param bufferProcessor The buffer processor. @param buffer A pointer to the user buffer pointer, or a pointer to a pointer to an array of user buffer pointers for a non-interleaved stream. It is important that this parameter points to a copy of the user buffer pointers, not to the actual user buffer pointers, because this function updates the pointers before returning. @param frameCount The number of frames of data in the buffer(s) pointed to by the buffer parameter. @return The number of frames copied. The buffer pointer(s) pointed to by the buffer parameter are advanced to point to the frame(s) following the last one copied. */ unsigned long PaUtil_CopyOutput( PaUtilBufferProcessor* bufferProcessor, const void ** buffer, unsigned long frameCount ); /* Zero samples in host output channels set up by the PaUtil_Set*OutputChannels functions. This function is useful for flushing streams. Zeros the minimum of frameCount and the number of host frames specified in a previous call to SetOutputFrameCount(). @param bufferProcessor The buffer processor. @param frameCount The maximum number of frames to zero. @return The number of frames zeroed. */ unsigned long PaUtil_ZeroOutput( PaUtilBufferProcessor* bufferProcessor, unsigned long frameCount ); /*@}*/ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_PROCESS_H */ pd-0.46-7/portaudio/src/common/pa_ringbuffer.c0000664000175000017500000002235512222201037017434 0ustar mspmsp/* * $Id: pa_ringbuffer.c 1738 2011-08-18 11:47:28Z rossb $ * Portable Audio I/O Library * Ring Buffer utility. * * Author: Phil Burk, http://www.softsynth.com * modified for SMP safety on Mac OS X by Bjorn Roche * modified for SMP safety on Linux by Leland Lucius * also, allowed for const where possible * modified for multiple-byte-sized data elements by Sven Fischer * * Note that this is safe only for a single-thread reader and a * single-thread writer. * * This program uses the PortAudio Portable Audio Library. * For more information see: http://www.portaudio.com * Copyright (c) 1999-2000 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src */ #include #include #include #include "pa_ringbuffer.h" #include #include "pa_memorybarrier.h" /*************************************************************************** * Initialize FIFO. * elementCount must be power of 2, returns -1 if not. */ ring_buffer_size_t PaUtil_InitializeRingBuffer( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementSizeBytes, ring_buffer_size_t elementCount, void *dataPtr ) { if( ((elementCount-1) & elementCount) != 0) return -1; /* Not Power of two. */ rbuf->bufferSize = elementCount; rbuf->buffer = (char *)dataPtr; PaUtil_FlushRingBuffer( rbuf ); rbuf->bigMask = (elementCount*2)-1; rbuf->smallMask = (elementCount)-1; rbuf->elementSizeBytes = elementSizeBytes; return 0; } /*************************************************************************** ** Return number of elements available for reading. */ ring_buffer_size_t PaUtil_GetRingBufferReadAvailable( const PaUtilRingBuffer *rbuf ) { return ( (rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask ); } /*************************************************************************** ** Return number of elements available for writing. */ ring_buffer_size_t PaUtil_GetRingBufferWriteAvailable( const PaUtilRingBuffer *rbuf ) { return ( rbuf->bufferSize - PaUtil_GetRingBufferReadAvailable(rbuf)); } /*************************************************************************** ** Clear buffer. Should only be called when buffer is NOT being read or written. */ void PaUtil_FlushRingBuffer( PaUtilRingBuffer *rbuf ) { rbuf->writeIndex = rbuf->readIndex = 0; } /*************************************************************************** ** Get address of region(s) to which we can write data. ** If the region is contiguous, size2 will be zero. ** If non-contiguous, size2 will be the size of second region. ** Returns room available to be written or elementCount, whichever is smaller. */ ring_buffer_size_t PaUtil_GetRingBufferWriteRegions( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount, void **dataPtr1, ring_buffer_size_t *sizePtr1, void **dataPtr2, ring_buffer_size_t *sizePtr2 ) { ring_buffer_size_t index; ring_buffer_size_t available = PaUtil_GetRingBufferWriteAvailable( rbuf ); if( elementCount > available ) elementCount = available; /* Check to see if write is not contiguous. */ index = rbuf->writeIndex & rbuf->smallMask; if( (index + elementCount) > rbuf->bufferSize ) { /* Write data in two blocks that wrap the buffer. */ ring_buffer_size_t firstHalf = rbuf->bufferSize - index; *dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes]; *sizePtr1 = firstHalf; *dataPtr2 = &rbuf->buffer[0]; *sizePtr2 = elementCount - firstHalf; } else { *dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes]; *sizePtr1 = elementCount; *dataPtr2 = NULL; *sizePtr2 = 0; } if( available ) PaUtil_FullMemoryBarrier(); /* (write-after-read) => full barrier */ return elementCount; } /*************************************************************************** */ ring_buffer_size_t PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount ) { /* ensure that previous writes are seen before we update the write index (write after write) */ PaUtil_WriteMemoryBarrier(); return rbuf->writeIndex = (rbuf->writeIndex + elementCount) & rbuf->bigMask; } /*************************************************************************** ** Get address of region(s) from which we can read data. ** If the region is contiguous, size2 will be zero. ** If non-contiguous, size2 will be the size of second region. ** Returns room available to be read or elementCount, whichever is smaller. */ ring_buffer_size_t PaUtil_GetRingBufferReadRegions( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount, void **dataPtr1, ring_buffer_size_t *sizePtr1, void **dataPtr2, ring_buffer_size_t *sizePtr2 ) { ring_buffer_size_t index; ring_buffer_size_t available = PaUtil_GetRingBufferReadAvailable( rbuf ); /* doesn't use memory barrier */ if( elementCount > available ) elementCount = available; /* Check to see if read is not contiguous. */ index = rbuf->readIndex & rbuf->smallMask; if( (index + elementCount) > rbuf->bufferSize ) { /* Write data in two blocks that wrap the buffer. */ ring_buffer_size_t firstHalf = rbuf->bufferSize - index; *dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes]; *sizePtr1 = firstHalf; *dataPtr2 = &rbuf->buffer[0]; *sizePtr2 = elementCount - firstHalf; } else { *dataPtr1 = &rbuf->buffer[index*rbuf->elementSizeBytes]; *sizePtr1 = elementCount; *dataPtr2 = NULL; *sizePtr2 = 0; } if( available ) PaUtil_ReadMemoryBarrier(); /* (read-after-read) => read barrier */ return elementCount; } /*************************************************************************** */ ring_buffer_size_t PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount ) { /* ensure that previous reads (copies out of the ring buffer) are always completed before updating (writing) the read index. (write-after-read) => full barrier */ PaUtil_FullMemoryBarrier(); return rbuf->readIndex = (rbuf->readIndex + elementCount) & rbuf->bigMask; } /*************************************************************************** ** Return elements written. */ ring_buffer_size_t PaUtil_WriteRingBuffer( PaUtilRingBuffer *rbuf, const void *data, ring_buffer_size_t elementCount ) { ring_buffer_size_t size1, size2, numWritten; void *data1, *data2; numWritten = PaUtil_GetRingBufferWriteRegions( rbuf, elementCount, &data1, &size1, &data2, &size2 ); if( size2 > 0 ) { memcpy( data1, data, size1*rbuf->elementSizeBytes ); data = ((char *)data) + size1*rbuf->elementSizeBytes; memcpy( data2, data, size2*rbuf->elementSizeBytes ); } else { memcpy( data1, data, size1*rbuf->elementSizeBytes ); } PaUtil_AdvanceRingBufferWriteIndex( rbuf, numWritten ); return numWritten; } /*************************************************************************** ** Return elements read. */ ring_buffer_size_t PaUtil_ReadRingBuffer( PaUtilRingBuffer *rbuf, void *data, ring_buffer_size_t elementCount ) { ring_buffer_size_t size1, size2, numRead; void *data1, *data2; numRead = PaUtil_GetRingBufferReadRegions( rbuf, elementCount, &data1, &size1, &data2, &size2 ); if( size2 > 0 ) { memcpy( data, data1, size1*rbuf->elementSizeBytes ); data = ((char *)data) + size1*rbuf->elementSizeBytes; memcpy( data, data2, size2*rbuf->elementSizeBytes ); } else { memcpy( data, data1, size1*rbuf->elementSizeBytes ); } PaUtil_AdvanceRingBufferReadIndex( rbuf, numRead ); return numRead; } pd-0.46-7/portaudio/src/common/pa_allocation.h0000664000175000017500000000743012160204055017436 0ustar mspmsp#ifndef PA_ALLOCATION_H #define PA_ALLOCATION_H /* * $Id: pa_allocation.h 1339 2008-02-15 07:50:33Z rossb $ * Portable Audio I/O Library allocation context header * memory allocation context for tracking allocation groups * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2008 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Allocation Group prototypes. An Allocation Group makes it easy to allocate multiple blocks of memory and free them all at once. An allocation group is useful for keeping track of multiple blocks of memory which are allocated at the same time (such as during initialization) and need to be deallocated at the same time. The allocation group maintains a list of allocated blocks, and can free all allocations at once. This can be usefull for cleaning up after a partially initialized object fails. The allocation group implementation is built on top of the lower level allocation functions defined in pa_util.h */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ typedef struct { long linkCount; struct PaUtilAllocationGroupLink *linkBlocks; struct PaUtilAllocationGroupLink *spareLinks; struct PaUtilAllocationGroupLink *allocations; }PaUtilAllocationGroup; /** Create an allocation group. */ PaUtilAllocationGroup* PaUtil_CreateAllocationGroup( void ); /** Destroy an allocation group, but not the memory allocated through the group. */ void PaUtil_DestroyAllocationGroup( PaUtilAllocationGroup* group ); /** Allocate a block of memory though an allocation group. */ void* PaUtil_GroupAllocateMemory( PaUtilAllocationGroup* group, long size ); /** Free a block of memory that was previously allocated though an allocation group. Calling this function is a relatively time consuming operation. Under normal circumstances clients should call PaUtil_FreeAllAllocations to free all allocated blocks simultaneously. @see PaUtil_FreeAllAllocations */ void PaUtil_GroupFreeMemory( PaUtilAllocationGroup* group, void *buffer ); /** Free all blocks of memory which have been allocated through the allocation group. This function doesn't destroy the group itself. */ void PaUtil_FreeAllAllocations( PaUtilAllocationGroup* group ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_ALLOCATION_H */ pd-0.46-7/portaudio/src/common/pa_allocation.c0000664000175000017500000001540512160204055017432 0ustar mspmsp/* * $Id: pa_allocation.c 1097 2006-08-26 08:27:53Z rossb $ * Portable Audio I/O Library allocation group implementation * memory allocation group for tracking allocation groups * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Allocation Group implementation. */ #include "pa_allocation.h" #include "pa_util.h" /* Maintain 3 singly linked lists... linkBlocks: the buffers used to allocate the links spareLinks: links available for use in the allocations list allocations: the buffers currently allocated using PaUtil_ContextAllocateMemory() Link block size is doubled every time new links are allocated. */ #define PA_INITIAL_LINK_COUNT_ 16 struct PaUtilAllocationGroupLink { struct PaUtilAllocationGroupLink *next; void *buffer; }; /* Allocate a block of links. The first link will have it's buffer member pointing to the block, and it's next member set to . The remaining links will have NULL buffer members, and each link will point to the next link except the last, which will point to */ static struct PaUtilAllocationGroupLink *AllocateLinks( long count, struct PaUtilAllocationGroupLink *nextBlock, struct PaUtilAllocationGroupLink *nextSpare ) { struct PaUtilAllocationGroupLink *result; int i; result = (struct PaUtilAllocationGroupLink *)PaUtil_AllocateMemory( sizeof(struct PaUtilAllocationGroupLink) * count ); if( result ) { /* the block link */ result[0].buffer = result; result[0].next = nextBlock; /* the spare links */ for( i=1; ilinkCount = PA_INITIAL_LINK_COUNT_; result->linkBlocks = &links[0]; result->spareLinks = &links[1]; result->allocations = 0; } else { PaUtil_FreeMemory( links ); } } return result; } void PaUtil_DestroyAllocationGroup( PaUtilAllocationGroup* group ) { struct PaUtilAllocationGroupLink *current = group->linkBlocks; struct PaUtilAllocationGroupLink *next; while( current ) { next = current->next; PaUtil_FreeMemory( current->buffer ); current = next; } PaUtil_FreeMemory( group ); } void* PaUtil_GroupAllocateMemory( PaUtilAllocationGroup* group, long size ) { struct PaUtilAllocationGroupLink *links, *link; void *result = 0; /* allocate more links if necessary */ if( !group->spareLinks ) { /* double the link count on each block allocation */ links = AllocateLinks( group->linkCount, group->linkBlocks, group->spareLinks ); if( links ) { group->linkCount += group->linkCount; group->linkBlocks = &links[0]; group->spareLinks = &links[1]; } } if( group->spareLinks ) { result = PaUtil_AllocateMemory( size ); if( result ) { link = group->spareLinks; group->spareLinks = link->next; link->buffer = result; link->next = group->allocations; group->allocations = link; } } return result; } void PaUtil_GroupFreeMemory( PaUtilAllocationGroup* group, void *buffer ) { struct PaUtilAllocationGroupLink *current = group->allocations; struct PaUtilAllocationGroupLink *previous = 0; if( buffer == 0 ) return; /* find the right link and remove it */ while( current ) { if( current->buffer == buffer ) { if( previous ) { previous->next = current->next; } else { group->allocations = current->next; } current->buffer = 0; current->next = group->spareLinks; group->spareLinks = current; break; } previous = current; current = current->next; } PaUtil_FreeMemory( buffer ); /* free the memory whether we found it in the list or not */ } void PaUtil_FreeAllAllocations( PaUtilAllocationGroup* group ) { struct PaUtilAllocationGroupLink *current = group->allocations; struct PaUtilAllocationGroupLink *previous = 0; /* free all buffers in the allocations list */ while( current ) { PaUtil_FreeMemory( current->buffer ); current->buffer = 0; previous = current; current = current->next; } /* link the former allocations list onto the front of the spareLinks list */ if( previous ) { previous->next = group->spareLinks; group->spareLinks = group->allocations; group->allocations = 0; } } pd-0.46-7/portaudio/src/common/pa_dither.h0000664000175000017500000000677612160204055016604 0ustar mspmsp#ifndef PA_DITHER_H #define PA_DITHER_H /* * $Id: pa_dither.h 1418 2009-10-12 21:00:53Z philburk $ * Portable Audio I/O Library triangular dither generator * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Phil Burk, Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Functions for generating dither noise */ #include "pa_types.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* Note that the linear congruential algorithm requires 32 bit integers * because it uses arithmetic overflow. So use PaUint32 instead of * unsigned long so it will work on 64 bit systems. */ /** @brief State needed to generate a dither signal */ typedef struct PaUtilTriangularDitherGenerator{ PaUint32 previous; PaUint32 randSeed1; PaUint32 randSeed2; } PaUtilTriangularDitherGenerator; /** @brief Initialize dither state */ void PaUtil_InitializeTriangularDitherState( PaUtilTriangularDitherGenerator *ditherState ); /** @brief Calculate 2 LSB dither signal with a triangular distribution. Ranged for adding to a 1 bit right-shifted 32 bit integer prior to >>15. eg:
    signed long in = *
    signed long dither = PaUtil_Generate16BitTriangularDither( ditherState );
    signed short out = (signed short)(((in>>1) + dither) >> 15);
@return A signed 32-bit integer with a range of +32767 to -32768 */ PaInt32 PaUtil_Generate16BitTriangularDither( PaUtilTriangularDitherGenerator *ditherState ); /** @brief Calculate 2 LSB dither signal with a triangular distribution. Ranged for adding to a pre-scaled float.
    float in = *
    float dither = PaUtil_GenerateFloatTriangularDither( ditherState );
    // use smaller scaler to prevent overflow when we add the dither
    signed short out = (signed short)(in*(32766.0f) + dither );
@return A float with a range of -2.0 to +1.99999. */ float PaUtil_GenerateFloatTriangularDither( PaUtilTriangularDitherGenerator *ditherState ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_DITHER_H */ pd-0.46-7/portaudio/src/common/pa_memorybarrier.h0000664000175000017500000001353112222201037020163 0ustar mspmsp/* * $Id: pa_memorybarrier.h 1240 2007-07-17 13:05:07Z bjornroche $ * Portable Audio I/O Library * Memory barrier utilities * * Author: Bjorn Roche, XO Audio, LLC * * This program uses the PortAudio Portable Audio Library. * For more information see: http://www.portaudio.com * Copyright (c) 1999-2000 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file pa_memorybarrier.h @ingroup common_src */ /**************** * Some memory barrier primitives based on the system. * right now only OS X, FreeBSD, and Linux are supported. In addition to providing * memory barriers, these functions should ensure that data cached in registers * is written out to cache where it can be snooped by other CPUs. (ie, the volatile * keyword should not be required) * * the primitives that must be defined are: * * PaUtil_FullMemoryBarrier() * PaUtil_ReadMemoryBarrier() * PaUtil_WriteMemoryBarrier() * ****************/ #if defined(__APPLE__) # include /* Here are the memory barrier functions. Mac OS X only provides full memory barriers, so the three types of barriers are the same, however, these barriers are superior to compiler-based ones. */ # define PaUtil_FullMemoryBarrier() OSMemoryBarrier() # define PaUtil_ReadMemoryBarrier() OSMemoryBarrier() # define PaUtil_WriteMemoryBarrier() OSMemoryBarrier() #elif defined(__GNUC__) /* GCC >= 4.1 has built-in intrinsics. We'll use those */ # if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) # define PaUtil_FullMemoryBarrier() __sync_synchronize() # define PaUtil_ReadMemoryBarrier() __sync_synchronize() # define PaUtil_WriteMemoryBarrier() __sync_synchronize() /* as a fallback, GCC understands volatile asm and "memory" to mean it * should not reorder memory read/writes */ /* Note that it is not clear that any compiler actually defines __PPC__, * it can probably removed safely. */ # elif defined( __ppc__ ) || defined( __powerpc__) || defined( __PPC__ ) # define PaUtil_FullMemoryBarrier() asm volatile("sync":::"memory") # define PaUtil_ReadMemoryBarrier() asm volatile("sync":::"memory") # define PaUtil_WriteMemoryBarrier() asm volatile("sync":::"memory") # elif defined( __i386__ ) || defined( __i486__ ) || defined( __i586__ ) || \ defined( __i686__ ) || defined( __x86_64__ ) # define PaUtil_FullMemoryBarrier() asm volatile("mfence":::"memory") # define PaUtil_ReadMemoryBarrier() asm volatile("lfence":::"memory") # define PaUtil_WriteMemoryBarrier() asm volatile("sfence":::"memory") # else # ifdef ALLOW_SMP_DANGERS # warning Memory barriers not defined on this system or system unknown # warning For SMP safety, you should fix this. # define PaUtil_FullMemoryBarrier() # define PaUtil_ReadMemoryBarrier() # define PaUtil_WriteMemoryBarrier() # else # error Memory barriers are not defined on this system. You can still compile by defining ALLOW_SMP_DANGERS, but SMP safety will not be guaranteed. # endif # endif #elif (_MSC_VER >= 1400) && !defined(_WIN32_WCE) # include # pragma intrinsic(_ReadWriteBarrier) # pragma intrinsic(_ReadBarrier) # pragma intrinsic(_WriteBarrier) /* note that MSVC intrinsics _ReadWriteBarrier(), _ReadBarrier(), _WriteBarrier() are just compiler barriers *not* memory barriers */ # define PaUtil_FullMemoryBarrier() _ReadWriteBarrier() # define PaUtil_ReadMemoryBarrier() _ReadBarrier() # define PaUtil_WriteMemoryBarrier() _WriteBarrier() #elif defined(_WIN32_WCE) # define PaUtil_FullMemoryBarrier() # define PaUtil_ReadMemoryBarrier() # define PaUtil_WriteMemoryBarrier() #elif defined(_MSC_VER) || defined(__BORLANDC__) # define PaUtil_FullMemoryBarrier() _asm { lock add [esp], 0 } # define PaUtil_ReadMemoryBarrier() _asm { lock add [esp], 0 } # define PaUtil_WriteMemoryBarrier() _asm { lock add [esp], 0 } #else # ifdef ALLOW_SMP_DANGERS # warning Memory barriers not defined on this system or system unknown # warning For SMP safety, you should fix this. # define PaUtil_FullMemoryBarrier() # define PaUtil_ReadMemoryBarrier() # define PaUtil_WriteMemoryBarrier() # else # error Memory barriers are not defined on this system. You can still compile by defining ALLOW_SMP_DANGERS, but SMP safety will not be guaranteed. # endif #endif pd-0.46-7/portaudio/src/common/pa_dither.c0000664000175000017500000001601112160204055016556 0ustar mspmsp/* * $Id: pa_dither.c 1418 2009-10-12 21:00:53Z philburk $ * Portable Audio I/O Library triangular dither generator * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Phil Burk, Ross Bencina * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Functions for generating dither noise */ #include "pa_types.h" #include "pa_dither.h" /* Note that the linear congruential algorithm requires 32 bit integers * because it uses arithmetic overflow. So use PaUint32 instead of * unsigned long so it will work on 64 bit systems. */ #define PA_DITHER_BITS_ (15) void PaUtil_InitializeTriangularDitherState( PaUtilTriangularDitherGenerator *state ) { state->previous = 0; state->randSeed1 = 22222; state->randSeed2 = 5555555; } PaInt32 PaUtil_Generate16BitTriangularDither( PaUtilTriangularDitherGenerator *state ) { PaInt32 current, highPass; /* Generate two random numbers. */ state->randSeed1 = (state->randSeed1 * 196314165) + 907633515; state->randSeed2 = (state->randSeed2 * 196314165) + 907633515; /* Generate triangular distribution about 0. * Shift before adding to prevent overflow which would skew the distribution. * Also shift an extra bit for the high pass filter. */ #define DITHER_SHIFT_ ((sizeof(PaInt32)*8 - PA_DITHER_BITS_) + 1) current = (((PaInt32)state->randSeed1)>>DITHER_SHIFT_) + (((PaInt32)state->randSeed2)>>DITHER_SHIFT_); /* High pass filter to reduce audibility. */ highPass = current - state->previous; state->previous = current; return highPass; } /* Multiply by PA_FLOAT_DITHER_SCALE_ to get a float between -2.0 and +1.99999 */ #define PA_FLOAT_DITHER_SCALE_ (1.0f / ((1<randSeed1 = (state->randSeed1 * 196314165) + 907633515; state->randSeed2 = (state->randSeed2 * 196314165) + 907633515; /* Generate triangular distribution about 0. * Shift before adding to prevent overflow which would skew the distribution. * Also shift an extra bit for the high pass filter. */ current = (((PaInt32)state->randSeed1)>>DITHER_SHIFT_) + (((PaInt32)state->randSeed2)>>DITHER_SHIFT_); /* High pass filter to reduce audibility. */ highPass = current - state->previous; state->previous = current; return ((float)highPass) * const_float_dither_scale_; } /* The following alternate dither algorithms (from musicdsp.org) could be considered */ /*Noise shaped dither (March 2000) ------------------- This is a simple implementation of highpass triangular-PDF dither with 2nd-order noise shaping, for use when truncating floating point audio data to fixed point. The noise shaping lowers the noise floor by 11dB below 5kHz (@ 44100Hz sample rate) compared to triangular-PDF dither. The code below assumes input data is in the range +1 to -1 and doesn't check for overloads! To save time when generating dither for multiple channels you can do things like this: r3=(r1 & 0x7F)<<8; instead of calling rand() again. int r1, r2; //rectangular-PDF random numbers float s1, s2; //error feedback buffers float s = 0.5f; //set to 0.0f for no noise shaping float w = pow(2.0,bits-1); //word length (usually bits=16) float wi= 1.0f/w; float d = wi / RAND_MAX; //dither amplitude (2 lsb) float o = wi * 0.5f; //remove dc offset float in, tmp; int out; //for each sample... r2=r1; //can make HP-TRI dither by r1=rand(); //subtracting previous rand() in += s * (s1 + s1 - s2); //error feedback tmp = in + o + d * (float)(r1 - r2); //dc offset and dither out = (int)(w * tmp); //truncate downwards if(tmp<0.0f) out--; //this is faster than floor() s2 = s1; s1 = in - wi * (float)out; //error -- paul.kellett@maxim.abel.co.uk http://www.maxim.abel.co.uk */ /* 16-to-8-bit first-order dither Type : First order error feedforward dithering code References : Posted by Jon Watte Notes : This is about as simple a dithering algorithm as you can implement, but it's likely to sound better than just truncating to N bits. Note that you might not want to carry forward the full difference for infinity. It's probably likely that the worst performance hit comes from the saturation conditionals, which can be avoided with appropriate instructions on many DSPs and integer SIMD type instructions, or CMOV. Last, if sound quality is paramount (such as when going from > 16 bits to 16 bits) you probably want to use a higher-order dither function found elsewhere on this site. Code : // This code will down-convert and dither a 16-bit signed short // mono signal into an 8-bit unsigned char signal, using a first // order forward-feeding error term dither. #define uchar unsigned char void dither_one_channel_16_to_8( short * input, uchar * output, int count, int * memory ) { int m = *memory; while( count-- > 0 ) { int i = *input++; i += m; int j = i + 32768 - 128; uchar o; if( j < 0 ) { o = 0; } else if( j > 65535 ) { o = 255; } else { o = (uchar)((j>>8)&0xff); } m = ((j-32768+128)-i); *output++ = o; } *memory = m; } */ pd-0.46-7/portaudio/src/common/pa_util.h0000664000175000017500000001262012222201037016257 0ustar mspmsp#ifndef PA_UTIL_H #define PA_UTIL_H /* * $Id: pa_util.h 1584 2011-02-02 18:58:17Z rossb $ * Portable Audio I/O Library implementation utilities header * common implementation utilities and interfaces * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2008 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Prototypes for utility functions used by PortAudio implementations. Some functions declared here are defined in pa_front.c while others are implemented separately for each platform. */ #include "portaudio.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ struct PaUtilHostApiRepresentation; /** Retrieve a specific host API representation. This function can be used by implementations to retrieve a pointer to their representation in host api specific extension functions which aren't passed a rep pointer by pa_front.c. @param hostApi A pointer to a host API represenation pointer. Apon success this will receive the requested representation pointer. @param type A valid host API type identifier. @returns An error code. If the result is PaNoError then a pointer to the requested host API representation will be stored in *hostApi. If the host API specified by type is not found, this function returns paHostApiNotFound. */ PaError PaUtil_GetHostApiRepresentation( struct PaUtilHostApiRepresentation **hostApi, PaHostApiTypeId type ); /** Convert a PortAudio device index into a host API specific device index. @param hostApiDevice Pointer to a device index, on success this will recieve the converted device index value. @param device The PortAudio device index to convert. @param hostApi The host api which the index should be converted for. @returns On success returns PaNoError and places the converted index in the hostApiDevice parameter. */ PaError PaUtil_DeviceIndexToHostApiDeviceIndex( PaDeviceIndex *hostApiDevice, PaDeviceIndex device, struct PaUtilHostApiRepresentation *hostApi ); /** Set the host error information returned by Pa_GetLastHostErrorInfo. This function and the paUnanticipatedHostError error code should be used as a last resort. Implementors should use existing PA error codes where possible, or nominate new ones. Note that at it is always better to use PaUtil_SetLastHostErrorInfo() and paUnanticipatedHostError than to return an ambiguous or inaccurate PaError code. @param hostApiType The host API which encountered the error (ie of the caller) @param errorCode The error code returned by the native API function. @param errorText A string describing the error. PaUtil_SetLastHostErrorInfo makes a copy of the string, so it is not necessary for the pointer to remain valid after the call to PaUtil_SetLastHostErrorInfo() returns. */ void PaUtil_SetLastHostErrorInfo( PaHostApiTypeId hostApiType, long errorCode, const char *errorText ); /* the following functions are implemented in a platform platform specific .c file */ /** Allocate size bytes, guaranteed to be aligned to a FIXME byte boundary */ void *PaUtil_AllocateMemory( long size ); /** Realease block if non-NULL. block may be NULL */ void PaUtil_FreeMemory( void *block ); /** Return the number of currently allocated blocks. This function can be used for detecting memory leaks. @note Allocations will only be tracked if PA_TRACK_MEMORY is #defined. If it isn't, this function will always return 0. */ int PaUtil_CountCurrentlyAllocatedBlocks( void ); /** Initialize the clock used by PaUtil_GetTime(). Call this before calling PaUtil_GetTime. @see PaUtil_GetTime */ void PaUtil_InitializeClock( void ); /** Return the system time in seconds. Used to implement CPU load functions @see PaUtil_InitializeClock */ double PaUtil_GetTime( void ); /* void Pa_Sleep( long msec ); must also be implemented in per-platform .c file */ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* PA_UTIL_H */ pd-0.46-7/portaudio/src/common/pa_debugprint.c0000664000175000017500000000764212222201037017450 0ustar mspmsp/* * $Id: pa_log.c $ * Portable Audio I/O Library Multi-Host API front end * Validate function parameters and manage multiple host APIs. * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2006 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Implements log function. PaUtil_SetLogPrintFunction can be user called to replace the provided DefaultLogPrint function, which writes to stderr. One can NOT pass var_args across compiler/dll boundaries as it is not "byte code/abi portable". So the technique used here is to allocate a local a static array, write in it, then callback the user with a pointer to its start. */ #include #include #include "pa_debugprint.h" // for OutputDebugStringA #if defined(_MSC_VER) && defined(PA_ENABLE_MSVC_DEBUG_OUTPUT) #define WIN32_LEAN_AND_MEAN // exclude rare headers #include "windows.h" #endif // User callback static PaUtilLogCallback userCB = NULL; // Sets user callback void PaUtil_SetDebugPrintFunction(PaUtilLogCallback cb) { userCB = cb; } /* If your platform doesnt have vsnprintf, you are stuck with a VERY dangerous alternative, vsprintf (with no n) */ #if _MSC_VER /* Some Windows Mobile SDKs don't define vsnprintf but all define _vsnprintf (hopefully). According to MSDN "vsnprintf is identical to _vsnprintf". So we use _vsnprintf with MSC. */ #define VSNPRINTF _vsnprintf #else #define VSNPRINTF vsnprintf #endif #define PA_LOG_BUF_SIZE 2048 void PaUtil_DebugPrint( const char *format, ... ) { // Optional logging into Output console of Visual Studio #if defined(_MSC_VER) && defined(PA_ENABLE_MSVC_DEBUG_OUTPUT) { char buf[PA_LOG_BUF_SIZE]; va_list ap; va_start(ap, format); VSNPRINTF(buf, sizeof(buf), format, ap); buf[sizeof(buf)-1] = 0; OutputDebugStringA(buf); va_end(ap); } #endif // Output to User-Callback if (userCB != NULL) { char strdump[PA_LOG_BUF_SIZE]; va_list ap; va_start(ap, format); VSNPRINTF(strdump, sizeof(strdump), format, ap); strdump[sizeof(strdump)-1] = 0; userCB(strdump); va_end(ap); } else // Standard output to stderr { va_list ap; va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap); fflush(stderr); } } pd-0.46-7/portaudio/src/common/pa_process.c0000664000175000017500000020452312222201037016760 0ustar mspmsp/* * $Id: pa_process.c 1706 2011-07-21 18:44:58Z philburk $ * Portable Audio I/O Library * streamCallback <-> host buffer processing adapter * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup common_src @brief Buffer Processor implementation. */ #include #include /* memset() */ #include "pa_process.h" #include "pa_util.h" #define PA_FRAMES_PER_TEMP_BUFFER_WHEN_HOST_BUFFER_SIZE_IS_UNKNOWN_ 1024 #define PA_MIN_( a, b ) ( ((a)<(b)) ? (a) : (b) ) /* greatest common divisor - PGCD in French */ static unsigned long GCD( unsigned long a, unsigned long b ) { return (b==0) ? a : GCD( b, a%b); } /* least common multiple - PPCM in French */ static unsigned long LCM( unsigned long a, unsigned long b ) { return (a*b) / GCD(a,b); } #define PA_MAX_( a, b ) (((a) > (b)) ? (a) : (b)) static unsigned long CalculateFrameShift( unsigned long M, unsigned long N ) { unsigned long result = 0; unsigned long i; unsigned long lcm; assert( M > 0 ); assert( N > 0 ); lcm = LCM( M, N ); for( i = M; i < lcm; i += M ) result = PA_MAX_( result, i % N ); return result; } PaError PaUtil_InitializeBufferProcessor( PaUtilBufferProcessor* bp, int inputChannelCount, PaSampleFormat userInputSampleFormat, PaSampleFormat hostInputSampleFormat, int outputChannelCount, PaSampleFormat userOutputSampleFormat, PaSampleFormat hostOutputSampleFormat, double sampleRate, PaStreamFlags streamFlags, unsigned long framesPerUserBuffer, unsigned long framesPerHostBuffer, PaUtilHostBufferSizeMode hostBufferSizeMode, PaStreamCallback *streamCallback, void *userData ) { PaError result = paNoError; PaError bytesPerSample; unsigned long tempInputBufferSize, tempOutputBufferSize; PaStreamFlags tempInputStreamFlags; if( streamFlags & paNeverDropInput ) { /* paNeverDropInput is only valid for full-duplex callback streams, with an unspecified number of frames per buffer. */ if( !streamCallback || !(inputChannelCount > 0 && outputChannelCount > 0) || framesPerUserBuffer != paFramesPerBufferUnspecified ) return paInvalidFlag; } /* initialize buffer ptrs to zero so they can be freed if necessary in error */ bp->tempInputBuffer = 0; bp->tempInputBufferPtrs = 0; bp->tempOutputBuffer = 0; bp->tempOutputBufferPtrs = 0; bp->framesPerUserBuffer = framesPerUserBuffer; bp->framesPerHostBuffer = framesPerHostBuffer; bp->inputChannelCount = inputChannelCount; bp->outputChannelCount = outputChannelCount; bp->hostBufferSizeMode = hostBufferSizeMode; bp->hostInputChannels[0] = bp->hostInputChannels[1] = 0; bp->hostOutputChannels[0] = bp->hostOutputChannels[1] = 0; if( framesPerUserBuffer == 0 ) /* streamCallback will accept any buffer size */ { bp->useNonAdaptingProcess = 1; bp->initialFramesInTempInputBuffer = 0; bp->initialFramesInTempOutputBuffer = 0; if( hostBufferSizeMode == paUtilFixedHostBufferSize || hostBufferSizeMode == paUtilBoundedHostBufferSize ) { bp->framesPerTempBuffer = framesPerHostBuffer; } else /* unknown host buffer size */ { bp->framesPerTempBuffer = PA_FRAMES_PER_TEMP_BUFFER_WHEN_HOST_BUFFER_SIZE_IS_UNKNOWN_; } } else { bp->framesPerTempBuffer = framesPerUserBuffer; if( hostBufferSizeMode == paUtilFixedHostBufferSize && framesPerHostBuffer % framesPerUserBuffer == 0 ) { bp->useNonAdaptingProcess = 1; bp->initialFramesInTempInputBuffer = 0; bp->initialFramesInTempOutputBuffer = 0; } else { bp->useNonAdaptingProcess = 0; if( inputChannelCount > 0 && outputChannelCount > 0 ) { /* full duplex */ if( hostBufferSizeMode == paUtilFixedHostBufferSize ) { unsigned long frameShift = CalculateFrameShift( framesPerHostBuffer, framesPerUserBuffer ); if( framesPerUserBuffer > framesPerHostBuffer ) { bp->initialFramesInTempInputBuffer = frameShift; bp->initialFramesInTempOutputBuffer = 0; } else { bp->initialFramesInTempInputBuffer = 0; bp->initialFramesInTempOutputBuffer = frameShift; } } else /* variable host buffer size, add framesPerUserBuffer latency */ { bp->initialFramesInTempInputBuffer = 0; bp->initialFramesInTempOutputBuffer = framesPerUserBuffer; } } else { /* half duplex */ bp->initialFramesInTempInputBuffer = 0; bp->initialFramesInTempOutputBuffer = 0; } } } bp->framesInTempInputBuffer = bp->initialFramesInTempInputBuffer; bp->framesInTempOutputBuffer = bp->initialFramesInTempOutputBuffer; if( inputChannelCount > 0 ) { bytesPerSample = Pa_GetSampleSize( hostInputSampleFormat ); if( bytesPerSample > 0 ) { bp->bytesPerHostInputSample = bytesPerSample; } else { result = bytesPerSample; goto error; } bytesPerSample = Pa_GetSampleSize( userInputSampleFormat ); if( bytesPerSample > 0 ) { bp->bytesPerUserInputSample = bytesPerSample; } else { result = bytesPerSample; goto error; } /* Under the assumption that no ADC in existence delivers better than 24bits resolution, we disable dithering when host input format is paInt32 and user format is paInt24, since the host samples will just be padded with zeros anyway. */ tempInputStreamFlags = streamFlags; if( !(tempInputStreamFlags & paDitherOff) /* dither is on */ && (hostInputSampleFormat & paInt32) /* host input format is int32 */ && (userInputSampleFormat & paInt24) /* user requested format is int24 */ ){ tempInputStreamFlags = tempInputStreamFlags | paDitherOff; } bp->inputConverter = PaUtil_SelectConverter( hostInputSampleFormat, userInputSampleFormat, tempInputStreamFlags ); bp->inputZeroer = PaUtil_SelectZeroer( hostInputSampleFormat ); bp->userInputIsInterleaved = (userInputSampleFormat & paNonInterleaved)?0:1; bp->hostInputIsInterleaved = (hostInputSampleFormat & paNonInterleaved)?0:1; bp->userInputSampleFormatIsEqualToHost = ((userInputSampleFormat & ~paNonInterleaved) == (hostInputSampleFormat & ~paNonInterleaved)); tempInputBufferSize = bp->framesPerTempBuffer * bp->bytesPerUserInputSample * inputChannelCount; bp->tempInputBuffer = PaUtil_AllocateMemory( tempInputBufferSize ); if( bp->tempInputBuffer == 0 ) { result = paInsufficientMemory; goto error; } if( bp->framesInTempInputBuffer > 0 ) memset( bp->tempInputBuffer, 0, tempInputBufferSize ); if( userInputSampleFormat & paNonInterleaved ) { bp->tempInputBufferPtrs = (void **)PaUtil_AllocateMemory( sizeof(void*)*inputChannelCount ); if( bp->tempInputBufferPtrs == 0 ) { result = paInsufficientMemory; goto error; } } bp->hostInputChannels[0] = (PaUtilChannelDescriptor*) PaUtil_AllocateMemory( sizeof(PaUtilChannelDescriptor) * inputChannelCount * 2); if( bp->hostInputChannels[0] == 0 ) { result = paInsufficientMemory; goto error; } bp->hostInputChannels[1] = &bp->hostInputChannels[0][inputChannelCount]; } if( outputChannelCount > 0 ) { bytesPerSample = Pa_GetSampleSize( hostOutputSampleFormat ); if( bytesPerSample > 0 ) { bp->bytesPerHostOutputSample = bytesPerSample; } else { result = bytesPerSample; goto error; } bytesPerSample = Pa_GetSampleSize( userOutputSampleFormat ); if( bytesPerSample > 0 ) { bp->bytesPerUserOutputSample = bytesPerSample; } else { result = bytesPerSample; goto error; } bp->outputConverter = PaUtil_SelectConverter( userOutputSampleFormat, hostOutputSampleFormat, streamFlags ); bp->outputZeroer = PaUtil_SelectZeroer( hostOutputSampleFormat ); bp->userOutputIsInterleaved = (userOutputSampleFormat & paNonInterleaved)?0:1; bp->hostOutputIsInterleaved = (hostOutputSampleFormat & paNonInterleaved)?0:1; bp->userOutputSampleFormatIsEqualToHost = ((userOutputSampleFormat & ~paNonInterleaved) == (hostOutputSampleFormat & ~paNonInterleaved)); tempOutputBufferSize = bp->framesPerTempBuffer * bp->bytesPerUserOutputSample * outputChannelCount; bp->tempOutputBuffer = PaUtil_AllocateMemory( tempOutputBufferSize ); if( bp->tempOutputBuffer == 0 ) { result = paInsufficientMemory; goto error; } if( bp->framesInTempOutputBuffer > 0 ) memset( bp->tempOutputBuffer, 0, tempOutputBufferSize ); if( userOutputSampleFormat & paNonInterleaved ) { bp->tempOutputBufferPtrs = (void **)PaUtil_AllocateMemory( sizeof(void*)*outputChannelCount ); if( bp->tempOutputBufferPtrs == 0 ) { result = paInsufficientMemory; goto error; } } bp->hostOutputChannels[0] = (PaUtilChannelDescriptor*) PaUtil_AllocateMemory( sizeof(PaUtilChannelDescriptor)*outputChannelCount * 2 ); if( bp->hostOutputChannels[0] == 0 ) { result = paInsufficientMemory; goto error; } bp->hostOutputChannels[1] = &bp->hostOutputChannels[0][outputChannelCount]; } PaUtil_InitializeTriangularDitherState( &bp->ditherGenerator ); bp->samplePeriod = 1. / sampleRate; bp->streamCallback = streamCallback; bp->userData = userData; return result; error: if( bp->tempInputBuffer ) PaUtil_FreeMemory( bp->tempInputBuffer ); if( bp->tempInputBufferPtrs ) PaUtil_FreeMemory( bp->tempInputBufferPtrs ); if( bp->hostInputChannels[0] ) PaUtil_FreeMemory( bp->hostInputChannels[0] ); if( bp->tempOutputBuffer ) PaUtil_FreeMemory( bp->tempOutputBuffer ); if( bp->tempOutputBufferPtrs ) PaUtil_FreeMemory( bp->tempOutputBufferPtrs ); if( bp->hostOutputChannels[0] ) PaUtil_FreeMemory( bp->hostOutputChannels[0] ); return result; } void PaUtil_TerminateBufferProcessor( PaUtilBufferProcessor* bp ) { if( bp->tempInputBuffer ) PaUtil_FreeMemory( bp->tempInputBuffer ); if( bp->tempInputBufferPtrs ) PaUtil_FreeMemory( bp->tempInputBufferPtrs ); if( bp->hostInputChannels[0] ) PaUtil_FreeMemory( bp->hostInputChannels[0] ); if( bp->tempOutputBuffer ) PaUtil_FreeMemory( bp->tempOutputBuffer ); if( bp->tempOutputBufferPtrs ) PaUtil_FreeMemory( bp->tempOutputBufferPtrs ); if( bp->hostOutputChannels[0] ) PaUtil_FreeMemory( bp->hostOutputChannels[0] ); } void PaUtil_ResetBufferProcessor( PaUtilBufferProcessor* bp ) { unsigned long tempInputBufferSize, tempOutputBufferSize; bp->framesInTempInputBuffer = bp->initialFramesInTempInputBuffer; bp->framesInTempOutputBuffer = bp->initialFramesInTempOutputBuffer; if( bp->framesInTempInputBuffer > 0 ) { tempInputBufferSize = bp->framesPerTempBuffer * bp->bytesPerUserInputSample * bp->inputChannelCount; memset( bp->tempInputBuffer, 0, tempInputBufferSize ); } if( bp->framesInTempOutputBuffer > 0 ) { tempOutputBufferSize = bp->framesPerTempBuffer * bp->bytesPerUserOutputSample * bp->outputChannelCount; memset( bp->tempOutputBuffer, 0, tempOutputBufferSize ); } } unsigned long PaUtil_GetBufferProcessorInputLatencyFrames( PaUtilBufferProcessor* bp ) { return bp->initialFramesInTempInputBuffer; } unsigned long PaUtil_GetBufferProcessorOutputLatencyFrames( PaUtilBufferProcessor* bp ) { return bp->initialFramesInTempOutputBuffer; } void PaUtil_SetInputFrameCount( PaUtilBufferProcessor* bp, unsigned long frameCount ) { if( frameCount == 0 ) bp->hostInputFrameCount[0] = bp->framesPerHostBuffer; else bp->hostInputFrameCount[0] = frameCount; } void PaUtil_SetNoInput( PaUtilBufferProcessor* bp ) { assert( bp->inputChannelCount > 0 ); bp->hostInputChannels[0][0].data = 0; } void PaUtil_SetInputChannel( PaUtilBufferProcessor* bp, unsigned int channel, void *data, unsigned int stride ) { assert( channel < bp->inputChannelCount ); bp->hostInputChannels[0][channel].data = data; bp->hostInputChannels[0][channel].stride = stride; } void PaUtil_SetInterleavedInputChannels( PaUtilBufferProcessor* bp, unsigned int firstChannel, void *data, unsigned int channelCount ) { unsigned int i; unsigned int channel = firstChannel; unsigned char *p = (unsigned char*)data; if( channelCount == 0 ) channelCount = bp->inputChannelCount; assert( firstChannel < bp->inputChannelCount ); assert( firstChannel + channelCount <= bp->inputChannelCount ); assert( bp->hostInputIsInterleaved ); for( i=0; i< channelCount; ++i ) { bp->hostInputChannels[0][channel+i].data = p; p += bp->bytesPerHostInputSample; bp->hostInputChannels[0][channel+i].stride = channelCount; } } void PaUtil_SetNonInterleavedInputChannel( PaUtilBufferProcessor* bp, unsigned int channel, void *data ) { assert( channel < bp->inputChannelCount ); assert( !bp->hostInputIsInterleaved ); bp->hostInputChannels[0][channel].data = data; bp->hostInputChannels[0][channel].stride = 1; } void PaUtil_Set2ndInputFrameCount( PaUtilBufferProcessor* bp, unsigned long frameCount ) { bp->hostInputFrameCount[1] = frameCount; } void PaUtil_Set2ndInputChannel( PaUtilBufferProcessor* bp, unsigned int channel, void *data, unsigned int stride ) { assert( channel < bp->inputChannelCount ); bp->hostInputChannels[1][channel].data = data; bp->hostInputChannels[1][channel].stride = stride; } void PaUtil_Set2ndInterleavedInputChannels( PaUtilBufferProcessor* bp, unsigned int firstChannel, void *data, unsigned int channelCount ) { unsigned int i; unsigned int channel = firstChannel; unsigned char *p = (unsigned char*)data; if( channelCount == 0 ) channelCount = bp->inputChannelCount; assert( firstChannel < bp->inputChannelCount ); assert( firstChannel + channelCount <= bp->inputChannelCount ); assert( bp->hostInputIsInterleaved ); for( i=0; i< channelCount; ++i ) { bp->hostInputChannels[1][channel+i].data = p; p += bp->bytesPerHostInputSample; bp->hostInputChannels[1][channel+i].stride = channelCount; } } void PaUtil_Set2ndNonInterleavedInputChannel( PaUtilBufferProcessor* bp, unsigned int channel, void *data ) { assert( channel < bp->inputChannelCount ); assert( !bp->hostInputIsInterleaved ); bp->hostInputChannels[1][channel].data = data; bp->hostInputChannels[1][channel].stride = 1; } void PaUtil_SetOutputFrameCount( PaUtilBufferProcessor* bp, unsigned long frameCount ) { if( frameCount == 0 ) bp->hostOutputFrameCount[0] = bp->framesPerHostBuffer; else bp->hostOutputFrameCount[0] = frameCount; } void PaUtil_SetNoOutput( PaUtilBufferProcessor* bp ) { assert( bp->outputChannelCount > 0 ); bp->hostOutputChannels[0][0].data = 0; /* note that only NonAdaptingProcess is able to deal with no output at this stage. not implemented for AdaptingProcess */ } void PaUtil_SetOutputChannel( PaUtilBufferProcessor* bp, unsigned int channel, void *data, unsigned int stride ) { assert( channel < bp->outputChannelCount ); assert( data != NULL ); bp->hostOutputChannels[0][channel].data = data; bp->hostOutputChannels[0][channel].stride = stride; } void PaUtil_SetInterleavedOutputChannels( PaUtilBufferProcessor* bp, unsigned int firstChannel, void *data, unsigned int channelCount ) { unsigned int i; unsigned int channel = firstChannel; unsigned char *p = (unsigned char*)data; if( channelCount == 0 ) channelCount = bp->outputChannelCount; assert( firstChannel < bp->outputChannelCount ); assert( firstChannel + channelCount <= bp->outputChannelCount ); assert( bp->hostOutputIsInterleaved ); for( i=0; i< channelCount; ++i ) { PaUtil_SetOutputChannel( bp, channel + i, p, channelCount ); p += bp->bytesPerHostOutputSample; } } void PaUtil_SetNonInterleavedOutputChannel( PaUtilBufferProcessor* bp, unsigned int channel, void *data ) { assert( channel < bp->outputChannelCount ); assert( !bp->hostOutputIsInterleaved ); PaUtil_SetOutputChannel( bp, channel, data, 1 ); } void PaUtil_Set2ndOutputFrameCount( PaUtilBufferProcessor* bp, unsigned long frameCount ) { bp->hostOutputFrameCount[1] = frameCount; } void PaUtil_Set2ndOutputChannel( PaUtilBufferProcessor* bp, unsigned int channel, void *data, unsigned int stride ) { assert( channel < bp->outputChannelCount ); assert( data != NULL ); bp->hostOutputChannels[1][channel].data = data; bp->hostOutputChannels[1][channel].stride = stride; } void PaUtil_Set2ndInterleavedOutputChannels( PaUtilBufferProcessor* bp, unsigned int firstChannel, void *data, unsigned int channelCount ) { unsigned int i; unsigned int channel = firstChannel; unsigned char *p = (unsigned char*)data; if( channelCount == 0 ) channelCount = bp->outputChannelCount; assert( firstChannel < bp->outputChannelCount ); assert( firstChannel + channelCount <= bp->outputChannelCount ); assert( bp->hostOutputIsInterleaved ); for( i=0; i< channelCount; ++i ) { PaUtil_Set2ndOutputChannel( bp, channel + i, p, channelCount ); p += bp->bytesPerHostOutputSample; } } void PaUtil_Set2ndNonInterleavedOutputChannel( PaUtilBufferProcessor* bp, unsigned int channel, void *data ) { assert( channel < bp->outputChannelCount ); assert( !bp->hostOutputIsInterleaved ); PaUtil_Set2ndOutputChannel( bp, channel, data, 1 ); } void PaUtil_BeginBufferProcessing( PaUtilBufferProcessor* bp, PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags callbackStatusFlags ) { bp->timeInfo = timeInfo; /* the first streamCallback will be called to process samples which are currently in the input buffer before the ones starting at the timeInfo time */ bp->timeInfo->inputBufferAdcTime -= bp->framesInTempInputBuffer * bp->samplePeriod; /* We just pass through timeInfo->currentTime provided by the caller. This is not strictly conformant to the word of the spec, since the buffer processor might call the callback multiple times, and we never refresh currentTime. */ /* the first streamCallback will be called to generate samples which will be outputted after the frames currently in the output buffer have been outputted. */ bp->timeInfo->outputBufferDacTime += bp->framesInTempOutputBuffer * bp->samplePeriod; bp->callbackStatusFlags = callbackStatusFlags; bp->hostInputFrameCount[1] = 0; bp->hostOutputFrameCount[1] = 0; } /* NonAdaptingProcess() is a simple buffer copying adaptor that can handle both full and half duplex copies. It processes framesToProcess frames, broken into blocks bp->framesPerTempBuffer long. This routine can be used when the streamCallback doesn't care what length the buffers are, or when framesToProcess is an integer multiple of bp->framesPerTempBuffer, in which case streamCallback will always be called with bp->framesPerTempBuffer samples. */ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp, int *streamCallbackResult, PaUtilChannelDescriptor *hostInputChannels, PaUtilChannelDescriptor *hostOutputChannels, unsigned long framesToProcess ) { void *userInput, *userOutput; unsigned char *srcBytePtr, *destBytePtr; unsigned int srcSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */ unsigned int srcChannelStrideBytes; /* stride from one channel to the next, in bytes */ unsigned int destSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */ unsigned int destChannelStrideBytes; /* stride from one channel to the next, in bytes */ unsigned int i; unsigned long frameCount; unsigned long framesToGo = framesToProcess; unsigned long framesProcessed = 0; int skipOutputConvert = 0; int skipInputConvert = 0; if( *streamCallbackResult == paContinue ) { do { frameCount = PA_MIN_( bp->framesPerTempBuffer, framesToGo ); /* configure user input buffer and convert input data (host -> user) */ if( bp->inputChannelCount == 0 ) { /* no input */ userInput = 0; } else /* there are input channels */ { destBytePtr = (unsigned char *)bp->tempInputBuffer; if( bp->userInputIsInterleaved ) { destSampleStrideSamples = bp->inputChannelCount; destChannelStrideBytes = bp->bytesPerUserInputSample; /* process host buffer directly, or use temp buffer if formats differ or host buffer non-interleaved */ if( bp->userInputSampleFormatIsEqualToHost && bp->hostInputIsInterleaved && bp->hostInputChannels[0][0].data) { userInput = hostInputChannels[0].data; destBytePtr = (unsigned char *)hostInputChannels[0].data; skipInputConvert = 1; } else { userInput = bp->tempInputBuffer; } } else /* user input is not interleaved */ { destSampleStrideSamples = 1; destChannelStrideBytes = frameCount * bp->bytesPerUserInputSample; /* setup non-interleaved ptrs */ if( bp->userInputSampleFormatIsEqualToHost && !bp->hostInputIsInterleaved && bp->hostInputChannels[0][0].data ) { for( i=0; iinputChannelCount; ++i ) { bp->tempInputBufferPtrs[i] = hostInputChannels[i].data; } skipInputConvert = 1; } else { for( i=0; iinputChannelCount; ++i ) { bp->tempInputBufferPtrs[i] = ((unsigned char*)bp->tempInputBuffer) + i * bp->bytesPerUserInputSample * frameCount; } } userInput = bp->tempInputBufferPtrs; } if( !bp->hostInputChannels[0][0].data ) { /* no input was supplied (see PaUtil_SetNoInput), so zero the input buffer */ for( i=0; iinputChannelCount; ++i ) { bp->inputZeroer( destBytePtr, destSampleStrideSamples, frameCount ); destBytePtr += destChannelStrideBytes; /* skip to next destination channel */ } } else { if( skipInputConvert ) { for( i=0; iinputChannelCount; ++i ) { /* advance src ptr for next iteration */ hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) + frameCount * hostInputChannels[i].stride * bp->bytesPerHostInputSample; } } else { for( i=0; iinputChannelCount; ++i ) { bp->inputConverter( destBytePtr, destSampleStrideSamples, hostInputChannels[i].data, hostInputChannels[i].stride, frameCount, &bp->ditherGenerator ); destBytePtr += destChannelStrideBytes; /* skip to next destination channel */ /* advance src ptr for next iteration */ hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) + frameCount * hostInputChannels[i].stride * bp->bytesPerHostInputSample; } } } } /* configure user output buffer */ if( bp->outputChannelCount == 0 ) { /* no output */ userOutput = 0; } else /* there are output channels */ { if( bp->userOutputIsInterleaved ) { /* process host buffer directly, or use temp buffer if formats differ or host buffer non-interleaved */ if( bp->userOutputSampleFormatIsEqualToHost && bp->hostOutputIsInterleaved ) { userOutput = hostOutputChannels[0].data; skipOutputConvert = 1; } else { userOutput = bp->tempOutputBuffer; } } else /* user output is not interleaved */ { if( bp->userOutputSampleFormatIsEqualToHost && !bp->hostOutputIsInterleaved ) { for( i=0; ioutputChannelCount; ++i ) { bp->tempOutputBufferPtrs[i] = hostOutputChannels[i].data; } skipOutputConvert = 1; } else { for( i=0; ioutputChannelCount; ++i ) { bp->tempOutputBufferPtrs[i] = ((unsigned char*)bp->tempOutputBuffer) + i * bp->bytesPerUserOutputSample * frameCount; } } userOutput = bp->tempOutputBufferPtrs; } } *streamCallbackResult = bp->streamCallback( userInput, userOutput, frameCount, bp->timeInfo, bp->callbackStatusFlags, bp->userData ); if( *streamCallbackResult == paAbort ) { /* callback returned paAbort, don't advance framesProcessed and framesToGo, they will be handled below */ } else { bp->timeInfo->inputBufferAdcTime += frameCount * bp->samplePeriod; bp->timeInfo->outputBufferDacTime += frameCount * bp->samplePeriod; /* convert output data (user -> host) */ if( bp->outputChannelCount != 0 && bp->hostOutputChannels[0][0].data ) { if( skipOutputConvert ) { for( i=0; ioutputChannelCount; ++i ) { /* advance dest ptr for next iteration */ hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) + frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample; } } else { srcBytePtr = (unsigned char *)bp->tempOutputBuffer; if( bp->userOutputIsInterleaved ) { srcSampleStrideSamples = bp->outputChannelCount; srcChannelStrideBytes = bp->bytesPerUserOutputSample; } else /* user output is not interleaved */ { srcSampleStrideSamples = 1; srcChannelStrideBytes = frameCount * bp->bytesPerUserOutputSample; } for( i=0; ioutputChannelCount; ++i ) { bp->outputConverter( hostOutputChannels[i].data, hostOutputChannels[i].stride, srcBytePtr, srcSampleStrideSamples, frameCount, &bp->ditherGenerator ); srcBytePtr += srcChannelStrideBytes; /* skip to next source channel */ /* advance dest ptr for next iteration */ hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) + frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample; } } } framesProcessed += frameCount; framesToGo -= frameCount; } } while( framesToGo > 0 && *streamCallbackResult == paContinue ); } if( framesToGo > 0 ) { /* zero any remaining frames output. There will only be remaining frames if the callback has returned paComplete or paAbort */ frameCount = framesToGo; if( bp->outputChannelCount != 0 && bp->hostOutputChannels[0][0].data ) { for( i=0; ioutputChannelCount; ++i ) { bp->outputZeroer( hostOutputChannels[i].data, hostOutputChannels[i].stride, frameCount ); /* advance dest ptr for next iteration */ hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) + frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample; } } framesProcessed += frameCount; } return framesProcessed; } /* AdaptingInputOnlyProcess() is a half duplex input buffer processor. It converts data from the input buffers into the temporary input buffer, when the temporary input buffer is full, it calls the streamCallback. */ static unsigned long AdaptingInputOnlyProcess( PaUtilBufferProcessor *bp, int *streamCallbackResult, PaUtilChannelDescriptor *hostInputChannels, unsigned long framesToProcess ) { void *userInput, *userOutput; unsigned char *destBytePtr; unsigned int destSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */ unsigned int destChannelStrideBytes; /* stride from one channel to the next, in bytes */ unsigned int i; unsigned long frameCount; unsigned long framesToGo = framesToProcess; unsigned long framesProcessed = 0; userOutput = 0; do { frameCount = ( bp->framesInTempInputBuffer + framesToGo > bp->framesPerUserBuffer ) ? ( bp->framesPerUserBuffer - bp->framesInTempInputBuffer ) : framesToGo; /* convert frameCount samples into temp buffer */ if( bp->userInputIsInterleaved ) { destBytePtr = ((unsigned char*)bp->tempInputBuffer) + bp->bytesPerUserInputSample * bp->inputChannelCount * bp->framesInTempInputBuffer; destSampleStrideSamples = bp->inputChannelCount; destChannelStrideBytes = bp->bytesPerUserInputSample; userInput = bp->tempInputBuffer; } else /* user input is not interleaved */ { destBytePtr = ((unsigned char*)bp->tempInputBuffer) + bp->bytesPerUserInputSample * bp->framesInTempInputBuffer; destSampleStrideSamples = 1; destChannelStrideBytes = bp->framesPerUserBuffer * bp->bytesPerUserInputSample; /* setup non-interleaved ptrs */ for( i=0; iinputChannelCount; ++i ) { bp->tempInputBufferPtrs[i] = ((unsigned char*)bp->tempInputBuffer) + i * bp->bytesPerUserInputSample * bp->framesPerUserBuffer; } userInput = bp->tempInputBufferPtrs; } for( i=0; iinputChannelCount; ++i ) { bp->inputConverter( destBytePtr, destSampleStrideSamples, hostInputChannels[i].data, hostInputChannels[i].stride, frameCount, &bp->ditherGenerator ); destBytePtr += destChannelStrideBytes; /* skip to next destination channel */ /* advance src ptr for next iteration */ hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) + frameCount * hostInputChannels[i].stride * bp->bytesPerHostInputSample; } bp->framesInTempInputBuffer += frameCount; if( bp->framesInTempInputBuffer == bp->framesPerUserBuffer ) { /** @todo (non-critical optimisation) The conditional below implements the continue/complete/abort mechanism simply by continuing on iterating through the input buffer, but not passing the data to the callback. With care, the outer loop could be terminated earlier, thus some unneeded conversion cycles would be saved. */ if( *streamCallbackResult == paContinue ) { bp->timeInfo->outputBufferDacTime = 0; *streamCallbackResult = bp->streamCallback( userInput, userOutput, bp->framesPerUserBuffer, bp->timeInfo, bp->callbackStatusFlags, bp->userData ); bp->timeInfo->inputBufferAdcTime += bp->framesPerUserBuffer * bp->samplePeriod; } bp->framesInTempInputBuffer = 0; } framesProcessed += frameCount; framesToGo -= frameCount; }while( framesToGo > 0 ); return framesProcessed; } /* AdaptingOutputOnlyProcess() is a half duplex output buffer processor. It converts data from the temporary output buffer, to the output buffers, when the temporary output buffer is empty, it calls the streamCallback. */ static unsigned long AdaptingOutputOnlyProcess( PaUtilBufferProcessor *bp, int *streamCallbackResult, PaUtilChannelDescriptor *hostOutputChannels, unsigned long framesToProcess ) { void *userInput, *userOutput; unsigned char *srcBytePtr; unsigned int srcSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */ unsigned int srcChannelStrideBytes; /* stride from one channel to the next, in bytes */ unsigned int i; unsigned long frameCount; unsigned long framesToGo = framesToProcess; unsigned long framesProcessed = 0; do { if( bp->framesInTempOutputBuffer == 0 && *streamCallbackResult == paContinue ) { userInput = 0; /* setup userOutput */ if( bp->userOutputIsInterleaved ) { userOutput = bp->tempOutputBuffer; } else /* user output is not interleaved */ { for( i = 0; i < bp->outputChannelCount; ++i ) { bp->tempOutputBufferPtrs[i] = ((unsigned char*)bp->tempOutputBuffer) + i * bp->framesPerUserBuffer * bp->bytesPerUserOutputSample; } userOutput = bp->tempOutputBufferPtrs; } bp->timeInfo->inputBufferAdcTime = 0; *streamCallbackResult = bp->streamCallback( userInput, userOutput, bp->framesPerUserBuffer, bp->timeInfo, bp->callbackStatusFlags, bp->userData ); if( *streamCallbackResult == paAbort ) { /* if the callback returned paAbort, we disregard its output */ } else { bp->timeInfo->outputBufferDacTime += bp->framesPerUserBuffer * bp->samplePeriod; bp->framesInTempOutputBuffer = bp->framesPerUserBuffer; } } if( bp->framesInTempOutputBuffer > 0 ) { /* convert frameCount frames from user buffer to host buffer */ frameCount = PA_MIN_( bp->framesInTempOutputBuffer, framesToGo ); if( bp->userOutputIsInterleaved ) { srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) + bp->bytesPerUserOutputSample * bp->outputChannelCount * (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer); srcSampleStrideSamples = bp->outputChannelCount; srcChannelStrideBytes = bp->bytesPerUserOutputSample; } else /* user output is not interleaved */ { srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) + bp->bytesPerUserOutputSample * (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer); srcSampleStrideSamples = 1; srcChannelStrideBytes = bp->framesPerUserBuffer * bp->bytesPerUserOutputSample; } for( i=0; ioutputChannelCount; ++i ) { bp->outputConverter( hostOutputChannels[i].data, hostOutputChannels[i].stride, srcBytePtr, srcSampleStrideSamples, frameCount, &bp->ditherGenerator ); srcBytePtr += srcChannelStrideBytes; /* skip to next source channel */ /* advance dest ptr for next iteration */ hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) + frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample; } bp->framesInTempOutputBuffer -= frameCount; } else { /* no more user data is available because the callback has returned paComplete or paAbort. Fill the remainder of the host buffer with zeros. */ frameCount = framesToGo; for( i=0; ioutputChannelCount; ++i ) { bp->outputZeroer( hostOutputChannels[i].data, hostOutputChannels[i].stride, frameCount ); /* advance dest ptr for next iteration */ hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) + frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample; } } framesProcessed += frameCount; framesToGo -= frameCount; }while( framesToGo > 0 ); return framesProcessed; } /* CopyTempOutputBuffersToHostOutputBuffers is called from AdaptingProcess to copy frames from tempOutputBuffer to hostOutputChannels. This includes data conversion and interleaving. */ static void CopyTempOutputBuffersToHostOutputBuffers( PaUtilBufferProcessor *bp) { unsigned long maxFramesToCopy; PaUtilChannelDescriptor *hostOutputChannels; unsigned int frameCount; unsigned char *srcBytePtr; unsigned int srcSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */ unsigned int srcChannelStrideBytes; /* stride from one channel to the next, in bytes */ unsigned int i; /* copy frames from user to host output buffers */ while( bp->framesInTempOutputBuffer > 0 && ((bp->hostOutputFrameCount[0] + bp->hostOutputFrameCount[1]) > 0) ) { maxFramesToCopy = bp->framesInTempOutputBuffer; /* select the output buffer set (1st or 2nd) */ if( bp->hostOutputFrameCount[0] > 0 ) { hostOutputChannels = bp->hostOutputChannels[0]; frameCount = PA_MIN_( bp->hostOutputFrameCount[0], maxFramesToCopy ); } else { hostOutputChannels = bp->hostOutputChannels[1]; frameCount = PA_MIN_( bp->hostOutputFrameCount[1], maxFramesToCopy ); } if( bp->userOutputIsInterleaved ) { srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) + bp->bytesPerUserOutputSample * bp->outputChannelCount * (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer); srcSampleStrideSamples = bp->outputChannelCount; srcChannelStrideBytes = bp->bytesPerUserOutputSample; } else /* user output is not interleaved */ { srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) + bp->bytesPerUserOutputSample * (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer); srcSampleStrideSamples = 1; srcChannelStrideBytes = bp->framesPerUserBuffer * bp->bytesPerUserOutputSample; } for( i=0; ioutputChannelCount; ++i ) { assert( hostOutputChannels[i].data != NULL ); bp->outputConverter( hostOutputChannels[i].data, hostOutputChannels[i].stride, srcBytePtr, srcSampleStrideSamples, frameCount, &bp->ditherGenerator ); srcBytePtr += srcChannelStrideBytes; /* skip to next source channel */ /* advance dest ptr for next iteration */ hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) + frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample; } if( bp->hostOutputFrameCount[0] > 0 ) bp->hostOutputFrameCount[0] -= frameCount; else bp->hostOutputFrameCount[1] -= frameCount; bp->framesInTempOutputBuffer -= frameCount; } } /* AdaptingProcess is a full duplex adapting buffer processor. It converts data from the temporary output buffer into the host output buffers, then from the host input buffers into the temporary input buffers. Calling the streamCallback when necessary. When processPartialUserBuffers is 0, all available input data will be consumed and all available output space will be filled. When processPartialUserBuffers is non-zero, as many full user buffers as possible will be processed, but partial buffers will not be consumed. */ static unsigned long AdaptingProcess( PaUtilBufferProcessor *bp, int *streamCallbackResult, int processPartialUserBuffers ) { void *userInput, *userOutput; unsigned long framesProcessed = 0; unsigned long framesAvailable; unsigned long endProcessingMinFrameCount; unsigned long maxFramesToCopy; PaUtilChannelDescriptor *hostInputChannels, *hostOutputChannels; unsigned int frameCount; unsigned char *destBytePtr; unsigned int destSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */ unsigned int destChannelStrideBytes; /* stride from one channel to the next, in bytes */ unsigned int i, j; framesAvailable = bp->hostInputFrameCount[0] + bp->hostInputFrameCount[1];/* this is assumed to be the same as the output buffer's frame count */ if( processPartialUserBuffers ) endProcessingMinFrameCount = 0; else endProcessingMinFrameCount = (bp->framesPerUserBuffer - 1); /* Fill host output with remaining frames in user output (tempOutputBuffer) */ CopyTempOutputBuffersToHostOutputBuffers( bp ); while( framesAvailable > endProcessingMinFrameCount ) { if( bp->framesInTempOutputBuffer == 0 && *streamCallbackResult != paContinue ) { /* the callback will not be called any more, so zero what remains of the host output buffers */ for( i=0; i<2; ++i ) { frameCount = bp->hostOutputFrameCount[i]; if( frameCount > 0 ) { hostOutputChannels = bp->hostOutputChannels[i]; for( j=0; joutputChannelCount; ++j ) { bp->outputZeroer( hostOutputChannels[j].data, hostOutputChannels[j].stride, frameCount ); /* advance dest ptr for next iteration */ hostOutputChannels[j].data = ((unsigned char*)hostOutputChannels[j].data) + frameCount * hostOutputChannels[j].stride * bp->bytesPerHostOutputSample; } bp->hostOutputFrameCount[i] = 0; } } } /* copy frames from host to user input buffers */ while( bp->framesInTempInputBuffer < bp->framesPerUserBuffer && ((bp->hostInputFrameCount[0] + bp->hostInputFrameCount[1]) > 0) ) { maxFramesToCopy = bp->framesPerUserBuffer - bp->framesInTempInputBuffer; /* select the input buffer set (1st or 2nd) */ if( bp->hostInputFrameCount[0] > 0 ) { hostInputChannels = bp->hostInputChannels[0]; frameCount = PA_MIN_( bp->hostInputFrameCount[0], maxFramesToCopy ); } else { hostInputChannels = bp->hostInputChannels[1]; frameCount = PA_MIN_( bp->hostInputFrameCount[1], maxFramesToCopy ); } /* configure conversion destination pointers */ if( bp->userInputIsInterleaved ) { destBytePtr = ((unsigned char*)bp->tempInputBuffer) + bp->bytesPerUserInputSample * bp->inputChannelCount * bp->framesInTempInputBuffer; destSampleStrideSamples = bp->inputChannelCount; destChannelStrideBytes = bp->bytesPerUserInputSample; } else /* user input is not interleaved */ { destBytePtr = ((unsigned char*)bp->tempInputBuffer) + bp->bytesPerUserInputSample * bp->framesInTempInputBuffer; destSampleStrideSamples = 1; destChannelStrideBytes = bp->framesPerUserBuffer * bp->bytesPerUserInputSample; } for( i=0; iinputChannelCount; ++i ) { bp->inputConverter( destBytePtr, destSampleStrideSamples, hostInputChannels[i].data, hostInputChannels[i].stride, frameCount, &bp->ditherGenerator ); destBytePtr += destChannelStrideBytes; /* skip to next destination channel */ /* advance src ptr for next iteration */ hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) + frameCount * hostInputChannels[i].stride * bp->bytesPerHostInputSample; } if( bp->hostInputFrameCount[0] > 0 ) bp->hostInputFrameCount[0] -= frameCount; else bp->hostInputFrameCount[1] -= frameCount; bp->framesInTempInputBuffer += frameCount; /* update framesAvailable and framesProcessed based on input consumed unless something is very wrong this will also correspond to the amount of output generated */ framesAvailable -= frameCount; framesProcessed += frameCount; } /* call streamCallback */ if( bp->framesInTempInputBuffer == bp->framesPerUserBuffer && bp->framesInTempOutputBuffer == 0 ) { if( *streamCallbackResult == paContinue ) { /* setup userInput */ if( bp->userInputIsInterleaved ) { userInput = bp->tempInputBuffer; } else /* user input is not interleaved */ { for( i = 0; i < bp->inputChannelCount; ++i ) { bp->tempInputBufferPtrs[i] = ((unsigned char*)bp->tempInputBuffer) + i * bp->framesPerUserBuffer * bp->bytesPerUserInputSample; } userInput = bp->tempInputBufferPtrs; } /* setup userOutput */ if( bp->userOutputIsInterleaved ) { userOutput = bp->tempOutputBuffer; } else /* user output is not interleaved */ { for( i = 0; i < bp->outputChannelCount; ++i ) { bp->tempOutputBufferPtrs[i] = ((unsigned char*)bp->tempOutputBuffer) + i * bp->framesPerUserBuffer * bp->bytesPerUserOutputSample; } userOutput = bp->tempOutputBufferPtrs; } /* call streamCallback */ *streamCallbackResult = bp->streamCallback( userInput, userOutput, bp->framesPerUserBuffer, bp->timeInfo, bp->callbackStatusFlags, bp->userData ); bp->timeInfo->inputBufferAdcTime += bp->framesPerUserBuffer * bp->samplePeriod; bp->timeInfo->outputBufferDacTime += bp->framesPerUserBuffer * bp->samplePeriod; bp->framesInTempInputBuffer = 0; if( *streamCallbackResult == paAbort ) bp->framesInTempOutputBuffer = 0; else bp->framesInTempOutputBuffer = bp->framesPerUserBuffer; } else { /* paComplete or paAbort has already been called. */ bp->framesInTempInputBuffer = 0; } } /* copy frames from user (tempOutputBuffer) to host output buffers (hostOutputChannels) Means to process the user output provided by the callback. Has to be called after each callback. */ CopyTempOutputBuffersToHostOutputBuffers( bp ); } return framesProcessed; } unsigned long PaUtil_EndBufferProcessing( PaUtilBufferProcessor* bp, int *streamCallbackResult ) { unsigned long framesToProcess, framesToGo; unsigned long framesProcessed = 0; if( bp->inputChannelCount != 0 && bp->outputChannelCount != 0 && bp->hostInputChannels[0][0].data /* input was supplied (see PaUtil_SetNoInput) */ && bp->hostOutputChannels[0][0].data /* output was supplied (see PaUtil_SetNoOutput) */ ) { assert( (bp->hostInputFrameCount[0] + bp->hostInputFrameCount[1]) == (bp->hostOutputFrameCount[0] + bp->hostOutputFrameCount[1]) ); } assert( *streamCallbackResult == paContinue || *streamCallbackResult == paComplete || *streamCallbackResult == paAbort ); /* don't forget to pass in a valid callback result value */ if( bp->useNonAdaptingProcess ) { if( bp->inputChannelCount != 0 && bp->outputChannelCount != 0 ) { /* full duplex non-adapting process, splice buffers if they are different lengths */ framesToGo = bp->hostOutputFrameCount[0] + bp->hostOutputFrameCount[1]; /* relies on assert above for input/output equivalence */ do{ unsigned long noInputInputFrameCount; unsigned long *hostInputFrameCount; PaUtilChannelDescriptor *hostInputChannels; unsigned long noOutputOutputFrameCount; unsigned long *hostOutputFrameCount; PaUtilChannelDescriptor *hostOutputChannels; unsigned long framesProcessedThisIteration; if( !bp->hostInputChannels[0][0].data ) { /* no input was supplied (see PaUtil_SetNoInput) NonAdaptingProcess knows how to deal with this */ noInputInputFrameCount = framesToGo; hostInputFrameCount = &noInputInputFrameCount; hostInputChannels = 0; } else if( bp->hostInputFrameCount[0] != 0 ) { hostInputFrameCount = &bp->hostInputFrameCount[0]; hostInputChannels = bp->hostInputChannels[0]; } else { hostInputFrameCount = &bp->hostInputFrameCount[1]; hostInputChannels = bp->hostInputChannels[1]; } if( !bp->hostOutputChannels[0][0].data ) { /* no output was supplied (see PaUtil_SetNoOutput) NonAdaptingProcess knows how to deal with this */ noOutputOutputFrameCount = framesToGo; hostOutputFrameCount = &noOutputOutputFrameCount; hostOutputChannels = 0; } if( bp->hostOutputFrameCount[0] != 0 ) { hostOutputFrameCount = &bp->hostOutputFrameCount[0]; hostOutputChannels = bp->hostOutputChannels[0]; } else { hostOutputFrameCount = &bp->hostOutputFrameCount[1]; hostOutputChannels = bp->hostOutputChannels[1]; } framesToProcess = PA_MIN_( *hostInputFrameCount, *hostOutputFrameCount ); assert( framesToProcess != 0 ); framesProcessedThisIteration = NonAdaptingProcess( bp, streamCallbackResult, hostInputChannels, hostOutputChannels, framesToProcess ); *hostInputFrameCount -= framesProcessedThisIteration; *hostOutputFrameCount -= framesProcessedThisIteration; framesProcessed += framesProcessedThisIteration; framesToGo -= framesProcessedThisIteration; }while( framesToGo > 0 ); } else { /* half duplex non-adapting process, just process 1st and 2nd buffer */ /* process first buffer */ framesToProcess = (bp->inputChannelCount != 0) ? bp->hostInputFrameCount[0] : bp->hostOutputFrameCount[0]; framesProcessed = NonAdaptingProcess( bp, streamCallbackResult, bp->hostInputChannels[0], bp->hostOutputChannels[0], framesToProcess ); /* process second buffer if provided */ framesToProcess = (bp->inputChannelCount != 0) ? bp->hostInputFrameCount[1] : bp->hostOutputFrameCount[1]; if( framesToProcess > 0 ) { framesProcessed += NonAdaptingProcess( bp, streamCallbackResult, bp->hostInputChannels[1], bp->hostOutputChannels[1], framesToProcess ); } } } else /* block adaption necessary*/ { if( bp->inputChannelCount != 0 && bp->outputChannelCount != 0 ) { /* full duplex */ if( bp->hostBufferSizeMode == paUtilVariableHostBufferSizePartialUsageAllowed ) { framesProcessed = AdaptingProcess( bp, streamCallbackResult, 0 /* dont process partial user buffers */ ); } else { framesProcessed = AdaptingProcess( bp, streamCallbackResult, 1 /* process partial user buffers */ ); } } else if( bp->inputChannelCount != 0 ) { /* input only */ framesToProcess = bp->hostInputFrameCount[0]; framesProcessed = AdaptingInputOnlyProcess( bp, streamCallbackResult, bp->hostInputChannels[0], framesToProcess ); framesToProcess = bp->hostInputFrameCount[1]; if( framesToProcess > 0 ) { framesProcessed += AdaptingInputOnlyProcess( bp, streamCallbackResult, bp->hostInputChannels[1], framesToProcess ); } } else { /* output only */ framesToProcess = bp->hostOutputFrameCount[0]; framesProcessed = AdaptingOutputOnlyProcess( bp, streamCallbackResult, bp->hostOutputChannels[0], framesToProcess ); framesToProcess = bp->hostOutputFrameCount[1]; if( framesToProcess > 0 ) { framesProcessed += AdaptingOutputOnlyProcess( bp, streamCallbackResult, bp->hostOutputChannels[1], framesToProcess ); } } } return framesProcessed; } int PaUtil_IsBufferProcessorOutputEmpty( PaUtilBufferProcessor* bp ) { return (bp->framesInTempOutputBuffer) ? 0 : 1; } unsigned long PaUtil_CopyInput( PaUtilBufferProcessor* bp, void **buffer, unsigned long frameCount ) { PaUtilChannelDescriptor *hostInputChannels; unsigned int framesToCopy; unsigned char *destBytePtr; void **nonInterleavedDestPtrs; unsigned int destSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */ unsigned int destChannelStrideBytes; /* stride from one channel to the next, in bytes */ unsigned int i; hostInputChannels = bp->hostInputChannels[0]; framesToCopy = PA_MIN_( bp->hostInputFrameCount[0], frameCount ); if( bp->userInputIsInterleaved ) { destBytePtr = (unsigned char*)*buffer; destSampleStrideSamples = bp->inputChannelCount; destChannelStrideBytes = bp->bytesPerUserInputSample; for( i=0; iinputChannelCount; ++i ) { bp->inputConverter( destBytePtr, destSampleStrideSamples, hostInputChannels[i].data, hostInputChannels[i].stride, framesToCopy, &bp->ditherGenerator ); destBytePtr += destChannelStrideBytes; /* skip to next source channel */ /* advance dest ptr for next iteration */ hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) + framesToCopy * hostInputChannels[i].stride * bp->bytesPerHostInputSample; } /* advance callers dest pointer (buffer) */ *buffer = ((unsigned char *)*buffer) + framesToCopy * bp->inputChannelCount * bp->bytesPerUserInputSample; } else { /* user input is not interleaved */ nonInterleavedDestPtrs = (void**)*buffer; destSampleStrideSamples = 1; for( i=0; iinputChannelCount; ++i ) { destBytePtr = (unsigned char*)nonInterleavedDestPtrs[i]; bp->inputConverter( destBytePtr, destSampleStrideSamples, hostInputChannels[i].data, hostInputChannels[i].stride, framesToCopy, &bp->ditherGenerator ); /* advance callers dest pointer (nonInterleavedDestPtrs[i]) */ destBytePtr += bp->bytesPerUserInputSample * framesToCopy; nonInterleavedDestPtrs[i] = destBytePtr; /* advance dest ptr for next iteration */ hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) + framesToCopy * hostInputChannels[i].stride * bp->bytesPerHostInputSample; } } bp->hostInputFrameCount[0] -= framesToCopy; return framesToCopy; } unsigned long PaUtil_CopyOutput( PaUtilBufferProcessor* bp, const void ** buffer, unsigned long frameCount ) { PaUtilChannelDescriptor *hostOutputChannels; unsigned int framesToCopy; unsigned char *srcBytePtr; void **nonInterleavedSrcPtrs; unsigned int srcSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */ unsigned int srcChannelStrideBytes; /* stride from one channel to the next, in bytes */ unsigned int i; hostOutputChannels = bp->hostOutputChannels[0]; framesToCopy = PA_MIN_( bp->hostOutputFrameCount[0], frameCount ); if( bp->userOutputIsInterleaved ) { srcBytePtr = (unsigned char*)*buffer; srcSampleStrideSamples = bp->outputChannelCount; srcChannelStrideBytes = bp->bytesPerUserOutputSample; for( i=0; ioutputChannelCount; ++i ) { bp->outputConverter( hostOutputChannels[i].data, hostOutputChannels[i].stride, srcBytePtr, srcSampleStrideSamples, framesToCopy, &bp->ditherGenerator ); srcBytePtr += srcChannelStrideBytes; /* skip to next source channel */ /* advance dest ptr for next iteration */ hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) + framesToCopy * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample; } /* advance callers source pointer (buffer) */ *buffer = ((unsigned char *)*buffer) + framesToCopy * bp->outputChannelCount * bp->bytesPerUserOutputSample; } else { /* user output is not interleaved */ nonInterleavedSrcPtrs = (void**)*buffer; srcSampleStrideSamples = 1; for( i=0; ioutputChannelCount; ++i ) { srcBytePtr = (unsigned char*)nonInterleavedSrcPtrs[i]; bp->outputConverter( hostOutputChannels[i].data, hostOutputChannels[i].stride, srcBytePtr, srcSampleStrideSamples, framesToCopy, &bp->ditherGenerator ); /* advance callers source pointer (nonInterleavedSrcPtrs[i]) */ srcBytePtr += bp->bytesPerUserOutputSample * framesToCopy; nonInterleavedSrcPtrs[i] = srcBytePtr; /* advance dest ptr for next iteration */ hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) + framesToCopy * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample; } } bp->hostOutputFrameCount[0] += framesToCopy; return framesToCopy; } unsigned long PaUtil_ZeroOutput( PaUtilBufferProcessor* bp, unsigned long frameCount ) { PaUtilChannelDescriptor *hostOutputChannels; unsigned int framesToZero; unsigned int i; hostOutputChannels = bp->hostOutputChannels[0]; framesToZero = PA_MIN_( bp->hostOutputFrameCount[0], frameCount ); for( i=0; ioutputChannelCount; ++i ) { bp->outputZeroer( hostOutputChannels[i].data, hostOutputChannels[i].stride, framesToZero ); /* advance dest ptr for next iteration */ hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) + framesToZero * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample; } bp->hostOutputFrameCount[0] += framesToZero; return framesToZero; } pd-0.46-7/portaudio/src/hostapi/0000775000175000017500000000000012160204055014633 5ustar mspmsppd-0.46-7/portaudio/src/hostapi/alsa/0000775000175000017500000000000012374245151015564 5ustar mspmsppd-0.46-7/portaudio/src/hostapi/alsa/pa_linux_alsa.c0000664000175000017500000051666412374245151020571 0ustar mspmsp/* * $Id: pa_linux_alsa.c 1893 2013-06-08 19:12:25Z gineera $ * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * ALSA implementation by Joshua Haberman and Arve Knudsen * * Copyright (c) 2002 Joshua Haberman * Copyright (c) 2005-2009 Arve Knudsen * Copyright (c) 2008 Kevin Kofler * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup hostapi_src */ #define ALSA_PCM_NEW_HW_PARAMS_API #define ALSA_PCM_NEW_SW_PARAMS_API #include #undef ALSA_PCM_NEW_HW_PARAMS_API #undef ALSA_PCM_NEW_SW_PARAMS_API #include #include /* strlen() */ #include #include #include #include #include #include #include /* For sig_atomic_t */ #ifdef PA_ALSA_DYNAMIC #include /* For dlXXX functions */ #endif #include "portaudio.h" #include "pa_util.h" #include "pa_unix_util.h" #include "pa_allocation.h" #include "pa_hostapi.h" #include "pa_stream.h" #include "pa_cpuload.h" #include "pa_process.h" #include "pa_endianness.h" #include "pa_debugprint.h" #include "pa_linux_alsa.h" /* Add missing define (for compatibility with older ALSA versions) */ #ifndef SND_PCM_TSTAMP_ENABLE #define SND_PCM_TSTAMP_ENABLE SND_PCM_TSTAMP_MMAP #endif /* Combine version elements into a single (unsigned) integer */ #define ALSA_VERSION_INT(major, minor, subminor) ((major << 16) | (minor << 8) | subminor) /* The acceptable tolerance of sample rate set, to that requested (as a ratio, eg 50 is 2%, 100 is 1%) */ #define RATE_MAX_DEVIATE_RATIO 100 /* Defines Alsa function types and pointers to these functions. */ #define _PA_DEFINE_FUNC(x) typedef typeof(x) x##_ft; static x##_ft *alsa_##x = 0 /* Alloca helper. */ #define __alsa_snd_alloca(ptr,type) do { size_t __alsa_alloca_size = alsa_##type##_sizeof(); (*ptr) = (type##_t *) alloca(__alsa_alloca_size); memset(*ptr, 0, __alsa_alloca_size); } while (0) _PA_DEFINE_FUNC(snd_pcm_open); _PA_DEFINE_FUNC(snd_pcm_close); _PA_DEFINE_FUNC(snd_pcm_nonblock); _PA_DEFINE_FUNC(snd_pcm_frames_to_bytes); _PA_DEFINE_FUNC(snd_pcm_prepare); _PA_DEFINE_FUNC(snd_pcm_start); _PA_DEFINE_FUNC(snd_pcm_resume); _PA_DEFINE_FUNC(snd_pcm_wait); _PA_DEFINE_FUNC(snd_pcm_state); _PA_DEFINE_FUNC(snd_pcm_avail_update); _PA_DEFINE_FUNC(snd_pcm_areas_silence); _PA_DEFINE_FUNC(snd_pcm_mmap_begin); _PA_DEFINE_FUNC(snd_pcm_mmap_commit); _PA_DEFINE_FUNC(snd_pcm_readi); _PA_DEFINE_FUNC(snd_pcm_readn); _PA_DEFINE_FUNC(snd_pcm_writei); _PA_DEFINE_FUNC(snd_pcm_writen); _PA_DEFINE_FUNC(snd_pcm_drain); _PA_DEFINE_FUNC(snd_pcm_recover); _PA_DEFINE_FUNC(snd_pcm_drop); _PA_DEFINE_FUNC(snd_pcm_area_copy); _PA_DEFINE_FUNC(snd_pcm_poll_descriptors); _PA_DEFINE_FUNC(snd_pcm_poll_descriptors_count); _PA_DEFINE_FUNC(snd_pcm_poll_descriptors_revents); _PA_DEFINE_FUNC(snd_pcm_format_size); _PA_DEFINE_FUNC(snd_pcm_link); _PA_DEFINE_FUNC(snd_pcm_delay); _PA_DEFINE_FUNC(snd_pcm_hw_params_sizeof); _PA_DEFINE_FUNC(snd_pcm_hw_params_malloc); _PA_DEFINE_FUNC(snd_pcm_hw_params_free); _PA_DEFINE_FUNC(snd_pcm_hw_params_any); _PA_DEFINE_FUNC(snd_pcm_hw_params_set_access); _PA_DEFINE_FUNC(snd_pcm_hw_params_set_format); _PA_DEFINE_FUNC(snd_pcm_hw_params_set_channels); //_PA_DEFINE_FUNC(snd_pcm_hw_params_set_periods_near); _PA_DEFINE_FUNC(snd_pcm_hw_params_set_rate_near); //!!! _PA_DEFINE_FUNC(snd_pcm_hw_params_set_rate); _PA_DEFINE_FUNC(snd_pcm_hw_params_set_rate_resample); //_PA_DEFINE_FUNC(snd_pcm_hw_params_set_buffer_time_near); _PA_DEFINE_FUNC(snd_pcm_hw_params_set_buffer_size); _PA_DEFINE_FUNC(snd_pcm_hw_params_set_buffer_size_near); //!!! _PA_DEFINE_FUNC(snd_pcm_hw_params_set_buffer_size_min); //_PA_DEFINE_FUNC(snd_pcm_hw_params_set_period_time_near); _PA_DEFINE_FUNC(snd_pcm_hw_params_set_period_size_near); _PA_DEFINE_FUNC(snd_pcm_hw_params_set_periods_integer); _PA_DEFINE_FUNC(snd_pcm_hw_params_set_periods_min); _PA_DEFINE_FUNC(snd_pcm_hw_params_get_buffer_size); //_PA_DEFINE_FUNC(snd_pcm_hw_params_get_period_size); //_PA_DEFINE_FUNC(snd_pcm_hw_params_get_access); //_PA_DEFINE_FUNC(snd_pcm_hw_params_get_periods); //_PA_DEFINE_FUNC(snd_pcm_hw_params_get_rate); _PA_DEFINE_FUNC(snd_pcm_hw_params_get_channels_min); _PA_DEFINE_FUNC(snd_pcm_hw_params_get_channels_max); _PA_DEFINE_FUNC(snd_pcm_hw_params_test_period_size); _PA_DEFINE_FUNC(snd_pcm_hw_params_test_format); _PA_DEFINE_FUNC(snd_pcm_hw_params_test_access); _PA_DEFINE_FUNC(snd_pcm_hw_params_dump); _PA_DEFINE_FUNC(snd_pcm_hw_params); _PA_DEFINE_FUNC(snd_pcm_hw_params_get_periods_min); _PA_DEFINE_FUNC(snd_pcm_hw_params_get_periods_max); _PA_DEFINE_FUNC(snd_pcm_hw_params_set_period_size); _PA_DEFINE_FUNC(snd_pcm_hw_params_get_period_size_min); _PA_DEFINE_FUNC(snd_pcm_hw_params_get_period_size_max); _PA_DEFINE_FUNC(snd_pcm_hw_params_get_buffer_size_max); _PA_DEFINE_FUNC(snd_pcm_hw_params_get_rate_min); _PA_DEFINE_FUNC(snd_pcm_hw_params_get_rate_max); _PA_DEFINE_FUNC(snd_pcm_hw_params_get_rate_numden); #define alsa_snd_pcm_hw_params_alloca(ptr) __alsa_snd_alloca(ptr, snd_pcm_hw_params) _PA_DEFINE_FUNC(snd_pcm_sw_params_sizeof); _PA_DEFINE_FUNC(snd_pcm_sw_params_malloc); _PA_DEFINE_FUNC(snd_pcm_sw_params_current); _PA_DEFINE_FUNC(snd_pcm_sw_params_set_avail_min); _PA_DEFINE_FUNC(snd_pcm_sw_params); _PA_DEFINE_FUNC(snd_pcm_sw_params_free); _PA_DEFINE_FUNC(snd_pcm_sw_params_set_start_threshold); _PA_DEFINE_FUNC(snd_pcm_sw_params_set_stop_threshold); _PA_DEFINE_FUNC(snd_pcm_sw_params_get_boundary); _PA_DEFINE_FUNC(snd_pcm_sw_params_set_silence_threshold); _PA_DEFINE_FUNC(snd_pcm_sw_params_set_silence_size); _PA_DEFINE_FUNC(snd_pcm_sw_params_set_xfer_align); _PA_DEFINE_FUNC(snd_pcm_sw_params_set_tstamp_mode); #define alsa_snd_pcm_sw_params_alloca(ptr) __alsa_snd_alloca(ptr, snd_pcm_sw_params) _PA_DEFINE_FUNC(snd_pcm_info); _PA_DEFINE_FUNC(snd_pcm_info_sizeof); _PA_DEFINE_FUNC(snd_pcm_info_malloc); _PA_DEFINE_FUNC(snd_pcm_info_free); _PA_DEFINE_FUNC(snd_pcm_info_set_device); _PA_DEFINE_FUNC(snd_pcm_info_set_subdevice); _PA_DEFINE_FUNC(snd_pcm_info_set_stream); _PA_DEFINE_FUNC(snd_pcm_info_get_name); _PA_DEFINE_FUNC(snd_pcm_info_get_card); #define alsa_snd_pcm_info_alloca(ptr) __alsa_snd_alloca(ptr, snd_pcm_info) _PA_DEFINE_FUNC(snd_ctl_pcm_next_device); _PA_DEFINE_FUNC(snd_ctl_pcm_info); _PA_DEFINE_FUNC(snd_ctl_open); _PA_DEFINE_FUNC(snd_ctl_close); _PA_DEFINE_FUNC(snd_ctl_card_info_malloc); _PA_DEFINE_FUNC(snd_ctl_card_info_free); _PA_DEFINE_FUNC(snd_ctl_card_info); _PA_DEFINE_FUNC(snd_ctl_card_info_sizeof); _PA_DEFINE_FUNC(snd_ctl_card_info_get_name); #define alsa_snd_ctl_card_info_alloca(ptr) __alsa_snd_alloca(ptr, snd_ctl_card_info) _PA_DEFINE_FUNC(snd_config); _PA_DEFINE_FUNC(snd_config_update); _PA_DEFINE_FUNC(snd_config_search); _PA_DEFINE_FUNC(snd_config_iterator_entry); _PA_DEFINE_FUNC(snd_config_iterator_first); _PA_DEFINE_FUNC(snd_config_iterator_end); _PA_DEFINE_FUNC(snd_config_iterator_next); _PA_DEFINE_FUNC(snd_config_get_string); _PA_DEFINE_FUNC(snd_config_get_id); _PA_DEFINE_FUNC(snd_config_update_free_global); _PA_DEFINE_FUNC(snd_pcm_status); _PA_DEFINE_FUNC(snd_pcm_status_sizeof); _PA_DEFINE_FUNC(snd_pcm_status_get_tstamp); _PA_DEFINE_FUNC(snd_pcm_status_get_state); _PA_DEFINE_FUNC(snd_pcm_status_get_trigger_tstamp); _PA_DEFINE_FUNC(snd_pcm_status_get_delay); #define alsa_snd_pcm_status_alloca(ptr) __alsa_snd_alloca(ptr, snd_pcm_status) _PA_DEFINE_FUNC(snd_card_next); _PA_DEFINE_FUNC(snd_asoundlib_version); _PA_DEFINE_FUNC(snd_strerror); _PA_DEFINE_FUNC(snd_output_stdio_attach); #define alsa_snd_config_for_each(pos, next, node)\ for (pos = alsa_snd_config_iterator_first(node),\ next = alsa_snd_config_iterator_next(pos);\ pos != alsa_snd_config_iterator_end(node); pos = next, next = alsa_snd_config_iterator_next(pos)) #undef _PA_DEFINE_FUNC /* Redefine 'PA_ALSA_PATHNAME' to a different Alsa library name if desired. */ #ifndef PA_ALSA_PATHNAME #define PA_ALSA_PATHNAME "libasound.so" #endif static const char *g_AlsaLibName = PA_ALSA_PATHNAME; /* Handle to dynamically loaded library. */ static void *g_AlsaLib = NULL; #ifdef PA_ALSA_DYNAMIC #define _PA_LOCAL_IMPL(x) __pa_local_##x int _PA_LOCAL_IMPL(snd_pcm_hw_params_set_rate_near) (snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir) { int ret; if(( ret = alsa_snd_pcm_hw_params_set_rate(pcm, params, (*val), (*dir)) ) < 0 ) return ret; return 0; } int _PA_LOCAL_IMPL(snd_pcm_hw_params_set_buffer_size_near) (snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val) { int ret; if(( ret = alsa_snd_pcm_hw_params_set_buffer_size(pcm, params, (*val)) ) < 0 ) return ret; return 0; } int _PA_LOCAL_IMPL(snd_pcm_hw_params_set_period_size_near) (snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir) { int ret; if(( ret = alsa_snd_pcm_hw_params_set_period_size(pcm, params, (*val), (*dir)) ) < 0 ) return ret; return 0; } int _PA_LOCAL_IMPL(snd_pcm_hw_params_get_channels_min) (const snd_pcm_hw_params_t *params, unsigned int *val) { (*val) = 1; return 0; } int _PA_LOCAL_IMPL(snd_pcm_hw_params_get_channels_max) (const snd_pcm_hw_params_t *params, unsigned int *val) { (*val) = 2; return 0; } int _PA_LOCAL_IMPL(snd_pcm_hw_params_get_periods_min) (const snd_pcm_hw_params_t *params, unsigned int *val, int *dir) { (*val) = 2; return 0; } int _PA_LOCAL_IMPL(snd_pcm_hw_params_get_periods_max) (const snd_pcm_hw_params_t *params, unsigned int *val, int *dir) { (*val) = 8; return 0; } int _PA_LOCAL_IMPL(snd_pcm_hw_params_get_period_size_min) (const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *frames, int *dir) { (*frames) = 64; return 0; } int _PA_LOCAL_IMPL(snd_pcm_hw_params_get_period_size_max) (const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *frames, int *dir) { (*frames) = 512; return 0; } int _PA_LOCAL_IMPL(snd_pcm_hw_params_get_buffer_size_max) (const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val) { int ret; int dir = 0; snd_pcm_uframes_t pmax = 0; unsigned int pcnt = 0; if(( ret = _PA_LOCAL_IMPL(snd_pcm_hw_params_get_period_size_max)(params, &pmax, &dir) ) < 0 ) return ret; if(( ret = _PA_LOCAL_IMPL(snd_pcm_hw_params_get_periods_max)(params, &pcnt, &dir) ) < 0 ) return ret; (*val) = pmax * pcnt; return 0; } int _PA_LOCAL_IMPL(snd_pcm_hw_params_get_rate_min) (const snd_pcm_hw_params_t *params, unsigned int *val, int *dir) { (*val) = 44100; return 0; } int _PA_LOCAL_IMPL(snd_pcm_hw_params_get_rate_max) (const snd_pcm_hw_params_t *params, unsigned int *val, int *dir) { (*val) = 44100; return 0; } #endif // PA_ALSA_DYNAMIC /* Trying to load Alsa library dynamically if 'PA_ALSA_DYNAMIC' is defined, othervise will link during compilation. */ static int PaAlsa_LoadLibrary() { #ifdef PA_ALSA_DYNAMIC PA_DEBUG(( "%s: loading ALSA library file - %s\n", __FUNCTION__, g_AlsaLibName )); dlerror(); g_AlsaLib = dlopen(g_AlsaLibName, (RTLD_NOW|RTLD_GLOBAL) ); if (g_AlsaLib == NULL) { PA_DEBUG(( "%s: failed dlopen() ALSA library file - %s, error: %s\n", __FUNCTION__, g_AlsaLibName, dlerror() )); return 0; } PA_DEBUG(( "%s: loading ALSA API\n", __FUNCTION__ )); #define _PA_LOAD_FUNC(x) do { \ alsa_##x = dlsym( g_AlsaLib, #x ); \ if( alsa_##x == NULL ) { \ PA_DEBUG(( "%s: symbol [%s] not found in - %s, error: %s\n", __FUNCTION__, #x, g_AlsaLibName, dlerror() )); }\ } while(0) #else #define _PA_LOAD_FUNC(x) alsa_##x = &x #endif _PA_LOAD_FUNC(snd_pcm_open); _PA_LOAD_FUNC(snd_pcm_close); _PA_LOAD_FUNC(snd_pcm_nonblock); _PA_LOAD_FUNC(snd_pcm_frames_to_bytes); _PA_LOAD_FUNC(snd_pcm_prepare); _PA_LOAD_FUNC(snd_pcm_start); _PA_LOAD_FUNC(snd_pcm_resume); _PA_LOAD_FUNC(snd_pcm_wait); _PA_LOAD_FUNC(snd_pcm_state); _PA_LOAD_FUNC(snd_pcm_avail_update); _PA_LOAD_FUNC(snd_pcm_areas_silence); _PA_LOAD_FUNC(snd_pcm_mmap_begin); _PA_LOAD_FUNC(snd_pcm_mmap_commit); _PA_LOAD_FUNC(snd_pcm_readi); _PA_LOAD_FUNC(snd_pcm_readn); _PA_LOAD_FUNC(snd_pcm_writei); _PA_LOAD_FUNC(snd_pcm_writen); _PA_LOAD_FUNC(snd_pcm_drain); _PA_LOAD_FUNC(snd_pcm_recover); _PA_LOAD_FUNC(snd_pcm_drop); _PA_LOAD_FUNC(snd_pcm_area_copy); _PA_LOAD_FUNC(snd_pcm_poll_descriptors); _PA_LOAD_FUNC(snd_pcm_poll_descriptors_count); _PA_LOAD_FUNC(snd_pcm_poll_descriptors_revents); _PA_LOAD_FUNC(snd_pcm_format_size); _PA_LOAD_FUNC(snd_pcm_link); _PA_LOAD_FUNC(snd_pcm_delay); _PA_LOAD_FUNC(snd_pcm_hw_params_sizeof); _PA_LOAD_FUNC(snd_pcm_hw_params_malloc); _PA_LOAD_FUNC(snd_pcm_hw_params_free); _PA_LOAD_FUNC(snd_pcm_hw_params_any); _PA_LOAD_FUNC(snd_pcm_hw_params_set_access); _PA_LOAD_FUNC(snd_pcm_hw_params_set_format); _PA_LOAD_FUNC(snd_pcm_hw_params_set_channels); // _PA_LOAD_FUNC(snd_pcm_hw_params_set_periods_near); _PA_LOAD_FUNC(snd_pcm_hw_params_set_rate_near); _PA_LOAD_FUNC(snd_pcm_hw_params_set_rate); _PA_LOAD_FUNC(snd_pcm_hw_params_set_rate_resample); // _PA_LOAD_FUNC(snd_pcm_hw_params_set_buffer_time_near); _PA_LOAD_FUNC(snd_pcm_hw_params_set_buffer_size); _PA_LOAD_FUNC(snd_pcm_hw_params_set_buffer_size_near); _PA_LOAD_FUNC(snd_pcm_hw_params_set_buffer_size_min); // _PA_LOAD_FUNC(snd_pcm_hw_params_set_period_time_near); _PA_LOAD_FUNC(snd_pcm_hw_params_set_period_size_near); _PA_LOAD_FUNC(snd_pcm_hw_params_set_periods_integer); _PA_LOAD_FUNC(snd_pcm_hw_params_set_periods_min); _PA_LOAD_FUNC(snd_pcm_hw_params_get_buffer_size); // _PA_LOAD_FUNC(snd_pcm_hw_params_get_period_size); // _PA_LOAD_FUNC(snd_pcm_hw_params_get_access); // _PA_LOAD_FUNC(snd_pcm_hw_params_get_periods); // _PA_LOAD_FUNC(snd_pcm_hw_params_get_rate); _PA_LOAD_FUNC(snd_pcm_hw_params_get_channels_min); _PA_LOAD_FUNC(snd_pcm_hw_params_get_channels_max); _PA_LOAD_FUNC(snd_pcm_hw_params_test_period_size); _PA_LOAD_FUNC(snd_pcm_hw_params_test_format); _PA_LOAD_FUNC(snd_pcm_hw_params_test_access); _PA_LOAD_FUNC(snd_pcm_hw_params_dump); _PA_LOAD_FUNC(snd_pcm_hw_params); _PA_LOAD_FUNC(snd_pcm_hw_params_get_periods_min); _PA_LOAD_FUNC(snd_pcm_hw_params_get_periods_max); _PA_LOAD_FUNC(snd_pcm_hw_params_set_period_size); _PA_LOAD_FUNC(snd_pcm_hw_params_get_period_size_min); _PA_LOAD_FUNC(snd_pcm_hw_params_get_period_size_max); _PA_LOAD_FUNC(snd_pcm_hw_params_get_buffer_size_max); _PA_LOAD_FUNC(snd_pcm_hw_params_get_rate_min); _PA_LOAD_FUNC(snd_pcm_hw_params_get_rate_max); _PA_LOAD_FUNC(snd_pcm_hw_params_get_rate_numden); _PA_LOAD_FUNC(snd_pcm_sw_params_sizeof); _PA_LOAD_FUNC(snd_pcm_sw_params_malloc); _PA_LOAD_FUNC(snd_pcm_sw_params_current); _PA_LOAD_FUNC(snd_pcm_sw_params_set_avail_min); _PA_LOAD_FUNC(snd_pcm_sw_params); _PA_LOAD_FUNC(snd_pcm_sw_params_free); _PA_LOAD_FUNC(snd_pcm_sw_params_set_start_threshold); _PA_LOAD_FUNC(snd_pcm_sw_params_set_stop_threshold); _PA_LOAD_FUNC(snd_pcm_sw_params_get_boundary); _PA_LOAD_FUNC(snd_pcm_sw_params_set_silence_threshold); _PA_LOAD_FUNC(snd_pcm_sw_params_set_silence_size); _PA_LOAD_FUNC(snd_pcm_sw_params_set_xfer_align); _PA_LOAD_FUNC(snd_pcm_sw_params_set_tstamp_mode); _PA_LOAD_FUNC(snd_pcm_info); _PA_LOAD_FUNC(snd_pcm_info_sizeof); _PA_LOAD_FUNC(snd_pcm_info_malloc); _PA_LOAD_FUNC(snd_pcm_info_free); _PA_LOAD_FUNC(snd_pcm_info_set_device); _PA_LOAD_FUNC(snd_pcm_info_set_subdevice); _PA_LOAD_FUNC(snd_pcm_info_set_stream); _PA_LOAD_FUNC(snd_pcm_info_get_name); _PA_LOAD_FUNC(snd_pcm_info_get_card); _PA_LOAD_FUNC(snd_ctl_pcm_next_device); _PA_LOAD_FUNC(snd_ctl_pcm_info); _PA_LOAD_FUNC(snd_ctl_open); _PA_LOAD_FUNC(snd_ctl_close); _PA_LOAD_FUNC(snd_ctl_card_info_malloc); _PA_LOAD_FUNC(snd_ctl_card_info_free); _PA_LOAD_FUNC(snd_ctl_card_info); _PA_LOAD_FUNC(snd_ctl_card_info_sizeof); _PA_LOAD_FUNC(snd_ctl_card_info_get_name); _PA_LOAD_FUNC(snd_config); _PA_LOAD_FUNC(snd_config_update); _PA_LOAD_FUNC(snd_config_search); _PA_LOAD_FUNC(snd_config_iterator_entry); _PA_LOAD_FUNC(snd_config_iterator_first); _PA_LOAD_FUNC(snd_config_iterator_end); _PA_LOAD_FUNC(snd_config_iterator_next); _PA_LOAD_FUNC(snd_config_get_string); _PA_LOAD_FUNC(snd_config_get_id); _PA_LOAD_FUNC(snd_config_update_free_global); _PA_LOAD_FUNC(snd_pcm_status); _PA_LOAD_FUNC(snd_pcm_status_sizeof); _PA_LOAD_FUNC(snd_pcm_status_get_tstamp); _PA_LOAD_FUNC(snd_pcm_status_get_state); _PA_LOAD_FUNC(snd_pcm_status_get_trigger_tstamp); _PA_LOAD_FUNC(snd_pcm_status_get_delay); _PA_LOAD_FUNC(snd_card_next); _PA_LOAD_FUNC(snd_asoundlib_version); _PA_LOAD_FUNC(snd_strerror); _PA_LOAD_FUNC(snd_output_stdio_attach); #undef _PA_LOAD_FUNC #ifdef PA_ALSA_DYNAMIC PA_DEBUG(( "%s: loaded ALSA API - ok\n", __FUNCTION__ )); #define _PA_VALIDATE_LOAD_REPLACEMENT(x)\ do {\ if( alsa_##x == NULL )\ {\ alsa_##x = &_PA_LOCAL_IMPL(x);\ PA_DEBUG(( "%s: replacing [%s] with local implementation\n", __FUNCTION__, #x ));\ }\ } while (0) _PA_VALIDATE_LOAD_REPLACEMENT(snd_pcm_hw_params_set_rate_near); _PA_VALIDATE_LOAD_REPLACEMENT(snd_pcm_hw_params_set_buffer_size_near); _PA_VALIDATE_LOAD_REPLACEMENT(snd_pcm_hw_params_set_period_size_near); _PA_VALIDATE_LOAD_REPLACEMENT(snd_pcm_hw_params_get_channels_min); _PA_VALIDATE_LOAD_REPLACEMENT(snd_pcm_hw_params_get_channels_max); _PA_VALIDATE_LOAD_REPLACEMENT(snd_pcm_hw_params_get_periods_min); _PA_VALIDATE_LOAD_REPLACEMENT(snd_pcm_hw_params_get_periods_max); _PA_VALIDATE_LOAD_REPLACEMENT(snd_pcm_hw_params_get_period_size_min); _PA_VALIDATE_LOAD_REPLACEMENT(snd_pcm_hw_params_get_period_size_max); _PA_VALIDATE_LOAD_REPLACEMENT(snd_pcm_hw_params_get_buffer_size_max); _PA_VALIDATE_LOAD_REPLACEMENT(snd_pcm_hw_params_get_rate_min); _PA_VALIDATE_LOAD_REPLACEMENT(snd_pcm_hw_params_get_rate_max); #undef _PA_LOCAL_IMPL #undef _PA_VALIDATE_LOAD_REPLACEMENT #endif // PA_ALSA_DYNAMIC return 1; } void PaAlsa_SetLibraryPathName( const char *pathName ) { #ifdef PA_ALSA_DYNAMIC g_AlsaLibName = pathName; #else (void)pathName; #endif } /* Close handle to Alsa library. */ static void PaAlsa_CloseLibrary() { #ifdef PA_ALSA_DYNAMIC dlclose(g_AlsaLib); g_AlsaLib = NULL; #endif } /* Check return value of ALSA function, and map it to PaError */ #define ENSURE_(expr, code) \ do { \ int __pa_unsure_error_id;\ if( UNLIKELY( (__pa_unsure_error_id = (expr)) < 0 ) ) \ { \ /* PaUtil_SetLastHostErrorInfo should only be used in the main thread */ \ if( (code) == paUnanticipatedHostError && pthread_equal( pthread_self(), paUnixMainThread) ) \ { \ PaUtil_SetLastHostErrorInfo( paALSA, __pa_unsure_error_id, alsa_snd_strerror( __pa_unsure_error_id ) ); \ } \ PaUtil_DebugPrint( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" ); \ if( (code) == paUnanticipatedHostError ) \ PA_DEBUG(( "Host error description: %s\n", alsa_snd_strerror( __pa_unsure_error_id ) )); \ result = (code); \ goto error; \ } \ } while (0) #define ASSERT_CALL_(expr, success) \ do {\ int __pa_assert_error_id;\ __pa_assert_error_id = (expr);\ assert( success == __pa_assert_error_id );\ } while (0) static int numPeriods_ = 4; static int busyRetries_ = 100; int PaAlsa_SetNumPeriods( int numPeriods ) { numPeriods_ = numPeriods; return paNoError; } typedef enum { StreamDirection_In, StreamDirection_Out } StreamDirection; typedef struct { PaSampleFormat hostSampleFormat; unsigned long framesPerBuffer; int numUserChannels, numHostChannels; int userInterleaved, hostInterleaved; int canMmap; void *nonMmapBuffer; unsigned int nonMmapBufferSize; PaDeviceIndex device; /* Keep the device index */ int deviceIsPlug; /* Distinguish plug types from direct 'hw:' devices */ int useReventFix; /* Alsa older than 1.0.16, plug devices need a fix */ snd_pcm_t *pcm; snd_pcm_uframes_t bufferSize; snd_pcm_format_t nativeFormat; unsigned int nfds; int ready; /* Marked ready from poll */ void **userBuffers; snd_pcm_uframes_t offset; StreamDirection streamDir; snd_pcm_channel_area_t *channelAreas; /* Needed for channel adaption */ } PaAlsaStreamComponent; /* Implementation specific stream structure */ typedef struct PaAlsaStream { PaUtilStreamRepresentation streamRepresentation; PaUtilCpuLoadMeasurer cpuLoadMeasurer; PaUtilBufferProcessor bufferProcessor; PaUnixThread thread; unsigned long framesPerUserBuffer, maxFramesPerHostBuffer; int primeBuffers; int callbackMode; /* bool: are we running in callback mode? */ int pcmsSynced; /* Have we successfully synced pcms */ int rtSched; /* the callback thread uses these to poll the sound device(s), waiting * for data to be ready/available */ struct pollfd* pfds; int pollTimeout; /* Used in communication between threads */ volatile sig_atomic_t callback_finished; /* bool: are we in the "callback finished" state? */ volatile sig_atomic_t callbackAbort; /* Drop frames? */ volatile sig_atomic_t isActive; /* Is stream in active state? (Between StartStream and StopStream || !paContinue) */ PaUnixMutex stateMtx; /* Used to synchronize access to stream state */ int neverDropInput; PaTime underrun; PaTime overrun; PaAlsaStreamComponent capture, playback; } PaAlsaStream; /* PaAlsaHostApiRepresentation - host api datastructure specific to this implementation */ typedef struct PaAlsaHostApiRepresentation { PaUtilHostApiRepresentation baseHostApiRep; PaUtilStreamInterface callbackStreamInterface; PaUtilStreamInterface blockingStreamInterface; PaUtilAllocationGroup *allocations; PaHostApiIndex hostApiIndex; PaUint32 alsaLibVersion; /* Retrieved from the library at run-time */ } PaAlsaHostApiRepresentation; typedef struct PaAlsaDeviceInfo { PaDeviceInfo baseDeviceInfo; char *alsaName; int isPlug; int minInputChannels; int minOutputChannels; } PaAlsaDeviceInfo; /* prototypes for functions declared in this file */ static void Terminate( struct PaUtilHostApiRepresentation *hostApi ); static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ); static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *callback, void *userData ); static PaError CloseStream( PaStream* stream ); static PaError StartStream( PaStream *stream ); static PaError StopStream( PaStream *stream ); static PaError AbortStream( PaStream *stream ); static PaError IsStreamStopped( PaStream *s ); static PaError IsStreamActive( PaStream *stream ); static PaTime GetStreamTime( PaStream *stream ); static double GetStreamCpuLoad( PaStream* stream ); static PaError BuildDeviceList( PaAlsaHostApiRepresentation *hostApi ); static int SetApproximateSampleRate( snd_pcm_t *pcm, snd_pcm_hw_params_t *hwParams, double sampleRate ); static int GetExactSampleRate( snd_pcm_hw_params_t *hwParams, double *sampleRate ); static PaUint32 PaAlsaVersionNum(void); /* Callback prototypes */ static void *CallbackThreadFunc( void *userData ); /* Blocking prototypes */ static signed long GetStreamReadAvailable( PaStream* s ); static signed long GetStreamWriteAvailable( PaStream* s ); static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames ); static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames ); static const PaAlsaDeviceInfo *GetDeviceInfo( const PaUtilHostApiRepresentation *hostApi, int device ) { return (const PaAlsaDeviceInfo *)hostApi->deviceInfos[device]; } /** Uncommented because AlsaErrorHandler is unused for anything good yet. If AlsaErrorHandler is to be used, do not forget to register this callback in PaAlsa_Initialize, and unregister in Terminate. */ /*static void AlsaErrorHandler(const char *file, int line, const char *function, int err, const char *fmt, ...) { }*/ PaError PaAlsa_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) { PaError result = paNoError; PaAlsaHostApiRepresentation *alsaHostApi = NULL; /* Try loading Alsa library. */ if (!PaAlsa_LoadLibrary()) return paHostApiNotFound; PA_UNLESS( alsaHostApi = (PaAlsaHostApiRepresentation*) PaUtil_AllocateMemory( sizeof(PaAlsaHostApiRepresentation) ), paInsufficientMemory ); PA_UNLESS( alsaHostApi->allocations = PaUtil_CreateAllocationGroup(), paInsufficientMemory ); alsaHostApi->hostApiIndex = hostApiIndex; alsaHostApi->alsaLibVersion = PaAlsaVersionNum(); *hostApi = (PaUtilHostApiRepresentation*)alsaHostApi; (*hostApi)->info.structVersion = 1; (*hostApi)->info.type = paALSA; (*hostApi)->info.name = "ALSA"; (*hostApi)->Terminate = Terminate; (*hostApi)->OpenStream = OpenStream; (*hostApi)->IsFormatSupported = IsFormatSupported; /** If AlsaErrorHandler is to be used, do not forget to unregister callback pointer in Terminate function. */ /*ENSURE_( snd_lib_error_set_handler(AlsaErrorHandler), paUnanticipatedHostError );*/ PA_ENSURE( BuildDeviceList( alsaHostApi ) ); PaUtil_InitializeStreamInterface( &alsaHostApi->callbackStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, GetStreamCpuLoad, PaUtil_DummyRead, PaUtil_DummyWrite, PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable ); PaUtil_InitializeStreamInterface( &alsaHostApi->blockingStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, PaUtil_DummyGetCpuLoad, ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable ); PA_ENSURE( PaUnixThreading_Initialize() ); return result; error: if( alsaHostApi ) { if( alsaHostApi->allocations ) { PaUtil_FreeAllAllocations( alsaHostApi->allocations ); PaUtil_DestroyAllocationGroup( alsaHostApi->allocations ); } PaUtil_FreeMemory( alsaHostApi ); } return result; } static void Terminate( struct PaUtilHostApiRepresentation *hostApi ) { PaAlsaHostApiRepresentation *alsaHostApi = (PaAlsaHostApiRepresentation*)hostApi; assert( hostApi ); /** See AlsaErrorHandler and PaAlsa_Initialize for details. */ /*snd_lib_error_set_handler(NULL);*/ if( alsaHostApi->allocations ) { PaUtil_FreeAllAllocations( alsaHostApi->allocations ); PaUtil_DestroyAllocationGroup( alsaHostApi->allocations ); } PaUtil_FreeMemory( alsaHostApi ); alsa_snd_config_update_free_global(); /* Close Alsa library. */ PaAlsa_CloseLibrary(); } /** Determine max channels and default latencies. * * This function provides functionality to grope an opened (might be opened for capture or playback) pcm device for * traits like max channels, suitable default latencies and default sample rate. Upon error, max channels is set to zero, * and a suitable result returned. The device is closed before returning. */ static PaError GropeDevice( snd_pcm_t* pcm, int isPlug, StreamDirection mode, int openBlocking, PaAlsaDeviceInfo* devInfo ) { PaError result = paNoError; snd_pcm_hw_params_t *hwParams; snd_pcm_uframes_t alsaBufferFrames, alsaPeriodFrames; unsigned int minChans, maxChans; int* minChannels, * maxChannels; double * defaultLowLatency, * defaultHighLatency, * defaultSampleRate = &devInfo->baseDeviceInfo.defaultSampleRate; double defaultSr = *defaultSampleRate; int dir; assert( pcm ); PA_DEBUG(( "%s: collecting info ..\n", __FUNCTION__ )); if( StreamDirection_In == mode ) { minChannels = &devInfo->minInputChannels; maxChannels = &devInfo->baseDeviceInfo.maxInputChannels; defaultLowLatency = &devInfo->baseDeviceInfo.defaultLowInputLatency; defaultHighLatency = &devInfo->baseDeviceInfo.defaultHighInputLatency; } else { minChannels = &devInfo->minOutputChannels; maxChannels = &devInfo->baseDeviceInfo.maxOutputChannels; defaultLowLatency = &devInfo->baseDeviceInfo.defaultLowOutputLatency; defaultHighLatency = &devInfo->baseDeviceInfo.defaultHighOutputLatency; } ENSURE_( alsa_snd_pcm_nonblock( pcm, 0 ), paUnanticipatedHostError ); alsa_snd_pcm_hw_params_alloca( &hwParams ); alsa_snd_pcm_hw_params_any( pcm, hwParams ); if( defaultSr >= 0 ) { /* Could be that the device opened in one mode supports samplerates that the other mode wont have, * so try again .. */ if( SetApproximateSampleRate( pcm, hwParams, defaultSr ) < 0 ) { defaultSr = -1.; alsa_snd_pcm_hw_params_any( pcm, hwParams ); /* Clear any params (rate) that might have been set */ PA_DEBUG(( "%s: Original default samplerate failed, trying again ..\n", __FUNCTION__ )); } } if( defaultSr < 0. ) /* Default sample rate not set */ { unsigned int sampleRate = 44100; /* Will contain approximate rate returned by alsa-lib */ /* Don't allow rate resampling when probing for the default rate (but ignore if this call fails) */ alsa_snd_pcm_hw_params_set_rate_resample( pcm, hwParams, 0 ); if( alsa_snd_pcm_hw_params_set_rate_near( pcm, hwParams, &sampleRate, NULL ) < 0 ) { result = paUnanticipatedHostError; goto error; } ENSURE_( GetExactSampleRate( hwParams, &defaultSr ), paUnanticipatedHostError ); } ENSURE_( alsa_snd_pcm_hw_params_get_channels_min( hwParams, &minChans ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_hw_params_get_channels_max( hwParams, &maxChans ), paUnanticipatedHostError ); assert( maxChans <= INT_MAX ); assert( maxChans > 0 ); /* Weird linking issue could cause wrong version of ALSA symbols to be called, resulting in zeroed values */ /* XXX: Limit to sensible number (ALSA plugins accept a crazy amount of channels)? */ if( isPlug && maxChans > 128 ) { maxChans = 128; PA_DEBUG(( "%s: Limiting number of plugin channels to %u\n", __FUNCTION__, maxChans )); } /* TWEAKME: * Giving values for default min and max latency is not straightforward. * * for low latency, we want to give the lowest value that will work reliably. * This varies based on the sound card, kernel, CPU, etc. Better to give * sub-optimal latency than to give a number too low and cause dropouts. * * for high latency we want to give a large enough value that dropouts are basically impossible. * This doesn't really require as much tweaking, since providing too large a number will * just cause us to select the nearest setting that will work at stream config time. */ /* Try low latency values, (sometimes the buffer & period that result are larger) */ alsaBufferFrames = 512; alsaPeriodFrames = 128; ENSURE_( alsa_snd_pcm_hw_params_set_buffer_size_near( pcm, hwParams, &alsaBufferFrames ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_hw_params_set_period_size_near( pcm, hwParams, &alsaPeriodFrames, &dir ), paUnanticipatedHostError ); *defaultLowLatency = (double) (alsaBufferFrames - alsaPeriodFrames) / defaultSr; /* Base the high latency case on values four times larger */ alsaBufferFrames = 2048; alsaPeriodFrames = 512; /* Have to reset hwParams, to set new buffer size; need to also set sample rate again */ ENSURE_( alsa_snd_pcm_hw_params_any( pcm, hwParams ), paUnanticipatedHostError ); ENSURE_( SetApproximateSampleRate( pcm, hwParams, defaultSr ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_hw_params_set_buffer_size_near( pcm, hwParams, &alsaBufferFrames ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_hw_params_set_period_size_near( pcm, hwParams, &alsaPeriodFrames, &dir ), paUnanticipatedHostError ); *defaultHighLatency = (double) (alsaBufferFrames - alsaPeriodFrames) / defaultSr; *minChannels = (int)minChans; *maxChannels = (int)maxChans; *defaultSampleRate = defaultSr; end: alsa_snd_pcm_close( pcm ); return result; error: goto end; } /* Initialize device info with invalid values (maxInputChannels and maxOutputChannels are set to zero since these indicate * wether input/output is available) */ static void InitializeDeviceInfo( PaDeviceInfo *deviceInfo ) { deviceInfo->structVersion = -1; deviceInfo->name = NULL; deviceInfo->hostApi = -1; deviceInfo->maxInputChannels = 0; deviceInfo->maxOutputChannels = 0; deviceInfo->defaultLowInputLatency = -1.; deviceInfo->defaultLowOutputLatency = -1.; deviceInfo->defaultHighInputLatency = -1.; deviceInfo->defaultHighOutputLatency = -1.; deviceInfo->defaultSampleRate = -1.; } /* Retrieve the version of the runtime Alsa-lib, as a single number equivalent to * SND_LIB_VERSION. Only a version string is available ("a.b.c") so this has to be converted. * Assume 'a' and 'b' are single digits only. */ static PaUint32 PaAlsaVersionNum(void) { char* verStr; PaUint32 verNum; verStr = (char*) alsa_snd_asoundlib_version(); verNum = ALSA_VERSION_INT( atoi(verStr), atoi(verStr + 2), atoi(verStr + 4) ); PA_DEBUG(( "ALSA version (build): " SND_LIB_VERSION_STR "\nALSA version (runtime): %s\n", verStr )); return verNum; } /* Helper struct */ typedef struct { char *alsaName; char *name; int isPlug; int hasPlayback; int hasCapture; } HwDevInfo; HwDevInfo predefinedNames[] = { { "center_lfe", NULL, 0, 1, 0 }, /* { "default", NULL, 0, 1, 1 }, */ { "dmix", NULL, 0, 1, 0 }, /* { "dpl", NULL, 0, 1, 0 }, */ /* { "dsnoop", NULL, 0, 0, 1 }, */ { "front", NULL, 0, 1, 0 }, { "iec958", NULL, 0, 1, 0 }, /* { "modem", NULL, 0, 1, 0 }, */ { "rear", NULL, 0, 1, 0 }, { "side", NULL, 0, 1, 0 }, /* { "spdif", NULL, 0, 0, 0 }, */ { "surround40", NULL, 0, 1, 0 }, { "surround41", NULL, 0, 1, 0 }, { "surround50", NULL, 0, 1, 0 }, { "surround51", NULL, 0, 1, 0 }, { "surround71", NULL, 0, 1, 0 }, { "AndroidPlayback_Earpiece_normal", NULL, 0, 1, 0 }, { "AndroidPlayback_Speaker_normal", NULL, 0, 1, 0 }, { "AndroidPlayback_Bluetooth_normal", NULL, 0, 1, 0 }, { "AndroidPlayback_Headset_normal", NULL, 0, 1, 0 }, { "AndroidPlayback_Speaker_Headset_normal", NULL, 0, 1, 0 }, { "AndroidPlayback_Bluetooth-A2DP_normal", NULL, 0, 1, 0 }, { "AndroidPlayback_ExtraDockSpeaker_normal", NULL, 0, 1, 0 }, { "AndroidPlayback_TvOut_normal", NULL, 0, 1, 0 }, { "AndroidRecord_Microphone", NULL, 0, 0, 1 }, { "AndroidRecord_Earpiece_normal", NULL, 0, 0, 1 }, { "AndroidRecord_Speaker_normal", NULL, 0, 0, 1 }, { "AndroidRecord_Headset_normal", NULL, 0, 0, 1 }, { "AndroidRecord_Bluetooth_normal", NULL, 0, 0, 1 }, { "AndroidRecord_Speaker_Headset_normal", NULL, 0, 0, 1 }, { NULL, NULL, 0, 1, 0 } }; static const HwDevInfo *FindDeviceName( const char *name ) { int i; for( i = 0; predefinedNames[i].alsaName; i++ ) { if( strcmp( name, predefinedNames[i].alsaName ) == 0 ) { return &predefinedNames[i]; } } return NULL; } static PaError PaAlsa_StrDup( PaAlsaHostApiRepresentation *alsaApi, char **dst, const char *src) { PaError result = paNoError; int len = strlen( src ) + 1; /* PA_DEBUG(("PaStrDup %s %d\n", src, len)); */ PA_UNLESS( *dst = (char *)PaUtil_GroupAllocateMemory( alsaApi->allocations, len ), paInsufficientMemory ); strncpy( *dst, src, len ); error: return result; } /* Disregard some standard plugins */ static int IgnorePlugin( const char *pluginId ) { static const char *ignoredPlugins[] = {"hw", "plughw", "plug", "dsnoop", "tee", "file", "null", "shm", "cards", "rate_convert", NULL}; int i = 0; while( ignoredPlugins[i] ) { if( !strcmp( pluginId, ignoredPlugins[i] ) ) { return 1; } ++i; } return 0; } /** Open PCM device. * * Wrapper around alsa_snd_pcm_open which may repeatedly retry opening a device if it is busy, for * a certain time. This is because dmix may temporarily hold on to a device after it (dmix) * has been opened and closed. * @param mode: Open mode (e.g., SND_PCM_BLOCKING). * @param waitOnBusy: Retry opening busy device for up to one second? **/ static int OpenPcm( snd_pcm_t **pcmp, const char *name, snd_pcm_stream_t stream, int mode, int waitOnBusy ) { int tries = 0, maxTries = waitOnBusy ? busyRetries_ : 0; int ret = alsa_snd_pcm_open( pcmp, name, stream, mode ); for( tries = 0; tries < maxTries && -EBUSY == ret; ++tries ) { Pa_Sleep( 10 ); ret = alsa_snd_pcm_open( pcmp, name, stream, mode ); if( -EBUSY != ret ) { PA_DEBUG(( "%s: Successfully opened initially busy device after %d tries\n", __FUNCTION__, tries )); } } if( -EBUSY == ret ) { PA_DEBUG(( "%s: Failed to open busy device '%s'\n", __FUNCTION__, name )); } else { if( ret < 0 ) PA_DEBUG(( "%s: Opened device '%s' ptr[%p] - result: [%d:%s]\n", __FUNCTION__, name, *pcmp, ret, alsa_snd_strerror(ret) )); } return ret; } static PaError FillInDevInfo( PaAlsaHostApiRepresentation *alsaApi, HwDevInfo* deviceName, int blocking, PaAlsaDeviceInfo* devInfo, int* devIdx ) { PaError result = 0; PaDeviceInfo *baseDeviceInfo = &devInfo->baseDeviceInfo; snd_pcm_t *pcm = NULL; PaUtilHostApiRepresentation *baseApi = &alsaApi->baseHostApiRep; PA_DEBUG(( "%s: Filling device info for: %s\n", __FUNCTION__, deviceName->name )); /* Zero fields */ InitializeDeviceInfo( baseDeviceInfo ); /* to determine device capabilities, we must open the device and query the * hardware parameter configuration space */ /* Query capture */ if( deviceName->hasCapture && OpenPcm( &pcm, deviceName->alsaName, SND_PCM_STREAM_CAPTURE, blocking, 0 ) >= 0 ) { if( GropeDevice( pcm, deviceName->isPlug, StreamDirection_In, blocking, devInfo ) != paNoError ) { /* Error */ PA_DEBUG(( "%s: Failed groping %s for capture\n", __FUNCTION__, deviceName->alsaName )); goto end; } } /* Query playback */ if( deviceName->hasPlayback && OpenPcm( &pcm, deviceName->alsaName, SND_PCM_STREAM_PLAYBACK, blocking, 0 ) >= 0 ) { if( GropeDevice( pcm, deviceName->isPlug, StreamDirection_Out, blocking, devInfo ) != paNoError ) { /* Error */ PA_DEBUG(( "%s: Failed groping %s for playback\n", __FUNCTION__, deviceName->alsaName )); goto end; } } baseDeviceInfo->structVersion = 2; baseDeviceInfo->hostApi = alsaApi->hostApiIndex; baseDeviceInfo->name = deviceName->name; devInfo->alsaName = deviceName->alsaName; devInfo->isPlug = deviceName->isPlug; /* A: Storing pointer to PaAlsaDeviceInfo object as pointer to PaDeviceInfo object. * Should now be safe to add device info, unless the device supports neither capture nor playback */ if( baseDeviceInfo->maxInputChannels > 0 || baseDeviceInfo->maxOutputChannels > 0 ) { /* Make device default if there isn't already one or it is the ALSA "default" device */ if( ( baseApi->info.defaultInputDevice == paNoDevice || !strcmp( deviceName->alsaName, "default" ) ) && baseDeviceInfo->maxInputChannels > 0 ) { baseApi->info.defaultInputDevice = *devIdx; PA_DEBUG(( "Default input device: %s\n", deviceName->name )); } if( ( baseApi->info.defaultOutputDevice == paNoDevice || !strcmp( deviceName->alsaName, "default" ) ) && baseDeviceInfo->maxOutputChannels > 0 ) { baseApi->info.defaultOutputDevice = *devIdx; PA_DEBUG(( "Default output device: %s\n", deviceName->name )); } PA_DEBUG(( "%s: Adding device %s: %d\n", __FUNCTION__, deviceName->name, *devIdx )); baseApi->deviceInfos[*devIdx] = (PaDeviceInfo *) devInfo; (*devIdx) += 1; } else { PA_DEBUG(( "%s: Skipped device: %s, all channels == 0\n", __FUNCTION__, deviceName->name )); } end: return result; } /* Build PaDeviceInfo list, ignore devices for which we cannot determine capabilities (possibly busy, sigh) */ static PaError BuildDeviceList( PaAlsaHostApiRepresentation *alsaApi ) { PaUtilHostApiRepresentation *baseApi = &alsaApi->baseHostApiRep; PaAlsaDeviceInfo *deviceInfoArray; int cardIdx = -1, devIdx = 0; snd_ctl_card_info_t *cardInfo; PaError result = paNoError; size_t numDeviceNames = 0, maxDeviceNames = 1, i; HwDevInfo *hwDevInfos = NULL; snd_config_t *topNode = NULL; snd_pcm_info_t *pcmInfo; int res; int blocking = SND_PCM_NONBLOCK; char alsaCardName[50]; #ifdef PA_ENABLE_DEBUG_OUTPUT PaTime startTime = PaUtil_GetTime(); #endif if( getenv( "PA_ALSA_INITIALIZE_BLOCK" ) && atoi( getenv( "PA_ALSA_INITIALIZE_BLOCK" ) ) ) blocking = 0; /* These two will be set to the first working input and output device, respectively */ baseApi->info.defaultInputDevice = paNoDevice; baseApi->info.defaultOutputDevice = paNoDevice; /* Gather info about hw devices * alsa_snd_card_next() modifies the integer passed to it to be: * the index of the first card if the parameter is -1 * the index of the next card if the parameter is the index of a card * -1 if there are no more cards * * The function itself returns 0 if it succeeded. */ cardIdx = -1; alsa_snd_ctl_card_info_alloca( &cardInfo ); alsa_snd_pcm_info_alloca( &pcmInfo ); while( alsa_snd_card_next( &cardIdx ) == 0 && cardIdx >= 0 ) { char *cardName; int devIdx = -1; snd_ctl_t *ctl; char buf[50]; snprintf( alsaCardName, sizeof (alsaCardName), "hw:%d", cardIdx ); /* Acquire name of card */ if( alsa_snd_ctl_open( &ctl, alsaCardName, 0 ) < 0 ) { /* Unable to open card :( */ PA_DEBUG(( "%s: Unable to open device %s\n", __FUNCTION__, alsaCardName )); continue; } alsa_snd_ctl_card_info( ctl, cardInfo ); PA_ENSURE( PaAlsa_StrDup( alsaApi, &cardName, alsa_snd_ctl_card_info_get_name( cardInfo )) ); while( alsa_snd_ctl_pcm_next_device( ctl, &devIdx ) == 0 && devIdx >= 0 ) { char *alsaDeviceName, *deviceName; size_t len; int hasPlayback = 0, hasCapture = 0; snprintf( buf, sizeof (buf), "hw:%d,%d", cardIdx, devIdx ); /* Obtain info about this particular device */ alsa_snd_pcm_info_set_device( pcmInfo, devIdx ); alsa_snd_pcm_info_set_subdevice( pcmInfo, 0 ); alsa_snd_pcm_info_set_stream( pcmInfo, SND_PCM_STREAM_CAPTURE ); if( alsa_snd_ctl_pcm_info( ctl, pcmInfo ) >= 0 ) { hasCapture = 1; } alsa_snd_pcm_info_set_stream( pcmInfo, SND_PCM_STREAM_PLAYBACK ); if( alsa_snd_ctl_pcm_info( ctl, pcmInfo ) >= 0 ) { hasPlayback = 1; } if( !hasPlayback && !hasCapture ) { /* Error */ continue; } /* The length of the string written by snprintf plus terminating 0 */ len = snprintf( NULL, 0, "%s: %s (%s)", cardName, alsa_snd_pcm_info_get_name( pcmInfo ), buf ) + 1; PA_UNLESS( deviceName = (char *)PaUtil_GroupAllocateMemory( alsaApi->allocations, len ), paInsufficientMemory ); snprintf( deviceName, len, "%s: %s (%s)", cardName, alsa_snd_pcm_info_get_name( pcmInfo ), buf ); ++numDeviceNames; if( !hwDevInfos || numDeviceNames > maxDeviceNames ) { maxDeviceNames *= 2; PA_UNLESS( hwDevInfos = (HwDevInfo *) realloc( hwDevInfos, maxDeviceNames * sizeof (HwDevInfo) ), paInsufficientMemory ); } PA_ENSURE( PaAlsa_StrDup( alsaApi, &alsaDeviceName, buf ) ); hwDevInfos[ numDeviceNames - 1 ].alsaName = alsaDeviceName; hwDevInfos[ numDeviceNames - 1 ].name = deviceName; hwDevInfos[ numDeviceNames - 1 ].isPlug = 0; hwDevInfos[ numDeviceNames - 1 ].hasPlayback = hasPlayback; hwDevInfos[ numDeviceNames - 1 ].hasCapture = hasCapture; } alsa_snd_ctl_close( ctl ); } /* Iterate over plugin devices */ if( NULL == (*alsa_snd_config) ) { /* alsa_snd_config_update is called implicitly by some functions, if this hasn't happened snd_config will be NULL (bleh) */ ENSURE_( alsa_snd_config_update(), paUnanticipatedHostError ); PA_DEBUG(( "Updating snd_config\n" )); } assert( *alsa_snd_config ); if( ( res = alsa_snd_config_search( *alsa_snd_config, "pcm", &topNode ) ) >= 0 ) { snd_config_iterator_t i, next; alsa_snd_config_for_each( i, next, topNode ) { const char *tpStr = "unknown", *idStr = NULL; int err = 0; char *alsaDeviceName, *deviceName; const HwDevInfo *predefined = NULL; snd_config_t *n = alsa_snd_config_iterator_entry( i ), * tp = NULL;; if( (err = alsa_snd_config_search( n, "type", &tp )) < 0 ) { if( -ENOENT != err ) { ENSURE_(err, paUnanticipatedHostError); } } else { ENSURE_( alsa_snd_config_get_string( tp, &tpStr ), paUnanticipatedHostError ); } ENSURE_( alsa_snd_config_get_id( n, &idStr ), paUnanticipatedHostError ); if( IgnorePlugin( idStr ) ) { PA_DEBUG(( "%s: Ignoring ALSA plugin device [%s] of type [%s]\n", __FUNCTION__, idStr, tpStr )); continue; } PA_DEBUG(( "%s: Found plugin [%s] of type [%s]\n", __FUNCTION__, idStr, tpStr )); PA_UNLESS( alsaDeviceName = (char*)PaUtil_GroupAllocateMemory( alsaApi->allocations, strlen(idStr) + 6 ), paInsufficientMemory ); strcpy( alsaDeviceName, idStr ); PA_UNLESS( deviceName = (char*)PaUtil_GroupAllocateMemory( alsaApi->allocations, strlen(idStr) + 1 ), paInsufficientMemory ); strcpy( deviceName, idStr ); ++numDeviceNames; if( !hwDevInfos || numDeviceNames > maxDeviceNames ) { maxDeviceNames *= 2; PA_UNLESS( hwDevInfos = (HwDevInfo *) realloc( hwDevInfos, maxDeviceNames * sizeof (HwDevInfo) ), paInsufficientMemory ); } predefined = FindDeviceName( alsaDeviceName ); hwDevInfos[numDeviceNames - 1].alsaName = alsaDeviceName; hwDevInfos[numDeviceNames - 1].name = deviceName; hwDevInfos[numDeviceNames - 1].isPlug = 1; if( predefined ) { hwDevInfos[numDeviceNames - 1].hasPlayback = predefined->hasPlayback; hwDevInfos[numDeviceNames - 1].hasCapture = predefined->hasCapture; } else { hwDevInfos[numDeviceNames - 1].hasPlayback = 1; hwDevInfos[numDeviceNames - 1].hasCapture = 1; } } } else PA_DEBUG(( "%s: Iterating over ALSA plugins failed: %s\n", __FUNCTION__, alsa_snd_strerror( res ) )); /* allocate deviceInfo memory based on the number of devices */ PA_UNLESS( baseApi->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( alsaApi->allocations, sizeof(PaDeviceInfo*) * (numDeviceNames) ), paInsufficientMemory ); /* allocate all device info structs in a contiguous block */ PA_UNLESS( deviceInfoArray = (PaAlsaDeviceInfo*)PaUtil_GroupAllocateMemory( alsaApi->allocations, sizeof(PaAlsaDeviceInfo) * numDeviceNames ), paInsufficientMemory ); /* Loop over list of cards, filling in info. If a device is deemed unavailable (can't get name), * it's ignored. * * Note that we do this in two stages. This is a workaround owing to the fact that the 'dmix' * plugin may cause the underlying hardware device to be busy for a short while even after it * (dmix) is closed. The 'default' plugin may also point to the dmix plugin, so the same goes * for this. */ PA_DEBUG(( "%s: Filling device info for %d devices\n", __FUNCTION__, numDeviceNames )); for( i = 0, devIdx = 0; i < numDeviceNames; ++i ) { PaAlsaDeviceInfo* devInfo = &deviceInfoArray[i]; HwDevInfo* hwInfo = &hwDevInfos[i]; if( !strcmp( hwInfo->name, "dmix" ) || !strcmp( hwInfo->name, "default" ) ) { continue; } PA_ENSURE( FillInDevInfo( alsaApi, hwInfo, blocking, devInfo, &devIdx ) ); } assert( devIdx < numDeviceNames ); /* Now inspect 'dmix' and 'default' plugins */ for( i = 0; i < numDeviceNames; ++i ) { PaAlsaDeviceInfo* devInfo = &deviceInfoArray[i]; HwDevInfo* hwInfo = &hwDevInfos[i]; if( strcmp( hwInfo->name, "dmix" ) && strcmp( hwInfo->name, "default" ) ) { continue; } PA_ENSURE( FillInDevInfo( alsaApi, hwInfo, blocking, devInfo, &devIdx ) ); } free( hwDevInfos ); baseApi->info.deviceCount = devIdx; /* Number of successfully queried devices */ #ifdef PA_ENABLE_DEBUG_OUTPUT PA_DEBUG(( "%s: Building device list took %f seconds\n", __FUNCTION__, PaUtil_GetTime() - startTime )); #endif end: return result; error: /* No particular action */ goto end; } /* Check against known device capabilities */ static PaError ValidateParameters( const PaStreamParameters *parameters, PaUtilHostApiRepresentation *hostApi, StreamDirection mode ) { PaError result = paNoError; int maxChans; const PaAlsaDeviceInfo *deviceInfo = NULL; assert( parameters ); if( parameters->device != paUseHostApiSpecificDeviceSpecification ) { assert( parameters->device < hostApi->info.deviceCount ); PA_UNLESS( parameters->hostApiSpecificStreamInfo == NULL, paBadIODeviceCombination ); deviceInfo = GetDeviceInfo( hostApi, parameters->device ); } else { const PaAlsaStreamInfo *streamInfo = parameters->hostApiSpecificStreamInfo; PA_UNLESS( parameters->device == paUseHostApiSpecificDeviceSpecification, paInvalidDevice ); PA_UNLESS( streamInfo->size == sizeof (PaAlsaStreamInfo) && streamInfo->version == 1, paIncompatibleHostApiSpecificStreamInfo ); PA_UNLESS( streamInfo->deviceString != NULL, paInvalidDevice ); /* Skip further checking */ return paNoError; } assert( deviceInfo ); assert( parameters->hostApiSpecificStreamInfo == NULL ); maxChans = ( StreamDirection_In == mode ? deviceInfo->baseDeviceInfo.maxInputChannels : deviceInfo->baseDeviceInfo.maxOutputChannels ); PA_UNLESS( parameters->channelCount <= maxChans, paInvalidChannelCount ); error: return result; } /* Given an open stream, what sample formats are available? */ static PaSampleFormat GetAvailableFormats( snd_pcm_t *pcm ) { PaSampleFormat available = 0; snd_pcm_hw_params_t *hwParams; alsa_snd_pcm_hw_params_alloca( &hwParams ); alsa_snd_pcm_hw_params_any( pcm, hwParams ); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_FLOAT ) >= 0) available |= paFloat32; if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S32 ) >= 0) available |= paInt32; #ifdef PA_LITTLE_ENDIAN if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_3LE ) >= 0) available |= paInt24; #elif defined PA_BIG_ENDIAN if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_3BE ) >= 0) available |= paInt24; #endif if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S16 ) >= 0) available |= paInt16; if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U8 ) >= 0) available |= paUInt8; if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S8 ) >= 0) available |= paInt8; return available; } /* Output to console all formats supported by device */ static void LogAllAvailableFormats( snd_pcm_t *pcm ) { PaSampleFormat available = 0; snd_pcm_hw_params_t *hwParams; alsa_snd_pcm_hw_params_alloca( &hwParams ); alsa_snd_pcm_hw_params_any( pcm, hwParams ); PA_DEBUG(( " --- Supported Formats ---\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S8 ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_S8\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U8 ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_U8\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S16_LE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_S16_LE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S16_BE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_S16_BE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U16_LE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_U16_LE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U16_BE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_U16_BE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_LE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_S24_LE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_BE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_S24_BE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U24_LE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_U24_LE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U24_BE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_U24_BE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_FLOAT_LE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_FLOAT_LE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_FLOAT_BE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_FLOAT_BE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_FLOAT64_LE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_FLOAT64_LE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_FLOAT64_BE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_FLOAT64_BE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_IEC958_SUBFRAME_LE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_IEC958_SUBFRAME_LE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_IEC958_SUBFRAME_BE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_IEC958_SUBFRAME_BE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_MU_LAW ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_MU_LAW\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_A_LAW ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_A_LAW\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_IMA_ADPCM ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_IMA_ADPCM\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_MPEG ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_MPEG\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_GSM ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_GSM\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_SPECIAL ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_SPECIAL\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_3LE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_S24_3LE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24_3BE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_S24_3BE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U24_3LE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_U24_3LE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U24_3BE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_U24_3BE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S20_3LE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_S20_3LE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S20_3BE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_S20_3BE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U20_3LE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_U20_3LE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U20_3BE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_U20_3BE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S18_3LE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_S18_3LE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S18_3BE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_S18_3BE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U18_3LE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_U18_3LE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U18_3BE ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_U18_3BE\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S16 ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_S16\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U16 ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_U16\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24 ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_S24\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U24 ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_U24\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S32 ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_S32\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U32 ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_U32\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_FLOAT ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_FLOAT\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_FLOAT64 ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_FLOAT64\n" )); if( alsa_snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_IEC958_SUBFRAME ) >= 0) PA_DEBUG(( "SND_PCM_FORMAT_IEC958_SUBFRAME\n" )); PA_DEBUG(( " -------------------------\n" )); } static snd_pcm_format_t Pa2AlsaFormat( PaSampleFormat paFormat ) { switch( paFormat ) { case paFloat32: return SND_PCM_FORMAT_FLOAT; case paInt16: return SND_PCM_FORMAT_S16; case paInt24: #ifdef PA_LITTLE_ENDIAN return SND_PCM_FORMAT_S24_3LE; #elif defined PA_BIG_ENDIAN return SND_PCM_FORMAT_S24_3BE; #endif case paInt32: return SND_PCM_FORMAT_S32; case paInt8: return SND_PCM_FORMAT_S8; case paUInt8: return SND_PCM_FORMAT_U8; default: return SND_PCM_FORMAT_UNKNOWN; } } /** Open an ALSA pcm handle. * * The device to be open can be specified in a custom PaAlsaStreamInfo struct, or it will be a device number. In case of a * device number, it maybe specified through an env variable (PA_ALSA_PLUGHW) that we should open the corresponding plugin * device. */ static PaError AlsaOpen( const PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *params, StreamDirection streamDir, snd_pcm_t **pcm ) { PaError result = paNoError; int ret; char dnameArray[50]; const char* deviceName = dnameArray; const PaAlsaDeviceInfo *deviceInfo = NULL; PaAlsaStreamInfo *streamInfo = (PaAlsaStreamInfo *)params->hostApiSpecificStreamInfo; if( !streamInfo ) { int usePlug = 0; deviceInfo = GetDeviceInfo( hostApi, params->device ); /* If device name starts with hw: and PA_ALSA_PLUGHW is 1, we open the plughw device instead */ if( !strncmp( "hw:", deviceInfo->alsaName, 3 ) && getenv( "PA_ALSA_PLUGHW" ) ) usePlug = atoi( getenv( "PA_ALSA_PLUGHW" ) ); if( usePlug ) snprintf( dnameArray, 50, "plug%s", deviceInfo->alsaName ); else deviceName = deviceInfo->alsaName; } else deviceName = streamInfo->deviceString; PA_DEBUG(( "%s: Opening device %s\n", __FUNCTION__, deviceName )); if( (ret = OpenPcm( pcm, deviceName, streamDir == StreamDirection_In ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK, 1 )) < 0 ) { /* Not to be closed */ *pcm = NULL; ENSURE_( ret, -EBUSY == ret ? paDeviceUnavailable : paBadIODeviceCombination ); } ENSURE_( alsa_snd_pcm_nonblock( *pcm, 0 ), paUnanticipatedHostError ); end: return result; error: goto end; } static PaError TestParameters( const PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *parameters, double sampleRate, StreamDirection streamDir ) { PaError result = paNoError; snd_pcm_t *pcm = NULL; PaSampleFormat availableFormats; /* We are able to adapt to a number of channels less than what the device supports */ unsigned int numHostChannels; PaSampleFormat hostFormat; snd_pcm_hw_params_t *hwParams; alsa_snd_pcm_hw_params_alloca( &hwParams ); if( !parameters->hostApiSpecificStreamInfo ) { const PaAlsaDeviceInfo *devInfo = GetDeviceInfo( hostApi, parameters->device ); numHostChannels = PA_MAX( parameters->channelCount, StreamDirection_In == streamDir ? devInfo->minInputChannels : devInfo->minOutputChannels ); } else numHostChannels = parameters->channelCount; PA_ENSURE( AlsaOpen( hostApi, parameters, streamDir, &pcm ) ); alsa_snd_pcm_hw_params_any( pcm, hwParams ); if( SetApproximateSampleRate( pcm, hwParams, sampleRate ) < 0 ) { result = paInvalidSampleRate; goto error; } if( alsa_snd_pcm_hw_params_set_channels( pcm, hwParams, numHostChannels ) < 0 ) { result = paInvalidChannelCount; goto error; } /* See if we can find a best possible match */ availableFormats = GetAvailableFormats( pcm ); PA_ENSURE( hostFormat = PaUtil_SelectClosestAvailableFormat( availableFormats, parameters->sampleFormat ) ); /* Some specific hardware (reported: Audio8 DJ) can fail with assertion during this step. */ ENSURE_( alsa_snd_pcm_hw_params_set_format( pcm, hwParams, Pa2AlsaFormat( hostFormat ) ), paUnanticipatedHostError ); { /* It happens that this call fails because the device is busy */ int ret = 0; if( ( ret = alsa_snd_pcm_hw_params( pcm, hwParams ) ) < 0 ) { if( -EINVAL == ret ) { /* Don't know what to return here */ result = paBadIODeviceCombination; goto error; } else if( -EBUSY == ret ) { result = paDeviceUnavailable; PA_DEBUG(( "%s: Device is busy\n", __FUNCTION__ )); } else { result = paUnanticipatedHostError; } ENSURE_( ret, result ); } } end: if( pcm ) { alsa_snd_pcm_close( pcm ); } return result; error: goto end; } static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ) { int inputChannelCount = 0, outputChannelCount = 0; PaSampleFormat inputSampleFormat, outputSampleFormat; PaError result = paFormatIsSupported; if( inputParameters ) { PA_ENSURE( ValidateParameters( inputParameters, hostApi, StreamDirection_In ) ); inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; } if( outputParameters ) { PA_ENSURE( ValidateParameters( outputParameters, hostApi, StreamDirection_Out ) ); outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; } if( inputChannelCount ) { if( ( result = TestParameters( hostApi, inputParameters, sampleRate, StreamDirection_In ) ) != paNoError ) goto error; } if ( outputChannelCount ) { if( ( result = TestParameters( hostApi, outputParameters, sampleRate, StreamDirection_Out ) ) != paNoError ) goto error; } return paFormatIsSupported; error: return result; } static PaError PaAlsaStreamComponent_Initialize( PaAlsaStreamComponent *self, PaAlsaHostApiRepresentation *alsaApi, const PaStreamParameters *params, StreamDirection streamDir, int callbackMode ) { PaError result = paNoError; PaSampleFormat userSampleFormat = params->sampleFormat, hostSampleFormat = paNoError; assert( params->channelCount > 0 ); /* Make sure things have an initial value */ memset( self, 0, sizeof (PaAlsaStreamComponent) ); if( NULL == params->hostApiSpecificStreamInfo ) { const PaAlsaDeviceInfo *devInfo = GetDeviceInfo( &alsaApi->baseHostApiRep, params->device ); self->numHostChannels = PA_MAX( params->channelCount, StreamDirection_In == streamDir ? devInfo->minInputChannels : devInfo->minOutputChannels ); self->deviceIsPlug = devInfo->isPlug; } else { /* We're blissfully unaware of the minimum channelCount */ self->numHostChannels = params->channelCount; /* Check if device name does not start with hw: to determine if it is a 'plug' device */ if( strncmp( "hw:", ((PaAlsaStreamInfo *)params->hostApiSpecificStreamInfo)->deviceString, 3 ) != 0 ) self->deviceIsPlug = 1; /* An Alsa plug device, not a direct hw device */ } if( self->deviceIsPlug && alsaApi->alsaLibVersion < ALSA_VERSION_INT( 1, 0, 16 ) ) self->useReventFix = 1; /* Prior to Alsa1.0.16, plug devices may stutter without this fix */ self->device = params->device; PA_ENSURE( AlsaOpen( &alsaApi->baseHostApiRep, params, streamDir, &self->pcm ) ); self->nfds = alsa_snd_pcm_poll_descriptors_count( self->pcm ); PA_ENSURE( hostSampleFormat = PaUtil_SelectClosestAvailableFormat( GetAvailableFormats( self->pcm ), userSampleFormat ) ); self->hostSampleFormat = hostSampleFormat; self->nativeFormat = Pa2AlsaFormat( hostSampleFormat ); self->hostInterleaved = self->userInterleaved = !( userSampleFormat & paNonInterleaved ); self->numUserChannels = params->channelCount; self->streamDir = streamDir; self->canMmap = 0; self->nonMmapBuffer = NULL; self->nonMmapBufferSize = 0; if( !callbackMode && !self->userInterleaved ) { /* Pre-allocate non-interleaved user provided buffers */ PA_UNLESS( self->userBuffers = PaUtil_AllocateMemory( sizeof (void *) * self->numUserChannels ), paInsufficientMemory ); } error: /* Log all available formats. */ if ( hostSampleFormat == paSampleFormatNotSupported ) { LogAllAvailableFormats( self->pcm ); PA_DEBUG(( "%s: Please provide the log output to PortAudio developers, your hardware does not have any sample format implemented yet.\n", __FUNCTION__ )); } return result; } static void PaAlsaStreamComponent_Terminate( PaAlsaStreamComponent *self ) { alsa_snd_pcm_close( self->pcm ); if( self->userBuffers ) PaUtil_FreeMemory( self->userBuffers ); } /* static int nearbyint_(float value) { if( value - (int)value > .5 ) return (int)ceil( value ); return (int)floor( value ); } */ /** Initiate configuration, preparing for determining a period size suitable for both capture and playback components. * */ static PaError PaAlsaStreamComponent_InitialConfigure( PaAlsaStreamComponent *self, const PaStreamParameters *params, int primeBuffers, snd_pcm_hw_params_t *hwParams, double *sampleRate ) { /* Configuration consists of setting all of ALSA's parameters. * These parameters come in two flavors: hardware parameters * and software paramters. Hardware parameters will affect * the way the device is initialized, software parameters * affect the way ALSA interacts with me, the user-level client. */ PaError result = paNoError; snd_pcm_access_t accessMode, alternateAccessMode; int dir = 0; snd_pcm_t *pcm = self->pcm; double sr = *sampleRate; unsigned int minPeriods = 2; /* self->framesPerBuffer = framesPerHostBuffer; */ /* ... fill up the configuration space with all possibile * combinations of parameters this device will accept */ ENSURE_( alsa_snd_pcm_hw_params_any( pcm, hwParams ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_hw_params_set_periods_integer( pcm, hwParams ), paUnanticipatedHostError ); /* I think there should be at least 2 periods (even though ALSA doesn't appear to enforce this) */ dir = 0; ENSURE_( alsa_snd_pcm_hw_params_set_periods_min( pcm, hwParams, &minPeriods, &dir ), paUnanticipatedHostError ); if( self->userInterleaved ) { accessMode = SND_PCM_ACCESS_MMAP_INTERLEAVED; alternateAccessMode = SND_PCM_ACCESS_MMAP_NONINTERLEAVED; /* test if MMAP supported */ self->canMmap = alsa_snd_pcm_hw_params_test_access( pcm, hwParams, accessMode ) >= 0 || alsa_snd_pcm_hw_params_test_access( pcm, hwParams, alternateAccessMode ) >= 0; PA_DEBUG(( "%s: device MMAP SND_PCM_ACCESS_MMAP_INTERLEAVED: %s\n", __FUNCTION__, ( alsa_snd_pcm_hw_params_test_access( pcm, hwParams, accessMode ) >= 0 ? "YES" : "NO" ) )); PA_DEBUG(( "%s: device MMAP SND_PCM_ACCESS_MMAP_NONINTERLEAVED: %s\n", __FUNCTION__, ( alsa_snd_pcm_hw_params_test_access( pcm, hwParams, alternateAccessMode ) >= 0 ? "YES" : "NO" ) )); if( !self->canMmap ) { accessMode = SND_PCM_ACCESS_RW_INTERLEAVED; alternateAccessMode = SND_PCM_ACCESS_RW_NONINTERLEAVED; } } else { accessMode = SND_PCM_ACCESS_MMAP_NONINTERLEAVED; alternateAccessMode = SND_PCM_ACCESS_MMAP_INTERLEAVED; /* test if MMAP supported */ self->canMmap = alsa_snd_pcm_hw_params_test_access( pcm, hwParams, accessMode ) >= 0 || alsa_snd_pcm_hw_params_test_access( pcm, hwParams, alternateAccessMode ) >= 0; PA_DEBUG((" %s: device MMAP SND_PCM_ACCESS_MMAP_NONINTERLEAVED: %s\n", __FUNCTION__, ( alsa_snd_pcm_hw_params_test_access( pcm, hwParams, accessMode ) >= 0 ? "YES" : "NO" ) )); PA_DEBUG(( "%s: device MMAP SND_PCM_ACCESS_MMAP_INTERLEAVED: %s\n", __FUNCTION__, ( alsa_snd_pcm_hw_params_test_access( pcm, hwParams, alternateAccessMode ) >= 0 ? "YES" : "NO" ) )); if( !self->canMmap ) { accessMode = SND_PCM_ACCESS_RW_NONINTERLEAVED; alternateAccessMode = SND_PCM_ACCESS_RW_INTERLEAVED; } } PA_DEBUG(( "%s: device can MMAP: %s\n", __FUNCTION__, ( self->canMmap ? "YES" : "NO" ) )); /* If requested access mode fails, try alternate mode */ if( alsa_snd_pcm_hw_params_set_access( pcm, hwParams, accessMode ) < 0 ) { int err = 0; if( ( err = alsa_snd_pcm_hw_params_set_access( pcm, hwParams, alternateAccessMode )) < 0 ) { result = paUnanticipatedHostError; PaUtil_SetLastHostErrorInfo( paALSA, err, alsa_snd_strerror( err ) ); goto error; } /* Flip mode */ self->hostInterleaved = !self->userInterleaved; } /* Some specific hardware (reported: Audio8 DJ) can fail with assertion during this step. */ ENSURE_( alsa_snd_pcm_hw_params_set_format( pcm, hwParams, self->nativeFormat ), paUnanticipatedHostError ); if( ( result = SetApproximateSampleRate( pcm, hwParams, sr )) != paUnanticipatedHostError ) { ENSURE_( GetExactSampleRate( hwParams, &sr ), paUnanticipatedHostError ); if( result == paInvalidSampleRate ) /* From the SetApproximateSampleRate() call above */ { /* The sample rate was returned as 'out of tolerance' of the one requested */ PA_DEBUG(( "%s: Wanted %.3f, closest sample rate was %.3f\n", __FUNCTION__, sampleRate, sr )); PA_ENSURE( paInvalidSampleRate ); } } else { PA_ENSURE( paUnanticipatedHostError ); } ENSURE_( alsa_snd_pcm_hw_params_set_channels( pcm, hwParams, self->numHostChannels ), paInvalidChannelCount ); *sampleRate = sr; end: return result; error: /* No particular action */ goto end; } /** Finish the configuration of the component's ALSA device. * * As part of this method, the component's bufferSize attribute will be set. * @param latency: The latency for this component. */ static PaError PaAlsaStreamComponent_FinishConfigure( PaAlsaStreamComponent *self, snd_pcm_hw_params_t* hwParams, const PaStreamParameters *params, int primeBuffers, double sampleRate, PaTime* latency ) { PaError result = paNoError; snd_pcm_sw_params_t* swParams; snd_pcm_uframes_t bufSz = 0; *latency = -1.; alsa_snd_pcm_sw_params_alloca( &swParams ); bufSz = params->suggestedLatency * sampleRate + self->framesPerBuffer; ENSURE_( alsa_snd_pcm_hw_params_set_buffer_size_near( self->pcm, hwParams, &bufSz ), paUnanticipatedHostError ); /* Set the parameters! */ { int r = alsa_snd_pcm_hw_params( self->pcm, hwParams ); #ifdef PA_ENABLE_DEBUG_OUTPUT if( r < 0 ) { snd_output_t *output = NULL; alsa_snd_output_stdio_attach( &output, stderr, 0 ); alsa_snd_pcm_hw_params_dump( hwParams, output ); } #endif ENSURE_( r, paUnanticipatedHostError ); } if( alsa_snd_pcm_hw_params_get_buffer_size != NULL ) { ENSURE_( alsa_snd_pcm_hw_params_get_buffer_size( hwParams, &self->bufferSize ), paUnanticipatedHostError ); } else { self->bufferSize = bufSz; } /* Latency in seconds */ *latency = (self->bufferSize - self->framesPerBuffer) / sampleRate; /* Now software parameters... */ ENSURE_( alsa_snd_pcm_sw_params_current( self->pcm, swParams ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_sw_params_set_start_threshold( self->pcm, swParams, self->framesPerBuffer ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_sw_params_set_stop_threshold( self->pcm, swParams, self->bufferSize ), paUnanticipatedHostError ); /* Silence buffer in the case of underrun */ if( !primeBuffers ) /* XXX: Make sense? */ { snd_pcm_uframes_t boundary; ENSURE_( alsa_snd_pcm_sw_params_get_boundary( swParams, &boundary ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_sw_params_set_silence_threshold( self->pcm, swParams, 0 ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_sw_params_set_silence_size( self->pcm, swParams, boundary ), paUnanticipatedHostError ); } ENSURE_( alsa_snd_pcm_sw_params_set_avail_min( self->pcm, swParams, self->framesPerBuffer ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_sw_params_set_xfer_align( self->pcm, swParams, 1 ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_sw_params_set_tstamp_mode( self->pcm, swParams, SND_PCM_TSTAMP_ENABLE ), paUnanticipatedHostError ); /* Set the parameters! */ ENSURE_( alsa_snd_pcm_sw_params( self->pcm, swParams ), paUnanticipatedHostError ); error: return result; } static PaError PaAlsaStream_Initialize( PaAlsaStream *self, PaAlsaHostApiRepresentation *alsaApi, const PaStreamParameters *inParams, const PaStreamParameters *outParams, double sampleRate, unsigned long framesPerUserBuffer, PaStreamCallback callback, PaStreamFlags streamFlags, void *userData ) { PaError result = paNoError; assert( self ); memset( self, 0, sizeof( PaAlsaStream ) ); if( NULL != callback ) { PaUtil_InitializeStreamRepresentation( &self->streamRepresentation, &alsaApi->callbackStreamInterface, callback, userData ); self->callbackMode = 1; } else { PaUtil_InitializeStreamRepresentation( &self->streamRepresentation, &alsaApi->blockingStreamInterface, NULL, userData ); } self->framesPerUserBuffer = framesPerUserBuffer; self->neverDropInput = streamFlags & paNeverDropInput; /* XXX: Ignore paPrimeOutputBuffersUsingStreamCallback untill buffer priming is fully supported in pa_process.c */ /* if( outParams & streamFlags & paPrimeOutputBuffersUsingStreamCallback ) self->primeBuffers = 1; */ memset( &self->capture, 0, sizeof (PaAlsaStreamComponent) ); memset( &self->playback, 0, sizeof (PaAlsaStreamComponent) ); if( inParams ) { PA_ENSURE( PaAlsaStreamComponent_Initialize( &self->capture, alsaApi, inParams, StreamDirection_In, NULL != callback ) ); } if( outParams ) { PA_ENSURE( PaAlsaStreamComponent_Initialize( &self->playback, alsaApi, outParams, StreamDirection_Out, NULL != callback ) ); } assert( self->capture.nfds || self->playback.nfds ); PA_UNLESS( self->pfds = (struct pollfd*)PaUtil_AllocateMemory( ( self->capture.nfds + self->playback.nfds ) * sizeof( struct pollfd ) ), paInsufficientMemory ); PaUtil_InitializeCpuLoadMeasurer( &self->cpuLoadMeasurer, sampleRate ); ASSERT_CALL_( PaUnixMutex_Initialize( &self->stateMtx ), paNoError ); error: return result; } /** Free resources associated with stream, and eventually stream itself. * * Frees allocated memory, and terminates individual StreamComponents. */ static void PaAlsaStream_Terminate( PaAlsaStream *self ) { assert( self ); if( self->capture.pcm ) { PaAlsaStreamComponent_Terminate( &self->capture ); } if( self->playback.pcm ) { PaAlsaStreamComponent_Terminate( &self->playback ); } PaUtil_FreeMemory( self->pfds ); ASSERT_CALL_( PaUnixMutex_Terminate( &self->stateMtx ), paNoError ); PaUtil_FreeMemory( self ); } /** Calculate polling timeout * * @param frames Time to wait * @return Polling timeout in milliseconds */ static int CalculatePollTimeout( const PaAlsaStream *stream, unsigned long frames ) { assert( stream->streamRepresentation.streamInfo.sampleRate > 0.0 ); /* Period in msecs, rounded up */ return (int)ceil( 1000 * frames / stream->streamRepresentation.streamInfo.sampleRate ); } /** Align value in backward direction. * * @param v: Value to align. * @param align: Alignment. */ static unsigned long PaAlsa_AlignBackward(unsigned long v, unsigned long align) { return ( v - ( align ? v % align : 0 ) ); } /** Align value in forward direction. * * @param v: Value to align. * @param align: Alignment. */ static unsigned long PaAlsa_AlignForward(unsigned long v, unsigned long align) { unsigned long remainder = ( align ? ( v % align ) : 0); return ( remainder != 0 ? v + ( align - remainder ) : v ); } /** Get size of host buffer maintained from the number of user frames, sample rate and suggested latency. Minimum double buffering * is maintained to allow 100% CPU usage inside user callback. * * @param userFramesPerBuffer: User buffer size in number of frames. * @param suggestedLatency: User provided desired latency. * @param sampleRate: Sample rate. */ static unsigned long PaAlsa_GetFramesPerHostBuffer(unsigned long userFramesPerBuffer, PaTime suggestedLatency, double sampleRate) { unsigned long frames = userFramesPerBuffer + PA_MAX( userFramesPerBuffer, (unsigned long)( suggestedLatency * sampleRate ) ); return frames; } /** Determine size per host buffer. * * During this method call, the component's framesPerBuffer attribute gets computed, and the corresponding period size * gets configured for the device. * @param accurate: If the configured period size is non-integer, this will be set to 0. */ static PaError PaAlsaStreamComponent_DetermineFramesPerBuffer( PaAlsaStreamComponent* self, const PaStreamParameters* params, unsigned long framesPerUserBuffer, double sampleRate, snd_pcm_hw_params_t* hwParams, int* accurate ) { PaError result = paNoError; unsigned long bufferSize, framesPerHostBuffer; int dir = 0; /* Calculate host buffer size */ bufferSize = PaAlsa_GetFramesPerHostBuffer(framesPerUserBuffer, params->suggestedLatency, sampleRate); /* Log */ PA_DEBUG(( "%s: user-buffer (frames) = %lu\n", __FUNCTION__, framesPerUserBuffer )); PA_DEBUG(( "%s: user-buffer (sec) = %f\n", __FUNCTION__, (double)(framesPerUserBuffer / sampleRate) )); PA_DEBUG(( "%s: suggested latency (sec) = %f\n", __FUNCTION__, params->suggestedLatency )); PA_DEBUG(( "%s: suggested host buffer (frames) = %lu\n", __FUNCTION__, bufferSize )); PA_DEBUG(( "%s: suggested host buffer (sec) = %f\n", __FUNCTION__, (double)(bufferSize / sampleRate) )); #ifdef PA_ALSA_USE_OBSOLETE_HOST_BUFFER_CALC if( framesPerUserBuffer != paFramesPerBufferUnspecified ) { /* Preferably the host buffer size should be a multiple of the user buffer size */ if( bufferSize > framesPerUserBuffer ) { snd_pcm_uframes_t remainder = bufferSize % framesPerUserBuffer; if( remainder > framesPerUserBuffer / 2. ) bufferSize += framesPerUserBuffer - remainder; else bufferSize -= remainder; assert( bufferSize % framesPerUserBuffer == 0 ); } else if( framesPerUserBuffer % bufferSize != 0 ) { /* Find a good compromise between user specified latency and buffer size */ if( bufferSize > framesPerUserBuffer * .75 ) { bufferSize = framesPerUserBuffer; } else { snd_pcm_uframes_t newSz = framesPerUserBuffer; while( newSz / 2 >= bufferSize ) { if( framesPerUserBuffer % (newSz / 2) != 0 ) { /* No use dividing any further */ break; } newSz /= 2; } bufferSize = newSz; } assert( framesPerUserBuffer % bufferSize == 0 ); } } #endif { unsigned numPeriods = numPeriods_, maxPeriods = 0, minPeriods = numPeriods_; /* It may be that the device only supports 2 periods for instance */ dir = 0; ENSURE_( alsa_snd_pcm_hw_params_get_periods_min( hwParams, &minPeriods, &dir ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_hw_params_get_periods_max( hwParams, &maxPeriods, &dir ), paUnanticipatedHostError ); assert( maxPeriods > 1 ); /* Clamp to min/max */ numPeriods = PA_MIN(maxPeriods, PA_MAX(minPeriods, numPeriods)); PA_DEBUG(( "%s: periods min = %lu, max = %lu, req = %lu \n", __FUNCTION__, minPeriods, maxPeriods, numPeriods )); #ifndef PA_ALSA_USE_OBSOLETE_HOST_BUFFER_CALC /* Calculate period size */ framesPerHostBuffer = (bufferSize / numPeriods); /* Align & test size */ if( framesPerUserBuffer != paFramesPerBufferUnspecified ) { /* Align to user buffer size */ framesPerHostBuffer = PaAlsa_AlignForward(framesPerHostBuffer, framesPerUserBuffer); /* Test (borrowed from older implementation) */ if( framesPerHostBuffer < framesPerUserBuffer ) { assert( framesPerUserBuffer % framesPerHostBuffer == 0 ); if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer, 0 ) < 0 ) { if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer * 2, 0 ) == 0 ) framesPerHostBuffer *= 2; else if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer / 2, 0 ) == 0 ) framesPerHostBuffer /= 2; } } else { assert( framesPerHostBuffer % framesPerUserBuffer == 0 ); if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer, 0 ) < 0 ) { if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer + framesPerUserBuffer, 0 ) == 0 ) framesPerHostBuffer += framesPerUserBuffer; else if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer - framesPerUserBuffer, 0 ) == 0 ) framesPerHostBuffer -= framesPerUserBuffer; } } } #endif #ifdef PA_ALSA_USE_OBSOLETE_HOST_BUFFER_CALC if( framesPerUserBuffer != paFramesPerBufferUnspecified ) { /* Try to get a power-of-two of the user buffer size. */ framesPerHostBuffer = framesPerUserBuffer; if( framesPerHostBuffer < bufferSize ) { while( bufferSize / framesPerHostBuffer > numPeriods ) { framesPerHostBuffer *= 2; } /* One extra period is preferrable to one less (should be more robust) */ if( bufferSize / framesPerHostBuffer < numPeriods ) { framesPerHostBuffer /= 2; } } else { while( bufferSize / framesPerHostBuffer < numPeriods ) { if( framesPerUserBuffer % ( framesPerHostBuffer / 2 ) != 0 ) { /* Can't be divided any further */ break; } framesPerHostBuffer /= 2; } } if( framesPerHostBuffer < framesPerUserBuffer ) { assert( framesPerUserBuffer % framesPerHostBuffer == 0 ); if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer, 0 ) < 0 ) { if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer * 2, 0 ) == 0 ) framesPerHostBuffer *= 2; else if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer / 2, 0 ) == 0 ) framesPerHostBuffer /= 2; } } else { assert( framesPerHostBuffer % framesPerUserBuffer == 0 ); if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer, 0 ) < 0 ) { if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer + framesPerUserBuffer, 0 ) == 0 ) framesPerHostBuffer += framesPerUserBuffer; else if( alsa_snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer - framesPerUserBuffer, 0 ) == 0 ) framesPerHostBuffer -= framesPerUserBuffer; } } } else { framesPerHostBuffer = bufferSize / numPeriods; } /* non-mmap mode needs a reasonably-sized buffer or it'll stutter */ if( !self->canMmap && framesPerHostBuffer < 2048 ) framesPerHostBuffer = 2048; #endif PA_DEBUG(( "%s: suggested host buffer period = %lu \n", __FUNCTION__, framesPerHostBuffer )); } { /* Get min/max period sizes and adjust our chosen */ snd_pcm_uframes_t min = 0, max = 0, minmax_diff; ENSURE_( alsa_snd_pcm_hw_params_get_period_size_min( hwParams, &min, NULL ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_hw_params_get_period_size_max( hwParams, &max, NULL ), paUnanticipatedHostError ); minmax_diff = max - min; if( framesPerHostBuffer < min ) { PA_DEBUG(( "%s: The determined period size (%lu) is less than minimum (%lu)\n", __FUNCTION__, framesPerHostBuffer, min )); framesPerHostBuffer = (( minmax_diff == 2 ) ? min + 1 : min ); } else if( framesPerHostBuffer > max ) { PA_DEBUG(( "%s: The determined period size (%lu) is greater than maximum (%lu)\n", __FUNCTION__, framesPerHostBuffer, max )); framesPerHostBuffer = (( minmax_diff == 2 ) ? max - 1 : max ); } PA_DEBUG(( "%s: device period minimum = %lu\n", __FUNCTION__, min )); PA_DEBUG(( "%s: device period maximum = %lu\n", __FUNCTION__, max )); PA_DEBUG(( "%s: host buffer period = %lu\n", __FUNCTION__, framesPerHostBuffer )); PA_DEBUG(( "%s: host buffer period latency = %f\n", __FUNCTION__, (double)( framesPerHostBuffer / sampleRate ) )); /* Try setting period size */ dir = 0; ENSURE_( alsa_snd_pcm_hw_params_set_period_size_near( self->pcm, hwParams, &framesPerHostBuffer, &dir ), paUnanticipatedHostError ); if( dir != 0 ) { PA_DEBUG(( "%s: The configured period size is non-integer.\n", __FUNCTION__, dir )); *accurate = 0; } } /* Set result */ self->framesPerBuffer = framesPerHostBuffer; error: return result; } /* We need to determine how many frames per host buffer (period) to use. Our * goals are to provide the best possible performance, but also to * honor the requested latency settings as closely as we can. Therefore this * decision is based on: * * - the period sizes that playback and/or capture support. The * host buffer size has to be one of these. * - the number of periods that playback and/or capture support. * * We want to make period_size*(num_periods-1) to be as close as possible * to latency*rate for both playback and capture. * * This method will determine suitable period sizes for capture and playback handles, and report the maximum number of * frames per host buffer. The latter is relevant, in case we should be so unfortunate that the period size differs * between capture and playback. If this should happen, the stream's hostBufferSizeMode attribute will be set to * paUtilBoundedHostBufferSize, because the best we can do is limit the size of individual host buffers to the upper * bound. The size of host buffers scheduled for processing should only matter if the user has specified a buffer size, * but when he/she does we must strive for an optimal configuration. By default we'll opt for a fixed host buffer size, * which should be fine if the period size is the same for capture and playback. In general, if there is a specified user * buffer size, this method tries it best to determine a period size which is a multiple of the user buffer size. * * The framesPerBuffer attributes of the individual capture and playback components of the stream are set to corresponding * values determined here. Since these should be reported as * * This is one of those blocks of code that will just take a lot of * refinement to be any good. * * In the full-duplex case it is possible that the routine was unable * to find a number of frames per buffer acceptable to both devices * TODO: Implement an algorithm to find the value closest to acceptance * by both devices, to minimize difference between period sizes? * * @param determinedFramesPerHostBuffer: The determined host buffer size. */ static PaError PaAlsaStream_DetermineFramesPerBuffer( PaAlsaStream* self, double sampleRate, const PaStreamParameters* inputParameters, const PaStreamParameters* outputParameters, unsigned long framesPerUserBuffer, snd_pcm_hw_params_t* hwParamsCapture, snd_pcm_hw_params_t* hwParamsPlayback, PaUtilHostBufferSizeMode* hostBufferSizeMode ) { PaError result = paNoError; unsigned long framesPerHostBuffer = 0; int dir = 0; int accurate = 1; unsigned numPeriods = numPeriods_; if( self->capture.pcm && self->playback.pcm ) { if( framesPerUserBuffer == paFramesPerBufferUnspecified ) { /* Come up with a common desired latency */ snd_pcm_uframes_t desiredBufSz, e, minPeriodSize, maxPeriodSize, optimalPeriodSize, periodSize, minCapture, minPlayback, maxCapture, maxPlayback; dir = 0; ENSURE_( alsa_snd_pcm_hw_params_get_period_size_min( hwParamsCapture, &minCapture, &dir ), paUnanticipatedHostError ); dir = 0; ENSURE_( alsa_snd_pcm_hw_params_get_period_size_min( hwParamsPlayback, &minPlayback, &dir ), paUnanticipatedHostError ); dir = 0; ENSURE_( alsa_snd_pcm_hw_params_get_period_size_max( hwParamsCapture, &maxCapture, &dir ), paUnanticipatedHostError ); dir = 0; ENSURE_( alsa_snd_pcm_hw_params_get_period_size_max( hwParamsPlayback, &maxPlayback, &dir ), paUnanticipatedHostError ); minPeriodSize = PA_MAX( minPlayback, minCapture ); maxPeriodSize = PA_MIN( maxPlayback, maxCapture ); PA_UNLESS( minPeriodSize <= maxPeriodSize, paBadIODeviceCombination ); desiredBufSz = (snd_pcm_uframes_t)( PA_MIN( outputParameters->suggestedLatency, inputParameters->suggestedLatency ) * sampleRate ); /* Clamp desiredBufSz */ { snd_pcm_uframes_t maxBufferSize; snd_pcm_uframes_t maxBufferSizeCapture, maxBufferSizePlayback; ENSURE_( alsa_snd_pcm_hw_params_get_buffer_size_max( hwParamsCapture, &maxBufferSizeCapture ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_hw_params_get_buffer_size_max( hwParamsPlayback, &maxBufferSizePlayback ), paUnanticipatedHostError ); maxBufferSize = PA_MIN( maxBufferSizeCapture, maxBufferSizePlayback ); desiredBufSz = PA_MIN( desiredBufSz, maxBufferSize ); } /* Find the closest power of 2 */ e = ilogb( minPeriodSize ); if( minPeriodSize & ( minPeriodSize - 1 ) ) e += 1; periodSize = (snd_pcm_uframes_t)pow( 2, e ); while( periodSize <= maxPeriodSize ) { if( alsa_snd_pcm_hw_params_test_period_size( self->playback.pcm, hwParamsPlayback, periodSize, 0 ) >= 0 && alsa_snd_pcm_hw_params_test_period_size( self->capture.pcm, hwParamsCapture, periodSize, 0 ) >= 0 ) { /* OK! */ break; } periodSize *= 2; } optimalPeriodSize = PA_MAX( desiredBufSz / numPeriods, minPeriodSize ); optimalPeriodSize = PA_MIN( optimalPeriodSize, maxPeriodSize ); /* Find the closest power of 2 */ e = ilogb( optimalPeriodSize ); if( optimalPeriodSize & (optimalPeriodSize - 1) ) e += 1; optimalPeriodSize = (snd_pcm_uframes_t)pow( 2, e ); while( optimalPeriodSize >= periodSize ) { if( alsa_snd_pcm_hw_params_test_period_size( self->capture.pcm, hwParamsCapture, optimalPeriodSize, 0 ) >= 0 && alsa_snd_pcm_hw_params_test_period_size( self->playback.pcm, hwParamsPlayback, optimalPeriodSize, 0 ) >= 0 ) { break; } optimalPeriodSize /= 2; } if( optimalPeriodSize > periodSize ) periodSize = optimalPeriodSize; if( periodSize <= maxPeriodSize ) { /* Looks good, the periodSize _should_ be acceptable by both devices */ ENSURE_( alsa_snd_pcm_hw_params_set_period_size( self->capture.pcm, hwParamsCapture, periodSize, 0 ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_hw_params_set_period_size( self->playback.pcm, hwParamsPlayback, periodSize, 0 ), paUnanticipatedHostError ); self->capture.framesPerBuffer = self->playback.framesPerBuffer = periodSize; framesPerHostBuffer = periodSize; } else { /* Unable to find a common period size, oh well */ optimalPeriodSize = PA_MAX( desiredBufSz / numPeriods, minPeriodSize ); optimalPeriodSize = PA_MIN( optimalPeriodSize, maxPeriodSize ); self->capture.framesPerBuffer = optimalPeriodSize; dir = 0; ENSURE_( alsa_snd_pcm_hw_params_set_period_size_near( self->capture.pcm, hwParamsCapture, &self->capture.framesPerBuffer, &dir ), paUnanticipatedHostError ); self->playback.framesPerBuffer = optimalPeriodSize; dir = 0; ENSURE_( alsa_snd_pcm_hw_params_set_period_size_near( self->playback.pcm, hwParamsPlayback, &self->playback.framesPerBuffer, &dir ), paUnanticipatedHostError ); framesPerHostBuffer = PA_MAX( self->capture.framesPerBuffer, self->playback.framesPerBuffer ); *hostBufferSizeMode = paUtilBoundedHostBufferSize; } } else { /* We choose the simple route and determine a suitable number of frames per buffer for one component of * the stream, then we hope that this will work for the other component too (it should!). */ unsigned maxPeriods = 0; PaAlsaStreamComponent* first = &self->capture, * second = &self->playback; const PaStreamParameters* firstStreamParams = inputParameters; snd_pcm_hw_params_t* firstHwParams = hwParamsCapture, * secondHwParams = hwParamsPlayback; dir = 0; ENSURE_( alsa_snd_pcm_hw_params_get_periods_max( hwParamsPlayback, &maxPeriods, &dir ), paUnanticipatedHostError ); if( maxPeriods < numPeriods ) { /* The playback component is trickier to get right, try that first */ first = &self->playback; second = &self->capture; firstStreamParams = outputParameters; firstHwParams = hwParamsPlayback; secondHwParams = hwParamsCapture; } PA_ENSURE( PaAlsaStreamComponent_DetermineFramesPerBuffer( first, firstStreamParams, framesPerUserBuffer, sampleRate, firstHwParams, &accurate ) ); second->framesPerBuffer = first->framesPerBuffer; dir = 0; ENSURE_( alsa_snd_pcm_hw_params_set_period_size_near( second->pcm, secondHwParams, &second->framesPerBuffer, &dir ), paUnanticipatedHostError ); if( self->capture.framesPerBuffer == self->playback.framesPerBuffer ) { framesPerHostBuffer = self->capture.framesPerBuffer; } else { framesPerHostBuffer = PA_MAX( self->capture.framesPerBuffer, self->playback.framesPerBuffer ); *hostBufferSizeMode = paUtilBoundedHostBufferSize; } } } else /* half-duplex is a slightly simpler case */ { if( self->capture.pcm ) { PA_ENSURE( PaAlsaStreamComponent_DetermineFramesPerBuffer( &self->capture, inputParameters, framesPerUserBuffer, sampleRate, hwParamsCapture, &accurate) ); framesPerHostBuffer = self->capture.framesPerBuffer; } else { assert( self->playback.pcm ); PA_ENSURE( PaAlsaStreamComponent_DetermineFramesPerBuffer( &self->playback, outputParameters, framesPerUserBuffer, sampleRate, hwParamsPlayback, &accurate ) ); framesPerHostBuffer = self->playback.framesPerBuffer; } } PA_UNLESS( framesPerHostBuffer != 0, paInternalError ); self->maxFramesPerHostBuffer = framesPerHostBuffer; if( !self->playback.canMmap || !accurate ) { /* Don't know the exact size per host buffer */ *hostBufferSizeMode = paUtilBoundedHostBufferSize; /* Raise upper bound */ if( !accurate ) ++self->maxFramesPerHostBuffer; } error: return result; } /** Set up ALSA stream parameters. * */ static PaError PaAlsaStream_Configure( PaAlsaStream *self, const PaStreamParameters *inParams, const PaStreamParameters* outParams, double sampleRate, unsigned long framesPerUserBuffer, double* inputLatency, double* outputLatency, PaUtilHostBufferSizeMode* hostBufferSizeMode ) { PaError result = paNoError; double realSr = sampleRate; snd_pcm_hw_params_t* hwParamsCapture, * hwParamsPlayback; alsa_snd_pcm_hw_params_alloca( &hwParamsCapture ); alsa_snd_pcm_hw_params_alloca( &hwParamsPlayback ); if( self->capture.pcm ) PA_ENSURE( PaAlsaStreamComponent_InitialConfigure( &self->capture, inParams, self->primeBuffers, hwParamsCapture, &realSr ) ); if( self->playback.pcm ) PA_ENSURE( PaAlsaStreamComponent_InitialConfigure( &self->playback, outParams, self->primeBuffers, hwParamsPlayback, &realSr ) ); PA_ENSURE( PaAlsaStream_DetermineFramesPerBuffer( self, realSr, inParams, outParams, framesPerUserBuffer, hwParamsCapture, hwParamsPlayback, hostBufferSizeMode ) ); if( self->capture.pcm ) { assert( self->capture.framesPerBuffer != 0 ); PA_ENSURE( PaAlsaStreamComponent_FinishConfigure( &self->capture, hwParamsCapture, inParams, self->primeBuffers, realSr, inputLatency ) ); PA_DEBUG(( "%s: Capture period size: %lu, latency: %f\n", __FUNCTION__, self->capture.framesPerBuffer, *inputLatency )); } if( self->playback.pcm ) { assert( self->playback.framesPerBuffer != 0 ); PA_ENSURE( PaAlsaStreamComponent_FinishConfigure( &self->playback, hwParamsPlayback, outParams, self->primeBuffers, realSr, outputLatency ) ); PA_DEBUG(( "%s: Playback period size: %lu, latency: %f\n", __FUNCTION__, self->playback.framesPerBuffer, *outputLatency )); } /* Should be exact now */ self->streamRepresentation.streamInfo.sampleRate = realSr; /* this will cause the two streams to automatically start/stop/prepare in sync. * We only need to execute these operations on one of the pair. * A: We don't want to do this on a blocking stream. */ if( self->callbackMode && self->capture.pcm && self->playback.pcm ) { int err = alsa_snd_pcm_link( self->capture.pcm, self->playback.pcm ); if( err == 0 ) self->pcmsSynced = 1; else PA_DEBUG(( "%s: Unable to sync pcms: %s\n", __FUNCTION__, alsa_snd_strerror( err ) )); } { unsigned long minFramesPerHostBuffer = PA_MIN( self->capture.pcm ? self->capture.framesPerBuffer : ULONG_MAX, self->playback.pcm ? self->playback.framesPerBuffer : ULONG_MAX ); self->pollTimeout = CalculatePollTimeout( self, minFramesPerHostBuffer ); /* Period in msecs, rounded up */ /* Time before watchdog unthrottles realtime thread == 1/4 of period time in msecs */ /* self->threading.throttledSleepTime = (unsigned long) (minFramesPerHostBuffer / sampleRate / 4 * 1000); */ } if( self->callbackMode ) { /* If the user expects a certain number of frames per callback we will either have to rely on block adaption * (framesPerHostBuffer is not an integer multiple of framesPerBuffer) or we can simply align the number * of host buffer frames with what the user specified */ if( self->framesPerUserBuffer != paFramesPerBufferUnspecified ) { /* self->alignFrames = 1; */ /* Unless the ratio between number of host and user buffer frames is an integer we will have to rely * on block adaption */ /* if( framesPerHostBuffer % framesPerBuffer != 0 || (self->capture.pcm && self->playback.pcm && self->capture.framesPerBuffer != self->playback.framesPerBuffer) ) self->useBlockAdaption = 1; else self->alignFrames = 1; */ } } error: return result; } static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback* callback, void *userData ) { PaError result = paNoError; PaAlsaHostApiRepresentation *alsaHostApi = (PaAlsaHostApiRepresentation*)hostApi; PaAlsaStream *stream = NULL; PaSampleFormat hostInputSampleFormat = 0, hostOutputSampleFormat = 0; PaSampleFormat inputSampleFormat = 0, outputSampleFormat = 0; int numInputChannels = 0, numOutputChannels = 0; PaTime inputLatency, outputLatency; /* Operate with fixed host buffer size by default, since other modes will invariably lead to block adaption */ /* XXX: Use Bounded by default? Output tends to get stuttery with Fixed ... */ PaUtilHostBufferSizeMode hostBufferSizeMode = paUtilFixedHostBufferSize; if( ( streamFlags & paPlatformSpecificFlags ) != 0 ) return paInvalidFlag; if( inputParameters ) { PA_ENSURE( ValidateParameters( inputParameters, hostApi, StreamDirection_In ) ); numInputChannels = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; } if( outputParameters ) { PA_ENSURE( ValidateParameters( outputParameters, hostApi, StreamDirection_Out ) ); numOutputChannels = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; } /* XXX: Why do we support this anyway? */ if( framesPerBuffer == paFramesPerBufferUnspecified && getenv( "PA_ALSA_PERIODSIZE" ) != NULL ) { PA_DEBUG(( "%s: Getting framesPerBuffer from environment\n", __FUNCTION__ )); framesPerBuffer = atoi( getenv("PA_ALSA_PERIODSIZE") ); } PA_UNLESS( stream = (PaAlsaStream*)PaUtil_AllocateMemory( sizeof(PaAlsaStream) ), paInsufficientMemory ); PA_ENSURE( PaAlsaStream_Initialize( stream, alsaHostApi, inputParameters, outputParameters, sampleRate, framesPerBuffer, callback, streamFlags, userData ) ); PA_ENSURE( PaAlsaStream_Configure( stream, inputParameters, outputParameters, sampleRate, framesPerBuffer, &inputLatency, &outputLatency, &hostBufferSizeMode ) ); hostInputSampleFormat = stream->capture.hostSampleFormat | (!stream->capture.hostInterleaved ? paNonInterleaved : 0); hostOutputSampleFormat = stream->playback.hostSampleFormat | (!stream->playback.hostInterleaved ? paNonInterleaved : 0); PA_ENSURE( PaUtil_InitializeBufferProcessor( &stream->bufferProcessor, numInputChannels, inputSampleFormat, hostInputSampleFormat, numOutputChannels, outputSampleFormat, hostOutputSampleFormat, sampleRate, streamFlags, framesPerBuffer, stream->maxFramesPerHostBuffer, hostBufferSizeMode, callback, userData ) ); /* Ok, buffer processor is initialized, now we can deduce it's latency */ if( numInputChannels > 0 ) stream->streamRepresentation.streamInfo.inputLatency = inputLatency + (PaTime)( PaUtil_GetBufferProcessorInputLatencyFrames( &stream->bufferProcessor ) / sampleRate); if( numOutputChannels > 0 ) stream->streamRepresentation.streamInfo.outputLatency = outputLatency + (PaTime)( PaUtil_GetBufferProcessorOutputLatencyFrames( &stream->bufferProcessor ) / sampleRate); PA_DEBUG(( "%s: Stream: framesPerBuffer = %lu, maxFramesPerHostBuffer = %lu, latency = i(%f)/o(%f), \n", __FUNCTION__, framesPerBuffer, stream->maxFramesPerHostBuffer, stream->streamRepresentation.streamInfo.inputLatency, stream->streamRepresentation.streamInfo.outputLatency)); *s = (PaStream*)stream; return result; error: if( stream ) { PA_DEBUG(( "%s: Stream in error, terminating\n", __FUNCTION__ )); PaAlsaStream_Terminate( stream ); } return result; } static PaError CloseStream( PaStream* s ) { PaError result = paNoError; PaAlsaStream *stream = (PaAlsaStream*)s; PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); PaAlsaStream_Terminate( stream ); return result; } static void SilenceBuffer( PaAlsaStream *stream ) { const snd_pcm_channel_area_t *areas; snd_pcm_uframes_t frames = (snd_pcm_uframes_t)alsa_snd_pcm_avail_update( stream->playback.pcm ), offset; alsa_snd_pcm_mmap_begin( stream->playback.pcm, &areas, &offset, &frames ); alsa_snd_pcm_areas_silence( areas, offset, stream->playback.numHostChannels, frames, stream->playback.nativeFormat ); alsa_snd_pcm_mmap_commit( stream->playback.pcm, offset, frames ); } /** Start/prepare pcm(s) for streaming. * * Depending on wether the stream is in callback or blocking mode, we will respectively start or simply * prepare the playback pcm. If the buffer has _not_ been primed, we will in callback mode prepare and * silence the buffer before starting playback. In blocking mode we simply prepare, as the playback will * be started automatically as the user writes to output. * * The capture pcm, however, will simply be prepared and started. */ static PaError AlsaStart( PaAlsaStream *stream, int priming ) { PaError result = paNoError; if( stream->playback.pcm ) { if( stream->callbackMode ) { if( !priming ) { /* Buffer isn't primed, so prepare and silence */ ENSURE_( alsa_snd_pcm_prepare( stream->playback.pcm ), paUnanticipatedHostError ); if( stream->playback.canMmap ) SilenceBuffer( stream ); } if( stream->playback.canMmap ) ENSURE_( alsa_snd_pcm_start( stream->playback.pcm ), paUnanticipatedHostError ); } else ENSURE_( alsa_snd_pcm_prepare( stream->playback.pcm ), paUnanticipatedHostError ); } if( stream->capture.pcm && !stream->pcmsSynced ) { ENSURE_( alsa_snd_pcm_prepare( stream->capture.pcm ), paUnanticipatedHostError ); /* For a blocking stream we want to start capture as well, since nothing will happen otherwise */ ENSURE_( alsa_snd_pcm_start( stream->capture.pcm ), paUnanticipatedHostError ); } end: return result; error: goto end; } /** Utility function for determining if pcms are in running state. * */ #if 0 static int IsRunning( PaAlsaStream *stream ) { int result = 0; PA_ENSURE( PaUnixMutex_Lock( &stream->stateMtx ) ); if( stream->capture.pcm ) { snd_pcm_state_t capture_state = alsa_snd_pcm_state( stream->capture.pcm ); if( capture_state == SND_PCM_STATE_RUNNING || capture_state == SND_PCM_STATE_XRUN || capture_state == SND_PCM_STATE_DRAINING ) { result = 1; goto end; } } if( stream->playback.pcm ) { snd_pcm_state_t playback_state = alsa_snd_pcm_state( stream->playback.pcm ); if( playback_state == SND_PCM_STATE_RUNNING || playback_state == SND_PCM_STATE_XRUN || playback_state == SND_PCM_STATE_DRAINING ) { result = 1; goto end; } } end: ASSERT_CALL_( PaUnixMutex_Unlock( &stream->stateMtx ), paNoError ); return result; error: goto error; } #endif static PaError StartStream( PaStream *s ) { PaError result = paNoError; PaAlsaStream* stream = (PaAlsaStream*)s; int streamStarted = 0; /* So we can know wether we need to take the stream down */ /* Ready the processor */ PaUtil_ResetBufferProcessor( &stream->bufferProcessor ); /* Set now, so we can test for activity further down */ stream->isActive = 1; if( stream->callbackMode ) { PA_ENSURE( PaUnixThread_New( &stream->thread, &CallbackThreadFunc, stream, 1., stream->rtSched ) ); } else { PA_ENSURE( AlsaStart( stream, 0 ) ); streamStarted = 1; } end: return result; error: if( streamStarted ) { AbortStream( stream ); } stream->isActive = 0; goto end; } /** Stop PCM handle, either softly or abruptly. */ static PaError AlsaStop( PaAlsaStream *stream, int abort ) { PaError result = paNoError; /* XXX: alsa_snd_pcm_drain tends to lock up, avoid it until we find out more */ abort = 1; /* if( stream->capture.pcm && !strcmp( Pa_GetDeviceInfo( stream->capture.device )->name, "dmix" ) ) { abort = 1; } else if( stream->playback.pcm && !strcmp( Pa_GetDeviceInfo( stream->playback.device )->name, "dmix" ) ) { abort = 1; } */ if( abort ) { if( stream->playback.pcm ) { ENSURE_( alsa_snd_pcm_drop( stream->playback.pcm ), paUnanticipatedHostError ); } if( stream->capture.pcm && !stream->pcmsSynced ) { ENSURE_( alsa_snd_pcm_drop( stream->capture.pcm ), paUnanticipatedHostError ); } PA_DEBUG(( "%s: Dropped frames\n", __FUNCTION__ )); } else { if( stream->playback.pcm ) { ENSURE_( alsa_snd_pcm_nonblock( stream->playback.pcm, 0 ), paUnanticipatedHostError ); if( alsa_snd_pcm_drain( stream->playback.pcm ) < 0 ) { PA_DEBUG(( "%s: Draining playback handle failed!\n", __FUNCTION__ )); } } if( stream->capture.pcm && !stream->pcmsSynced ) { /* We don't need to retrieve any remaining frames */ if( alsa_snd_pcm_drain( stream->capture.pcm ) < 0 ) { PA_DEBUG(( "%s: Draining capture handle failed!\n", __FUNCTION__ )); } } } end: return result; error: goto end; } /** Stop or abort stream. * * If a stream is in callback mode we will have to inspect wether the background thread has * finished, or we will have to take it out. In either case we join the thread before * returning. In blocking mode, we simply tell ALSA to stop abruptly (abort) or finish * buffers (drain) * * Stream will be considered inactive (!PaAlsaStream::isActive) after a call to this function */ static PaError RealStop( PaAlsaStream *stream, int abort ) { PaError result = paNoError; /* First deal with the callback thread, cancelling and/or joining * it if necessary */ if( stream->callbackMode ) { PaError threadRes; stream->callbackAbort = abort; if( !abort ) { PA_DEBUG(( "Stopping callback\n" )); } PA_ENSURE( PaUnixThread_Terminate( &stream->thread, !abort, &threadRes ) ); if( threadRes != paNoError ) { PA_DEBUG(( "Callback thread returned: %d\n", threadRes )); } #if 0 if( watchdogRes != paNoError ) PA_DEBUG(( "Watchdog thread returned: %d\n", watchdogRes )); #endif stream->callback_finished = 0; } else { PA_ENSURE( AlsaStop( stream, abort ) ); } stream->isActive = 0; end: return result; error: goto end; } static PaError StopStream( PaStream *s ) { return RealStop( (PaAlsaStream *) s, 0 ); } static PaError AbortStream( PaStream *s ) { return RealStop( (PaAlsaStream * ) s, 1 ); } /** The stream is considered stopped before StartStream, or AFTER a call to Abort/StopStream (callback * returning !paContinue is not considered) * */ static PaError IsStreamStopped( PaStream *s ) { PaAlsaStream *stream = (PaAlsaStream *)s; /* callback_finished indicates we need to join callback thread (ie. in Abort/StopStream) */ return !IsStreamActive( s ) && !stream->callback_finished; } static PaError IsStreamActive( PaStream *s ) { PaAlsaStream *stream = (PaAlsaStream*)s; return stream->isActive; } static PaTime GetStreamTime( PaStream *s ) { PaAlsaStream *stream = (PaAlsaStream*)s; snd_timestamp_t timestamp; snd_pcm_status_t* status; alsa_snd_pcm_status_alloca( &status ); /* TODO: what if we have both? does it really matter? */ /* TODO: if running in callback mode, this will mean * libasound routines are being called from multiple threads. * need to verify that libasound is thread-safe. */ if( stream->capture.pcm ) { alsa_snd_pcm_status( stream->capture.pcm, status ); } else if( stream->playback.pcm ) { alsa_snd_pcm_status( stream->playback.pcm, status ); } alsa_snd_pcm_status_get_tstamp( status, ×tamp ); return timestamp.tv_sec + (PaTime)timestamp.tv_usec / 1e6; } static double GetStreamCpuLoad( PaStream* s ) { PaAlsaStream *stream = (PaAlsaStream*)s; return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ); } /* Set the stream sample rate to a nominal value requested; allow only a defined tolerance range */ static int SetApproximateSampleRate( snd_pcm_t *pcm, snd_pcm_hw_params_t *hwParams, double sampleRate ) { PaError result = paNoError; unsigned int reqRate, setRate, deviation; assert( pcm && hwParams ); /* The Alsa sample rate is set by integer value; also the actual rate may differ */ reqRate = setRate = (unsigned int) sampleRate; ENSURE_( alsa_snd_pcm_hw_params_set_rate_near( pcm, hwParams, &setRate, NULL ), paUnanticipatedHostError ); /* The value actually set will be put in 'setRate' (may be way off); check the deviation as a proportion * of the requested-rate with reference to the max-deviate-ratio (larger values allow less deviation) */ deviation = abs( setRate - reqRate ); if( deviation > 0 && deviation * RATE_MAX_DEVIATE_RATIO > reqRate ) result = paInvalidSampleRate; end: return result; error: /* Log */ { unsigned int _min = 0, _max = 0; int _dir = 0; ENSURE_( alsa_snd_pcm_hw_params_get_rate_min( hwParams, &_min, &_dir ), paUnanticipatedHostError ); ENSURE_( alsa_snd_pcm_hw_params_get_rate_max( hwParams, &_max, &_dir ), paUnanticipatedHostError ); PA_DEBUG(( "%s: SR min = %u, max = %u, req = %u\n", __FUNCTION__, _min, _max, reqRate )); } goto end; } /* Return exact sample rate in param sampleRate */ static int GetExactSampleRate( snd_pcm_hw_params_t *hwParams, double *sampleRate ) { unsigned int num, den = 1; int err; assert( hwParams ); err = alsa_snd_pcm_hw_params_get_rate_numden( hwParams, &num, &den ); *sampleRate = (double) num / den; return err; } /* Utility functions for blocking/callback interfaces */ /* Atomic restart of stream (we don't want the intermediate state visible) */ static PaError AlsaRestart( PaAlsaStream *stream ) { PaError result = paNoError; PA_ENSURE( PaUnixMutex_Lock( &stream->stateMtx ) ); PA_ENSURE( AlsaStop( stream, 0 ) ); PA_ENSURE( AlsaStart( stream, 0 ) ); PA_DEBUG(( "%s: Restarted audio\n", __FUNCTION__ )); error: PA_ENSURE( PaUnixMutex_Unlock( &stream->stateMtx ) ); return result; } /** Recover from xrun state. * */ static PaError PaAlsaStream_HandleXrun( PaAlsaStream *self ) { PaError result = paNoError; snd_pcm_status_t *st; PaTime now = PaUtil_GetTime(); snd_timestamp_t t; int restartAlsa = 0; /* do not restart Alsa by default */ alsa_snd_pcm_status_alloca( &st ); if( self->playback.pcm ) { alsa_snd_pcm_status( self->playback.pcm, st ); if( alsa_snd_pcm_status_get_state( st ) == SND_PCM_STATE_XRUN ) { alsa_snd_pcm_status_get_trigger_tstamp( st, &t ); self->underrun = now * 1000 - ( (PaTime)t.tv_sec * 1000 + (PaTime)t.tv_usec / 1000 ); if( !self->playback.canMmap ) { if( alsa_snd_pcm_recover( self->playback.pcm, -EPIPE, 0 ) < 0 ) { PA_DEBUG(( "%s: [playback] non-MMAP-PCM failed recovering from XRUN, will restart Alsa\n", __FUNCTION__ )); ++ restartAlsa; /* did not manage to recover */ } } else ++ restartAlsa; /* always restart MMAPed device */ } } if( self->capture.pcm ) { alsa_snd_pcm_status( self->capture.pcm, st ); if( alsa_snd_pcm_status_get_state( st ) == SND_PCM_STATE_XRUN ) { alsa_snd_pcm_status_get_trigger_tstamp( st, &t ); self->overrun = now * 1000 - ((PaTime) t.tv_sec * 1000 + (PaTime) t.tv_usec / 1000); if (!self->capture.canMmap) { if (alsa_snd_pcm_recover( self->capture.pcm, -EPIPE, 0 ) < 0) { PA_DEBUG(( "%s: [capture] non-MMAP-PCM failed recovering from XRUN, will restart Alsa\n", __FUNCTION__ )); ++ restartAlsa; /* did not manage to recover */ } } else ++ restartAlsa; /* always restart MMAPed device */ } } if( restartAlsa ) { PA_DEBUG(( "%s: restarting Alsa to recover from XRUN\n", __FUNCTION__ )); PA_ENSURE( AlsaRestart( self ) ); } end: return result; error: goto end; } /** Decide if we should continue polling for specified direction, eventually adjust the poll timeout. * */ static PaError ContinuePoll( const PaAlsaStream *stream, StreamDirection streamDir, int *pollTimeout, int *continuePoll ) { PaError result = paNoError; snd_pcm_sframes_t delay, margin; int err; const PaAlsaStreamComponent *component = NULL, *otherComponent = NULL; *continuePoll = 1; if( StreamDirection_In == streamDir ) { component = &stream->capture; otherComponent = &stream->playback; } else { component = &stream->playback; otherComponent = &stream->capture; } /* ALSA docs say that negative delay should indicate xrun, but in my experience alsa_snd_pcm_delay returns -EPIPE */ if( ( err = alsa_snd_pcm_delay( otherComponent->pcm, &delay ) ) < 0 ) { if( err == -EPIPE ) { /* Xrun */ *continuePoll = 0; goto error; } ENSURE_( err, paUnanticipatedHostError ); } if( StreamDirection_Out == streamDir ) { /* Number of eligible frames before capture overrun */ delay = otherComponent->bufferSize - delay; } margin = delay - otherComponent->framesPerBuffer / 2; if( margin < 0 ) { PA_DEBUG(( "%s: Stopping poll for %s\n", __FUNCTION__, StreamDirection_In == streamDir ? "capture" : "playback" )); *continuePoll = 0; } else if( margin < otherComponent->framesPerBuffer ) { *pollTimeout = CalculatePollTimeout( stream, margin ); PA_DEBUG(( "%s: Trying to poll again for %s frames, pollTimeout: %d\n", __FUNCTION__, StreamDirection_In == streamDir ? "capture" : "playback", *pollTimeout )); } error: return result; } /* Callback interface */ static void OnExit( void *data ) { PaAlsaStream *stream = (PaAlsaStream *) data; assert( data ); PaUtil_ResetCpuLoadMeasurer( &stream->cpuLoadMeasurer ); stream->callback_finished = 1; /* Let the outside world know stream was stopped in callback */ PA_DEBUG(( "%s: Stopping ALSA handles\n", __FUNCTION__ )); AlsaStop( stream, stream->callbackAbort ); PA_DEBUG(( "%s: Stoppage\n", __FUNCTION__ )); /* Eventually notify user all buffers have played */ if( stream->streamRepresentation.streamFinishedCallback ) { stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); } stream->isActive = 0; } static void CalculateTimeInfo( PaAlsaStream *stream, PaStreamCallbackTimeInfo *timeInfo ) { snd_pcm_status_t *capture_status, *playback_status; snd_timestamp_t capture_timestamp, playback_timestamp; PaTime capture_time = 0., playback_time = 0.; alsa_snd_pcm_status_alloca( &capture_status ); alsa_snd_pcm_status_alloca( &playback_status ); if( stream->capture.pcm ) { snd_pcm_sframes_t capture_delay; alsa_snd_pcm_status( stream->capture.pcm, capture_status ); alsa_snd_pcm_status_get_tstamp( capture_status, &capture_timestamp ); capture_time = capture_timestamp.tv_sec + ( (PaTime)capture_timestamp.tv_usec / 1000000.0 ); timeInfo->currentTime = capture_time; capture_delay = alsa_snd_pcm_status_get_delay( capture_status ); timeInfo->inputBufferAdcTime = timeInfo->currentTime - (PaTime)capture_delay / stream->streamRepresentation.streamInfo.sampleRate; } if( stream->playback.pcm ) { snd_pcm_sframes_t playback_delay; alsa_snd_pcm_status( stream->playback.pcm, playback_status ); alsa_snd_pcm_status_get_tstamp( playback_status, &playback_timestamp ); playback_time = playback_timestamp.tv_sec + ((PaTime)playback_timestamp.tv_usec / 1000000.0); if( stream->capture.pcm ) /* Full duplex */ { /* Hmm, we have both a playback and a capture timestamp. * Hopefully they are the same... */ if( fabs( capture_time - playback_time ) > 0.01 ) PA_DEBUG(( "Capture time and playback time differ by %f\n", fabs( capture_time-playback_time ) )); } else timeInfo->currentTime = playback_time; playback_delay = alsa_snd_pcm_status_get_delay( playback_status ); timeInfo->outputBufferDacTime = timeInfo->currentTime + (PaTime)playback_delay / stream->streamRepresentation.streamInfo.sampleRate; } } /** Called after buffer processing is finished. * * A number of mmapped frames is committed, it is possible that an xrun has occurred in the meantime. * * @param numFrames The number of frames that has been processed * @param xrun Return whether an xrun has occurred */ static PaError PaAlsaStreamComponent_EndProcessing( PaAlsaStreamComponent *self, unsigned long numFrames, int *xrun ) { PaError result = paNoError; int res = 0; /* @concern FullDuplex It is possible that only one direction is marked ready after polling, and processed * afterwards */ if( !self->ready ) goto end; if( !self->canMmap && StreamDirection_Out == self->streamDir ) { /* Play sound */ if( self->hostInterleaved ) res = alsa_snd_pcm_writei( self->pcm, self->nonMmapBuffer, numFrames ); else { void *bufs[self->numHostChannels]; int bufsize = alsa_snd_pcm_format_size( self->nativeFormat, self->framesPerBuffer + 1 ); unsigned char *buffer = self->nonMmapBuffer; int i; for( i = 0; i < self->numHostChannels; ++i ) { bufs[i] = buffer; buffer += bufsize; } res = alsa_snd_pcm_writen( self->pcm, bufs, numFrames ); } } if( self->canMmap ) res = alsa_snd_pcm_mmap_commit( self->pcm, self->offset, numFrames ); else { /* using realloc for optimisation free( self->nonMmapBuffer ); self->nonMmapBuffer = NULL; */ } if( res == -EPIPE || res == -ESTRPIPE ) { *xrun = 1; } else { ENSURE_( res, paUnanticipatedHostError ); } end: error: return result; } /* Extract buffer from channel area */ static unsigned char *ExtractAddress( const snd_pcm_channel_area_t *area, snd_pcm_uframes_t offset ) { return (unsigned char *) area->addr + ( area->first + offset * area->step ) / 8; } /** Do necessary adaption between user and host channels. * @concern ChannelAdaption Adapting between user and host channels can involve silencing unused channels and duplicating mono information if host outputs come in pairs. */ static PaError PaAlsaStreamComponent_DoChannelAdaption( PaAlsaStreamComponent *self, PaUtilBufferProcessor *bp, int numFrames ) { PaError result = paNoError; unsigned char *p; int i; int unusedChans = self->numHostChannels - self->numUserChannels; unsigned char *src, *dst; int convertMono = ( self->numHostChannels % 2 ) == 0 && ( self->numUserChannels % 2 ) != 0; assert( StreamDirection_Out == self->streamDir ); if( self->hostInterleaved ) { int swidth = alsa_snd_pcm_format_size( self->nativeFormat, 1 ); unsigned char *buffer = self->canMmap ? ExtractAddress( self->channelAreas, self->offset ) : self->nonMmapBuffer; /* Start after the last user channel */ p = buffer + self->numUserChannels * swidth; if( convertMono ) { /* Convert the last user channel into stereo pair */ src = buffer + ( self->numUserChannels - 1 ) * swidth; for( i = 0; i < numFrames; ++i ) { dst = src + swidth; memcpy( dst, src, swidth ); src += self->numHostChannels * swidth; } /* Don't touch the channel we just wrote to */ p += swidth; --unusedChans; } if( unusedChans > 0 ) { /* Silence unused output channels */ for( i = 0; i < numFrames; ++i ) { memset( p, 0, swidth * unusedChans ); p += self->numHostChannels * swidth; } } } else { /* We extract the last user channel */ if( convertMono ) { ENSURE_( alsa_snd_pcm_area_copy( self->channelAreas + self->numUserChannels, self->offset, self->channelAreas + ( self->numUserChannels - 1 ), self->offset, numFrames, self->nativeFormat ), paUnanticipatedHostError ); --unusedChans; } if( unusedChans > 0 ) { alsa_snd_pcm_areas_silence( self->channelAreas + ( self->numHostChannels - unusedChans ), self->offset, unusedChans, numFrames, self->nativeFormat ); } } error: return result; } static PaError PaAlsaStream_EndProcessing( PaAlsaStream *self, unsigned long numFrames, int *xrunOccurred ) { PaError result = paNoError; int xrun = 0; if( self->capture.pcm ) { PA_ENSURE( PaAlsaStreamComponent_EndProcessing( &self->capture, numFrames, &xrun ) ); } if( self->playback.pcm ) { if( self->playback.numHostChannels > self->playback.numUserChannels ) { PA_ENSURE( PaAlsaStreamComponent_DoChannelAdaption( &self->playback, &self->bufferProcessor, numFrames ) ); } PA_ENSURE( PaAlsaStreamComponent_EndProcessing( &self->playback, numFrames, &xrun ) ); } error: *xrunOccurred = xrun; return result; } /** Update the number of available frames. * */ static PaError PaAlsaStreamComponent_GetAvailableFrames( PaAlsaStreamComponent *self, unsigned long *numFrames, int *xrunOccurred ) { PaError result = paNoError; snd_pcm_sframes_t framesAvail = alsa_snd_pcm_avail_update( self->pcm ); *xrunOccurred = 0; if( -EPIPE == framesAvail ) { *xrunOccurred = 1; framesAvail = 0; } else { ENSURE_( framesAvail, paUnanticipatedHostError ); } *numFrames = framesAvail; error: return result; } /** Fill in pollfd objects. */ static PaError PaAlsaStreamComponent_BeginPolling( PaAlsaStreamComponent* self, struct pollfd* pfds ) { PaError result = paNoError; int ret = alsa_snd_pcm_poll_descriptors( self->pcm, pfds, self->nfds ); (void)ret; /* Prevent unused variable warning if asserts are turned off */ assert( ret == self->nfds ); self->ready = 0; return result; } /** Examine results from poll(). * * @param pfds pollfds to inspect * @param shouldPoll Should we continue to poll * @param xrun Has an xrun occurred */ static PaError PaAlsaStreamComponent_EndPolling( PaAlsaStreamComponent* self, struct pollfd* pfds, int* shouldPoll, int* xrun ) { PaError result = paNoError; unsigned short revents; ENSURE_( alsa_snd_pcm_poll_descriptors_revents( self->pcm, pfds, self->nfds, &revents ), paUnanticipatedHostError ); if( revents != 0 ) { if( revents & POLLERR ) { *xrun = 1; } else if( revents & POLLHUP ) { *xrun = 1; PA_DEBUG(( "%s: revents has POLLHUP, processing as XRUN\n", __FUNCTION__ )); } else self->ready = 1; *shouldPoll = 0; } else /* (A zero revent occurred) */ /* Work around an issue with Alsa older than 1.0.16 using some plugins (eg default with plug + dmix) where * POLLIN or POLLOUT are zeroed by Alsa-lib if _mmap_avail() is a few frames short of avail_min at period * boundary, possibly due to erratic dma interrupts at period boundary? Treat as a valid event. */ if( self->useReventFix ) { self->ready = 1; *shouldPoll = 0; } error: return result; } /** Return the number of available frames for this stream. * * @concern FullDuplex The minimum available for the two directions is calculated, it might be desirable to ignore * one direction however (not marked ready from poll), so this is controlled by queryCapture and queryPlayback. * * @param queryCapture Check available for capture * @param queryPlayback Check available for playback * @param available The returned number of frames * @param xrunOccurred Return whether an xrun has occurred */ static PaError PaAlsaStream_GetAvailableFrames( PaAlsaStream *self, int queryCapture, int queryPlayback, unsigned long *available, int *xrunOccurred ) { PaError result = paNoError; unsigned long captureFrames, playbackFrames; *xrunOccurred = 0; assert( queryCapture || queryPlayback ); if( queryCapture ) { assert( self->capture.pcm ); PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( &self->capture, &captureFrames, xrunOccurred ) ); if( *xrunOccurred ) { goto end; } } if( queryPlayback ) { assert( self->playback.pcm ); PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( &self->playback, &playbackFrames, xrunOccurred ) ); if( *xrunOccurred ) { goto end; } } if( queryCapture && queryPlayback ) { *available = PA_MIN( captureFrames, playbackFrames ); /*PA_DEBUG(("capture: %lu, playback: %lu, combined: %lu\n", captureFrames, playbackFrames, *available));*/ } else if( queryCapture ) { *available = captureFrames; } else { *available = playbackFrames; } end: error: return result; } /** Wait for and report available buffer space from ALSA. * * Unless ALSA reports a minimum of frames available for I/O, we poll the ALSA filedescriptors for more. * Both of these operations can uncover xrun conditions. * * @concern Xruns Both polling and querying available frames can report an xrun condition. * * @param framesAvail Return the number of available frames * @param xrunOccurred Return whether an xrun has occurred */ static PaError PaAlsaStream_WaitForFrames( PaAlsaStream *self, unsigned long *framesAvail, int *xrunOccurred ) { PaError result = paNoError; int pollPlayback = self->playback.pcm != NULL, pollCapture = self->capture.pcm != NULL; int pollTimeout = self->pollTimeout; int xrun = 0, timeouts = 0; int pollResults; assert( self ); assert( framesAvail ); if( !self->callbackMode ) { /* In blocking mode we will only wait if necessary */ PA_ENSURE( PaAlsaStream_GetAvailableFrames( self, self->capture.pcm != NULL, self->playback.pcm != NULL, framesAvail, &xrun ) ); if( xrun ) { goto end; } if( *framesAvail > 0 ) { /* Mark pcms ready from poll */ if( self->capture.pcm ) self->capture.ready = 1; if( self->playback.pcm ) self->playback.ready = 1; goto end; } } while( pollPlayback || pollCapture ) { int totalFds = 0; struct pollfd *capturePfds = NULL, *playbackPfds = NULL; #ifdef PTHREAD_CANCELED pthread_testcancel(); #endif if( pollCapture ) { capturePfds = self->pfds; PA_ENSURE( PaAlsaStreamComponent_BeginPolling( &self->capture, capturePfds ) ); totalFds += self->capture.nfds; } if( pollPlayback ) { playbackPfds = self->pfds + (self->capture.pcm ? self->capture.nfds : 0); PA_ENSURE( PaAlsaStreamComponent_BeginPolling( &self->playback, playbackPfds ) ); totalFds += self->playback.nfds; } pollResults = poll( self->pfds, totalFds, pollTimeout ); if( pollResults < 0 ) { /* XXX: Depend on preprocessor condition? */ if( errno == EINTR ) { /* gdb */ Pa_Sleep( 1 ); /* avoid hot loop */ continue; } /* TODO: Add macro for checking system calls */ PA_ENSURE( paInternalError ); } else if( pollResults == 0 ) { /* Suspended, paused or failed device can provide 0 poll results. To avoid deadloop in such situation * we simply run counter 'timeouts' which detects 0 poll result and accumulates. As soon as 2048 timouts (around 2 seconds) * are achieved we simply fail function with paTimedOut to notify waiting methods that device is not capable * of providing audio data anymore and needs some corresponding recovery action. * Note that 'timeouts' is reset to 0 if poll() managed to return non 0 results. */ /*PA_DEBUG(( "%s: poll == 0 results, timed out, %d times left\n", __FUNCTION__, 2048 - timeouts ));*/ ++ timeouts; if( timeouts > 1 ) /* sometimes device times out, but normally once, so we do not sleep any time */ { Pa_Sleep( 1 ); /* avoid hot loop */ } /* not else ! */ if( timeouts >= 2048 ) /* audio device not working, shall return error to notify waiters */ { *framesAvail = 0; /* no frames available for processing */ xrun = 1; /* try recovering device */ PA_DEBUG(( "%s: poll timed out\n", __FUNCTION__, timeouts )); goto end;/*PA_ENSURE( paTimedOut );*/ } } else if( pollResults > 0 ) { /* reset timouts counter */ timeouts = 0; /* check the return status of our pfds */ if( pollCapture ) { PA_ENSURE( PaAlsaStreamComponent_EndPolling( &self->capture, capturePfds, &pollCapture, &xrun ) ); } if( pollPlayback ) { PA_ENSURE( PaAlsaStreamComponent_EndPolling( &self->playback, playbackPfds, &pollPlayback, &xrun ) ); } if( xrun ) { break; } } /* @concern FullDuplex If only one of two pcms is ready we may want to compromise between the two. * If there is less than half a period's worth of samples left of frames in the other pcm's buffer we will * stop polling. */ if( self->capture.pcm && self->playback.pcm ) { if( pollCapture && !pollPlayback ) { PA_ENSURE( ContinuePoll( self, StreamDirection_In, &pollTimeout, &pollCapture ) ); } else if( pollPlayback && !pollCapture ) { PA_ENSURE( ContinuePoll( self, StreamDirection_Out, &pollTimeout, &pollPlayback ) ); } } } if( !xrun ) { /* Get the number of available frames for the pcms that are marked ready. * @concern FullDuplex If only one direction is marked ready (from poll), the number of frames available for * the other direction is returned. Output is normally preferred over capture however, so capture frames may be * discarded to avoid overrun unless paNeverDropInput is specified. */ int captureReady = self->capture.pcm ? self->capture.ready : 0, playbackReady = self->playback.pcm ? self->playback.ready : 0; PA_ENSURE( PaAlsaStream_GetAvailableFrames( self, captureReady, playbackReady, framesAvail, &xrun ) ); if( self->capture.pcm && self->playback.pcm ) { if( !self->playback.ready && !self->neverDropInput ) { /* Drop input, a period's worth */ assert( self->capture.ready ); PaAlsaStreamComponent_EndProcessing( &self->capture, PA_MIN( self->capture.framesPerBuffer, *framesAvail ), &xrun ); *framesAvail = 0; self->capture.ready = 0; } } else if( self->capture.pcm ) assert( self->capture.ready ); else assert( self->playback.ready ); } end: error: if( xrun ) { /* Recover from the xrun state */ PA_ENSURE( PaAlsaStream_HandleXrun( self ) ); *framesAvail = 0; } else { if( 0 != *framesAvail ) { /* If we're reporting frames eligible for processing, one of the handles better be ready */ PA_UNLESS( self->capture.ready || self->playback.ready, paInternalError ); } } *xrunOccurred = xrun; return result; } /** Register per-channel ALSA buffer information with buffer processor. * * Mmapped buffer space is acquired from ALSA, and registered with the buffer processor. Differences between the * number of host and user channels is taken into account. * * @param numFrames On entrance the number of requested frames, on exit the number of contiguously accessible frames. */ static PaError PaAlsaStreamComponent_RegisterChannels( PaAlsaStreamComponent* self, PaUtilBufferProcessor* bp, unsigned long* numFrames, int* xrun ) { PaError result = paNoError; const snd_pcm_channel_area_t *areas, *area; void (*setChannel)(PaUtilBufferProcessor *, unsigned int, void *, unsigned int) = StreamDirection_In == self->streamDir ? PaUtil_SetInputChannel : PaUtil_SetOutputChannel; unsigned char *buffer, *p; int i; unsigned long framesAvail; /* This _must_ be called before mmap_begin */ PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( self, &framesAvail, xrun ) ); if( *xrun ) { *numFrames = 0; goto end; } if( self->canMmap ) { ENSURE_( alsa_snd_pcm_mmap_begin( self->pcm, &areas, &self->offset, numFrames ), paUnanticipatedHostError ); /* @concern ChannelAdaption Buffer address is recorded so we can do some channel adaption later */ self->channelAreas = (snd_pcm_channel_area_t *)areas; } else { unsigned int bufferSize = self->numHostChannels * alsa_snd_pcm_format_size( self->nativeFormat, *numFrames ); if( bufferSize > self->nonMmapBufferSize ) { self->nonMmapBuffer = realloc( self->nonMmapBuffer, ( self->nonMmapBufferSize = bufferSize ) ); if( !self->nonMmapBuffer ) { result = paInsufficientMemory; goto error; } } } if( self->hostInterleaved ) { int swidth = alsa_snd_pcm_format_size( self->nativeFormat, 1 ); p = buffer = self->canMmap ? ExtractAddress( areas, self->offset ) : self->nonMmapBuffer; for( i = 0; i < self->numUserChannels; ++i ) { /* We're setting the channels up to userChannels, but the stride will be hostChannels samples */ setChannel( bp, i, p, self->numHostChannels ); p += swidth; } } else { if( self->canMmap ) { for( i = 0; i < self->numUserChannels; ++i ) { area = areas + i; buffer = ExtractAddress( area, self->offset ); setChannel( bp, i, buffer, 1 ); } } else { unsigned int buf_per_ch_size = self->nonMmapBufferSize / self->numHostChannels; buffer = self->nonMmapBuffer; for( i = 0; i < self->numUserChannels; ++i ) { setChannel( bp, i, buffer, 1 ); buffer += buf_per_ch_size; } } } if( !self->canMmap && StreamDirection_In == self->streamDir ) { /* Read sound */ int res; if( self->hostInterleaved ) res = alsa_snd_pcm_readi( self->pcm, self->nonMmapBuffer, *numFrames ); else { void *bufs[self->numHostChannels]; unsigned int buf_per_ch_size = self->nonMmapBufferSize / self->numHostChannels; unsigned char *buffer = self->nonMmapBuffer; int i; for( i = 0; i < self->numHostChannels; ++i ) { bufs[i] = buffer; buffer += buf_per_ch_size; } res = alsa_snd_pcm_readn( self->pcm, bufs, *numFrames ); } if( res == -EPIPE || res == -ESTRPIPE ) { *xrun = 1; *numFrames = 0; } } end: error: return result; } /** Initiate buffer processing. * * ALSA buffers are registered with the PA buffer processor and the buffer size (in frames) set. * * @concern FullDuplex If both directions are being processed, the minimum amount of frames for the two directions is * calculated. * * @param numFrames On entrance the number of available frames, on exit the number of received frames * @param xrunOccurred Return whether an xrun has occurred */ static PaError PaAlsaStream_SetUpBuffers( PaAlsaStream* self, unsigned long* numFrames, int* xrunOccurred ) { PaError result = paNoError; unsigned long captureFrames = ULONG_MAX, playbackFrames = ULONG_MAX, commonFrames = 0; int xrun = 0; if( *xrunOccurred ) { *numFrames = 0; return result; } /* If we got here at least one of the pcm's should be marked ready */ PA_UNLESS( self->capture.ready || self->playback.ready, paInternalError ); /* Extract per-channel ALSA buffer pointers and register them with the buffer processor. * It is possible that a direction is not marked ready however, because it is out of sync with the other. */ if( self->capture.pcm && self->capture.ready ) { captureFrames = *numFrames; PA_ENSURE( PaAlsaStreamComponent_RegisterChannels( &self->capture, &self->bufferProcessor, &captureFrames, &xrun ) ); } if( self->playback.pcm && self->playback.ready ) { playbackFrames = *numFrames; PA_ENSURE( PaAlsaStreamComponent_RegisterChannels( &self->playback, &self->bufferProcessor, &playbackFrames, &xrun ) ); } if( xrun ) { /* Nothing more to do */ assert( 0 == commonFrames ); goto end; } commonFrames = PA_MIN( captureFrames, playbackFrames ); /* assert( commonFrames <= *numFrames ); */ if( commonFrames > *numFrames ) { /* Hmmm ... how come there are more frames available than we requested!? Blah. */ PA_DEBUG(( "%s: Common available frames are reported to be more than number requested: %lu, %lu, callbackMode: %d\n", __FUNCTION__, commonFrames, *numFrames, self->callbackMode )); if( self->capture.pcm ) { PA_DEBUG(( "%s: captureFrames: %lu, capture.ready: %d\n", __FUNCTION__, captureFrames, self->capture.ready )); } if( self->playback.pcm ) { PA_DEBUG(( "%s: playbackFrames: %lu, playback.ready: %d\n", __FUNCTION__, playbackFrames, self->playback.ready )); } commonFrames = 0; goto end; } /* Inform PortAudio of the number of frames we got. * @concern FullDuplex We might be experiencing underflow in either end; if its an input underflow, we go on * with output. If its output underflow however, depending on the paNeverDropInput flag, we may want to simply * discard the excess input or call the callback with paOutputOverflow flagged. */ if( self->capture.pcm ) { if( self->capture.ready ) { PaUtil_SetInputFrameCount( &self->bufferProcessor, commonFrames ); } else { /* We have input underflow */ PaUtil_SetNoInput( &self->bufferProcessor ); } } if( self->playback.pcm ) { if( self->playback.ready ) { PaUtil_SetOutputFrameCount( &self->bufferProcessor, commonFrames ); } else { /* We have output underflow, but keeping input data (paNeverDropInput) */ assert( self->neverDropInput ); assert( self->capture.pcm != NULL ); PA_DEBUG(( "%s: Setting output buffers to NULL\n", __FUNCTION__ )); PaUtil_SetNoOutput( &self->bufferProcessor ); } } end: *numFrames = commonFrames; error: if( xrun ) { PA_ENSURE( PaAlsaStream_HandleXrun( self ) ); *numFrames = 0; } *xrunOccurred = xrun; return result; } /** Callback thread's function. * * Roughly, the workflow can be described in the following way: The number of available frames that can be processed * directly is obtained from ALSA, we then request as much directly accessible memory as possible within this amount * from ALSA. The buffer memory is registered with the PA buffer processor and processing is carried out with * PaUtil_EndBufferProcessing. Finally, the number of processed frames is reported to ALSA. The processing can * happen in several iterations untill we have consumed the known number of available frames (or an xrun is detected). */ static void *CallbackThreadFunc( void *userData ) { PaError result = paNoError; PaAlsaStream *stream = (PaAlsaStream*) userData; PaStreamCallbackTimeInfo timeInfo = {0, 0, 0}; snd_pcm_sframes_t startThreshold = 0; int callbackResult = paContinue; PaStreamCallbackFlags cbFlags = 0; /* We might want to keep state across iterations */ int streamStarted = 0; assert( stream ); /* Execute OnExit when exiting */ pthread_cleanup_push( &OnExit, stream ); /* Not implemented */ assert( !stream->primeBuffers ); /* @concern StreamStart If the output is being primed the output pcm needs to be prepared, otherwise the * stream is started immediately. The latter involves signaling the waiting main thread. */ if( stream->primeBuffers ) { snd_pcm_sframes_t avail; if( stream->playback.pcm ) ENSURE_( alsa_snd_pcm_prepare( stream->playback.pcm ), paUnanticipatedHostError ); if( stream->capture.pcm && !stream->pcmsSynced ) ENSURE_( alsa_snd_pcm_prepare( stream->capture.pcm ), paUnanticipatedHostError ); /* We can't be certain that the whole ring buffer is available for priming, but there should be * at least one period */ avail = alsa_snd_pcm_avail_update( stream->playback.pcm ); startThreshold = avail - (avail % stream->playback.framesPerBuffer); assert( startThreshold >= stream->playback.framesPerBuffer ); } else { PA_ENSURE( PaUnixThread_PrepareNotify( &stream->thread ) ); /* Buffer will be zeroed */ PA_ENSURE( AlsaStart( stream, 0 ) ); PA_ENSURE( PaUnixThread_NotifyParent( &stream->thread ) ); streamStarted = 1; } while( 1 ) { unsigned long framesAvail, framesGot; int xrun = 0; #ifdef PTHREAD_CANCELED pthread_testcancel(); #endif /* @concern StreamStop if the main thread has requested a stop and the stream has not been effectively * stopped we signal this condition by modifying callbackResult (we'll want to flush buffered output). */ if( PaUnixThread_StopRequested( &stream->thread ) && paContinue == callbackResult ) { PA_DEBUG(( "Setting callbackResult to paComplete\n" )); callbackResult = paComplete; } if( paContinue != callbackResult ) { stream->callbackAbort = ( paAbort == callbackResult ); if( stream->callbackAbort || /** @concern BlockAdaption: Go on if adaption buffers are empty */ PaUtil_IsBufferProcessorOutputEmpty( &stream->bufferProcessor ) ) { goto end; } PA_DEBUG(( "%s: Flushing buffer processor\n", __FUNCTION__ )); /* There is still buffered output that needs to be processed */ } /* Wait for data to become available, this comes down to polling the ALSA file descriptors untill we have * a number of available frames. */ PA_ENSURE( PaAlsaStream_WaitForFrames( stream, &framesAvail, &xrun ) ); if( xrun ) { assert( 0 == framesAvail ); continue; /* XXX: Report xruns to the user? A situation is conceivable where the callback is never invoked due * to constant xruns, it might be desirable to notify the user of this. */ } /* Consume buffer space. Once we have a number of frames available for consumption we must retrieve the * mmapped buffers from ALSA, this is contiguously accessible memory however, so we may receive smaller * portions at a time than is available as a whole. Therefore we should be prepared to process several * chunks successively. The buffers are passed to the PA buffer processor. */ while( framesAvail > 0 ) { xrun = 0; #ifdef PTHREAD_CANCELED pthread_testcancel(); #endif /** @concern Xruns Under/overflows are to be reported to the callback */ if( stream->underrun > 0.0 ) { cbFlags |= paOutputUnderflow; stream->underrun = 0.0; } if( stream->overrun > 0.0 ) { cbFlags |= paInputOverflow; stream->overrun = 0.0; } if( stream->capture.pcm && stream->playback.pcm ) { /** @concern FullDuplex It's possible that only one direction is being processed to avoid an * under- or overflow, this should be reported correspondingly */ if( !stream->capture.ready ) { cbFlags |= paInputUnderflow; PA_DEBUG(( "%s: Input underflow\n", __FUNCTION__ )); } else if( !stream->playback.ready ) { cbFlags |= paOutputOverflow; PA_DEBUG(( "%s: Output overflow\n", __FUNCTION__ )); } } #if 0 CallbackUpdate( &stream->threading ); #endif CalculateTimeInfo( stream, &timeInfo ); PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, cbFlags ); cbFlags = 0; /* CPU load measurement should include processing activivity external to the stream callback */ PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer ); framesGot = framesAvail; if( paUtilFixedHostBufferSize == stream->bufferProcessor.hostBufferSizeMode ) { /* We've committed to a fixed host buffer size, stick to that */ framesGot = framesGot >= stream->maxFramesPerHostBuffer ? stream->maxFramesPerHostBuffer : 0; } else { /* We've committed to an upper bound on the size of host buffers */ assert( paUtilBoundedHostBufferSize == stream->bufferProcessor.hostBufferSizeMode ); framesGot = PA_MIN( framesGot, stream->maxFramesPerHostBuffer ); } PA_ENSURE( PaAlsaStream_SetUpBuffers( stream, &framesGot, &xrun ) ); /* Check the host buffer size against the buffer processor configuration */ framesAvail -= framesGot; if( framesGot > 0 ) { assert( !xrun ); PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult ); PA_ENSURE( PaAlsaStream_EndProcessing( stream, framesGot, &xrun ) ); } PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesGot ); if( 0 == framesGot ) { /* Go back to polling for more frames */ break; } if( paContinue != callbackResult ) break; } } end: ; /* Hack to fix "label at end of compound statement" error caused by pthread_cleanup_pop(1) macro. */ /* Match pthread_cleanup_push */ pthread_cleanup_pop( 1 ); PA_DEBUG(( "%s: Thread %d exiting\n ", __FUNCTION__, pthread_self() )); PaUnixThreading_EXIT( result ); error: PA_DEBUG(( "%s: Thread %d is canceled due to error %d\n ", __FUNCTION__, pthread_self(), result )); goto end; } /* Blocking interface */ static PaError ReadStream( PaStream* s, void *buffer, unsigned long frames ) { PaError result = paNoError; PaAlsaStream *stream = (PaAlsaStream*)s; unsigned long framesGot, framesAvail; void *userBuffer; snd_pcm_t *save = stream->playback.pcm; assert( stream ); PA_UNLESS( stream->capture.pcm, paCanNotReadFromAnOutputOnlyStream ); /* Disregard playback */ stream->playback.pcm = NULL; if( stream->overrun > 0. ) { result = paInputOverflowed; stream->overrun = 0.0; } if( stream->capture.userInterleaved ) { userBuffer = buffer; } else { /* Copy channels into local array */ userBuffer = stream->capture.userBuffers; memcpy( userBuffer, buffer, sizeof (void *) * stream->capture.numUserChannels ); } /* Start stream if in prepared state */ if( alsa_snd_pcm_state( stream->capture.pcm ) == SND_PCM_STATE_PREPARED ) { ENSURE_( alsa_snd_pcm_start( stream->capture.pcm ), paUnanticipatedHostError ); } while( frames > 0 ) { int xrun = 0; PA_ENSURE( PaAlsaStream_WaitForFrames( stream, &framesAvail, &xrun ) ); framesGot = PA_MIN( framesAvail, frames ); PA_ENSURE( PaAlsaStream_SetUpBuffers( stream, &framesGot, &xrun ) ); if( framesGot > 0 ) { framesGot = PaUtil_CopyInput( &stream->bufferProcessor, &userBuffer, framesGot ); PA_ENSURE( PaAlsaStream_EndProcessing( stream, framesGot, &xrun ) ); frames -= framesGot; } } end: stream->playback.pcm = save; return result; error: goto end; } static PaError WriteStream( PaStream* s, const void *buffer, unsigned long frames ) { PaError result = paNoError; signed long err; PaAlsaStream *stream = (PaAlsaStream*)s; snd_pcm_uframes_t framesGot, framesAvail; const void *userBuffer; snd_pcm_t *save = stream->capture.pcm; assert( stream ); PA_UNLESS( stream->playback.pcm, paCanNotWriteToAnInputOnlyStream ); /* Disregard capture */ stream->capture.pcm = NULL; if( stream->underrun > 0. ) { result = paOutputUnderflowed; stream->underrun = 0.0; } if( stream->playback.userInterleaved ) userBuffer = buffer; else /* Copy channels into local array */ { userBuffer = stream->playback.userBuffers; memcpy( (void *)userBuffer, buffer, sizeof (void *) * stream->playback.numUserChannels ); } while( frames > 0 ) { int xrun = 0; snd_pcm_uframes_t hwAvail; PA_ENSURE( PaAlsaStream_WaitForFrames( stream, &framesAvail, &xrun ) ); framesGot = PA_MIN( framesAvail, frames ); PA_ENSURE( PaAlsaStream_SetUpBuffers( stream, &framesGot, &xrun ) ); if( framesGot > 0 ) { framesGot = PaUtil_CopyOutput( &stream->bufferProcessor, &userBuffer, framesGot ); PA_ENSURE( PaAlsaStream_EndProcessing( stream, framesGot, &xrun ) ); frames -= framesGot; } /* Start stream after one period of samples worth */ /* Frames residing in buffer */ PA_ENSURE( err = GetStreamWriteAvailable( stream ) ); framesAvail = err; hwAvail = stream->playback.bufferSize - framesAvail; if( alsa_snd_pcm_state( stream->playback.pcm ) == SND_PCM_STATE_PREPARED && hwAvail >= stream->playback.framesPerBuffer ) { ENSURE_( alsa_snd_pcm_start( stream->playback.pcm ), paUnanticipatedHostError ); } } end: stream->capture.pcm = save; return result; error: goto end; } /* Return frames available for reading. In the event of an overflow, the capture pcm will be restarted */ static signed long GetStreamReadAvailable( PaStream* s ) { PaError result = paNoError; PaAlsaStream *stream = (PaAlsaStream*)s; unsigned long avail; int xrun; PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( &stream->capture, &avail, &xrun ) ); if( xrun ) { PA_ENSURE( PaAlsaStream_HandleXrun( stream ) ); PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( &stream->capture, &avail, &xrun ) ); if( xrun ) PA_ENSURE( paInputOverflowed ); } return (signed long)avail; error: return result; } static signed long GetStreamWriteAvailable( PaStream* s ) { PaError result = paNoError; PaAlsaStream *stream = (PaAlsaStream*)s; unsigned long avail; int xrun; PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( &stream->playback, &avail, &xrun ) ); if( xrun ) { snd_pcm_sframes_t savail; PA_ENSURE( PaAlsaStream_HandleXrun( stream ) ); savail = alsa_snd_pcm_avail_update( stream->playback.pcm ); /* savail should not contain -EPIPE now, since PaAlsaStream_HandleXrun will only prepare the pcm */ ENSURE_( savail, paUnanticipatedHostError ); avail = (unsigned long) savail; } return (signed long)avail; error: return result; } /* Extensions */ void PaAlsa_InitializeStreamInfo( PaAlsaStreamInfo *info ) { info->size = sizeof (PaAlsaStreamInfo); info->hostApiType = paALSA; info->version = 1; info->deviceString = NULL; } void PaAlsa_EnableRealtimeScheduling( PaStream *s, int enable ) { PaAlsaStream *stream = (PaAlsaStream *) s; stream->rtSched = enable; } #if 0 void PaAlsa_EnableWatchdog( PaStream *s, int enable ) { PaAlsaStream *stream = (PaAlsaStream *) s; stream->thread.useWatchdog = enable; } #endif static PaError GetAlsaStreamPointer( PaStream* s, PaAlsaStream** stream ) { PaError result = paNoError; PaUtilHostApiRepresentation* hostApi; PaAlsaHostApiRepresentation* alsaHostApi; PA_ENSURE( PaUtil_ValidateStreamPointer( s ) ); PA_ENSURE( PaUtil_GetHostApiRepresentation( &hostApi, paALSA ) ); alsaHostApi = (PaAlsaHostApiRepresentation*)hostApi; PA_UNLESS( PA_STREAM_REP( s )->streamInterface == &alsaHostApi->callbackStreamInterface || PA_STREAM_REP( s )->streamInterface == &alsaHostApi->blockingStreamInterface, paIncompatibleStreamHostApi ); *stream = (PaAlsaStream*)s; error: return paNoError; } PaError PaAlsa_GetStreamInputCard( PaStream* s, int* card ) { PaAlsaStream *stream; PaError result = paNoError; snd_pcm_info_t* pcmInfo; PA_ENSURE( GetAlsaStreamPointer( s, &stream ) ); /* XXX: More descriptive error? */ PA_UNLESS( stream->capture.pcm, paDeviceUnavailable ); alsa_snd_pcm_info_alloca( &pcmInfo ); PA_ENSURE( alsa_snd_pcm_info( stream->capture.pcm, pcmInfo ) ); *card = alsa_snd_pcm_info_get_card( pcmInfo ); error: return result; } PaError PaAlsa_GetStreamOutputCard( PaStream* s, int* card ) { PaAlsaStream *stream; PaError result = paNoError; snd_pcm_info_t* pcmInfo; PA_ENSURE( GetAlsaStreamPointer( s, &stream ) ); /* XXX: More descriptive error? */ PA_UNLESS( stream->playback.pcm, paDeviceUnavailable ); alsa_snd_pcm_info_alloca( &pcmInfo ); PA_ENSURE( alsa_snd_pcm_info( stream->playback.pcm, pcmInfo ) ); *card = alsa_snd_pcm_info_get_card( pcmInfo ); error: return result; } PaError PaAlsa_SetRetriesBusy( int retries ) { busyRetries_ = retries; return paNoError; } pd-0.46-7/portaudio/src/hostapi/asio/0000775000175000017500000000000012374245151015577 5ustar mspmsppd-0.46-7/portaudio/src/hostapi/asio/iasiothiscallresolver.cpp0000664000175000017500000005666312222201037022720 0ustar mspmsp/* IASIOThiscallResolver.cpp see the comments in iasiothiscallresolver.h for the top level description - this comment describes the technical details of the implementation. The latest version of this file is available from: http://www.audiomulch.com/~rossb/code/calliasio please email comments to Ross Bencina BACKGROUND The IASIO interface declared in the Steinberg ASIO 2 SDK declares functions with no explicit calling convention. This causes MSVC++ to default to using the thiscall convention, which is a proprietary convention not implemented by some non-microsoft compilers - notably borland BCC, C++Builder, and gcc. MSVC++ is the defacto standard compiler used by Steinberg. As a result of this situation, the ASIO sdk will compile with any compiler, however attempting to execute the compiled code will cause a crash due to different default calling conventions on non-Microsoft compilers. IASIOThiscallResolver solves the problem by providing an adapter class that delegates to the IASIO interface using the correct calling convention (thiscall). Due to the lack of support for thiscall in the Borland and GCC compilers, the calls have been implemented in assembly language. A number of macros are defined for thiscall function calls with different numbers of parameters, with and without return values - it may be possible to modify the format of these macros to make them work with other inline assemblers. THISCALL DEFINITION A number of definitions of the thiscall calling convention are floating around the internet. The following definition has been validated against output from the MSVC++ compiler: For non-vararg functions, thiscall works as follows: the object (this) pointer is passed in ECX. All arguments are passed on the stack in right to left order. The return value is placed in EAX. The callee clears the passed arguments from the stack. FINDING FUNCTION POINTERS FROM AN IASIO POINTER The first field of a COM object is a pointer to its vtble. Thus a pointer to an object implementing the IASIO interface also points to a pointer to that object's vtbl. The vtble is a table of function pointers for all of the virtual functions exposed by the implemented interfaces. If we consider a variable declared as a pointer to IASO: IASIO *theAsioDriver theAsioDriver points to: object implementing IASIO { IASIOvtbl *vtbl other data } in other words, theAsioDriver points to a pointer to an IASIOvtbl vtbl points to a table of function pointers: IASIOvtbl ( interface IASIO : public IUnknown ) { (IUnknown functions) 0 virtual HRESULT STDMETHODCALLTYPE (*QueryInterface)(REFIID riid, void **ppv) = 0; 4 virtual ULONG STDMETHODCALLTYPE (*AddRef)() = 0; 8 virtual ULONG STDMETHODCALLTYPE (*Release)() = 0; (IASIO functions) 12 virtual ASIOBool (*init)(void *sysHandle) = 0; 16 virtual void (*getDriverName)(char *name) = 0; 20 virtual long (*getDriverVersion)() = 0; 24 virtual void (*getErrorMessage)(char *string) = 0; 28 virtual ASIOError (*start)() = 0; 32 virtual ASIOError (*stop)() = 0; 36 virtual ASIOError (*getChannels)(long *numInputChannels, long *numOutputChannels) = 0; 40 virtual ASIOError (*getLatencies)(long *inputLatency, long *outputLatency) = 0; 44 virtual ASIOError (*getBufferSize)(long *minSize, long *maxSize, long *preferredSize, long *granularity) = 0; 48 virtual ASIOError (*canSampleRate)(ASIOSampleRate sampleRate) = 0; 52 virtual ASIOError (*getSampleRate)(ASIOSampleRate *sampleRate) = 0; 56 virtual ASIOError (*setSampleRate)(ASIOSampleRate sampleRate) = 0; 60 virtual ASIOError (*getClockSources)(ASIOClockSource *clocks, long *numSources) = 0; 64 virtual ASIOError (*setClockSource)(long reference) = 0; 68 virtual ASIOError (*getSamplePosition)(ASIOSamples *sPos, ASIOTimeStamp *tStamp) = 0; 72 virtual ASIOError (*getChannelInfo)(ASIOChannelInfo *info) = 0; 76 virtual ASIOError (*createBuffers)(ASIOBufferInfo *bufferInfos, long numChannels, long bufferSize, ASIOCallbacks *callbacks) = 0; 80 virtual ASIOError (*disposeBuffers)() = 0; 84 virtual ASIOError (*controlPanel)() = 0; 88 virtual ASIOError (*future)(long selector,void *opt) = 0; 92 virtual ASIOError (*outputReady)() = 0; }; The numbers in the left column show the byte offset of each function ptr from the beginning of the vtbl. These numbers are used in the code below to select different functions. In order to find the address of a particular function, theAsioDriver must first be dereferenced to find the value of the vtbl pointer: mov eax, theAsioDriver mov edx, [theAsioDriver] // edx now points to vtbl[0] Then an offset must be added to the vtbl pointer to select a particular function, for example vtbl+44 points to the slot containing a pointer to the getBufferSize function. Finally vtbl+x must be dereferenced to obtain the value of the function pointer stored in that address: call [edx+44] // call the function pointed to by // the value in the getBufferSize field of the vtbl SEE ALSO Martin Fay's OpenASIO DLL at http://www.martinfay.com solves the same problem by providing a new COM interface which wraps IASIO with an interface that uses portable calling conventions. OpenASIO must be compiled with MSVC, and requires that you ship the OpenASIO DLL with your application. ACKNOWLEDGEMENTS Ross Bencina: worked out the thiscall details above, wrote the original Borland asm macros, and a patch for asio.cpp (which is no longer needed). Thanks to Martin Fay for introducing me to the issues discussed here, and to Rene G. Ceballos for assisting with asm dumps from MSVC++. Antti Silvast: converted the original calliasio to work with gcc and NASM by implementing the asm code in a separate file. Fraser Adams: modified the original calliasio containing the Borland inline asm to add inline asm for gcc i.e. Intel syntax for Borland and AT&T syntax for gcc. This seems a neater approach for gcc than to have a separate .asm file and it means that we only need one version of the thiscall patch. Fraser Adams: rewrote the original calliasio patch in the form of the IASIOThiscallResolver class in order to avoid modifications to files from the Steinberg SDK, which may have had potential licence issues. Andrew Baldwin: contributed fixes for compatibility problems with more recent versions of the gcc assembler. */ // We only need IASIOThiscallResolver at all if we are on Win32. For other // platforms we simply bypass the IASIOThiscallResolver definition to allow us // to be safely #include'd whatever the platform to keep client code portable #if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) && !defined(_WIN64) // If microsoft compiler we can call IASIO directly so IASIOThiscallResolver // is not used. #if !defined(_MSC_VER) #include #include // We have a mechanism in iasiothiscallresolver.h to ensure that asio.h is // #include'd before it in client code, we do NOT want to do this test here. #define iasiothiscallresolver_sourcefile 1 #include "iasiothiscallresolver.h" #undef iasiothiscallresolver_sourcefile // iasiothiscallresolver.h redefines ASIOInit for clients, but we don't want // this macro defined in this translation unit. #undef ASIOInit // theAsioDriver is a global pointer to the current IASIO instance which the // ASIO SDK uses to perform all actions on the IASIO interface. We substitute // our own forwarding interface into this pointer. extern IASIO* theAsioDriver; // The following macros define the inline assembler for BORLAND first then gcc #if defined(__BCPLUSPLUS__) || defined(__BORLANDC__) #define CALL_THISCALL_0( resultName, thisPtr, funcOffset )\ void *this_ = (thisPtr); \ __asm { \ mov ecx, this_ ; \ mov eax, [ecx] ; \ call [eax+funcOffset] ; \ mov resultName, eax ; \ } #define CALL_VOID_THISCALL_1( thisPtr, funcOffset, param1 )\ void *this_ = (thisPtr); \ __asm { \ mov eax, param1 ; \ push eax ; \ mov ecx, this_ ; \ mov eax, [ecx] ; \ call [eax+funcOffset] ; \ } #define CALL_THISCALL_1( resultName, thisPtr, funcOffset, param1 )\ void *this_ = (thisPtr); \ __asm { \ mov eax, param1 ; \ push eax ; \ mov ecx, this_ ; \ mov eax, [ecx] ; \ call [eax+funcOffset] ; \ mov resultName, eax ; \ } #define CALL_THISCALL_1_DOUBLE( resultName, thisPtr, funcOffset, param1 )\ void *this_ = (thisPtr); \ void *doubleParamPtr_ (¶m1); \ __asm { \ mov eax, doubleParamPtr_ ; \ push [eax+4] ; \ push [eax] ; \ mov ecx, this_ ; \ mov eax, [ecx] ; \ call [eax+funcOffset] ; \ mov resultName, eax ; \ } #define CALL_THISCALL_2( resultName, thisPtr, funcOffset, param1, param2 )\ void *this_ = (thisPtr); \ __asm { \ mov eax, param2 ; \ push eax ; \ mov eax, param1 ; \ push eax ; \ mov ecx, this_ ; \ mov eax, [ecx] ; \ call [eax+funcOffset] ; \ mov resultName, eax ; \ } #define CALL_THISCALL_4( resultName, thisPtr, funcOffset, param1, param2, param3, param4 )\ void *this_ = (thisPtr); \ __asm { \ mov eax, param4 ; \ push eax ; \ mov eax, param3 ; \ push eax ; \ mov eax, param2 ; \ push eax ; \ mov eax, param1 ; \ push eax ; \ mov ecx, this_ ; \ mov eax, [ecx] ; \ call [eax+funcOffset] ; \ mov resultName, eax ; \ } #elif defined(__GNUC__) #define CALL_THISCALL_0( resultName, thisPtr, funcOffset ) \ __asm__ __volatile__ ("movl (%1), %%edx\n\t" \ "call *"#funcOffset"(%%edx)\n\t" \ :"=a"(resultName) /* Output Operands */ \ :"c"(thisPtr) /* Input Operands */ \ : "%edx" /* Clobbered Registers */ \ ); \ #define CALL_VOID_THISCALL_1( thisPtr, funcOffset, param1 ) \ __asm__ __volatile__ ("pushl %0\n\t" \ "movl (%1), %%edx\n\t" \ "call *"#funcOffset"(%%edx)\n\t" \ : /* Output Operands */ \ :"r"(param1), /* Input Operands */ \ "c"(thisPtr) \ : "%edx" /* Clobbered Registers */ \ ); \ #define CALL_THISCALL_1( resultName, thisPtr, funcOffset, param1 ) \ __asm__ __volatile__ ("pushl %1\n\t" \ "movl (%2), %%edx\n\t" \ "call *"#funcOffset"(%%edx)\n\t" \ :"=a"(resultName) /* Output Operands */ \ :"r"(param1), /* Input Operands */ \ "c"(thisPtr) \ : "%edx" /* Clobbered Registers */ \ ); \ #define CALL_THISCALL_1_DOUBLE( resultName, thisPtr, funcOffset, param1 ) \ do { \ double param1f64 = param1; /* Cast explicitly to double */ \ double *param1f64Ptr = ¶m1f64; /* Make pointer to address */ \ __asm__ __volatile__ ("pushl 4(%1)\n\t" \ "pushl (%1)\n\t" \ "movl (%2), %%edx\n\t" \ "call *"#funcOffset"(%%edx);\n\t" \ : "=a"(resultName) /* Output Operands */ \ : "r"(param1f64Ptr), /* Input Operands */ \ "c"(thisPtr), \ "m"(*param1f64Ptr) /* Using address */ \ : "%edx" /* Clobbered Registers */ \ ); \ } while (0); \ #define CALL_THISCALL_2( resultName, thisPtr, funcOffset, param1, param2 ) \ __asm__ __volatile__ ("pushl %1\n\t" \ "pushl %2\n\t" \ "movl (%3), %%edx\n\t" \ "call *"#funcOffset"(%%edx)\n\t" \ :"=a"(resultName) /* Output Operands */ \ :"r"(param2), /* Input Operands */ \ "r"(param1), \ "c"(thisPtr) \ : "%edx" /* Clobbered Registers */ \ ); \ #define CALL_THISCALL_4( resultName, thisPtr, funcOffset, param1, param2, param3, param4 )\ __asm__ __volatile__ ("pushl %1\n\t" \ "pushl %2\n\t" \ "pushl %3\n\t" \ "pushl %4\n\t" \ "movl (%5), %%edx\n\t" \ "call *"#funcOffset"(%%edx)\n\t" \ :"=a"(resultName) /* Output Operands */ \ :"r"(param4), /* Input Operands */ \ "r"(param3), \ "r"(param2), \ "r"(param1), \ "c"(thisPtr) \ : "%edx" /* Clobbered Registers */ \ ); \ #endif // Our static singleton instance. IASIOThiscallResolver IASIOThiscallResolver::instance; // Constructor called to initialize static Singleton instance above. Note that // it is important not to clear that_ incase it has already been set by the call // to placement new in ASIOInit(). IASIOThiscallResolver::IASIOThiscallResolver() { } // Constructor called from ASIOInit() below IASIOThiscallResolver::IASIOThiscallResolver(IASIO* that) : that_( that ) { } // Implement IUnknown methods as assert(false). IASIOThiscallResolver is not // really a COM object, just a wrapper which will work with the ASIO SDK. // If you wanted to use ASIO without the SDK you might want to implement COM // aggregation in these methods. HRESULT STDMETHODCALLTYPE IASIOThiscallResolver::QueryInterface(REFIID riid, void **ppv) { (void)riid; // suppress unused variable warning assert( false ); // this function should never be called by the ASIO SDK. *ppv = NULL; return E_NOINTERFACE; } ULONG STDMETHODCALLTYPE IASIOThiscallResolver::AddRef() { assert( false ); // this function should never be called by the ASIO SDK. return 1; } ULONG STDMETHODCALLTYPE IASIOThiscallResolver::Release() { assert( false ); // this function should never be called by the ASIO SDK. return 1; } // Implement the IASIO interface methods by performing the vptr manipulation // described above then delegating to the real implementation. ASIOBool IASIOThiscallResolver::init(void *sysHandle) { ASIOBool result; CALL_THISCALL_1( result, that_, 12, sysHandle ); return result; } void IASIOThiscallResolver::getDriverName(char *name) { CALL_VOID_THISCALL_1( that_, 16, name ); } long IASIOThiscallResolver::getDriverVersion() { ASIOBool result; CALL_THISCALL_0( result, that_, 20 ); return result; } void IASIOThiscallResolver::getErrorMessage(char *string) { CALL_VOID_THISCALL_1( that_, 24, string ); } ASIOError IASIOThiscallResolver::start() { ASIOBool result; CALL_THISCALL_0( result, that_, 28 ); return result; } ASIOError IASIOThiscallResolver::stop() { ASIOBool result; CALL_THISCALL_0( result, that_, 32 ); return result; } ASIOError IASIOThiscallResolver::getChannels(long *numInputChannels, long *numOutputChannels) { ASIOBool result; CALL_THISCALL_2( result, that_, 36, numInputChannels, numOutputChannels ); return result; } ASIOError IASIOThiscallResolver::getLatencies(long *inputLatency, long *outputLatency) { ASIOBool result; CALL_THISCALL_2( result, that_, 40, inputLatency, outputLatency ); return result; } ASIOError IASIOThiscallResolver::getBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity) { ASIOBool result; CALL_THISCALL_4( result, that_, 44, minSize, maxSize, preferredSize, granularity ); return result; } ASIOError IASIOThiscallResolver::canSampleRate(ASIOSampleRate sampleRate) { ASIOBool result; CALL_THISCALL_1_DOUBLE( result, that_, 48, sampleRate ); return result; } ASIOError IASIOThiscallResolver::getSampleRate(ASIOSampleRate *sampleRate) { ASIOBool result; CALL_THISCALL_1( result, that_, 52, sampleRate ); return result; } ASIOError IASIOThiscallResolver::setSampleRate(ASIOSampleRate sampleRate) { ASIOBool result; CALL_THISCALL_1_DOUBLE( result, that_, 56, sampleRate ); return result; } ASIOError IASIOThiscallResolver::getClockSources(ASIOClockSource *clocks, long *numSources) { ASIOBool result; CALL_THISCALL_2( result, that_, 60, clocks, numSources ); return result; } ASIOError IASIOThiscallResolver::setClockSource(long reference) { ASIOBool result; CALL_THISCALL_1( result, that_, 64, reference ); return result; } ASIOError IASIOThiscallResolver::getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp) { ASIOBool result; CALL_THISCALL_2( result, that_, 68, sPos, tStamp ); return result; } ASIOError IASIOThiscallResolver::getChannelInfo(ASIOChannelInfo *info) { ASIOBool result; CALL_THISCALL_1( result, that_, 72, info ); return result; } ASIOError IASIOThiscallResolver::createBuffers(ASIOBufferInfo *bufferInfos, long numChannels, long bufferSize, ASIOCallbacks *callbacks) { ASIOBool result; CALL_THISCALL_4( result, that_, 76, bufferInfos, numChannels, bufferSize, callbacks ); return result; } ASIOError IASIOThiscallResolver::disposeBuffers() { ASIOBool result; CALL_THISCALL_0( result, that_, 80 ); return result; } ASIOError IASIOThiscallResolver::controlPanel() { ASIOBool result; CALL_THISCALL_0( result, that_, 84 ); return result; } ASIOError IASIOThiscallResolver::future(long selector,void *opt) { ASIOBool result; CALL_THISCALL_2( result, that_, 88, selector, opt ); return result; } ASIOError IASIOThiscallResolver::outputReady() { ASIOBool result; CALL_THISCALL_0( result, that_, 92 ); return result; } // Implement our substitute ASIOInit() method ASIOError IASIOThiscallResolver::ASIOInit(ASIODriverInfo *info) { // To ensure that our instance's vptr is correctly constructed, even if // ASIOInit is called prior to main(), we explicitly call its constructor // (potentially over the top of an existing instance). Note that this is // pretty ugly, and is only safe because IASIOThiscallResolver has no // destructor and contains no objects with destructors. new((void*)&instance) IASIOThiscallResolver( theAsioDriver ); // Interpose between ASIO client code and the real driver. theAsioDriver = &instance; // Note that we never need to switch theAsioDriver back to point to the // real driver because theAsioDriver is reset to zero in ASIOExit(). // Delegate to the real ASIOInit return ::ASIOInit(info); } #endif /* !defined(_MSC_VER) */ #endif /* Win32 */ pd-0.46-7/portaudio/src/hostapi/asio/pa_asio.cpp0000664000175000017500000047557712374245151017747 0ustar mspmsp/* * $Id: pa_asio.cpp 1890 2013-05-02 01:06:01Z rbencina $ * Portable Audio I/O Library for ASIO Drivers * * Author: Stephane Letz * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 2000-2002 Stephane Letz, Phil Burk, Ross Bencina * Blocking i/o implementation by Sven Fischer, Institute of Hearing * Technology and Audiology (www.hoertechnik-audiologie.de) * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /* Modification History 08-03-01 First version : Stephane Letz 08-06-01 Tweaks for PC, use C++, buffer allocation, Float32 to Int32 conversion : Phil Burk 08-20-01 More conversion, PA_StreamTime, Pa_GetHostError : Stephane Letz 08-21-01 PaUInt8 bug correction, implementation of ASIOSTFloat32LSB and ASIOSTFloat32MSB native formats : Stephane Letz 08-24-01 MAX_INT32_FP hack, another Uint8 fix : Stephane and Phil 08-27-01 Implementation of hostBufferSize < userBufferSize case, better management of the ouput buffer when the stream is stopped : Stephane Letz 08-28-01 Check the stream pointer for null in bufferSwitchTimeInfo, correct bug in bufferSwitchTimeInfo when the stream is stopped : Stephane Letz 10-12-01 Correct the PaHost_CalcNumHostBuffers function: computes FramesPerHostBuffer to be the lowest that respect requested FramesPerUserBuffer and userBuffersPerHostBuffer : Stephane Letz 10-26-01 Management of hostBufferSize and userBufferSize of any size : Stephane Letz 10-27-01 Improve calculus of hostBufferSize to be multiple or divisor of userBufferSize if possible : Stephane and Phil 10-29-01 Change MAX_INT32_FP to (2147483520.0f) to prevent roundup to 0x80000000 : Phil Burk 10-31-01 Clear the ouput buffer and user buffers in PaHost_StartOutput, correct bug in GetFirstMultiple : Stephane Letz 11-06-01 Rename functions : Stephane Letz 11-08-01 New Pa_ASIO_Adaptor_Init function to init Callback adpatation variables, cleanup of Pa_ASIO_Callback_Input: Stephane Letz 11-29-01 Break apart device loading to debug random failure in Pa_ASIO_QueryDeviceInfo ; Phil Burk 01-03-02 Desallocate all resources in PaHost_Term for cases where Pa_CloseStream is not called properly : Stephane Letz 02-01-02 Cleanup, test of multiple-stream opening : Stephane Letz 19-02-02 New Pa_ASIO_loadDriver that calls CoInitialize on each thread on Windows : Stephane Letz 09-04-02 Correct error code management in PaHost_Term, removes various compiler warning : Stephane Letz 12-04-02 Add Mac includes for and : Phil Burk 13-04-02 Removes another compiler warning : Stephane Letz 30-04-02 Pa_ASIO_QueryDeviceInfo bug correction, memory allocation checking, better error handling : D Viens, P Burk, S Letz 12-06-02 Rehashed into new multi-api infrastructure, added support for all ASIO sample formats : Ross Bencina 18-06-02 Added pa_asio.h, PaAsio_GetAvailableLatencyValues() : Ross B. 21-06-02 Added SelectHostBufferSize() which selects host buffer size based on user latency parameters : Ross Bencina ** NOTE maintanance history is now stored in CVS ** */ /** @file @ingroup hostapi_src Note that specific support for paInputUnderflow, paOutputOverflow and paNeverDropInput is not necessary or possible with this driver due to the synchronous full duplex double-buffered architecture of ASIO. */ #include #include #include //#include #include #include #include #include "portaudio.h" #include "pa_asio.h" #include "pa_util.h" #include "pa_allocation.h" #include "pa_hostapi.h" #include "pa_stream.h" #include "pa_cpuload.h" #include "pa_process.h" #include "pa_debugprint.h" #include "pa_ringbuffer.h" #include "pa_win_coinitialize.h" /* This version of pa_asio.cpp is currently only targetted at Win32, It would require a few tweaks to work with pre-OS X Macintosh. To make configuration easier, we define WIN32 here to make sure that the ASIO SDK knows this is Win32. */ #ifndef WIN32 #define WIN32 #endif #include "asiosys.h" #include "asio.h" #include "asiodrivers.h" #include "iasiothiscallresolver.h" /* #if MAC #include #include #include #else */ /* #include #include #include */ /* #endif */ /* winmm.lib is needed for timeGetTime() (this is in winmm.a if you're using gcc) */ #if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) /* MSC version 6 and above */ #pragma comment(lib, "winmm.lib") #endif /* external reference to ASIO SDK's asioDrivers. This is a bit messy because we want to explicitly manage allocation/deallocation of this structure, but some layers of the SDK which we currently use (eg the implementation in asio.cpp) still use this global version. For now we keep it in sync with our local instance in the host API representation structure, but later we should be able to remove all dependence on it. */ extern AsioDrivers* asioDrivers; /* We are trying to be compatible with CARBON but this has not been thoroughly tested. */ /* not tested at all since new V19 code was introduced. */ #define CARBON_COMPATIBLE (0) /* prototypes for functions declared in this file */ extern "C" PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ); static void Terminate( struct PaUtilHostApiRepresentation *hostApi ); static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ); static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ); static PaError CloseStream( PaStream* stream ); static PaError StartStream( PaStream *stream ); static PaError StopStream( PaStream *stream ); static PaError AbortStream( PaStream *stream ); static PaError IsStreamStopped( PaStream *s ); static PaError IsStreamActive( PaStream *stream ); static PaTime GetStreamTime( PaStream *stream ); static double GetStreamCpuLoad( PaStream* stream ); static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames ); static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames ); static signed long GetStreamReadAvailable( PaStream* stream ); static signed long GetStreamWriteAvailable( PaStream* stream ); /* Blocking i/o callback function. */ static int BlockingIoPaCallback(const void *inputBuffer , void *outputBuffer , unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo , PaStreamCallbackFlags statusFlags , void *userData ); /* our ASIO callback functions */ static void bufferSwitch(long index, ASIOBool processNow); static ASIOTime *bufferSwitchTimeInfo(ASIOTime *timeInfo, long index, ASIOBool processNow); static void sampleRateChanged(ASIOSampleRate sRate); static long asioMessages(long selector, long value, void* message, double* opt); static ASIOCallbacks asioCallbacks_ = { bufferSwitch, sampleRateChanged, asioMessages, bufferSwitchTimeInfo }; #define PA_ASIO_SET_LAST_HOST_ERROR( errorCode, errorText ) \ PaUtil_SetLastHostErrorInfo( paASIO, errorCode, errorText ) static void PaAsio_SetLastSystemError( DWORD errorCode ) { LPVOID lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); PaUtil_SetLastHostErrorInfo( paASIO, errorCode, (const char*)lpMsgBuf ); LocalFree( lpMsgBuf ); } #define PA_ASIO_SET_LAST_SYSTEM_ERROR( errorCode ) \ PaAsio_SetLastSystemError( errorCode ) static const char* PaAsio_GetAsioErrorText( ASIOError asioError ) { const char *result; switch( asioError ){ case ASE_OK: case ASE_SUCCESS: result = "Success"; break; case ASE_NotPresent: result = "Hardware input or output is not present or available"; break; case ASE_HWMalfunction: result = "Hardware is malfunctioning"; break; case ASE_InvalidParameter: result = "Input parameter invalid"; break; case ASE_InvalidMode: result = "Hardware is in a bad mode or used in a bad mode"; break; case ASE_SPNotAdvancing: result = "Hardware is not running when sample position is inquired"; break; case ASE_NoClock: result = "Sample clock or rate cannot be determined or is not present"; break; case ASE_NoMemory: result = "Not enough memory for completing the request"; break; default: result = "Unknown ASIO error"; break; } return result; } #define PA_ASIO_SET_LAST_ASIO_ERROR( asioError ) \ PaUtil_SetLastHostErrorInfo( paASIO, asioError, PaAsio_GetAsioErrorText( asioError ) ) // Atomic increment and decrement operations #if MAC /* need to be implemented on Mac */ inline long PaAsio_AtomicIncrement(volatile long* v) {return ++(*const_cast(v));} inline long PaAsio_AtomicDecrement(volatile long* v) {return --(*const_cast(v));} #elif WINDOWS inline long PaAsio_AtomicIncrement(volatile long* v) {return InterlockedIncrement(const_cast(v));} inline long PaAsio_AtomicDecrement(volatile long* v) {return InterlockedDecrement(const_cast(v));} #endif typedef struct PaAsioDriverInfo { ASIODriverInfo asioDriverInfo; long inputChannelCount, outputChannelCount; long bufferMinSize, bufferMaxSize, bufferPreferredSize, bufferGranularity; bool postOutput; } PaAsioDriverInfo; /* PaAsioHostApiRepresentation - host api datastructure specific to this implementation */ typedef struct { PaUtilHostApiRepresentation inheritedHostApiRep; PaUtilStreamInterface callbackStreamInterface; PaUtilStreamInterface blockingStreamInterface; PaUtilAllocationGroup *allocations; PaWinUtilComInitializationResult comInitializationResult; AsioDrivers *asioDrivers; void *systemSpecific; /* the ASIO C API only allows one ASIO driver to be open at a time, so we keep track of whether we have the driver open here, and use this information to return errors from OpenStream if the driver is already open. openAsioDeviceIndex will be PaNoDevice if there is no device open and a valid pa_asio (not global) device index otherwise. openAsioDriverInfo is populated with the driver info for the currently open device (if any) */ PaDeviceIndex openAsioDeviceIndex; PaAsioDriverInfo openAsioDriverInfo; } PaAsioHostApiRepresentation; /* Retrieve driver names from ASIO, returned in a char** allocated in . */ static char **GetAsioDriverNames( PaAsioHostApiRepresentation *asioHostApi, PaUtilAllocationGroup *group, long driverCount ) { char **result = 0; int i; result =(char**)PaUtil_GroupAllocateMemory( group, sizeof(char*) * driverCount ); if( !result ) goto error; result[0] = (char*)PaUtil_GroupAllocateMemory( group, 32 * driverCount ); if( !result[0] ) goto error; for( i=0; iasioDrivers->getDriverNames( result, driverCount ); error: return result; } static PaSampleFormat AsioSampleTypeToPaNativeSampleFormat(ASIOSampleType type) { switch (type) { case ASIOSTInt16MSB: case ASIOSTInt16LSB: return paInt16; case ASIOSTFloat32MSB: case ASIOSTFloat32LSB: case ASIOSTFloat64MSB: case ASIOSTFloat64LSB: return paFloat32; case ASIOSTInt32MSB: case ASIOSTInt32LSB: case ASIOSTInt32MSB16: case ASIOSTInt32LSB16: case ASIOSTInt32MSB18: case ASIOSTInt32MSB20: case ASIOSTInt32MSB24: case ASIOSTInt32LSB18: case ASIOSTInt32LSB20: case ASIOSTInt32LSB24: return paInt32; case ASIOSTInt24MSB: case ASIOSTInt24LSB: return paInt24; default: return paCustomFormat; } } void AsioSampleTypeLOG(ASIOSampleType type) { switch (type) { case ASIOSTInt16MSB: PA_DEBUG(("ASIOSTInt16MSB\n")); break; case ASIOSTInt16LSB: PA_DEBUG(("ASIOSTInt16LSB\n")); break; case ASIOSTFloat32MSB:PA_DEBUG(("ASIOSTFloat32MSB\n"));break; case ASIOSTFloat32LSB:PA_DEBUG(("ASIOSTFloat32LSB\n"));break; case ASIOSTFloat64MSB:PA_DEBUG(("ASIOSTFloat64MSB\n"));break; case ASIOSTFloat64LSB:PA_DEBUG(("ASIOSTFloat64LSB\n"));break; case ASIOSTInt32MSB: PA_DEBUG(("ASIOSTInt32MSB\n")); break; case ASIOSTInt32LSB: PA_DEBUG(("ASIOSTInt32LSB\n")); break; case ASIOSTInt32MSB16:PA_DEBUG(("ASIOSTInt32MSB16\n"));break; case ASIOSTInt32LSB16:PA_DEBUG(("ASIOSTInt32LSB16\n"));break; case ASIOSTInt32MSB18:PA_DEBUG(("ASIOSTInt32MSB18\n"));break; case ASIOSTInt32MSB20:PA_DEBUG(("ASIOSTInt32MSB20\n"));break; case ASIOSTInt32MSB24:PA_DEBUG(("ASIOSTInt32MSB24\n"));break; case ASIOSTInt32LSB18:PA_DEBUG(("ASIOSTInt32LSB18\n"));break; case ASIOSTInt32LSB20:PA_DEBUG(("ASIOSTInt32LSB20\n"));break; case ASIOSTInt32LSB24:PA_DEBUG(("ASIOSTInt32LSB24\n"));break; case ASIOSTInt24MSB: PA_DEBUG(("ASIOSTInt24MSB\n")); break; case ASIOSTInt24LSB: PA_DEBUG(("ASIOSTInt24LSB\n")); break; default: PA_DEBUG(("Custom Format%d\n",type));break; } } static int BytesPerAsioSample( ASIOSampleType sampleType ) { switch (sampleType) { case ASIOSTInt16MSB: case ASIOSTInt16LSB: return 2; case ASIOSTFloat64MSB: case ASIOSTFloat64LSB: return 8; case ASIOSTFloat32MSB: case ASIOSTFloat32LSB: case ASIOSTInt32MSB: case ASIOSTInt32LSB: case ASIOSTInt32MSB16: case ASIOSTInt32LSB16: case ASIOSTInt32MSB18: case ASIOSTInt32MSB20: case ASIOSTInt32MSB24: case ASIOSTInt32LSB18: case ASIOSTInt32LSB20: case ASIOSTInt32LSB24: return 4; case ASIOSTInt24MSB: case ASIOSTInt24LSB: return 3; default: return 0; } } static void Swap16( void *buffer, long shift, long count ) { unsigned short *p = (unsigned short*)buffer; unsigned short temp; (void) shift; /* unused parameter */ while( count-- ) { temp = *p; *p++ = (unsigned short)((temp<<8) | (temp>>8)); } } static void Swap24( void *buffer, long shift, long count ) { unsigned char *p = (unsigned char*)buffer; unsigned char temp; (void) shift; /* unused parameter */ while( count-- ) { temp = *p; *p = *(p+2); *(p+2) = temp; p += 3; } } #define PA_SWAP32_( x ) ((x>>24) | ((x>>8)&0xFF00) | ((x<<8)&0xFF0000) | (x<<24)); static void Swap32( void *buffer, long shift, long count ) { unsigned long *p = (unsigned long*)buffer; unsigned long temp; (void) shift; /* unused parameter */ while( count-- ) { temp = *p; *p++ = PA_SWAP32_( temp); } } static void SwapShiftLeft32( void *buffer, long shift, long count ) { unsigned long *p = (unsigned long*)buffer; unsigned long temp; while( count-- ) { temp = *p; temp = PA_SWAP32_( temp); *p++ = temp << shift; } } static void ShiftRightSwap32( void *buffer, long shift, long count ) { unsigned long *p = (unsigned long*)buffer; unsigned long temp; while( count-- ) { temp = *p >> shift; *p++ = PA_SWAP32_( temp); } } static void ShiftLeft32( void *buffer, long shift, long count ) { unsigned long *p = (unsigned long*)buffer; unsigned long temp; while( count-- ) { temp = *p; *p++ = temp << shift; } } static void ShiftRight32( void *buffer, long shift, long count ) { unsigned long *p = (unsigned long*)buffer; unsigned long temp; while( count-- ) { temp = *p; *p++ = temp >> shift; } } #define PA_SWAP_( x, y ) temp=x; x = y; y = temp; static void Swap64ConvertFloat64ToFloat32( void *buffer, long shift, long count ) { double *in = (double*)buffer; float *out = (float*)buffer; unsigned char *p; unsigned char temp; (void) shift; /* unused parameter */ while( count-- ) { p = (unsigned char*)in; PA_SWAP_( p[0], p[7] ); PA_SWAP_( p[1], p[6] ); PA_SWAP_( p[2], p[5] ); PA_SWAP_( p[3], p[4] ); *out++ = (float) (*in++); } } static void ConvertFloat64ToFloat32( void *buffer, long shift, long count ) { double *in = (double*)buffer; float *out = (float*)buffer; (void) shift; /* unused parameter */ while( count-- ) *out++ = (float) (*in++); } static void ConvertFloat32ToFloat64Swap64( void *buffer, long shift, long count ) { float *in = ((float*)buffer) + (count-1); double *out = ((double*)buffer) + (count-1); unsigned char *p; unsigned char temp; (void) shift; /* unused parameter */ while( count-- ) { *out = *in--; p = (unsigned char*)out; PA_SWAP_( p[0], p[7] ); PA_SWAP_( p[1], p[6] ); PA_SWAP_( p[2], p[5] ); PA_SWAP_( p[3], p[4] ); out--; } } static void ConvertFloat32ToFloat64( void *buffer, long shift, long count ) { float *in = ((float*)buffer) + (count-1); double *out = ((double*)buffer) + (count-1); (void) shift; /* unused parameter */ while( count-- ) *out-- = *in--; } #ifdef MAC #define PA_MSB_IS_NATIVE_ #undef PA_LSB_IS_NATIVE_ #endif #ifdef WINDOWS #undef PA_MSB_IS_NATIVE_ #define PA_LSB_IS_NATIVE_ #endif typedef void PaAsioBufferConverter( void *, long, long ); static void SelectAsioToPaConverter( ASIOSampleType type, PaAsioBufferConverter **converter, long *shift ) { *shift = 0; *converter = 0; switch (type) { case ASIOSTInt16MSB: /* dest: paInt16, no conversion necessary, possible byte swap*/ #ifdef PA_LSB_IS_NATIVE_ *converter = Swap16; #endif break; case ASIOSTInt16LSB: /* dest: paInt16, no conversion necessary, possible byte swap*/ #ifdef PA_MSB_IS_NATIVE_ *converter = Swap16; #endif break; case ASIOSTFloat32MSB: /* dest: paFloat32, no conversion necessary, possible byte swap*/ #ifdef PA_LSB_IS_NATIVE_ *converter = Swap32; #endif break; case ASIOSTFloat32LSB: /* dest: paFloat32, no conversion necessary, possible byte swap*/ #ifdef PA_MSB_IS_NATIVE_ *converter = Swap32; #endif break; case ASIOSTFloat64MSB: /* dest: paFloat32, in-place conversion to/from float32, possible byte swap*/ #ifdef PA_LSB_IS_NATIVE_ *converter = Swap64ConvertFloat64ToFloat32; #else *converter = ConvertFloat64ToFloat32; #endif break; case ASIOSTFloat64LSB: /* dest: paFloat32, in-place conversion to/from float32, possible byte swap*/ #ifdef PA_MSB_IS_NATIVE_ *converter = Swap64ConvertFloat64ToFloat32; #else *converter = ConvertFloat64ToFloat32; #endif break; case ASIOSTInt32MSB: /* dest: paInt32, no conversion necessary, possible byte swap */ #ifdef PA_LSB_IS_NATIVE_ *converter = Swap32; #endif break; case ASIOSTInt32LSB: /* dest: paInt32, no conversion necessary, possible byte swap */ #ifdef PA_MSB_IS_NATIVE_ *converter = Swap32; #endif break; case ASIOSTInt32MSB16: /* dest: paInt32, 16 bit shift, possible byte swap */ #ifdef PA_LSB_IS_NATIVE_ *converter = SwapShiftLeft32; #else *converter = ShiftLeft32; #endif *shift = 16; break; case ASIOSTInt32MSB18: /* dest: paInt32, 14 bit shift, possible byte swap */ #ifdef PA_LSB_IS_NATIVE_ *converter = SwapShiftLeft32; #else *converter = ShiftLeft32; #endif *shift = 14; break; case ASIOSTInt32MSB20: /* dest: paInt32, 12 bit shift, possible byte swap */ #ifdef PA_LSB_IS_NATIVE_ *converter = SwapShiftLeft32; #else *converter = ShiftLeft32; #endif *shift = 12; break; case ASIOSTInt32MSB24: /* dest: paInt32, 8 bit shift, possible byte swap */ #ifdef PA_LSB_IS_NATIVE_ *converter = SwapShiftLeft32; #else *converter = ShiftLeft32; #endif *shift = 8; break; case ASIOSTInt32LSB16: /* dest: paInt32, 16 bit shift, possible byte swap */ #ifdef PA_MSB_IS_NATIVE_ *converter = SwapShiftLeft32; #else *converter = ShiftLeft32; #endif *shift = 16; break; case ASIOSTInt32LSB18: /* dest: paInt32, 14 bit shift, possible byte swap */ #ifdef PA_MSB_IS_NATIVE_ *converter = SwapShiftLeft32; #else *converter = ShiftLeft32; #endif *shift = 14; break; case ASIOSTInt32LSB20: /* dest: paInt32, 12 bit shift, possible byte swap */ #ifdef PA_MSB_IS_NATIVE_ *converter = SwapShiftLeft32; #else *converter = ShiftLeft32; #endif *shift = 12; break; case ASIOSTInt32LSB24: /* dest: paInt32, 8 bit shift, possible byte swap */ #ifdef PA_MSB_IS_NATIVE_ *converter = SwapShiftLeft32; #else *converter = ShiftLeft32; #endif *shift = 8; break; case ASIOSTInt24MSB: /* dest: paInt24, no conversion necessary, possible byte swap */ #ifdef PA_LSB_IS_NATIVE_ *converter = Swap24; #endif break; case ASIOSTInt24LSB: /* dest: paInt24, no conversion necessary, possible byte swap */ #ifdef PA_MSB_IS_NATIVE_ *converter = Swap24; #endif break; } } static void SelectPaToAsioConverter( ASIOSampleType type, PaAsioBufferConverter **converter, long *shift ) { *shift = 0; *converter = 0; switch (type) { case ASIOSTInt16MSB: /* src: paInt16, no conversion necessary, possible byte swap*/ #ifdef PA_LSB_IS_NATIVE_ *converter = Swap16; #endif break; case ASIOSTInt16LSB: /* src: paInt16, no conversion necessary, possible byte swap*/ #ifdef PA_MSB_IS_NATIVE_ *converter = Swap16; #endif break; case ASIOSTFloat32MSB: /* src: paFloat32, no conversion necessary, possible byte swap*/ #ifdef PA_LSB_IS_NATIVE_ *converter = Swap32; #endif break; case ASIOSTFloat32LSB: /* src: paFloat32, no conversion necessary, possible byte swap*/ #ifdef PA_MSB_IS_NATIVE_ *converter = Swap32; #endif break; case ASIOSTFloat64MSB: /* src: paFloat32, in-place conversion to/from float32, possible byte swap*/ #ifdef PA_LSB_IS_NATIVE_ *converter = ConvertFloat32ToFloat64Swap64; #else *converter = ConvertFloat32ToFloat64; #endif break; case ASIOSTFloat64LSB: /* src: paFloat32, in-place conversion to/from float32, possible byte swap*/ #ifdef PA_MSB_IS_NATIVE_ *converter = ConvertFloat32ToFloat64Swap64; #else *converter = ConvertFloat32ToFloat64; #endif break; case ASIOSTInt32MSB: /* src: paInt32, no conversion necessary, possible byte swap */ #ifdef PA_LSB_IS_NATIVE_ *converter = Swap32; #endif break; case ASIOSTInt32LSB: /* src: paInt32, no conversion necessary, possible byte swap */ #ifdef PA_MSB_IS_NATIVE_ *converter = Swap32; #endif break; case ASIOSTInt32MSB16: /* src: paInt32, 16 bit shift, possible byte swap */ #ifdef PA_LSB_IS_NATIVE_ *converter = ShiftRightSwap32; #else *converter = ShiftRight32; #endif *shift = 16; break; case ASIOSTInt32MSB18: /* src: paInt32, 14 bit shift, possible byte swap */ #ifdef PA_LSB_IS_NATIVE_ *converter = ShiftRightSwap32; #else *converter = ShiftRight32; #endif *shift = 14; break; case ASIOSTInt32MSB20: /* src: paInt32, 12 bit shift, possible byte swap */ #ifdef PA_LSB_IS_NATIVE_ *converter = ShiftRightSwap32; #else *converter = ShiftRight32; #endif *shift = 12; break; case ASIOSTInt32MSB24: /* src: paInt32, 8 bit shift, possible byte swap */ #ifdef PA_LSB_IS_NATIVE_ *converter = ShiftRightSwap32; #else *converter = ShiftRight32; #endif *shift = 8; break; case ASIOSTInt32LSB16: /* src: paInt32, 16 bit shift, possible byte swap */ #ifdef PA_MSB_IS_NATIVE_ *converter = ShiftRightSwap32; #else *converter = ShiftRight32; #endif *shift = 16; break; case ASIOSTInt32LSB18: /* src: paInt32, 14 bit shift, possible byte swap */ #ifdef PA_MSB_IS_NATIVE_ *converter = ShiftRightSwap32; #else *converter = ShiftRight32; #endif *shift = 14; break; case ASIOSTInt32LSB20: /* src: paInt32, 12 bit shift, possible byte swap */ #ifdef PA_MSB_IS_NATIVE_ *converter = ShiftRightSwap32; #else *converter = ShiftRight32; #endif *shift = 12; break; case ASIOSTInt32LSB24: /* src: paInt32, 8 bit shift, possible byte swap */ #ifdef PA_MSB_IS_NATIVE_ *converter = ShiftRightSwap32; #else *converter = ShiftRight32; #endif *shift = 8; break; case ASIOSTInt24MSB: /* src: paInt24, no conversion necessary, possible byte swap */ #ifdef PA_LSB_IS_NATIVE_ *converter = Swap24; #endif break; case ASIOSTInt24LSB: /* src: paInt24, no conversion necessary, possible byte swap */ #ifdef PA_MSB_IS_NATIVE_ *converter = Swap24; #endif break; } } typedef struct PaAsioDeviceInfo { PaDeviceInfo commonDeviceInfo; long minBufferSize; long maxBufferSize; long preferredBufferSize; long bufferGranularity; ASIOChannelInfo *asioChannelInfos; } PaAsioDeviceInfo; PaError PaAsio_GetAvailableBufferSizes( PaDeviceIndex device, long *minBufferSizeFrames, long *maxBufferSizeFrames, long *preferredBufferSizeFrames, long *granularity ) { PaError result; PaUtilHostApiRepresentation *hostApi; PaDeviceIndex hostApiDevice; result = PaUtil_GetHostApiRepresentation( &hostApi, paASIO ); if( result == paNoError ) { result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice, device, hostApi ); if( result == paNoError ) { PaAsioDeviceInfo *asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[hostApiDevice]; *minBufferSizeFrames = asioDeviceInfo->minBufferSize; *maxBufferSizeFrames = asioDeviceInfo->maxBufferSize; *preferredBufferSizeFrames = asioDeviceInfo->preferredBufferSize; *granularity = asioDeviceInfo->bufferGranularity; } } return result; } /* Unload whatever we loaded in LoadAsioDriver(). */ static void UnloadAsioDriver( void ) { ASIOExit(); } /* load the asio driver named by and return statistics about the driver in info. If no error occurred, the driver will remain open and must be closed by the called by calling UnloadAsioDriver() - if an error is returned the driver will already be unloaded. */ static PaError LoadAsioDriver( PaAsioHostApiRepresentation *asioHostApi, const char *driverName, PaAsioDriverInfo *driverInfo, void *systemSpecific ) { PaError result = paNoError; ASIOError asioError; int asioIsInitialized = 0; if( !asioHostApi->asioDrivers->loadDriver( const_cast(driverName) ) ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_HOST_ERROR( 0, "Failed to load ASIO driver" ); goto error; } memset( &driverInfo->asioDriverInfo, 0, sizeof(ASIODriverInfo) ); driverInfo->asioDriverInfo.asioVersion = 2; driverInfo->asioDriverInfo.sysRef = systemSpecific; if( (asioError = ASIOInit( &driverInfo->asioDriverInfo )) != ASE_OK ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); goto error; } else { asioIsInitialized = 1; } if( (asioError = ASIOGetChannels(&driverInfo->inputChannelCount, &driverInfo->outputChannelCount)) != ASE_OK ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); goto error; } if( (asioError = ASIOGetBufferSize(&driverInfo->bufferMinSize, &driverInfo->bufferMaxSize, &driverInfo->bufferPreferredSize, &driverInfo->bufferGranularity)) != ASE_OK ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); goto error; } if( ASIOOutputReady() == ASE_OK ) driverInfo->postOutput = true; else driverInfo->postOutput = false; return result; error: if( asioIsInitialized ) { ASIOExit(); } return result; } #define PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_ 13 /* must be the same number of elements as in the array below */ static ASIOSampleRate defaultSampleRateSearchOrder_[] = {44100.0, 48000.0, 32000.0, 24000.0, 22050.0, 88200.0, 96000.0, 192000.0, 16000.0, 12000.0, 11025.0, 9600.0, 8000.0 }; static PaError InitPaDeviceInfoFromAsioDriver( PaAsioHostApiRepresentation *asioHostApi, const char *driverName, int driverIndex, PaDeviceInfo *deviceInfo, PaAsioDeviceInfo *asioDeviceInfo ) { PaError result = paNoError; /* Due to the headless design of the ASIO API, drivers are free to write over data given to them (like M-Audio drivers f.i.). This is an attempt to overcome that. */ union _tag_local { PaAsioDriverInfo info; char _padding[4096]; } paAsioDriver; asioDeviceInfo->asioChannelInfos = 0; /* we check this below to handle error cleanup */ result = LoadAsioDriver( asioHostApi, driverName, &paAsioDriver.info, asioHostApi->systemSpecific ); if( result == paNoError ) { PA_DEBUG(("PaAsio_Initialize: drv:%d name = %s\n", driverIndex,deviceInfo->name)); PA_DEBUG(("PaAsio_Initialize: drv:%d inputChannels = %d\n", driverIndex, paAsioDriver.info.inputChannelCount)); PA_DEBUG(("PaAsio_Initialize: drv:%d outputChannels = %d\n", driverIndex, paAsioDriver.info.outputChannelCount)); PA_DEBUG(("PaAsio_Initialize: drv:%d bufferMinSize = %d\n", driverIndex, paAsioDriver.info.bufferMinSize)); PA_DEBUG(("PaAsio_Initialize: drv:%d bufferMaxSize = %d\n", driverIndex, paAsioDriver.info.bufferMaxSize)); PA_DEBUG(("PaAsio_Initialize: drv:%d bufferPreferredSize = %d\n", driverIndex, paAsioDriver.info.bufferPreferredSize)); PA_DEBUG(("PaAsio_Initialize: drv:%d bufferGranularity = %d\n", driverIndex, paAsioDriver.info.bufferGranularity)); deviceInfo->maxInputChannels = paAsioDriver.info.inputChannelCount; deviceInfo->maxOutputChannels = paAsioDriver.info.outputChannelCount; deviceInfo->defaultSampleRate = 0.; bool foundDefaultSampleRate = false; for( int j=0; j < PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_; ++j ) { ASIOError asioError = ASIOCanSampleRate( defaultSampleRateSearchOrder_[j] ); if( asioError != ASE_NoClock && asioError != ASE_NotPresent ) { deviceInfo->defaultSampleRate = defaultSampleRateSearchOrder_[j]; foundDefaultSampleRate = true; break; } } PA_DEBUG(("PaAsio_Initialize: drv:%d defaultSampleRate = %f\n", driverIndex, deviceInfo->defaultSampleRate)); if( foundDefaultSampleRate ){ /* calculate default latency values from bufferPreferredSize for default low latency, and bufferMaxSize for default high latency. use the default sample rate to convert from samples to seconds. Without knowing what sample rate the user will use this is the best we can do. */ double defaultLowLatency = paAsioDriver.info.bufferPreferredSize / deviceInfo->defaultSampleRate; deviceInfo->defaultLowInputLatency = defaultLowLatency; deviceInfo->defaultLowOutputLatency = defaultLowLatency; double defaultHighLatency = paAsioDriver.info.bufferMaxSize / deviceInfo->defaultSampleRate; if( defaultHighLatency < defaultLowLatency ) defaultHighLatency = defaultLowLatency; /* just in case the driver returns something strange */ deviceInfo->defaultHighInputLatency = defaultHighLatency; deviceInfo->defaultHighOutputLatency = defaultHighLatency; }else{ deviceInfo->defaultLowInputLatency = 0.; deviceInfo->defaultLowOutputLatency = 0.; deviceInfo->defaultHighInputLatency = 0.; deviceInfo->defaultHighOutputLatency = 0.; } PA_DEBUG(("PaAsio_Initialize: drv:%d defaultLowInputLatency = %f\n", driverIndex, deviceInfo->defaultLowInputLatency)); PA_DEBUG(("PaAsio_Initialize: drv:%d defaultLowOutputLatency = %f\n", driverIndex, deviceInfo->defaultLowOutputLatency)); PA_DEBUG(("PaAsio_Initialize: drv:%d defaultHighInputLatency = %f\n", driverIndex, deviceInfo->defaultHighInputLatency)); PA_DEBUG(("PaAsio_Initialize: drv:%d defaultHighOutputLatency = %f\n", driverIndex, deviceInfo->defaultHighOutputLatency)); asioDeviceInfo->minBufferSize = paAsioDriver.info.bufferMinSize; asioDeviceInfo->maxBufferSize = paAsioDriver.info.bufferMaxSize; asioDeviceInfo->preferredBufferSize = paAsioDriver.info.bufferPreferredSize; asioDeviceInfo->bufferGranularity = paAsioDriver.info.bufferGranularity; asioDeviceInfo->asioChannelInfos = (ASIOChannelInfo*)PaUtil_GroupAllocateMemory( asioHostApi->allocations, sizeof(ASIOChannelInfo) * (deviceInfo->maxInputChannels + deviceInfo->maxOutputChannels) ); if( !asioDeviceInfo->asioChannelInfos ) { result = paInsufficientMemory; goto error_unload; } int a; for( a=0; a < deviceInfo->maxInputChannels; ++a ){ asioDeviceInfo->asioChannelInfos[a].channel = a; asioDeviceInfo->asioChannelInfos[a].isInput = ASIOTrue; ASIOError asioError = ASIOGetChannelInfo( &asioDeviceInfo->asioChannelInfos[a] ); if( asioError != ASE_OK ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); goto error_unload; } } for( a=0; a < deviceInfo->maxOutputChannels; ++a ){ int b = deviceInfo->maxInputChannels + a; asioDeviceInfo->asioChannelInfos[b].channel = a; asioDeviceInfo->asioChannelInfos[b].isInput = ASIOFalse; ASIOError asioError = ASIOGetChannelInfo( &asioDeviceInfo->asioChannelInfos[b] ); if( asioError != ASE_OK ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); goto error_unload; } } /* unload the driver */ UnloadAsioDriver(); } return result; error_unload: UnloadAsioDriver(); if( asioDeviceInfo->asioChannelInfos ){ PaUtil_GroupFreeMemory( asioHostApi->allocations, asioDeviceInfo->asioChannelInfos ); asioDeviceInfo->asioChannelInfos = 0; } return result; } /* we look up IsDebuggerPresent at runtime incase it isn't present (on Win95 for example) */ typedef BOOL (WINAPI *IsDebuggerPresentPtr)(VOID); IsDebuggerPresentPtr IsDebuggerPresent_ = 0; //FARPROC IsDebuggerPresent_ = 0; // this is the current way to do it apparently according to davidv PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) { PaError result = paNoError; int i, driverCount; PaAsioHostApiRepresentation *asioHostApi; PaAsioDeviceInfo *deviceInfoArray; char **names; asioHostApi = (PaAsioHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaAsioHostApiRepresentation) ); if( !asioHostApi ) { result = paInsufficientMemory; goto error; } memset( asioHostApi, 0, sizeof(PaAsioHostApiRepresentation) ); /* ensure all fields are zeroed. especially asioHostApi->allocations */ /* We initialize COM ourselves here and uninitialize it in Terminate(). This should be the only COM initialization needed in this module. The ASIO SDK may also initialize COM but since we want to reduce dependency on the ASIO SDK we manage COM initialization ourselves. There used to be code that initialized COM in other situations such as when creating a Stream. This made PA work when calling Pa_CreateStream from a non-main thread. However we currently consider initialization of COM in non-main threads to be the caller's responsibility. */ result = PaWinUtil_CoInitialize( paASIO, &asioHostApi->comInitializationResult ); if( result != paNoError ) { goto error; } asioHostApi->asioDrivers = 0; /* avoid surprises in our error handler below */ asioHostApi->allocations = PaUtil_CreateAllocationGroup(); if( !asioHostApi->allocations ) { result = paInsufficientMemory; goto error; } /* Allocate the AsioDrivers() driver list (class from ASIO SDK) */ try { asioHostApi->asioDrivers = new AsioDrivers(); /* invokes CoInitialize(0) in AsioDriverList::AsioDriverList */ } catch (std::bad_alloc) { asioHostApi->asioDrivers = 0; } /* some implementations of new (ie MSVC, see http://support.microsoft.com/?kbid=167733) don't throw std::bad_alloc, so we also explicitly test for a null return. */ if( asioHostApi->asioDrivers == 0 ) { result = paInsufficientMemory; goto error; } asioDrivers = asioHostApi->asioDrivers; /* keep SDK global in sync until we stop depending on it */ asioHostApi->systemSpecific = 0; asioHostApi->openAsioDeviceIndex = paNoDevice; *hostApi = &asioHostApi->inheritedHostApiRep; (*hostApi)->info.structVersion = 1; (*hostApi)->info.type = paASIO; (*hostApi)->info.name = "ASIO"; (*hostApi)->info.deviceCount = 0; #ifdef WINDOWS /* use desktop window as system specific ptr */ asioHostApi->systemSpecific = GetDesktopWindow(); #endif /* driverCount is the number of installed drivers - not necessarily the number of installed physical devices. */ #if MAC driverCount = asioHostApi->asioDrivers->getNumFragments(); #elif WINDOWS driverCount = asioHostApi->asioDrivers->asioGetNumDev(); #endif if( driverCount > 0 ) { names = GetAsioDriverNames( asioHostApi, asioHostApi->allocations, driverCount ); if( !names ) { result = paInsufficientMemory; goto error; } /* allocate enough space for all drivers, even if some aren't installed */ (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( asioHostApi->allocations, sizeof(PaDeviceInfo*) * driverCount ); if( !(*hostApi)->deviceInfos ) { result = paInsufficientMemory; goto error; } /* allocate all device info structs in a contiguous block */ deviceInfoArray = (PaAsioDeviceInfo*)PaUtil_GroupAllocateMemory( asioHostApi->allocations, sizeof(PaAsioDeviceInfo) * driverCount ); if( !deviceInfoArray ) { result = paInsufficientMemory; goto error; } IsDebuggerPresent_ = (IsDebuggerPresentPtr)GetProcAddress( LoadLibraryA( "Kernel32.dll" ), "IsDebuggerPresent" ); for( i=0; i < driverCount; ++i ) { PA_DEBUG(("ASIO names[%d]:%s\n",i,names[i])); // Since portaudio opens ALL ASIO drivers, and no one else does that, // we face fact that some drivers were not meant for it, drivers which act // like shells on top of REAL drivers, for instance. // so we get duplicate handles, locks and other problems. // so lets NOT try to load any such wrappers. // The ones i [davidv] know of so far are: if ( strcmp (names[i],"ASIO DirectX Full Duplex Driver") == 0 || strcmp (names[i],"ASIO Multimedia Driver") == 0 || strncmp(names[i],"Premiere",8) == 0 //"Premiere Elements Windows Sound 1.0" || strncmp(names[i],"Adobe",5) == 0 //"Adobe Default Windows Sound 1.5" ) { PA_DEBUG(("BLACKLISTED!!!\n")); continue; } if( IsDebuggerPresent_ && IsDebuggerPresent_() ) { /* ASIO Digidesign Driver uses PACE copy protection which quits out if a debugger is running. So we don't load it if a debugger is running. */ if( strcmp(names[i], "ASIO Digidesign Driver") == 0 ) { PA_DEBUG(("BLACKLISTED!!! ASIO Digidesign Driver would quit the debugger\n")); continue; } } /* Attempt to init device info from the asio driver... */ { PaAsioDeviceInfo *asioDeviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ]; PaDeviceInfo *deviceInfo = &asioDeviceInfo->commonDeviceInfo; deviceInfo->structVersion = 2; deviceInfo->hostApi = hostApiIndex; deviceInfo->name = names[i]; if( InitPaDeviceInfoFromAsioDriver( asioHostApi, names[i], i, deviceInfo, asioDeviceInfo ) == paNoError ) { (*hostApi)->deviceInfos[ (*hostApi)->info.deviceCount ] = deviceInfo; ++(*hostApi)->info.deviceCount; } else { PA_DEBUG(("Skipping ASIO device:%s\n",names[i])); continue; } } } } if( (*hostApi)->info.deviceCount > 0 ) { (*hostApi)->info.defaultInputDevice = 0; (*hostApi)->info.defaultOutputDevice = 0; } else { (*hostApi)->info.defaultInputDevice = paNoDevice; (*hostApi)->info.defaultOutputDevice = paNoDevice; } (*hostApi)->Terminate = Terminate; (*hostApi)->OpenStream = OpenStream; (*hostApi)->IsFormatSupported = IsFormatSupported; PaUtil_InitializeStreamInterface( &asioHostApi->callbackStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, GetStreamCpuLoad, PaUtil_DummyRead, PaUtil_DummyWrite, PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable ); PaUtil_InitializeStreamInterface( &asioHostApi->blockingStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, PaUtil_DummyGetCpuLoad, ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable ); return result; error: if( asioHostApi ) { if( asioHostApi->allocations ) { PaUtil_FreeAllAllocations( asioHostApi->allocations ); PaUtil_DestroyAllocationGroup( asioHostApi->allocations ); } delete asioHostApi->asioDrivers; asioDrivers = 0; /* keep SDK global in sync until we stop depending on it */ PaWinUtil_CoUninitialize( paASIO, &asioHostApi->comInitializationResult ); PaUtil_FreeMemory( asioHostApi ); } return result; } static void Terminate( struct PaUtilHostApiRepresentation *hostApi ) { PaAsioHostApiRepresentation *asioHostApi = (PaAsioHostApiRepresentation*)hostApi; /* IMPLEMENT ME: - clean up any resources not handled by the allocation group (need to review if there are any) */ if( asioHostApi->allocations ) { PaUtil_FreeAllAllocations( asioHostApi->allocations ); PaUtil_DestroyAllocationGroup( asioHostApi->allocations ); } delete asioHostApi->asioDrivers; asioDrivers = 0; /* keep SDK global in sync until we stop depending on it */ PaWinUtil_CoUninitialize( paASIO, &asioHostApi->comInitializationResult ); PaUtil_FreeMemory( asioHostApi ); } static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ) { PaError result = paNoError; PaAsioHostApiRepresentation *asioHostApi = (PaAsioHostApiRepresentation*)hostApi; PaAsioDriverInfo *driverInfo = &asioHostApi->openAsioDriverInfo; int inputChannelCount, outputChannelCount; PaSampleFormat inputSampleFormat, outputSampleFormat; PaDeviceIndex asioDeviceIndex; ASIOError asioError; if( inputParameters && outputParameters ) { /* full duplex ASIO stream must use the same device for input and output */ if( inputParameters->device != outputParameters->device ) return paBadIODeviceCombination; } if( inputParameters ) { inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; /* all standard sample formats are supported by the buffer adapter, this implementation doesn't support any custom sample formats */ if( inputSampleFormat & paCustomFormat ) return paSampleFormatNotSupported; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; asioDeviceIndex = inputParameters->device; /* validate inputStreamInfo */ /** @todo do more validation here */ // if( inputParameters->hostApiSpecificStreamInfo ) // return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } else { inputChannelCount = 0; } if( outputParameters ) { outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; /* all standard sample formats are supported by the buffer adapter, this implementation doesn't support any custom sample formats */ if( outputSampleFormat & paCustomFormat ) return paSampleFormatNotSupported; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; asioDeviceIndex = outputParameters->device; /* validate outputStreamInfo */ /** @todo do more validation here */ // if( outputParameters->hostApiSpecificStreamInfo ) // return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } else { outputChannelCount = 0; } /* if an ASIO device is open we can only get format information for the currently open device */ if( asioHostApi->openAsioDeviceIndex != paNoDevice && asioHostApi->openAsioDeviceIndex != asioDeviceIndex ) { return paDeviceUnavailable; } /* NOTE: we load the driver and use its current settings rather than the ones in our device info structure which may be stale */ /* open the device if it's not already open */ if( asioHostApi->openAsioDeviceIndex == paNoDevice ) { result = LoadAsioDriver( asioHostApi, asioHostApi->inheritedHostApiRep.deviceInfos[ asioDeviceIndex ]->name, driverInfo, asioHostApi->systemSpecific ); if( result != paNoError ) return result; } /* check that input device can support inputChannelCount */ if( inputChannelCount > 0 ) { if( inputChannelCount > driverInfo->inputChannelCount ) { result = paInvalidChannelCount; goto done; } } /* check that output device can support outputChannelCount */ if( outputChannelCount ) { if( outputChannelCount > driverInfo->outputChannelCount ) { result = paInvalidChannelCount; goto done; } } /* query for sample rate support */ asioError = ASIOCanSampleRate( sampleRate ); if( asioError == ASE_NoClock || asioError == ASE_NotPresent ) { result = paInvalidSampleRate; goto done; } done: /* close the device if it wasn't already open */ if( asioHostApi->openAsioDeviceIndex == paNoDevice ) { UnloadAsioDriver(); /* not sure if we should check for errors here */ } if( result == paNoError ) return paFormatIsSupported; else return result; } /** A data structure specifically for storing blocking i/o related data. */ typedef struct PaAsioStreamBlockingState { int stopFlag; /**< Flag indicating that block processing is to be stopped. */ unsigned long writeBuffersRequested; /**< The number of available output buffers, requested by the #WriteStream() function. */ unsigned long readFramesRequested; /**< The number of available input frames, requested by the #ReadStream() function. */ int writeBuffersRequestedFlag; /**< Flag to indicate that #WriteStream() has requested more output buffers to be available. */ int readFramesRequestedFlag; /**< Flag to indicate that #ReadStream() requires more input frames to be available. */ HANDLE writeBuffersReadyEvent; /**< Event to signal that requested output buffers are available. */ HANDLE readFramesReadyEvent; /**< Event to signal that requested input frames are available. */ void *writeRingBufferData; /**< The actual ring buffer memory, used by the output ring buffer. */ void *readRingBufferData; /**< The actual ring buffer memory, used by the input ring buffer. */ PaUtilRingBuffer writeRingBuffer; /**< Frame-aligned blocking i/o ring buffer to store output data (interleaved user format). */ PaUtilRingBuffer readRingBuffer; /**< Frame-aligned blocking i/o ring buffer to store input data (interleaved user format). */ long writeRingBufferInitialFrames; /**< The initial number of silent frames within the output ring buffer. */ const void **writeStreamBuffer; /**< Temp buffer, used by #WriteStream() for handling non-interleaved data. */ void **readStreamBuffer; /**< Temp buffer, used by #ReadStream() for handling non-interleaved data. */ PaUtilBufferProcessor bufferProcessor; /**< Buffer processor, used to handle the blocking i/o ring buffers. */ int outputUnderflowFlag; /**< Flag to signal an output underflow from within the callback function. */ int inputOverflowFlag; /**< Flag to signal an input overflow from within the callback function. */ } PaAsioStreamBlockingState; /* PaAsioStream - a stream data structure specifically for this implementation */ typedef struct PaAsioStream { PaUtilStreamRepresentation streamRepresentation; PaUtilCpuLoadMeasurer cpuLoadMeasurer; PaUtilBufferProcessor bufferProcessor; PaAsioHostApiRepresentation *asioHostApi; unsigned long framesPerHostCallback; /* ASIO driver info - these may not be needed for the life of the stream, but store them here until we work out how format conversion is going to work. */ ASIOBufferInfo *asioBufferInfos; ASIOChannelInfo *asioChannelInfos; long asioInputLatencyFrames, asioOutputLatencyFrames; // actual latencies returned by asio long inputChannelCount, outputChannelCount; bool postOutput; void **bufferPtrs; /* this is carved up for inputBufferPtrs and outputBufferPtrs */ void **inputBufferPtrs[2]; void **outputBufferPtrs[2]; PaAsioBufferConverter *inputBufferConverter; long inputShift; PaAsioBufferConverter *outputBufferConverter; long outputShift; volatile bool stopProcessing; int stopPlayoutCount; HANDLE completedBuffersPlayedEvent; bool streamFinishedCallbackCalled; int isStopped; volatile int isActive; volatile bool zeroOutput; /* all future calls to the callback will output silence */ volatile long reenterCount; volatile long reenterError; PaStreamCallbackFlags callbackFlags; PaAsioStreamBlockingState *blockingState; /**< Blocking i/o data struct, or NULL when using callback interface. */ } PaAsioStream; static PaAsioStream *theAsioStream = 0; /* due to ASIO sdk limitations there can be only one stream */ static void ZeroOutputBuffers( PaAsioStream *stream, long index ) { int i; for( i=0; i < stream->outputChannelCount; ++i ) { void *buffer = stream->asioBufferInfos[ i + stream->inputChannelCount ].buffers[index]; int bytesPerSample = BytesPerAsioSample( stream->asioChannelInfos[ i + stream->inputChannelCount ].type ); memset( buffer, 0, stream->framesPerHostCallback * bytesPerSample ); } } /* return the next power of two >= x. Returns the input parameter if it is already a power of two. http://stackoverflow.com/questions/364985/algorithm-for-finding-the-smallest-power-of-two-thats-greater-or-equal-to-a-giv */ static unsigned long NextPowerOfTwo( unsigned long x ) { --x; x |= x >> 1; x |= x >> 2; x |= x >> 4; x |= x >> 8; x |= x >> 16; /* If you needed to deal with numbers > 2^32 the following would be needed. For latencies, we don't deal with values this large. x |= x >> 16; */ return x + 1; } static unsigned long SelectHostBufferSizeForUnspecifiedUserFramesPerBuffer( unsigned long targetBufferingLatencyFrames, PaAsioDriverInfo *driverInfo ) { /* Choose a host buffer size based only on targetBufferingLatencyFrames and the device's supported buffer sizes. Always returns a valid value. */ unsigned long result; if( targetBufferingLatencyFrames <= (unsigned long)driverInfo->bufferMinSize ) { result = driverInfo->bufferMinSize; } else if( targetBufferingLatencyFrames >= (unsigned long)driverInfo->bufferMaxSize ) { result = driverInfo->bufferMaxSize; } else { if( driverInfo->bufferGranularity == 0 ) /* single fixed host buffer size */ { /* The documentation states that bufferGranularity should be zero when bufferMinSize, bufferMaxSize and bufferPreferredSize are the same. We assume that is the case. */ result = driverInfo->bufferPreferredSize; } else if( driverInfo->bufferGranularity == -1 ) /* power-of-two */ { /* We assume bufferMinSize and bufferMaxSize are powers of two. */ result = NextPowerOfTwo( targetBufferingLatencyFrames ); if( result < (unsigned long)driverInfo->bufferMinSize ) result = driverInfo->bufferMinSize; if( result > (unsigned long)driverInfo->bufferMaxSize ) result = driverInfo->bufferMaxSize; } else /* modulo bufferGranularity */ { /* round up to the next multiple of granularity */ unsigned long n = (targetBufferingLatencyFrames + driverInfo->bufferGranularity - 1) / driverInfo->bufferGranularity; result = n * driverInfo->bufferGranularity; if( result < (unsigned long)driverInfo->bufferMinSize ) result = driverInfo->bufferMinSize; if( result > (unsigned long)driverInfo->bufferMaxSize ) result = driverInfo->bufferMaxSize; } } return result; } static unsigned long SelectHostBufferSizeForSpecifiedUserFramesPerBuffer( unsigned long targetBufferingLatencyFrames, unsigned long userFramesPerBuffer, PaAsioDriverInfo *driverInfo ) { /* Select a host buffer size conforming to targetBufferingLatencyFrames and the device's supported buffer sizes. The return value will always be a multiple of userFramesPerBuffer. If a valid buffer size can not be found the function returns 0. The current implementation uses a simple iterative search for clarity. Feel free to suggest a closed form solution. */ unsigned long result = 0; assert( userFramesPerBuffer != 0 ); if( driverInfo->bufferGranularity == 0 ) /* single fixed host buffer size */ { /* The documentation states that bufferGranularity should be zero when bufferMinSize, bufferMaxSize and bufferPreferredSize are the same. We assume that is the case. */ if( (driverInfo->bufferPreferredSize % userFramesPerBuffer) == 0 ) result = driverInfo->bufferPreferredSize; } else if( driverInfo->bufferGranularity == -1 ) /* power-of-two */ { /* We assume bufferMinSize and bufferMaxSize are powers of two. */ /* Search all powers of two in the range [bufferMinSize,bufferMaxSize] for multiples of userFramesPerBuffer. We prefer the first multiple that is equal or greater than targetBufferingLatencyFrames, or failing that, the largest multiple less than targetBufferingLatencyFrames. */ unsigned long x = (unsigned long)driverInfo->bufferMinSize; do { if( (x % userFramesPerBuffer) == 0 ) { /* any multiple of userFramesPerBuffer is acceptable */ result = x; if( result >= targetBufferingLatencyFrames ) break; /* stop. a value >= to targetBufferingLatencyFrames is ideal. */ } x *= 2; } while( x <= (unsigned long)driverInfo->bufferMaxSize ); } else /* modulo granularity */ { /* We assume bufferMinSize is a multiple of bufferGranularity. */ /* Search all multiples of bufferGranularity in the range [bufferMinSize,bufferMaxSize] for multiples of userFramesPerBuffer. We prefer the first multiple that is equal or greater than targetBufferingLatencyFrames, or failing that, the largest multiple less than targetBufferingLatencyFrames. */ unsigned long x = (unsigned long)driverInfo->bufferMinSize; do { if( (x % userFramesPerBuffer) == 0 ) { /* any multiple of userFramesPerBuffer is acceptable */ result = x; if( result >= targetBufferingLatencyFrames ) break; /* stop. a value >= to targetBufferingLatencyFrames is ideal. */ } x += driverInfo->bufferGranularity; } while( x <= (unsigned long)driverInfo->bufferMaxSize ); } return result; } static unsigned long SelectHostBufferSize( unsigned long targetBufferingLatencyFrames, unsigned long userFramesPerBuffer, PaAsioDriverInfo *driverInfo ) { unsigned long result = 0; /* We select a host buffer size based on the following requirements (in priority order): 1. The host buffer size must be permissible according to the ASIO driverInfo buffer size constraints (min, max, granularity or powers-of-two). 2. If the user specifies a non-zero framesPerBuffer parameter (userFramesPerBuffer here) the host buffer should be a multiple of this (subject to the constraints in (1) above). [NOTE: Where no permissible host buffer size is a multiple of userFramesPerBuffer, we choose a value as if userFramesPerBuffer were zero (i.e. we ignore it). This strategy is open for review ~ perhaps there are still "more optimal" buffer sizes related to userFramesPerBuffer that we could use.] 3. The host buffer size should be greater than or equal to targetBufferingLatencyFrames, subject to (1) and (2) above. Where it is not possible to select a host buffer size equal or greater than targetBufferingLatencyFrames, the highest buffer size conforming to (1) and (2) should be chosen. */ if( userFramesPerBuffer != 0 ) { /* userFramesPerBuffer is specified, try to find a buffer size that's a multiple of it */ result = SelectHostBufferSizeForSpecifiedUserFramesPerBuffer( targetBufferingLatencyFrames, userFramesPerBuffer, driverInfo ); } if( result == 0 ) { /* either userFramesPerBuffer was not specified, or we couldn't find a host buffer size that is a multiple of it. Select a host buffer size according to targetBufferingLatencyFrames and the ASIO driverInfo buffer size constraints. */ result = SelectHostBufferSizeForUnspecifiedUserFramesPerBuffer( targetBufferingLatencyFrames, driverInfo ); } return result; } /* returns channelSelectors if present */ static PaError ValidateAsioSpecificStreamInfo( const PaStreamParameters *streamParameters, const PaAsioStreamInfo *streamInfo, int deviceChannelCount, int **channelSelectors ) { if( streamInfo ) { if( streamInfo->size != sizeof( PaAsioStreamInfo ) || streamInfo->version != 1 ) { return paIncompatibleHostApiSpecificStreamInfo; } if( streamInfo->flags & paAsioUseChannelSelectors ) *channelSelectors = streamInfo->channelSelectors; if( !(*channelSelectors) ) return paIncompatibleHostApiSpecificStreamInfo; for( int i=0; i < streamParameters->channelCount; ++i ){ if( (*channelSelectors)[i] < 0 || (*channelSelectors)[i] >= deviceChannelCount ){ return paInvalidChannelCount; } } } return paNoError; } static bool IsUsingExternalClockSource() { bool result = false; ASIOError asioError; ASIOClockSource clocks[32]; long numSources=32; /* davidv: listing ASIO Clock sources. there is an ongoing investigation by me about whether or not to call ASIOSetSampleRate if an external Clock is used. A few drivers expected different things here */ asioError = ASIOGetClockSources(clocks, &numSources); if( asioError != ASE_OK ){ PA_DEBUG(("ERROR: ASIOGetClockSources: %s\n", PaAsio_GetAsioErrorText(asioError) )); }else{ PA_DEBUG(("INFO ASIOGetClockSources listing %d clocks\n", numSources )); for (int i=0;iopenAsioDeviceIndex != paNoDevice ) { PA_DEBUG(("OpenStream paDeviceUnavailable\n")); return paDeviceUnavailable; } assert( theAsioStream == 0 ); if( inputParameters && outputParameters ) { /* full duplex ASIO stream must use the same device for input and output */ if( inputParameters->device != outputParameters->device ) { PA_DEBUG(("OpenStream paBadIODeviceCombination\n")); return paBadIODeviceCombination; } } if( inputParameters ) { inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; suggestedInputLatencyFrames = (unsigned long)((inputParameters->suggestedLatency * sampleRate)+0.5f); /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; asioDeviceIndex = inputParameters->device; PaAsioDeviceInfo *asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[asioDeviceIndex]; /* validate hostApiSpecificStreamInfo */ inputStreamInfo = (PaAsioStreamInfo*)inputParameters->hostApiSpecificStreamInfo; result = ValidateAsioSpecificStreamInfo( inputParameters, inputStreamInfo, asioDeviceInfo->commonDeviceInfo.maxInputChannels, &inputChannelSelectors ); if( result != paNoError ) return result; } else { inputChannelCount = 0; inputSampleFormat = 0; suggestedInputLatencyFrames = 0; } if( outputParameters ) { outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; suggestedOutputLatencyFrames = (unsigned long)((outputParameters->suggestedLatency * sampleRate)+0.5f); /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; asioDeviceIndex = outputParameters->device; PaAsioDeviceInfo *asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[asioDeviceIndex]; /* validate hostApiSpecificStreamInfo */ outputStreamInfo = (PaAsioStreamInfo*)outputParameters->hostApiSpecificStreamInfo; result = ValidateAsioSpecificStreamInfo( outputParameters, outputStreamInfo, asioDeviceInfo->commonDeviceInfo.maxOutputChannels, &outputChannelSelectors ); if( result != paNoError ) return result; } else { outputChannelCount = 0; outputSampleFormat = 0; suggestedOutputLatencyFrames = 0; } driverInfo = &asioHostApi->openAsioDriverInfo; /* NOTE: we load the driver and use its current settings rather than the ones in our device info structure which may be stale */ result = LoadAsioDriver( asioHostApi, asioHostApi->inheritedHostApiRep.deviceInfos[ asioDeviceIndex ]->name, driverInfo, asioHostApi->systemSpecific ); if( result == paNoError ) asioIsInitialized = 1; else{ PA_DEBUG(("OpenStream ERROR1 - LoadAsioDriver returned %d\n", result)); goto error; } /* check that input device can support inputChannelCount */ if( inputChannelCount > 0 ) { if( inputChannelCount > driverInfo->inputChannelCount ) { result = paInvalidChannelCount; PA_DEBUG(("OpenStream ERROR2\n")); goto error; } } /* check that output device can support outputChannelCount */ if( outputChannelCount ) { if( outputChannelCount > driverInfo->outputChannelCount ) { result = paInvalidChannelCount; PA_DEBUG(("OpenStream ERROR3\n")); goto error; } } result = ValidateAndSetSampleRate( sampleRate ); if( result != paNoError ) goto error; /* IMPLEMENT ME: - if a full duplex stream is requested, check that the combination of input and output parameters is supported */ /* validate platform specific flags */ if( (streamFlags & paPlatformSpecificFlags) != 0 ){ PA_DEBUG(("OpenStream invalid flags!!\n")); return paInvalidFlag; /* unexpected platform specific flag */ } stream = (PaAsioStream*)PaUtil_AllocateMemory( sizeof(PaAsioStream) ); if( !stream ) { result = paInsufficientMemory; PA_DEBUG(("OpenStream ERROR5\n")); goto error; } stream->blockingState = NULL; /* Blocking i/o not initialized, yet. */ stream->completedBuffersPlayedEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); if( stream->completedBuffersPlayedEvent == NULL ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() ); PA_DEBUG(("OpenStream ERROR6\n")); goto error; } completedBuffersPlayedEventInited = 1; stream->asioBufferInfos = 0; /* for deallocation in error */ stream->asioChannelInfos = 0; /* for deallocation in error */ stream->bufferPtrs = 0; /* for deallocation in error */ /* Using blocking i/o interface... */ if( usingBlockingIo ) { /* Blocking i/o is implemented by running callback mode, using a special blocking i/o callback. */ streamCallback = BlockingIoPaCallback; /* Setup PA to use the ASIO blocking i/o callback. */ userData = &theAsioStream; /* The callback user data will be the PA ASIO stream. */ PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &asioHostApi->blockingStreamInterface, streamCallback, userData ); } else /* Using callback interface... */ { PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &asioHostApi->callbackStreamInterface, streamCallback, userData ); } PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate ); stream->asioBufferInfos = (ASIOBufferInfo*)PaUtil_AllocateMemory( sizeof(ASIOBufferInfo) * (inputChannelCount + outputChannelCount) ); if( !stream->asioBufferInfos ) { result = paInsufficientMemory; PA_DEBUG(("OpenStream ERROR7\n")); goto error; } for( i=0; i < inputChannelCount; ++i ) { ASIOBufferInfo *info = &stream->asioBufferInfos[i]; info->isInput = ASIOTrue; if( inputChannelSelectors ){ // inputChannelSelectors values have already been validated in // ValidateAsioSpecificStreamInfo() above info->channelNum = inputChannelSelectors[i]; }else{ info->channelNum = i; } info->buffers[0] = info->buffers[1] = 0; } for( i=0; i < outputChannelCount; ++i ){ ASIOBufferInfo *info = &stream->asioBufferInfos[inputChannelCount+i]; info->isInput = ASIOFalse; if( outputChannelSelectors ){ // outputChannelSelectors values have already been validated in // ValidateAsioSpecificStreamInfo() above info->channelNum = outputChannelSelectors[i]; }else{ info->channelNum = i; } info->buffers[0] = info->buffers[1] = 0; } /* Using blocking i/o interface... */ if( usingBlockingIo ) { /** @todo REVIEW selection of host buffer size for blocking i/o */ framesPerHostBuffer = SelectHostBufferSize( 0, framesPerBuffer, driverInfo ); } else /* Using callback interface... */ { /* Select the host buffer size based on user framesPerBuffer and the maximum of suggestedInputLatencyFrames and suggestedOutputLatencyFrames. We should subtract any fixed known driver latency from suggestedLatencyFrames before computing the host buffer size. However, the ASIO API doesn't provide a method for determining fixed latencies independent of the host buffer size. ASIOGetLatencies() only returns latencies after the buffer size has been configured, so we can't reliably use it to determine fixed latencies here. We could set the preferred buffer size and then subtract it from the values returned from ASIOGetLatencies, but this would not be 100% reliable, so we don't do it. */ unsigned long targetBufferingLatencyFrames = (( suggestedInputLatencyFrames > suggestedOutputLatencyFrames ) ? suggestedInputLatencyFrames : suggestedOutputLatencyFrames); framesPerHostBuffer = SelectHostBufferSize( targetBufferingLatencyFrames, framesPerBuffer, driverInfo ); } PA_DEBUG(("PaAsioOpenStream: framesPerHostBuffer :%d\n", framesPerHostBuffer)); asioError = ASIOCreateBuffers( stream->asioBufferInfos, inputChannelCount+outputChannelCount, framesPerHostBuffer, &asioCallbacks_ ); if( asioError != ASE_OK && framesPerHostBuffer != (unsigned long)driverInfo->bufferPreferredSize ) { PA_DEBUG(("ERROR: ASIOCreateBuffers: %s\n", PaAsio_GetAsioErrorText(asioError) )); /* Some buggy drivers (like the Hoontech DSP24) give incorrect [min, preferred, max] values They should work with the preferred size value, thus if Pa_ASIO_CreateBuffers fails with the hostBufferSize computed in SelectHostBufferSize, we try again with the preferred size. */ framesPerHostBuffer = driverInfo->bufferPreferredSize; PA_DEBUG(("PaAsioOpenStream: CORRECTED framesPerHostBuffer :%d\n", framesPerHostBuffer)); ASIOError asioError2 = ASIOCreateBuffers( stream->asioBufferInfos, inputChannelCount+outputChannelCount, framesPerHostBuffer, &asioCallbacks_ ); if( asioError2 == ASE_OK ) asioError = ASE_OK; } if( asioError != ASE_OK ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); PA_DEBUG(("OpenStream ERROR9\n")); goto error; } asioBuffersCreated = 1; stream->asioChannelInfos = (ASIOChannelInfo*)PaUtil_AllocateMemory( sizeof(ASIOChannelInfo) * (inputChannelCount + outputChannelCount) ); if( !stream->asioChannelInfos ) { result = paInsufficientMemory; PA_DEBUG(("OpenStream ERROR10\n")); goto error; } for( i=0; i < inputChannelCount + outputChannelCount; ++i ) { stream->asioChannelInfos[i].channel = stream->asioBufferInfos[i].channelNum; stream->asioChannelInfos[i].isInput = stream->asioBufferInfos[i].isInput; asioError = ASIOGetChannelInfo( &stream->asioChannelInfos[i] ); if( asioError != ASE_OK ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); PA_DEBUG(("OpenStream ERROR11\n")); goto error; } } stream->bufferPtrs = (void**)PaUtil_AllocateMemory( 2 * sizeof(void*) * (inputChannelCount + outputChannelCount) ); if( !stream->bufferPtrs ) { result = paInsufficientMemory; PA_DEBUG(("OpenStream ERROR12\n")); goto error; } if( inputChannelCount > 0 ) { stream->inputBufferPtrs[0] = stream-> bufferPtrs; stream->inputBufferPtrs[1] = &stream->bufferPtrs[inputChannelCount]; for( i=0; iinputBufferPtrs[0][i] = stream->asioBufferInfos[i].buffers[0]; stream->inputBufferPtrs[1][i] = stream->asioBufferInfos[i].buffers[1]; } } else { stream->inputBufferPtrs[0] = 0; stream->inputBufferPtrs[1] = 0; } if( outputChannelCount > 0 ) { stream->outputBufferPtrs[0] = &stream->bufferPtrs[inputChannelCount*2]; stream->outputBufferPtrs[1] = &stream->bufferPtrs[inputChannelCount*2 + outputChannelCount]; for( i=0; ioutputBufferPtrs[0][i] = stream->asioBufferInfos[inputChannelCount+i].buffers[0]; stream->outputBufferPtrs[1][i] = stream->asioBufferInfos[inputChannelCount+i].buffers[1]; } } else { stream->outputBufferPtrs[0] = 0; stream->outputBufferPtrs[1] = 0; } if( inputChannelCount > 0 ) { /* FIXME: assume all channels use the same type for now see: "ASIO devices with multiple sample formats are unsupported" http://www.portaudio.com/trac/ticket/106 */ ASIOSampleType inputType = stream->asioChannelInfos[0].type; PA_DEBUG(("ASIO Input type:%d",inputType)); AsioSampleTypeLOG(inputType); hostInputSampleFormat = AsioSampleTypeToPaNativeSampleFormat( inputType ); SelectAsioToPaConverter( inputType, &stream->inputBufferConverter, &stream->inputShift ); } else { hostInputSampleFormat = 0; stream->inputBufferConverter = 0; } if( outputChannelCount > 0 ) { /* FIXME: assume all channels use the same type for now see: "ASIO devices with multiple sample formats are unsupported" http://www.portaudio.com/trac/ticket/106 */ ASIOSampleType outputType = stream->asioChannelInfos[inputChannelCount].type; PA_DEBUG(("ASIO Output type:%d",outputType)); AsioSampleTypeLOG(outputType); hostOutputSampleFormat = AsioSampleTypeToPaNativeSampleFormat( outputType ); SelectPaToAsioConverter( outputType, &stream->outputBufferConverter, &stream->outputShift ); } else { hostOutputSampleFormat = 0; stream->outputBufferConverter = 0; } /* Values returned by ASIOGetLatencies() include the latency introduced by the ASIO double buffer. */ ASIOGetLatencies( &stream->asioInputLatencyFrames, &stream->asioOutputLatencyFrames ); /* Using blocking i/o interface... */ if( usingBlockingIo ) { /* Allocate the blocking i/o input ring buffer memory. */ stream->blockingState = (PaAsioStreamBlockingState*)PaUtil_AllocateMemory( sizeof(PaAsioStreamBlockingState) ); if( !stream->blockingState ) { result = paInsufficientMemory; PA_DEBUG(("ERROR! Blocking i/o interface struct allocation failed in OpenStream()\n")); goto error; } /* Initialize blocking i/o interface struct. */ stream->blockingState->readFramesReadyEvent = NULL; /* Uninitialized, yet. */ stream->blockingState->writeBuffersReadyEvent = NULL; /* Uninitialized, yet. */ stream->blockingState->readRingBufferData = NULL; /* Uninitialized, yet. */ stream->blockingState->writeRingBufferData = NULL; /* Uninitialized, yet. */ stream->blockingState->readStreamBuffer = NULL; /* Uninitialized, yet. */ stream->blockingState->writeStreamBuffer = NULL; /* Uninitialized, yet. */ stream->blockingState->stopFlag = TRUE; /* Not started, yet. */ /* If the user buffer is unspecified */ if( framesPerBuffer == paFramesPerBufferUnspecified ) { /* Make the user buffer the same size as the host buffer. */ framesPerBuffer = framesPerHostBuffer; } /* Initialize callback buffer processor. */ result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor , inputChannelCount , inputSampleFormat & ~paNonInterleaved , /* Ring buffer. */ (hostInputSampleFormat | paNonInterleaved), /* Host format. */ outputChannelCount , outputSampleFormat & ~paNonInterleaved, /* Ring buffer. */ (hostOutputSampleFormat | paNonInterleaved), /* Host format. */ sampleRate , streamFlags , framesPerBuffer , /* Frames per ring buffer block. */ framesPerHostBuffer , /* Frames per asio buffer. */ paUtilFixedHostBufferSize , streamCallback , userData ); if( result != paNoError ){ PA_DEBUG(("OpenStream ERROR13\n")); goto error; } callbackBufferProcessorInited = TRUE; /* Initialize the blocking i/o buffer processor. */ result = PaUtil_InitializeBufferProcessor(&stream->blockingState->bufferProcessor, inputChannelCount , inputSampleFormat , /* User format. */ inputSampleFormat & ~paNonInterleaved , /* Ring buffer. */ outputChannelCount , outputSampleFormat , /* User format. */ outputSampleFormat & ~paNonInterleaved, /* Ring buffer. */ sampleRate , paClipOff | paDitherOff , /* Don't use dither nor clipping. */ framesPerBuffer , /* Frames per user buffer. */ framesPerBuffer , /* Frames per ring buffer block. */ paUtilBoundedHostBufferSize , NULL, NULL );/* No callback! */ if( result != paNoError ){ PA_DEBUG(("ERROR! Blocking i/o buffer processor initialization failed in OpenStream()\n")); goto error; } blockingBufferProcessorInited = TRUE; /* If input is requested. */ if( inputChannelCount ) { /* Create the callback sync-event. */ stream->blockingState->readFramesReadyEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); if( stream->blockingState->readFramesReadyEvent == NULL ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() ); PA_DEBUG(("ERROR! Blocking i/o \"read frames ready\" event creation failed in OpenStream()\n")); goto error; } blockingReadFramesReadyEventInitialized = 1; /* Create pointer buffer to access non-interleaved data in ReadStream() */ stream->blockingState->readStreamBuffer = (void**)PaUtil_AllocateMemory( sizeof(void*) * inputChannelCount ); if( !stream->blockingState->readStreamBuffer ) { result = paInsufficientMemory; PA_DEBUG(("ERROR! Blocking i/o read stream buffer allocation failed in OpenStream()\n")); goto error; } /* The ring buffer should store as many data blocks as needed to achieve the requested latency. Whereas it must be large enough to store at least two complete data blocks. 1) Determine the amount of latency to be added to the prefered ASIO latency. 2) Make sure we have at lest one additional latency frame. 3) Divide the number of frames by the desired block size to get the number (rounded up to pure integer) of blocks to be stored in the buffer. 4) Add one additional block for block processing and convert to samples frames. 5) Get the next larger (or equal) power-of-two buffer size. */ lBlockingBufferSize = suggestedInputLatencyFrames - stream->asioInputLatencyFrames; lBlockingBufferSize = (lBlockingBufferSize > 0) ? lBlockingBufferSize : 1; lBlockingBufferSize = (lBlockingBufferSize + framesPerBuffer - 1) / framesPerBuffer; lBlockingBufferSize = (lBlockingBufferSize + 1) * framesPerBuffer; /* Get the next larger or equal power-of-two buffersize. */ lBlockingBufferSizePow2 = 1; while( lBlockingBufferSize > (lBlockingBufferSizePow2<<=1) ); lBlockingBufferSize = lBlockingBufferSizePow2; /* Compute total intput latency in seconds */ stream->streamRepresentation.streamInfo.inputLatency = (double)( PaUtil_GetBufferProcessorInputLatencyFrames(&stream->bufferProcessor ) + PaUtil_GetBufferProcessorInputLatencyFrames(&stream->blockingState->bufferProcessor) + (lBlockingBufferSize / framesPerBuffer - 1) * framesPerBuffer + stream->asioInputLatencyFrames ) / sampleRate; /* The code below prints the ASIO latency which doesn't include the buffer processor latency nor the blocking i/o latency. It reports the added latency separately. */ PA_DEBUG(("PaAsio : ASIO InputLatency = %ld (%ld ms),\n added buffProc:%ld (%ld ms),\n added blocking:%ld (%ld ms)\n", stream->asioInputLatencyFrames, (long)( stream->asioInputLatencyFrames * (1000.0 / sampleRate) ), PaUtil_GetBufferProcessorInputLatencyFrames(&stream->bufferProcessor), (long)( PaUtil_GetBufferProcessorInputLatencyFrames(&stream->bufferProcessor) * (1000.0 / sampleRate) ), PaUtil_GetBufferProcessorInputLatencyFrames(&stream->blockingState->bufferProcessor) + (lBlockingBufferSize / framesPerBuffer - 1) * framesPerBuffer, (long)( (PaUtil_GetBufferProcessorInputLatencyFrames(&stream->blockingState->bufferProcessor) + (lBlockingBufferSize / framesPerBuffer - 1) * framesPerBuffer) * (1000.0 / sampleRate) ) )); /* Determine the size of ring buffer in bytes. */ lBytesPerFrame = inputChannelCount * Pa_GetSampleSize(inputSampleFormat ); /* Allocate the blocking i/o input ring buffer memory. */ stream->blockingState->readRingBufferData = (void*)PaUtil_AllocateMemory( lBlockingBufferSize * lBytesPerFrame ); if( !stream->blockingState->readRingBufferData ) { result = paInsufficientMemory; PA_DEBUG(("ERROR! Blocking i/o input ring buffer allocation failed in OpenStream()\n")); goto error; } /* Initialize the input ring buffer struct. */ PaUtil_InitializeRingBuffer( &stream->blockingState->readRingBuffer , lBytesPerFrame , lBlockingBufferSize , stream->blockingState->readRingBufferData ); } /* If output is requested. */ if( outputChannelCount ) { stream->blockingState->writeBuffersReadyEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); if( stream->blockingState->writeBuffersReadyEvent == NULL ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() ); PA_DEBUG(("ERROR! Blocking i/o \"write buffers ready\" event creation failed in OpenStream()\n")); goto error; } blockingWriteBuffersReadyEventInitialized = 1; /* Create pointer buffer to access non-interleaved data in WriteStream() */ stream->blockingState->writeStreamBuffer = (const void**)PaUtil_AllocateMemory( sizeof(const void*) * outputChannelCount ); if( !stream->blockingState->writeStreamBuffer ) { result = paInsufficientMemory; PA_DEBUG(("ERROR! Blocking i/o write stream buffer allocation failed in OpenStream()\n")); goto error; } /* The ring buffer should store as many data blocks as needed to achieve the requested latency. Whereas it must be large enough to store at least two complete data blocks. 1) Determine the amount of latency to be added to the prefered ASIO latency. 2) Make sure we have at lest one additional latency frame. 3) Divide the number of frames by the desired block size to get the number (rounded up to pure integer) of blocks to be stored in the buffer. 4) Add one additional block for block processing and convert to samples frames. 5) Get the next larger (or equal) power-of-two buffer size. */ lBlockingBufferSize = suggestedOutputLatencyFrames - stream->asioOutputLatencyFrames; lBlockingBufferSize = (lBlockingBufferSize > 0) ? lBlockingBufferSize : 1; lBlockingBufferSize = (lBlockingBufferSize + framesPerBuffer - 1) / framesPerBuffer; lBlockingBufferSize = (lBlockingBufferSize + 1) * framesPerBuffer; /* The buffer size (without the additional block) corresponds to the initial number of silent samples in the output ring buffer. */ stream->blockingState->writeRingBufferInitialFrames = lBlockingBufferSize - framesPerBuffer; /* Get the next larger or equal power-of-two buffersize. */ lBlockingBufferSizePow2 = 1; while( lBlockingBufferSize > (lBlockingBufferSizePow2<<=1) ); lBlockingBufferSize = lBlockingBufferSizePow2; /* Compute total output latency in seconds */ stream->streamRepresentation.streamInfo.outputLatency = (double)( PaUtil_GetBufferProcessorOutputLatencyFrames(&stream->bufferProcessor) + PaUtil_GetBufferProcessorOutputLatencyFrames(&stream->blockingState->bufferProcessor) + (lBlockingBufferSize / framesPerBuffer - 1) * framesPerBuffer + stream->asioOutputLatencyFrames ) / sampleRate; /* The code below prints the ASIO latency which doesn't include the buffer processor latency nor the blocking i/o latency. It reports the added latency separately. */ PA_DEBUG(("PaAsio : ASIO OutputLatency = %ld (%ld ms),\n added buffProc:%ld (%ld ms),\n added blocking:%ld (%ld ms)\n", stream->asioOutputLatencyFrames, (long)( stream->asioOutputLatencyFrames * (1000.0 / sampleRate) ), PaUtil_GetBufferProcessorOutputLatencyFrames(&stream->bufferProcessor), (long)( PaUtil_GetBufferProcessorOutputLatencyFrames(&stream->bufferProcessor) * (1000.0 / sampleRate) ), PaUtil_GetBufferProcessorOutputLatencyFrames(&stream->blockingState->bufferProcessor) + (lBlockingBufferSize / framesPerBuffer - 1) * framesPerBuffer, (long)( (PaUtil_GetBufferProcessorOutputLatencyFrames(&stream->blockingState->bufferProcessor) + (lBlockingBufferSize / framesPerBuffer - 1) * framesPerBuffer) * (1000.0 / sampleRate) ) )); /* Determine the size of ring buffer in bytes. */ lBytesPerFrame = outputChannelCount * Pa_GetSampleSize(outputSampleFormat); /* Allocate the blocking i/o output ring buffer memory. */ stream->blockingState->writeRingBufferData = (void*)PaUtil_AllocateMemory( lBlockingBufferSize * lBytesPerFrame ); if( !stream->blockingState->writeRingBufferData ) { result = paInsufficientMemory; PA_DEBUG(("ERROR! Blocking i/o output ring buffer allocation failed in OpenStream()\n")); goto error; } /* Initialize the output ring buffer struct. */ PaUtil_InitializeRingBuffer( &stream->blockingState->writeRingBuffer , lBytesPerFrame , lBlockingBufferSize , stream->blockingState->writeRingBufferData ); } stream->streamRepresentation.streamInfo.sampleRate = sampleRate; } else /* Using callback interface... */ { result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor, inputChannelCount, inputSampleFormat, (hostInputSampleFormat | paNonInterleaved), outputChannelCount, outputSampleFormat, (hostOutputSampleFormat | paNonInterleaved), sampleRate, streamFlags, framesPerBuffer, framesPerHostBuffer, paUtilFixedHostBufferSize, streamCallback, userData ); if( result != paNoError ){ PA_DEBUG(("OpenStream ERROR13\n")); goto error; } callbackBufferProcessorInited = TRUE; stream->streamRepresentation.streamInfo.inputLatency = (double)( PaUtil_GetBufferProcessorInputLatencyFrames(&stream->bufferProcessor) + stream->asioInputLatencyFrames) / sampleRate; // seconds stream->streamRepresentation.streamInfo.outputLatency = (double)( PaUtil_GetBufferProcessorOutputLatencyFrames(&stream->bufferProcessor) + stream->asioOutputLatencyFrames) / sampleRate; // seconds stream->streamRepresentation.streamInfo.sampleRate = sampleRate; // the code below prints the ASIO latency which doesn't include the // buffer processor latency. it reports the added latency separately PA_DEBUG(("PaAsio : ASIO InputLatency = %ld (%ld ms), added buffProc:%ld (%ld ms)\n", stream->asioInputLatencyFrames, (long)((stream->asioInputLatencyFrames*1000)/ sampleRate), PaUtil_GetBufferProcessorInputLatencyFrames(&stream->bufferProcessor), (long)((PaUtil_GetBufferProcessorInputLatencyFrames(&stream->bufferProcessor)*1000)/ sampleRate) )); PA_DEBUG(("PaAsio : ASIO OuputLatency = %ld (%ld ms), added buffProc:%ld (%ld ms)\n", stream->asioOutputLatencyFrames, (long)((stream->asioOutputLatencyFrames*1000)/ sampleRate), PaUtil_GetBufferProcessorOutputLatencyFrames(&stream->bufferProcessor), (long)((PaUtil_GetBufferProcessorOutputLatencyFrames(&stream->bufferProcessor)*1000)/ sampleRate) )); } stream->asioHostApi = asioHostApi; stream->framesPerHostCallback = framesPerHostBuffer; stream->inputChannelCount = inputChannelCount; stream->outputChannelCount = outputChannelCount; stream->postOutput = driverInfo->postOutput; stream->isStopped = 1; stream->isActive = 0; asioHostApi->openAsioDeviceIndex = asioDeviceIndex; theAsioStream = stream; *s = (PaStream*)stream; return result; error: PA_DEBUG(("goto errored\n")); if( stream ) { if( stream->blockingState ) { if( blockingBufferProcessorInited ) PaUtil_TerminateBufferProcessor( &stream->blockingState->bufferProcessor ); if( stream->blockingState->writeRingBufferData ) PaUtil_FreeMemory( stream->blockingState->writeRingBufferData ); if( stream->blockingState->writeStreamBuffer ) PaUtil_FreeMemory( stream->blockingState->writeStreamBuffer ); if( blockingWriteBuffersReadyEventInitialized ) CloseHandle( stream->blockingState->writeBuffersReadyEvent ); if( stream->blockingState->readRingBufferData ) PaUtil_FreeMemory( stream->blockingState->readRingBufferData ); if( stream->blockingState->readStreamBuffer ) PaUtil_FreeMemory( stream->blockingState->readStreamBuffer ); if( blockingReadFramesReadyEventInitialized ) CloseHandle( stream->blockingState->readFramesReadyEvent ); PaUtil_FreeMemory( stream->blockingState ); } if( callbackBufferProcessorInited ) PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); if( completedBuffersPlayedEventInited ) CloseHandle( stream->completedBuffersPlayedEvent ); if( stream->asioBufferInfos ) PaUtil_FreeMemory( stream->asioBufferInfos ); if( stream->asioChannelInfos ) PaUtil_FreeMemory( stream->asioChannelInfos ); if( stream->bufferPtrs ) PaUtil_FreeMemory( stream->bufferPtrs ); PaUtil_FreeMemory( stream ); } if( asioBuffersCreated ) ASIODisposeBuffers(); if( asioIsInitialized ) { UnloadAsioDriver(); } return result; } /* When CloseStream() is called, the multi-api layer ensures that the stream has already been stopped or aborted. */ static PaError CloseStream( PaStream* s ) { PaError result = paNoError; PaAsioStream *stream = (PaAsioStream*)s; /* IMPLEMENT ME: - additional stream closing + cleanup */ PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); stream->asioHostApi->openAsioDeviceIndex = paNoDevice; CloseHandle( stream->completedBuffersPlayedEvent ); /* Using blocking i/o interface... */ if( stream->blockingState ) { PaUtil_TerminateBufferProcessor( &stream->blockingState->bufferProcessor ); if( stream->inputChannelCount ) { PaUtil_FreeMemory( stream->blockingState->readRingBufferData ); PaUtil_FreeMemory( stream->blockingState->readStreamBuffer ); CloseHandle( stream->blockingState->readFramesReadyEvent ); } if( stream->outputChannelCount ) { PaUtil_FreeMemory( stream->blockingState->writeRingBufferData ); PaUtil_FreeMemory( stream->blockingState->writeStreamBuffer ); CloseHandle( stream->blockingState->writeBuffersReadyEvent ); } PaUtil_FreeMemory( stream->blockingState ); } PaUtil_FreeMemory( stream->asioBufferInfos ); PaUtil_FreeMemory( stream->asioChannelInfos ); PaUtil_FreeMemory( stream->bufferPtrs ); PaUtil_FreeMemory( stream ); ASIODisposeBuffers(); UnloadAsioDriver(); theAsioStream = 0; return result; } static void bufferSwitch(long index, ASIOBool directProcess) { //TAKEN FROM THE ASIO SDK // the actual processing callback. // Beware that this is normally in a seperate thread, hence be sure that // you take care about thread synchronization. This is omitted here for // simplicity. // as this is a "back door" into the bufferSwitchTimeInfo a timeInfo needs // to be created though it will only set the timeInfo.samplePosition and // timeInfo.systemTime fields and the according flags ASIOTime timeInfo; memset( &timeInfo, 0, sizeof (timeInfo) ); // get the time stamp of the buffer, not necessary if no // synchronization to other media is required if( ASIOGetSamplePosition(&timeInfo.timeInfo.samplePosition, &timeInfo.timeInfo.systemTime) == ASE_OK) timeInfo.timeInfo.flags = kSystemTimeValid | kSamplePositionValid; // Call the real callback bufferSwitchTimeInfo( &timeInfo, index, directProcess ); } // conversion from 64 bit ASIOSample/ASIOTimeStamp to double float #if NATIVE_INT64 #define ASIO64toDouble(a) (a) #else const double twoRaisedTo32 = 4294967296.; #define ASIO64toDouble(a) ((a).lo + (a).hi * twoRaisedTo32) #endif static ASIOTime *bufferSwitchTimeInfo( ASIOTime *timeInfo, long index, ASIOBool directProcess ) { // the actual processing callback. // Beware that this is normally in a seperate thread, hence be sure that // you take care about thread synchronization. /* The SDK says the following about the directProcess flag: suggests to the host whether it should immediately start processing (directProcess == ASIOTrue), or whether its process should be deferred because the call comes from a very low level (for instance, a high level priority interrupt), and direct processing would cause timing instabilities for the rest of the system. If in doubt, directProcess should be set to ASIOFalse. We just ignore directProcess. This could cause incompatibilities with drivers which really don't want the audio processing to occur in this callback, but none have been identified yet. */ (void) directProcess; /* suppress unused parameter warning */ #if 0 // store the timeInfo for later use asioDriverInfo.tInfo = *timeInfo; // get the time stamp of the buffer, not necessary if no // synchronization to other media is required if (timeInfo->timeInfo.flags & kSystemTimeValid) asioDriverInfo.nanoSeconds = ASIO64toDouble(timeInfo->timeInfo.systemTime); else asioDriverInfo.nanoSeconds = 0; if (timeInfo->timeInfo.flags & kSamplePositionValid) asioDriverInfo.samples = ASIO64toDouble(timeInfo->timeInfo.samplePosition); else asioDriverInfo.samples = 0; if (timeInfo->timeCode.flags & kTcValid) asioDriverInfo.tcSamples = ASIO64toDouble(timeInfo->timeCode.timeCodeSamples); else asioDriverInfo.tcSamples = 0; // get the system reference time asioDriverInfo.sysRefTime = get_sys_reference_time(); #endif #if 0 // a few debug messages for the Windows device driver developer // tells you the time when driver got its interrupt and the delay until the app receives // the event notification. static double last_samples = 0; char tmp[128]; sprintf (tmp, "diff: %d / %d ms / %d ms / %d samples \n", asioDriverInfo.sysRefTime - (long)(asioDriverInfo.nanoSeconds / 1000000.0), asioDriverInfo.sysRefTime, (long)(asioDriverInfo.nanoSeconds / 1000000.0), (long)(asioDriverInfo.samples - last_samples)); OutputDebugString (tmp); last_samples = asioDriverInfo.samples; #endif if( !theAsioStream ) return 0L; // protect against reentrancy if( PaAsio_AtomicIncrement(&theAsioStream->reenterCount) ) { theAsioStream->reenterError++; //DBUG(("bufferSwitchTimeInfo : reentrancy detection = %d\n", asioDriverInfo.reenterError)); return 0L; } int buffersDone = 0; do { if( buffersDone > 0 ) { // this is a reentered buffer, we missed processing it on time // set the input overflow and output underflow flags as appropriate if( theAsioStream->inputChannelCount > 0 ) theAsioStream->callbackFlags |= paInputOverflow; if( theAsioStream->outputChannelCount > 0 ) theAsioStream->callbackFlags |= paOutputUnderflow; } else { if( theAsioStream->zeroOutput ) { ZeroOutputBuffers( theAsioStream, index ); // Finally if the driver supports the ASIOOutputReady() optimization, // do it here, all data are in place if( theAsioStream->postOutput ) ASIOOutputReady(); if( theAsioStream->stopProcessing ) { if( theAsioStream->stopPlayoutCount < 2 ) { ++theAsioStream->stopPlayoutCount; if( theAsioStream->stopPlayoutCount == 2 ) { theAsioStream->isActive = 0; if( theAsioStream->streamRepresentation.streamFinishedCallback != 0 ) theAsioStream->streamRepresentation.streamFinishedCallback( theAsioStream->streamRepresentation.userData ); theAsioStream->streamFinishedCallbackCalled = true; SetEvent( theAsioStream->completedBuffersPlayedEvent ); } } } } else { #if 0 /* see: "ASIO callback underflow/overflow buffer slip detection doesn't work" http://www.portaudio.com/trac/ticket/110 */ // test code to try to detect slip conditions... these may work on some systems // but neither of them work on the RME Digi96 // check that sample delta matches buffer size (otherwise we must have skipped // a buffer. static double last_samples = -512; double samples; //if( timeInfo->timeCode.flags & kTcValid ) // samples = ASIO64toDouble(timeInfo->timeCode.timeCodeSamples); //else samples = ASIO64toDouble(timeInfo->timeInfo.samplePosition); int delta = samples - last_samples; //printf( "%d\n", delta); last_samples = samples; if( delta > theAsioStream->framesPerHostCallback ) { if( theAsioStream->inputChannelCount > 0 ) theAsioStream->callbackFlags |= paInputOverflow; if( theAsioStream->outputChannelCount > 0 ) theAsioStream->callbackFlags |= paOutputUnderflow; } // check that the buffer index is not the previous index (which would indicate // that a buffer was skipped. static int previousIndex = 1; if( index == previousIndex ) { if( theAsioStream->inputChannelCount > 0 ) theAsioStream->callbackFlags |= paInputOverflow; if( theAsioStream->outputChannelCount > 0 ) theAsioStream->callbackFlags |= paOutputUnderflow; } previousIndex = index; #endif int i; PaUtil_BeginCpuLoadMeasurement( &theAsioStream->cpuLoadMeasurer ); PaStreamCallbackTimeInfo paTimeInfo; // asio systemTime is supposed to be measured according to the same // clock as timeGetTime paTimeInfo.currentTime = (ASIO64toDouble( timeInfo->timeInfo.systemTime ) * .000000001); /* patch from Paul Boege */ paTimeInfo.inputBufferAdcTime = paTimeInfo.currentTime - ((double)theAsioStream->asioInputLatencyFrames/theAsioStream->streamRepresentation.streamInfo.sampleRate); paTimeInfo.outputBufferDacTime = paTimeInfo.currentTime + ((double)theAsioStream->asioOutputLatencyFrames/theAsioStream->streamRepresentation.streamInfo.sampleRate); /* old version is buggy because the buffer processor also adds in its latency to the time parameters paTimeInfo.inputBufferAdcTime = paTimeInfo.currentTime - theAsioStream->streamRepresentation.streamInfo.inputLatency; paTimeInfo.outputBufferDacTime = paTimeInfo.currentTime + theAsioStream->streamRepresentation.streamInfo.outputLatency; */ /* Disabled! Stopping and re-starting the stream causes an input overflow / output underflow. S.Fischer */ #if 0 // detect underflows by checking inter-callback time > 2 buffer period static double previousTime = -1; if( previousTime > 0 ){ double delta = paTimeInfo.currentTime - previousTime; if( delta >= 2. * (theAsioStream->framesPerHostCallback / theAsioStream->streamRepresentation.streamInfo.sampleRate) ){ if( theAsioStream->inputChannelCount > 0 ) theAsioStream->callbackFlags |= paInputOverflow; if( theAsioStream->outputChannelCount > 0 ) theAsioStream->callbackFlags |= paOutputUnderflow; } } previousTime = paTimeInfo.currentTime; #endif // note that the above input and output times do not need to be // adjusted for the latency of the buffer processor -- the buffer // processor handles that. if( theAsioStream->inputBufferConverter ) { for( i=0; iinputChannelCount; i++ ) { theAsioStream->inputBufferConverter( theAsioStream->inputBufferPtrs[index][i], theAsioStream->inputShift, theAsioStream->framesPerHostCallback ); } } PaUtil_BeginBufferProcessing( &theAsioStream->bufferProcessor, &paTimeInfo, theAsioStream->callbackFlags ); /* reset status flags once they've been passed to the callback */ theAsioStream->callbackFlags = 0; PaUtil_SetInputFrameCount( &theAsioStream->bufferProcessor, 0 /* default to host buffer size */ ); for( i=0; iinputChannelCount; ++i ) PaUtil_SetNonInterleavedInputChannel( &theAsioStream->bufferProcessor, i, theAsioStream->inputBufferPtrs[index][i] ); PaUtil_SetOutputFrameCount( &theAsioStream->bufferProcessor, 0 /* default to host buffer size */ ); for( i=0; ioutputChannelCount; ++i ) PaUtil_SetNonInterleavedOutputChannel( &theAsioStream->bufferProcessor, i, theAsioStream->outputBufferPtrs[index][i] ); int callbackResult; if( theAsioStream->stopProcessing ) callbackResult = paComplete; else callbackResult = paContinue; unsigned long framesProcessed = PaUtil_EndBufferProcessing( &theAsioStream->bufferProcessor, &callbackResult ); if( theAsioStream->outputBufferConverter ) { for( i=0; ioutputChannelCount; i++ ) { theAsioStream->outputBufferConverter( theAsioStream->outputBufferPtrs[index][i], theAsioStream->outputShift, theAsioStream->framesPerHostCallback ); } } PaUtil_EndCpuLoadMeasurement( &theAsioStream->cpuLoadMeasurer, framesProcessed ); // Finally if the driver supports the ASIOOutputReady() optimization, // do it here, all data are in place if( theAsioStream->postOutput ) ASIOOutputReady(); if( callbackResult == paContinue ) { /* nothing special to do */ } else if( callbackResult == paAbort ) { /* finish playback immediately */ theAsioStream->isActive = 0; if( theAsioStream->streamRepresentation.streamFinishedCallback != 0 ) theAsioStream->streamRepresentation.streamFinishedCallback( theAsioStream->streamRepresentation.userData ); theAsioStream->streamFinishedCallbackCalled = true; SetEvent( theAsioStream->completedBuffersPlayedEvent ); theAsioStream->zeroOutput = true; } else /* paComplete or other non-zero value indicating complete */ { /* Finish playback once currently queued audio has completed. */ theAsioStream->stopProcessing = true; if( PaUtil_IsBufferProcessorOutputEmpty( &theAsioStream->bufferProcessor ) ) { theAsioStream->zeroOutput = true; theAsioStream->stopPlayoutCount = 0; } } } } ++buffersDone; }while( PaAsio_AtomicDecrement(&theAsioStream->reenterCount) >= 0 ); return 0L; } static void sampleRateChanged(ASIOSampleRate sRate) { // TAKEN FROM THE ASIO SDK // do whatever you need to do if the sample rate changed // usually this only happens during external sync. // Audio processing is not stopped by the driver, actual sample rate // might not have even changed, maybe only the sample rate status of an // AES/EBU or S/PDIF digital input at the audio device. // You might have to update time/sample related conversion routines, etc. (void) sRate; /* unused parameter */ PA_DEBUG( ("sampleRateChanged : %d \n", sRate)); } static long asioMessages(long selector, long value, void* message, double* opt) { // TAKEN FROM THE ASIO SDK // currently the parameters "value", "message" and "opt" are not used. long ret = 0; (void) message; /* unused parameters */ (void) opt; PA_DEBUG( ("asioMessages : %d , %d \n", selector, value)); switch(selector) { case kAsioSelectorSupported: if(value == kAsioResetRequest || value == kAsioEngineVersion || value == kAsioResyncRequest || value == kAsioLatenciesChanged // the following three were added for ASIO 2.0, you don't necessarily have to support them || value == kAsioSupportsTimeInfo || value == kAsioSupportsTimeCode || value == kAsioSupportsInputMonitor) ret = 1L; break; case kAsioBufferSizeChange: //printf("kAsioBufferSizeChange \n"); break; case kAsioResetRequest: // defer the task and perform the reset of the driver during the next "safe" situation // You cannot reset the driver right now, as this code is called from the driver. // Reset the driver is done by completely destruct is. I.e. ASIOStop(), ASIODisposeBuffers(), Destruction // Afterwards you initialize the driver again. /*FIXME: commented the next line out see: "PA/ASIO ignores some driver notifications it probably shouldn't" http://www.portaudio.com/trac/ticket/108 */ //asioDriverInfo.stopped; // In this sample the processing will just stop ret = 1L; break; case kAsioResyncRequest: // This informs the application, that the driver encountered some non fatal data loss. // It is used for synchronization purposes of different media. // Added mainly to work around the Win16Mutex problems in Windows 95/98 with the // Windows Multimedia system, which could loose data because the Mutex was hold too long // by another thread. // However a driver can issue it in other situations, too. ret = 1L; break; case kAsioLatenciesChanged: // This will inform the host application that the drivers were latencies changed. // Beware, it this does not mean that the buffer sizes have changed! // You might need to update internal delay data. ret = 1L; //printf("kAsioLatenciesChanged \n"); break; case kAsioEngineVersion: // return the supported ASIO version of the host application // If a host applications does not implement this selector, ASIO 1.0 is assumed // by the driver ret = 2L; break; case kAsioSupportsTimeInfo: // informs the driver wether the asioCallbacks.bufferSwitchTimeInfo() callback // is supported. // For compatibility with ASIO 1.0 drivers the host application should always support // the "old" bufferSwitch method, too. ret = 1; break; case kAsioSupportsTimeCode: // informs the driver wether application is interested in time code info. // If an application does not need to know about time code, the driver has less work // to do. ret = 0; break; } return ret; } static PaError StartStream( PaStream *s ) { PaError result = paNoError; PaAsioStream *stream = (PaAsioStream*)s; PaAsioStreamBlockingState *blockingState = stream->blockingState; ASIOError asioError; if( stream->outputChannelCount > 0 ) { ZeroOutputBuffers( stream, 0 ); ZeroOutputBuffers( stream, 1 ); } PaUtil_ResetBufferProcessor( &stream->bufferProcessor ); stream->stopProcessing = false; stream->zeroOutput = false; /* Reentrancy counter initialisation */ stream->reenterCount = -1; stream->reenterError = 0; stream->callbackFlags = 0; if( ResetEvent( stream->completedBuffersPlayedEvent ) == 0 ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() ); } /* Using blocking i/o interface... */ if( blockingState ) { /* Reset blocking i/o buffer processor. */ PaUtil_ResetBufferProcessor( &blockingState->bufferProcessor ); /* If we're about to process some input data. */ if( stream->inputChannelCount ) { /* Reset callback-ReadStream sync event. */ if( ResetEvent( blockingState->readFramesReadyEvent ) == 0 ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() ); } /* Flush blocking i/o ring buffer. */ PaUtil_FlushRingBuffer( &blockingState->readRingBuffer ); (*blockingState->bufferProcessor.inputZeroer)( blockingState->readRingBuffer.buffer, 1, blockingState->bufferProcessor.inputChannelCount * blockingState->readRingBuffer.bufferSize ); } /* If we're about to process some output data. */ if( stream->outputChannelCount ) { /* Reset callback-WriteStream sync event. */ if( ResetEvent( blockingState->writeBuffersReadyEvent ) == 0 ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() ); } /* Flush blocking i/o ring buffer. */ PaUtil_FlushRingBuffer( &blockingState->writeRingBuffer ); (*blockingState->bufferProcessor.outputZeroer)( blockingState->writeRingBuffer.buffer, 1, blockingState->bufferProcessor.outputChannelCount * blockingState->writeRingBuffer.bufferSize ); /* Initialize the output ring buffer to "silence". */ PaUtil_AdvanceRingBufferWriteIndex( &blockingState->writeRingBuffer, blockingState->writeRingBufferInitialFrames ); } /* Clear requested frames / buffers count. */ blockingState->writeBuffersRequested = 0; blockingState->readFramesRequested = 0; blockingState->writeBuffersRequestedFlag = FALSE; blockingState->readFramesRequestedFlag = FALSE; blockingState->outputUnderflowFlag = FALSE; blockingState->inputOverflowFlag = FALSE; blockingState->stopFlag = FALSE; } if( result == paNoError ) { assert( theAsioStream == stream ); /* theAsioStream should be set correctly in OpenStream */ /* initialize these variables before the callback has a chance to be invoked */ stream->isStopped = 0; stream->isActive = 1; stream->streamFinishedCallbackCalled = false; asioError = ASIOStart(); if( asioError != ASE_OK ) { stream->isStopped = 1; stream->isActive = 0; result = paUnanticipatedHostError; PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); } } return result; } static void EnsureCallbackHasCompleted( PaAsioStream *stream ) { // make sure that the callback is not still in-flight after ASIOStop() // returns. This has been observed to happen on the Hoontech DSP24 for // example. int count = 2000; // only wait for 2 seconds, rather than hanging. while( stream->reenterCount != -1 && count > 0 ) { Sleep(1); --count; } } static PaError StopStream( PaStream *s ) { PaError result = paNoError; PaAsioStream *stream = (PaAsioStream*)s; PaAsioStreamBlockingState *blockingState = stream->blockingState; ASIOError asioError; if( stream->isActive ) { /* If blocking i/o output is in use */ if( blockingState && stream->outputChannelCount ) { /* Request the whole output buffer to be available. */ blockingState->writeBuffersRequested = blockingState->writeRingBuffer.bufferSize; /* Signalize that additional buffers are need. */ blockingState->writeBuffersRequestedFlag = TRUE; /* Set flag to indicate the playback is to be stopped. */ blockingState->stopFlag = TRUE; /* Wait until requested number of buffers has been freed. Time out after twice the blocking i/o ouput buffer could have been consumed. */ DWORD timeout = (DWORD)( 2 * blockingState->writeRingBuffer.bufferSize * 1000 / stream->streamRepresentation.streamInfo.sampleRate ); DWORD waitResult = WaitForSingleObject( blockingState->writeBuffersReadyEvent, timeout ); /* If something seriously went wrong... */ if( waitResult == WAIT_FAILED ) { PA_DEBUG(("WaitForSingleObject() failed in StopStream()\n")); result = paUnanticipatedHostError; PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() ); } else if( waitResult == WAIT_TIMEOUT ) { PA_DEBUG(("WaitForSingleObject() timed out in StopStream()\n")); result = paTimedOut; } } stream->stopProcessing = true; /* wait for the stream to finish playing out enqueued buffers. timeout after four times the stream latency. @todo should use a better time out value - if the user buffer length is longer than the asio buffer size then that should be taken into account. */ if( WaitForSingleObject( stream->completedBuffersPlayedEvent, (DWORD)(stream->streamRepresentation.streamInfo.outputLatency * 1000. * 4.) ) == WAIT_TIMEOUT ) { PA_DEBUG(("WaitForSingleObject() timed out in StopStream()\n" )); } } asioError = ASIOStop(); if( asioError == ASE_OK ) { EnsureCallbackHasCompleted( stream ); } else { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); } stream->isStopped = 1; stream->isActive = 0; if( !stream->streamFinishedCallbackCalled ) { if( stream->streamRepresentation.streamFinishedCallback != 0 ) stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); } return result; } static PaError AbortStream( PaStream *s ) { PaError result = paNoError; PaAsioStream *stream = (PaAsioStream*)s; ASIOError asioError; stream->zeroOutput = true; asioError = ASIOStop(); if( asioError == ASE_OK ) { EnsureCallbackHasCompleted( stream ); } else { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); } stream->isStopped = 1; stream->isActive = 0; if( !stream->streamFinishedCallbackCalled ) { if( stream->streamRepresentation.streamFinishedCallback != 0 ) stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); } return result; } static PaError IsStreamStopped( PaStream *s ) { PaAsioStream *stream = (PaAsioStream*)s; return stream->isStopped; } static PaError IsStreamActive( PaStream *s ) { PaAsioStream *stream = (PaAsioStream*)s; return stream->isActive; } static PaTime GetStreamTime( PaStream *s ) { (void) s; /* unused parameter */ return (double)timeGetTime() * .001; } static double GetStreamCpuLoad( PaStream* s ) { PaAsioStream *stream = (PaAsioStream*)s; return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ); } /* As separate stream interfaces are used for blocking and callback streams, the following functions can be guaranteed to only be called for blocking streams. */ static PaError ReadStream( PaStream *s , void *buffer, unsigned long frames ) { PaError result = paNoError; /* Initial return value. */ PaAsioStream *stream = (PaAsioStream*)s; /* The PA ASIO stream. */ /* Pointer to the blocking i/o data struct. */ PaAsioStreamBlockingState *blockingState = stream->blockingState; /* Get blocking i/o buffer processor and ring buffer pointers. */ PaUtilBufferProcessor *pBp = &blockingState->bufferProcessor; PaUtilRingBuffer *pRb = &blockingState->readRingBuffer; /* Ring buffer segment(s) used for writing. */ void *pRingBufferData1st = NULL; /* First segment. (Mandatory) */ void *pRingBufferData2nd = NULL; /* Second segment. (Optional) */ /* Number of frames per ring buffer segment. */ long lRingBufferSize1st = 0; /* First segment. (Mandatory) */ long lRingBufferSize2nd = 0; /* Second segment. (Optional) */ /* Get number of frames to be processed per data block. */ unsigned long lFramesPerBlock = stream->bufferProcessor.framesPerUserBuffer; /* Actual number of frames that has been copied into the ring buffer. */ unsigned long lFramesCopied = 0; /* The number of remaining unprocessed dtat frames. */ unsigned long lFramesRemaining = frames; /* Copy the input argument to avoid pointer increment! */ const void *userBuffer; unsigned int i; /* Just a counter. */ /* About the time, needed to process 8 data blocks. */ DWORD timeout = (DWORD)( 8 * lFramesPerBlock * 1000 / stream->streamRepresentation.streamInfo.sampleRate ); DWORD waitResult = 0; /* Check if the stream is still available ready to gather new data. */ if( blockingState->stopFlag || !stream->isActive ) { PA_DEBUG(("Warning! Stream no longer available for reading in ReadStream()\n")); result = paStreamIsStopped; return result; } /* If the stream is a input stream. */ if( stream->inputChannelCount ) { /* Prepare buffer access. */ if( !pBp->userOutputIsInterleaved ) { userBuffer = blockingState->readStreamBuffer; for( i = 0; iinputChannelCount; ++i ) { ((void**)userBuffer)[i] = ((void**)buffer)[i]; } } /* Use the unchanged buffer. */ else { userBuffer = buffer; } do /* Internal block processing for too large user data buffers. */ { /* Get the size of the current data block to be processed. */ lFramesPerBlock =(lFramesPerBlock < lFramesRemaining) ? lFramesPerBlock : lFramesRemaining; /* Use predefined block size for as long there are enough buffers available, thereafter reduce the processing block size to match the number of remaining buffers. So the final data block is processed although it may be incomplete. */ /* If the available amount of data frames is insufficient. */ if( PaUtil_GetRingBufferReadAvailable(pRb) < (long) lFramesPerBlock ) { /* Make sure, the event isn't already set! */ /* ResetEvent( blockingState->readFramesReadyEvent ); */ /* Set the number of requested buffers. */ blockingState->readFramesRequested = lFramesPerBlock; /* Signalize that additional buffers are need. */ blockingState->readFramesRequestedFlag = TRUE; /* Wait until requested number of buffers has been freed. */ waitResult = WaitForSingleObject( blockingState->readFramesReadyEvent, timeout ); /* If something seriously went wrong... */ if( waitResult == WAIT_FAILED ) { PA_DEBUG(("WaitForSingleObject() failed in ReadStream()\n")); result = paUnanticipatedHostError; PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() ); return result; } else if( waitResult == WAIT_TIMEOUT ) { PA_DEBUG(("WaitForSingleObject() timed out in ReadStream()\n")); /* If block processing has stopped, abort! */ if( blockingState->stopFlag ) { return result = paStreamIsStopped; } /* If a timeout is encountered, give up eventually. */ return result = paTimedOut; } } /* Now, the ring buffer contains the required amount of data frames. (Therefor we don't need to check the return argument of PaUtil_GetRingBufferReadRegions(). ;-) ) */ /* Retrieve pointer(s) to the ring buffer's current write position(s). If the first buffer segment is too small to store the requested number of bytes, an additional second segment is returned. Otherwise, i.e. if the first segment is large enough, the second segment's pointer will be NULL. */ PaUtil_GetRingBufferReadRegions(pRb , lFramesPerBlock , &pRingBufferData1st, &lRingBufferSize1st, &pRingBufferData2nd, &lRingBufferSize2nd); /* Set number of frames to be copied from the ring buffer. */ PaUtil_SetInputFrameCount( pBp, lRingBufferSize1st ); /* Setup ring buffer access. */ PaUtil_SetInterleavedInputChannels(pBp , /* Buffer processor. */ 0 , /* The first channel's index. */ pRingBufferData1st, /* First ring buffer segment. */ 0 ); /* Use all available channels. */ /* If a second ring buffer segment is required. */ if( lRingBufferSize2nd ) { /* Set number of frames to be copied from the ring buffer. */ PaUtil_Set2ndInputFrameCount( pBp, lRingBufferSize2nd ); /* Setup ring buffer access. */ PaUtil_Set2ndInterleavedInputChannels(pBp , /* Buffer processor. */ 0 , /* The first channel's index. */ pRingBufferData2nd, /* Second ring buffer segment. */ 0 ); /* Use all available channels. */ } /* Let the buffer processor handle "copy and conversion" and update the ring buffer indices manually. */ lFramesCopied = PaUtil_CopyInput( pBp, &buffer, lFramesPerBlock ); PaUtil_AdvanceRingBufferReadIndex( pRb, lFramesCopied ); /* Decrease number of unprocessed frames. */ lFramesRemaining -= lFramesCopied; } /* Continue with the next data chunk. */ while( lFramesRemaining ); /* If there has been an input overflow within the callback */ if( blockingState->inputOverflowFlag ) { blockingState->inputOverflowFlag = FALSE; /* Return the corresponding error code. */ result = paInputOverflowed; } } /* If this is not an input stream. */ else { result = paCanNotReadFromAnOutputOnlyStream; } return result; } static PaError WriteStream( PaStream *s , const void *buffer, unsigned long frames ) { PaError result = paNoError; /* Initial return value. */ PaAsioStream *stream = (PaAsioStream*)s; /* The PA ASIO stream. */ /* Pointer to the blocking i/o data struct. */ PaAsioStreamBlockingState *blockingState = stream->blockingState; /* Get blocking i/o buffer processor and ring buffer pointers. */ PaUtilBufferProcessor *pBp = &blockingState->bufferProcessor; PaUtilRingBuffer *pRb = &blockingState->writeRingBuffer; /* Ring buffer segment(s) used for writing. */ void *pRingBufferData1st = NULL; /* First segment. (Mandatory) */ void *pRingBufferData2nd = NULL; /* Second segment. (Optional) */ /* Number of frames per ring buffer segment. */ long lRingBufferSize1st = 0; /* First segment. (Mandatory) */ long lRingBufferSize2nd = 0; /* Second segment. (Optional) */ /* Get number of frames to be processed per data block. */ unsigned long lFramesPerBlock = stream->bufferProcessor.framesPerUserBuffer; /* Actual number of frames that has been copied into the ring buffer. */ unsigned long lFramesCopied = 0; /* The number of remaining unprocessed dtat frames. */ unsigned long lFramesRemaining = frames; /* About the time, needed to process 8 data blocks. */ DWORD timeout = (DWORD)( 8 * lFramesPerBlock * 1000 / stream->streamRepresentation.streamInfo.sampleRate ); DWORD waitResult = 0; /* Copy the input argument to avoid pointer increment! */ const void *userBuffer; unsigned int i; /* Just a counter. */ /* Check if the stream ist still available ready to recieve new data. */ if( blockingState->stopFlag || !stream->isActive ) { PA_DEBUG(("Warning! Stream no longer available for writing in WriteStream()\n")); result = paStreamIsStopped; return result; } /* If the stream is a output stream. */ if( stream->outputChannelCount ) { /* Prepare buffer access. */ if( !pBp->userOutputIsInterleaved ) { userBuffer = blockingState->writeStreamBuffer; for( i = 0; ioutputChannelCount; ++i ) { ((const void**)userBuffer)[i] = ((const void**)buffer)[i]; } } /* Use the unchanged buffer. */ else { userBuffer = buffer; } do /* Internal block processing for too large user data buffers. */ { /* Get the size of the current data block to be processed. */ lFramesPerBlock =(lFramesPerBlock < lFramesRemaining) ? lFramesPerBlock : lFramesRemaining; /* Use predefined block size for as long there are enough frames available, thereafter reduce the processing block size to match the number of remaining frames. So the final data block is processed although it may be incomplete. */ /* If the available amount of buffers is insufficient. */ if( PaUtil_GetRingBufferWriteAvailable(pRb) < (long) lFramesPerBlock ) { /* Make sure, the event isn't already set! */ /* ResetEvent( blockingState->writeBuffersReadyEvent ); */ /* Set the number of requested buffers. */ blockingState->writeBuffersRequested = lFramesPerBlock; /* Signalize that additional buffers are need. */ blockingState->writeBuffersRequestedFlag = TRUE; /* Wait until requested number of buffers has been freed. */ waitResult = WaitForSingleObject( blockingState->writeBuffersReadyEvent, timeout ); /* If something seriously went wrong... */ if( waitResult == WAIT_FAILED ) { PA_DEBUG(("WaitForSingleObject() failed in WriteStream()\n")); result = paUnanticipatedHostError; PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() ); return result; } else if( waitResult == WAIT_TIMEOUT ) { PA_DEBUG(("WaitForSingleObject() timed out in WriteStream()\n")); /* If block processing has stopped, abort! */ if( blockingState->stopFlag ) { return result = paStreamIsStopped; } /* If a timeout is encountered, give up eventually. */ return result = paTimedOut; } } /* Now, the ring buffer contains the required amount of free space to store the provided number of data frames. (Therefor we don't need to check the return argument of PaUtil_GetRingBufferWriteRegions(). ;-) ) */ /* Retrieve pointer(s) to the ring buffer's current write position(s). If the first buffer segment is too small to store the requested number of bytes, an additional second segment is returned. Otherwise, i.e. if the first segment is large enough, the second segment's pointer will be NULL. */ PaUtil_GetRingBufferWriteRegions(pRb , lFramesPerBlock , &pRingBufferData1st, &lRingBufferSize1st, &pRingBufferData2nd, &lRingBufferSize2nd); /* Set number of frames to be copied to the ring buffer. */ PaUtil_SetOutputFrameCount( pBp, lRingBufferSize1st ); /* Setup ring buffer access. */ PaUtil_SetInterleavedOutputChannels(pBp , /* Buffer processor. */ 0 , /* The first channel's index. */ pRingBufferData1st, /* First ring buffer segment. */ 0 ); /* Use all available channels. */ /* If a second ring buffer segment is required. */ if( lRingBufferSize2nd ) { /* Set number of frames to be copied to the ring buffer. */ PaUtil_Set2ndOutputFrameCount( pBp, lRingBufferSize2nd ); /* Setup ring buffer access. */ PaUtil_Set2ndInterleavedOutputChannels(pBp , /* Buffer processor. */ 0 , /* The first channel's index. */ pRingBufferData2nd, /* Second ring buffer segment. */ 0 ); /* Use all available channels. */ } /* Let the buffer processor handle "copy and conversion" and update the ring buffer indices manually. */ lFramesCopied = PaUtil_CopyOutput( pBp, &userBuffer, lFramesPerBlock ); PaUtil_AdvanceRingBufferWriteIndex( pRb, lFramesCopied ); /* Decrease number of unprocessed frames. */ lFramesRemaining -= lFramesCopied; } /* Continue with the next data chunk. */ while( lFramesRemaining ); /* If there has been an output underflow within the callback */ if( blockingState->outputUnderflowFlag ) { blockingState->outputUnderflowFlag = FALSE; /* Return the corresponding error code. */ result = paOutputUnderflowed; } } /* If this is not an output stream. */ else { result = paCanNotWriteToAnInputOnlyStream; } return result; } static signed long GetStreamReadAvailable( PaStream* s ) { PaAsioStream *stream = (PaAsioStream*)s; /* Call buffer utility routine to get the number of available frames. */ return PaUtil_GetRingBufferReadAvailable( &stream->blockingState->readRingBuffer ); } static signed long GetStreamWriteAvailable( PaStream* s ) { PaAsioStream *stream = (PaAsioStream*)s; /* Call buffer utility routine to get the number of empty buffers. */ return PaUtil_GetRingBufferWriteAvailable( &stream->blockingState->writeRingBuffer ); } /* This routine will be called by the PortAudio engine when audio is needed. ** It may called at interrupt level on some machines so don't do anything ** that could mess up the system like calling malloc() or free(). */ static int BlockingIoPaCallback(const void *inputBuffer , void *outputBuffer , unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo , PaStreamCallbackFlags statusFlags , void *userData ) { PaError result = paNoError; /* Initial return value. */ PaAsioStream *stream = *(PaAsioStream**)userData; /* The PA ASIO stream. */ PaAsioStreamBlockingState *blockingState = stream->blockingState; /* Persume blockingState is valid, otherwise the callback wouldn't be running. */ /* Get a pointer to the stream's blocking i/o buffer processor. */ PaUtilBufferProcessor *pBp = &blockingState->bufferProcessor; PaUtilRingBuffer *pRb = NULL; /* If output data has been requested. */ if( stream->outputChannelCount ) { /* If the callback input argument signalizes a output underflow, make sure the WriteStream() function knows about it, too! */ if( statusFlags & paOutputUnderflowed ) { blockingState->outputUnderflowFlag = TRUE; } /* Access the corresponding ring buffer. */ pRb = &blockingState->writeRingBuffer; /* If the blocking i/o buffer contains enough output data, */ if( PaUtil_GetRingBufferReadAvailable(pRb) >= (long) framesPerBuffer ) { /* Extract the requested data from the ring buffer. */ PaUtil_ReadRingBuffer( pRb, outputBuffer, framesPerBuffer ); } else /* If no output data is available :-( */ { /* Signalize a write-buffer underflow. */ blockingState->outputUnderflowFlag = TRUE; /* Fill the output buffer with silence. */ (*pBp->outputZeroer)( outputBuffer, 1, pBp->outputChannelCount * framesPerBuffer ); /* If playback is to be stopped */ if( blockingState->stopFlag && PaUtil_GetRingBufferReadAvailable(pRb) < (long) framesPerBuffer ) { /* Extract all the remaining data from the ring buffer, whether it is a complete data block or not. */ PaUtil_ReadRingBuffer( pRb, outputBuffer, PaUtil_GetRingBufferReadAvailable(pRb) ); } } /* Set blocking i/o event? */ if( blockingState->writeBuffersRequestedFlag && PaUtil_GetRingBufferWriteAvailable(pRb) >= (long) blockingState->writeBuffersRequested ) { /* Reset buffer request. */ blockingState->writeBuffersRequestedFlag = FALSE; blockingState->writeBuffersRequested = 0; /* Signalize that requested buffers are ready. */ SetEvent( blockingState->writeBuffersReadyEvent ); /* What do we do if SetEvent() returns zero, i.e. the event could not be set? How to return errors from within the callback? - S.Fischer */ } } /* If input data has been supplied. */ if( stream->inputChannelCount ) { /* If the callback input argument signalizes a input overflow, make sure the ReadStream() function knows about it, too! */ if( statusFlags & paInputOverflowed ) { blockingState->inputOverflowFlag = TRUE; } /* Access the corresponding ring buffer. */ pRb = &blockingState->readRingBuffer; /* If the blocking i/o buffer contains not enough input buffers */ if( PaUtil_GetRingBufferWriteAvailable(pRb) < (long) framesPerBuffer ) { /* Signalize a read-buffer overflow. */ blockingState->inputOverflowFlag = TRUE; /* Remove some old data frames from the buffer. */ PaUtil_AdvanceRingBufferReadIndex( pRb, framesPerBuffer ); } /* Insert the current input data into the ring buffer. */ PaUtil_WriteRingBuffer( pRb, inputBuffer, framesPerBuffer ); /* Set blocking i/o event? */ if( blockingState->readFramesRequestedFlag && PaUtil_GetRingBufferReadAvailable(pRb) >= (long) blockingState->readFramesRequested ) { /* Reset buffer request. */ blockingState->readFramesRequestedFlag = FALSE; blockingState->readFramesRequested = 0; /* Signalize that requested buffers are ready. */ SetEvent( blockingState->readFramesReadyEvent ); /* What do we do if SetEvent() returns zero, i.e. the event could not be set? How to return errors from within the callback? - S.Fischer */ /** @todo report an error with PA_DEBUG */ } } return paContinue; } PaError PaAsio_ShowControlPanel( PaDeviceIndex device, void* systemSpecific ) { PaError result = paNoError; PaUtilHostApiRepresentation *hostApi; PaDeviceIndex hostApiDevice; ASIODriverInfo asioDriverInfo; ASIOError asioError; int asioIsInitialized = 0; PaAsioHostApiRepresentation *asioHostApi; PaAsioDeviceInfo *asioDeviceInfo; PaWinUtilComInitializationResult comInitializationResult; /* initialize COM again here, we might be in another thread */ result = PaWinUtil_CoInitialize( paASIO, &comInitializationResult ); if( result != paNoError ) return result; result = PaUtil_GetHostApiRepresentation( &hostApi, paASIO ); if( result != paNoError ) goto error; result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice, device, hostApi ); if( result != paNoError ) goto error; /* In theory we could proceed if the currently open device was the same one for which the control panel was requested, however because the window pointer is not available until this function is called we currently need to call ASIOInit() again here, which of course can't be done safely while a stream is open. */ asioHostApi = (PaAsioHostApiRepresentation*)hostApi; if( asioHostApi->openAsioDeviceIndex != paNoDevice ) { result = paDeviceUnavailable; goto error; } asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[hostApiDevice]; if( !asioHostApi->asioDrivers->loadDriver( const_cast(asioDeviceInfo->commonDeviceInfo.name) ) ) { result = paUnanticipatedHostError; goto error; } /* CRUCIAL!!! */ memset( &asioDriverInfo, 0, sizeof(ASIODriverInfo) ); asioDriverInfo.asioVersion = 2; asioDriverInfo.sysRef = systemSpecific; asioError = ASIOInit( &asioDriverInfo ); if( asioError != ASE_OK ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); goto error; } else { asioIsInitialized = 1; } PA_DEBUG(("PaAsio_ShowControlPanel: ASIOInit(): %s\n", PaAsio_GetAsioErrorText(asioError) )); PA_DEBUG(("asioVersion: ASIOInit(): %ld\n", asioDriverInfo.asioVersion )); PA_DEBUG(("driverVersion: ASIOInit(): %ld\n", asioDriverInfo.driverVersion )); PA_DEBUG(("Name: ASIOInit(): %s\n", asioDriverInfo.name )); PA_DEBUG(("ErrorMessage: ASIOInit(): %s\n", asioDriverInfo.errorMessage )); asioError = ASIOControlPanel(); if( asioError != ASE_OK ) { PA_DEBUG(("PaAsio_ShowControlPanel: ASIOControlPanel(): %s\n", PaAsio_GetAsioErrorText(asioError) )); result = paUnanticipatedHostError; PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); goto error; } PA_DEBUG(("PaAsio_ShowControlPanel: ASIOControlPanel(): %s\n", PaAsio_GetAsioErrorText(asioError) )); asioError = ASIOExit(); if( asioError != ASE_OK ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); asioIsInitialized = 0; goto error; } PA_DEBUG(("PaAsio_ShowControlPanel: ASIOExit(): %s\n", PaAsio_GetAsioErrorText(asioError) )); return result; error: if( asioIsInitialized ) { ASIOExit(); } PaWinUtil_CoUninitialize( paASIO, &comInitializationResult ); return result; } PaError PaAsio_GetInputChannelName( PaDeviceIndex device, int channelIndex, const char** channelName ) { PaError result = paNoError; PaUtilHostApiRepresentation *hostApi; PaDeviceIndex hostApiDevice; PaAsioDeviceInfo *asioDeviceInfo; result = PaUtil_GetHostApiRepresentation( &hostApi, paASIO ); if( result != paNoError ) goto error; result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice, device, hostApi ); if( result != paNoError ) goto error; asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[hostApiDevice]; if( channelIndex < 0 || channelIndex >= asioDeviceInfo->commonDeviceInfo.maxInputChannels ){ result = paInvalidChannelCount; goto error; } *channelName = asioDeviceInfo->asioChannelInfos[channelIndex].name; return paNoError; error: return result; } PaError PaAsio_GetOutputChannelName( PaDeviceIndex device, int channelIndex, const char** channelName ) { PaError result = paNoError; PaUtilHostApiRepresentation *hostApi; PaDeviceIndex hostApiDevice; PaAsioDeviceInfo *asioDeviceInfo; result = PaUtil_GetHostApiRepresentation( &hostApi, paASIO ); if( result != paNoError ) goto error; result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice, device, hostApi ); if( result != paNoError ) goto error; asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[hostApiDevice]; if( channelIndex < 0 || channelIndex >= asioDeviceInfo->commonDeviceInfo.maxOutputChannels ){ result = paInvalidChannelCount; goto error; } *channelName = asioDeviceInfo->asioChannelInfos[ asioDeviceInfo->commonDeviceInfo.maxInputChannels + channelIndex].name; return paNoError; error: return result; } /* NOTE: the following functions are ASIO-stream specific, and are called directly by client code. We need to check for many more error conditions here because we don't have the benefit of pa_front.c's parameter checking. */ static PaError GetAsioStreamPointer( PaAsioStream **stream, PaStream *s ) { PaError result; PaUtilHostApiRepresentation *hostApi; PaAsioHostApiRepresentation *asioHostApi; result = PaUtil_ValidateStreamPointer( s ); if( result != paNoError ) return result; result = PaUtil_GetHostApiRepresentation( &hostApi, paASIO ); if( result != paNoError ) return result; asioHostApi = (PaAsioHostApiRepresentation*)hostApi; if( PA_STREAM_REP( s )->streamInterface == &asioHostApi->callbackStreamInterface || PA_STREAM_REP( s )->streamInterface == &asioHostApi->blockingStreamInterface ) { /* s is an ASIO stream */ *stream = (PaAsioStream *)s; return paNoError; } else { return paIncompatibleStreamHostApi; } } PaError PaAsio_SetStreamSampleRate( PaStream* s, double sampleRate ) { PaAsioStream *stream; PaError result = GetAsioStreamPointer( &stream, s ); if( result != paNoError ) return result; if( stream != theAsioStream ) return paBadStreamPtr; return ValidateAndSetSampleRate( sampleRate ); } pd-0.46-7/portaudio/src/hostapi/asio/iasiothiscallresolver.h0000664000175000017500000002225012222201037022346 0ustar mspmsp// **************************************************************************** // File: IASIOThiscallResolver.h // Description: The IASIOThiscallResolver class implements the IASIO // interface and acts as a proxy to the real IASIO interface by // calling through its vptr table using the thiscall calling // convention. To put it another way, we interpose // IASIOThiscallResolver between ASIO SDK code and the driver. // This is necessary because most non-Microsoft compilers don't // implement the thiscall calling convention used by IASIO. // // iasiothiscallresolver.cpp contains the background of this // problem plus a technical description of the vptr // manipulations. // // In order to use this mechanism one simply has to add // iasiothiscallresolver.cpp to the list of files to compile // and #include // // Note that this #include must come after the other ASIO SDK // #includes, for example: // // #include // #include // #include // #include // #include // // Actually the important thing is to #include // after . We have // incorporated a test to enforce this ordering. // // The code transparently takes care of the interposition by // using macro substitution to intercept calls to ASIOInit() // and ASIOExit(). We save the original ASIO global // "theAsioDriver" in our "that" variable, and then set // "theAsioDriver" to equal our IASIOThiscallResolver instance. // // Whilst this method of resolving the thiscall problem requires // the addition of #include to client // code it has the advantage that it does not break the terms // of the ASIO licence by publishing it. We are NOT modifying // any Steinberg code here, we are merely implementing the IASIO // interface in the same way that we would need to do if we // wished to provide an open source ASIO driver. // // For compilation with MinGW -lole32 needs to be added to the // linker options. For BORLAND, linking with Import32.lib is // sufficient. // // The dependencies are with: CoInitialize, CoUninitialize, // CoCreateInstance, CLSIDFromString - used by asiolist.cpp // and are required on Windows whether ThiscallResolver is used // or not. // // Searching for the above strings in the root library path // of your compiler should enable the correct libraries to be // identified if they aren't immediately obvious. // // Note that the current implementation of IASIOThiscallResolver // is not COM compliant - it does not correctly implement the // IUnknown interface. Implementing it is not necessary because // it is not called by parts of the ASIO SDK which call through // theAsioDriver ptr. The IUnknown methods are implemented as // assert(false) to ensure that the code fails if they are // ever called. // Restrictions: None. Public Domain & Open Source distribute freely // You may use IASIOThiscallResolver commercially as well as // privately. // You the user assume the responsibility for the use of the // files, binary or text, and there is no guarantee or warranty, // expressed or implied, including but not limited to the // implied warranties of merchantability and fitness for a // particular purpose. You assume all responsibility and agree // to hold no entity, copyright holder or distributors liable // for any loss of data or inaccurate representations of data // as a result of using IASIOThiscallResolver. // Version: 1.4 Added separate macro CALL_THISCALL_1_DOUBLE from // Andrew Baldwin, and volatile for whole gcc asm blocks, // both for compatibility with newer gcc versions. Cleaned up // Borland asm to use one less register. // 1.3 Switched to including assert.h for better compatibility. // Wrapped entire .h and .cpp contents with a check for // _MSC_VER to provide better compatibility with MS compilers. // Changed Singleton implementation to use static instance // instead of freestore allocated instance. Removed ASIOExit // macro as it is no longer needed. // 1.2 Removed semicolons from ASIOInit and ASIOExit macros to // allow them to be embedded in expressions (if statements). // Cleaned up some comments. Removed combase.c dependency (it // doesn't compile with BCB anyway) by stubbing IUnknown. // 1.1 Incorporated comments from Ross Bencina including things // such as changing name from ThiscallResolver to // IASIOThiscallResolver, tidying up the constructor, fixing // a bug in IASIOThiscallResolver::ASIOExit() and improving // portability through the use of conditional compilation // 1.0 Initial working version. // Created: 6/09/2003 // Authors: Fraser Adams // Ross Bencina // Rene G. Ceballos // Martin Fay // Antti Silvast // Andrew Baldwin // // **************************************************************************** #ifndef included_iasiothiscallresolver_h #define included_iasiothiscallresolver_h // We only need IASIOThiscallResolver at all if we are on Win32. For other // platforms we simply bypass the IASIOThiscallResolver definition to allow us // to be safely #include'd whatever the platform to keep client code portable #if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) && !defined(_WIN64) // If microsoft compiler we can call IASIO directly so IASIOThiscallResolver // is not used. #if !defined(_MSC_VER) // The following is in order to ensure that this header is only included after // the other ASIO headers (except for the case of iasiothiscallresolver.cpp). // We need to do this because IASIOThiscallResolver works by eclipsing the // original definition of ASIOInit() with a macro (see below). #if !defined(iasiothiscallresolver_sourcefile) #if !defined(__ASIO_H) #error iasiothiscallresolver.h must be included AFTER asio.h #endif #endif #include #include /* From ASIO SDK */ class IASIOThiscallResolver : public IASIO { private: IASIO* that_; // Points to the real IASIO static IASIOThiscallResolver instance; // Singleton instance // Constructors - declared private so construction is limited to // our Singleton instance IASIOThiscallResolver(); IASIOThiscallResolver(IASIO* that); public: // Methods from the IUnknown interface. We don't fully implement IUnknown // because the ASIO SDK never calls these methods through theAsioDriver ptr. // These methods are implemented as assert(false). virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppv); virtual ULONG STDMETHODCALLTYPE AddRef(); virtual ULONG STDMETHODCALLTYPE Release(); // Methods from the IASIO interface, implemented as forwarning calls to that. virtual ASIOBool init(void *sysHandle); virtual void getDriverName(char *name); virtual long getDriverVersion(); virtual void getErrorMessage(char *string); virtual ASIOError start(); virtual ASIOError stop(); virtual ASIOError getChannels(long *numInputChannels, long *numOutputChannels); virtual ASIOError getLatencies(long *inputLatency, long *outputLatency); virtual ASIOError getBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity); virtual ASIOError canSampleRate(ASIOSampleRate sampleRate); virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate); virtual ASIOError setSampleRate(ASIOSampleRate sampleRate); virtual ASIOError getClockSources(ASIOClockSource *clocks, long *numSources); virtual ASIOError setClockSource(long reference); virtual ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp); virtual ASIOError getChannelInfo(ASIOChannelInfo *info); virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels, long bufferSize, ASIOCallbacks *callbacks); virtual ASIOError disposeBuffers(); virtual ASIOError controlPanel(); virtual ASIOError future(long selector,void *opt); virtual ASIOError outputReady(); // Class method, see ASIOInit() macro below. static ASIOError ASIOInit(ASIODriverInfo *info); // Delegates to ::ASIOInit }; // Replace calls to ASIOInit with our interposing version. // This macro enables us to perform thiscall resolution simply by #including // after the asio #includes (this file _must_ be // included _after_ the asio #includes) #define ASIOInit(name) IASIOThiscallResolver::ASIOInit((name)) #endif /* !defined(_MSC_VER) */ #endif /* Win32 */ #endif /* included_iasiothiscallresolver_h */ pd-0.46-7/portaudio/src/hostapi/oss/0000775000175000017500000000000012374245151015450 5ustar mspmsppd-0.46-7/portaudio/src/hostapi/oss/low_latency_tip.txt0000664000175000017500000000604712160204055021403 0ustar mspmspFrom: "Benno Senoner" To: Subject: Re: [music-dsp] coding realtime guitar efx on a "pc" Date: Saturday, June 30, 2001 8:19 AM Andr, you are solving your problem the wrong way: you need to use a single threaded solution which does this: - set the audio I/O parameters to fragnum=4 fragsize=128 bytes (=32samples) if you use stereo or fragsize=64 bytes (=32 samples) if you use mono. (do not forget to activate fulltuplex with using the _TRIGGER_ stuff) (you need to frist deactivate audio and then start the trigger after the DAC is prefilled (see below)) This will give you a total input to output latency of 4x32 samples = 128 samples which at 44.1kHz correspond to 2.9msec latency. now set your process to SCHED_FIFO (see man sched_setscheduler) after the initialization your code should do more than less this: - write() 4 x 32 samples to the audio fd in order to prefill the DAC. Without this you will get dropouts. while(1) { read() 32 samples from ADC perform_dsp_stuff() on the 32 samples write() 32 samples to DAC } If you use a low latency kernel and pay attention to all the stuff above, then you will get rock solid 3msec latencies (plus eventual converter latencies but these are in the 1-2msec range AFAIK). Using multiple threads , pipes etc, only complicates your life and often makes it impossible to achieve these low latences. Realtime/audio programming is not an easy task , this is why people often fail to get the desired results even if their hardware is low-latency capable. The problem is that the final latency depends on the hardware you use, the application and the operating system. cheers, Benno. http://www.linuxaudiodev.org The Home of Linux Audio Development On Sat, 30 Jun 2001, you wrote: > On 2001-06-29 21:38 +0200, Benno Senoner wrote: > > > OSS/Free refuses to use a low # of frags ? > > > > That's a myth. > > I hope it is. :-) > > The fact is that ioctl(SNDCTL_DSP_SETFRAGMENT) succeeds with > values as low a 0x10007 (one 128-B fragment) but the latency is > still high enough to be clearly noticeable, which suggests that > it's *way* above 2/3 ms. This is on an otherwise idle machine > equipped with a SB PCI 128. > > But maybe it's me who's doing something wrong. I've been careful > to flush stdio buffers or use unbuffered I/O (write(2)) but I > may have let something else through. > > For example, since the signal processing and the I/O are done by > two different vanilla processes communicating via pipes, it may > be a scheduling granularity problem (E.G. the kernel giving the > I/O process a time slice every 20 ms). > > -- > Andr Majorel > http://www.teaser.fr/~amajorel/ > > dupswapdrop -- the music-dsp mailing list and website: subscription info, > FAQ, source code archive, list archive, book reviews, dsp links > http://shoko.calarts.edu/musicdsp/ -- dupswapdrop -- the music-dsp mailing list and website: subscription info, FAQ, source code archive, list archive, book reviews, dsp links http://shoko.calarts.edu/musicdsp/ pd-0.46-7/portaudio/src/hostapi/oss/recplay.c0000664000175000017500000000436512160204055017252 0ustar mspmsp/* * recplay.c * Phil Burk * Minimal record and playback test. * */ #include #include #include #ifndef __STDC__ /* #include */ #endif /* __STDC__ */ #include #ifdef __STDC__ #include #else /* __STDC__ */ #include #endif /* __STDC__ */ #include #define NUM_BYTES (64*1024) #define BLOCK_SIZE (4*1024) #define AUDIO "/dev/dsp" char buffer[NUM_BYTES]; int audioDev = 0; main (int argc, char *argv[]) { int numLeft; char *ptr; int num; int samplesize; /********** RECORD ********************/ /* Open audio device. */ audioDev = open (AUDIO, O_RDONLY, 0); if (audioDev == -1) { perror (AUDIO); exit (-1); } /* Set to 16 bit samples. */ samplesize = 16; ioctl(audioDev, SNDCTL_DSP_SAMPLESIZE, &samplesize); if (samplesize != 16) { perror("Unable to set the sample size."); exit(-1); } /* Record in blocks */ printf("Begin recording.\n"); numLeft = NUM_BYTES; ptr = buffer; while( numLeft >= BLOCK_SIZE ) { if ( (num = read (audioDev, ptr, BLOCK_SIZE)) < 0 ) { perror (AUDIO); exit (-1); } else { printf("Read %d bytes\n", num); ptr += num; numLeft -= num; } } close( audioDev ); /********** PLAYBACK ********************/ /* Open audio device for writing. */ audioDev = open (AUDIO, O_WRONLY, 0); if (audioDev == -1) { perror (AUDIO); exit (-1); } /* Set to 16 bit samples. */ samplesize = 16; ioctl(audioDev, SNDCTL_DSP_SAMPLESIZE, &samplesize); if (samplesize != 16) { perror("Unable to set the sample size."); exit(-1); } /* Play in blocks */ printf("Begin playing.\n"); numLeft = NUM_BYTES; ptr = buffer; while( numLeft >= BLOCK_SIZE ) { if ( (num = write (audioDev, ptr, BLOCK_SIZE)) < 0 ) { perror (AUDIO); exit (-1); } else { printf("Wrote %d bytes\n", num); ptr += num; numLeft -= num; } } close( audioDev ); } pd-0.46-7/portaudio/src/hostapi/oss/pa_unix_oss.c0000664000175000017500000021342512374245151020152 0ustar mspmsp/* * $Id: pa_unix_oss.c 1894 2013-06-08 19:30:41Z gineera $ * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * OSS implementation by: * Douglas Repetto * Phil Burk * Dominic Mazzoni * Arve Knudsen * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup hostapi_src */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_SYS_SOUNDCARD_H # include # ifdef __NetBSD__ # define DEVICE_NAME_BASE "/dev/audio" # else # define DEVICE_NAME_BASE "/dev/dsp" # endif #elif defined(HAVE_LINUX_SOUNDCARD_H) # include # define DEVICE_NAME_BASE "/dev/dsp" #elif defined(HAVE_MACHINE_SOUNDCARD_H) # include /* JH20010905 */ # define DEVICE_NAME_BASE "/dev/audio" #else # error No sound card header file #endif #include "portaudio.h" #include "pa_util.h" #include "pa_allocation.h" #include "pa_hostapi.h" #include "pa_stream.h" #include "pa_cpuload.h" #include "pa_process.h" #include "pa_unix_util.h" #include "pa_debugprint.h" static int sysErr_; static pthread_t mainThread_; /* Check return value of system call, and map it to PaError */ #define ENSURE_(expr, code) \ do { \ if( UNLIKELY( (sysErr_ = (expr)) < 0 ) ) \ { \ /* PaUtil_SetLastHostErrorInfo should only be used in the main thread */ \ if( (code) == paUnanticipatedHostError && pthread_self() == mainThread_ ) \ { \ PaUtil_SetLastHostErrorInfo( paOSS, sysErr_, strerror( errno ) ); \ } \ \ PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \ result = (code); \ goto error; \ } \ } while( 0 ); #ifndef AFMT_S16_NE #define AFMT_S16_NE Get_AFMT_S16_NE() /********************************************************************* * Some versions of OSS do not define AFMT_S16_NE. So check CPU. * PowerPC is Big Endian. X86 is Little Endian. */ static int Get_AFMT_S16_NE( void ) { long testData = 1; char *ptr = (char *) &testData; int isLittle = ( *ptr == 1 ); /* Does address point to least significant byte? */ return isLittle ? AFMT_S16_LE : AFMT_S16_BE; } #endif /* PaOSSHostApiRepresentation - host api datastructure specific to this implementation */ typedef struct { PaUtilHostApiRepresentation inheritedHostApiRep; PaUtilStreamInterface callbackStreamInterface; PaUtilStreamInterface blockingStreamInterface; PaUtilAllocationGroup *allocations; PaHostApiIndex hostApiIndex; } PaOSSHostApiRepresentation; /** Per-direction structure for PaOssStream. * * Aspect StreamChannels: In case the user requests to open the same device for both capture and playback, * but with different number of channels we will have to adapt between the number of user and host * channels for at least one direction, since the configuration space is the same for both directions * of an OSS device. */ typedef struct { int fd; const char *devName; int userChannelCount, hostChannelCount; int userInterleaved; void *buffer; PaSampleFormat userFormat, hostFormat; double latency; unsigned long hostFrames, numBufs; void **userBuffers; /* For non-interleaved blocking */ } PaOssStreamComponent; /** Implementation specific representation of a PaStream. * */ typedef struct PaOssStream { PaUtilStreamRepresentation streamRepresentation; PaUtilCpuLoadMeasurer cpuLoadMeasurer; PaUtilBufferProcessor bufferProcessor; PaUtilThreading threading; int sharedDevice; unsigned long framesPerHostBuffer; int triggered; /* Have the devices been triggered yet (first start) */ int isActive; int isStopped; int lastPosPtr; double lastStreamBytes; int framesProcessed; double sampleRate; int callbackMode; volatile int callbackStop, callbackAbort; PaOssStreamComponent *capture, *playback; unsigned long pollTimeout; sem_t semaphore; } PaOssStream; typedef enum { StreamMode_In, StreamMode_Out } StreamMode; /* prototypes for functions declared in this file */ static void Terminate( struct PaUtilHostApiRepresentation *hostApi ); static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ); static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ); static PaError CloseStream( PaStream* stream ); static PaError StartStream( PaStream *stream ); static PaError StopStream( PaStream *stream ); static PaError AbortStream( PaStream *stream ); static PaError IsStreamStopped( PaStream *s ); static PaError IsStreamActive( PaStream *stream ); static PaTime GetStreamTime( PaStream *stream ); static double GetStreamCpuLoad( PaStream* stream ); static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames ); static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames ); static signed long GetStreamReadAvailable( PaStream* stream ); static signed long GetStreamWriteAvailable( PaStream* stream ); static PaError BuildDeviceList( PaOSSHostApiRepresentation *hostApi ); /** Initialize the OSS API implementation. * * This function will initialize host API datastructures and query host devices for information. * * Aspect DeviceCapabilities: Enumeration of host API devices is initiated from here * * Aspect FreeResources: If an error is encountered under way we have to free each resource allocated in this function, * this happens with the usual "error" label. */ PaError PaOSS_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) { PaError result = paNoError; PaOSSHostApiRepresentation *ossHostApi = NULL; PA_UNLESS( ossHostApi = (PaOSSHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaOSSHostApiRepresentation) ), paInsufficientMemory ); PA_UNLESS( ossHostApi->allocations = PaUtil_CreateAllocationGroup(), paInsufficientMemory ); ossHostApi->hostApiIndex = hostApiIndex; /* Initialize host API structure */ *hostApi = &ossHostApi->inheritedHostApiRep; (*hostApi)->info.structVersion = 1; (*hostApi)->info.type = paOSS; (*hostApi)->info.name = "OSS"; (*hostApi)->Terminate = Terminate; (*hostApi)->OpenStream = OpenStream; (*hostApi)->IsFormatSupported = IsFormatSupported; PA_ENSURE( BuildDeviceList( ossHostApi ) ); PaUtil_InitializeStreamInterface( &ossHostApi->callbackStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, GetStreamCpuLoad, PaUtil_DummyRead, PaUtil_DummyWrite, PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable ); PaUtil_InitializeStreamInterface( &ossHostApi->blockingStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, PaUtil_DummyGetCpuLoad, ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable ); mainThread_ = pthread_self(); return result; error: if( ossHostApi ) { if( ossHostApi->allocations ) { PaUtil_FreeAllAllocations( ossHostApi->allocations ); PaUtil_DestroyAllocationGroup( ossHostApi->allocations ); } PaUtil_FreeMemory( ossHostApi ); } return result; } PaError PaUtil_InitializeDeviceInfo( PaDeviceInfo *deviceInfo, const char *name, PaHostApiIndex hostApiIndex, int maxInputChannels, int maxOutputChannels, PaTime defaultLowInputLatency, PaTime defaultLowOutputLatency, PaTime defaultHighInputLatency, PaTime defaultHighOutputLatency, double defaultSampleRate, PaUtilAllocationGroup *allocations ) { PaError result = paNoError; deviceInfo->structVersion = 2; if( allocations ) { size_t len = strlen( name ) + 1; PA_UNLESS( deviceInfo->name = PaUtil_GroupAllocateMemory( allocations, len ), paInsufficientMemory ); strncpy( (char *)deviceInfo->name, name, len ); } else deviceInfo->name = name; deviceInfo->hostApi = hostApiIndex; deviceInfo->maxInputChannels = maxInputChannels; deviceInfo->maxOutputChannels = maxOutputChannels; deviceInfo->defaultLowInputLatency = defaultLowInputLatency; deviceInfo->defaultLowOutputLatency = defaultLowOutputLatency; deviceInfo->defaultHighInputLatency = defaultHighInputLatency; deviceInfo->defaultHighOutputLatency = defaultHighOutputLatency; deviceInfo->defaultSampleRate = defaultSampleRate; error: return result; } static int CalcHigherLogTwo( int n ) { int log2 = 0; while( (1<= 2 ) break; } else { /* ioctl() worked but bail out if it does not support numChannels. * We don't want to leave gaps in the numChannels supported. */ if( (numChannels > 2) && (temp != numChannels) ) break; if( temp > maxNumChannels ) maxNumChannels = temp; /* Save maximum. */ } } /* A: We're able to open a device for capture if it's busy playing back and vice versa, * but we can't configure anything */ if( 0 == maxNumChannels && busy ) { result = paDeviceUnavailable; goto error; } /* The above negotiation may fail for an old driver so try this older technique. */ if( maxNumChannels < 1 ) { int stereo = 1; if( ioctl( devHandle, SNDCTL_DSP_STEREO, &stereo ) < 0 ) { maxNumChannels = 1; } else { maxNumChannels = (stereo) ? 2 : 1; } PA_DEBUG(( "%s: use SNDCTL_DSP_STEREO, maxNumChannels = %d\n", __FUNCTION__, maxNumChannels )); } /* During channel negotiation, the last ioctl() may have failed. This can * also cause sample rate negotiation to fail. Hence the following, to return * to a supported number of channels. SG20011005 */ { /* use most reasonable default value */ numChannels = PA_MIN( maxNumChannels, 2 ); ENSURE_( ioctl( devHandle, SNDCTL_DSP_CHANNELS, &numChannels ), paUnanticipatedHostError ); } /* Get supported sample rate closest to 44100 Hz */ if( *defaultSampleRate < 0 ) { sr = 44100; ENSURE_( ioctl( devHandle, SNDCTL_DSP_SPEED, &sr ), paUnanticipatedHostError ); *defaultSampleRate = sr; } *maxChannelCount = maxNumChannels; /* Attempt to set low latency with 4 frags-per-buffer, 128 frames-per-frag (total buffer 512 frames) * since the ioctl sets bytes, multiply by numChannels, and base on 2 bytes-per-sample, */ fragFrames = 128; frgmt = (4 << 16) + (CalcHigherLogTwo( fragFrames * numChannels * 2 ) & 0xffff); ENSURE_( ioctl( devHandle, SNDCTL_DSP_SETFRAGMENT, &frgmt ), paUnanticipatedHostError ); /* Use the value set by the ioctl to give the latency achieved */ fragFrames = pow( 2, frgmt & 0xffff ) / (numChannels * 2); *defaultLowLatency = ((frgmt >> 16) - 1) * fragFrames / *defaultSampleRate; /* Cannot now try setting a high latency (device would need closing and opening again). Make * high-latency 4 times the low unless the fragFrames are significantly more than requested 128 */ temp = (fragFrames < 256) ? 4 : (fragFrames < 512) ? 2 : 1; *defaultHighLatency = temp * *defaultLowLatency; error: if( devHandle >= 0 ) close( devHandle ); return result; } /** Query OSS device. * * This is where PaDeviceInfo objects are constructed and filled in with relevant information. * * Aspect DeviceCapabilities: The inferred device capabilities are recorded in a PaDeviceInfo object that is constructed * in place. */ static PaError QueryDevice( char *deviceName, PaOSSHostApiRepresentation *ossApi, PaDeviceInfo **deviceInfo ) { PaError result = paNoError; double sampleRate = -1.; int maxInputChannels, maxOutputChannels; PaTime defaultLowInputLatency, defaultLowOutputLatency, defaultHighInputLatency, defaultHighOutputLatency; PaError tmpRes = paNoError; int busy = 0; *deviceInfo = NULL; /* douglas: we have to do this querying in a slightly different order. apparently some sound cards will give you different info based on their settins. e.g. a card might give you stereo at 22kHz but only mono at 44kHz. the correct order for OSS is: format, channels, sample rate */ /* Aspect StreamChannels: The number of channels supported for a device may depend on the mode it is * opened in, it may have more channels available for capture than playback and vice versa. Therefore * we will open the device in both read- and write-only mode to determine the supported number. */ if( (tmpRes = QueryDirection( deviceName, StreamMode_In, &sampleRate, &maxInputChannels, &defaultLowInputLatency, &defaultHighInputLatency )) != paNoError ) { if( tmpRes != paDeviceUnavailable ) { PA_DEBUG(( "%s: Querying device %s for capture failed!\n", __FUNCTION__, deviceName )); /* PA_ENSURE( tmpRes ); */ } ++busy; } if( (tmpRes = QueryDirection( deviceName, StreamMode_Out, &sampleRate, &maxOutputChannels, &defaultLowOutputLatency, &defaultHighOutputLatency )) != paNoError ) { if( tmpRes != paDeviceUnavailable ) { PA_DEBUG(( "%s: Querying device %s for playback failed!\n", __FUNCTION__, deviceName )); /* PA_ENSURE( tmpRes ); */ } ++busy; } assert( 0 <= busy && busy <= 2 ); if( 2 == busy ) /* Both directions are unavailable to us */ { result = paDeviceUnavailable; goto error; } PA_UNLESS( *deviceInfo = PaUtil_GroupAllocateMemory( ossApi->allocations, sizeof (PaDeviceInfo) ), paInsufficientMemory ); PA_ENSURE( PaUtil_InitializeDeviceInfo( *deviceInfo, deviceName, ossApi->hostApiIndex, maxInputChannels, maxOutputChannels, defaultLowInputLatency, defaultLowOutputLatency, defaultHighInputLatency, defaultHighOutputLatency, sampleRate, ossApi->allocations ) ); error: return result; } /** Query host devices. * * Loop over host devices and query their capabilitiesu * * Aspect DeviceCapabilities: This function calls QueryDevice on each device entry and receives a filled in PaDeviceInfo object * per device, these are placed in the host api representation's deviceInfos array. */ static PaError BuildDeviceList( PaOSSHostApiRepresentation *ossApi ) { PaError result = paNoError; PaUtilHostApiRepresentation *commonApi = &ossApi->inheritedHostApiRep; int i; int numDevices = 0, maxDeviceInfos = 1; PaDeviceInfo **deviceInfos = NULL; /* These two will be set to the first working input and output device, respectively */ commonApi->info.defaultInputDevice = paNoDevice; commonApi->info.defaultOutputDevice = paNoDevice; /* Find devices by calling QueryDevice on each * potential device names. When we find a valid one, * add it to a linked list. * A: Set an arbitrary of 100 devices, should probably be a smarter way. */ for( i = 0; i < 100; i++ ) { char deviceName[32]; PaDeviceInfo *deviceInfo; int testResult; if( i == 0 ) snprintf(deviceName, sizeof (deviceName), "%s", DEVICE_NAME_BASE); else snprintf(deviceName, sizeof (deviceName), "%s%d", DEVICE_NAME_BASE, i); /* PA_DEBUG(("%s: trying device %s\n", __FUNCTION__, deviceName )); */ if( (testResult = QueryDevice( deviceName, ossApi, &deviceInfo )) != paNoError ) { if( testResult != paDeviceUnavailable ) PA_ENSURE( testResult ); continue; } ++numDevices; if( !deviceInfos || numDevices > maxDeviceInfos ) { maxDeviceInfos *= 2; PA_UNLESS( deviceInfos = (PaDeviceInfo **) realloc( deviceInfos, maxDeviceInfos * sizeof (PaDeviceInfo *) ), paInsufficientMemory ); } { int devIdx = numDevices - 1; deviceInfos[devIdx] = deviceInfo; if( commonApi->info.defaultInputDevice == paNoDevice && deviceInfo->maxInputChannels > 0 ) commonApi->info.defaultInputDevice = devIdx; if( commonApi->info.defaultOutputDevice == paNoDevice && deviceInfo->maxOutputChannels > 0 ) commonApi->info.defaultOutputDevice = devIdx; } } /* Make an array of PaDeviceInfo pointers out of the linked list */ PA_DEBUG(("PaOSS %s: Total number of devices found: %d\n", __FUNCTION__, numDevices)); commonApi->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( ossApi->allocations, sizeof(PaDeviceInfo*) * numDevices ); memcpy( commonApi->deviceInfos, deviceInfos, numDevices * sizeof (PaDeviceInfo *) ); commonApi->info.deviceCount = numDevices; error: free( deviceInfos ); return result; } static void Terminate( struct PaUtilHostApiRepresentation *hostApi ) { PaOSSHostApiRepresentation *ossHostApi = (PaOSSHostApiRepresentation*)hostApi; if( ossHostApi->allocations ) { PaUtil_FreeAllAllocations( ossHostApi->allocations ); PaUtil_DestroyAllocationGroup( ossHostApi->allocations ); } PaUtil_FreeMemory( ossHostApi ); } static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ) { PaError result = paNoError; PaDeviceIndex device; PaDeviceInfo *deviceInfo; char *deviceName; int inputChannelCount, outputChannelCount; int tempDevHandle = -1; int flags; PaSampleFormat inputSampleFormat, outputSampleFormat; if( inputParameters ) { inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that input device can support inputChannelCount */ if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels ) return paInvalidChannelCount; /* validate inputStreamInfo */ if( inputParameters->hostApiSpecificStreamInfo ) return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } else { inputChannelCount = 0; } if( outputParameters ) { outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that output device can support inputChannelCount */ if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels ) return paInvalidChannelCount; /* validate outputStreamInfo */ if( outputParameters->hostApiSpecificStreamInfo ) return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } else { outputChannelCount = 0; } if (inputChannelCount == 0 && outputChannelCount == 0) return paInvalidChannelCount; /* if full duplex, make sure that they're the same device */ if (inputChannelCount > 0 && outputChannelCount > 0 && inputParameters->device != outputParameters->device) return paInvalidDevice; /* if full duplex, also make sure that they're the same number of channels */ if (inputChannelCount > 0 && outputChannelCount > 0 && inputChannelCount != outputChannelCount) return paInvalidChannelCount; /* open the device so we can do more tests */ if( inputChannelCount > 0 ) { result = PaUtil_DeviceIndexToHostApiDeviceIndex(&device, inputParameters->device, hostApi); if (result != paNoError) return result; } else { result = PaUtil_DeviceIndexToHostApiDeviceIndex(&device, outputParameters->device, hostApi); if (result != paNoError) return result; } deviceInfo = hostApi->deviceInfos[device]; deviceName = (char *)deviceInfo->name; flags = O_NONBLOCK; if (inputChannelCount > 0 && outputChannelCount > 0) flags |= O_RDWR; else if (inputChannelCount > 0) flags |= O_RDONLY; else flags |= O_WRONLY; ENSURE_( tempDevHandle = open( deviceInfo->name, flags ), paDeviceUnavailable ); /* PaOssStream_Configure will do the rest of the checking for us */ /* PA_ENSURE( PaOssStream_Configure( tempDevHandle, deviceName, outputChannelCount, &sampleRate ) ); */ /* everything succeeded! */ error: if( tempDevHandle >= 0 ) close( tempDevHandle ); return result; } /** Validate stream parameters. * * Aspect StreamChannels: We verify that the number of channels is within the allowed range for the device */ static PaError ValidateParameters( const PaStreamParameters *parameters, const PaDeviceInfo *deviceInfo, StreamMode mode ) { int maxChans; assert( parameters ); if( parameters->device == paUseHostApiSpecificDeviceSpecification ) { return paInvalidDevice; } maxChans = (mode == StreamMode_In ? deviceInfo->maxInputChannels : deviceInfo->maxOutputChannels); if( parameters->channelCount > maxChans ) { return paInvalidChannelCount; } return paNoError; } static PaError PaOssStreamComponent_Initialize( PaOssStreamComponent *component, const PaStreamParameters *parameters, int callbackMode, int fd, const char *deviceName ) { PaError result = paNoError; assert( component ); memset( component, 0, sizeof (PaOssStreamComponent) ); component->fd = fd; component->devName = deviceName; component->userChannelCount = parameters->channelCount; component->userFormat = parameters->sampleFormat; component->latency = parameters->suggestedLatency; component->userInterleaved = !(parameters->sampleFormat & paNonInterleaved); if( !callbackMode && !component->userInterleaved ) { /* Pre-allocate non-interleaved user provided buffers */ PA_UNLESS( component->userBuffers = PaUtil_AllocateMemory( sizeof (void *) * component->userChannelCount ), paInsufficientMemory ); } error: return result; } static void PaOssStreamComponent_Terminate( PaOssStreamComponent *component ) { assert( component ); if( component->fd >= 0 ) close( component->fd ); if( component->buffer ) PaUtil_FreeMemory( component->buffer ); if( component->userBuffers ) PaUtil_FreeMemory( component->userBuffers ); PaUtil_FreeMemory( component ); } static PaError ModifyBlocking( int fd, int blocking ) { PaError result = paNoError; int fflags; ENSURE_( fflags = fcntl( fd, F_GETFL ), paUnanticipatedHostError ); if( blocking ) fflags &= ~O_NONBLOCK; else fflags |= O_NONBLOCK; ENSURE_( fcntl( fd, F_SETFL, fflags ), paUnanticipatedHostError ); error: return result; } /** Open input and output devices. * * @param idev: Returned input device file descriptor. * @param odev: Returned output device file descriptor. */ static PaError OpenDevices( const char *idevName, const char *odevName, int *idev, int *odev ) { PaError result = paNoError; int flags = O_NONBLOCK, duplex = 0; *idev = *odev = -1; if( idevName && odevName ) { duplex = 1; flags |= O_RDWR; } else if( idevName ) flags |= O_RDONLY; else flags |= O_WRONLY; /* open first in nonblocking mode, in case it's busy... * A: then unset the non-blocking attribute */ assert( flags & O_NONBLOCK ); if( idevName ) { ENSURE_( *idev = open( idevName, flags ), paDeviceUnavailable ); PA_ENSURE( ModifyBlocking( *idev, 1 ) ); /* Blocking */ } if( odevName ) { if( !idevName ) { ENSURE_( *odev = open( odevName, flags ), paDeviceUnavailable ); PA_ENSURE( ModifyBlocking( *odev, 1 ) ); /* Blocking */ } else { ENSURE_( *odev = dup( *idev ), paUnanticipatedHostError ); } } error: return result; } static PaError PaOssStream_Initialize( PaOssStream *stream, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, PaStreamCallback callback, void *userData, PaStreamFlags streamFlags, PaOSSHostApiRepresentation *ossApi ) { PaError result = paNoError; int idev, odev; PaUtilHostApiRepresentation *hostApi = &ossApi->inheritedHostApiRep; const char *idevName = NULL, *odevName = NULL; assert( stream ); memset( stream, 0, sizeof (PaOssStream) ); stream->isStopped = 1; PA_ENSURE( PaUtil_InitializeThreading( &stream->threading ) ); if( inputParameters && outputParameters ) { if( inputParameters->device == outputParameters->device ) stream->sharedDevice = 1; } if( inputParameters ) idevName = hostApi->deviceInfos[inputParameters->device]->name; if( outputParameters ) odevName = hostApi->deviceInfos[outputParameters->device]->name; PA_ENSURE( OpenDevices( idevName, odevName, &idev, &odev ) ); if( inputParameters ) { PA_UNLESS( stream->capture = PaUtil_AllocateMemory( sizeof (PaOssStreamComponent) ), paInsufficientMemory ); PA_ENSURE( PaOssStreamComponent_Initialize( stream->capture, inputParameters, callback != NULL, idev, idevName ) ); } if( outputParameters ) { PA_UNLESS( stream->playback = PaUtil_AllocateMemory( sizeof (PaOssStreamComponent) ), paInsufficientMemory ); PA_ENSURE( PaOssStreamComponent_Initialize( stream->playback, outputParameters, callback != NULL, odev, odevName ) ); } if( callback != NULL ) { PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &ossApi->callbackStreamInterface, callback, userData ); stream->callbackMode = 1; } else { PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &ossApi->blockingStreamInterface, callback, userData ); } ENSURE_( sem_init( &stream->semaphore, 0, 0 ), paInternalError ); error: return result; } static void PaOssStream_Terminate( PaOssStream *stream ) { assert( stream ); PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); PaUtil_TerminateThreading( &stream->threading ); if( stream->capture ) PaOssStreamComponent_Terminate( stream->capture ); if( stream->playback ) PaOssStreamComponent_Terminate( stream->playback ); sem_destroy( &stream->semaphore ); PaUtil_FreeMemory( stream ); } /** Translate from PA format to OSS native. * */ static PaError Pa2OssFormat( PaSampleFormat paFormat, int *ossFormat ) { switch( paFormat ) { case paUInt8: *ossFormat = AFMT_U8; break; case paInt8: *ossFormat = AFMT_S8; break; case paInt16: *ossFormat = AFMT_S16_NE; break; default: return paInternalError; /* This shouldn't happen */ } return paNoError; } /** Return the PA-compatible formats that this device can support. * */ static PaError GetAvailableFormats( PaOssStreamComponent *component, PaSampleFormat *availableFormats ) { PaError result = paNoError; int mask = 0; PaSampleFormat frmts = 0; ENSURE_( ioctl( component->fd, SNDCTL_DSP_GETFMTS, &mask ), paUnanticipatedHostError ); if( mask & AFMT_U8 ) frmts |= paUInt8; if( mask & AFMT_S8 ) frmts |= paInt8; if( mask & AFMT_S16_NE ) frmts |= paInt16; else result = paSampleFormatNotSupported; *availableFormats = frmts; error: return result; } static unsigned int PaOssStreamComponent_FrameSize( PaOssStreamComponent *component ) { return Pa_GetSampleSize( component->hostFormat ) * component->hostChannelCount; } /** Buffer size in bytes. * */ static unsigned long PaOssStreamComponent_BufferSize( PaOssStreamComponent *component ) { return PaOssStreamComponent_FrameSize( component ) * component->hostFrames * component->numBufs; } /** Configure stream component device parameters. */ static PaError PaOssStreamComponent_Configure( PaOssStreamComponent *component, double sampleRate, unsigned long framesPerBuffer, StreamMode streamMode, PaOssStreamComponent *master ) { PaError result = paNoError; int temp, nativeFormat; int sr = (int)sampleRate; PaSampleFormat availableFormats = 0, hostFormat = 0; int chans = component->userChannelCount; int frgmt; int numBufs; int bytesPerBuf; unsigned long bufSz; unsigned long fragSz; audio_buf_info bufInfo; /* We may have a situation where only one component (the master) is configured, if both point to the same device. * In that case, the second component will copy settings from the other */ if( !master ) { /* Aspect BufferSettings: If framesPerBuffer is unspecified we have to infer a suitable fragment size. * The hardware need not respect the requested fragment size, so we may have to adapt. */ if( framesPerBuffer == paFramesPerBufferUnspecified ) { /* Aim for 4 fragments in the complete buffer; the latency comes from 3 of these */ fragSz = (unsigned long)(component->latency * sampleRate / 3); bufSz = fragSz * 4; } else { fragSz = framesPerBuffer; bufSz = (unsigned long)(component->latency * sampleRate) + fragSz; /* Latency + 1 buffer */ } PA_ENSURE( GetAvailableFormats( component, &availableFormats ) ); hostFormat = PaUtil_SelectClosestAvailableFormat( availableFormats, component->userFormat ); /* OSS demands at least 2 buffers, and 16 bytes per buffer */ numBufs = (int)PA_MAX( bufSz / fragSz, 2 ); bytesPerBuf = PA_MAX( fragSz * Pa_GetSampleSize( hostFormat ) * chans, 16 ); /* The fragment parameters are encoded like this: * Most significant byte: number of fragments * Least significant byte: exponent of fragment size (i.e., for 256, 8) */ frgmt = (numBufs << 16) + (CalcHigherLogTwo( bytesPerBuf ) & 0xffff); ENSURE_( ioctl( component->fd, SNDCTL_DSP_SETFRAGMENT, &frgmt ), paUnanticipatedHostError ); /* A: according to the OSS programmer's guide parameters should be set in this order: * format, channels, rate */ /* This format should be deemed good before we get this far */ PA_ENSURE( Pa2OssFormat( hostFormat, &temp ) ); nativeFormat = temp; ENSURE_( ioctl( component->fd, SNDCTL_DSP_SETFMT, &temp ), paUnanticipatedHostError ); PA_UNLESS( temp == nativeFormat, paInternalError ); /* try to set the number of channels */ ENSURE_( ioctl( component->fd, SNDCTL_DSP_CHANNELS, &chans ), paSampleFormatNotSupported ); /* XXX: Should be paInvalidChannelCount? */ /* It's possible that the minimum number of host channels is greater than what the user requested */ PA_UNLESS( chans >= component->userChannelCount, paInvalidChannelCount ); /* try to set the sample rate */ ENSURE_( ioctl( component->fd, SNDCTL_DSP_SPEED, &sr ), paInvalidSampleRate ); /* reject if there's no sample rate within 1% of the one requested */ if( (fabs( sampleRate - sr ) / sampleRate) > 0.01 ) { PA_DEBUG(("%s: Wanted %f, closest sample rate was %d\n", __FUNCTION__, sampleRate, sr )); PA_ENSURE( paInvalidSampleRate ); } ENSURE_( ioctl( component->fd, streamMode == StreamMode_In ? SNDCTL_DSP_GETISPACE : SNDCTL_DSP_GETOSPACE, &bufInfo ), paUnanticipatedHostError ); component->numBufs = bufInfo.fragstotal; /* This needs to be the last ioctl call before the first read/write, according to the OSS programmer's guide */ ENSURE_( ioctl( component->fd, SNDCTL_DSP_GETBLKSIZE, &bytesPerBuf ), paUnanticipatedHostError ); component->hostFrames = bytesPerBuf / Pa_GetSampleSize( hostFormat ) / chans; component->hostChannelCount = chans; component->hostFormat = hostFormat; } else { component->hostFormat = master->hostFormat; component->hostFrames = master->hostFrames; component->hostChannelCount = master->hostChannelCount; component->numBufs = master->numBufs; } PA_UNLESS( component->buffer = PaUtil_AllocateMemory( PaOssStreamComponent_BufferSize( component ) ), paInsufficientMemory ); error: return result; } static PaError PaOssStreamComponent_Read( PaOssStreamComponent *component, unsigned long *frames ) { PaError result = paNoError; size_t len = *frames * PaOssStreamComponent_FrameSize( component ); ssize_t bytesRead; ENSURE_( bytesRead = read( component->fd, component->buffer, len ), paUnanticipatedHostError ); *frames = bytesRead / PaOssStreamComponent_FrameSize( component ); /* TODO: Handle condition where number of frames read doesn't equal number of frames requested */ error: return result; } static PaError PaOssStreamComponent_Write( PaOssStreamComponent *component, unsigned long *frames ) { PaError result = paNoError; size_t len = *frames * PaOssStreamComponent_FrameSize( component ); ssize_t bytesWritten; ENSURE_( bytesWritten = write( component->fd, component->buffer, len ), paUnanticipatedHostError ); *frames = bytesWritten / PaOssStreamComponent_FrameSize( component ); /* TODO: Handle condition where number of frames written doesn't equal number of frames requested */ error: return result; } /** Configure the stream according to input/output parameters. * * Aspect StreamChannels: The minimum number of channels supported by the device may exceed that requested by * the user, if so we'll record the actual number of host channels and adapt later. */ static PaError PaOssStream_Configure( PaOssStream *stream, double sampleRate, unsigned long framesPerBuffer, double *inputLatency, double *outputLatency ) { PaError result = paNoError; int duplex = stream->capture && stream->playback; unsigned long framesPerHostBuffer = 0; /* We should request full duplex first thing after opening the device */ if( duplex && stream->sharedDevice ) ENSURE_( ioctl( stream->capture->fd, SNDCTL_DSP_SETDUPLEX, 0 ), paUnanticipatedHostError ); if( stream->capture ) { PaOssStreamComponent *component = stream->capture; PA_ENSURE( PaOssStreamComponent_Configure( component, sampleRate, framesPerBuffer, StreamMode_In, NULL ) ); assert( component->hostChannelCount > 0 ); assert( component->hostFrames > 0 ); *inputLatency = (component->hostFrames * (component->numBufs - 1)) / sampleRate; } if( stream->playback ) { PaOssStreamComponent *component = stream->playback, *master = stream->sharedDevice ? stream->capture : NULL; PA_ENSURE( PaOssStreamComponent_Configure( component, sampleRate, framesPerBuffer, StreamMode_Out, master ) ); assert( component->hostChannelCount > 0 ); assert( component->hostFrames > 0 ); *outputLatency = (component->hostFrames * (component->numBufs - 1)) / sampleRate; } if( duplex ) framesPerHostBuffer = PA_MIN( stream->capture->hostFrames, stream->playback->hostFrames ); else if( stream->capture ) framesPerHostBuffer = stream->capture->hostFrames; else if( stream->playback ) framesPerHostBuffer = stream->playback->hostFrames; stream->framesPerHostBuffer = framesPerHostBuffer; stream->pollTimeout = (int) ceil( 1e6 * framesPerHostBuffer / sampleRate ); /* Period in usecs, rounded up */ stream->sampleRate = stream->streamRepresentation.streamInfo.sampleRate = sampleRate; error: return result; } /* see pa_hostapi.h for a list of validity guarantees made about OpenStream parameters */ /** Open a PA OSS stream. * * Aspect StreamChannels: The number of channels is specified per direction (in/out), and can differ between the * two. However, OSS doesn't support separate configuration spaces for capture and playback so if both * directions are the same device we will demand the same number of channels. The number of channels can range * from 1 to the maximum supported by the device. * * Aspect BufferSettings: If framesPerBuffer != paFramesPerBufferUnspecified the number of frames per callback * must reflect this, in addition the host latency per device should approximate the corresponding * suggestedLatency. Based on these constraints we need to determine a number of frames per host buffer that * both capture and playback can agree on (they can be different devices), the buffer processor can adapt * between host and user buffer size, but the ratio should preferably be integral. */ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ) { PaError result = paNoError; PaOSSHostApiRepresentation *ossHostApi = (PaOSSHostApiRepresentation*)hostApi; PaOssStream *stream = NULL; int inputChannelCount = 0, outputChannelCount = 0; PaSampleFormat inputSampleFormat = 0, outputSampleFormat = 0, inputHostFormat = 0, outputHostFormat = 0; const PaDeviceInfo *inputDeviceInfo = 0, *outputDeviceInfo = 0; int bpInitialized = 0; double inLatency = 0., outLatency = 0.; int i = 0; /* validate platform specific flags */ if( (streamFlags & paPlatformSpecificFlags) != 0 ) return paInvalidFlag; /* unexpected platform specific flag */ if( inputParameters ) { /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ inputDeviceInfo = hostApi->deviceInfos[inputParameters->device]; PA_ENSURE( ValidateParameters( inputParameters, inputDeviceInfo, StreamMode_In ) ); inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; } if( outputParameters ) { outputDeviceInfo = hostApi->deviceInfos[outputParameters->device]; PA_ENSURE( ValidateParameters( outputParameters, outputDeviceInfo, StreamMode_Out ) ); outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; } /* Aspect StreamChannels: We currently demand that number of input and output channels are the same, if the same * device is opened for both directions */ if( inputChannelCount > 0 && outputChannelCount > 0 ) { if( inputParameters->device == outputParameters->device ) { if( inputParameters->channelCount != outputParameters->channelCount ) return paInvalidChannelCount; } } /* Round framesPerBuffer to the next power-of-two to make OSS happy. */ if( framesPerBuffer != paFramesPerBufferUnspecified ) { framesPerBuffer &= INT_MAX; for (i = 1; framesPerBuffer > i; i <<= 1) ; framesPerBuffer = i; } /* allocate and do basic initialization of the stream structure */ PA_UNLESS( stream = (PaOssStream*)PaUtil_AllocateMemory( sizeof(PaOssStream) ), paInsufficientMemory ); PA_ENSURE( PaOssStream_Initialize( stream, inputParameters, outputParameters, streamCallback, userData, streamFlags, ossHostApi ) ); PA_ENSURE( PaOssStream_Configure( stream, sampleRate, framesPerBuffer, &inLatency, &outLatency ) ); PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate ); if( inputParameters ) { inputHostFormat = stream->capture->hostFormat; stream->streamRepresentation.streamInfo.inputLatency = inLatency + PaUtil_GetBufferProcessorInputLatencyFrames( &stream->bufferProcessor ) / sampleRate; } if( outputParameters ) { outputHostFormat = stream->playback->hostFormat; stream->streamRepresentation.streamInfo.outputLatency = outLatency + PaUtil_GetBufferProcessorOutputLatencyFrames( &stream->bufferProcessor ) / sampleRate; } /* Initialize buffer processor with fixed host buffer size. * Aspect StreamSampleFormat: Here we commit the user and host sample formats, PA infrastructure will * convert between the two. */ PA_ENSURE( PaUtil_InitializeBufferProcessor( &stream->bufferProcessor, inputChannelCount, inputSampleFormat, inputHostFormat, outputChannelCount, outputSampleFormat, outputHostFormat, sampleRate, streamFlags, framesPerBuffer, stream->framesPerHostBuffer, paUtilFixedHostBufferSize, streamCallback, userData ) ); bpInitialized = 1; *s = (PaStream*)stream; return result; error: if( bpInitialized ) PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); if( stream ) PaOssStream_Terminate( stream ); return result; } /*! Poll on I/O filedescriptors. Poll till we've determined there's data for read or write. In the full-duplex case, we don't want to hang around forever waiting for either input or output frames, so whenever we have a timed out filedescriptor we check if we're nearing under/overrun for the other direction (critical limit set at one buffer). If so, we exit the waiting state, and go on with what we got. We align the number of frames on a host buffer boundary because it is possible that the buffer size differs for the two directions and the host buffer size is a compromise between the two. */ static PaError PaOssStream_WaitForFrames( PaOssStream *stream, unsigned long *frames ) { PaError result = paNoError; int pollPlayback = 0, pollCapture = 0; int captureAvail = INT_MAX, playbackAvail = INT_MAX, commonAvail; audio_buf_info bufInfo; /* int ofs = 0, nfds = stream->nfds; */ fd_set readFds, writeFds; int nfds = 0; struct timeval selectTimeval = {0, 0}; unsigned long timeout = stream->pollTimeout; /* In usecs */ int captureFd = -1, playbackFd = -1; assert( stream ); assert( frames ); if( stream->capture ) { pollCapture = 1; captureFd = stream->capture->fd; /* stream->capture->pfd->events = POLLIN; */ } if( stream->playback ) { pollPlayback = 1; playbackFd = stream->playback->fd; /* stream->playback->pfd->events = POLLOUT; */ } FD_ZERO( &readFds ); FD_ZERO( &writeFds ); while( pollPlayback || pollCapture ) { #ifdef PTHREAD_CANCELED pthread_testcancel(); #else /* avoid indefinite waiting on thread not supporting cancelation */ if( stream->callbackStop || stream->callbackAbort ) { PA_DEBUG(( "Cancelling PaOssStream_WaitForFrames\n" )); (*frames) = 0; return paNoError; } #endif /* select may modify the timeout parameter */ selectTimeval.tv_usec = timeout; nfds = 0; if( pollCapture ) { FD_SET( captureFd, &readFds ); nfds = captureFd + 1; } if( pollPlayback ) { FD_SET( playbackFd, &writeFds ); nfds = PA_MAX( nfds, playbackFd + 1 ); } ENSURE_( select( nfds, &readFds, &writeFds, NULL, &selectTimeval ), paUnanticipatedHostError ); /* if( poll( stream->pfds + ofs, nfds, stream->pollTimeout ) < 0 ) { ENSURE_( -1, paUnanticipatedHostError ); } */ #ifdef PTHREAD_CANCELED pthread_testcancel(); #else /* avoid indefinite waiting on thread not supporting cancelation */ if( stream->callbackStop || stream->callbackAbort ) { PA_DEBUG(( "Cancelling PaOssStream_WaitForFrames\n" )); (*frames) = 0; return paNoError; } #endif if( pollCapture ) { if( FD_ISSET( captureFd, &readFds ) ) { FD_CLR( captureFd, &readFds ); pollCapture = 0; } /* if( stream->capture->pfd->revents & POLLIN ) { --nfds; ++ofs; pollCapture = 0; } */ else if( stream->playback ) /* Timed out, go on with playback? */ { /*PA_DEBUG(( "%s: Trying to poll again for capture frames, pollTimeout: %d\n", __FUNCTION__, stream->pollTimeout ));*/ } } if( pollPlayback ) { if( FD_ISSET( playbackFd, &writeFds ) ) { FD_CLR( playbackFd, &writeFds ); pollPlayback = 0; } /* if( stream->playback->pfd->revents & POLLOUT ) { --nfds; pollPlayback = 0; } */ else if( stream->capture ) /* Timed out, go on with capture? */ { /*PA_DEBUG(( "%s: Trying to poll again for playback frames, pollTimeout: %d\n\n", __FUNCTION__, stream->pollTimeout ));*/ } } } if( stream->capture ) { ENSURE_( ioctl( captureFd, SNDCTL_DSP_GETISPACE, &bufInfo ), paUnanticipatedHostError ); captureAvail = bufInfo.fragments * stream->capture->hostFrames; if( !captureAvail ) PA_DEBUG(( "%s: captureAvail: 0\n", __FUNCTION__ )); captureAvail = captureAvail == 0 ? INT_MAX : captureAvail; /* Disregard if zero */ } if( stream->playback ) { ENSURE_( ioctl( playbackFd, SNDCTL_DSP_GETOSPACE, &bufInfo ), paUnanticipatedHostError ); playbackAvail = bufInfo.fragments * stream->playback->hostFrames; if( !playbackAvail ) { PA_DEBUG(( "%s: playbackAvail: 0\n", __FUNCTION__ )); } playbackAvail = playbackAvail == 0 ? INT_MAX : playbackAvail; /* Disregard if zero */ } commonAvail = PA_MIN( captureAvail, playbackAvail ); if( commonAvail == INT_MAX ) commonAvail = 0; commonAvail -= commonAvail % stream->framesPerHostBuffer; assert( commonAvail != INT_MAX ); assert( commonAvail >= 0 ); *frames = commonAvail; error: return result; } /** Prepare stream for capture/playback. * * In order to synchronize capture and playback properly we use the SETTRIGGER command. */ static PaError PaOssStream_Prepare( PaOssStream *stream ) { PaError result = paNoError; int enableBits = 0; if( stream->triggered ) return result; /* The OSS reference instructs us to clear direction bits before setting them.*/ if( stream->playback ) ENSURE_( ioctl( stream->playback->fd, SNDCTL_DSP_SETTRIGGER, &enableBits ), paUnanticipatedHostError ); if( stream->capture ) ENSURE_( ioctl( stream->capture->fd, SNDCTL_DSP_SETTRIGGER, &enableBits ), paUnanticipatedHostError ); if( stream->playback ) { size_t bufSz = PaOssStreamComponent_BufferSize( stream->playback ); memset( stream->playback->buffer, 0, bufSz ); /* Looks like we have to turn off blocking before we try this, but if we don't fill the buffer * OSS will complain. */ PA_ENSURE( ModifyBlocking( stream->playback->fd, 0 ) ); while (1) { if( write( stream->playback->fd, stream->playback->buffer, bufSz ) < 0 ) break; } PA_ENSURE( ModifyBlocking( stream->playback->fd, 1 ) ); } if( stream->sharedDevice ) { enableBits = PCM_ENABLE_INPUT | PCM_ENABLE_OUTPUT; ENSURE_( ioctl( stream->capture->fd, SNDCTL_DSP_SETTRIGGER, &enableBits ), paUnanticipatedHostError ); } else { if( stream->capture ) { enableBits = PCM_ENABLE_INPUT; ENSURE_( ioctl( stream->capture->fd, SNDCTL_DSP_SETTRIGGER, &enableBits ), paUnanticipatedHostError ); } if( stream->playback ) { enableBits = PCM_ENABLE_OUTPUT; ENSURE_( ioctl( stream->playback->fd, SNDCTL_DSP_SETTRIGGER, &enableBits ), paUnanticipatedHostError ); } } /* Ok, we have triggered the stream */ stream->triggered = 1; error: return result; } /** Stop audio processing * */ static PaError PaOssStream_Stop( PaOssStream *stream, int abort ) { PaError result = paNoError; /* Looks like the only safe way to stop audio without reopening the device is SNDCTL_DSP_POST. * Also disable capture/playback till the stream is started again. */ int captureErr = 0, playbackErr = 0; if( stream->capture ) { if( (captureErr = ioctl( stream->capture->fd, SNDCTL_DSP_POST, 0 )) < 0 ) { PA_DEBUG(( "%s: Failed to stop capture device, error: %d\n", __FUNCTION__, captureErr )); } } if( stream->playback && !stream->sharedDevice ) { if( (playbackErr = ioctl( stream->playback->fd, SNDCTL_DSP_POST, 0 )) < 0 ) { PA_DEBUG(( "%s: Failed to stop playback device, error: %d\n", __FUNCTION__, playbackErr )); } } if( captureErr || playbackErr ) { result = paUnanticipatedHostError; } return result; } /** Clean up after thread exit. * * Aspect StreamState: If the user has registered a streamFinishedCallback it will be called here */ static void OnExit( void *data ) { PaOssStream *stream = (PaOssStream *) data; assert( data ); PaUtil_ResetCpuLoadMeasurer( &stream->cpuLoadMeasurer ); PaOssStream_Stop( stream, stream->callbackAbort ); PA_DEBUG(( "OnExit: Stoppage\n" )); /* Eventually notify user all buffers have played */ if( stream->streamRepresentation.streamFinishedCallback ) stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); stream->callbackAbort = 0; /* Clear state */ stream->isActive = 0; } static PaError SetUpBuffers( PaOssStream *stream, unsigned long framesAvail ) { PaError result = paNoError; if( stream->capture ) { PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, 0, stream->capture->buffer, stream->capture->hostChannelCount ); PaUtil_SetInputFrameCount( &stream->bufferProcessor, framesAvail ); } if( stream->playback ) { PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, 0, stream->playback->buffer, stream->playback->hostChannelCount ); PaUtil_SetOutputFrameCount( &stream->bufferProcessor, framesAvail ); } return result; } /** Thread procedure for callback processing. * * Aspect StreamState: StartStream will wait on this to initiate audio processing, useful in case the * callback should be used for buffer priming. When the stream is cancelled a separate function will * take care of the transition to the Callback Finished state (the stream isn't considered Stopped * before StopStream() or AbortStream() are called). */ static void *PaOSS_AudioThreadProc( void *userData ) { PaError result = paNoError; PaOssStream *stream = (PaOssStream*)userData; unsigned long framesAvail = 0, framesProcessed = 0; int callbackResult = paContinue; int triggered = stream->triggered; /* See if SNDCTL_DSP_TRIGGER has been issued already */ int initiateProcessing = triggered; /* Already triggered? */ PaStreamCallbackFlags cbFlags = 0; /* We might want to keep state across iterations */ PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /* TODO: IMPLEMENT ME */ /* #if ( SOUND_VERSION > 0x030904 ) audio_errinfo errinfo; #endif */ assert( stream ); pthread_cleanup_push( &OnExit, stream ); /* Execute OnExit when exiting */ /* The first time the stream is started we use SNDCTL_DSP_TRIGGER to accurately start capture and * playback in sync, when the stream is restarted after being stopped we simply start by reading/ * writing. */ PA_ENSURE( PaOssStream_Prepare( stream ) ); /* If we are to initiate processing implicitly by reading/writing data, we start off in blocking mode */ if( initiateProcessing ) { /* Make sure devices are in blocking mode */ if( stream->capture ) ModifyBlocking( stream->capture->fd, 1 ); if( stream->playback ) ModifyBlocking( stream->playback->fd, 1 ); } while( 1 ) { #ifdef PTHREAD_CANCELED pthread_testcancel(); #else if( stream->callbackAbort ) /* avoid indefinite waiting on thread not supporting cancelation */ { PA_DEBUG(( "Aborting callback thread\n" )); break; } #endif if( stream->callbackStop && callbackResult == paContinue ) { PA_DEBUG(( "Setting callbackResult to paComplete\n" )); callbackResult = paComplete; } /* Aspect StreamState: Because of the messy OSS scheme we can't explicitly trigger device start unless * the stream has been recently started, we will have to go right ahead and read/write in blocking * fashion to trigger operation. Therefore we begin with processing one host buffer before we switch * to non-blocking mode. */ if( !initiateProcessing ) { /* Wait on available frames */ PA_ENSURE( PaOssStream_WaitForFrames( stream, &framesAvail ) ); assert( framesAvail % stream->framesPerHostBuffer == 0 ); } else { framesAvail = stream->framesPerHostBuffer; } while( framesAvail > 0 ) { unsigned long frames = framesAvail; #ifdef PTHREAD_CANCELED pthread_testcancel(); #else if( stream->callbackStop ) { PA_DEBUG(( "Setting callbackResult to paComplete\n" )); callbackResult = paComplete; } if( stream->callbackAbort ) /* avoid indefinite waiting on thread not supporting cancelation */ { PA_DEBUG(( "Aborting callback thread\n" )); break; } #endif PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer ); /* Read data */ if ( stream->capture ) { PA_ENSURE( PaOssStreamComponent_Read( stream->capture, &frames ) ); if( frames < framesAvail ) { PA_DEBUG(( "Read %lu less frames than requested\n", framesAvail - frames )); framesAvail = frames; } } #if ( SOUND_VERSION >= 0x030904 ) /* Check with OSS to see if there have been any under/overruns since last time we checked. */ /* if( ioctl( stream->deviceHandle, SNDCTL_DSP_GETERROR, &errinfo ) >= 0 ) { if( errinfo.play_underruns ) cbFlags |= paOutputUnderflow ; if( errinfo.record_underruns ) cbFlags |= paInputUnderflow ; } else PA_DEBUG(( "SNDCTL_DSP_GETERROR command failed: %s\n", strerror( errno ) )); */ #endif PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, cbFlags ); cbFlags = 0; PA_ENSURE( SetUpBuffers( stream, framesAvail ) ); framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult ); assert( framesProcessed == framesAvail ); PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed ); if ( stream->playback ) { frames = framesAvail; PA_ENSURE( PaOssStreamComponent_Write( stream->playback, &frames ) ); if( frames < framesAvail ) { /* TODO: handle bytesWritten != bytesRequested (slippage?) */ PA_DEBUG(( "Wrote %lu less frames than requested\n", framesAvail - frames )); } } framesAvail -= framesProcessed; stream->framesProcessed += framesProcessed; if( callbackResult != paContinue ) break; } if( initiateProcessing || !triggered ) { /* Non-blocking */ if( stream->capture ) PA_ENSURE( ModifyBlocking( stream->capture->fd, 0 ) ); if( stream->playback && !stream->sharedDevice ) PA_ENSURE( ModifyBlocking( stream->playback->fd, 0 ) ); initiateProcessing = 0; sem_post( &stream->semaphore ); } if( callbackResult != paContinue ) { stream->callbackAbort = callbackResult == paAbort; if( stream->callbackAbort || PaUtil_IsBufferProcessorOutputEmpty( &stream->bufferProcessor ) ) break; } } pthread_cleanup_pop( 1 ); error: pthread_exit( NULL ); } /** Close the stream. * */ static PaError CloseStream( PaStream* s ) { PaError result = paNoError; PaOssStream *stream = (PaOssStream*)s; assert( stream ); PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); PaOssStream_Terminate( stream ); return result; } /** Start the stream. * * Aspect StreamState: After returning, the stream shall be in the Active state, implying that an eventual * callback will be repeatedly called in a separate thread. If a separate thread is started this function * will block untill it has started processing audio, otherwise audio processing is started directly. */ static PaError StartStream( PaStream *s ) { PaError result = paNoError; PaOssStream *stream = (PaOssStream*)s; stream->isActive = 1; stream->isStopped = 0; stream->lastPosPtr = 0; stream->lastStreamBytes = 0; stream->framesProcessed = 0; /* only use the thread for callback streams */ if( stream->bufferProcessor.streamCallback ) { PA_ENSURE( PaUtil_StartThreading( &stream->threading, &PaOSS_AudioThreadProc, stream ) ); sem_wait( &stream->semaphore ); } else PA_ENSURE( PaOssStream_Prepare( stream ) ); error: return result; } static PaError RealStop( PaOssStream *stream, int abort ) { PaError result = paNoError; if( stream->callbackMode ) { if( abort ) stream->callbackAbort = 1; else stream->callbackStop = 1; PA_ENSURE( PaUtil_CancelThreading( &stream->threading, !abort, NULL ) ); stream->callbackStop = stream->callbackAbort = 0; } else PA_ENSURE( PaOssStream_Stop( stream, abort ) ); stream->isStopped = 1; error: return result; } /** Stop the stream. * * Aspect StreamState: This will cause the stream to transition to the Stopped state, playing all enqueued * buffers. */ static PaError StopStream( PaStream *s ) { return RealStop( (PaOssStream *)s, 0 ); } /** Abort the stream. * * Aspect StreamState: This will cause the stream to transition to the Stopped state, discarding all enqueued * buffers. Note that the buffers are not currently correctly discarded, this is difficult without closing * the OSS device. */ static PaError AbortStream( PaStream *s ) { return RealStop( (PaOssStream *)s, 1 ); } /** Is the stream in the Stopped state. * */ static PaError IsStreamStopped( PaStream *s ) { PaOssStream *stream = (PaOssStream*)s; return (stream->isStopped); } /** Is the stream in the Active state. * */ static PaError IsStreamActive( PaStream *s ) { PaOssStream *stream = (PaOssStream*)s; return (stream->isActive); } static PaTime GetStreamTime( PaStream *s ) { PaOssStream *stream = (PaOssStream*)s; count_info info; int delta; if( stream->playback ) { if( ioctl( stream->playback->fd, SNDCTL_DSP_GETOPTR, &info) == 0 ) { delta = ( info.bytes - stream->lastPosPtr ) /* & 0x000FFFFF*/; return (float)(stream->lastStreamBytes + delta) / PaOssStreamComponent_FrameSize( stream->playback ) / stream->sampleRate; } } else { if (ioctl( stream->capture->fd, SNDCTL_DSP_GETIPTR, &info) == 0) { delta = (info.bytes - stream->lastPosPtr) /*& 0x000FFFFF*/; return (float)(stream->lastStreamBytes + delta) / PaOssStreamComponent_FrameSize( stream->capture ) / stream->sampleRate; } } /* the ioctl failed, but we can still give a coarse estimate */ return stream->framesProcessed / stream->sampleRate; } static double GetStreamCpuLoad( PaStream* s ) { PaOssStream *stream = (PaOssStream*)s; return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ); } /* As separate stream interfaces are used for blocking and callback streams, the following functions can be guaranteed to only be called for blocking streams. */ static PaError ReadStream( PaStream* s, void *buffer, unsigned long frames ) { PaError result = paNoError; PaOssStream *stream = (PaOssStream*)s; int bytesRequested, bytesRead; unsigned long framesRequested; void *userBuffer; /* If user input is non-interleaved, PaUtil_CopyInput will manipulate the channel pointers, * so we copy the user provided pointers */ if( stream->bufferProcessor.userInputIsInterleaved ) userBuffer = buffer; else /* Copy channels into local array */ { userBuffer = stream->capture->userBuffers; memcpy( (void *)userBuffer, buffer, sizeof (void *) * stream->capture->userChannelCount ); } while( frames ) { framesRequested = PA_MIN( frames, stream->capture->hostFrames ); bytesRequested = framesRequested * PaOssStreamComponent_FrameSize( stream->capture ); ENSURE_( (bytesRead = read( stream->capture->fd, stream->capture->buffer, bytesRequested )), paUnanticipatedHostError ); if ( bytesRequested != bytesRead ) { PA_DEBUG(( "Requested %d bytes, read %d\n", bytesRequested, bytesRead )); return paUnanticipatedHostError; } PaUtil_SetInputFrameCount( &stream->bufferProcessor, stream->capture->hostFrames ); PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, 0, stream->capture->buffer, stream->capture->hostChannelCount ); PaUtil_CopyInput( &stream->bufferProcessor, &userBuffer, framesRequested ); frames -= framesRequested; } error: return result; } static PaError WriteStream( PaStream *s, const void *buffer, unsigned long frames ) { PaError result = paNoError; PaOssStream *stream = (PaOssStream*)s; int bytesRequested, bytesWritten; unsigned long framesConverted; const void *userBuffer; /* If user output is non-interleaved, PaUtil_CopyOutput will manipulate the channel pointers, * so we copy the user provided pointers */ if( stream->bufferProcessor.userOutputIsInterleaved ) userBuffer = buffer; else { /* Copy channels into local array */ userBuffer = stream->playback->userBuffers; memcpy( (void *)userBuffer, buffer, sizeof (void *) * stream->playback->userChannelCount ); } while( frames ) { PaUtil_SetOutputFrameCount( &stream->bufferProcessor, stream->playback->hostFrames ); PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, 0, stream->playback->buffer, stream->playback->hostChannelCount ); framesConverted = PaUtil_CopyOutput( &stream->bufferProcessor, &userBuffer, frames ); frames -= framesConverted; bytesRequested = framesConverted * PaOssStreamComponent_FrameSize( stream->playback ); ENSURE_( (bytesWritten = write( stream->playback->fd, stream->playback->buffer, bytesRequested )), paUnanticipatedHostError ); if ( bytesRequested != bytesWritten ) { PA_DEBUG(( "Requested %d bytes, wrote %d\n", bytesRequested, bytesWritten )); return paUnanticipatedHostError; } } error: return result; } static signed long GetStreamReadAvailable( PaStream* s ) { PaError result = paNoError; PaOssStream *stream = (PaOssStream*)s; audio_buf_info info; ENSURE_( ioctl( stream->capture->fd, SNDCTL_DSP_GETISPACE, &info ), paUnanticipatedHostError ); return info.fragments * stream->capture->hostFrames; error: return result; } /* TODO: Compute number of allocated bytes somewhere else, can we use ODELAY with capture */ static signed long GetStreamWriteAvailable( PaStream* s ) { PaError result = paNoError; PaOssStream *stream = (PaOssStream*)s; int delay = 0; #ifdef SNDCTL_DSP_GETODELAY ENSURE_( ioctl( stream->playback->fd, SNDCTL_DSP_GETODELAY, &delay ), paUnanticipatedHostError ); #endif return (PaOssStreamComponent_BufferSize( stream->playback ) - delay) / PaOssStreamComponent_FrameSize( stream->playback ); /* Conditionally compile this to avoid warning about unused label */ #ifdef SNDCTL_DSP_GETODELAY error: return result; #endif } pd-0.46-7/portaudio/src/hostapi/coreaudio/0000775000175000017500000000000012374250720016614 5ustar mspmsppd-0.46-7/portaudio/src/hostapi/coreaudio/pa_mac_core_internal.h0000664000175000017500000001600312222201037023076 0ustar mspmsp/* * Internal interfaces for PortAudio Apple AUHAL implementation * * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * * Written by Bjorn Roche of XO Audio LLC, from PA skeleton code. * Portions copied from code by Dominic Mazzoni (who wrote a HAL implementation) * * Dominic's code was based on code by Phil Burk, Darren Gibbs, * Gord Peters, Stephane Letz, and Greg Pfiel. * * The following people also deserve acknowledgements: * * Olivier Tristan for feedback and testing * Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O * interface. * * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file pa_mac_core @ingroup hostapi_src @author Bjorn Roche @brief AUHAL implementation of PortAudio */ #ifndef PA_MAC_CORE_INTERNAL_H__ #define PA_MAC_CORE_INTERNAL_H__ #include #include #include #include #include "portaudio.h" #include "pa_util.h" #include "pa_hostapi.h" #include "pa_stream.h" #include "pa_allocation.h" #include "pa_cpuload.h" #include "pa_process.h" #include "pa_ringbuffer.h" #include "pa_mac_core_blocking.h" /* function prototypes */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); #ifdef __cplusplus } #endif /* __cplusplus */ #define RING_BUFFER_ADVANCE_DENOMINATOR (4) PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames ); PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames ); signed long GetStreamReadAvailable( PaStream* stream ); signed long GetStreamWriteAvailable( PaStream* stream ); /* PaMacAUHAL - host api datastructure specific to this implementation */ typedef struct { PaUtilHostApiRepresentation inheritedHostApiRep; PaUtilStreamInterface callbackStreamInterface; PaUtilStreamInterface blockingStreamInterface; PaUtilAllocationGroup *allocations; /* implementation specific data goes here */ long devCount; AudioDeviceID *devIds; /*array of all audio devices*/ AudioDeviceID defaultIn; AudioDeviceID defaultOut; } PaMacAUHAL; typedef struct PaMacCoreDeviceProperties { /* Values in Frames from property queries. */ UInt32 safetyOffset; UInt32 bufferFrameSize; // UInt32 streamLatency; // Seems to be the same as deviceLatency!? UInt32 deviceLatency; /* Current device sample rate. May change! These are initialized to the nominal device sample rate, and updated with the actual sample rate, when/where available. Note that these are the *device* sample rates, prior to any required SR conversion. */ Float64 sampleRate; Float64 samplePeriod; // reciprocal } PaMacCoreDeviceProperties; /* stream data structure specifically for this implementation */ typedef struct PaMacCoreStream { PaUtilStreamRepresentation streamRepresentation; PaUtilCpuLoadMeasurer cpuLoadMeasurer; PaUtilBufferProcessor bufferProcessor; /* implementation specific data goes here */ bool bufferProcessorIsInitialized; AudioUnit inputUnit; AudioUnit outputUnit; AudioDeviceID inputDevice; AudioDeviceID outputDevice; size_t userInChan; size_t userOutChan; size_t inputFramesPerBuffer; size_t outputFramesPerBuffer; PaMacBlio blio; /* We use this ring buffer when input and out devs are different. */ PaUtilRingBuffer inputRingBuffer; /* We may need to do SR conversion on input. */ AudioConverterRef inputSRConverter; /* We need to preallocate an inputBuffer for reading data. */ AudioBufferList inputAudioBufferList; AudioTimeStamp startTime; /* FIXME: instead of volatile, these should be properly memory barriered */ volatile uint32_t xrunFlags; /*PaStreamCallbackFlags*/ volatile enum { STOPPED = 0, /* playback is completely stopped, and the user has called StopStream(). */ CALLBACK_STOPPED = 1, /* callback has requested stop, but user has not yet called StopStream(). */ STOPPING = 2, /* The stream is in the process of closing because the user has called StopStream. This state is just used internally; externally it is indistinguishable from ACTIVE.*/ ACTIVE = 3 /* The stream is active and running. */ } state; double sampleRate; PaMacCoreDeviceProperties inputProperties; PaMacCoreDeviceProperties outputProperties; /* data updated by main thread and notifications, protected by timingInformationMutex */ int timingInformationMutexIsInitialized; pthread_mutex_t timingInformationMutex; /* These are written by the PA thread or from CoreAudio callbacks. Protected by the mutex. */ Float64 timestampOffsetCombined; Float64 timestampOffsetInputDevice; Float64 timestampOffsetOutputDevice; /* Offsets in seconds to be applied to Apple timestamps to convert them to PA timestamps. * While the io proc is active, the following values are only accessed and manipulated by the ioproc */ Float64 timestampOffsetCombined_ioProcCopy; Float64 timestampOffsetInputDevice_ioProcCopy; Float64 timestampOffsetOutputDevice_ioProcCopy; } PaMacCoreStream; #endif /* PA_MAC_CORE_INTERNAL_H__ */ pd-0.46-7/portaudio/src/hostapi/coreaudio/pa_mac_core_blocking.c0000664000175000017500000004702112222201037023051 0ustar mspmsp/* * Implementation of the PortAudio API for Apple AUHAL * * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * * Written by Bjorn Roche of XO Audio LLC, from PA skeleton code. * Portions copied from code by Dominic Mazzoni (who wrote a HAL implementation) * * Dominic's code was based on code by Phil Burk, Darren Gibbs, * Gord Peters, Stephane Letz, and Greg Pfiel. * * The following people also deserve acknowledgements: * * Olivier Tristan for feedback and testing * Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O * interface. * * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup hostapi_src This file contains the implementation required for blocking I/O. It is separated from pa_mac_core.c simply to ease development. */ #include "pa_mac_core_blocking.h" #include "pa_mac_core_internal.h" #include #ifdef MOSX_USE_NON_ATOMIC_FLAG_BITS # define OSAtomicOr32( a, b ) ( (*(b)) |= (a) ) # define OSAtomicAnd32( a, b ) ( (*(b)) &= (a) ) #else # include #endif /* * This function determines the size of a particular sample format. * if the format is not recognized, this returns zero. */ static size_t computeSampleSizeFromFormat( PaSampleFormat format ) { switch( format & (~paNonInterleaved) ) { case paFloat32: return 4; case paInt32: return 4; case paInt24: return 3; case paInt16: return 2; case paInt8: case paUInt8: return 1; default: return 0; } } /* * Same as computeSampleSizeFromFormat, except that if * the size is not a power of two, it returns the next power of two up */ static size_t computeSampleSizeFromFormatPow2( PaSampleFormat format ) { switch( format & (~paNonInterleaved) ) { case paFloat32: return 4; case paInt32: return 4; case paInt24: return 4; case paInt16: return 2; case paInt8: case paUInt8: return 1; default: return 0; } } /* * Functions for initializing, resetting, and destroying BLIO structures. * */ /* This should be called with the relevant info when initializing a stream for callback. */ PaError initializeBlioRingBuffers( PaMacBlio *blio, PaSampleFormat inputSampleFormat, PaSampleFormat outputSampleFormat, size_t framesPerBuffer, long ringBufferSize, int inChan, int outChan ) { void *data; int result; OSStatus err; /* zeroify things */ bzero( blio, sizeof( PaMacBlio ) ); /* this is redundant, but the buffers are used to check if the bufffers have been initialized, so we do it explicitly. */ blio->inputRingBuffer.buffer = NULL; blio->outputRingBuffer.buffer = NULL; /* initialize simple data */ blio->ringBufferFrames = ringBufferSize; blio->inputSampleFormat = inputSampleFormat; blio->inputSampleSizeActual = computeSampleSizeFromFormat(inputSampleFormat); blio->inputSampleSizePow2 = computeSampleSizeFromFormatPow2(inputSampleFormat); blio->outputSampleFormat = outputSampleFormat; blio->outputSampleSizeActual = computeSampleSizeFromFormat(outputSampleFormat); blio->outputSampleSizePow2 = computeSampleSizeFromFormatPow2(outputSampleFormat); blio->framesPerBuffer = framesPerBuffer; blio->inChan = inChan; blio->outChan = outChan; blio->statusFlags = 0; blio->errors = paNoError; #ifdef PA_MAC_BLIO_MUTEX blio->isInputEmpty = false; blio->isOutputFull = false; #endif /* setup ring buffers */ #ifdef PA_MAC_BLIO_MUTEX result = PaMacCore_SetUnixError( pthread_mutex_init(&(blio->inputMutex),NULL), 0 ); if( result ) goto error; result = UNIX_ERR( pthread_cond_init( &(blio->inputCond), NULL ) ); if( result ) goto error; result = UNIX_ERR( pthread_mutex_init(&(blio->outputMutex),NULL) ); if( result ) goto error; result = UNIX_ERR( pthread_cond_init( &(blio->outputCond), NULL ) ); #endif if( inChan ) { data = calloc( ringBufferSize, blio->inputSampleSizePow2*inChan ); if( !data ) { result = paInsufficientMemory; goto error; } err = PaUtil_InitializeRingBuffer( &blio->inputRingBuffer, 1, ringBufferSize*blio->inputSampleSizePow2*inChan, data ); assert( !err ); } if( outChan ) { data = calloc( ringBufferSize, blio->outputSampleSizePow2*outChan ); if( !data ) { result = paInsufficientMemory; goto error; } err = PaUtil_InitializeRingBuffer( &blio->outputRingBuffer, 1, ringBufferSize*blio->outputSampleSizePow2*outChan, data ); assert( !err ); } result = resetBlioRingBuffers( blio ); if( result ) goto error; return 0; error: destroyBlioRingBuffers( blio ); return result; } #ifdef PA_MAC_BLIO_MUTEX PaError blioSetIsInputEmpty( PaMacBlio *blio, bool isEmpty ) { PaError result = paNoError; if( isEmpty == blio->isInputEmpty ) goto done; /* we need to update the value. Here's what we do: * - Lock the mutex, so noone else can write. * - update the value. * - unlock. * - broadcast to all listeners. */ result = UNIX_ERR( pthread_mutex_lock( &blio->inputMutex ) ); if( result ) goto done; blio->isInputEmpty = isEmpty; result = UNIX_ERR( pthread_mutex_unlock( &blio->inputMutex ) ); if( result ) goto done; result = UNIX_ERR( pthread_cond_broadcast( &blio->inputCond ) ); if( result ) goto done; done: return result; } PaError blioSetIsOutputFull( PaMacBlio *blio, bool isFull ) { PaError result = paNoError; if( isFull == blio->isOutputFull ) goto done; /* we need to update the value. Here's what we do: * - Lock the mutex, so noone else can write. * - update the value. * - unlock. * - broadcast to all listeners. */ result = UNIX_ERR( pthread_mutex_lock( &blio->outputMutex ) ); if( result ) goto done; blio->isOutputFull = isFull; result = UNIX_ERR( pthread_mutex_unlock( &blio->outputMutex ) ); if( result ) goto done; result = UNIX_ERR( pthread_cond_broadcast( &blio->outputCond ) ); if( result ) goto done; done: return result; } #endif /* This should be called after stopping or aborting the stream, so that on next start, the buffers will be ready. */ PaError resetBlioRingBuffers( PaMacBlio *blio ) { #ifdef PA_MAC__BLIO_MUTEX int result; #endif blio->statusFlags = 0; if( blio->outputRingBuffer.buffer ) { PaUtil_FlushRingBuffer( &blio->outputRingBuffer ); bzero( blio->outputRingBuffer.buffer, blio->outputRingBuffer.bufferSize ); /* Advance buffer */ PaUtil_AdvanceRingBufferWriteIndex( &blio->outputRingBuffer, blio->ringBufferFrames*blio->outputSampleSizeActual*blio->outChan ); //PaUtil_AdvanceRingBufferWriteIndex( &blio->outputRingBuffer, blio->outputRingBuffer.bufferSize ); /* Update isOutputFull. */ #ifdef PA_MAC__BLIO_MUTEX result = blioSetIsOutputFull( blio, toAdvance == blio->outputRingBuffer.bufferSize ); if( result ) goto error; #endif /* printf( "------%d\n" , blio->framesPerBuffer ); printf( "------%d\n" , blio->outChan ); printf( "------%d\n" , blio->outputSampleSize ); printf( "------%d\n" , blio->framesPerBuffer*blio->outChan*blio->outputSampleSize ); */ } if( blio->inputRingBuffer.buffer ) { PaUtil_FlushRingBuffer( &blio->inputRingBuffer ); bzero( blio->inputRingBuffer.buffer, blio->inputRingBuffer.bufferSize ); /* Update isInputEmpty. */ #ifdef PA_MAC__BLIO_MUTEX result = blioSetIsInputEmpty( blio, true ); if( result ) goto error; #endif } return paNoError; #ifdef PA_MAC__BLIO_MUTEX error: return result; #endif } /*This should be called when you are done with the blio. It can safely be called multiple times if there are no exceptions. */ PaError destroyBlioRingBuffers( PaMacBlio *blio ) { PaError result = paNoError; if( blio->inputRingBuffer.buffer ) { free( blio->inputRingBuffer.buffer ); #ifdef PA_MAC__BLIO_MUTEX result = UNIX_ERR( pthread_mutex_destroy( & blio->inputMutex ) ); if( result ) return result; result = UNIX_ERR( pthread_cond_destroy( & blio->inputCond ) ); if( result ) return result; #endif } blio->inputRingBuffer.buffer = NULL; if( blio->outputRingBuffer.buffer ) { free( blio->outputRingBuffer.buffer ); #ifdef PA_MAC__BLIO_MUTEX result = UNIX_ERR( pthread_mutex_destroy( & blio->outputMutex ) ); if( result ) return result; result = UNIX_ERR( pthread_cond_destroy( & blio->outputCond ) ); if( result ) return result; #endif } blio->outputRingBuffer.buffer = NULL; return result; } /* * this is the BlioCallback function. It expects to recieve a PaMacBlio Object * pointer as userData. * */ int BlioCallback( const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData ) { PaMacBlio *blio = (PaMacBlio*)userData; long avail; long toRead; long toWrite; long read; long written; /* set flags returned by OS: */ OSAtomicOr32( statusFlags, &blio->statusFlags ) ; /* --- Handle Input Buffer --- */ if( blio->inChan ) { avail = PaUtil_GetRingBufferWriteAvailable( &blio->inputRingBuffer ); /* check for underflow */ if( avail < frameCount * blio->inputSampleSizeActual * blio->inChan ) { OSAtomicOr32( paInputOverflow, &blio->statusFlags ); } toRead = MIN( avail, frameCount * blio->inputSampleSizeActual * blio->inChan ); /* copy the data */ /*printf( "reading %d\n", toRead );*/ read = PaUtil_WriteRingBuffer( &blio->inputRingBuffer, input, toRead ); assert( toRead == read ); #ifdef PA_MAC__BLIO_MUTEX /* Priority inversion. See notes below. */ blioSetIsInputEmpty( blio, false ); #endif } /* --- Handle Output Buffer --- */ if( blio->outChan ) { avail = PaUtil_GetRingBufferReadAvailable( &blio->outputRingBuffer ); /* check for underflow */ if( avail < frameCount * blio->outputSampleSizeActual * blio->outChan ) OSAtomicOr32( paOutputUnderflow, &blio->statusFlags ); toWrite = MIN( avail, frameCount * blio->outputSampleSizeActual * blio->outChan ); if( toWrite != frameCount * blio->outputSampleSizeActual * blio->outChan ) bzero( ((char *)output)+toWrite, frameCount * blio->outputSampleSizeActual * blio->outChan - toWrite ); /* copy the data */ /*printf( "writing %d\n", toWrite );*/ written = PaUtil_ReadRingBuffer( &blio->outputRingBuffer, output, toWrite ); assert( toWrite == written ); #ifdef PA_MAC__BLIO_MUTEX /* We have a priority inversion here. However, we will only have to wait if this was true and is now false, which means we've got some room in the buffer. Hopefully problems will be minimized. */ blioSetIsOutputFull( blio, false ); #endif } return paContinue; } PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames ) { PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio; char *cbuf = (char *) buffer; PaError ret = paNoError; VVDBUG(("ReadStream()\n")); while( frames > 0 ) { long avail; long toRead; do { avail = PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer ); /* printf( "Read Buffer is %%%g full: %ld of %ld.\n", 100 * (float)avail / (float) blio->inputRingBuffer.bufferSize, avail, blio->inputRingBuffer.bufferSize ); */ if( avail == 0 ) { #ifdef PA_MAC_BLIO_MUTEX /**block when empty*/ ret = UNIX_ERR( pthread_mutex_lock( &blio->inputMutex ) ); if( ret ) return ret; while( blio->isInputEmpty ) { ret = UNIX_ERR( pthread_cond_wait( &blio->inputCond, &blio->inputMutex ) ); if( ret ) return ret; } ret = UNIX_ERR( pthread_mutex_unlock( &blio->inputMutex ) ); if( ret ) return ret; #else Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL ); #endif } } while( avail == 0 ); toRead = MIN( avail, frames * blio->inputSampleSizeActual * blio->inChan ); toRead -= toRead % blio->inputSampleSizeActual * blio->inChan ; PaUtil_ReadRingBuffer( &blio->inputRingBuffer, (void *)cbuf, toRead ); cbuf += toRead; frames -= toRead / ( blio->inputSampleSizeActual * blio->inChan ); if( toRead == avail ) { #ifdef PA_MAC_BLIO_MUTEX /* we just emptied the buffer, so we need to mark it as empty. */ ret = blioSetIsInputEmpty( blio, true ); if( ret ) return ret; /* of course, in the meantime, the callback may have put some sats in, so so check for that, too, to avoid a race condition. */ if( PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer ) ) { blioSetIsInputEmpty( blio, false ); if( ret ) return ret; } #endif } } /* Report either paNoError or paInputOverflowed. */ /* may also want to report other errors, but this is non-standard. */ ret = blio->statusFlags & paInputOverflow; /* report underflow only once: */ if( ret ) { OSAtomicAnd32( (uint32_t)(~paInputOverflow), &blio->statusFlags ); ret = paInputOverflowed; } return ret; } PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames ) { PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio; char *cbuf = (char *) buffer; PaError ret = paNoError; VVDBUG(("WriteStream()\n")); while( frames > 0 ) { long avail = 0; long toWrite; do { avail = PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer ); /* printf( "Write Buffer is %%%g full: %ld of %ld.\n", 100 - 100 * (float)avail / (float) blio->outputRingBuffer.bufferSize, avail, blio->outputRingBuffer.bufferSize ); */ if( avail == 0 ) { #ifdef PA_MAC_BLIO_MUTEX /*block while full*/ ret = UNIX_ERR( pthread_mutex_lock( &blio->outputMutex ) ); if( ret ) return ret; while( blio->isOutputFull ) { ret = UNIX_ERR( pthread_cond_wait( &blio->outputCond, &blio->outputMutex ) ); if( ret ) return ret; } ret = UNIX_ERR( pthread_mutex_unlock( &blio->outputMutex ) ); if( ret ) return ret; #else Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL ); #endif } } while( avail == 0 ); toWrite = MIN( avail, frames * blio->outputSampleSizeActual * blio->outChan ); toWrite -= toWrite % blio->outputSampleSizeActual * blio->outChan ; PaUtil_WriteRingBuffer( &blio->outputRingBuffer, (void *)cbuf, toWrite ); cbuf += toWrite; frames -= toWrite / ( blio->outputSampleSizeActual * blio->outChan ); #ifdef PA_MAC_BLIO_MUTEX if( toWrite == avail ) { /* we just filled up the buffer, so we need to mark it as filled. */ ret = blioSetIsOutputFull( blio, true ); if( ret ) return ret; /* of course, in the meantime, we may have emptied the buffer, so so check for that, too, to avoid a race condition. */ if( PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer ) ) { blioSetIsOutputFull( blio, false ); if( ret ) return ret; } } #endif } /* Report either paNoError or paOutputUnderflowed. */ /* may also want to report other errors, but this is non-standard. */ ret = blio->statusFlags & paOutputUnderflow; /* report underflow only once: */ if( ret ) { OSAtomicAnd32( (uint32_t)(~paOutputUnderflow), &blio->statusFlags ); ret = paOutputUnderflowed; } return ret; } /* * */ void waitUntilBlioWriteBufferIsFlushed( PaMacBlio *blio ) { if( blio->outputRingBuffer.buffer ) { long avail = PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer ); while( avail != blio->outputRingBuffer.bufferSize ) { if( avail == 0 ) Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL ); avail = PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer ); } } } signed long GetStreamReadAvailable( PaStream* stream ) { PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio; VVDBUG(("GetStreamReadAvailable()\n")); return PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer ) / ( blio->inputSampleSizeActual * blio->inChan ); } signed long GetStreamWriteAvailable( PaStream* stream ) { PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio; VVDBUG(("GetStreamWriteAvailable()\n")); return PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer ) / ( blio->outputSampleSizeActual * blio->outChan ); } pd-0.46-7/portaudio/src/hostapi/coreaudio/pa_mac_core_old.c0000664000175000017500000010465712160204055022054 0ustar mspmsp/* * $Id: pa_mac_core_old.c 1083 2006-08-23 07:30:49Z rossb $ * pa_mac_core.c * Implementation of PortAudio for Mac OS X CoreAudio * * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * * Authors: Ross Bencina and Phil Burk * Copyright (c) 1999-2000 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ #include #include #include #include #include #include #include "portaudio.h" #include "pa_trace.h" #include "pa_util.h" #include "pa_allocation.h" #include "pa_hostapi.h" #include "pa_stream.h" #include "pa_cpuload.h" #include "pa_process.h" // ===== constants ===== // ===== structs ===== #pragma mark structs // PaMacCoreHostApiRepresentation - host api datastructure specific to this implementation typedef struct PaMacCore_HAR { PaUtilHostApiRepresentation inheritedHostApiRep; PaUtilStreamInterface callbackStreamInterface; PaUtilStreamInterface blockingStreamInterface; PaUtilAllocationGroup *allocations; AudioDeviceID *macCoreDeviceIds; } PaMacCoreHostApiRepresentation; typedef struct PaMacCore_DI { PaDeviceInfo inheritedDeviceInfo; } PaMacCoreDeviceInfo; // PaMacCoreStream - a stream data structure specifically for this implementation typedef struct PaMacCore_S { PaUtilStreamRepresentation streamRepresentation; PaUtilCpuLoadMeasurer cpuLoadMeasurer; PaUtilBufferProcessor bufferProcessor; int primeStreamUsingCallback; AudioDeviceID inputDevice; AudioDeviceID outputDevice; // Processing thread management -------------- // HANDLE abortEvent; // HANDLE processingThread; // DWORD processingThreadId; char throttleProcessingThreadOnOverload; // 0 -> don't throtte, non-0 -> throttle int processingThreadPriority; int highThreadPriority; int throttledThreadPriority; unsigned long throttledSleepMsecs; int isStopped; volatile int isActive; volatile int stopProcessing; // stop thread once existing buffers have been returned volatile int abortProcessing; // stop thread immediately // DWORD allBuffersDurationMs; // used to calculate timeouts } PaMacCoreStream; // Data needed by the CoreAudio callback functions typedef struct PaMacCore_CD { PaMacCoreStream *stream; PaStreamCallback *callback; void *userData; PaUtilConverter *inputConverter; PaUtilConverter *outputConverter; void *inputBuffer; void *outputBuffer; int inputChannelCount; int outputChannelCount; PaSampleFormat inputSampleFormat; PaSampleFormat outputSampleFormat; PaUtilTriangularDitherGenerator *ditherGenerator; } PaMacClientData; // ===== CoreAudio-PortAudio bridge functions ===== #pragma mark CoreAudio-PortAudio bridge functions // Maps CoreAudio OSStatus codes to PortAudio PaError codes static PaError conv_err(OSStatus error) { PaError result; switch (error) { case kAudioHardwareNoError: result = paNoError; break; case kAudioHardwareNotRunningError: result = paInternalError; break; case kAudioHardwareUnspecifiedError: result = paInternalError; break; case kAudioHardwareUnknownPropertyError: result = paInternalError; break; case kAudioHardwareBadPropertySizeError: result = paInternalError; break; case kAudioHardwareIllegalOperationError: result = paInternalError; break; case kAudioHardwareBadDeviceError: result = paInvalidDevice; break; case kAudioHardwareBadStreamError: result = paBadStreamPtr; break; case kAudioHardwareUnsupportedOperationError: result = paInternalError; break; case kAudioDeviceUnsupportedFormatError: result = paSampleFormatNotSupported; break; case kAudioDevicePermissionsError: result = paDeviceUnavailable; break; default: result = paInternalError; } return result; } /* This function is unused static AudioStreamBasicDescription *InitializeStreamDescription(const PaStreamParameters *parameters, double sampleRate) { struct AudioStreamBasicDescription *streamDescription = PaUtil_AllocateMemory(sizeof(AudioStreamBasicDescription)); streamDescription->mSampleRate = sampleRate; streamDescription->mFormatID = kAudioFormatLinearPCM; streamDescription->mFormatFlags = 0; streamDescription->mFramesPerPacket = 1; if (parameters->sampleFormat & paNonInterleaved) { streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsNonInterleaved; streamDescription->mChannelsPerFrame = 1; streamDescription->mBytesPerFrame = Pa_GetSampleSize(parameters->sampleFormat); streamDescription->mBytesPerPacket = Pa_GetSampleSize(parameters->sampleFormat); } else { streamDescription->mChannelsPerFrame = parameters->channelCount; } streamDescription->mBytesPerFrame = Pa_GetSampleSize(parameters->sampleFormat) * streamDescription->mChannelsPerFrame; streamDescription->mBytesPerPacket = streamDescription->mBytesPerFrame * streamDescription->mFramesPerPacket; if (parameters->sampleFormat & paFloat32) { streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsFloat; streamDescription->mBitsPerChannel = 32; } else if (parameters->sampleFormat & paInt32) { streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger; streamDescription->mBitsPerChannel = 32; } else if (parameters->sampleFormat & paInt24) { streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger; streamDescription->mBitsPerChannel = 24; } else if (parameters->sampleFormat & paInt16) { streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger; streamDescription->mBitsPerChannel = 16; } else if (parameters->sampleFormat & paInt8) { streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger; streamDescription->mBitsPerChannel = 8; } else if (parameters->sampleFormat & paInt32) { streamDescription->mBitsPerChannel = 8; } return streamDescription; } */ static PaStreamCallbackTimeInfo *InitializeTimeInfo(const AudioTimeStamp* now, const AudioTimeStamp* inputTime, const AudioTimeStamp* outputTime) { PaStreamCallbackTimeInfo *timeInfo = PaUtil_AllocateMemory(sizeof(PaStreamCallbackTimeInfo)); timeInfo->inputBufferAdcTime = inputTime->mSampleTime; timeInfo->currentTime = now->mSampleTime; timeInfo->outputBufferDacTime = outputTime->mSampleTime; return timeInfo; } // ===== support functions ===== #pragma mark support functions static void CleanUp(PaMacCoreHostApiRepresentation *macCoreHostApi) { if( macCoreHostApi->allocations ) { PaUtil_FreeAllAllocations( macCoreHostApi->allocations ); PaUtil_DestroyAllocationGroup( macCoreHostApi->allocations ); } PaUtil_FreeMemory( macCoreHostApi ); } static PaError GetChannelInfo(PaDeviceInfo *deviceInfo, AudioDeviceID macCoreDeviceId, int isInput) { UInt32 propSize; PaError err = paNoError; UInt32 i; int numChannels = 0; AudioBufferList *buflist; err = conv_err(AudioDeviceGetPropertyInfo(macCoreDeviceId, 0, isInput, kAudioDevicePropertyStreamConfiguration, &propSize, NULL)); buflist = PaUtil_AllocateMemory(propSize); err = conv_err(AudioDeviceGetProperty(macCoreDeviceId, 0, isInput, kAudioDevicePropertyStreamConfiguration, &propSize, buflist)); if (!err) { for (i = 0; i < buflist->mNumberBuffers; ++i) { numChannels += buflist->mBuffers[i].mNumberChannels; } if (isInput) deviceInfo->maxInputChannels = numChannels; else deviceInfo->maxOutputChannels = numChannels; int frameLatency; propSize = sizeof(UInt32); err = conv_err(AudioDeviceGetProperty(macCoreDeviceId, 0, isInput, kAudioDevicePropertyLatency, &propSize, &frameLatency)); if (!err) { double secondLatency = frameLatency / deviceInfo->defaultSampleRate; if (isInput) { deviceInfo->defaultLowInputLatency = secondLatency; deviceInfo->defaultHighInputLatency = secondLatency; } else { deviceInfo->defaultLowOutputLatency = secondLatency; deviceInfo->defaultHighOutputLatency = secondLatency; } } } PaUtil_FreeMemory(buflist); return err; } static PaError InitializeDeviceInfo(PaMacCoreDeviceInfo *macCoreDeviceInfo, AudioDeviceID macCoreDeviceId, PaHostApiIndex hostApiIndex ) { PaDeviceInfo *deviceInfo = &macCoreDeviceInfo->inheritedDeviceInfo; deviceInfo->structVersion = 2; deviceInfo->hostApi = hostApiIndex; PaError err = paNoError; UInt32 propSize; err = conv_err(AudioDeviceGetPropertyInfo(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, NULL)); // FIXME: this allocation should be part of the allocations group char *name = PaUtil_AllocateMemory(propSize); err = conv_err(AudioDeviceGetProperty(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, name)); if (!err) { deviceInfo->name = name; } Float64 sampleRate; propSize = sizeof(Float64); err = conv_err(AudioDeviceGetProperty(macCoreDeviceId, 0, 0, kAudioDevicePropertyNominalSampleRate, &propSize, &sampleRate)); if (!err) { deviceInfo->defaultSampleRate = sampleRate; } // Get channel info err = GetChannelInfo(deviceInfo, macCoreDeviceId, 1); err = GetChannelInfo(deviceInfo, macCoreDeviceId, 0); return err; } static PaError InitializeDeviceInfos( PaMacCoreHostApiRepresentation *macCoreHostApi, PaHostApiIndex hostApiIndex ) { PaError result = paNoError; PaUtilHostApiRepresentation *hostApi; PaMacCoreDeviceInfo *deviceInfoArray; // initialise device counts and default devices under the assumption that there are no devices. These values are incremented below if and when devices are successfully initialized. hostApi = &macCoreHostApi->inheritedHostApiRep; hostApi->info.deviceCount = 0; hostApi->info.defaultInputDevice = paNoDevice; hostApi->info.defaultOutputDevice = paNoDevice; UInt32 propsize; AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &propsize, NULL); int numDevices = propsize / sizeof(AudioDeviceID); hostApi->info.deviceCount = numDevices; if (numDevices > 0) { hostApi->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( macCoreHostApi->allocations, sizeof(PaDeviceInfo*) * numDevices ); if( !hostApi->deviceInfos ) { return paInsufficientMemory; } // allocate all device info structs in a contiguous block deviceInfoArray = (PaMacCoreDeviceInfo*)PaUtil_GroupAllocateMemory( macCoreHostApi->allocations, sizeof(PaMacCoreDeviceInfo) * numDevices ); if( !deviceInfoArray ) { return paInsufficientMemory; } macCoreHostApi->macCoreDeviceIds = PaUtil_GroupAllocateMemory(macCoreHostApi->allocations, propsize); AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &propsize, macCoreHostApi->macCoreDeviceIds); AudioDeviceID defaultInputDevice, defaultOutputDevice; propsize = sizeof(AudioDeviceID); AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &propsize, &defaultInputDevice); AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &propsize, &defaultOutputDevice); UInt32 i; for (i = 0; i < numDevices; ++i) { if (macCoreHostApi->macCoreDeviceIds[i] == defaultInputDevice) { hostApi->info.defaultInputDevice = i; } if (macCoreHostApi->macCoreDeviceIds[i] == defaultOutputDevice) { hostApi->info.defaultOutputDevice = i; } InitializeDeviceInfo(&deviceInfoArray[i], macCoreHostApi->macCoreDeviceIds[i], hostApiIndex); hostApi->deviceInfos[i] = &(deviceInfoArray[i].inheritedDeviceInfo); } } return result; } static OSStatus CheckFormat(AudioDeviceID macCoreDeviceId, const PaStreamParameters *parameters, double sampleRate, int isInput) { UInt32 propSize = sizeof(AudioStreamBasicDescription); AudioStreamBasicDescription *streamDescription = PaUtil_AllocateMemory(propSize); streamDescription->mSampleRate = sampleRate; streamDescription->mFormatID = 0; streamDescription->mFormatFlags = 0; streamDescription->mBytesPerPacket = 0; streamDescription->mFramesPerPacket = 0; streamDescription->mBytesPerFrame = 0; streamDescription->mChannelsPerFrame = 0; streamDescription->mBitsPerChannel = 0; streamDescription->mReserved = 0; OSStatus result = AudioDeviceGetProperty(macCoreDeviceId, 0, isInput, kAudioDevicePropertyStreamFormatSupported, &propSize, streamDescription); PaUtil_FreeMemory(streamDescription); return result; } static OSStatus CopyInputData(PaMacClientData* destination, const AudioBufferList *source, unsigned long frameCount) { int frameSpacing, channelSpacing; if (destination->inputSampleFormat & paNonInterleaved) { frameSpacing = 1; channelSpacing = destination->inputChannelCount; } else { frameSpacing = destination->inputChannelCount; channelSpacing = 1; } AudioBuffer const *inputBuffer = &source->mBuffers[0]; void *coreAudioBuffer = inputBuffer->mData; void *portAudioBuffer = destination->inputBuffer; UInt32 i, streamNumber, streamChannel; for (i = streamNumber = streamChannel = 0; i < destination->inputChannelCount; ++i, ++streamChannel) { if (streamChannel >= inputBuffer->mNumberChannels) { ++streamNumber; inputBuffer = &source->mBuffers[streamNumber]; coreAudioBuffer = inputBuffer->mData; streamChannel = 0; } destination->inputConverter(portAudioBuffer, frameSpacing, coreAudioBuffer, inputBuffer->mNumberChannels, frameCount, destination->ditherGenerator); coreAudioBuffer += sizeof(Float32); portAudioBuffer += Pa_GetSampleSize(destination->inputSampleFormat) * channelSpacing; } return noErr; } static OSStatus CopyOutputData(AudioBufferList* destination, PaMacClientData *source, unsigned long frameCount) { int frameSpacing, channelSpacing; if (source->outputSampleFormat & paNonInterleaved) { frameSpacing = 1; channelSpacing = source->outputChannelCount; } else { frameSpacing = source->outputChannelCount; channelSpacing = 1; } AudioBuffer *outputBuffer = &destination->mBuffers[0]; void *coreAudioBuffer = outputBuffer->mData; void *portAudioBuffer = source->outputBuffer; UInt32 i, streamNumber, streamChannel; for (i = streamNumber = streamChannel = 0; i < source->outputChannelCount; ++i, ++streamChannel) { if (streamChannel >= outputBuffer->mNumberChannels) { ++streamNumber; outputBuffer = &destination->mBuffers[streamNumber]; coreAudioBuffer = outputBuffer->mData; streamChannel = 0; } source->outputConverter(coreAudioBuffer, outputBuffer->mNumberChannels, portAudioBuffer, frameSpacing, frameCount, NULL); coreAudioBuffer += sizeof(Float32); portAudioBuffer += Pa_GetSampleSize(source->outputSampleFormat) * channelSpacing; } return noErr; } static OSStatus AudioIOProc( AudioDeviceID inDevice, const AudioTimeStamp* inNow, const AudioBufferList* inInputData, const AudioTimeStamp* inInputTime, AudioBufferList* outOutputData, const AudioTimeStamp* inOutputTime, void* inClientData) { PaMacClientData *clientData = (PaMacClientData *)inClientData; PaStreamCallbackTimeInfo *timeInfo = InitializeTimeInfo(inNow, inInputTime, inOutputTime); PaUtil_BeginCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer ); AudioBuffer *outputBuffer = &outOutputData->mBuffers[0]; unsigned long frameCount = outputBuffer->mDataByteSize / (outputBuffer->mNumberChannels * sizeof(Float32)); if (clientData->inputBuffer) { CopyInputData(clientData, inInputData, frameCount); } PaStreamCallbackResult result = clientData->callback(clientData->inputBuffer, clientData->outputBuffer, frameCount, timeInfo, paNoFlag, clientData->userData); if (clientData->outputBuffer) { CopyOutputData(outOutputData, clientData, frameCount); } PaUtil_EndCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer, frameCount ); if (result == paComplete || result == paAbort) { Pa_StopStream(clientData->stream); } PaUtil_FreeMemory( timeInfo ); return noErr; } // This is not for input-only streams, this is for streams where the input device is different from the output device static OSStatus AudioInputProc( AudioDeviceID inDevice, const AudioTimeStamp* inNow, const AudioBufferList* inInputData, const AudioTimeStamp* inInputTime, AudioBufferList* outOutputData, const AudioTimeStamp* inOutputTime, void* inClientData) { PaMacClientData *clientData = (PaMacClientData *)inClientData; PaStreamCallbackTimeInfo *timeInfo = InitializeTimeInfo(inNow, inInputTime, inOutputTime); PaUtil_BeginCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer ); AudioBuffer const *inputBuffer = &inInputData->mBuffers[0]; unsigned long frameCount = inputBuffer->mDataByteSize / (inputBuffer->mNumberChannels * sizeof(Float32)); CopyInputData(clientData, inInputData, frameCount); PaStreamCallbackResult result = clientData->callback(clientData->inputBuffer, clientData->outputBuffer, frameCount, timeInfo, paNoFlag, clientData->userData); PaUtil_EndCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer, frameCount ); if( result == paComplete || result == paAbort ) Pa_StopStream(clientData->stream); PaUtil_FreeMemory( timeInfo ); return noErr; } // This is not for output-only streams, this is for streams where the input device is different from the output device static OSStatus AudioOutputProc( AudioDeviceID inDevice, const AudioTimeStamp* inNow, const AudioBufferList* inInputData, const AudioTimeStamp* inInputTime, AudioBufferList* outOutputData, const AudioTimeStamp* inOutputTime, void* inClientData) { PaMacClientData *clientData = (PaMacClientData *)inClientData; //PaStreamCallbackTimeInfo *timeInfo = InitializeTimeInfo(inNow, inInputTime, inOutputTime); PaUtil_BeginCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer ); AudioBuffer *outputBuffer = &outOutputData->mBuffers[0]; unsigned long frameCount = outputBuffer->mDataByteSize / (outputBuffer->mNumberChannels * sizeof(Float32)); //clientData->callback(NULL, clientData->outputBuffer, frameCount, timeInfo, paNoFlag, clientData->userData); CopyOutputData(outOutputData, clientData, frameCount); PaUtil_EndCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer, frameCount ); return noErr; } static PaError SetSampleRate(AudioDeviceID device, double sampleRate, int isInput) { PaError result = paNoError; double actualSampleRate; UInt32 propSize = sizeof(double); result = conv_err(AudioDeviceSetProperty(device, NULL, 0, isInput, kAudioDevicePropertyNominalSampleRate, propSize, &sampleRate)); result = conv_err(AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyNominalSampleRate, &propSize, &actualSampleRate)); if (result == paNoError && actualSampleRate != sampleRate) { result = paInvalidSampleRate; } return result; } static PaError SetFramesPerBuffer(AudioDeviceID device, unsigned long framesPerBuffer, int isInput) { PaError result = paNoError; UInt32 preferredFramesPerBuffer = framesPerBuffer; // while (preferredFramesPerBuffer > UINT32_MAX) { // preferredFramesPerBuffer /= 2; // } UInt32 actualFramesPerBuffer; UInt32 propSize = sizeof(UInt32); result = conv_err(AudioDeviceSetProperty(device, NULL, 0, isInput, kAudioDevicePropertyBufferFrameSize, propSize, &preferredFramesPerBuffer)); result = conv_err(AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyBufferFrameSize, &propSize, &actualFramesPerBuffer)); if (result != paNoError) { // do nothing } else if (actualFramesPerBuffer > framesPerBuffer) { result = paBufferTooSmall; } else if (actualFramesPerBuffer < framesPerBuffer) { result = paBufferTooBig; } return result; } static PaError SetUpUnidirectionalStream(AudioDeviceID device, double sampleRate, unsigned long framesPerBuffer, int isInput) { PaError err = paNoError; err = SetSampleRate(device, sampleRate, isInput); if( err == paNoError ) err = SetFramesPerBuffer(device, framesPerBuffer, isInput); return err; } // ===== PortAudio functions ===== #pragma mark PortAudio functions #ifdef __cplusplus extern "C" { #endif // __cplusplus PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); #ifdef __cplusplus } #endif // __cplusplus static void Terminate( struct PaUtilHostApiRepresentation *hostApi ) { PaMacCoreHostApiRepresentation *macCoreHostApi = (PaMacCoreHostApiRepresentation*)hostApi; CleanUp(macCoreHostApi); } static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ) { PaMacCoreHostApiRepresentation *macCoreHostApi = (PaMacCoreHostApiRepresentation*)hostApi; PaDeviceInfo *deviceInfo; PaError result = paNoError; if (inputParameters) { deviceInfo = macCoreHostApi->inheritedHostApiRep.deviceInfos[inputParameters->device]; if (inputParameters->channelCount > deviceInfo->maxInputChannels) result = paInvalidChannelCount; else if (CheckFormat(macCoreHostApi->macCoreDeviceIds[inputParameters->device], inputParameters, sampleRate, 1) != kAudioHardwareNoError) { result = paInvalidSampleRate; } } if (outputParameters && result == paNoError) { deviceInfo = macCoreHostApi->inheritedHostApiRep.deviceInfos[outputParameters->device]; if (outputParameters->channelCount > deviceInfo->maxOutputChannels) result = paInvalidChannelCount; else if (CheckFormat(macCoreHostApi->macCoreDeviceIds[outputParameters->device], outputParameters, sampleRate, 0) != kAudioHardwareNoError) { result = paInvalidSampleRate; } } return result; } static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ) { PaError err = paNoError; PaMacCoreHostApiRepresentation *macCoreHostApi = (PaMacCoreHostApiRepresentation *)hostApi; PaMacCoreStream *stream = PaUtil_AllocateMemory(sizeof(PaMacCoreStream)); stream->isActive = 0; stream->isStopped = 1; stream->inputDevice = kAudioDeviceUnknown; stream->outputDevice = kAudioDeviceUnknown; PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, ( (streamCallback) ? &macCoreHostApi->callbackStreamInterface : &macCoreHostApi->blockingStreamInterface ), streamCallback, userData ); PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate ); *s = (PaStream*)stream; PaMacClientData *clientData = PaUtil_AllocateMemory(sizeof(PaMacClientData)); clientData->stream = stream; clientData->callback = streamCallback; clientData->userData = userData; clientData->inputBuffer = 0; clientData->outputBuffer = 0; clientData->ditherGenerator = PaUtil_AllocateMemory(sizeof(PaUtilTriangularDitherGenerator)); PaUtil_InitializeTriangularDitherState(clientData->ditherGenerator); if (inputParameters != NULL) { stream->inputDevice = macCoreHostApi->macCoreDeviceIds[inputParameters->device]; clientData->inputConverter = PaUtil_SelectConverter(paFloat32, inputParameters->sampleFormat, streamFlags); clientData->inputBuffer = PaUtil_AllocateMemory(Pa_GetSampleSize(inputParameters->sampleFormat) * framesPerBuffer * inputParameters->channelCount); clientData->inputChannelCount = inputParameters->channelCount; clientData->inputSampleFormat = inputParameters->sampleFormat; err = SetUpUnidirectionalStream(stream->inputDevice, sampleRate, framesPerBuffer, 1); } if (err == paNoError && outputParameters != NULL) { stream->outputDevice = macCoreHostApi->macCoreDeviceIds[outputParameters->device]; clientData->outputConverter = PaUtil_SelectConverter(outputParameters->sampleFormat, paFloat32, streamFlags); clientData->outputBuffer = PaUtil_AllocateMemory(Pa_GetSampleSize(outputParameters->sampleFormat) * framesPerBuffer * outputParameters->channelCount); clientData->outputChannelCount = outputParameters->channelCount; clientData->outputSampleFormat = outputParameters->sampleFormat; err = SetUpUnidirectionalStream(stream->outputDevice, sampleRate, framesPerBuffer, 0); } if (inputParameters == NULL || outputParameters == NULL || stream->inputDevice == stream->outputDevice) { AudioDeviceID device = (inputParameters == NULL) ? stream->outputDevice : stream->inputDevice; AudioDeviceAddIOProc(device, AudioIOProc, clientData); } else { // using different devices for input and output AudioDeviceAddIOProc(stream->inputDevice, AudioInputProc, clientData); AudioDeviceAddIOProc(stream->outputDevice, AudioOutputProc, clientData); } return err; } // Note: When CloseStream() is called, the multi-api layer ensures that the stream has already been stopped or aborted. static PaError CloseStream( PaStream* s ) { PaError err = paNoError; PaMacCoreStream *stream = (PaMacCoreStream*)s; PaUtil_ResetCpuLoadMeasurer( &stream->cpuLoadMeasurer ); if (stream->inputDevice != kAudioDeviceUnknown) { if (stream->outputDevice == kAudioDeviceUnknown || stream->outputDevice == stream->inputDevice) { err = conv_err(AudioDeviceRemoveIOProc(stream->inputDevice, AudioIOProc)); } else { err = conv_err(AudioDeviceRemoveIOProc(stream->inputDevice, AudioInputProc)); err = conv_err(AudioDeviceRemoveIOProc(stream->outputDevice, AudioOutputProc)); } } else { err = conv_err(AudioDeviceRemoveIOProc(stream->outputDevice, AudioIOProc)); } return err; } static PaError StartStream( PaStream *s ) { PaError err = paNoError; PaMacCoreStream *stream = (PaMacCoreStream*)s; if (stream->inputDevice != kAudioDeviceUnknown) { if (stream->outputDevice == kAudioDeviceUnknown || stream->outputDevice == stream->inputDevice) { err = conv_err(AudioDeviceStart(stream->inputDevice, AudioIOProc)); } else { err = conv_err(AudioDeviceStart(stream->inputDevice, AudioInputProc)); err = conv_err(AudioDeviceStart(stream->outputDevice, AudioOutputProc)); } } else { err = conv_err(AudioDeviceStart(stream->outputDevice, AudioIOProc)); } stream->isActive = 1; stream->isStopped = 0; return err; } static PaError AbortStream( PaStream *s ) { PaError err = paNoError; PaMacCoreStream *stream = (PaMacCoreStream*)s; if (stream->inputDevice != kAudioDeviceUnknown) { if (stream->outputDevice == kAudioDeviceUnknown || stream->outputDevice == stream->inputDevice) { err = conv_err(AudioDeviceStop(stream->inputDevice, AudioIOProc)); } else { err = conv_err(AudioDeviceStop(stream->inputDevice, AudioInputProc)); err = conv_err(AudioDeviceStop(stream->outputDevice, AudioOutputProc)); } } else { err = conv_err(AudioDeviceStop(stream->outputDevice, AudioIOProc)); } stream->isActive = 0; stream->isStopped = 1; return err; } static PaError StopStream( PaStream *s ) { // TODO: this should be nicer than abort return AbortStream(s); } static PaError IsStreamStopped( PaStream *s ) { PaMacCoreStream *stream = (PaMacCoreStream*)s; return stream->isStopped; } static PaError IsStreamActive( PaStream *s ) { PaMacCoreStream *stream = (PaMacCoreStream*)s; return stream->isActive; } static PaTime GetStreamTime( PaStream *s ) { OSStatus err; PaTime result; PaMacCoreStream *stream = (PaMacCoreStream*)s; AudioTimeStamp *timeStamp = PaUtil_AllocateMemory(sizeof(AudioTimeStamp)); if (stream->inputDevice != kAudioDeviceUnknown) { err = AudioDeviceGetCurrentTime(stream->inputDevice, timeStamp); } else { err = AudioDeviceGetCurrentTime(stream->outputDevice, timeStamp); } result = err ? 0 : timeStamp->mSampleTime; PaUtil_FreeMemory(timeStamp); return result; } static double GetStreamCpuLoad( PaStream* s ) { PaMacCoreStream *stream = (PaMacCoreStream*)s; return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ); } // As separate stream interfaces are used for blocking and callback streams, the following functions can be guaranteed to only be called for blocking streams. static PaError ReadStream( PaStream* s, void *buffer, unsigned long frames ) { return paInternalError; } static PaError WriteStream( PaStream* s, const void *buffer, unsigned long frames ) { return paInternalError; } static signed long GetStreamReadAvailable( PaStream* s ) { return paInternalError; } static signed long GetStreamWriteAvailable( PaStream* s ) { return paInternalError; } // HostAPI-specific initialization function PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) { PaError result = paNoError; PaMacCoreHostApiRepresentation *macCoreHostApi = (PaMacCoreHostApiRepresentation *)PaUtil_AllocateMemory( sizeof(PaMacCoreHostApiRepresentation) ); if( !macCoreHostApi ) { result = paInsufficientMemory; goto error; } macCoreHostApi->allocations = PaUtil_CreateAllocationGroup(); if( !macCoreHostApi->allocations ) { result = paInsufficientMemory; goto error; } *hostApi = &macCoreHostApi->inheritedHostApiRep; (*hostApi)->info.structVersion = 1; (*hostApi)->info.type = paCoreAudio; (*hostApi)->info.name = "CoreAudio"; result = InitializeDeviceInfos(macCoreHostApi, hostApiIndex); if (result != paNoError) { goto error; } // Set up the proper callbacks to this HostApi's functions (*hostApi)->Terminate = Terminate; (*hostApi)->OpenStream = OpenStream; (*hostApi)->IsFormatSupported = IsFormatSupported; PaUtil_InitializeStreamInterface( &macCoreHostApi->callbackStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, GetStreamCpuLoad, PaUtil_DummyRead, PaUtil_DummyWrite, PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable ); PaUtil_InitializeStreamInterface( &macCoreHostApi->blockingStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, PaUtil_DummyGetCpuLoad, ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable ); return result; error: if( macCoreHostApi ) { CleanUp(macCoreHostApi); } return result; } pd-0.46-7/portaudio/src/hostapi/coreaudio/pa_mac_core.c0000664000175000017500000034237412374250720021225 0ustar mspmsp/* * Implementation of the PortAudio API for Apple AUHAL * * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * * Written by Bjorn Roche of XO Audio LLC, from PA skeleton code. * Portions copied from code by Dominic Mazzoni (who wrote a HAL implementation) * * Dominic's code was based on code by Phil Burk, Darren Gibbs, * Gord Peters, Stephane Letz, and Greg Pfiel. * * The following people also deserve acknowledgements: * * Olivier Tristan for feedback and testing * Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O * interface. * * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file pa_mac_core @ingroup hostapi_src @author Bjorn Roche @brief AUHAL implementation of PortAudio */ /* FIXME: not all error conditions call PaUtil_SetLastHostErrorInfo() * PaMacCore_SetError() will do this. */ #include "pa_mac_core_internal.h" #include /* strlen(), memcmp() etc. */ #include #include "pa_mac_core.h" #include "pa_mac_core_utilities.h" #include "pa_mac_core_blocking.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* This is a reasonable size for a small buffer based on experience. */ #define PA_MAC_SMALL_BUFFER_SIZE (64) /* prototypes for functions declared in this file */ PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); /* * Function declared in pa_mac_core.h. Sets up a PaMacCoreStreamInfoStruct * with the requested flags and initializes channel map. */ void PaMacCore_SetupStreamInfo( PaMacCoreStreamInfo *data, const unsigned long flags ) { bzero( data, sizeof( PaMacCoreStreamInfo ) ); data->size = sizeof( PaMacCoreStreamInfo ); data->hostApiType = paCoreAudio; data->version = 0x01; data->flags = flags; data->channelMap = NULL; data->channelMapSize = 0; } /* * Function declared in pa_mac_core.h. Adds channel mapping to a PaMacCoreStreamInfoStruct */ void PaMacCore_SetupChannelMap( PaMacCoreStreamInfo *data, const SInt32 * const channelMap, const unsigned long channelMapSize ) { data->channelMap = channelMap; data->channelMapSize = channelMapSize; } static char *channelName = NULL; static int channelNameSize = 0; static bool ensureChannelNameSize( int size ) { if( size >= channelNameSize ) { free( channelName ); channelName = (char *) malloc( ( channelNameSize = size ) + 1 ); if( !channelName ) { channelNameSize = 0; return false; } } return true; } /* * Function declared in pa_mac_core.h. retrives channel names. */ const char *PaMacCore_GetChannelName( int device, int channelIndex, bool input ) { struct PaUtilHostApiRepresentation *hostApi; PaError err; OSStatus error; err = PaUtil_GetHostApiRepresentation( &hostApi, paCoreAudio ); assert(err == paNoError); if( err != paNoError ) return NULL; PaMacAUHAL *macCoreHostApi = (PaMacAUHAL*)hostApi; AudioDeviceID hostApiDevice = macCoreHostApi->devIds[device]; UInt32 size = 0; error = AudioDeviceGetPropertyInfo( hostApiDevice, channelIndex + 1, input, kAudioDevicePropertyChannelName, &size, NULL ); if( error ) { //try the CFString CFStringRef name; bool isDeviceName = false; size = sizeof( name ); error = AudioDeviceGetProperty( hostApiDevice, channelIndex + 1, input, kAudioDevicePropertyChannelNameCFString, &size, &name ); if( error ) { //as a last-ditch effort, get the device name. Later we'll append the channel number. size = sizeof( name ); error = AudioDeviceGetProperty( hostApiDevice, channelIndex + 1, input, kAudioDevicePropertyDeviceNameCFString, &size, &name ); if( error ) return NULL; isDeviceName = true; } if( isDeviceName ) { name = CFStringCreateWithFormat( NULL, NULL, CFSTR( "%@: %d"), name, channelIndex + 1 ); } CFIndex length = CFStringGetLength(name); while( ensureChannelNameSize( length * sizeof(UniChar) + 1 ) ) { if( CFStringGetCString( name, channelName, channelNameSize, kCFStringEncodingUTF8 ) ) { if( isDeviceName ) CFRelease( name ); return channelName; } if( length == 0 ) ++length; length *= 2; } if( isDeviceName ) CFRelease( name ); return NULL; } //continue with C string: if( !ensureChannelNameSize( size ) ) return NULL; error = AudioDeviceGetProperty( hostApiDevice, channelIndex + 1, input, kAudioDevicePropertyChannelName, &size, channelName ); if( error ) { ERR( error ); return NULL; } return channelName; } PaError PaMacCore_GetBufferSizeRange( PaDeviceIndex device, long *minBufferSizeFrames, long *maxBufferSizeFrames ) { PaError result; PaUtilHostApiRepresentation *hostApi; result = PaUtil_GetHostApiRepresentation( &hostApi, paCoreAudio ); if( result == paNoError ) { PaDeviceIndex hostApiDeviceIndex; result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDeviceIndex, device, hostApi ); if( result == paNoError ) { PaMacAUHAL *macCoreHostApi = (PaMacAUHAL*)hostApi; AudioDeviceID macCoreDeviceId = macCoreHostApi->devIds[hostApiDeviceIndex]; AudioValueRange audioRange; UInt32 propSize = sizeof( audioRange ); // return the size range for the output scope unless we only have inputs Boolean isInput = 0; if( macCoreHostApi->inheritedHostApiRep.deviceInfos[hostApiDeviceIndex]->maxOutputChannels == 0 ) isInput = 1; result = WARNING(AudioDeviceGetProperty( macCoreDeviceId, 0, isInput, kAudioDevicePropertyBufferFrameSizeRange, &propSize, &audioRange ) ); *minBufferSizeFrames = audioRange.mMinimum; *maxBufferSizeFrames = audioRange.mMaximum; } } return result; } AudioDeviceID PaMacCore_GetStreamInputDevice( PaStream* s ) { PaMacCoreStream *stream = (PaMacCoreStream*)s; VVDBUG(("PaMacCore_GetStreamInputHandle()\n")); return ( stream->inputDevice ); } AudioDeviceID PaMacCore_GetStreamOutputDevice( PaStream* s ) { PaMacCoreStream *stream = (PaMacCoreStream*)s; VVDBUG(("PaMacCore_GetStreamOutputHandle()\n")); return ( stream->outputDevice ); } #ifdef __cplusplus } #endif /* __cplusplus */ #define RING_BUFFER_ADVANCE_DENOMINATOR (4) static void Terminate( struct PaUtilHostApiRepresentation *hostApi ); static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ); static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ); static PaError CloseStream( PaStream* stream ); static PaError StartStream( PaStream *stream ); static PaError StopStream( PaStream *stream ); static PaError AbortStream( PaStream *stream ); static PaError IsStreamStopped( PaStream *s ); static PaError IsStreamActive( PaStream *stream ); static PaTime GetStreamTime( PaStream *stream ); static OSStatus AudioIOProc( void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData ); static double GetStreamCpuLoad( PaStream* stream ); static PaError GetChannelInfo( PaMacAUHAL *auhalHostApi, PaDeviceInfo *deviceInfo, AudioDeviceID macCoreDeviceId, int isInput); static PaError OpenAndSetupOneAudioUnit( const PaMacCoreStream *stream, const PaStreamParameters *inStreamParams, const PaStreamParameters *outStreamParams, const UInt32 requestedFramesPerBuffer, UInt32 *actualInputFramesPerBuffer, UInt32 *actualOutputFramesPerBuffer, const PaMacAUHAL *auhalHostApi, AudioUnit *audioUnit, AudioConverterRef *srConverter, AudioDeviceID *audioDevice, const double sampleRate, void *refCon ); /* for setting errors. */ #define PA_AUHAL_SET_LAST_HOST_ERROR( errorCode, errorText ) \ PaUtil_SetLastHostErrorInfo( paInDevelopment, errorCode, errorText ) /* * Callback called when starting or stopping a stream. */ static void startStopCallback( void * inRefCon, AudioUnit ci, AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement ) { PaMacCoreStream *stream = (PaMacCoreStream *) inRefCon; UInt32 isRunning; UInt32 size = sizeof( isRunning ); OSStatus err; err = AudioUnitGetProperty( ci, kAudioOutputUnitProperty_IsRunning, inScope, inElement, &isRunning, &size ); assert( !err ); if( err ) isRunning = false; //it's very unclear what to do in case of error here. There's no real way to notify the user, and crashing seems unreasonable. if( isRunning ) return; //We are only interested in when we are stopping // -- if we are using 2 I/O units, we only need one notification! if( stream->inputUnit && stream->outputUnit && stream->inputUnit != stream->outputUnit && ci == stream->inputUnit ) return; PaStreamFinishedCallback *sfc = stream->streamRepresentation.streamFinishedCallback; if( stream->state == STOPPING ) stream->state = STOPPED ; if( sfc ) sfc( stream->streamRepresentation.userData ); } /*currently, this is only used in initialization, but it might be modified to be used when the list of devices changes.*/ static PaError gatherDeviceInfo(PaMacAUHAL *auhalHostApi) { UInt32 size; UInt32 propsize; VVDBUG(("gatherDeviceInfo()\n")); /* -- free any previous allocations -- */ if( auhalHostApi->devIds ) PaUtil_GroupFreeMemory(auhalHostApi->allocations, auhalHostApi->devIds); auhalHostApi->devIds = NULL; /* -- figure out how many devices there are -- */ AudioHardwareGetPropertyInfo( kAudioHardwarePropertyDevices, &propsize, NULL ); auhalHostApi->devCount = propsize / sizeof( AudioDeviceID ); VDBUG( ( "Found %ld device(s).\n", auhalHostApi->devCount ) ); /* -- copy the device IDs -- */ auhalHostApi->devIds = (AudioDeviceID *)PaUtil_GroupAllocateMemory( auhalHostApi->allocations, propsize ); if( !auhalHostApi->devIds ) return paInsufficientMemory; AudioHardwareGetProperty( kAudioHardwarePropertyDevices, &propsize, auhalHostApi->devIds ); #ifdef MAC_CORE_VERBOSE_DEBUG { int i; for( i=0; idevCount; ++i ) printf( "Device %d\t: %ld\n", i, auhalHostApi->devIds[i] ); } #endif size = sizeof(AudioDeviceID); auhalHostApi->defaultIn = kAudioDeviceUnknown; auhalHostApi->defaultOut = kAudioDeviceUnknown; /* determine the default device. */ /* I am not sure how these calls to AudioHardwareGetProperty() could fail, but in case they do, we use the first available device as the default. */ if( 0 != AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &size, &auhalHostApi->defaultIn) ) { int i; auhalHostApi->defaultIn = kAudioDeviceUnknown; VDBUG(("Failed to get default input device from OS.")); VDBUG((" I will substitute the first available input Device.")); for( i=0; idevCount; ++i ) { PaDeviceInfo devInfo; if( 0 != GetChannelInfo( auhalHostApi, &devInfo, auhalHostApi->devIds[i], TRUE ) ) if( devInfo.maxInputChannels ) { auhalHostApi->defaultIn = auhalHostApi->devIds[i]; break; } } } if( 0 != AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &size, &auhalHostApi->defaultOut) ) { int i; auhalHostApi->defaultIn = kAudioDeviceUnknown; VDBUG(("Failed to get default output device from OS.")); VDBUG((" I will substitute the first available output Device.")); for( i=0; idevCount; ++i ) { PaDeviceInfo devInfo; if( 0 != GetChannelInfo( auhalHostApi, &devInfo, auhalHostApi->devIds[i], FALSE ) ) if( devInfo.maxOutputChannels ) { auhalHostApi->defaultOut = auhalHostApi->devIds[i]; break; } } } VDBUG( ( "Default in : %ld\n", auhalHostApi->defaultIn ) ); VDBUG( ( "Default out: %ld\n", auhalHostApi->defaultOut ) ); return paNoError; } /* =================================================================================================== */ /** * @internal * @brief Clip the desired size against the allowed IO buffer size range for the device. */ static PaError ClipToDeviceBufferSize( AudioDeviceID macCoreDeviceId, int isInput, UInt32 desiredSize, UInt32 *allowedSize ) { UInt32 resultSize = desiredSize; AudioValueRange audioRange; UInt32 propSize = sizeof( audioRange ); PaError err = WARNING(AudioDeviceGetProperty( macCoreDeviceId, 0, isInput, kAudioDevicePropertyBufferFrameSizeRange, &propSize, &audioRange ) ); resultSize = MAX( resultSize, audioRange.mMinimum ); resultSize = MIN( resultSize, audioRange.mMaximum ); *allowedSize = resultSize; return err; } /* =================================================================================================== */ #if 0 static void DumpDeviceProperties( AudioDeviceID macCoreDeviceId, int isInput ) { PaError err; int i; UInt32 propSize; UInt32 deviceLatency; UInt32 streamLatency; UInt32 bufferFrames; UInt32 safetyOffset; AudioStreamID streamIDs[128]; printf("\n======= latency query : macCoreDeviceId = %d, isInput %d =======\n", (int)macCoreDeviceId, isInput ); propSize = sizeof(UInt32); err = WARNING(AudioDeviceGetProperty(macCoreDeviceId, 0, isInput, kAudioDevicePropertyBufferFrameSize, &propSize, &bufferFrames)); printf("kAudioDevicePropertyBufferFrameSize: err = %d, propSize = %d, value = %d\n", err, propSize, bufferFrames ); propSize = sizeof(UInt32); err = WARNING(AudioDeviceGetProperty(macCoreDeviceId, 0, isInput, kAudioDevicePropertySafetyOffset, &propSize, &safetyOffset)); printf("kAudioDevicePropertySafetyOffset: err = %d, propSize = %d, value = %d\n", err, propSize, safetyOffset ); propSize = sizeof(UInt32); err = WARNING(AudioDeviceGetProperty(macCoreDeviceId, 0, isInput, kAudioDevicePropertyLatency, &propSize, &deviceLatency)); printf("kAudioDevicePropertyLatency: err = %d, propSize = %d, value = %d\n", err, propSize, deviceLatency ); AudioValueRange audioRange; propSize = sizeof( audioRange ); err = WARNING(AudioDeviceGetProperty( macCoreDeviceId, 0, isInput, kAudioDevicePropertyBufferFrameSizeRange, &propSize, &audioRange ) ); printf("kAudioDevicePropertyBufferFrameSizeRange: err = %d, propSize = %u, minimum = %g\n", err, propSize, audioRange.mMinimum); printf("kAudioDevicePropertyBufferFrameSizeRange: err = %d, propSize = %u, maximum = %g\n", err, propSize, audioRange.mMaximum ); /* Get the streams from the device and query their latency. */ propSize = sizeof(streamIDs); err = WARNING(AudioDeviceGetProperty(macCoreDeviceId, 0, isInput, kAudioDevicePropertyStreams, &propSize, &streamIDs[0])); int numStreams = propSize / sizeof(AudioStreamID); for( i=0; imNumberBuffers; ++i) numChannels += buflist->mBuffers[i].mNumberChannels; if (isInput) deviceInfo->maxInputChannels = numChannels; else deviceInfo->maxOutputChannels = numChannels; if (numChannels > 0) /* do not try to retrieve the latency if there are no channels. */ { /* Get the latency. Don't fail if we can't get this. */ /* default to something reasonable */ deviceInfo->defaultLowInputLatency = .01; deviceInfo->defaultHighInputLatency = .10; deviceInfo->defaultLowOutputLatency = .01; deviceInfo->defaultHighOutputLatency = .10; UInt32 lowLatencyFrames = 0; UInt32 highLatencyFrames = 0; err = CalculateDefaultDeviceLatencies( macCoreDeviceId, isInput, &lowLatencyFrames, &highLatencyFrames ); if( err == 0 ) { double lowLatencySeconds = lowLatencyFrames / deviceInfo->defaultSampleRate; double highLatencySeconds = highLatencyFrames / deviceInfo->defaultSampleRate; if (isInput) { deviceInfo->defaultLowInputLatency = lowLatencySeconds; deviceInfo->defaultHighInputLatency = highLatencySeconds; } else { deviceInfo->defaultLowOutputLatency = lowLatencySeconds; deviceInfo->defaultHighOutputLatency = highLatencySeconds; } } } PaUtil_FreeMemory( buflist ); return paNoError; error: PaUtil_FreeMemory( buflist ); return err; } /* =================================================================================================== */ static PaError InitializeDeviceInfo( PaMacAUHAL *auhalHostApi, PaDeviceInfo *deviceInfo, AudioDeviceID macCoreDeviceId, PaHostApiIndex hostApiIndex ) { Float64 sampleRate; char *name; PaError err = paNoError; UInt32 propSize; VVDBUG(("InitializeDeviceInfo(): macCoreDeviceId=%ld\n", macCoreDeviceId)); memset(deviceInfo, 0, sizeof(PaDeviceInfo)); deviceInfo->structVersion = 2; deviceInfo->hostApi = hostApiIndex; /* Get the device name. Fail if we can't get it. */ err = ERR(AudioDeviceGetPropertyInfo(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, NULL)); if (err) return err; name = PaUtil_GroupAllocateMemory(auhalHostApi->allocations,propSize); if ( !name ) return paInsufficientMemory; err = ERR(AudioDeviceGetProperty(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, name)); if (err) return err; deviceInfo->name = name; /* Try to get the default sample rate. Don't fail if we can't get this. */ propSize = sizeof(Float64); err = ERR(AudioDeviceGetProperty(macCoreDeviceId, 0, 0, kAudioDevicePropertyNominalSampleRate, &propSize, &sampleRate)); if (err) deviceInfo->defaultSampleRate = 0.0; else deviceInfo->defaultSampleRate = sampleRate; /* Get the maximum number of input and output channels. Fail if we can't get this. */ err = GetChannelInfo(auhalHostApi, deviceInfo, macCoreDeviceId, 1); if (err) return err; err = GetChannelInfo(auhalHostApi, deviceInfo, macCoreDeviceId, 0); if (err) return err; return paNoError; } PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) { PaError result = paNoError; int i; PaMacAUHAL *auhalHostApi = NULL; PaDeviceInfo *deviceInfoArray; int unixErr; VVDBUG(("PaMacCore_Initialize(): hostApiIndex=%d\n", hostApiIndex)); SInt32 major; SInt32 minor; Gestalt(gestaltSystemVersionMajor, &major); Gestalt(gestaltSystemVersionMinor, &minor); // Starting with 10.6 systems, the HAL notification thread is created internally if (major == 10 && minor >= 6) { CFRunLoopRef theRunLoop = NULL; AudioObjectPropertyAddress theAddress = { kAudioHardwarePropertyRunLoop, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; OSStatus osErr = AudioObjectSetPropertyData (kAudioObjectSystemObject, &theAddress, 0, NULL, sizeof(CFRunLoopRef), &theRunLoop); if (osErr != noErr) { goto error; } } unixErr = initializeXRunListenerList(); if( 0 != unixErr ) { return UNIX_ERR(unixErr); } auhalHostApi = (PaMacAUHAL*)PaUtil_AllocateMemory( sizeof(PaMacAUHAL) ); if( !auhalHostApi ) { result = paInsufficientMemory; goto error; } auhalHostApi->allocations = PaUtil_CreateAllocationGroup(); if( !auhalHostApi->allocations ) { result = paInsufficientMemory; goto error; } auhalHostApi->devIds = NULL; auhalHostApi->devCount = 0; /* get the info we need about the devices */ result = gatherDeviceInfo( auhalHostApi ); if( result != paNoError ) goto error; *hostApi = &auhalHostApi->inheritedHostApiRep; (*hostApi)->info.structVersion = 1; (*hostApi)->info.type = paCoreAudio; (*hostApi)->info.name = "Core Audio"; (*hostApi)->info.defaultInputDevice = paNoDevice; (*hostApi)->info.defaultOutputDevice = paNoDevice; (*hostApi)->info.deviceCount = 0; if( auhalHostApi->devCount > 0 ) { (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( auhalHostApi->allocations, sizeof(PaDeviceInfo*) * auhalHostApi->devCount); if( !(*hostApi)->deviceInfos ) { result = paInsufficientMemory; goto error; } /* allocate all device info structs in a contiguous block */ deviceInfoArray = (PaDeviceInfo*)PaUtil_GroupAllocateMemory( auhalHostApi->allocations, sizeof(PaDeviceInfo) * auhalHostApi->devCount ); if( !deviceInfoArray ) { result = paInsufficientMemory; goto error; } for( i=0; i < auhalHostApi->devCount; ++i ) { int err; err = InitializeDeviceInfo( auhalHostApi, &deviceInfoArray[i], auhalHostApi->devIds[i], hostApiIndex ); if (err == paNoError) { /* copy some info and set the defaults */ (*hostApi)->deviceInfos[(*hostApi)->info.deviceCount] = &deviceInfoArray[i]; if (auhalHostApi->devIds[i] == auhalHostApi->defaultIn) (*hostApi)->info.defaultInputDevice = (*hostApi)->info.deviceCount; if (auhalHostApi->devIds[i] == auhalHostApi->defaultOut) (*hostApi)->info.defaultOutputDevice = (*hostApi)->info.deviceCount; (*hostApi)->info.deviceCount++; } else { /* there was an error. we need to shift the devices down, so we ignore this one */ int j; auhalHostApi->devCount--; for( j=i; jdevCount; ++j ) auhalHostApi->devIds[j] = auhalHostApi->devIds[j+1]; i--; } } } (*hostApi)->Terminate = Terminate; (*hostApi)->OpenStream = OpenStream; (*hostApi)->IsFormatSupported = IsFormatSupported; PaUtil_InitializeStreamInterface( &auhalHostApi->callbackStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, GetStreamCpuLoad, PaUtil_DummyRead, PaUtil_DummyWrite, PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable ); PaUtil_InitializeStreamInterface( &auhalHostApi->blockingStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, PaUtil_DummyGetCpuLoad, ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable ); return result; error: if( auhalHostApi ) { if( auhalHostApi->allocations ) { PaUtil_FreeAllAllocations( auhalHostApi->allocations ); PaUtil_DestroyAllocationGroup( auhalHostApi->allocations ); } PaUtil_FreeMemory( auhalHostApi ); } return result; } static void Terminate( struct PaUtilHostApiRepresentation *hostApi ) { int unixErr; PaMacAUHAL *auhalHostApi = (PaMacAUHAL*)hostApi; VVDBUG(("Terminate()\n")); unixErr = destroyXRunListenerList(); if( 0 != unixErr ) UNIX_ERR(unixErr); /* IMPLEMENT ME: - clean up any resources not handled by the allocation group TODO: Double check that everything is handled by alloc group */ if( auhalHostApi->allocations ) { PaUtil_FreeAllAllocations( auhalHostApi->allocations ); PaUtil_DestroyAllocationGroup( auhalHostApi->allocations ); } PaUtil_FreeMemory( auhalHostApi ); } static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ) { int inputChannelCount, outputChannelCount; PaSampleFormat inputSampleFormat, outputSampleFormat; VVDBUG(("IsFormatSupported(): in chan=%d, in fmt=%ld, out chan=%d, out fmt=%ld sampleRate=%g\n", inputParameters ? inputParameters->channelCount : -1, inputParameters ? inputParameters->sampleFormat : -1, outputParameters ? outputParameters->channelCount : -1, outputParameters ? outputParameters->sampleFormat : -1, (float) sampleRate )); /** These first checks are standard PA checks. We do some fancier checks later. */ if( inputParameters ) { inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; /* all standard sample formats are supported by the buffer adapter, this implementation doesn't support any custom sample formats */ if( inputSampleFormat & paCustomFormat ) return paSampleFormatNotSupported; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that input device can support inputChannelCount */ if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels ) return paInvalidChannelCount; } else { inputChannelCount = 0; } if( outputParameters ) { outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; /* all standard sample formats are supported by the buffer adapter, this implementation doesn't support any custom sample formats */ if( outputSampleFormat & paCustomFormat ) return paSampleFormatNotSupported; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that output device can support outputChannelCount */ if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels ) return paInvalidChannelCount; } else { outputChannelCount = 0; } /* FEEDBACK */ /* I think the only way to check a given format SR combo is */ /* to try opening it. This could be disruptive, is that Okay? */ /* The alternative is to just read off available sample rates, */ /* but this will not work %100 of the time (eg, a device that */ /* supports N output at one rate but only N/2 at a higher rate.)*/ /* The following code opens the device with the requested parameters to see if it works. */ { PaError err; PaStream *s; err = OpenStream( hostApi, &s, inputParameters, outputParameters, sampleRate, 1024, 0, (PaStreamCallback *)1, NULL ); if( err != paNoError && err != paInvalidSampleRate ) DBUG( ( "OpenStream @ %g returned: %d: %s\n", (float) sampleRate, err, Pa_GetErrorText( err ) ) ); if( err ) return err; err = CloseStream( s ); if( err ) { /* FEEDBACK: is this more serious? should we assert? */ DBUG( ( "WARNING: could not close Stream. %d: %s\n", err, Pa_GetErrorText( err ) ) ); } } return paFormatIsSupported; } /* ================================================================================= */ static void InitializeDeviceProperties( PaMacCoreDeviceProperties *deviceProperties ) { memset( deviceProperties, 0, sizeof(PaMacCoreDeviceProperties) ); deviceProperties->sampleRate = 1.0; // Better than random. Overwritten by actual values later on. deviceProperties->samplePeriod = 1.0 / deviceProperties->sampleRate; } static Float64 CalculateSoftwareLatencyFromProperties( PaMacCoreStream *stream, PaMacCoreDeviceProperties *deviceProperties ) { UInt32 latencyFrames = deviceProperties->bufferFrameSize + deviceProperties->deviceLatency + deviceProperties->safetyOffset; return latencyFrames * deviceProperties->samplePeriod; // same as dividing by sampleRate but faster } static Float64 CalculateHardwareLatencyFromProperties( PaMacCoreStream *stream, PaMacCoreDeviceProperties *deviceProperties ) { return deviceProperties->deviceLatency * deviceProperties->samplePeriod; // same as dividing by sampleRate but faster } /* Calculate values used to convert Apple timestamps into PA timestamps * from the device properties. The final results of this calculation * will be used in the audio callback function. */ static void UpdateTimeStampOffsets( PaMacCoreStream *stream ) { Float64 inputSoftwareLatency = 0.0; Float64 inputHardwareLatency = 0.0; Float64 outputSoftwareLatency = 0.0; Float64 outputHardwareLatency = 0.0; if( stream->inputUnit != NULL ) { inputSoftwareLatency = CalculateSoftwareLatencyFromProperties( stream, &stream->inputProperties ); inputHardwareLatency = CalculateHardwareLatencyFromProperties( stream, &stream->inputProperties ); } if( stream->outputUnit != NULL ) { outputSoftwareLatency = CalculateSoftwareLatencyFromProperties( stream, &stream->outputProperties ); outputHardwareLatency = CalculateHardwareLatencyFromProperties( stream, &stream->outputProperties ); } /* We only need a mutex around setting these variables as a group. */ pthread_mutex_lock( &stream->timingInformationMutex ); stream->timestampOffsetCombined = inputSoftwareLatency + outputSoftwareLatency; stream->timestampOffsetInputDevice = inputHardwareLatency; stream->timestampOffsetOutputDevice = outputHardwareLatency; pthread_mutex_unlock( &stream->timingInformationMutex ); } /* ================================================================================= */ /* can be used to update from nominal or actual sample rate */ static OSStatus UpdateSampleRateFromDeviceProperty( PaMacCoreStream *stream, AudioDeviceID deviceID, Boolean isInput, AudioDevicePropertyID sampleRatePropertyID ) { PaMacCoreDeviceProperties * deviceProperties = isInput ? &stream->inputProperties : &stream->outputProperties; Float64 sampleRate = 0.0; UInt32 propSize = sizeof(Float64); OSStatus osErr = AudioDeviceGetProperty( deviceID, 0, isInput, sampleRatePropertyID, &propSize, &sampleRate); if( (osErr == noErr) && (sampleRate > 1000.0) ) /* avoid divide by zero if there's an error */ { deviceProperties->sampleRate = sampleRate; deviceProperties->samplePeriod = 1.0 / sampleRate; } return osErr; } static OSStatus AudioDevicePropertyActualSampleRateListenerProc( AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void *inClientData ) { PaMacCoreStream *stream = (PaMacCoreStream*)inClientData; // Make sure the callback is operating on a stream that is still valid! assert( stream->streamRepresentation.magic == PA_STREAM_MAGIC ); OSStatus osErr = UpdateSampleRateFromDeviceProperty( stream, inDevice, isInput, kAudioDevicePropertyActualSampleRate ); if( osErr == noErr ) { UpdateTimeStampOffsets( stream ); } return osErr; } /* ================================================================================= */ static OSStatus QueryUInt32DeviceProperty( AudioDeviceID deviceID, Boolean isInput, AudioDevicePropertyID propertyID, UInt32 *outValue ) { UInt32 propertyValue = 0; UInt32 propertySize = sizeof(UInt32); OSStatus osErr = AudioDeviceGetProperty( deviceID, 0, isInput, propertyID, &propertySize, &propertyValue); if( osErr == noErr ) { *outValue = propertyValue; } return osErr; } static OSStatus AudioDevicePropertyGenericListenerProc( AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void *inClientData ) { OSStatus osErr = noErr; PaMacCoreStream *stream = (PaMacCoreStream*)inClientData; // Make sure the callback is operating on a stream that is still valid! assert( stream->streamRepresentation.magic == PA_STREAM_MAGIC ); PaMacCoreDeviceProperties *deviceProperties = isInput ? &stream->inputProperties : &stream->outputProperties; UInt32 *valuePtr = NULL; switch( inPropertyID ) { case kAudioDevicePropertySafetyOffset: valuePtr = &deviceProperties->safetyOffset; break; case kAudioDevicePropertyLatency: valuePtr = &deviceProperties->deviceLatency; break; case kAudioDevicePropertyBufferFrameSize: valuePtr = &deviceProperties->bufferFrameSize; break; } if( valuePtr != NULL ) { osErr = QueryUInt32DeviceProperty( inDevice, isInput, inPropertyID, valuePtr ); if( osErr == noErr ) { UpdateTimeStampOffsets( stream ); } } return osErr; } /* ================================================================================= */ /* * Setup listeners in case device properties change during the run. */ static OSStatus SetupDevicePropertyListeners( PaMacCoreStream *stream, AudioDeviceID deviceID, Boolean isInput ) { OSStatus osErr = noErr; PaMacCoreDeviceProperties *deviceProperties = isInput ? &stream->inputProperties : &stream->outputProperties; if( (osErr = QueryUInt32DeviceProperty( deviceID, isInput, kAudioDevicePropertyLatency, &deviceProperties->deviceLatency )) != noErr ) return osErr; if( (osErr = QueryUInt32DeviceProperty( deviceID, isInput, kAudioDevicePropertyBufferFrameSize, &deviceProperties->bufferFrameSize )) != noErr ) return osErr; if( (osErr = QueryUInt32DeviceProperty( deviceID, isInput, kAudioDevicePropertySafetyOffset, &deviceProperties->safetyOffset )) != noErr ) return osErr; AudioDeviceAddPropertyListener( deviceID, 0, isInput, kAudioDevicePropertyActualSampleRate, AudioDevicePropertyActualSampleRateListenerProc, stream ); AudioDeviceAddPropertyListener( deviceID, 0, isInput, kAudioStreamPropertyLatency, AudioDevicePropertyGenericListenerProc, stream ); AudioDeviceAddPropertyListener( deviceID, 0, isInput, kAudioDevicePropertyBufferFrameSize, AudioDevicePropertyGenericListenerProc, stream ); AudioDeviceAddPropertyListener( deviceID, 0, isInput, kAudioDevicePropertySafetyOffset, AudioDevicePropertyGenericListenerProc, stream ); return osErr; } static void CleanupDevicePropertyListeners( PaMacCoreStream *stream, AudioDeviceID deviceID, Boolean isInput ) { AudioDeviceRemovePropertyListener( deviceID, 0, isInput, kAudioDevicePropertyActualSampleRate, AudioDevicePropertyActualSampleRateListenerProc ); AudioDeviceRemovePropertyListener( deviceID, 0, isInput, kAudioDevicePropertyLatency, AudioDevicePropertyGenericListenerProc ); AudioDeviceRemovePropertyListener( deviceID, 0, isInput, kAudioDevicePropertyBufferFrameSize, AudioDevicePropertyGenericListenerProc ); AudioDeviceRemovePropertyListener( deviceID, 0, isInput, kAudioDevicePropertySafetyOffset, AudioDevicePropertyGenericListenerProc ); } /* ================================================================================= */ static PaError OpenAndSetupOneAudioUnit( const PaMacCoreStream *stream, const PaStreamParameters *inStreamParams, const PaStreamParameters *outStreamParams, const UInt32 requestedFramesPerBuffer, UInt32 *actualInputFramesPerBuffer, UInt32 *actualOutputFramesPerBuffer, const PaMacAUHAL *auhalHostApi, AudioUnit *audioUnit, AudioConverterRef *srConverter, AudioDeviceID *audioDevice, const double sampleRate, void *refCon ) { ComponentDescription desc; Component comp; /*An Apple TN suggests using CAStreamBasicDescription, but that is C++*/ AudioStreamBasicDescription desiredFormat; OSStatus result = noErr; PaError paResult = paNoError; int line = 0; UInt32 callbackKey; AURenderCallbackStruct rcbs; unsigned long macInputStreamFlags = paMacCorePlayNice; unsigned long macOutputStreamFlags = paMacCorePlayNice; SInt32 const *inChannelMap = NULL; SInt32 const *outChannelMap = NULL; unsigned long inChannelMapSize = 0; unsigned long outChannelMapSize = 0; VVDBUG(("OpenAndSetupOneAudioUnit(): in chan=%d, in fmt=%ld, out chan=%d, out fmt=%ld, requestedFramesPerBuffer=%ld\n", inStreamParams ? inStreamParams->channelCount : -1, inStreamParams ? inStreamParams->sampleFormat : -1, outStreamParams ? outStreamParams->channelCount : -1, outStreamParams ? outStreamParams->sampleFormat : -1, requestedFramesPerBuffer )); /* -- handle the degenerate case -- */ if( !inStreamParams && !outStreamParams ) { *audioUnit = NULL; *audioDevice = kAudioDeviceUnknown; return paNoError; } /* -- get the user's api specific info, if they set any -- */ if( inStreamParams && inStreamParams->hostApiSpecificStreamInfo ) { macInputStreamFlags= ((PaMacCoreStreamInfo*)inStreamParams->hostApiSpecificStreamInfo) ->flags; inChannelMap = ((PaMacCoreStreamInfo*)inStreamParams->hostApiSpecificStreamInfo) ->channelMap; inChannelMapSize = ((PaMacCoreStreamInfo*)inStreamParams->hostApiSpecificStreamInfo) ->channelMapSize; } if( outStreamParams && outStreamParams->hostApiSpecificStreamInfo ) { macOutputStreamFlags= ((PaMacCoreStreamInfo*)outStreamParams->hostApiSpecificStreamInfo) ->flags; outChannelMap = ((PaMacCoreStreamInfo*)outStreamParams->hostApiSpecificStreamInfo) ->channelMap; outChannelMapSize = ((PaMacCoreStreamInfo*)outStreamParams->hostApiSpecificStreamInfo) ->channelMapSize; } /* Override user's flags here, if desired for testing. */ /* * The HAL AU is a Mac OS style "component". * the first few steps deal with that. * Later steps work on a combination of Mac OS * components and the slightly lower level * HAL. */ /* -- describe the output type AudioUnit -- */ /* Note: for the default AudioUnit, we could use the * componentSubType value kAudioUnitSubType_DefaultOutput; * but I don't think that's relevant here. */ desc.componentType = kAudioUnitType_Output; desc.componentSubType = kAudioUnitSubType_HALOutput; desc.componentManufacturer = kAudioUnitManufacturer_Apple; desc.componentFlags = 0; desc.componentFlagsMask = 0; /* -- find the component -- */ comp = FindNextComponent( NULL, &desc ); if( !comp ) { DBUG( ( "AUHAL component not found." ) ); *audioUnit = NULL; *audioDevice = kAudioDeviceUnknown; return paUnanticipatedHostError; } /* -- open it -- */ result = OpenAComponent( comp, audioUnit ); if( result ) { DBUG( ( "Failed to open AUHAL component." ) ); *audioUnit = NULL; *audioDevice = kAudioDeviceUnknown; return ERR( result ); } /* -- prepare a little error handling logic / hackery -- */ #define ERR_WRAP(mac_err) do { result = mac_err ; line = __LINE__ ; if ( result != noErr ) goto error ; } while(0) /* -- if there is input, we have to explicitly enable input -- */ if( inStreamParams ) { UInt32 enableIO = 1; ERR_WRAP( AudioUnitSetProperty( *audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, INPUT_ELEMENT, &enableIO, sizeof(enableIO) ) ); } /* -- if there is no output, we must explicitly disable output -- */ if( !outStreamParams ) { UInt32 enableIO = 0; ERR_WRAP( AudioUnitSetProperty( *audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, OUTPUT_ELEMENT, &enableIO, sizeof(enableIO) ) ); } /* -- set the devices -- */ /* make sure input and output are the same device if we are doing input and output. */ if( inStreamParams && outStreamParams ) { assert( outStreamParams->device == inStreamParams->device ); } if( inStreamParams ) { *audioDevice = auhalHostApi->devIds[inStreamParams->device] ; ERR_WRAP( AudioUnitSetProperty( *audioUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, INPUT_ELEMENT, audioDevice, sizeof(AudioDeviceID) ) ); } if( outStreamParams && outStreamParams != inStreamParams ) { *audioDevice = auhalHostApi->devIds[outStreamParams->device] ; ERR_WRAP( AudioUnitSetProperty( *audioUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, OUTPUT_ELEMENT, audioDevice, sizeof(AudioDeviceID) ) ); } /* -- add listener for dropouts -- */ result = AudioDeviceAddPropertyListener( *audioDevice, 0, outStreamParams ? false : true, kAudioDeviceProcessorOverload, xrunCallback, addToXRunListenerList( (void *)stream ) ) ; if( result == kAudioHardwareIllegalOperationError ) { // -- already registered, we're good } else { // -- not already registered, just check for errors ERR_WRAP( result ); } /* -- listen for stream start and stop -- */ ERR_WRAP( AudioUnitAddPropertyListener( *audioUnit, kAudioOutputUnitProperty_IsRunning, startStopCallback, (void *)stream ) ); /* -- set format -- */ bzero( &desiredFormat, sizeof(desiredFormat) ); desiredFormat.mFormatID = kAudioFormatLinearPCM ; desiredFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked; desiredFormat.mFramesPerPacket = 1; desiredFormat.mBitsPerChannel = sizeof( float ) * 8; result = 0; /* set device format first, but only touch the device if the user asked */ if( inStreamParams ) { /*The callback never calls back if we don't set the FPB */ /*This seems wierd, because I would think setting anything on the device would be disruptive.*/ paResult = setBestFramesPerBuffer( *audioDevice, FALSE, requestedFramesPerBuffer, actualInputFramesPerBuffer ); if( paResult ) goto error; if( macInputStreamFlags & paMacCoreChangeDeviceParameters ) { bool requireExact; requireExact=macInputStreamFlags & paMacCoreFailIfConversionRequired; paResult = setBestSampleRateForDevice( *audioDevice, FALSE, requireExact, sampleRate ); if( paResult ) goto error; } if( actualInputFramesPerBuffer && actualOutputFramesPerBuffer ) *actualOutputFramesPerBuffer = *actualInputFramesPerBuffer ; } if( outStreamParams && !inStreamParams ) { /*The callback never calls back if we don't set the FPB */ /*This seems wierd, because I would think setting anything on the device would be disruptive.*/ paResult = setBestFramesPerBuffer( *audioDevice, TRUE, requestedFramesPerBuffer, actualOutputFramesPerBuffer ); if( paResult ) goto error; if( macOutputStreamFlags & paMacCoreChangeDeviceParameters ) { bool requireExact; requireExact=macOutputStreamFlags & paMacCoreFailIfConversionRequired; paResult = setBestSampleRateForDevice( *audioDevice, TRUE, requireExact, sampleRate ); if( paResult ) goto error; } } /* -- set the quality of the output converter -- */ if( outStreamParams ) { UInt32 value = kAudioConverterQuality_Max; switch( macOutputStreamFlags & 0x0700 ) { case 0x0100: /*paMacCore_ConversionQualityMin:*/ value=kRenderQuality_Min; break; case 0x0200: /*paMacCore_ConversionQualityLow:*/ value=kRenderQuality_Low; break; case 0x0300: /*paMacCore_ConversionQualityMedium:*/ value=kRenderQuality_Medium; break; case 0x0400: /*paMacCore_ConversionQualityHigh:*/ value=kRenderQuality_High; break; } ERR_WRAP( AudioUnitSetProperty( *audioUnit, kAudioUnitProperty_RenderQuality, kAudioUnitScope_Global, OUTPUT_ELEMENT, &value, sizeof(value) ) ); } /* now set the format on the Audio Units. */ if( outStreamParams ) { desiredFormat.mSampleRate =sampleRate; desiredFormat.mBytesPerPacket=sizeof(float)*outStreamParams->channelCount; desiredFormat.mBytesPerFrame =sizeof(float)*outStreamParams->channelCount; desiredFormat.mChannelsPerFrame = outStreamParams->channelCount; ERR_WRAP( AudioUnitSetProperty( *audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, OUTPUT_ELEMENT, &desiredFormat, sizeof(AudioStreamBasicDescription) ) ); } if( inStreamParams ) { AudioStreamBasicDescription sourceFormat; UInt32 size = sizeof( AudioStreamBasicDescription ); /* keep the sample rate of the device, or we confuse AUHAL */ ERR_WRAP( AudioUnitGetProperty( *audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, INPUT_ELEMENT, &sourceFormat, &size ) ); desiredFormat.mSampleRate = sourceFormat.mSampleRate; desiredFormat.mBytesPerPacket=sizeof(float)*inStreamParams->channelCount; desiredFormat.mBytesPerFrame =sizeof(float)*inStreamParams->channelCount; desiredFormat.mChannelsPerFrame = inStreamParams->channelCount; ERR_WRAP( AudioUnitSetProperty( *audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, INPUT_ELEMENT, &desiredFormat, sizeof(AudioStreamBasicDescription) ) ); } /* set the maximumFramesPerSlice */ /* not doing this causes real problems (eg. the callback might not be called). The idea of setting both this and the frames per buffer on the device is that we'll be most likely to actually get the frame size we requested in the callback with the minimum latency. */ if( outStreamParams ) { UInt32 size = sizeof( *actualOutputFramesPerBuffer ); ERR_WRAP( AudioUnitSetProperty( *audioUnit, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Input, OUTPUT_ELEMENT, actualOutputFramesPerBuffer, sizeof(*actualOutputFramesPerBuffer) ) ); ERR_WRAP( AudioUnitGetProperty( *audioUnit, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, OUTPUT_ELEMENT, actualOutputFramesPerBuffer, &size ) ); } if( inStreamParams ) { /*UInt32 size = sizeof( *actualInputFramesPerBuffer );*/ ERR_WRAP( AudioUnitSetProperty( *audioUnit, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Output, INPUT_ELEMENT, actualInputFramesPerBuffer, sizeof(*actualInputFramesPerBuffer) ) ); /* Don't know why this causes problems ERR_WRAP( AudioUnitGetProperty( *audioUnit, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, //Output, INPUT_ELEMENT, actualInputFramesPerBuffer, &size ) ); */ } /* -- if we have input, we may need to setup an SR converter -- */ /* even if we got the sample rate we asked for, we need to do the conversion in case another program changes the underlying SR. */ /* FIXME: I think we need to monitor stream and change the converter if the incoming format changes. */ if( inStreamParams ) { AudioStreamBasicDescription desiredFormat; AudioStreamBasicDescription sourceFormat; UInt32 sourceSize = sizeof( sourceFormat ); bzero( &desiredFormat, sizeof(desiredFormat) ); desiredFormat.mSampleRate = sampleRate; desiredFormat.mFormatID = kAudioFormatLinearPCM ; desiredFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked; desiredFormat.mFramesPerPacket = 1; desiredFormat.mBitsPerChannel = sizeof( float ) * 8; desiredFormat.mBytesPerPacket=sizeof(float)*inStreamParams->channelCount; desiredFormat.mBytesPerFrame =sizeof(float)*inStreamParams->channelCount; desiredFormat.mChannelsPerFrame = inStreamParams->channelCount; /* get the source format */ ERR_WRAP( AudioUnitGetProperty( *audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, INPUT_ELEMENT, &sourceFormat, &sourceSize ) ); if( desiredFormat.mSampleRate != sourceFormat.mSampleRate ) { UInt32 value = kAudioConverterQuality_Max; switch( macInputStreamFlags & 0x0700 ) { case 0x0100: /*paMacCore_ConversionQualityMin:*/ value=kAudioConverterQuality_Min; break; case 0x0200: /*paMacCore_ConversionQualityLow:*/ value=kAudioConverterQuality_Low; break; case 0x0300: /*paMacCore_ConversionQualityMedium:*/ value=kAudioConverterQuality_Medium; break; case 0x0400: /*paMacCore_ConversionQualityHigh:*/ value=kAudioConverterQuality_High; break; } VDBUG(( "Creating sample rate converter for input" " to convert from %g to %g\n", (float)sourceFormat.mSampleRate, (float)desiredFormat.mSampleRate ) ); /* create our converter */ ERR_WRAP( AudioConverterNew( &sourceFormat, &desiredFormat, srConverter ) ); /* Set quality */ ERR_WRAP( AudioConverterSetProperty( *srConverter, kAudioConverterSampleRateConverterQuality, sizeof( value ), &value ) ); } } /* -- set IOProc (callback) -- */ callbackKey = outStreamParams ? kAudioUnitProperty_SetRenderCallback : kAudioOutputUnitProperty_SetInputCallback ; rcbs.inputProc = AudioIOProc; rcbs.inputProcRefCon = refCon; ERR_WRAP( AudioUnitSetProperty( *audioUnit, callbackKey, kAudioUnitScope_Output, outStreamParams ? OUTPUT_ELEMENT : INPUT_ELEMENT, &rcbs, sizeof(rcbs)) ); if( inStreamParams && outStreamParams && *srConverter ) ERR_WRAP( AudioUnitSetProperty( *audioUnit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Output, INPUT_ELEMENT, &rcbs, sizeof(rcbs)) ); /* channel mapping. */ if(inChannelMap) { UInt32 mapSize = inChannelMapSize *sizeof(SInt32); //for each channel of desired input, map the channel from //the device's output channel. ERR_WRAP( AudioUnitSetProperty(*audioUnit, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Output, INPUT_ELEMENT, inChannelMap, mapSize)); } if(outChannelMap) { UInt32 mapSize = outChannelMapSize *sizeof(SInt32); //for each channel of desired output, map the channel from //the device's output channel. ERR_WRAP(AudioUnitSetProperty(*audioUnit, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Output, OUTPUT_ELEMENT, outChannelMap, mapSize)); } /* initialize the audio unit */ ERR_WRAP( AudioUnitInitialize(*audioUnit) ); if( inStreamParams && outStreamParams ) { VDBUG( ("Opened device %ld for input and output.\n", *audioDevice ) ); } else if( inStreamParams ) { VDBUG( ("Opened device %ld for input.\n", *audioDevice ) ); } else if( outStreamParams ) { VDBUG( ("Opened device %ld for output.\n", *audioDevice ) ); } return paNoError; #undef ERR_WRAP error: CloseComponent( *audioUnit ); *audioUnit = NULL; if( result ) return PaMacCore_SetError( result, line, 1 ); return paResult; } /* =================================================================================================== */ static UInt32 CalculateOptimalBufferSize( PaMacAUHAL *auhalHostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, UInt32 fixedInputLatency, UInt32 fixedOutputLatency, double sampleRate, UInt32 requestedFramesPerBuffer ) { UInt32 resultBufferSizeFrames = 0; // Use maximum of suggested input and output latencies. if( inputParameters ) { UInt32 suggestedLatencyFrames = inputParameters->suggestedLatency * sampleRate; // Calculate a buffer size assuming we are double buffered. SInt32 variableLatencyFrames = suggestedLatencyFrames - fixedInputLatency; // Prevent negative latency. variableLatencyFrames = MAX( variableLatencyFrames, 0 ); resultBufferSizeFrames = MAX( resultBufferSizeFrames, (UInt32) variableLatencyFrames ); } if( outputParameters ) { UInt32 suggestedLatencyFrames = outputParameters->suggestedLatency * sampleRate; SInt32 variableLatencyFrames = suggestedLatencyFrames - fixedOutputLatency; variableLatencyFrames = MAX( variableLatencyFrames, 0 ); resultBufferSizeFrames = MAX( resultBufferSizeFrames, (UInt32) variableLatencyFrames ); } // can't have zero frames. code to round up to next user buffer requires non-zero resultBufferSizeFrames = MAX( resultBufferSizeFrames, 1 ); if( requestedFramesPerBuffer != paFramesPerBufferUnspecified ) { // make host buffer the next highest integer multiple of user frames per buffer UInt32 n = (resultBufferSizeFrames + requestedFramesPerBuffer - 1) / requestedFramesPerBuffer; resultBufferSizeFrames = n * requestedFramesPerBuffer; // FIXME: really we should be searching for a multiple of requestedFramesPerBuffer // that is >= suggested latency and also fits within device buffer min/max }else{ VDBUG( ("Block Size unspecified. Based on Latency, the user wants a Block Size near: %ld.\n", resultBufferSizeFrames ) ); } // Clip to the capabilities of the device. if( inputParameters ) { ClipToDeviceBufferSize( auhalHostApi->devIds[inputParameters->device], true, // In the old code isInput was false! resultBufferSizeFrames, &resultBufferSizeFrames ); } if( outputParameters ) { ClipToDeviceBufferSize( auhalHostApi->devIds[outputParameters->device], false, resultBufferSizeFrames, &resultBufferSizeFrames ); } VDBUG(("After querying hardware, setting block size to %ld.\n", resultBufferSizeFrames)); return resultBufferSizeFrames; } /* =================================================================================================== */ /* see pa_hostapi.h for a list of validity guarantees made about OpenStream parameters */ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long requestedFramesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ) { PaError result = paNoError; PaMacAUHAL *auhalHostApi = (PaMacAUHAL*)hostApi; PaMacCoreStream *stream = 0; int inputChannelCount, outputChannelCount; PaSampleFormat inputSampleFormat, outputSampleFormat; PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat; UInt32 fixedInputLatency = 0; UInt32 fixedOutputLatency = 0; // Accumulate contributions to latency in these variables. UInt32 inputLatencyFrames = 0; UInt32 outputLatencyFrames = 0; UInt32 suggestedLatencyFramesPerBuffer = requestedFramesPerBuffer; VVDBUG(("OpenStream(): in chan=%d, in fmt=%ld, out chan=%d, out fmt=%ld SR=%g, FPB=%ld\n", inputParameters ? inputParameters->channelCount : -1, inputParameters ? inputParameters->sampleFormat : -1, outputParameters ? outputParameters->channelCount : -1, outputParameters ? outputParameters->sampleFormat : -1, (float) sampleRate, requestedFramesPerBuffer )); VDBUG( ("Opening Stream.\n") ); /* These first few bits of code are from paSkeleton with few modifications. */ if( inputParameters ) { inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; /* @todo Blocking read/write on Mac is not yet supported. */ if( !streamCallback && inputSampleFormat & paNonInterleaved ) { return paSampleFormatNotSupported; } /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that input device can support inputChannelCount */ if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels ) return paInvalidChannelCount; /* Host supports interleaved float32 */ hostInputSampleFormat = paFloat32; } else { inputChannelCount = 0; inputSampleFormat = hostInputSampleFormat = paFloat32; /* Surpress 'uninitialised var' warnings. */ } if( outputParameters ) { outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; /* @todo Blocking read/write on Mac is not yet supported. */ if( !streamCallback && outputSampleFormat & paNonInterleaved ) { return paSampleFormatNotSupported; } /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that output device can support inputChannelCount */ if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels ) return paInvalidChannelCount; /* Host supports interleaved float32 */ hostOutputSampleFormat = paFloat32; } else { outputChannelCount = 0; outputSampleFormat = hostOutputSampleFormat = paFloat32; /* Surpress 'uninitialized var' warnings. */ } /* validate platform specific flags */ if( (streamFlags & paPlatformSpecificFlags) != 0 ) return paInvalidFlag; /* unexpected platform specific flag */ stream = (PaMacCoreStream*)PaUtil_AllocateMemory( sizeof(PaMacCoreStream) ); if( !stream ) { result = paInsufficientMemory; goto error; } /* If we fail after this point, we my be left in a bad state, with some data structures setup and others not. So, first thing we do is initialize everything so that if we fail, we know what hasn't been touched. */ bzero( stream, sizeof( PaMacCoreStream ) ); /* stream->blio.inputRingBuffer.buffer = NULL; stream->blio.outputRingBuffer.buffer = NULL; stream->blio.inputSampleFormat = inputParameters?inputParameters->sampleFormat:0; stream->blio.inputSampleSize = computeSampleSizeFromFormat(stream->blio.inputSampleFormat); stream->blio.outputSampleFormat=outputParameters?outputParameters->sampleFormat:0; stream->blio.outputSampleSize = computeSampleSizeFromFormat(stream->blio.outputSampleFormat); */ /* assert( streamCallback ) ; */ /* only callback mode is implemented */ if( streamCallback ) { PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &auhalHostApi->callbackStreamInterface, streamCallback, userData ); } else { PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &auhalHostApi->blockingStreamInterface, BlioCallback, &stream->blio ); } PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate ); if( inputParameters ) { CalculateFixedDeviceLatency( auhalHostApi->devIds[inputParameters->device], true, &fixedInputLatency ); inputLatencyFrames += fixedInputLatency; } if( outputParameters ) { CalculateFixedDeviceLatency( auhalHostApi->devIds[outputParameters->device], false, &fixedOutputLatency ); outputLatencyFrames += fixedOutputLatency; } suggestedLatencyFramesPerBuffer = CalculateOptimalBufferSize( auhalHostApi, inputParameters, outputParameters, fixedInputLatency, fixedOutputLatency, sampleRate, requestedFramesPerBuffer ); if( requestedFramesPerBuffer == paFramesPerBufferUnspecified ) { requestedFramesPerBuffer = suggestedLatencyFramesPerBuffer; } /* -- Now we actually open and setup streams. -- */ if( inputParameters && outputParameters && outputParameters->device == inputParameters->device ) { /* full duplex. One device. */ UInt32 inputFramesPerBuffer = (UInt32) stream->inputFramesPerBuffer; UInt32 outputFramesPerBuffer = (UInt32) stream->outputFramesPerBuffer; result = OpenAndSetupOneAudioUnit( stream, inputParameters, outputParameters, suggestedLatencyFramesPerBuffer, &inputFramesPerBuffer, &outputFramesPerBuffer, auhalHostApi, &(stream->inputUnit), &(stream->inputSRConverter), &(stream->inputDevice), sampleRate, stream ); stream->inputFramesPerBuffer = inputFramesPerBuffer; stream->outputFramesPerBuffer = outputFramesPerBuffer; stream->outputUnit = stream->inputUnit; stream->outputDevice = stream->inputDevice; if( result != paNoError ) goto error; } else { /* full duplex, different devices OR simplex */ UInt32 outputFramesPerBuffer = (UInt32) stream->outputFramesPerBuffer; UInt32 inputFramesPerBuffer = (UInt32) stream->inputFramesPerBuffer; result = OpenAndSetupOneAudioUnit( stream, NULL, outputParameters, suggestedLatencyFramesPerBuffer, NULL, &outputFramesPerBuffer, auhalHostApi, &(stream->outputUnit), NULL, &(stream->outputDevice), sampleRate, stream ); if( result != paNoError ) goto error; result = OpenAndSetupOneAudioUnit( stream, inputParameters, NULL, suggestedLatencyFramesPerBuffer, &inputFramesPerBuffer, NULL, auhalHostApi, &(stream->inputUnit), &(stream->inputSRConverter), &(stream->inputDevice), sampleRate, stream ); if( result != paNoError ) goto error; stream->inputFramesPerBuffer = inputFramesPerBuffer; stream->outputFramesPerBuffer = outputFramesPerBuffer; } inputLatencyFrames += stream->inputFramesPerBuffer; outputLatencyFrames += stream->outputFramesPerBuffer; if( stream->inputUnit ) { const size_t szfl = sizeof(float); /* setup the AudioBufferList used for input */ bzero( &stream->inputAudioBufferList, sizeof( AudioBufferList ) ); stream->inputAudioBufferList.mNumberBuffers = 1; stream->inputAudioBufferList.mBuffers[0].mNumberChannels = inputChannelCount; stream->inputAudioBufferList.mBuffers[0].mDataByteSize = stream->inputFramesPerBuffer*inputChannelCount*szfl; stream->inputAudioBufferList.mBuffers[0].mData = (float *) calloc( stream->inputFramesPerBuffer*inputChannelCount, szfl ); if( !stream->inputAudioBufferList.mBuffers[0].mData ) { result = paInsufficientMemory; goto error; } /* * If input and output devs are different or we are doing SR conversion, * we also need a * ring buffer to store inpt data while waiting for output * data. */ if( (stream->outputUnit && (stream->inputUnit != stream->outputUnit)) || stream->inputSRConverter ) { /* May want the ringSize ot initial position in ring buffer to depend somewhat on sample rate change */ void *data; long ringSize; ringSize = computeRingBufferSize( inputParameters, outputParameters, stream->inputFramesPerBuffer, stream->outputFramesPerBuffer, sampleRate ); /*ringSize <<= 4; *//*16x bigger, for testing */ /*now, we need to allocate memory for the ring buffer*/ data = calloc( ringSize, szfl*inputParameters->channelCount ); if( !data ) { result = paInsufficientMemory; goto error; } /* now we can initialize the ring buffer */ PaUtil_InitializeRingBuffer( &stream->inputRingBuffer, szfl*inputParameters->channelCount, ringSize, data ) ; /* advance the read point a little, so we are reading from the middle of the buffer */ if( stream->outputUnit ) PaUtil_AdvanceRingBufferWriteIndex( &stream->inputRingBuffer, ringSize / RING_BUFFER_ADVANCE_DENOMINATOR ); // Just adds to input latency between input device and PA full duplex callback. inputLatencyFrames += ringSize; } } /* -- initialize Blio Buffer Processors -- */ if( !streamCallback ) { long ringSize; ringSize = computeRingBufferSize( inputParameters, outputParameters, stream->inputFramesPerBuffer, stream->outputFramesPerBuffer, sampleRate ); result = initializeBlioRingBuffers( &stream->blio, inputParameters?inputParameters->sampleFormat:0 , outputParameters?outputParameters->sampleFormat:0 , MAX(stream->inputFramesPerBuffer,stream->outputFramesPerBuffer), ringSize, inputParameters?inputChannelCount:0 , outputParameters?outputChannelCount:0 ) ; if( result != paNoError ) goto error; inputLatencyFrames += ringSize; outputLatencyFrames += ringSize; } /* -- initialize Buffer Processor -- */ { unsigned long maxHostFrames = stream->inputFramesPerBuffer; if( stream->outputFramesPerBuffer > maxHostFrames ) maxHostFrames = stream->outputFramesPerBuffer; result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor, inputChannelCount, inputSampleFormat, hostInputSampleFormat, outputChannelCount, outputSampleFormat, hostOutputSampleFormat, sampleRate, streamFlags, requestedFramesPerBuffer, /* If sample rate conversion takes place, the buffer size will not be known. */ maxHostFrames, stream->inputSRConverter ? paUtilUnknownHostBufferSize : paUtilBoundedHostBufferSize, streamCallback ? streamCallback : BlioCallback, streamCallback ? userData : &stream->blio ); if( result != paNoError ) goto error; } stream->bufferProcessorIsInitialized = TRUE; // Calculate actual latency from the sum of individual latencies. if( inputParameters ) { inputLatencyFrames += PaUtil_GetBufferProcessorInputLatencyFrames(&stream->bufferProcessor); stream->streamRepresentation.streamInfo.inputLatency = inputLatencyFrames / sampleRate; } else { stream->streamRepresentation.streamInfo.inputLatency = 0.0; } if( outputParameters ) { outputLatencyFrames += PaUtil_GetBufferProcessorOutputLatencyFrames(&stream->bufferProcessor); stream->streamRepresentation.streamInfo.outputLatency = outputLatencyFrames / sampleRate; } else { stream->streamRepresentation.streamInfo.outputLatency = 0.0; } stream->streamRepresentation.streamInfo.sampleRate = sampleRate; stream->sampleRate = sampleRate; stream->userInChan = inputChannelCount; stream->userOutChan = outputChannelCount; // Setup property listeners for timestamp and latency calculations. pthread_mutex_init( &stream->timingInformationMutex, NULL ); stream->timingInformationMutexIsInitialized = 1; InitializeDeviceProperties( &stream->inputProperties ); // zeros the struct. doesn't actually init it to useful values InitializeDeviceProperties( &stream->outputProperties ); // zeros the struct. doesn't actually init it to useful values if( stream->outputUnit ) { Boolean isInput = FALSE; // Start with the current values for the device properties. // Init with nominal sample rate. Use actual sample rate where available result = ERR( UpdateSampleRateFromDeviceProperty( stream, stream->outputDevice, isInput, kAudioDevicePropertyNominalSampleRate ) ); if( result ) goto error; /* fail if we can't even get a nominal device sample rate */ UpdateSampleRateFromDeviceProperty( stream, stream->outputDevice, isInput, kAudioDevicePropertyActualSampleRate ); SetupDevicePropertyListeners( stream, stream->outputDevice, isInput ); } if( stream->inputUnit ) { Boolean isInput = TRUE; // as above result = ERR( UpdateSampleRateFromDeviceProperty( stream, stream->inputDevice, isInput, kAudioDevicePropertyNominalSampleRate ) ); if( result ) goto error; UpdateSampleRateFromDeviceProperty( stream, stream->inputDevice, isInput, kAudioDevicePropertyActualSampleRate ); SetupDevicePropertyListeners( stream, stream->inputDevice, isInput ); } UpdateTimeStampOffsets( stream ); // Setup timestamp copies to be used by audio callback. stream->timestampOffsetCombined_ioProcCopy = stream->timestampOffsetCombined; stream->timestampOffsetInputDevice_ioProcCopy = stream->timestampOffsetInputDevice; stream->timestampOffsetOutputDevice_ioProcCopy = stream->timestampOffsetOutputDevice; stream->state = STOPPED; stream->xrunFlags = 0; *s = (PaStream*)stream; return result; error: CloseStream( stream ); return result; } #define HOST_TIME_TO_PA_TIME( x ) ( AudioConvertHostTimeToNanos( (x) ) * 1.0E-09) /* convert to nanoseconds and then to seconds */ PaTime GetStreamTime( PaStream *s ) { return HOST_TIME_TO_PA_TIME( AudioGetCurrentHostTime() ); } #define RING_BUFFER_EMPTY (1000) static OSStatus ringBufferIOProc( AudioConverterRef inAudioConverter, UInt32*ioDataSize, void** outData, void*inUserData ) { void *dummyData; ring_buffer_size_t dummySize; PaUtilRingBuffer *rb = (PaUtilRingBuffer *) inUserData; VVDBUG(("ringBufferIOProc()\n")); if( PaUtil_GetRingBufferReadAvailable( rb ) == 0 ) { *outData = NULL; *ioDataSize = 0; return RING_BUFFER_EMPTY; } assert(sizeof(UInt32) == sizeof(ring_buffer_size_t)); assert( ( (*ioDataSize) / rb->elementSizeBytes ) * rb->elementSizeBytes == (*ioDataSize) ) ; (*ioDataSize) /= rb->elementSizeBytes ; PaUtil_GetRingBufferReadRegions( rb, *ioDataSize, outData, (ring_buffer_size_t *)ioDataSize, &dummyData, &dummySize ); assert( *ioDataSize ); PaUtil_AdvanceRingBufferReadIndex( rb, *ioDataSize ); (*ioDataSize) *= rb->elementSizeBytes ; return noErr; } /* * Called by the AudioUnit API to process audio from the sound card. * This is where the magic happens. */ /* FEEDBACK: there is a lot of redundant code here because of how all the cases differ. This makes it hard to maintain, so if there are suggestinos for cleaning it up, I'm all ears. */ static OSStatus AudioIOProc( void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData ) { unsigned long framesProcessed = 0; PaStreamCallbackTimeInfo timeInfo = {0,0,0}; PaMacCoreStream *stream = (PaMacCoreStream*)inRefCon; const bool isRender = inBusNumber == OUTPUT_ELEMENT; int callbackResult = paContinue ; double hostTimeStampInPaTime = HOST_TIME_TO_PA_TIME(inTimeStamp->mHostTime); VVDBUG(("AudioIOProc()\n")); PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer ); /* -----------------------------------------------------------------*\ This output may be useful for debugging, But printing durring the callback is a bad enough idea that this is not enabled by enableing the usual debugging calls. \* -----------------------------------------------------------------*/ /* static int renderCount = 0; static int inputCount = 0; printf( "------------------- starting reder/input\n" ); if( isRender ) printf("Render callback (%d):\t", ++renderCount); else printf("Input callback (%d):\t", ++inputCount); printf( "Call totals: %d (input), %d (render)\n", inputCount, renderCount ); printf( "--- inBusNumber: %lu\n", inBusNumber ); printf( "--- inNumberFrames: %lu\n", inNumberFrames ); printf( "--- %x ioData\n", (unsigned) ioData ); if( ioData ) { int i=0; printf( "--- ioData.mNumBuffers %lu: \n", ioData->mNumberBuffers ); for( i=0; imNumberBuffers; ++i ) printf( "--- ioData buffer %d size: %lu.\n", i, ioData->mBuffers[i].mDataByteSize ); } ----------------------------------------------------------------- */ /* compute PaStreamCallbackTimeInfo */ if( pthread_mutex_trylock( &stream->timingInformationMutex ) == 0 ){ /* snapshot the ioproc copy of timing information */ stream->timestampOffsetCombined_ioProcCopy = stream->timestampOffsetCombined; stream->timestampOffsetInputDevice_ioProcCopy = stream->timestampOffsetInputDevice; stream->timestampOffsetOutputDevice_ioProcCopy = stream->timestampOffsetOutputDevice; pthread_mutex_unlock( &stream->timingInformationMutex ); } /* For timeInfo.currentTime we could calculate current time backwards from the HAL audio output time to give a more accurate impression of the current timeslice but it doesn't seem worth it at the moment since other PA host APIs don't do any better. */ timeInfo.currentTime = HOST_TIME_TO_PA_TIME( AudioGetCurrentHostTime() ); /* For an input HAL AU, inTimeStamp is the time the samples are received from the hardware, for an output HAL AU inTimeStamp is the time the samples are sent to the hardware. PA expresses timestamps in terms of when the samples enter the ADC or leave the DAC so we add or subtract kAudioDevicePropertyLatency below. */ /* FIXME: not sure what to do below if the host timestamps aren't valid (kAudioTimeStampHostTimeValid isn't set) Could ask on CA mailing list if it is possible for it not to be set. If so, could probably grab a now timestamp at the top and compute from there (modulo scheduling jitter) or ask on mailing list for other options. */ if( isRender ) { if( stream->inputUnit ) /* full duplex */ { if( stream->inputUnit == stream->outputUnit ) /* full duplex AUHAL IOProc */ { // Ross and Phil agreed that the following calculation is correct based on an email from Jeff Moore: // http://osdir.com/ml/coreaudio-api/2009-07/msg00140.html // Basically the difference between the Apple output timestamp and the PA timestamp is kAudioDevicePropertyLatency. timeInfo.inputBufferAdcTime = hostTimeStampInPaTime - (stream->timestampOffsetCombined_ioProcCopy + stream->timestampOffsetInputDevice_ioProcCopy); timeInfo.outputBufferDacTime = hostTimeStampInPaTime + stream->timestampOffsetOutputDevice_ioProcCopy; } else /* full duplex with ring-buffer from a separate input AUHAL ioproc */ { /* FIXME: take the ring buffer latency into account */ timeInfo.inputBufferAdcTime = hostTimeStampInPaTime - (stream->timestampOffsetCombined_ioProcCopy + stream->timestampOffsetInputDevice_ioProcCopy); timeInfo.outputBufferDacTime = hostTimeStampInPaTime + stream->timestampOffsetOutputDevice_ioProcCopy; } } else /* output only */ { timeInfo.inputBufferAdcTime = 0; timeInfo.outputBufferDacTime = hostTimeStampInPaTime + stream->timestampOffsetOutputDevice_ioProcCopy; } } else /* input only */ { timeInfo.inputBufferAdcTime = hostTimeStampInPaTime - stream->timestampOffsetInputDevice_ioProcCopy; timeInfo.outputBufferDacTime = 0; } //printf( "---%g, %g, %g\n", timeInfo.inputBufferAdcTime, timeInfo.currentTime, timeInfo.outputBufferDacTime ); if( isRender && stream->inputUnit == stream->outputUnit && !stream->inputSRConverter ) { /* --------- Full Duplex, One Device, no SR Conversion ------- * * This is the lowest latency case, and also the simplest. * Input data and output data are available at the same time. * we do not use the input SR converter or the input ring buffer. * */ OSStatus err = 0; unsigned long frames; long bytesPerFrame = sizeof( float ) * ioData->mBuffers[0].mNumberChannels; /* -- start processing -- */ PaUtil_BeginBufferProcessing( &(stream->bufferProcessor), &timeInfo, stream->xrunFlags ); stream->xrunFlags = 0; //FIXME: this flag also gets set outside by a callback, which calls the xrunCallback function. It should be in the same thread as the main audio callback, but the apple docs just use the word "usually" so it may be possible to loose an xrun notification, if that callback happens here. /* -- compute frames. do some checks -- */ assert( ioData->mNumberBuffers == 1 ); assert( ioData->mBuffers[0].mNumberChannels == stream->userOutChan ); frames = ioData->mBuffers[0].mDataByteSize / bytesPerFrame; /* -- copy and process input data -- */ err= AudioUnitRender(stream->inputUnit, ioActionFlags, inTimeStamp, INPUT_ELEMENT, inNumberFrames, &stream->inputAudioBufferList ); /* FEEDBACK: I'm not sure what to do when this call fails. There's nothing in the PA API to * do about failures in the callback system. */ assert( !err ); PaUtil_SetInputFrameCount( &(stream->bufferProcessor), frames ); PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor), 0, stream->inputAudioBufferList.mBuffers[0].mData, stream->inputAudioBufferList.mBuffers[0].mNumberChannels); /* -- Copy and process output data -- */ PaUtil_SetOutputFrameCount( &(stream->bufferProcessor), frames ); PaUtil_SetInterleavedOutputChannels( &(stream->bufferProcessor), 0, ioData->mBuffers[0].mData, ioData->mBuffers[0].mNumberChannels); /* -- complete processing -- */ framesProcessed = PaUtil_EndBufferProcessing( &(stream->bufferProcessor), &callbackResult ); } else if( isRender ) { /* -------- Output Side of Full Duplex (Separate Devices or SR Conversion) * -- OR Simplex Output * * This case handles output data as in the full duplex case, * and, if there is input data, reads it off the ring buffer * and into the PA buffer processor. If sample rate conversion * is required on input, that is done here as well. */ unsigned long frames; long bytesPerFrame = sizeof( float ) * ioData->mBuffers[0].mNumberChannels; /* Sometimes, when stopping a duplex stream we get erroneous xrun flags, so if this is our last run, clear the flags. */ int xrunFlags = stream->xrunFlags; /* if( xrunFlags & paInputUnderflow ) printf( "input underflow.\n" ); if( xrunFlags & paInputOverflow ) printf( "input overflow.\n" ); */ if( stream->state == STOPPING || stream->state == CALLBACK_STOPPED ) xrunFlags = 0; /* -- start processing -- */ PaUtil_BeginBufferProcessing( &(stream->bufferProcessor), &timeInfo, xrunFlags ); stream->xrunFlags = 0; /* FEEDBACK: we only send flags to Buf Proc once */ /* -- Copy and process output data -- */ assert( ioData->mNumberBuffers == 1 ); frames = ioData->mBuffers[0].mDataByteSize / bytesPerFrame; assert( ioData->mBuffers[0].mNumberChannels == stream->userOutChan ); PaUtil_SetOutputFrameCount( &(stream->bufferProcessor), frames ); PaUtil_SetInterleavedOutputChannels( &(stream->bufferProcessor), 0, ioData->mBuffers[0].mData, ioData->mBuffers[0].mNumberChannels); /* -- copy and process input data, and complete processing -- */ if( stream->inputUnit ) { const int flsz = sizeof( float ); /* Here, we read the data out of the ring buffer, through the audio converter. */ int inChan = stream->inputAudioBufferList.mBuffers[0].mNumberChannels; long bytesPerFrame = flsz * inChan; if( stream->inputSRConverter ) { OSStatus err; UInt32 size; float data[ inChan * frames ]; size = sizeof( data ); err = AudioConverterFillBuffer( stream->inputSRConverter, ringBufferIOProc, &stream->inputRingBuffer, &size, (void *)&data ); if( err == RING_BUFFER_EMPTY ) { /*the ring buffer callback underflowed */ err = 0; bzero( ((char *)data) + size, sizeof(data)-size ); /* The ring buffer can underflow normally when the stream is stopping. * So only report an error if the stream is active. */ if( stream->state == ACTIVE ) { stream->xrunFlags |= paInputUnderflow; } } ERR( err ); assert( !err ); PaUtil_SetInputFrameCount( &(stream->bufferProcessor), frames ); PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor), 0, data, inChan ); framesProcessed = PaUtil_EndBufferProcessing( &(stream->bufferProcessor), &callbackResult ); } else { /* Without the AudioConverter is actually a bit more complex because we have to do a little buffer processing that the AudioConverter would otherwise handle for us. */ void *data1, *data2; ring_buffer_size_t size1, size2; ring_buffer_size_t framesReadable = PaUtil_GetRingBufferReadRegions( &stream->inputRingBuffer, frames, &data1, &size1, &data2, &size2 ); if( size1 == frames ) { /* simplest case: all in first buffer */ PaUtil_SetInputFrameCount( &(stream->bufferProcessor), frames ); PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor), 0, data1, inChan ); framesProcessed = PaUtil_EndBufferProcessing( &(stream->bufferProcessor), &callbackResult ); PaUtil_AdvanceRingBufferReadIndex(&stream->inputRingBuffer, size1 ); } else if( framesReadable < frames ) { long sizeBytes1 = size1 * bytesPerFrame; long sizeBytes2 = size2 * bytesPerFrame; /*we underflowed. take what data we can, zero the rest.*/ unsigned char data[ frames * bytesPerFrame ]; if( size1 > 0 ) { memcpy( data, data1, sizeBytes1 ); } if( size2 > 0 ) { memcpy( data+sizeBytes1, data2, sizeBytes2 ); } bzero( data+sizeBytes1+sizeBytes2, (frames*bytesPerFrame) - sizeBytes1 - sizeBytes2 ); PaUtil_SetInputFrameCount( &(stream->bufferProcessor), frames ); PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor), 0, data, inChan ); framesProcessed = PaUtil_EndBufferProcessing( &(stream->bufferProcessor), &callbackResult ); PaUtil_AdvanceRingBufferReadIndex( &stream->inputRingBuffer, framesReadable ); /* flag underflow */ stream->xrunFlags |= paInputUnderflow; } else { /*we got all the data, but split between buffers*/ PaUtil_SetInputFrameCount( &(stream->bufferProcessor), size1 ); PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor), 0, data1, inChan ); PaUtil_Set2ndInputFrameCount( &(stream->bufferProcessor), size2 ); PaUtil_Set2ndInterleavedInputChannels( &(stream->bufferProcessor), 0, data2, inChan ); framesProcessed = PaUtil_EndBufferProcessing( &(stream->bufferProcessor), &callbackResult ); PaUtil_AdvanceRingBufferReadIndex(&stream->inputRingBuffer, framesReadable ); } } } else { framesProcessed = PaUtil_EndBufferProcessing( &(stream->bufferProcessor), &callbackResult ); } } else { /* ------------------ Input * * First, we read off the audio data and put it in the ring buffer. * if this is an input-only stream, we need to process it more, * otherwise, we let the output case deal with it. */ OSStatus err = 0; int chan = stream->inputAudioBufferList.mBuffers[0].mNumberChannels ; /* FIXME: looping here may not actually be necessary, but it was something I tried in testing. */ do { err= AudioUnitRender(stream->inputUnit, ioActionFlags, inTimeStamp, INPUT_ELEMENT, inNumberFrames, &stream->inputAudioBufferList ); if( err == -10874 ) inNumberFrames /= 2; } while( err == -10874 && inNumberFrames > 1 ); /* FEEDBACK: I'm not sure what to do when this call fails */ ERR( err ); assert( !err ); if( stream->inputSRConverter || stream->outputUnit ) { /* If this is duplex or we use a converter, put the data into the ring buffer. */ ring_buffer_size_t framesWritten = PaUtil_WriteRingBuffer( &stream->inputRingBuffer, stream->inputAudioBufferList.mBuffers[0].mData, inNumberFrames ); if( framesWritten != inNumberFrames ) { stream->xrunFlags |= paInputOverflow ; } } else { /* for simplex input w/o SR conversion, just pop the data into the buffer processor.*/ PaUtil_BeginBufferProcessing( &(stream->bufferProcessor), &timeInfo, stream->xrunFlags ); stream->xrunFlags = 0; PaUtil_SetInputFrameCount( &(stream->bufferProcessor), inNumberFrames); PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor), 0, stream->inputAudioBufferList.mBuffers[0].mData, chan ); framesProcessed = PaUtil_EndBufferProcessing( &(stream->bufferProcessor), &callbackResult ); } if( !stream->outputUnit && stream->inputSRConverter ) { /* ------------------ Simplex Input w/ SR Conversion * * if this is a simplex input stream, we need to read off the buffer, * do our sample rate conversion and pass the results to the buffer * processor. * The logic here is complicated somewhat by the fact that we don't * know how much data is available, so we loop on reasonably sized * chunks, and let the BufferProcessor deal with the rest. * */ /*This might be too big or small depending on SR conversion*/ float data[ chan * inNumberFrames ]; OSStatus err; do { /*Run the buffer processor until we are out of data*/ UInt32 size; long f; size = sizeof( data ); err = AudioConverterFillBuffer( stream->inputSRConverter, ringBufferIOProc, &stream->inputRingBuffer, &size, (void *)data ); if( err != RING_BUFFER_EMPTY ) ERR( err ); assert( err == 0 || err == RING_BUFFER_EMPTY ); f = size / ( chan * sizeof(float) ); PaUtil_SetInputFrameCount( &(stream->bufferProcessor), f ); if( f ) { PaUtil_BeginBufferProcessing( &(stream->bufferProcessor), &timeInfo, stream->xrunFlags ); stream->xrunFlags = 0; PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor), 0, data, chan ); framesProcessed = PaUtil_EndBufferProcessing( &(stream->bufferProcessor), &callbackResult ); } } while( callbackResult == paContinue && !err ); } } switch( callbackResult ) { case paContinue: break; case paComplete: case paAbort: stream->state = CALLBACK_STOPPED ; if( stream->outputUnit ) AudioOutputUnitStop(stream->outputUnit); if( stream->inputUnit ) AudioOutputUnitStop(stream->inputUnit); break; } PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed ); return noErr; } /* When CloseStream() is called, the multi-api layer ensures that the stream has already been stopped or aborted. */ static PaError CloseStream( PaStream* s ) { /* This may be called from a failed OpenStream. Therefore, each piece of info is treated seperately. */ PaError result = paNoError; PaMacCoreStream *stream = (PaMacCoreStream*)s; VVDBUG(("CloseStream()\n")); VDBUG( ( "Closing stream.\n" ) ); if( stream ) { if( stream->outputUnit ) { Boolean isInput = FALSE; CleanupDevicePropertyListeners( stream, stream->outputDevice, isInput ); } if( stream->inputUnit ) { Boolean isInput = TRUE; CleanupDevicePropertyListeners( stream, stream->inputDevice, isInput ); } if( stream->outputUnit ) { int count = removeFromXRunListenerList( stream ); if( count == 0 ) AudioDeviceRemovePropertyListener( stream->outputDevice, 0, false, kAudioDeviceProcessorOverload, xrunCallback ); } if( stream->inputUnit && stream->outputUnit != stream->inputUnit ) { int count = removeFromXRunListenerList( stream ); if( count == 0 ) AudioDeviceRemovePropertyListener( stream->inputDevice, 0, true, kAudioDeviceProcessorOverload, xrunCallback ); } if( stream->outputUnit && stream->outputUnit != stream->inputUnit ) { AudioUnitUninitialize( stream->outputUnit ); CloseComponent( stream->outputUnit ); } stream->outputUnit = NULL; if( stream->inputUnit ) { AudioUnitUninitialize( stream->inputUnit ); CloseComponent( stream->inputUnit ); stream->inputUnit = NULL; } if( stream->inputRingBuffer.buffer ) free( (void *) stream->inputRingBuffer.buffer ); stream->inputRingBuffer.buffer = NULL; /*TODO: is there more that needs to be done on error from AudioConverterDispose?*/ if( stream->inputSRConverter ) ERR( AudioConverterDispose( stream->inputSRConverter ) ); stream->inputSRConverter = NULL; if( stream->inputAudioBufferList.mBuffers[0].mData ) free( stream->inputAudioBufferList.mBuffers[0].mData ); stream->inputAudioBufferList.mBuffers[0].mData = NULL; result = destroyBlioRingBuffers( &stream->blio ); if( result ) return result; if( stream->bufferProcessorIsInitialized ) PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); if( stream->timingInformationMutexIsInitialized ) pthread_mutex_destroy( &stream->timingInformationMutex ); PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); PaUtil_FreeMemory( stream ); } return result; } static PaError StartStream( PaStream *s ) { PaMacCoreStream *stream = (PaMacCoreStream*)s; OSStatus result = noErr; VVDBUG(("StartStream()\n")); VDBUG( ( "Starting stream.\n" ) ); #define ERR_WRAP(mac_err) do { result = mac_err ; if ( result != noErr ) return ERR(result) ; } while(0) /*FIXME: maybe want to do this on close/abort for faster start? */ PaUtil_ResetBufferProcessor( &stream->bufferProcessor ); if( stream->inputSRConverter ) ERR_WRAP( AudioConverterReset( stream->inputSRConverter ) ); /* -- start -- */ stream->state = ACTIVE; if( stream->inputUnit ) { ERR_WRAP( AudioOutputUnitStart(stream->inputUnit) ); } if( stream->outputUnit && stream->outputUnit != stream->inputUnit ) { ERR_WRAP( AudioOutputUnitStart(stream->outputUnit) ); } return paNoError; #undef ERR_WRAP } // it's not clear from appl's docs that this really waits // until all data is flushed. static ComponentResult BlockWhileAudioUnitIsRunning( AudioUnit audioUnit, AudioUnitElement element ) { Boolean isRunning = 1; while( isRunning ) { UInt32 s = sizeof( isRunning ); ComponentResult err = AudioUnitGetProperty( audioUnit, kAudioOutputUnitProperty_IsRunning, kAudioUnitScope_Global, element, &isRunning, &s ); if( err ) return err; Pa_Sleep( 100 ); } return noErr; } static PaError StopStream( PaStream *s ) { PaMacCoreStream *stream = (PaMacCoreStream*)s; OSStatus result = noErr; PaError paErr; VVDBUG(("StopStream()\n")); VDBUG( ("Waiting for BLIO.\n") ); waitUntilBlioWriteBufferIsFlushed( &stream->blio ); VDBUG( ( "Stopping stream.\n" ) ); stream->state = STOPPING; #define ERR_WRAP(mac_err) do { result = mac_err ; if ( result != noErr ) return ERR(result) ; } while(0) /* -- stop and reset -- */ if( stream->inputUnit == stream->outputUnit && stream->inputUnit ) { ERR_WRAP( AudioOutputUnitStop(stream->inputUnit) ); ERR_WRAP( BlockWhileAudioUnitIsRunning(stream->inputUnit,0) ); ERR_WRAP( BlockWhileAudioUnitIsRunning(stream->inputUnit,1) ); ERR_WRAP( AudioUnitReset(stream->inputUnit, kAudioUnitScope_Global, 1) ); ERR_WRAP( AudioUnitReset(stream->inputUnit, kAudioUnitScope_Global, 0) ); } else { if( stream->inputUnit ) { ERR_WRAP(AudioOutputUnitStop(stream->inputUnit) ); ERR_WRAP( BlockWhileAudioUnitIsRunning(stream->inputUnit,1) ); ERR_WRAP(AudioUnitReset(stream->inputUnit,kAudioUnitScope_Global,1)); } if( stream->outputUnit ) { ERR_WRAP(AudioOutputUnitStop(stream->outputUnit)); ERR_WRAP( BlockWhileAudioUnitIsRunning(stream->outputUnit,0) ); ERR_WRAP(AudioUnitReset(stream->outputUnit,kAudioUnitScope_Global,0)); } } if( stream->inputRingBuffer.buffer ) { PaUtil_FlushRingBuffer( &stream->inputRingBuffer ); bzero( (void *)stream->inputRingBuffer.buffer, stream->inputRingBuffer.bufferSize ); /* advance the write point a little, so we are reading from the middle of the buffer. We'll need extra at the end because testing has shown that this helps. */ if( stream->outputUnit ) PaUtil_AdvanceRingBufferWriteIndex( &stream->inputRingBuffer, stream->inputRingBuffer.bufferSize / RING_BUFFER_ADVANCE_DENOMINATOR ); } stream->xrunFlags = 0; stream->state = STOPPED; paErr = resetBlioRingBuffers( &stream->blio ); if( paErr ) return paErr; VDBUG( ( "Stream Stopped.\n" ) ); return paNoError; #undef ERR_WRAP } static PaError AbortStream( PaStream *s ) { VVDBUG(("AbortStream()->StopStream()\n")); VDBUG( ( "Aborting stream.\n" ) ); /* We have nothing faster than StopStream. */ return StopStream(s); } static PaError IsStreamStopped( PaStream *s ) { PaMacCoreStream *stream = (PaMacCoreStream*)s; VVDBUG(("IsStreamStopped()\n")); return stream->state == STOPPED ? 1 : 0; } static PaError IsStreamActive( PaStream *s ) { PaMacCoreStream *stream = (PaMacCoreStream*)s; VVDBUG(("IsStreamActive()\n")); return ( stream->state == ACTIVE || stream->state == STOPPING ); } static double GetStreamCpuLoad( PaStream* s ) { PaMacCoreStream *stream = (PaMacCoreStream*)s; VVDBUG(("GetStreamCpuLoad()\n")); return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ); } pd-0.46-7/portaudio/src/hostapi/coreaudio/notes.txt0000664000175000017500000002135412160204055020503 0ustar mspmspNotes on status of CoreAudio Implementation of PortAudio Document Last Updated December 9, 2005 There are currently two implementations of PortAudio for Mac Core Audio. The original is in pa_mac_core_old.c, and the newer, default implementation is in pa_mac_core.c. Only pa_mac_core.c is currently developed and supported as it uses apple's current core audio technology. To select use the old implementation, replace pa_mac_core.c with pa_mac_core_old.c (eg. "cp pa_mac_core_auhal.c pa_mac_core.c"), then run configure and make as usual. ------------------------------------------- Notes on Newer/Default AUHAL implementation: by Bjorn Roche Last Updated December 9, 2005 Principle of Operation: This implementation uses AUHAL for audio I/O. To some extent, it also operates at the "HAL" Layer, though this behavior can be limited by platform specific flags (see pa_mac_core.h for details). The default settings should be reasonable: they don't change the SR of the device and don't cause interruptions if other devices are using the device. Major Software Elements Used: Apple's HAL AUs provide output SR conversion transparently, however, only on output, so this implementation uses AudioConverters to convert the sample rate on input. A PortAudio ring buffer is used to buffer input when sample rate conversion is required or when separate audio units are used for duplex IO. Finally, a PortAudio buffer processor is used to convert formats and provide additional buffers if needed. Internally, interleaved floating point data streams are used exclusively - the audio unit converts from the audio hardware's native format to interleaved float PCM and PortAudio's Buffer processor is used for conversion to user formats. Simplex Input: Simplex input uses a single callback. If sample rate conversion is required, a ring buffer and AudioConverter are used as well. Simplex output: Simplex output uses a single callback. No ring buffer or audio converter is used because AUHAL does its own output SR conversion. Duplex, one device (no SR conversion): When one device is used, a single callback is used. This achieves very low latency. Duplex, separate devices or SR conversion: When SR conversion is required, data must be buffered before it is converted and data is not always available at the same times on input and output, so SR conversion requires the same treatment as separate devices. The input callback reads data and puts it in the ring buffer. The output callback reads the data off the ring buffer, into an audio converter and finally to the buffer processor. Platform Specific Options: By using the flags in pa_mac_core.h, the user may specify several options. For example, the user can specify the sample-rate conversion quality, and the extent to which PA will attempt to "play nice" and to what extent it will interrupt other apps to improve performance. For example, if 44100 Hz sample rate is requested but the device is set at 48000 Hz, PA can either change the device for optimal playback ("Pro" mode), which may interrupt other programs playing back audio, or simple use a sample-rate coversion, which allows for friendlier sharing of the device ("Play Nice" mode). Additionally, the user may define a "channel mapping" by calling paSetupMacCoreChannelMap() on their stream info structure before opening the stream with it. See below for creating a channel map. Known issues: - Buffering: No buffering beyond that provided by core audio is provided except where absolutely needed for the implementation to work. This may cause issues with large framesPerBuffer settings and it also means that no additional latency will be provided even if a large latency setting is selected. - Latency: Latency settings are generally ignored. They may be used as a hint for buffer size in paHostFramesPerBufferUnspecified, or the value may be used in cases where additional buffering is needed, such as doing input and output on seperate devices. Latency settings are always automatically bound to "safe" values, however, so setting extreme values here should not be an issue. - Buffer Size: paHostFramesPerBufferUnspecified and specific host buffer sizes are supported. paHostFramesPerBufferUnspecified works best in "pro" mode, where the buffer size and sample rate of the audio device is most likely to match the expected values. In the case of paHostFramesPerBuffer, an appropriate framesPerBuffer value will be used that guarantees minimum requested latency if that's possible. - Timing info. It reports on stream time, but I'm probably doing something wrong since patest_sine_time often reports negative latency numbers. Also, there are currently issues with some devices whehn plugging/unplugging devices. - xrun detection: The only xrun detection performed is when reading and writing the ring buffer. There is probably more that can be done. - abort/stop issues: stopping a stream is always a complete operation, but latency should be low enough to make the lack of a separate abort unnecessary. Apple clarifies its AudioOutputUnitStop() call here: http://lists.apple.com/archives/coreaudio-api/2005/Dec/msg00055.html - blocking interface: should work fine. - multichannel: It has been tested successfully on multichannel hardware from MOTU: traveler and 896HD. Also Presonus firepod and others. It is believed to work with all Core Audio devices, including virtual devices such as soundflower. - sample rate conversion quality: By default, SR conversion is the maximum available. This can be tweaked using flags pa_mac_core.h. Note that the AU render quyality property is used to set the sample rate conversion quality as "documented" here: http://lists.apple.com/archives/coreaudio-api/2004/Jan/msg00141.html - x86/Universal Binary: Universal binaries can be build. Creating a channel map: How to create the map array - Text taken From AUHAL.rtfd : [3] Channel Maps Clients can tell the AUHAL units which channels of the device they are interested in. For example, the client may be processing stereo data, but outputting to a six-channel device. This is done by using the kAudioOutputUnitProperty_ChannelMap property. To use this property: For Output: Create an array of SInt32 that is the size of the number of channels of the device (Get the Format of the AUHAL's output Element == 0) Initialize each of the array's values to -1 (-1 indicates that that channel is NOT to be presented in the conversion.) Next, for each channel of your app's output, set: channelMapArray[deviceOutputChannel] = desiredAppOutputChannel. For example: we have a 6 channel output device and our application has a stereo source it wants to provide to the device. Suppose we want that stereo source to go to the 3rd and 4th channels of the device. The channel map would look like this: { -1, -1, 0, 1, -1, -1 } Where the formats are: Input Element == 0: 2 channels (- client format - settable) Output Element == 0: 6 channels (- device format - NOT settable) So channel 2 (zero-based) of the device will take the first channel of output and channel 3 will take the second channel of output. (This translates to the 3rd and 4th plugs of the 6 output plugs of the device of course!) For Input: Create an array of SInt32 that is the size of the number of channels of the format you require for input. Get (or Set in this case as needed) the AUHAL's output Element == 1. Next, for each channel of input you require, set: channelMapArray[desiredAppInputChannel] = deviceOutputChannel; For example: we have a 6 channel input device from which we wish to receive stereo input from the 3rd and 4th channels. The channel map looks like this: { 2, 3 } Where the formats are: Input Element == 0: 2 channels (- device format - NOT settable) Output Element == 0: 6 channels (- client format - settable) ---------------------------------------- Notes on Original implementation: by Phil Burk and Darren Gibbs Last updated March 20, 2002 WHAT WORKS Output with very low latency, <10 msec. Half duplex input or output. Full duplex on the same CoreAudio device. The paFLoat32, paInt16, paInt8, paUInt8 sample formats. Pa_GetCPULoad() Pa_StreamTime() KNOWN BUGS OR LIMITATIONS We do not yet support simultaneous input and output on different devices. Note that some CoreAudio devices like the Roland UH30 look like one device but are actually two different CoreAudio devices. The Built-In audio is typically one CoreAudio device. Mono doesn't work. DEVICE MAPPING CoreAudio devices can support both input and output. But the sample rates supported may be different. So we have map one or two PortAudio device to each CoreAudio device depending on whether it supports input, output or both. When we query devices, we first get a list of CoreAudio devices. Then we scan the list and add a PortAudio device for each CoreAudio device that supports input. Then we make a scan for output devices. pd-0.46-7/portaudio/src/hostapi/coreaudio/pa_mac_core_utilities.c0000664000175000017500000006025512222201037023300 0ustar mspmsp/* * Helper and utility functions for pa_mac_core.c (Apple AUHAL implementation) * * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * * Written by Bjorn Roche of XO Audio LLC, from PA skeleton code. * Portions copied from code by Dominic Mazzoni (who wrote a HAL implementation) * * Dominic's code was based on code by Phil Burk, Darren Gibbs, * Gord Peters, Stephane Letz, and Greg Pfiel. * * The following people also deserve acknowledgements: * * Olivier Tristan for feedback and testing * Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O * interface. * * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup hostapi_src */ #include "pa_mac_core_utilities.h" #include "pa_mac_core_internal.h" #include #include #include #include PaError PaMacCore_SetUnixError( int err, int line ) { PaError ret; const char *errorText; if( err == 0 ) { return paNoError; } ret = paNoError; errorText = strerror( err ); /** Map Unix error to PaError. Pretty much the only one that maps is ENOMEM. */ if( err == ENOMEM ) ret = paInsufficientMemory; else ret = paInternalError; DBUG(("%d on line %d: msg='%s'\n", err, line, errorText)); PaUtil_SetLastHostErrorInfo( paCoreAudio, err, errorText ); return ret; } /* * Translates MacOS generated errors into PaErrors */ PaError PaMacCore_SetError(OSStatus error, int line, int isError) { /*FIXME: still need to handle possible ComponentResult values.*/ /* unfortunately, they don't seem to be documented anywhere.*/ PaError result; const char *errorType; const char *errorText; switch (error) { case kAudioHardwareNoError: return paNoError; case kAudioHardwareNotRunningError: errorText = "Audio Hardware Not Running"; result = paInternalError; break; case kAudioHardwareUnspecifiedError: errorText = "Unspecified Audio Hardware Error"; result = paInternalError; break; case kAudioHardwareUnknownPropertyError: errorText = "Audio Hardware: Unknown Property"; result = paInternalError; break; case kAudioHardwareBadPropertySizeError: errorText = "Audio Hardware: Bad Property Size"; result = paInternalError; break; case kAudioHardwareIllegalOperationError: errorText = "Audio Hardware: Illegal Operation"; result = paInternalError; break; case kAudioHardwareBadDeviceError: errorText = "Audio Hardware: Bad Device"; result = paInvalidDevice; break; case kAudioHardwareBadStreamError: errorText = "Audio Hardware: BadStream"; result = paBadStreamPtr; break; case kAudioHardwareUnsupportedOperationError: errorText = "Audio Hardware: Unsupported Operation"; result = paInternalError; break; case kAudioDeviceUnsupportedFormatError: errorText = "Audio Device: Unsupported Format"; result = paSampleFormatNotSupported; break; case kAudioDevicePermissionsError: errorText = "Audio Device: Permissions Error"; result = paDeviceUnavailable; break; /* Audio Unit Errors: http://developer.apple.com/documentation/MusicAudio/Reference/CoreAudio/audio_units/chapter_5_section_3.html */ case kAudioUnitErr_InvalidProperty: errorText = "Audio Unit: Invalid Property"; result = paInternalError; break; case kAudioUnitErr_InvalidParameter: errorText = "Audio Unit: Invalid Parameter"; result = paInternalError; break; case kAudioUnitErr_NoConnection: errorText = "Audio Unit: No Connection"; result = paInternalError; break; case kAudioUnitErr_FailedInitialization: errorText = "Audio Unit: Initialization Failed"; result = paInternalError; break; case kAudioUnitErr_TooManyFramesToProcess: errorText = "Audio Unit: Too Many Frames"; result = paInternalError; break; case kAudioUnitErr_IllegalInstrument: errorText = "Audio Unit: Illegal Instrument"; result = paInternalError; break; case kAudioUnitErr_InstrumentTypeNotFound: errorText = "Audio Unit: Instrument Type Not Found"; result = paInternalError; break; case kAudioUnitErr_InvalidFile: errorText = "Audio Unit: Invalid File"; result = paInternalError; break; case kAudioUnitErr_UnknownFileType: errorText = "Audio Unit: Unknown File Type"; result = paInternalError; break; case kAudioUnitErr_FileNotSpecified: errorText = "Audio Unit: File Not Specified"; result = paInternalError; break; case kAudioUnitErr_FormatNotSupported: errorText = "Audio Unit: Format Not Supported"; result = paInternalError; break; case kAudioUnitErr_Uninitialized: errorText = "Audio Unit: Unitialized"; result = paInternalError; break; case kAudioUnitErr_InvalidScope: errorText = "Audio Unit: Invalid Scope"; result = paInternalError; break; case kAudioUnitErr_PropertyNotWritable: errorText = "Audio Unit: PropertyNotWritable"; result = paInternalError; break; case kAudioUnitErr_InvalidPropertyValue: errorText = "Audio Unit: Invalid Property Value"; result = paInternalError; break; case kAudioUnitErr_PropertyNotInUse: errorText = "Audio Unit: Property Not In Use"; result = paInternalError; break; case kAudioUnitErr_Initialized: errorText = "Audio Unit: Initialized"; result = paInternalError; break; case kAudioUnitErr_InvalidOfflineRender: errorText = "Audio Unit: Invalid Offline Render"; result = paInternalError; break; case kAudioUnitErr_Unauthorized: errorText = "Audio Unit: Unauthorized"; result = paInternalError; break; case kAudioUnitErr_CannotDoInCurrentContext: errorText = "Audio Unit: cannot do in current context"; result = paInternalError; break; default: errorText = "Unknown Error"; result = paInternalError; } if (isError) errorType = "Error"; else errorType = "Warning"; char str[20]; // see if it appears to be a 4-char-code *(UInt32 *)(str + 1) = CFSwapInt32HostToBig(error); if (isprint(str[1]) && isprint(str[2]) && isprint(str[3]) && isprint(str[4])) { str[0] = str[5] = '\''; str[6] = '\0'; } else { // no, format it as an integer sprintf(str, "%d", (int)error); } DBUG(("%s on line %d: err='%s', msg=%s\n", errorType, line, str, errorText)); PaUtil_SetLastHostErrorInfo( paCoreAudio, error, errorText ); return result; } /* * This function computes an appropriate ring buffer size given * a requested latency (in seconds), sample rate and framesPerBuffer. * * The returned ringBufferSize is computed using the following * constraints: * - it must be at least 4. * - it must be at least 3x framesPerBuffer. * - it must be at least 2x the suggestedLatency. * - it must be a power of 2. * This function attempts to compute the minimum such size. * * FEEDBACK: too liberal/conservative/another way? */ long computeRingBufferSize( const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, long inputFramesPerBuffer, long outputFramesPerBuffer, double sampleRate ) { long ringSize; int index; int i; double latency ; long framesPerBuffer ; VVDBUG(( "computeRingBufferSize()\n" )); assert( inputParameters || outputParameters ); if( outputParameters && inputParameters ) { latency = MAX( inputParameters->suggestedLatency, outputParameters->suggestedLatency ); framesPerBuffer = MAX( inputFramesPerBuffer, outputFramesPerBuffer ); } else if( outputParameters ) { latency = outputParameters->suggestedLatency; framesPerBuffer = outputFramesPerBuffer ; } else /* we have inputParameters */ { latency = inputParameters->suggestedLatency; framesPerBuffer = inputFramesPerBuffer ; } ringSize = (long) ( latency * sampleRate * 2 + .5); VDBUG( ( "suggested latency : %d\n", (int) (latency*sampleRate) ) ); if( ringSize < framesPerBuffer * 3 ) ringSize = framesPerBuffer * 3 ; VDBUG(("framesPerBuffer:%d\n",(int)framesPerBuffer)); VDBUG(("Ringbuffer size (1): %d\n", (int)ringSize )); /* make sure it's at least 4 */ ringSize = MAX( ringSize, 4 ); /* round up to the next power of 2 */ index = -1; for( i=0; i> i & 0x01 ) index = i; assert( index > 0 ); if( ringSize <= ( 0x01 << index ) ) ringSize = 0x01 << index ; else ringSize = 0x01 << ( index + 1 ); VDBUG(( "Final Ringbuffer size (2): %d\n", (int)ringSize )); return ringSize; } /* * Durring testing of core audio, I found that serious crashes could occur * if properties such as sample rate were changed multiple times in rapid * succession. The function below could be used to with a condition variable. * to prevent propertychanges from happening until the last property * change is acknowledged. Instead, I implemented a busy-wait, which is simpler * to implement b/c in second round of testing (nov '09) property changes occured * quickly and so there was no real way to test the condition variable implementation. * therefore, this function is not used, but it is aluded to in commented code below, * since it represents a theoretically better implementation. */ OSStatus propertyProc( AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void* inClientData ) { // this is where we would set the condition variable return noErr; } /* sets the value of the given property and waits for the change to be acknowledged, and returns the final value, which is not guaranteed by this function to be the same as the desired value. Obviously, this function can only be used for data whose input and output are the same size and format, and their size and format are known in advance. whether or not the call succeeds, if the data is successfully read, it is returned in outPropertyData. If it is not read successfully, outPropertyData is zeroed, which may or may not be useful in determining if the property was read. */ PaError AudioDeviceSetPropertyNowAndWaitForChange( AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, UInt32 inPropertyDataSize, const void *inPropertyData, void *outPropertyData ) { OSStatus macErr; UInt32 outPropertyDataSize = inPropertyDataSize; /* First, see if it already has that value. If so, return. */ macErr = AudioDeviceGetProperty( inDevice, inChannel, isInput, inPropertyID, &outPropertyDataSize, outPropertyData ); if( macErr ) { memset( outPropertyData, 0, inPropertyDataSize ); goto failMac; } if( inPropertyDataSize!=outPropertyDataSize ) return paInternalError; if( 0==memcmp( outPropertyData, inPropertyData, outPropertyDataSize ) ) return paNoError; /* Ideally, we'd use a condition variable to determine changes. we could set that up here. */ /* If we were using a cond variable, we'd do something useful here, but for now, this is just to make 10.6 happy. */ macErr = AudioDeviceAddPropertyListener( inDevice, inChannel, isInput, inPropertyID, propertyProc, NULL ); if( macErr ) /* we couldn't add a listener. */ goto failMac; /* set property */ macErr = AudioDeviceSetProperty( inDevice, NULL, inChannel, isInput, inPropertyID, inPropertyDataSize, inPropertyData ); if( macErr ) goto failMac; /* busy-wait up to 30 seconds for the property to change */ /* busy-wait is justified here only because the correct alternative (condition variable) was hard to test, since most of the waiting ended up being for setting rather than getting in OS X 10.5. This was not the case in earlier OS versions. */ struct timeval tv1, tv2; gettimeofday( &tv1, NULL ); memcpy( &tv2, &tv1, sizeof( struct timeval ) ); while( tv2.tv_sec - tv1.tv_sec < 30 ) { /* now read the property back out */ macErr = AudioDeviceGetProperty( inDevice, inChannel, isInput, inPropertyID, &outPropertyDataSize, outPropertyData ); if( macErr ) { memset( outPropertyData, 0, inPropertyDataSize ); goto failMac; } /* and compare... */ if( 0==memcmp( outPropertyData, inPropertyData, outPropertyDataSize ) ) { AudioDeviceRemovePropertyListener( inDevice, inChannel, isInput, inPropertyID, propertyProc ); return paNoError; } /* No match yet, so let's sleep and try again. */ Pa_Sleep( 100 ); gettimeofday( &tv2, NULL ); } DBUG( ("Timeout waiting for device setting.\n" ) ); AudioDeviceRemovePropertyListener( inDevice, inChannel, isInput, inPropertyID, propertyProc ); return paNoError; failMac: AudioDeviceRemovePropertyListener( inDevice, inChannel, isInput, inPropertyID, propertyProc ); return ERR( macErr ); } /* * Sets the sample rate the HAL device. * if requireExact: set the sample rate or fail. * * otherwise : set the exact sample rate. * If that fails, check for available sample rates, and choose one * higher than the requested rate. If there isn't a higher one, * just use the highest available. */ PaError setBestSampleRateForDevice( const AudioDeviceID device, const bool isOutput, const bool requireExact, const Float64 desiredSrate ) { const bool isInput = isOutput ? 0 : 1; Float64 srate; UInt32 propsize = sizeof( Float64 ); OSErr err; AudioValueRange *ranges; int i=0; Float64 max = -1; /*the maximum rate available*/ Float64 best = -1; /*the lowest sample rate still greater than desired rate*/ VDBUG(("Setting sample rate for device %ld to %g.\n",device,(float)desiredSrate)); /* -- try setting the sample rate -- */ srate = 0; err = AudioDeviceSetPropertyNowAndWaitForChange( device, 0, isInput, kAudioDevicePropertyNominalSampleRate, propsize, &desiredSrate, &srate ); /* -- if the rate agrees, and was changed, we are done -- */ if( srate != 0 && srate == desiredSrate ) return paNoError; /* -- if the rate agrees, and we got no errors, we are done -- */ if( !err && srate == desiredSrate ) return paNoError; /* -- we've failed if the rates disagree and we are setting input -- */ if( requireExact ) return paInvalidSampleRate; /* -- generate a list of available sample rates -- */ err = AudioDeviceGetPropertyInfo( device, 0, isInput, kAudioDevicePropertyAvailableNominalSampleRates, &propsize, NULL ); if( err ) return ERR( err ); ranges = (AudioValueRange *)calloc( 1, propsize ); if( !ranges ) return paInsufficientMemory; err = AudioDeviceGetProperty( device, 0, isInput, kAudioDevicePropertyAvailableNominalSampleRates, &propsize, ranges ); if( err ) { free( ranges ); return ERR( err ); } VDBUG(("Requested sample rate of %g was not available.\n", (float)desiredSrate)); VDBUG(("%lu Available Sample Rates are:\n",propsize/sizeof(AudioValueRange))); #ifdef MAC_CORE_VERBOSE_DEBUG for( i=0; i max ) max = ranges[i].mMaximum; if( ranges[i].mMinimum > desiredSrate ) { if( best < 0 ) best = ranges[i].mMinimum; else if( ranges[i].mMinimum < best ) best = ranges[i].mMinimum; } } if( best < 0 ) best = max; VDBUG( ("Maximum Rate %g. best is %g.\n", max, best ) ); free( ranges ); /* -- set the sample rate -- */ propsize = sizeof( best ); srate = 0; err = AudioDeviceSetPropertyNowAndWaitForChange( device, 0, isInput, kAudioDevicePropertyNominalSampleRate, propsize, &best, &srate ); /* -- if the set rate matches, we are done -- */ if( srate != 0 && srate == best ) return paNoError; if( err ) return ERR( err ); /* -- otherwise, something wierd happened: we didn't set the rate, and we got no errors. Just bail. */ return paInternalError; } /* Attempts to set the requestedFramesPerBuffer. If it can't set the exact value, it settles for something smaller if available. If nothing smaller is available, it uses the smallest available size. actualFramesPerBuffer will be set to the actual value on successful return. OK to pass NULL to actualFramesPerBuffer. The logic is very simmilar too setBestSampleRate only failure here is not usually catastrophic. */ PaError setBestFramesPerBuffer( const AudioDeviceID device, const bool isOutput, UInt32 requestedFramesPerBuffer, UInt32 *actualFramesPerBuffer ) { UInt32 afpb; const bool isInput = !isOutput; UInt32 propsize = sizeof(UInt32); OSErr err; AudioValueRange range; if( actualFramesPerBuffer == NULL ) { actualFramesPerBuffer = &afpb; } /* -- try and set exact FPB -- */ err = AudioDeviceSetProperty( device, NULL, 0, isInput, kAudioDevicePropertyBufferFrameSize, propsize, &requestedFramesPerBuffer); err = AudioDeviceGetProperty( device, 0, isInput, kAudioDevicePropertyBufferFrameSize, &propsize, actualFramesPerBuffer); if( err ) { return ERR( err ); } // Did we get the size we asked for? if( *actualFramesPerBuffer == requestedFramesPerBuffer ) { return paNoError; /* we are done */ } // Clip requested value against legal range for the device. propsize = sizeof(AudioValueRange); err = AudioDeviceGetProperty( device, 0, isInput, kAudioDevicePropertyBufferFrameSizeRange, &propsize, &range ); if( err ) { return ERR( err ); } if( requestedFramesPerBuffer < range.mMinimum ) { requestedFramesPerBuffer = range.mMinimum; } else if( requestedFramesPerBuffer > range.mMaximum ) { requestedFramesPerBuffer = range.mMaximum; } /* --- set the buffer size (ignore errors) -- */ propsize = sizeof( UInt32 ); err = AudioDeviceSetProperty( device, NULL, 0, isInput, kAudioDevicePropertyBufferFrameSize, propsize, &requestedFramesPerBuffer ); /* --- read the property to check that it was set -- */ err = AudioDeviceGetProperty( device, 0, isInput, kAudioDevicePropertyBufferFrameSize, &propsize, actualFramesPerBuffer ); if( err ) return ERR( err ); return paNoError; } /********************** * * XRun stuff * **********************/ struct PaMacXRunListNode_s { PaMacCoreStream *stream; struct PaMacXRunListNode_s *next; } ; typedef struct PaMacXRunListNode_s PaMacXRunListNode; /** Always empty, so that it can always be the one returned by addToXRunListenerList. note that it's not a pointer. */ static PaMacXRunListNode firstXRunListNode; static int xRunListSize; static pthread_mutex_t xrunMutex; OSStatus xrunCallback( AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void* inClientData) { PaMacXRunListNode *node = (PaMacXRunListNode *) inClientData; int ret = pthread_mutex_trylock( &xrunMutex ) ; if( ret == 0 ) { node = node->next ; //skip the first node for( ; node; node=node->next ) { PaMacCoreStream *stream = node->stream; if( stream->state != ACTIVE ) continue; //if the stream isn't active, we don't care if the device is dropping if( isInput ) { if( stream->inputDevice == inDevice ) OSAtomicOr32( paInputOverflow, &stream->xrunFlags ); } else { if( stream->outputDevice == inDevice ) OSAtomicOr32( paOutputUnderflow, &stream->xrunFlags ); } } pthread_mutex_unlock( &xrunMutex ); } return 0; } int initializeXRunListenerList() { xRunListSize = 0; bzero( (void *) &firstXRunListNode, sizeof(firstXRunListNode) ); return pthread_mutex_init( &xrunMutex, NULL ); } int destroyXRunListenerList() { PaMacXRunListNode *node; node = firstXRunListNode.next; while( node ) { PaMacXRunListNode *tmp = node; node = node->next; free( tmp ); } xRunListSize = 0; return pthread_mutex_destroy( &xrunMutex ); } void *addToXRunListenerList( void *stream ) { pthread_mutex_lock( &xrunMutex ); PaMacXRunListNode *newNode; // setup new node: newNode = (PaMacXRunListNode *) malloc( sizeof( PaMacXRunListNode ) ); newNode->stream = (PaMacCoreStream *) stream; newNode->next = firstXRunListNode.next; // insert: firstXRunListNode.next = newNode; pthread_mutex_unlock( &xrunMutex ); return &firstXRunListNode; } int removeFromXRunListenerList( void *stream ) { pthread_mutex_lock( &xrunMutex ); PaMacXRunListNode *node, *prev; prev = &firstXRunListNode; node = firstXRunListNode.next; while( node ) { if( node->stream == stream ) { //found it: --xRunListSize; prev->next = node->next; free( node ); pthread_mutex_unlock( &xrunMutex ); return xRunListSize; } prev = prev->next; node = node->next; } pthread_mutex_unlock( &xrunMutex ); // failure return xRunListSize; } pd-0.46-7/portaudio/src/hostapi/coreaudio/pa_mac_core_blocking.h0000664000175000017500000001104312160204055023055 0ustar mspmsp/* * Internal blocking interfaces for PortAudio Apple AUHAL implementation * * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * * Written by Bjorn Roche of XO Audio LLC, from PA skeleton code. * Portions copied from code by Dominic Mazzoni (who wrote a HAL implementation) * * Dominic's code was based on code by Phil Burk, Darren Gibbs, * Gord Peters, Stephane Letz, and Greg Pfiel. * * The following people also deserve acknowledgements: * * Olivier Tristan for feedback and testing * Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O * interface. * * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup hostapi_src */ #ifndef PA_MAC_CORE_BLOCKING_H_ #define PA_MAC_CORE_BLOCKING_H_ #include "pa_ringbuffer.h" #include "portaudio.h" #include "pa_mac_core_utilities.h" /* * Number of miliseconds to busy wait whil waiting for data in blocking calls. */ #define PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL (5) /* * Define exactly one of these blocking methods * PA_MAC_BLIO_MUTEX is not actively maintained. */ #define PA_MAC_BLIO_BUSY_WAIT /* #define PA_MAC_BLIO_MUTEX */ typedef struct { PaUtilRingBuffer inputRingBuffer; PaUtilRingBuffer outputRingBuffer; size_t ringBufferFrames; PaSampleFormat inputSampleFormat; size_t inputSampleSizeActual; size_t inputSampleSizePow2; PaSampleFormat outputSampleFormat; size_t outputSampleSizeActual; size_t outputSampleSizePow2; size_t framesPerBuffer; int inChan; int outChan; //PaStreamCallbackFlags statusFlags; uint32_t statusFlags; PaError errors; /* Here we handle blocking, using condition variables. */ #ifdef PA_MAC_BLIO_MUTEX volatile bool isInputEmpty; pthread_mutex_t inputMutex; pthread_cond_t inputCond; volatile bool isOutputFull; pthread_mutex_t outputMutex; pthread_cond_t outputCond; #endif } PaMacBlio; /* * These functions operate on condition and related variables. */ PaError initializeBlioRingBuffers( PaMacBlio *blio, PaSampleFormat inputSampleFormat, PaSampleFormat outputSampleFormat, size_t framesPerBuffer, long ringBufferSize, int inChan, int outChan ); PaError destroyBlioRingBuffers( PaMacBlio *blio ); PaError resetBlioRingBuffers( PaMacBlio *blio ); int BlioCallback( const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData ); void waitUntilBlioWriteBufferIsFlushed( PaMacBlio *blio ); #endif /*PA_MAC_CORE_BLOCKING_H_*/ pd-0.46-7/portaudio/src/hostapi/coreaudio/pa_mac_core_utilities.h0000664000175000017500000001643512222201037023306 0ustar mspmsp/* * Helper and utility functions for pa_mac_core.c (Apple AUHAL implementation) * * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * * Written by Bjorn Roche of XO Audio LLC, from PA skeleton code. * Portions copied from code by Dominic Mazzoni (who wrote a HAL implementation) * * Dominic's code was based on code by Phil Burk, Darren Gibbs, * Gord Peters, Stephane Letz, and Greg Pfiel. * * The following people also deserve acknowledgements: * * Olivier Tristan for feedback and testing * Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O * interface. * * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup hostapi_src */ #ifndef PA_MAC_CORE_UTILITIES_H__ #define PA_MAC_CORE_UTILITIES_H__ #include #include "portaudio.h" #include "pa_util.h" #include #include #ifndef MIN #define MIN(a, b) (((a)<(b))?(a):(b)) #endif #ifndef MAX #define MAX(a, b) (((a)<(b))?(b):(a)) #endif #define ERR(mac_error) PaMacCore_SetError(mac_error, __LINE__, 1 ) #define WARNING(mac_error) PaMacCore_SetError(mac_error, __LINE__, 0 ) /* Help keep track of AUHAL element numbers */ #define INPUT_ELEMENT (1) #define OUTPUT_ELEMENT (0) /* Normal level of debugging: fine for most apps that don't mind the occational warning being printf'ed */ /* */ #define MAC_CORE_DEBUG #ifdef MAC_CORE_DEBUG # define DBUG(MSG) do { printf("||PaMacCore (AUHAL)|| "); printf MSG ; fflush(stdout); } while(0) #else # define DBUG(MSG) #endif /* Verbose Debugging: useful for developement */ /* #define MAC_CORE_VERBOSE_DEBUG */ #ifdef MAC_CORE_VERBOSE_DEBUG # define VDBUG(MSG) do { printf("||PaMacCore (v )|| "); printf MSG ; fflush(stdout); } while(0) #else # define VDBUG(MSG) #endif /* Very Verbose Debugging: Traces every call. */ /* #define MAC_CORE_VERY_VERBOSE_DEBUG */ #ifdef MAC_CORE_VERY_VERBOSE_DEBUG # define VVDBUG(MSG) do { printf("||PaMacCore (vv)|| "); printf MSG ; fflush(stdout); } while(0) #else # define VVDBUG(MSG) #endif #define UNIX_ERR(err) PaMacCore_SetUnixError( err, __LINE__ ) PaError PaMacCore_SetUnixError( int err, int line ); /* * Translates MacOS generated errors into PaErrors */ PaError PaMacCore_SetError(OSStatus error, int line, int isError); /* * This function computes an appropriate ring buffer size given * a requested latency (in seconds), sample rate and framesPerBuffer. * * The returned ringBufferSize is computed using the following * constraints: * - it must be at least 4. * - it must be at least 3x framesPerBuffer. * - it must be at least 2x the suggestedLatency. * - it must be a power of 2. * This function attempts to compute the minimum such size. * */ long computeRingBufferSize( const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, long inputFramesPerBuffer, long outputFramesPerBuffer, double sampleRate ); OSStatus propertyProc( AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void* inClientData ); /* sets the value of the given property and waits for the change to be acknowledged, and returns the final value, which is not guaranteed by this function to be the same as the desired value. Obviously, this function can only be used for data whose input and output are the same size and format, and their size and format are known in advance.*/ PaError AudioDeviceSetPropertyNowAndWaitForChange( AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, UInt32 inPropertyDataSize, const void *inPropertyData, void *outPropertyData ); /* * Sets the sample rate the HAL device. * if requireExact: set the sample rate or fail. * * otherwise : set the exact sample rate. * If that fails, check for available sample rates, and choose one * higher than the requested rate. If there isn't a higher one, * just use the highest available. */ PaError setBestSampleRateForDevice( const AudioDeviceID device, const bool isOutput, const bool requireExact, const Float64 desiredSrate ); /* Attempts to set the requestedFramesPerBuffer. If it can't set the exact value, it settles for something smaller if available. If nothing smaller is available, it uses the smallest available size. actualFramesPerBuffer will be set to the actual value on successful return. OK to pass NULL to actualFramesPerBuffer. The logic is very simmilar too setBestSampleRate only failure here is not usually catastrophic. */ PaError setBestFramesPerBuffer( const AudioDeviceID device, const bool isOutput, UInt32 requestedFramesPerBuffer, UInt32 *actualFramesPerBuffer ); /********************* * * xrun handling * *********************/ OSStatus xrunCallback( AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput, AudioDevicePropertyID inPropertyID, void* inClientData ) ; /** returns zero on success or a unix style error code. */ int initializeXRunListenerList(); /** returns zero on success or a unix style error code. */ int destroyXRunListenerList(); /**Returns the list, so that it can be passed to CorAudio.*/ void *addToXRunListenerList( void *stream ); /**Returns the number of Listeners in the list remaining.*/ int removeFromXRunListenerList( void *stream ); #endif /* PA_MAC_CORE_UTILITIES_H__*/ pd-0.46-7/portaudio/src/hostapi/jack/0000775000175000017500000000000012222201037015537 5ustar mspmsppd-0.46-7/portaudio/src/hostapi/jack/pa_jack.c0000664000175000017500000017322112222201037017301 0ustar mspmsp/* * $Id: pa_jack.c 1668 2011-05-02 17:07:11Z rossb $ * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * JACK Implementation by Joshua Haberman * * Copyright (c) 2004 Stefan Westerfeld * Copyright (c) 2004 Arve Knudsen * Copyright (c) 2002 Joshua Haberman * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /** @file @ingroup hostapi_src */ #include #include #include #include #include #include #include #include /* EBUSY */ #include /* sig_atomic_t */ #include #include #include #include #include "pa_util.h" #include "pa_hostapi.h" #include "pa_stream.h" #include "pa_process.h" #include "pa_allocation.h" #include "pa_cpuload.h" #include "pa_ringbuffer.h" #include "pa_debugprint.h" static pthread_t mainThread_; static char *jackErr_ = NULL; static const char* clientName_ = "PortAudio"; #define STRINGIZE_HELPER(expr) #expr #define STRINGIZE(expr) STRINGIZE_HELPER(expr) /* Check PaError */ #define ENSURE_PA(expr) \ do { \ PaError paErr; \ if( (paErr = (expr)) < paNoError ) \ { \ if( (paErr) == paUnanticipatedHostError && pthread_self() == mainThread_ ) \ { \ const char *err = jackErr_; \ if (! err ) err = "unknown error"; \ PaUtil_SetLastHostErrorInfo( paJACK, -1, err ); \ } \ PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \ result = paErr; \ goto error; \ } \ } while( 0 ) #define UNLESS(expr, code) \ do { \ if( (expr) == 0 ) \ { \ if( (code) == paUnanticipatedHostError && pthread_self() == mainThread_ ) \ { \ const char *err = jackErr_; \ if (!err) err = "unknown error"; \ PaUtil_SetLastHostErrorInfo( paJACK, -1, err ); \ } \ PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \ result = (code); \ goto error; \ } \ } while( 0 ) #define ASSERT_CALL(expr, success) \ do { \ int err = (expr); \ assert( err == success ); \ } while( 0 ) /* * Functions that directly map to the PortAudio stream interface */ static void Terminate( struct PaUtilHostApiRepresentation *hostApi ); static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ); static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ); static PaError CloseStream( PaStream* stream ); static PaError StartStream( PaStream *stream ); static PaError StopStream( PaStream *stream ); static PaError AbortStream( PaStream *stream ); static PaError IsStreamStopped( PaStream *s ); static PaError IsStreamActive( PaStream *stream ); /*static PaTime GetStreamInputLatency( PaStream *stream );*/ /*static PaTime GetStreamOutputLatency( PaStream *stream );*/ static PaTime GetStreamTime( PaStream *stream ); static double GetStreamCpuLoad( PaStream* stream ); /* * Data specific to this API */ struct PaJackStream; typedef struct { PaUtilHostApiRepresentation commonHostApiRep; PaUtilStreamInterface callbackStreamInterface; PaUtilStreamInterface blockingStreamInterface; PaUtilAllocationGroup *deviceInfoMemory; jack_client_t *jack_client; int jack_buffer_size; PaHostApiIndex hostApiIndex; pthread_mutex_t mtx; pthread_cond_t cond; unsigned long inputBase, outputBase; /* For dealing with the process thread */ volatile int xrun; /* Received xrun notification from JACK? */ struct PaJackStream * volatile toAdd, * volatile toRemove; struct PaJackStream *processQueue; volatile sig_atomic_t jackIsDown; } PaJackHostApiRepresentation; /* PaJackStream - a stream data structure specifically for this implementation */ typedef struct PaJackStream { PaUtilStreamRepresentation streamRepresentation; PaUtilBufferProcessor bufferProcessor; PaUtilCpuLoadMeasurer cpuLoadMeasurer; PaJackHostApiRepresentation *hostApi; /* our input and output ports */ jack_port_t **local_input_ports; jack_port_t **local_output_ports; /* the input and output ports of the client we are connecting to */ jack_port_t **remote_input_ports; jack_port_t **remote_output_ports; int num_incoming_connections; int num_outgoing_connections; jack_client_t *jack_client; /* The stream is running if it's still producing samples. * The stream is active if samples it produced are still being heard. */ volatile sig_atomic_t is_running; volatile sig_atomic_t is_active; /* Used to signal processing thread that stream should start or stop, respectively */ volatile sig_atomic_t doStart, doStop, doAbort; jack_nframes_t t0; PaUtilAllocationGroup *stream_memory; /* These are useful in the process callback */ int callbackResult; int isSilenced; int xrun; /* These are useful for the blocking API */ int isBlockingStream; PaUtilRingBuffer inFIFO; PaUtilRingBuffer outFIFO; volatile sig_atomic_t data_available; sem_t data_semaphore; int bytesPerFrame; int samplesPerFrame; struct PaJackStream *next; } PaJackStream; #define TRUE 1 #define FALSE 0 /* * Functions specific to this API */ static int JackCallback( jack_nframes_t frames, void *userData ); /* * * Implementation * */ /* ---- blocking emulation layer ---- */ /* Allocate buffer. */ static PaError BlockingInitFIFO( PaUtilRingBuffer *rbuf, long numFrames, long bytesPerFrame ) { long numBytes = numFrames * bytesPerFrame; char *buffer = (char *) malloc( numBytes ); if( buffer == NULL ) return paInsufficientMemory; memset( buffer, 0, numBytes ); return (PaError) PaUtil_InitializeRingBuffer( rbuf, 1, numBytes, buffer ); } /* Free buffer. */ static PaError BlockingTermFIFO( PaUtilRingBuffer *rbuf ) { if( rbuf->buffer ) free( rbuf->buffer ); rbuf->buffer = NULL; return paNoError; } static int BlockingCallback( const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData ) { struct PaJackStream *stream = (PaJackStream *)userData; long numBytes = stream->bytesPerFrame * framesPerBuffer; /* This may get called with NULL inputBuffer during initial setup. */ if( inputBuffer != NULL ) { PaUtil_WriteRingBuffer( &stream->inFIFO, inputBuffer, numBytes ); } if( outputBuffer != NULL ) { int numRead = PaUtil_ReadRingBuffer( &stream->outFIFO, outputBuffer, numBytes ); /* Zero out remainder of buffer if we run out of data. */ memset( (char *)outputBuffer + numRead, 0, numBytes - numRead ); } if( !stream->data_available ) { stream->data_available = 1; sem_post( &stream->data_semaphore ); } return paContinue; } static PaError BlockingBegin( PaJackStream *stream, int minimum_buffer_size ) { long doRead = 0; long doWrite = 0; PaError result = paNoError; long numFrames; doRead = stream->local_input_ports != NULL; doWrite = stream->local_output_ports != NULL; /* */ stream->samplesPerFrame = 2; stream->bytesPerFrame = sizeof(float) * stream->samplesPerFrame; /* */ numFrames = 32; while (numFrames < minimum_buffer_size) numFrames *= 2; if( doRead ) { ENSURE_PA( BlockingInitFIFO( &stream->inFIFO, numFrames, stream->bytesPerFrame ) ); } if( doWrite ) { long numBytes; ENSURE_PA( BlockingInitFIFO( &stream->outFIFO, numFrames, stream->bytesPerFrame ) ); /* Make Write FIFO appear full initially. */ numBytes = PaUtil_GetRingBufferWriteAvailable( &stream->outFIFO ); PaUtil_AdvanceRingBufferWriteIndex( &stream->outFIFO, numBytes ); } stream->data_available = 0; sem_init( &stream->data_semaphore, 0, 0 ); error: return result; } static void BlockingEnd( PaJackStream *stream ) { BlockingTermFIFO( &stream->inFIFO ); BlockingTermFIFO( &stream->outFIFO ); sem_destroy( &stream->data_semaphore ); } static PaError BlockingReadStream( PaStream* s, void *data, unsigned long numFrames ) { PaError result = paNoError; PaJackStream *stream = (PaJackStream *)s; long bytesRead; char *p = (char *) data; long numBytes = stream->bytesPerFrame * numFrames; while( numBytes > 0 ) { bytesRead = PaUtil_ReadRingBuffer( &stream->inFIFO, p, numBytes ); numBytes -= bytesRead; p += bytesRead; if( numBytes > 0 ) { /* see write for an explanation */ if( stream->data_available ) stream->data_available = 0; else sem_wait( &stream->data_semaphore ); } } return result; } static PaError BlockingWriteStream( PaStream* s, const void *data, unsigned long numFrames ) { PaError result = paNoError; PaJackStream *stream = (PaJackStream *)s; long bytesWritten; char *p = (char *) data; long numBytes = stream->bytesPerFrame * numFrames; while( numBytes > 0 ) { bytesWritten = PaUtil_WriteRingBuffer( &stream->outFIFO, p, numBytes ); numBytes -= bytesWritten; p += bytesWritten; if( numBytes > 0 ) { /* we use the following algorithm: * (1) write data * (2) if some data didn't fit into the ringbuffer, set data_available to 0 * to indicate to the audio that if space becomes available, we want to know * (3) retry to write data (because it might be that between (1) and (2) * new space in the buffer became available) * (4) if this failed, we are sure that the buffer is really empty and * we will definitely receive a notification when it becomes available * thus we can safely sleep * * if the algorithm bailed out in step (3) before, it leaks a count of 1 * on the semaphore; however, it doesn't matter, because if we block in (4), * we also do it in a loop */ if( stream->data_available ) stream->data_available = 0; else sem_wait( &stream->data_semaphore ); } } return result; } static signed long BlockingGetStreamReadAvailable( PaStream* s ) { PaJackStream *stream = (PaJackStream *)s; int bytesFull = PaUtil_GetRingBufferReadAvailable( &stream->inFIFO ); return bytesFull / stream->bytesPerFrame; } static signed long BlockingGetStreamWriteAvailable( PaStream* s ) { PaJackStream *stream = (PaJackStream *)s; int bytesEmpty = PaUtil_GetRingBufferWriteAvailable( &stream->outFIFO ); return bytesEmpty / stream->bytesPerFrame; } static PaError BlockingWaitEmpty( PaStream *s ) { PaJackStream *stream = (PaJackStream *)s; while( PaUtil_GetRingBufferReadAvailable( &stream->outFIFO ) > 0 ) { stream->data_available = 0; sem_wait( &stream->data_semaphore ); } return 0; } /* ---- jack driver ---- */ /* BuildDeviceList(): * * The process of determining a list of PortAudio "devices" from * JACK's client/port system is fairly involved, so it is separated * into its own routine. */ static PaError BuildDeviceList( PaJackHostApiRepresentation *jackApi ) { /* Utility macros for the repetitive process of allocating memory */ /* JACK has no concept of a device. To JACK, there are clients * which have an arbitrary number of ports. To make this * intelligible to PortAudio clients, we will group each JACK client * into a device, and make each port of that client a channel */ PaError result = paNoError; PaUtilHostApiRepresentation *commonApi = &jackApi->commonHostApiRep; const char **jack_ports = NULL; char **client_names = NULL; char *regex_pattern = NULL; int port_index, client_index, i; double globalSampleRate; regex_t port_regex; unsigned long numClients = 0, numPorts = 0; char *tmp_client_name = NULL; commonApi->info.defaultInputDevice = paNoDevice; commonApi->info.defaultOutputDevice = paNoDevice; commonApi->info.deviceCount = 0; /* Parse the list of ports, using a regex to grab the client names */ ASSERT_CALL( regcomp( &port_regex, "^[^:]*", REG_EXTENDED ), 0 ); /* since we are rebuilding the list of devices, free all memory * associated with the previous list */ PaUtil_FreeAllAllocations( jackApi->deviceInfoMemory ); regex_pattern = PaUtil_GroupAllocateMemory( jackApi->deviceInfoMemory, jack_client_name_size() + 3 ); tmp_client_name = PaUtil_GroupAllocateMemory( jackApi->deviceInfoMemory, jack_client_name_size() ); /* We can only retrieve the list of clients indirectly, by first * asking for a list of all ports, then parsing the port names * according to the client_name:port_name convention (which is * enforced by jackd) * A: If jack_get_ports returns NULL, there's nothing for us to do */ UNLESS( (jack_ports = jack_get_ports( jackApi->jack_client, "", "", 0 )) && jack_ports[0], paNoError ); /* Find number of ports */ while( jack_ports[numPorts] ) ++numPorts; /* At least there will be one port per client :) */ UNLESS( client_names = PaUtil_GroupAllocateMemory( jackApi->deviceInfoMemory, numPorts * sizeof (char *) ), paInsufficientMemory ); /* Build a list of clients from the list of ports */ for( numClients = 0, port_index = 0; jack_ports[port_index] != NULL; port_index++ ) { int client_seen = FALSE; regmatch_t match_info; const char *port = jack_ports[port_index]; /* extract the client name from the port name, using a regex * that parses the clientname:portname syntax */ UNLESS( !regexec( &port_regex, port, 1, &match_info, 0 ), paInternalError ); assert(match_info.rm_eo - match_info.rm_so < jack_client_name_size()); memcpy( tmp_client_name, port + match_info.rm_so, match_info.rm_eo - match_info.rm_so ); tmp_client_name[match_info.rm_eo - match_info.rm_so] = '\0'; /* do we know about this port's client yet? */ for( i = 0; i < numClients; i++ ) { if( strcmp( tmp_client_name, client_names[i] ) == 0 ) client_seen = TRUE; } if (client_seen) continue; /* A: Nothing to see here, move along */ UNLESS( client_names[numClients] = (char*)PaUtil_GroupAllocateMemory( jackApi->deviceInfoMemory, strlen(tmp_client_name) + 1), paInsufficientMemory ); /* The alsa_pcm client should go in spot 0. If this * is the alsa_pcm client AND we are NOT about to put * it in spot 0 put it in spot 0 and move whatever * was already in spot 0 to the end. */ if( strcmp( "alsa_pcm", tmp_client_name ) == 0 && numClients > 0 ) { /* alsa_pcm goes in spot 0 */ strcpy( client_names[ numClients ], client_names[0] ); strcpy( client_names[0], tmp_client_name ); } else { /* put the new client at the end of the client list */ strcpy( client_names[ numClients ], tmp_client_name ); } ++numClients; } /* Now we have a list of clients, which will become the list of * PortAudio devices. */ /* there is one global sample rate all clients must conform to */ globalSampleRate = jack_get_sample_rate( jackApi->jack_client ); UNLESS( commonApi->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( jackApi->deviceInfoMemory, sizeof(PaDeviceInfo*) * numClients ), paInsufficientMemory ); assert( commonApi->info.deviceCount == 0 ); /* Create a PaDeviceInfo structure for every client */ for( client_index = 0; client_index < numClients; client_index++ ) { PaDeviceInfo *curDevInfo; const char **clientPorts = NULL; UNLESS( curDevInfo = (PaDeviceInfo*)PaUtil_GroupAllocateMemory( jackApi->deviceInfoMemory, sizeof(PaDeviceInfo) ), paInsufficientMemory ); UNLESS( curDevInfo->name = (char*)PaUtil_GroupAllocateMemory( jackApi->deviceInfoMemory, strlen(client_names[client_index]) + 1 ), paInsufficientMemory ); strcpy( (char *)curDevInfo->name, client_names[client_index] ); curDevInfo->structVersion = 2; curDevInfo->hostApi = jackApi->hostApiIndex; /* JACK is very inflexible: there is one sample rate the whole * system must run at, and all clients must speak IEEE float. */ curDevInfo->defaultSampleRate = globalSampleRate; /* To determine how many input and output channels are available, * we re-query jackd with more specific parameters. */ sprintf( regex_pattern, "%s:.*", client_names[client_index] ); /* ... what are your output ports (that we could input from)? */ clientPorts = jack_get_ports( jackApi->jack_client, regex_pattern, NULL, JackPortIsOutput); curDevInfo->maxInputChannels = 0; curDevInfo->defaultLowInputLatency = 0.; curDevInfo->defaultHighInputLatency = 0.; if( clientPorts ) { jack_port_t *p = jack_port_by_name( jackApi->jack_client, clientPorts[0] ); curDevInfo->defaultLowInputLatency = curDevInfo->defaultHighInputLatency = jack_port_get_latency( p ) / globalSampleRate; for( i = 0; clientPorts[i] != NULL; i++) { /* The number of ports returned is the number of output channels. * We don't care what they are, we just care how many */ curDevInfo->maxInputChannels++; } free(clientPorts); } /* ... what are your input ports (that we could output to)? */ clientPorts = jack_get_ports( jackApi->jack_client, regex_pattern, NULL, JackPortIsInput); curDevInfo->maxOutputChannels = 0; curDevInfo->defaultLowOutputLatency = 0.; curDevInfo->defaultHighOutputLatency = 0.; if( clientPorts ) { jack_port_t *p = jack_port_by_name( jackApi->jack_client, clientPorts[0] ); curDevInfo->defaultLowOutputLatency = curDevInfo->defaultHighOutputLatency = jack_port_get_latency( p ) / globalSampleRate; for( i = 0; clientPorts[i] != NULL; i++) { /* The number of ports returned is the number of input channels. * We don't care what they are, we just care how many */ curDevInfo->maxOutputChannels++; } free(clientPorts); } /* Add this client to the list of devices */ commonApi->deviceInfos[client_index] = curDevInfo; ++commonApi->info.deviceCount; if( commonApi->info.defaultInputDevice == paNoDevice && curDevInfo->maxInputChannels > 0 ) commonApi->info.defaultInputDevice = client_index; if( commonApi->info.defaultOutputDevice == paNoDevice && curDevInfo->maxOutputChannels > 0 ) commonApi->info.defaultOutputDevice = client_index; } error: regfree( &port_regex ); free( jack_ports ); return result; } static void UpdateSampleRate( PaJackStream *stream, double sampleRate ) { /* XXX: Maybe not the cleanest way of going about this? */ stream->cpuLoadMeasurer.samplingPeriod = stream->bufferProcessor.samplePeriod = 1. / sampleRate; stream->streamRepresentation.streamInfo.sampleRate = sampleRate; } static void JackErrorCallback( const char *msg ) { if( pthread_self() == mainThread_ ) { assert( msg ); jackErr_ = realloc( jackErr_, strlen( msg ) + 1 ); strcpy( jackErr_, msg ); } } static void JackOnShutdown( void *arg ) { PaJackHostApiRepresentation *jackApi = (PaJackHostApiRepresentation *)arg; PaJackStream *stream = jackApi->processQueue; PA_DEBUG(( "%s: JACK server is shutting down\n", __FUNCTION__ )); for( ; stream; stream = stream->next ) { stream->is_active = 0; } /* Make sure that the main thread doesn't get stuck waiting on the condition */ ASSERT_CALL( pthread_mutex_lock( &jackApi->mtx ), 0 ); jackApi->jackIsDown = 1; ASSERT_CALL( pthread_cond_signal( &jackApi->cond ), 0 ); ASSERT_CALL( pthread_mutex_unlock( &jackApi->mtx ), 0 ); } static int JackSrCb( jack_nframes_t nframes, void *arg ) { PaJackHostApiRepresentation *jackApi = (PaJackHostApiRepresentation *)arg; double sampleRate = (double)nframes; PaJackStream *stream = jackApi->processQueue; /* Update all streams in process queue */ PA_DEBUG(( "%s: Acting on change in JACK samplerate: %f\n", __FUNCTION__, sampleRate )); for( ; stream; stream = stream->next ) { if( stream->streamRepresentation.streamInfo.sampleRate != sampleRate ) { PA_DEBUG(( "%s: Updating samplerate\n", __FUNCTION__ )); UpdateSampleRate( stream, sampleRate ); } } return 0; } static int JackXRunCb(void *arg) { PaJackHostApiRepresentation *hostApi = (PaJackHostApiRepresentation *)arg; assert( hostApi ); hostApi->xrun = TRUE; PA_DEBUG(( "%s: JACK signalled xrun\n", __FUNCTION__ )); return 0; } PaError PaJack_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) { PaError result = paNoError; PaJackHostApiRepresentation *jackHostApi; int activated = 0; jack_status_t jackStatus = 0; *hostApi = NULL; /* Initialize to NULL */ UNLESS( jackHostApi = (PaJackHostApiRepresentation*) PaUtil_AllocateMemory( sizeof(PaJackHostApiRepresentation) ), paInsufficientMemory ); UNLESS( jackHostApi->deviceInfoMemory = PaUtil_CreateAllocationGroup(), paInsufficientMemory ); mainThread_ = pthread_self(); ASSERT_CALL( pthread_mutex_init( &jackHostApi->mtx, NULL ), 0 ); ASSERT_CALL( pthread_cond_init( &jackHostApi->cond, NULL ), 0 ); /* Try to become a client of the JACK server. If we cannot do * this, then this API cannot be used. * * Without the JackNoStartServer option, the jackd server is started * automatically which we do not want. */ jackHostApi->jack_client = jack_client_open( clientName_, JackNoStartServer, &jackStatus ); if( !jackHostApi->jack_client ) { /* the V19 development docs say that if an implementation * detects that it cannot be used, it should return a NULL * interface and paNoError */ PA_DEBUG(( "%s: Couldn't connect to JACK, status: %d\n", __FUNCTION__, jackStatus )); result = paNoError; goto error; } jackHostApi->hostApiIndex = hostApiIndex; *hostApi = &jackHostApi->commonHostApiRep; (*hostApi)->info.structVersion = 1; (*hostApi)->info.type = paJACK; (*hostApi)->info.name = "JACK Audio Connection Kit"; /* Build a device list by querying the JACK server */ ENSURE_PA( BuildDeviceList( jackHostApi ) ); /* Register functions */ (*hostApi)->Terminate = Terminate; (*hostApi)->OpenStream = OpenStream; (*hostApi)->IsFormatSupported = IsFormatSupported; PaUtil_InitializeStreamInterface( &jackHostApi->callbackStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, GetStreamCpuLoad, PaUtil_DummyRead, PaUtil_DummyWrite, PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable ); PaUtil_InitializeStreamInterface( &jackHostApi->blockingStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, PaUtil_DummyGetCpuLoad, BlockingReadStream, BlockingWriteStream, BlockingGetStreamReadAvailable, BlockingGetStreamWriteAvailable ); jackHostApi->inputBase = jackHostApi->outputBase = 0; jackHostApi->xrun = 0; jackHostApi->toAdd = jackHostApi->toRemove = NULL; jackHostApi->processQueue = NULL; jackHostApi->jackIsDown = 0; jack_on_shutdown( jackHostApi->jack_client, JackOnShutdown, jackHostApi ); jack_set_error_function( JackErrorCallback ); jackHostApi->jack_buffer_size = jack_get_buffer_size ( jackHostApi->jack_client ); /* Don't check for error, may not be supported (deprecated in at least jackdmp) */ jack_set_sample_rate_callback( jackHostApi->jack_client, JackSrCb, jackHostApi ); UNLESS( !jack_set_xrun_callback( jackHostApi->jack_client, JackXRunCb, jackHostApi ), paUnanticipatedHostError ); UNLESS( !jack_set_process_callback( jackHostApi->jack_client, JackCallback, jackHostApi ), paUnanticipatedHostError ); UNLESS( !jack_activate( jackHostApi->jack_client ), paUnanticipatedHostError ); activated = 1; return result; error: if( activated ) ASSERT_CALL( jack_deactivate( jackHostApi->jack_client ), 0 ); if( jackHostApi ) { if( jackHostApi->jack_client ) ASSERT_CALL( jack_client_close( jackHostApi->jack_client ), 0 ); if( jackHostApi->deviceInfoMemory ) { PaUtil_FreeAllAllocations( jackHostApi->deviceInfoMemory ); PaUtil_DestroyAllocationGroup( jackHostApi->deviceInfoMemory ); } PaUtil_FreeMemory( jackHostApi ); } return result; } static void Terminate( struct PaUtilHostApiRepresentation *hostApi ) { PaJackHostApiRepresentation *jackHostApi = (PaJackHostApiRepresentation*)hostApi; /* note: this automatically disconnects all ports, since a deactivated * client is not allowed to have any ports connected */ ASSERT_CALL( jack_deactivate( jackHostApi->jack_client ), 0 ); ASSERT_CALL( pthread_mutex_destroy( &jackHostApi->mtx ), 0 ); ASSERT_CALL( pthread_cond_destroy( &jackHostApi->cond ), 0 ); ASSERT_CALL( jack_client_close( jackHostApi->jack_client ), 0 ); if( jackHostApi->deviceInfoMemory ) { PaUtil_FreeAllAllocations( jackHostApi->deviceInfoMemory ); PaUtil_DestroyAllocationGroup( jackHostApi->deviceInfoMemory ); } PaUtil_FreeMemory( jackHostApi ); free( jackErr_ ); jackErr_ = NULL; } static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ) { int inputChannelCount = 0, outputChannelCount = 0; PaSampleFormat inputSampleFormat, outputSampleFormat; if( inputParameters ) { inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that input device can support inputChannelCount */ if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels ) return paInvalidChannelCount; /* validate inputStreamInfo */ if( inputParameters->hostApiSpecificStreamInfo ) return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } else { inputChannelCount = 0; } if( outputParameters ) { outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that output device can support inputChannelCount */ if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels ) return paInvalidChannelCount; /* validate outputStreamInfo */ if( outputParameters->hostApiSpecificStreamInfo ) return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } else { outputChannelCount = 0; } /* The following check is not necessary for JACK. - if a full duplex stream is requested, check that the combination of input and output parameters is supported Because the buffer adapter handles conversion between all standard sample formats, the following checks are only required if paCustomFormat is implemented, or under some other unusual conditions. - check that input device can support inputSampleFormat, or that we have the capability to convert from outputSampleFormat to a native format - check that output device can support outputSampleFormat, or that we have the capability to convert from outputSampleFormat to a native format */ /* check that the device supports sampleRate */ #define ABS(x) ( (x) > 0 ? (x) : -(x) ) if( ABS(sampleRate - jack_get_sample_rate(((PaJackHostApiRepresentation *) hostApi)->jack_client )) > 1 ) return paInvalidSampleRate; #undef ABS return paFormatIsSupported; } /* Basic stream initialization */ static PaError InitializeStream( PaJackStream *stream, PaJackHostApiRepresentation *hostApi, int numInputChannels, int numOutputChannels ) { PaError result = paNoError; assert( stream ); memset( stream, 0, sizeof (PaJackStream) ); UNLESS( stream->stream_memory = PaUtil_CreateAllocationGroup(), paInsufficientMemory ); stream->jack_client = hostApi->jack_client; stream->hostApi = hostApi; if( numInputChannels > 0 ) { UNLESS( stream->local_input_ports = (jack_port_t**) PaUtil_GroupAllocateMemory( stream->stream_memory, sizeof(jack_port_t*) * numInputChannels ), paInsufficientMemory ); memset( stream->local_input_ports, 0, sizeof(jack_port_t*) * numInputChannels ); UNLESS( stream->remote_output_ports = (jack_port_t**) PaUtil_GroupAllocateMemory( stream->stream_memory, sizeof(jack_port_t*) * numInputChannels ), paInsufficientMemory ); memset( stream->remote_output_ports, 0, sizeof(jack_port_t*) * numInputChannels ); } if( numOutputChannels > 0 ) { UNLESS( stream->local_output_ports = (jack_port_t**) PaUtil_GroupAllocateMemory( stream->stream_memory, sizeof(jack_port_t*) * numOutputChannels ), paInsufficientMemory ); memset( stream->local_output_ports, 0, sizeof(jack_port_t*) * numOutputChannels ); UNLESS( stream->remote_input_ports = (jack_port_t**) PaUtil_GroupAllocateMemory( stream->stream_memory, sizeof(jack_port_t*) * numOutputChannels ), paInsufficientMemory ); memset( stream->remote_input_ports, 0, sizeof(jack_port_t*) * numOutputChannels ); } stream->num_incoming_connections = numInputChannels; stream->num_outgoing_connections = numOutputChannels; error: return result; } /*! * Free resources associated with stream, and eventually stream itself. * * Frees allocated memory, and closes opened pcms. */ static void CleanUpStream( PaJackStream *stream, int terminateStreamRepresentation, int terminateBufferProcessor ) { int i; assert( stream ); if( stream->isBlockingStream ) BlockingEnd( stream ); for( i = 0; i < stream->num_incoming_connections; ++i ) { if( stream->local_input_ports[i] ) ASSERT_CALL( jack_port_unregister( stream->jack_client, stream->local_input_ports[i] ), 0 ); } for( i = 0; i < stream->num_outgoing_connections; ++i ) { if( stream->local_output_ports[i] ) ASSERT_CALL( jack_port_unregister( stream->jack_client, stream->local_output_ports[i] ), 0 ); } if( terminateStreamRepresentation ) PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); if( terminateBufferProcessor ) PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); if( stream->stream_memory ) { PaUtil_FreeAllAllocations( stream->stream_memory ); PaUtil_DestroyAllocationGroup( stream->stream_memory ); } PaUtil_FreeMemory( stream ); } static PaError WaitCondition( PaJackHostApiRepresentation *hostApi ) { PaError result = paNoError; int err = 0; PaTime pt = PaUtil_GetTime(); struct timespec ts; ts.tv_sec = (time_t) floor( pt + 10 * 60 /* 10 minutes */ ); ts.tv_nsec = (long) ((pt - floor( pt )) * 1000000000); /* XXX: Best enclose in loop, in case of spurious wakeups? */ err = pthread_cond_timedwait( &hostApi->cond, &hostApi->mtx, &ts ); /* Make sure we didn't time out */ UNLESS( err != ETIMEDOUT, paTimedOut ); UNLESS( !err, paInternalError ); error: return result; } static PaError AddStream( PaJackStream *stream ) { PaError result = paNoError; PaJackHostApiRepresentation *hostApi = stream->hostApi; /* Add to queue of streams that should be processed */ ASSERT_CALL( pthread_mutex_lock( &hostApi->mtx ), 0 ); if( !hostApi->jackIsDown ) { hostApi->toAdd = stream; /* Unlock mutex and await signal from processing thread */ result = WaitCondition( stream->hostApi ); } ASSERT_CALL( pthread_mutex_unlock( &hostApi->mtx ), 0 ); ENSURE_PA( result ); UNLESS( !hostApi->jackIsDown, paDeviceUnavailable ); error: return result; } /* Remove stream from processing queue */ static PaError RemoveStream( PaJackStream *stream ) { PaError result = paNoError; PaJackHostApiRepresentation *hostApi = stream->hostApi; /* Add to queue over streams that should be processed */ ASSERT_CALL( pthread_mutex_lock( &hostApi->mtx ), 0 ); if( !hostApi->jackIsDown ) { hostApi->toRemove = stream; /* Unlock mutex and await signal from processing thread */ result = WaitCondition( stream->hostApi ); } ASSERT_CALL( pthread_mutex_unlock( &hostApi->mtx ), 0 ); ENSURE_PA( result ); error: return result; } /* Add stream to JACK callback processing queue */ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ) { PaError result = paNoError; PaJackHostApiRepresentation *jackHostApi = (PaJackHostApiRepresentation*)hostApi; PaJackStream *stream = NULL; char *port_string = PaUtil_GroupAllocateMemory( jackHostApi->deviceInfoMemory, jack_port_name_size() ); unsigned long regexSz = jack_client_name_size() + 3; char *regex_pattern = PaUtil_GroupAllocateMemory( jackHostApi->deviceInfoMemory, regexSz ); const char **jack_ports = NULL; /* int jack_max_buffer_size = jack_get_buffer_size( jackHostApi->jack_client ); */ int i; int inputChannelCount, outputChannelCount; const double jackSr = jack_get_sample_rate( jackHostApi->jack_client ); PaSampleFormat inputSampleFormat = 0, outputSampleFormat = 0; int bpInitialized = 0, srInitialized = 0; /* Initialized buffer processor and stream representation? */ unsigned long ofs; /* validate platform specific flags */ if( (streamFlags & paPlatformSpecificFlags) != 0 ) return paInvalidFlag; /* unexpected platform specific flag */ if( (streamFlags & paPrimeOutputBuffersUsingStreamCallback) != 0 ) { streamFlags &= ~paPrimeOutputBuffersUsingStreamCallback; /*return paInvalidFlag;*/ /* This implementation does not support buffer priming */ } if( framesPerBuffer != paFramesPerBufferUnspecified ) { /* Jack operates with power of two buffers, and we don't support non-integer buffer adaption (yet) */ /*UNLESS( !(framesPerBuffer & (framesPerBuffer - 1)), paBufferTooBig );*/ /* TODO: Add descriptive error code? */ } /* Preliminary checks */ if( inputParameters ) { inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that input device can support inputChannelCount */ if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels ) return paInvalidChannelCount; /* validate inputStreamInfo */ if( inputParameters->hostApiSpecificStreamInfo ) return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } else { inputChannelCount = 0; } if( outputParameters ) { outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; /* unless alternate device specification is supported, reject the use of paUseHostApiSpecificDeviceSpecification */ if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; /* check that output device can support inputChannelCount */ if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels ) return paInvalidChannelCount; /* validate outputStreamInfo */ if( outputParameters->hostApiSpecificStreamInfo ) return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } else { outputChannelCount = 0; } /* ... check that the sample rate exactly matches the ONE acceptable rate * A: This rate isn't necessarily constant though? */ #define ABS(x) ( (x) > 0 ? (x) : -(x) ) if( ABS(sampleRate - jackSr) > 1 ) return paInvalidSampleRate; #undef ABS UNLESS( stream = (PaJackStream*)PaUtil_AllocateMemory( sizeof(PaJackStream) ), paInsufficientMemory ); ENSURE_PA( InitializeStream( stream, jackHostApi, inputChannelCount, outputChannelCount ) ); /* the blocking emulation, if necessary */ stream->isBlockingStream = !streamCallback; if( stream->isBlockingStream ) { float latency = 0.001; /* 1ms is the absolute minimum we support */ int minimum_buffer_frames = 0; if( inputParameters && inputParameters->suggestedLatency > latency ) latency = inputParameters->suggestedLatency; else if( outputParameters && outputParameters->suggestedLatency > latency ) latency = outputParameters->suggestedLatency; /* the latency the user asked for indicates the minimum buffer size in frames */ minimum_buffer_frames = (int) (latency * jack_get_sample_rate( jackHostApi->jack_client )); /* we also need to be able to store at least three full jack buffers to avoid dropouts */ if( jackHostApi->jack_buffer_size * 3 > minimum_buffer_frames ) minimum_buffer_frames = jackHostApi->jack_buffer_size * 3; /* setup blocking API data structures (FIXME: can fail) */ BlockingBegin( stream, minimum_buffer_frames ); /* install our own callback for the blocking API */ streamCallback = BlockingCallback; userData = stream; PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &jackHostApi->blockingStreamInterface, streamCallback, userData ); } else { PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, &jackHostApi->callbackStreamInterface, streamCallback, userData ); } srInitialized = 1; PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, jackSr ); /* create the JACK ports. We cannot connect them until audio * processing begins */ /* Register a unique set of ports for this stream * TODO: Robust allocation of new port names */ ofs = jackHostApi->inputBase; for( i = 0; i < inputChannelCount; i++ ) { snprintf( port_string, jack_port_name_size(), "in_%lu", ofs + i ); UNLESS( stream->local_input_ports[i] = jack_port_register( jackHostApi->jack_client, port_string, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0 ), paInsufficientMemory ); } jackHostApi->inputBase += inputChannelCount; ofs = jackHostApi->outputBase; for( i = 0; i < outputChannelCount; i++ ) { snprintf( port_string, jack_port_name_size(), "out_%lu", ofs + i ); UNLESS( stream->local_output_ports[i] = jack_port_register( jackHostApi->jack_client, port_string, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 ), paInsufficientMemory ); } jackHostApi->outputBase += outputChannelCount; /* look up the jack_port_t's for the remote ports. We could do * this at stream start time, but doing it here ensures the * name lookup only happens once. */ if( inputChannelCount > 0 ) { int err = 0; /* Get output ports of our capture device */ snprintf( regex_pattern, regexSz, "%s:.*", hostApi->deviceInfos[ inputParameters->device ]->name ); UNLESS( jack_ports = jack_get_ports( jackHostApi->jack_client, regex_pattern, NULL, JackPortIsOutput ), paUnanticipatedHostError ); for( i = 0; i < inputChannelCount && jack_ports[i]; i++ ) { if( (stream->remote_output_ports[i] = jack_port_by_name( jackHostApi->jack_client, jack_ports[i] )) == NULL ) { err = 1; break; } } free( jack_ports ); UNLESS( !err, paInsufficientMemory ); /* Fewer ports than expected? */ UNLESS( i == inputChannelCount, paInternalError ); } if( outputChannelCount > 0 ) { int err = 0; /* Get input ports of our playback device */ snprintf( regex_pattern, regexSz, "%s:.*", hostApi->deviceInfos[ outputParameters->device ]->name ); UNLESS( jack_ports = jack_get_ports( jackHostApi->jack_client, regex_pattern, NULL, JackPortIsInput ), paUnanticipatedHostError ); for( i = 0; i < outputChannelCount && jack_ports[i]; i++ ) { if( (stream->remote_input_ports[i] = jack_port_by_name( jackHostApi->jack_client, jack_ports[i] )) == 0 ) { err = 1; break; } } free( jack_ports ); UNLESS( !err , paInsufficientMemory ); /* Fewer ports than expected? */ UNLESS( i == outputChannelCount, paInternalError ); } ENSURE_PA( PaUtil_InitializeBufferProcessor( &stream->bufferProcessor, inputChannelCount, inputSampleFormat, paFloat32 | paNonInterleaved, /* hostInputSampleFormat */ outputChannelCount, outputSampleFormat, paFloat32 | paNonInterleaved, /* hostOutputSampleFormat */ jackSr, streamFlags, framesPerBuffer, 0, /* Ignored */ paUtilUnknownHostBufferSize, /* Buffer size may vary on JACK's discretion */ streamCallback, userData ) ); bpInitialized = 1; if( stream->num_incoming_connections > 0 ) stream->streamRepresentation.streamInfo.inputLatency = (jack_port_get_latency( stream->remote_output_ports[0] ) - jack_get_buffer_size( jackHostApi->jack_client ) /* One buffer is not counted as latency */ + PaUtil_GetBufferProcessorInputLatencyFrames( &stream->bufferProcessor )) / sampleRate; if( stream->num_outgoing_connections > 0 ) stream->streamRepresentation.streamInfo.outputLatency = (jack_port_get_latency( stream->remote_input_ports[0] ) - jack_get_buffer_size( jackHostApi->jack_client ) /* One buffer is not counted as latency */ + PaUtil_GetBufferProcessorOutputLatencyFrames( &stream->bufferProcessor )) / sampleRate; stream->streamRepresentation.streamInfo.sampleRate = jackSr; stream->t0 = jack_frame_time( jackHostApi->jack_client ); /* A: Time should run from Pa_OpenStream */ /* Add to queue of opened streams */ ENSURE_PA( AddStream( stream ) ); *s = (PaStream*)stream; return result; error: if( stream ) CleanUpStream( stream, srInitialized, bpInitialized ); return result; } /* When CloseStream() is called, the multi-api layer ensures that the stream has already been stopped or aborted. */ static PaError CloseStream( PaStream* s ) { PaError result = paNoError; PaJackStream *stream = (PaJackStream*)s; /* Remove this stream from the processing queue */ ENSURE_PA( RemoveStream( stream ) ); error: CleanUpStream( stream, 1, 1 ); return result; } static PaError RealProcess( PaJackStream *stream, jack_nframes_t frames ) { PaError result = paNoError; PaStreamCallbackTimeInfo timeInfo = {0,0,0}; int chn; int framesProcessed; const double sr = jack_get_sample_rate( stream->jack_client ); /* Shouldn't change during the process callback */ PaStreamCallbackFlags cbFlags = 0; /* If the user has returned !paContinue from the callback we'll want to flush the internal buffers, * when these are empty we can finally mark the stream as inactive */ if( stream->callbackResult != paContinue && PaUtil_IsBufferProcessorOutputEmpty( &stream->bufferProcessor ) ) { stream->is_active = 0; if( stream->streamRepresentation.streamFinishedCallback ) stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); PA_DEBUG(( "%s: Callback finished\n", __FUNCTION__ )); goto end; } timeInfo.currentTime = (jack_frame_time( stream->jack_client ) - stream->t0) / sr; if( stream->num_incoming_connections > 0 ) timeInfo.inputBufferAdcTime = timeInfo.currentTime - jack_port_get_latency( stream->remote_output_ports[0] ) / sr; if( stream->num_outgoing_connections > 0 ) timeInfo.outputBufferDacTime = timeInfo.currentTime + jack_port_get_latency( stream->remote_input_ports[0] ) / sr; PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer ); if( stream->xrun ) { /* XXX: Any way to tell which of these occurred? */ cbFlags = paOutputUnderflow | paInputOverflow; stream->xrun = FALSE; } PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, cbFlags ); if( stream->num_incoming_connections > 0 ) PaUtil_SetInputFrameCount( &stream->bufferProcessor, frames ); if( stream->num_outgoing_connections > 0 ) PaUtil_SetOutputFrameCount( &stream->bufferProcessor, frames ); for( chn = 0; chn < stream->num_incoming_connections; chn++ ) { jack_default_audio_sample_t *channel_buf = (jack_default_audio_sample_t*) jack_port_get_buffer( stream->local_input_ports[chn], frames ); PaUtil_SetNonInterleavedInputChannel( &stream->bufferProcessor, chn, channel_buf ); } for( chn = 0; chn < stream->num_outgoing_connections; chn++ ) { jack_default_audio_sample_t *channel_buf = (jack_default_audio_sample_t*) jack_port_get_buffer( stream->local_output_ports[chn], frames ); PaUtil_SetNonInterleavedOutputChannel( &stream->bufferProcessor, chn, channel_buf ); } framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &stream->callbackResult ); /* We've specified a host buffer size mode where every frame should be consumed by the buffer processor */ assert( framesProcessed == frames ); PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed ); end: return result; } /* Update the JACK callback's stream processing queue. */ static PaError UpdateQueue( PaJackHostApiRepresentation *hostApi ) { PaError result = paNoError; int queueModified = 0; const double jackSr = jack_get_sample_rate( hostApi->jack_client ); int err; if( (err = pthread_mutex_trylock( &hostApi->mtx )) != 0 ) { assert( err == EBUSY ); return paNoError; } if( hostApi->toAdd ) { if( hostApi->processQueue ) { PaJackStream *node = hostApi->processQueue; /* Advance to end of queue */ while( node->next ) node = node->next; node->next = hostApi->toAdd; } else { /* The only queue entry. */ hostApi->processQueue = (PaJackStream *)hostApi->toAdd; } /* If necessary, update stream state */ if( hostApi->toAdd->streamRepresentation.streamInfo.sampleRate != jackSr ) UpdateSampleRate( hostApi->toAdd, jackSr ); hostApi->toAdd = NULL; queueModified = 1; } if( hostApi->toRemove ) { int removed = 0; PaJackStream *node = hostApi->processQueue, *prev = NULL; assert( hostApi->processQueue ); while( node ) { if( node == hostApi->toRemove ) { if( prev ) prev->next = node->next; else hostApi->processQueue = (PaJackStream *)node->next; removed = 1; break; } prev = node; node = node->next; } UNLESS( removed, paInternalError ); hostApi->toRemove = NULL; PA_DEBUG(( "%s: Removed stream from processing queue\n", __FUNCTION__ )); queueModified = 1; } if( queueModified ) { /* Signal that we've done what was asked of us */ ASSERT_CALL( pthread_cond_signal( &hostApi->cond ), 0 ); } error: ASSERT_CALL( pthread_mutex_unlock( &hostApi->mtx ), 0 ); return result; } /* Audio processing callback invoked periodically from JACK. */ static int JackCallback( jack_nframes_t frames, void *userData ) { PaError result = paNoError; PaJackHostApiRepresentation *hostApi = (PaJackHostApiRepresentation *)userData; PaJackStream *stream = NULL; int xrun = hostApi->xrun; hostApi->xrun = 0; assert( hostApi ); ENSURE_PA( UpdateQueue( hostApi ) ); /* Process each stream */ stream = hostApi->processQueue; for( ; stream; stream = stream->next ) { if( xrun ) /* Don't override if already set */ stream->xrun = 1; /* See if this stream is to be started */ if( stream->doStart ) { /* If we can't obtain a lock, we'll try next time */ int err = pthread_mutex_trylock( &stream->hostApi->mtx ); if( !err ) { if( stream->doStart ) /* Could potentially change before obtaining the lock */ { stream->is_active = 1; stream->doStart = 0; PA_DEBUG(( "%s: Starting stream\n", __FUNCTION__ )); ASSERT_CALL( pthread_cond_signal( &stream->hostApi->cond ), 0 ); stream->callbackResult = paContinue; stream->isSilenced = 0; } ASSERT_CALL( pthread_mutex_unlock( &stream->hostApi->mtx ), 0 ); } else assert( err == EBUSY ); } else if( stream->doStop || stream->doAbort ) /* Should we stop/abort stream? */ { if( stream->callbackResult == paContinue ) /* Ok, make it stop */ { PA_DEBUG(( "%s: Stopping stream\n", __FUNCTION__ )); stream->callbackResult = stream->doStop ? paComplete : paAbort; } } if( stream->is_active ) ENSURE_PA( RealProcess( stream, frames ) ); /* If we have just entered inactive state, silence output */ if( !stream->is_active && !stream->isSilenced ) { int i; /* Silence buffer after entering inactive state */ PA_DEBUG(( "Silencing the output\n" )); for( i = 0; i < stream->num_outgoing_connections; ++i ) { jack_default_audio_sample_t *buffer = jack_port_get_buffer( stream->local_output_ports[i], frames ); memset( buffer, 0, sizeof (jack_default_audio_sample_t) * frames ); } stream->isSilenced = 1; } if( stream->doStop || stream->doAbort ) { /* See if RealProcess has acted on the request */ if( !stream->is_active ) /* Ok, signal to the main thread that we've carried out the operation */ { /* If we can't obtain a lock, we'll try next time */ int err = pthread_mutex_trylock( &stream->hostApi->mtx ); if( !err ) { stream->doStop = stream->doAbort = 0; ASSERT_CALL( pthread_cond_signal( &stream->hostApi->cond ), 0 ); ASSERT_CALL( pthread_mutex_unlock( &stream->hostApi->mtx ), 0 ); } else assert( err == EBUSY ); } } } return 0; error: return -1; } static PaError StartStream( PaStream *s ) { PaError result = paNoError; PaJackStream *stream = (PaJackStream*)s; int i; /* Ready the processor */ PaUtil_ResetBufferProcessor( &stream->bufferProcessor ); /* Connect the ports. Note that the ports may already have been connected by someone else in * the meantime, in which case JACK returns EEXIST. */ if( stream->num_incoming_connections > 0 ) { for( i = 0; i < stream->num_incoming_connections; i++ ) { int r = jack_connect( stream->jack_client, jack_port_name( stream->remote_output_ports[i] ), jack_port_name( stream->local_input_ports[i] ) ); UNLESS( 0 == r || EEXIST == r, paUnanticipatedHostError ); } } if( stream->num_outgoing_connections > 0 ) { for( i = 0; i < stream->num_outgoing_connections; i++ ) { int r = jack_connect( stream->jack_client, jack_port_name( stream->local_output_ports[i] ), jack_port_name( stream->remote_input_ports[i] ) ); UNLESS( 0 == r || EEXIST == r, paUnanticipatedHostError ); } } stream->xrun = FALSE; /* Enable processing */ ASSERT_CALL( pthread_mutex_lock( &stream->hostApi->mtx ), 0 ); stream->doStart = 1; /* Wait for stream to be started */ result = WaitCondition( stream->hostApi ); /* do { err = pthread_cond_timedwait( &stream->hostApi->cond, &stream->hostApi->mtx, &ts ); } while( !stream->is_active && !err ); */ if( result != paNoError ) /* Something went wrong, call off the stream start */ { stream->doStart = 0; stream->is_active = 0; /* Cancel any processing */ } ASSERT_CALL( pthread_mutex_unlock( &stream->hostApi->mtx ), 0 ); ENSURE_PA( result ); stream->is_running = TRUE; PA_DEBUG(( "%s: Stream started\n", __FUNCTION__ )); error: return result; } static PaError RealStop( PaJackStream *stream, int abort ) { PaError result = paNoError; int i; if( stream->isBlockingStream ) BlockingWaitEmpty ( stream ); ASSERT_CALL( pthread_mutex_lock( &stream->hostApi->mtx ), 0 ); if( abort ) stream->doAbort = 1; else stream->doStop = 1; /* Wait for stream to be stopped */ result = WaitCondition( stream->hostApi ); ASSERT_CALL( pthread_mutex_unlock( &stream->hostApi->mtx ), 0 ); ENSURE_PA( result ); UNLESS( !stream->is_active, paInternalError ); PA_DEBUG(( "%s: Stream stopped\n", __FUNCTION__ )); error: stream->is_running = FALSE; /* Disconnect ports belonging to this stream */ if( !stream->hostApi->jackIsDown ) /* XXX: Well? */ { for( i = 0; i < stream->num_incoming_connections; i++ ) { if( jack_port_connected( stream->local_input_ports[i] ) ) { UNLESS( !jack_port_disconnect( stream->jack_client, stream->local_input_ports[i] ), paUnanticipatedHostError ); } } for( i = 0; i < stream->num_outgoing_connections; i++ ) { if( jack_port_connected( stream->local_output_ports[i] ) ) { UNLESS( !jack_port_disconnect( stream->jack_client, stream->local_output_ports[i] ), paUnanticipatedHostError ); } } } return result; } static PaError StopStream( PaStream *s ) { assert(s); return RealStop( (PaJackStream *)s, 0 ); } static PaError AbortStream( PaStream *s ) { assert(s); return RealStop( (PaJackStream *)s, 1 ); } static PaError IsStreamStopped( PaStream *s ) { PaJackStream *stream = (PaJackStream*)s; return !stream->is_running; } static PaError IsStreamActive( PaStream *s ) { PaJackStream *stream = (PaJackStream*)s; return stream->is_active; } static PaTime GetStreamTime( PaStream *s ) { PaJackStream *stream = (PaJackStream*)s; /* A: Is this relevant?? --> TODO: what if we're recording-only? */ return (jack_frame_time( stream->jack_client ) - stream->t0) / (PaTime)jack_get_sample_rate( stream->jack_client ); } static double GetStreamCpuLoad( PaStream* s ) { PaJackStream *stream = (PaJackStream*)s; return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ); } PaError PaJack_SetClientName( const char* name ) { if( strlen( name ) > jack_client_name_size() ) { /* OK, I don't know any better error code */ return paInvalidFlag; } clientName_ = name; return paNoError; } PaError PaJack_GetClientName(const char** clientName) { PaError result = paNoError; PaJackHostApiRepresentation* jackHostApi = NULL; PaJackHostApiRepresentation** ref = &jackHostApi; ENSURE_PA( PaUtil_GetHostApiRepresentation( (PaUtilHostApiRepresentation**)ref, paJACK ) ); *clientName = jack_get_client_name( jackHostApi->jack_client ); error: return result; } pd-0.46-7/portaudio/src/hostapi/wmme/0000775000175000017500000000000012222201037015574 5ustar mspmsppd-0.46-7/portaudio/src/hostapi/wmme/pa_win_wmme.c0000664000175000017500000045624112222201037020256 0ustar mspmsp/* * $Id: pa_win_wmme.c 1874 2012-10-31 06:20:59Z rbencina $ * pa_win_wmme.c * Implementation of PortAudio for Windows MultiMedia Extensions (WMME) * * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * * Authors: Ross Bencina and Phil Burk * Copyright (c) 1999-2000 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ /* Modification History: PLB = Phil Burk JM = Julien Maillard RDB = Ross Bencina PLB20010402 - sDevicePtrs now allocates based on sizeof(pointer) PLB20010413 - check for excessive numbers of channels PLB20010422 - apply Mike Berry's changes for CodeWarrior on PC including conditional inclusion of memory.h, and explicit typecasting on memory allocation PLB20010802 - use GlobalAlloc for sDevicesPtr instead of PaHost_AllocFastMemory PLB20010816 - pass process instead of thread to SetPriorityClass() PLB20010927 - use number of frames instead of real-time for CPULoad calculation. JM20020118 - prevent hung thread when buffers underflow. PLB20020321 - detect Win XP versus NT, 9x; fix DBUG typo; removed init of CurrentCount RDB20020411 - various renaming cleanups, factored streamData alloc and cpu usage init RDB20020417 - stopped counting WAVE_MAPPER when there were no real devices refactoring, renaming and fixed a few edge case bugs RDB20020531 - converted to V19 framework ** NOTE maintanance history is now stored in CVS ** */ /** @file @ingroup hostapi_src @brief Win32 host API implementation for the Windows MultiMedia Extensions (WMME) audio API. */ /* How it works: For both callback and blocking read/write streams we open the MME devices in CALLBACK_EVENT mode. In this mode, MME signals an Event object whenever it has finished with a buffer (either filled it for input, or played it for output). Where necessary, we block waiting for Event objects using WaitMultipleObjects(). When implementing a PA callback stream, we set up a high priority thread which waits on the MME buffer Events and drains/fills the buffers when they are ready. When implementing a PA blocking read/write stream, we simply wait on these Events (when necessary) inside the ReadStream() and WriteStream() functions. */ #include #include #include #include #include #ifndef UNDER_CE #include #endif #include /* PLB20010422 - "memory.h" doesn't work on CodeWarrior for PC. Thanks Mike Berry for the mod. */ #ifndef __MWERKS__ #include #include #endif /* __MWERKS__ */ #include "portaudio.h" #include "pa_trace.h" #include "pa_util.h" #include "pa_allocation.h" #include "pa_hostapi.h" #include "pa_stream.h" #include "pa_cpuload.h" #include "pa_process.h" #include "pa_debugprint.h" #include "pa_win_wmme.h" #include "pa_win_waveformat.h" #ifdef PAWIN_USE_WDMKS_DEVICE_INFO #include "pa_win_wdmks_utils.h" #ifndef DRV_QUERYDEVICEINTERFACE #define DRV_QUERYDEVICEINTERFACE (DRV_RESERVED + 12) #endif #ifndef DRV_QUERYDEVICEINTERFACESIZE #define DRV_QUERYDEVICEINTERFACESIZE (DRV_RESERVED + 13) #endif #endif /* PAWIN_USE_WDMKS_DEVICE_INFO */ /* use CreateThread for CYGWIN, _beginthreadex for all others */ #if !defined(__CYGWIN__) && !defined(_WIN32_WCE) #define CREATE_THREAD (HANDLE)_beginthreadex( 0, 0, ProcessingThreadProc, stream, 0, &stream->processingThreadId ) #define PA_THREAD_FUNC static unsigned WINAPI #define PA_THREAD_ID unsigned #else #define CREATE_THREAD CreateThread( 0, 0, ProcessingThreadProc, stream, 0, &stream->processingThreadId ) #define PA_THREAD_FUNC static DWORD WINAPI #define PA_THREAD_ID DWORD #endif #if (defined(_WIN32_WCE)) #pragma comment(lib, "Coredll.lib") #elif (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) /* MSC version 6 and above */ #pragma comment(lib, "winmm.lib") #endif /* provided in newer platform sdks */ #ifndef DWORD_PTR #if defined(_WIN64) #define DWORD_PTR unsigned __int64 #else #define DWORD_PTR unsigned long #endif #endif /************************************************* Constants ********/ #define PA_MME_USE_HIGH_DEFAULT_LATENCY_ (0) /* For debugging glitches. */ #if PA_MME_USE_HIGH_DEFAULT_LATENCY_ #define PA_MME_WIN_9X_DEFAULT_LATENCY_ (0.4) #define PA_MME_MIN_HOST_OUTPUT_BUFFER_COUNT_ (4) #define PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_ (4) #define PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_HALF_DUPLEX_ (4) #define PA_MME_HOST_BUFFER_GRANULARITY_FRAMES_WHEN_UNSPECIFIED_ (16) #define PA_MME_MAX_HOST_BUFFER_SECS_ (0.3) /* Do not exceed unless user buffer exceeds */ #define PA_MME_MAX_HOST_BUFFER_BYTES_ (32 * 1024) /* Has precedence over PA_MME_MAX_HOST_BUFFER_SECS_, some drivers are known to crash with buffer sizes > 32k */ #else #define PA_MME_WIN_9X_DEFAULT_LATENCY_ (0.2) #define PA_MME_MIN_HOST_OUTPUT_BUFFER_COUNT_ (2) #define PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_ (3) /* always use at least 3 input buffers for full duplex */ #define PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_HALF_DUPLEX_ (2) #define PA_MME_HOST_BUFFER_GRANULARITY_FRAMES_WHEN_UNSPECIFIED_ (16) #define PA_MME_MAX_HOST_BUFFER_SECS_ (0.1) /* Do not exceed unless user buffer exceeds */ #define PA_MME_MAX_HOST_BUFFER_BYTES_ (32 * 1024) /* Has precedence over PA_MME_MAX_HOST_BUFFER_SECS_, some drivers are known to crash with buffer sizes > 32k */ #endif /* Use higher latency for NT because it is even worse at real-time operation than Win9x. */ #define PA_MME_WIN_NT_DEFAULT_LATENCY_ (0.4) /* Default low latency for WDM based systems. This is based on a rough survey of workable latency settings using patest_wmme_find_best_latency_params.c. See pdf attached to ticket 185 for a graph of the survey results: http://www.portaudio.com/trac/ticket/185 Workable latencies varied between 40ms and ~80ms on different systems (different combinations of hardware, 32 and 64 bit, WinXP, Vista and Win7. We didn't get enough Vista results to know if Vista has systemically worse latency. For now we choose a safe value across all Windows versions here. */ #define PA_MME_WIN_WDM_DEFAULT_LATENCY_ (0.090) /* When client suggestedLatency could result in many host buffers, we aim to have around 8, based off Windows documentation that suggests that the kmixer uses 8 buffers. This choice is somewhat arbitrary here, since we havn't observed significant stability degredation with using either more, or less buffers. */ #define PA_MME_TARGET_HOST_BUFFER_COUNT_ 8 #define PA_MME_MIN_TIMEOUT_MSEC_ (1000) static const char constInputMapperSuffix_[] = " - Input"; static const char constOutputMapperSuffix_[] = " - Output"; /* copies TCHAR string to explicit char string */ char *StrTCpyToC(char *to, const TCHAR *from) { #if !defined(_UNICODE) && !defined(UNICODE) return strcpy(to, from); #else int count = wcslen(from); if (count != 0) if (WideCharToMultiByte(CP_ACP, 0, from, count, to, count, NULL, NULL) == 0) return NULL; return to; #endif } /* returns length of TCHAR string */ size_t StrTLen(const TCHAR *str) { #if !defined(_UNICODE) && !defined(UNICODE) return strlen(str); #else return wcslen(str); #endif } /********************************************************************/ typedef struct PaWinMmeStream PaWinMmeStream; /* forward declaration */ /* prototypes for functions declared in this file */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); #ifdef __cplusplus } #endif /* __cplusplus */ static void Terminate( struct PaUtilHostApiRepresentation *hostApi ); static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** stream, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ); static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ); static PaError CloseStream( PaStream* stream ); static PaError StartStream( PaStream *stream ); static PaError StopStream( PaStream *stream ); static PaError AbortStream( PaStream *stream ); static PaError IsStreamStopped( PaStream *s ); static PaError IsStreamActive( PaStream *stream ); static PaTime GetStreamTime( PaStream *stream ); static double GetStreamCpuLoad( PaStream* stream ); static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames ); static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames ); static signed long GetStreamReadAvailable( PaStream* stream ); static signed long GetStreamWriteAvailable( PaStream* stream ); /* macros for setting last host error information */ #ifdef UNICODE #define PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ) \ { \ wchar_t mmeErrorTextWide[ MAXERRORLENGTH ]; \ char mmeErrorText[ MAXERRORLENGTH ]; \ waveInGetErrorText( mmresult, mmeErrorTextWide, MAXERRORLENGTH ); \ WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR,\ mmeErrorTextWide, -1, mmeErrorText, MAXERRORLENGTH, NULL, NULL ); \ PaUtil_SetLastHostErrorInfo( paMME, mmresult, mmeErrorText ); \ } #define PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ) \ { \ wchar_t mmeErrorTextWide[ MAXERRORLENGTH ]; \ char mmeErrorText[ MAXERRORLENGTH ]; \ waveOutGetErrorText( mmresult, mmeErrorTextWide, MAXERRORLENGTH ); \ WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR,\ mmeErrorTextWide, -1, mmeErrorText, MAXERRORLENGTH, NULL, NULL ); \ PaUtil_SetLastHostErrorInfo( paMME, mmresult, mmeErrorText ); \ } #else /* !UNICODE */ #define PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ) \ { \ char mmeErrorText[ MAXERRORLENGTH ]; \ waveInGetErrorText( mmresult, mmeErrorText, MAXERRORLENGTH ); \ PaUtil_SetLastHostErrorInfo( paMME, mmresult, mmeErrorText ); \ } #define PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ) \ { \ char mmeErrorText[ MAXERRORLENGTH ]; \ waveOutGetErrorText( mmresult, mmeErrorText, MAXERRORLENGTH ); \ PaUtil_SetLastHostErrorInfo( paMME, mmresult, mmeErrorText ); \ } #endif /* UNICODE */ static void PaMme_SetLastSystemError( DWORD errorCode ) { char *lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); PaUtil_SetLastHostErrorInfo( paMME, errorCode, lpMsgBuf ); LocalFree( lpMsgBuf ); } #define PA_MME_SET_LAST_SYSTEM_ERROR( errorCode ) \ PaMme_SetLastSystemError( errorCode ) /* PaError returning wrappers for some commonly used win32 functions note that we allow passing a null ptr to have no effect. */ static PaError CreateEventWithPaError( HANDLE *handle, LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCTSTR lpName ) { PaError result = paNoError; *handle = NULL; *handle = CreateEvent( lpEventAttributes, bManualReset, bInitialState, lpName ); if( *handle == NULL ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() ); } return result; } static PaError ResetEventWithPaError( HANDLE handle ) { PaError result = paNoError; if( handle ) { if( ResetEvent( handle ) == 0 ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() ); } } return result; } static PaError CloseHandleWithPaError( HANDLE handle ) { PaError result = paNoError; if( handle ) { if( CloseHandle( handle ) == 0 ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() ); } } return result; } /* PaWinMmeHostApiRepresentation - host api datastructure specific to this implementation */ typedef struct { PaUtilHostApiRepresentation inheritedHostApiRep; PaUtilStreamInterface callbackStreamInterface; PaUtilStreamInterface blockingStreamInterface; PaUtilAllocationGroup *allocations; int inputDeviceCount, outputDeviceCount; /** winMmeDeviceIds is an array of WinMme device ids. fields in the range [0, inputDeviceCount) are input device ids, and [inputDeviceCount, inputDeviceCount + outputDeviceCount) are output device ids. */ UINT *winMmeDeviceIds; } PaWinMmeHostApiRepresentation; typedef struct { PaDeviceInfo inheritedDeviceInfo; DWORD dwFormats; /**<< standard formats bitmask from the WAVEINCAPS and WAVEOUTCAPS structures */ char deviceInputChannelCountIsKnown; /**<< if the system returns 0xFFFF then we don't really know the number of supported channels (1=>known, 0=>unknown)*/ char deviceOutputChannelCountIsKnown; /**<< if the system returns 0xFFFF then we don't really know the number of supported channels (1=>known, 0=>unknown)*/ } PaWinMmeDeviceInfo; /************************************************************************* * Returns recommended device ID. * On the PC, the recommended device can be specified by the user by * setting an environment variable. For example, to use device #1. * * set PA_RECOMMENDED_OUTPUT_DEVICE=1 * * The user should first determine the available device ID by using * the supplied application "pa_devs". */ #define PA_ENV_BUF_SIZE_ (32) #define PA_REC_IN_DEV_ENV_NAME_ ("PA_RECOMMENDED_INPUT_DEVICE") #define PA_REC_OUT_DEV_ENV_NAME_ ("PA_RECOMMENDED_OUTPUT_DEVICE") static PaDeviceIndex GetEnvDefaultDeviceID( char *envName ) { PaDeviceIndex recommendedIndex = paNoDevice; DWORD hresult; char envbuf[PA_ENV_BUF_SIZE_]; #ifndef WIN32_PLATFORM_PSPC /* no GetEnvironmentVariable on PocketPC */ /* Let user determine default device by setting environment variable. */ hresult = GetEnvironmentVariableA( envName, envbuf, PA_ENV_BUF_SIZE_ ); if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE_) ) { recommendedIndex = atoi( envbuf ); } #endif return recommendedIndex; } static void InitializeDefaultDeviceIdsFromEnv( PaWinMmeHostApiRepresentation *hostApi ) { PaDeviceIndex device; /* input */ device = GetEnvDefaultDeviceID( PA_REC_IN_DEV_ENV_NAME_ ); if( device != paNoDevice && ( device >= 0 && device < hostApi->inheritedHostApiRep.info.deviceCount ) && hostApi->inheritedHostApiRep.deviceInfos[ device ]->maxInputChannels > 0 ) { hostApi->inheritedHostApiRep.info.defaultInputDevice = device; } /* output */ device = GetEnvDefaultDeviceID( PA_REC_OUT_DEV_ENV_NAME_ ); if( device != paNoDevice && ( device >= 0 && device < hostApi->inheritedHostApiRep.info.deviceCount ) && hostApi->inheritedHostApiRep.deviceInfos[ device ]->maxOutputChannels > 0 ) { hostApi->inheritedHostApiRep.info.defaultOutputDevice = device; } } /** Convert external PA ID to a windows multimedia device ID */ static UINT LocalDeviceIndexToWinMmeDeviceId( PaWinMmeHostApiRepresentation *hostApi, PaDeviceIndex device ) { assert( device >= 0 && device < hostApi->inputDeviceCount + hostApi->outputDeviceCount ); return hostApi->winMmeDeviceIds[ device ]; } static int SampleFormatAndWinWmmeSpecificFlagsToLinearWaveFormatTag( PaSampleFormat sampleFormat, unsigned long winMmeSpecificFlags ) { int waveFormatTag = 0; if( winMmeSpecificFlags & paWinMmeWaveFormatDolbyAc3Spdif ) waveFormatTag = PAWIN_WAVE_FORMAT_DOLBY_AC3_SPDIF; else if( winMmeSpecificFlags & paWinMmeWaveFormatWmaSpdif ) waveFormatTag = PAWIN_WAVE_FORMAT_WMA_SPDIF; else waveFormatTag = PaWin_SampleFormatToLinearWaveFormatTag( sampleFormat ); return waveFormatTag; } static PaError QueryInputWaveFormatEx( int deviceId, WAVEFORMATEX *waveFormatEx ) { MMRESULT mmresult; switch( mmresult = waveInOpen( NULL, deviceId, waveFormatEx, 0, 0, WAVE_FORMAT_QUERY ) ) { case MMSYSERR_NOERROR: return paNoError; case MMSYSERR_ALLOCATED: /* Specified resource is already allocated. */ return paDeviceUnavailable; case MMSYSERR_NODRIVER: /* No device driver is present. */ return paDeviceUnavailable; case MMSYSERR_NOMEM: /* Unable to allocate or lock memory. */ return paInsufficientMemory; case WAVERR_BADFORMAT: /* Attempted to open with an unsupported waveform-audio format. */ return paSampleFormatNotSupported; case MMSYSERR_BADDEVICEID: /* Specified device identifier is out of range. */ /* falls through */ default: PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); return paUnanticipatedHostError; } } static PaError QueryOutputWaveFormatEx( int deviceId, WAVEFORMATEX *waveFormatEx ) { MMRESULT mmresult; switch( mmresult = waveOutOpen( NULL, deviceId, waveFormatEx, 0, 0, WAVE_FORMAT_QUERY ) ) { case MMSYSERR_NOERROR: return paNoError; case MMSYSERR_ALLOCATED: /* Specified resource is already allocated. */ return paDeviceUnavailable; case MMSYSERR_NODRIVER: /* No device driver is present. */ return paDeviceUnavailable; case MMSYSERR_NOMEM: /* Unable to allocate or lock memory. */ return paInsufficientMemory; case WAVERR_BADFORMAT: /* Attempted to open with an unsupported waveform-audio format. */ return paSampleFormatNotSupported; case MMSYSERR_BADDEVICEID: /* Specified device identifier is out of range. */ /* falls through */ default: PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); return paUnanticipatedHostError; } } static PaError QueryFormatSupported( PaDeviceInfo *deviceInfo, PaError (*waveFormatExQueryFunction)(int, WAVEFORMATEX*), int winMmeDeviceId, int channels, double sampleRate, unsigned long winMmeSpecificFlags ) { PaWinMmeDeviceInfo *winMmeDeviceInfo = (PaWinMmeDeviceInfo*)deviceInfo; PaWinWaveFormat waveFormat; PaSampleFormat sampleFormat; int waveFormatTag; /* @todo at the moment we only query with 16 bit sample format and directout speaker config*/ sampleFormat = paInt16; waveFormatTag = SampleFormatAndWinWmmeSpecificFlagsToLinearWaveFormatTag( sampleFormat, winMmeSpecificFlags ); if( waveFormatTag == PaWin_SampleFormatToLinearWaveFormatTag( paInt16 ) ){ /* attempt bypass querying the device for linear formats */ if( sampleRate == 11025.0 && ( (channels == 1 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_1M16)) || (channels == 2 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_1S16)) ) ){ return paNoError; } if( sampleRate == 22050.0 && ( (channels == 1 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_2M16)) || (channels == 2 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_2S16)) ) ){ return paNoError; } if( sampleRate == 44100.0 && ( (channels == 1 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_4M16)) || (channels == 2 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_4S16)) ) ){ return paNoError; } } /* first, attempt to query the device using WAVEFORMATEXTENSIBLE, if this fails we fall back to WAVEFORMATEX */ PaWin_InitializeWaveFormatExtensible( &waveFormat, channels, sampleFormat, waveFormatTag, sampleRate, PAWIN_SPEAKER_DIRECTOUT ); if( waveFormatExQueryFunction( winMmeDeviceId, (WAVEFORMATEX*)&waveFormat ) == paNoError ) return paNoError; PaWin_InitializeWaveFormatEx( &waveFormat, channels, sampleFormat, waveFormatTag, sampleRate ); return waveFormatExQueryFunction( winMmeDeviceId, (WAVEFORMATEX*)&waveFormat ); } #define PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_ (13) /* must match array length below */ static double defaultSampleRateSearchOrder_[] = { 44100.0, 48000.0, 32000.0, 24000.0, 22050.0, 88200.0, 96000.0, 192000.0, 16000.0, 12000.0, 11025.0, 9600.0, 8000.0 }; static void DetectDefaultSampleRate( PaWinMmeDeviceInfo *winMmeDeviceInfo, int winMmeDeviceId, PaError (*waveFormatExQueryFunction)(int, WAVEFORMATEX*), int maxChannels ) { PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo; int i; deviceInfo->defaultSampleRate = 0.; for( i=0; i < PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_; ++i ) { double sampleRate = defaultSampleRateSearchOrder_[ i ]; PaError paerror = QueryFormatSupported( deviceInfo, waveFormatExQueryFunction, winMmeDeviceId, maxChannels, sampleRate, 0 ); if( paerror == paNoError ) { deviceInfo->defaultSampleRate = sampleRate; break; } } } #ifdef PAWIN_USE_WDMKS_DEVICE_INFO static int QueryWaveInKSFilterMaxChannels( int waveInDeviceId, int *maxChannels ) { void *devicePath; DWORD devicePathSize; int result = 0; if( waveInMessage((HWAVEIN)waveInDeviceId, DRV_QUERYDEVICEINTERFACESIZE, (DWORD_PTR)&devicePathSize, 0 ) != MMSYSERR_NOERROR ) return 0; devicePath = PaUtil_AllocateMemory( devicePathSize ); if( !devicePath ) return 0; /* apparently DRV_QUERYDEVICEINTERFACE returns a unicode interface path, although this is undocumented */ if( waveInMessage((HWAVEIN)waveInDeviceId, DRV_QUERYDEVICEINTERFACE, (DWORD_PTR)devicePath, devicePathSize ) == MMSYSERR_NOERROR ) { int count = PaWin_WDMKS_QueryFilterMaximumChannelCount( devicePath, /* isInput= */ 1 ); if( count > 0 ) { *maxChannels = count; result = 1; } } PaUtil_FreeMemory( devicePath ); return result; } #endif /* PAWIN_USE_WDMKS_DEVICE_INFO */ static PaError InitializeInputDeviceInfo( PaWinMmeHostApiRepresentation *winMmeHostApi, PaWinMmeDeviceInfo *winMmeDeviceInfo, UINT winMmeInputDeviceId, int *success ) { PaError result = paNoError; char *deviceName; /* non-const ptr */ MMRESULT mmresult; WAVEINCAPS wic; PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo; *success = 0; mmresult = waveInGetDevCaps( winMmeInputDeviceId, &wic, sizeof( WAVEINCAPS ) ); if( mmresult == MMSYSERR_NOMEM ) { result = paInsufficientMemory; goto error; } else if( mmresult != MMSYSERR_NOERROR ) { /* instead of returning paUnanticipatedHostError we return paNoError, but leave success set as 0. This allows Pa_Initialize to just ignore this device, without failing the entire initialisation process. */ return paNoError; } if( winMmeInputDeviceId == WAVE_MAPPER ) { /* Append I/O suffix to WAVE_MAPPER device. */ deviceName = (char *)PaUtil_GroupAllocateMemory( winMmeHostApi->allocations, (long) (StrTLen( wic.szPname ) + 1 + sizeof(constInputMapperSuffix_)) ); if( !deviceName ) { result = paInsufficientMemory; goto error; } StrTCpyToC( deviceName, wic.szPname ); strcat( deviceName, constInputMapperSuffix_ ); } else { deviceName = (char*)PaUtil_GroupAllocateMemory( winMmeHostApi->allocations, (long) (StrTLen( wic.szPname ) + 1) ); if( !deviceName ) { result = paInsufficientMemory; goto error; } StrTCpyToC( deviceName, wic.szPname ); } deviceInfo->name = deviceName; if( wic.wChannels == 0xFFFF || wic.wChannels < 1 || wic.wChannels > 255 ){ /* For Windows versions using WDM (possibly Windows 98 ME and later) * the kernel mixer sits between the application and the driver. As a result, * wave*GetDevCaps often kernel mixer channel counts, which are unlimited. * When this happens we assume the device is stereo and set a flag * so that other channel counts can be tried with OpenStream -- i.e. when * device*ChannelCountIsKnown is false, OpenStream will try whatever * channel count you supply. * see also InitializeOutputDeviceInfo() below. */ PA_DEBUG(("Pa_GetDeviceInfo: Num input channels reported as %d! Changed to 2.\n", wic.wChannels )); deviceInfo->maxInputChannels = 2; winMmeDeviceInfo->deviceInputChannelCountIsKnown = 0; }else{ deviceInfo->maxInputChannels = wic.wChannels; winMmeDeviceInfo->deviceInputChannelCountIsKnown = 1; } #ifdef PAWIN_USE_WDMKS_DEVICE_INFO winMmeDeviceInfo->deviceInputChannelCountIsKnown = QueryWaveInKSFilterMaxChannels( winMmeInputDeviceId, &deviceInfo->maxInputChannels ); #endif /* PAWIN_USE_WDMKS_DEVICE_INFO */ winMmeDeviceInfo->dwFormats = wic.dwFormats; DetectDefaultSampleRate( winMmeDeviceInfo, winMmeInputDeviceId, QueryInputWaveFormatEx, deviceInfo->maxInputChannels ); *success = 1; error: return result; } #ifdef PAWIN_USE_WDMKS_DEVICE_INFO static int QueryWaveOutKSFilterMaxChannels( int waveOutDeviceId, int *maxChannels ) { void *devicePath; DWORD devicePathSize; int result = 0; if( waveOutMessage((HWAVEOUT)waveOutDeviceId, DRV_QUERYDEVICEINTERFACESIZE, (DWORD_PTR)&devicePathSize, 0 ) != MMSYSERR_NOERROR ) return 0; devicePath = PaUtil_AllocateMemory( devicePathSize ); if( !devicePath ) return 0; /* apparently DRV_QUERYDEVICEINTERFACE returns a unicode interface path, although this is undocumented */ if( waveOutMessage((HWAVEOUT)waveOutDeviceId, DRV_QUERYDEVICEINTERFACE, (DWORD_PTR)devicePath, devicePathSize ) == MMSYSERR_NOERROR ) { int count = PaWin_WDMKS_QueryFilterMaximumChannelCount( devicePath, /* isInput= */ 0 ); if( count > 0 ) { *maxChannels = count; result = 1; } } PaUtil_FreeMemory( devicePath ); return result; } #endif /* PAWIN_USE_WDMKS_DEVICE_INFO */ static PaError InitializeOutputDeviceInfo( PaWinMmeHostApiRepresentation *winMmeHostApi, PaWinMmeDeviceInfo *winMmeDeviceInfo, UINT winMmeOutputDeviceId, int *success ) { PaError result = paNoError; char *deviceName; /* non-const ptr */ MMRESULT mmresult; WAVEOUTCAPS woc; PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo; #ifdef PAWIN_USE_WDMKS_DEVICE_INFO int wdmksDeviceOutputChannelCountIsKnown; #endif *success = 0; mmresult = waveOutGetDevCaps( winMmeOutputDeviceId, &woc, sizeof( WAVEOUTCAPS ) ); if( mmresult == MMSYSERR_NOMEM ) { result = paInsufficientMemory; goto error; } else if( mmresult != MMSYSERR_NOERROR ) { /* instead of returning paUnanticipatedHostError we return paNoError, but leave success set as 0. This allows Pa_Initialize to just ignore this device, without failing the entire initialisation process. */ return paNoError; } if( winMmeOutputDeviceId == WAVE_MAPPER ) { /* Append I/O suffix to WAVE_MAPPER device. */ deviceName = (char *)PaUtil_GroupAllocateMemory( winMmeHostApi->allocations, (long) (StrTLen( woc.szPname ) + 1 + sizeof(constOutputMapperSuffix_)) ); if( !deviceName ) { result = paInsufficientMemory; goto error; } StrTCpyToC( deviceName, woc.szPname ); strcat( deviceName, constOutputMapperSuffix_ ); } else { deviceName = (char*)PaUtil_GroupAllocateMemory( winMmeHostApi->allocations, (long) (StrTLen( woc.szPname ) + 1) ); if( !deviceName ) { result = paInsufficientMemory; goto error; } StrTCpyToC( deviceName, woc.szPname ); } deviceInfo->name = deviceName; if( woc.wChannels == 0xFFFF || woc.wChannels < 1 || woc.wChannels > 255 ){ /* For Windows versions using WDM (possibly Windows 98 ME and later) * the kernel mixer sits between the application and the driver. As a result, * wave*GetDevCaps often kernel mixer channel counts, which are unlimited. * When this happens we assume the device is stereo and set a flag * so that other channel counts can be tried with OpenStream -- i.e. when * device*ChannelCountIsKnown is false, OpenStream will try whatever * channel count you supply. * see also InitializeInputDeviceInfo() above. */ PA_DEBUG(("Pa_GetDeviceInfo: Num output channels reported as %d! Changed to 2.\n", woc.wChannels )); deviceInfo->maxOutputChannels = 2; winMmeDeviceInfo->deviceOutputChannelCountIsKnown = 0; }else{ deviceInfo->maxOutputChannels = woc.wChannels; winMmeDeviceInfo->deviceOutputChannelCountIsKnown = 1; } #ifdef PAWIN_USE_WDMKS_DEVICE_INFO wdmksDeviceOutputChannelCountIsKnown = QueryWaveOutKSFilterMaxChannels( winMmeOutputDeviceId, &deviceInfo->maxOutputChannels ); if( wdmksDeviceOutputChannelCountIsKnown && !winMmeDeviceInfo->deviceOutputChannelCountIsKnown ) winMmeDeviceInfo->deviceOutputChannelCountIsKnown = 1; #endif /* PAWIN_USE_WDMKS_DEVICE_INFO */ winMmeDeviceInfo->dwFormats = woc.dwFormats; DetectDefaultSampleRate( winMmeDeviceInfo, winMmeOutputDeviceId, QueryOutputWaveFormatEx, deviceInfo->maxOutputChannels ); *success = 1; error: return result; } static void GetDefaultLatencies( PaTime *defaultLowLatency, PaTime *defaultHighLatency ) { OSVERSIONINFO osvi; osvi.dwOSVersionInfoSize = sizeof( osvi ); GetVersionEx( &osvi ); /* Check for NT */ if( (osvi.dwMajorVersion == 4) && (osvi.dwPlatformId == 2) ) { *defaultLowLatency = PA_MME_WIN_NT_DEFAULT_LATENCY_; } else if(osvi.dwMajorVersion >= 5) { *defaultLowLatency = PA_MME_WIN_WDM_DEFAULT_LATENCY_; } else { *defaultLowLatency = PA_MME_WIN_9X_DEFAULT_LATENCY_; } *defaultHighLatency = *defaultLowLatency * 2; } PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ) { PaError result = paNoError; int i; PaWinMmeHostApiRepresentation *winMmeHostApi; int inputDeviceCount, outputDeviceCount, maximumPossibleDeviceCount; PaWinMmeDeviceInfo *deviceInfoArray; int deviceInfoInitializationSucceeded; PaTime defaultLowLatency, defaultHighLatency; DWORD waveInPreferredDevice, waveOutPreferredDevice; DWORD preferredDeviceStatusFlags; winMmeHostApi = (PaWinMmeHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaWinMmeHostApiRepresentation) ); if( !winMmeHostApi ) { result = paInsufficientMemory; goto error; } winMmeHostApi->allocations = PaUtil_CreateAllocationGroup(); if( !winMmeHostApi->allocations ) { result = paInsufficientMemory; goto error; } *hostApi = &winMmeHostApi->inheritedHostApiRep; (*hostApi)->info.structVersion = 1; (*hostApi)->info.type = paMME; (*hostApi)->info.name = "MME"; /* initialise device counts and default devices under the assumption that there are no devices. These values are incremented below if and when devices are successfully initialized. */ (*hostApi)->info.deviceCount = 0; (*hostApi)->info.defaultInputDevice = paNoDevice; (*hostApi)->info.defaultOutputDevice = paNoDevice; winMmeHostApi->inputDeviceCount = 0; winMmeHostApi->outputDeviceCount = 0; #if !defined(DRVM_MAPPER_PREFERRED_GET) /* DRVM_MAPPER_PREFERRED_GET is defined in mmddk.h but we avoid a dependency on the DDK by defining it here */ #define DRVM_MAPPER_PREFERRED_GET (0x2000+21) #endif /* the following calls assume that if wave*Message fails the preferred device parameter won't be modified */ preferredDeviceStatusFlags = 0; waveInPreferredDevice = -1; waveInMessage( (HWAVEIN)WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)&waveInPreferredDevice, (DWORD_PTR)&preferredDeviceStatusFlags ); preferredDeviceStatusFlags = 0; waveOutPreferredDevice = -1; waveOutMessage( (HWAVEOUT)WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)&waveOutPreferredDevice, (DWORD_PTR)&preferredDeviceStatusFlags ); maximumPossibleDeviceCount = 0; inputDeviceCount = waveInGetNumDevs(); if( inputDeviceCount > 0 ) maximumPossibleDeviceCount += inputDeviceCount + 1; /* assume there is a WAVE_MAPPER */ outputDeviceCount = waveOutGetNumDevs(); if( outputDeviceCount > 0 ) maximumPossibleDeviceCount += outputDeviceCount + 1; /* assume there is a WAVE_MAPPER */ if( maximumPossibleDeviceCount > 0 ){ (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( winMmeHostApi->allocations, sizeof(PaDeviceInfo*) * maximumPossibleDeviceCount ); if( !(*hostApi)->deviceInfos ) { result = paInsufficientMemory; goto error; } /* allocate all device info structs in a contiguous block */ deviceInfoArray = (PaWinMmeDeviceInfo*)PaUtil_GroupAllocateMemory( winMmeHostApi->allocations, sizeof(PaWinMmeDeviceInfo) * maximumPossibleDeviceCount ); if( !deviceInfoArray ) { result = paInsufficientMemory; goto error; } winMmeHostApi->winMmeDeviceIds = (UINT*)PaUtil_GroupAllocateMemory( winMmeHostApi->allocations, sizeof(int) * maximumPossibleDeviceCount ); if( !winMmeHostApi->winMmeDeviceIds ) { result = paInsufficientMemory; goto error; } GetDefaultLatencies( &defaultLowLatency, &defaultHighLatency ); if( inputDeviceCount > 0 ){ /* -1 is the WAVE_MAPPER */ for( i = -1; i < inputDeviceCount; ++i ){ UINT winMmeDeviceId = (UINT)((i==-1) ? WAVE_MAPPER : i); PaWinMmeDeviceInfo *wmmeDeviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ]; PaDeviceInfo *deviceInfo = &wmmeDeviceInfo->inheritedDeviceInfo; deviceInfo->structVersion = 2; deviceInfo->hostApi = hostApiIndex; deviceInfo->maxInputChannels = 0; wmmeDeviceInfo->deviceInputChannelCountIsKnown = 1; deviceInfo->maxOutputChannels = 0; wmmeDeviceInfo->deviceOutputChannelCountIsKnown = 1; deviceInfo->defaultLowInputLatency = defaultLowLatency; deviceInfo->defaultLowOutputLatency = defaultLowLatency; deviceInfo->defaultHighInputLatency = defaultHighLatency; deviceInfo->defaultHighOutputLatency = defaultHighLatency; result = InitializeInputDeviceInfo( winMmeHostApi, wmmeDeviceInfo, winMmeDeviceId, &deviceInfoInitializationSucceeded ); if( result != paNoError ) goto error; if( deviceInfoInitializationSucceeded ){ if( (*hostApi)->info.defaultInputDevice == paNoDevice ){ /* if there is currently no default device, use the first one available */ (*hostApi)->info.defaultInputDevice = (*hostApi)->info.deviceCount; }else if( winMmeDeviceId == waveInPreferredDevice ){ /* set the default device to the system preferred device */ (*hostApi)->info.defaultInputDevice = (*hostApi)->info.deviceCount; } winMmeHostApi->winMmeDeviceIds[ (*hostApi)->info.deviceCount ] = winMmeDeviceId; (*hostApi)->deviceInfos[ (*hostApi)->info.deviceCount ] = deviceInfo; winMmeHostApi->inputDeviceCount++; (*hostApi)->info.deviceCount++; } } } if( outputDeviceCount > 0 ){ /* -1 is the WAVE_MAPPER */ for( i = -1; i < outputDeviceCount; ++i ){ UINT winMmeDeviceId = (UINT)((i==-1) ? WAVE_MAPPER : i); PaWinMmeDeviceInfo *wmmeDeviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ]; PaDeviceInfo *deviceInfo = &wmmeDeviceInfo->inheritedDeviceInfo; deviceInfo->structVersion = 2; deviceInfo->hostApi = hostApiIndex; deviceInfo->maxInputChannels = 0; wmmeDeviceInfo->deviceInputChannelCountIsKnown = 1; deviceInfo->maxOutputChannels = 0; wmmeDeviceInfo->deviceOutputChannelCountIsKnown = 1; deviceInfo->defaultLowInputLatency = defaultLowLatency; deviceInfo->defaultLowOutputLatency = defaultLowLatency; deviceInfo->defaultHighInputLatency = defaultHighLatency; deviceInfo->defaultHighOutputLatency = defaultHighLatency; result = InitializeOutputDeviceInfo( winMmeHostApi, wmmeDeviceInfo, winMmeDeviceId, &deviceInfoInitializationSucceeded ); if( result != paNoError ) goto error; if( deviceInfoInitializationSucceeded ){ if( (*hostApi)->info.defaultOutputDevice == paNoDevice ){ /* if there is currently no default device, use the first one available */ (*hostApi)->info.defaultOutputDevice = (*hostApi)->info.deviceCount; }else if( winMmeDeviceId == waveOutPreferredDevice ){ /* set the default device to the system preferred device */ (*hostApi)->info.defaultOutputDevice = (*hostApi)->info.deviceCount; } winMmeHostApi->winMmeDeviceIds[ (*hostApi)->info.deviceCount ] = winMmeDeviceId; (*hostApi)->deviceInfos[ (*hostApi)->info.deviceCount ] = deviceInfo; winMmeHostApi->outputDeviceCount++; (*hostApi)->info.deviceCount++; } } } } InitializeDefaultDeviceIdsFromEnv( winMmeHostApi ); (*hostApi)->Terminate = Terminate; (*hostApi)->OpenStream = OpenStream; (*hostApi)->IsFormatSupported = IsFormatSupported; PaUtil_InitializeStreamInterface( &winMmeHostApi->callbackStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, GetStreamCpuLoad, PaUtil_DummyRead, PaUtil_DummyWrite, PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable ); PaUtil_InitializeStreamInterface( &winMmeHostApi->blockingStreamInterface, CloseStream, StartStream, StopStream, AbortStream, IsStreamStopped, IsStreamActive, GetStreamTime, PaUtil_DummyGetCpuLoad, ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable ); return result; error: if( winMmeHostApi ) { if( winMmeHostApi->allocations ) { PaUtil_FreeAllAllocations( winMmeHostApi->allocations ); PaUtil_DestroyAllocationGroup( winMmeHostApi->allocations ); } PaUtil_FreeMemory( winMmeHostApi ); } return result; } static void Terminate( struct PaUtilHostApiRepresentation *hostApi ) { PaWinMmeHostApiRepresentation *winMmeHostApi = (PaWinMmeHostApiRepresentation*)hostApi; if( winMmeHostApi->allocations ) { PaUtil_FreeAllAllocations( winMmeHostApi->allocations ); PaUtil_DestroyAllocationGroup( winMmeHostApi->allocations ); } PaUtil_FreeMemory( winMmeHostApi ); } static PaError IsInputChannelCountSupported( PaWinMmeDeviceInfo* deviceInfo, int channelCount ) { PaError result = paNoError; if( channelCount > 0 && deviceInfo->deviceInputChannelCountIsKnown && channelCount > deviceInfo->inheritedDeviceInfo.maxInputChannels ){ result = paInvalidChannelCount; } return result; } static PaError IsOutputChannelCountSupported( PaWinMmeDeviceInfo* deviceInfo, int channelCount ) { PaError result = paNoError; if( channelCount > 0 && deviceInfo->deviceOutputChannelCountIsKnown && channelCount > deviceInfo->inheritedDeviceInfo.maxOutputChannels ){ result = paInvalidChannelCount; } return result; } static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate ) { PaWinMmeHostApiRepresentation *winMmeHostApi = (PaWinMmeHostApiRepresentation*)hostApi; PaDeviceInfo *inputDeviceInfo, *outputDeviceInfo; int inputChannelCount, outputChannelCount; int inputMultipleDeviceChannelCount, outputMultipleDeviceChannelCount; PaSampleFormat inputSampleFormat, outputSampleFormat; PaWinMmeStreamInfo *inputStreamInfo, *outputStreamInfo; UINT winMmeInputDeviceId, winMmeOutputDeviceId; unsigned int i; PaError paerror; /* The calls to QueryFormatSupported below are intended to detect invalid sample rates. If we assume that the channel count and format are OK, then the only thing that could fail is the sample rate. This isn't strictly true, but I can't think of a better way to test that the sample rate is valid. */ if( inputParameters ) { inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; inputStreamInfo = inputParameters->hostApiSpecificStreamInfo; /* all standard sample formats are supported by the buffer adapter, this implementation doesn't support any custom sample formats */ if( inputSampleFormat & paCustomFormat ) return paSampleFormatNotSupported; if( inputParameters->device == paUseHostApiSpecificDeviceSpecification && inputStreamInfo && (inputStreamInfo->flags & paWinMmeUseMultipleDevices) ) { inputMultipleDeviceChannelCount = 0; for( i=0; i< inputStreamInfo->deviceCount; ++i ) { inputMultipleDeviceChannelCount += inputStreamInfo->devices[i].channelCount; inputDeviceInfo = hostApi->deviceInfos[ inputStreamInfo->devices[i].device ]; /* check that input device can support inputChannelCount */ if( inputStreamInfo->devices[i].channelCount < 1 ) return paInvalidChannelCount; paerror = IsInputChannelCountSupported( (PaWinMmeDeviceInfo*)inputDeviceInfo, inputStreamInfo->devices[i].channelCount ); if( paerror != paNoError ) return paerror; /* test for valid sample rate, see comment above */ winMmeInputDeviceId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, inputStreamInfo->devices[i].device ); paerror = QueryFormatSupported( inputDeviceInfo, QueryInputWaveFormatEx, winMmeInputDeviceId, inputStreamInfo->devices[i].channelCount, sampleRate, ((inputStreamInfo) ? inputStreamInfo->flags : 0) ); if( paerror != paNoError ) return paInvalidSampleRate; } if( inputMultipleDeviceChannelCount != inputChannelCount ) return paIncompatibleHostApiSpecificStreamInfo; } else { if( inputStreamInfo && (inputStreamInfo->flags & paWinMmeUseMultipleDevices) ) return paIncompatibleHostApiSpecificStreamInfo; /* paUseHostApiSpecificDeviceSpecification was not supplied as the input device */ inputDeviceInfo = hostApi->deviceInfos[ inputParameters->device ]; /* check that input device can support inputChannelCount */ paerror = IsInputChannelCountSupported( (PaWinMmeDeviceInfo*)inputDeviceInfo, inputChannelCount ); if( paerror != paNoError ) return paerror; /* test for valid sample rate, see comment above */ winMmeInputDeviceId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, inputParameters->device ); paerror = QueryFormatSupported( inputDeviceInfo, QueryInputWaveFormatEx, winMmeInputDeviceId, inputChannelCount, sampleRate, ((inputStreamInfo) ? inputStreamInfo->flags : 0) ); if( paerror != paNoError ) return paInvalidSampleRate; } } if( outputParameters ) { outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; outputStreamInfo = outputParameters->hostApiSpecificStreamInfo; /* all standard sample formats are supported by the buffer adapter, this implementation doesn't support any custom sample formats */ if( outputSampleFormat & paCustomFormat ) return paSampleFormatNotSupported; if( outputParameters->device == paUseHostApiSpecificDeviceSpecification && outputStreamInfo && (outputStreamInfo->flags & paWinMmeUseMultipleDevices) ) { outputMultipleDeviceChannelCount = 0; for( i=0; i< outputStreamInfo->deviceCount; ++i ) { outputMultipleDeviceChannelCount += outputStreamInfo->devices[i].channelCount; outputDeviceInfo = hostApi->deviceInfos[ outputStreamInfo->devices[i].device ]; /* check that output device can support outputChannelCount */ if( outputStreamInfo->devices[i].channelCount < 1 ) return paInvalidChannelCount; paerror = IsOutputChannelCountSupported( (PaWinMmeDeviceInfo*)outputDeviceInfo, outputStreamInfo->devices[i].channelCount ); if( paerror != paNoError ) return paerror; /* test for valid sample rate, see comment above */ winMmeOutputDeviceId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, outputStreamInfo->devices[i].device ); paerror = QueryFormatSupported( outputDeviceInfo, QueryOutputWaveFormatEx, winMmeOutputDeviceId, outputStreamInfo->devices[i].channelCount, sampleRate, ((outputStreamInfo) ? outputStreamInfo->flags : 0) ); if( paerror != paNoError ) return paInvalidSampleRate; } if( outputMultipleDeviceChannelCount != outputChannelCount ) return paIncompatibleHostApiSpecificStreamInfo; } else { if( outputStreamInfo && (outputStreamInfo->flags & paWinMmeUseMultipleDevices) ) return paIncompatibleHostApiSpecificStreamInfo; /* paUseHostApiSpecificDeviceSpecification was not supplied as the output device */ outputDeviceInfo = hostApi->deviceInfos[ outputParameters->device ]; /* check that output device can support outputChannelCount */ paerror = IsOutputChannelCountSupported( (PaWinMmeDeviceInfo*)outputDeviceInfo, outputChannelCount ); if( paerror != paNoError ) return paerror; /* test for valid sample rate, see comment above */ winMmeOutputDeviceId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, outputParameters->device ); paerror = QueryFormatSupported( outputDeviceInfo, QueryOutputWaveFormatEx, winMmeOutputDeviceId, outputChannelCount, sampleRate, ((outputStreamInfo) ? outputStreamInfo->flags : 0) ); if( paerror != paNoError ) return paInvalidSampleRate; } } /* - if a full duplex stream is requested, check that the combination of input and output parameters is supported - check that the device supports sampleRate for mme all we can do is test that the input and output devices support the requested sample rate and number of channels. we cannot test for full duplex compatibility. */ return paFormatIsSupported; } static unsigned long ComputeHostBufferCountForFixedBufferSizeFrames( unsigned long suggestedLatencyFrames, unsigned long hostBufferSizeFrames, unsigned long minimumBufferCount ) { /* Calculate the number of buffers of length hostFramesPerBuffer that fit in suggestedLatencyFrames, rounding up to the next integer. The value (hostBufferSizeFrames - 1) below is to ensure the buffer count is rounded up. */ unsigned long resultBufferCount = ((suggestedLatencyFrames + (hostBufferSizeFrames - 1)) / hostBufferSizeFrames); /* We always need one extra buffer for processing while the rest are queued/playing. i.e. latency is framesPerBuffer * (bufferCount - 1) */ resultBufferCount += 1; if( resultBufferCount < minimumBufferCount ) /* clamp to minimum buffer count */ resultBufferCount = minimumBufferCount; return resultBufferCount; } static unsigned long ComputeHostBufferSizeGivenHardUpperLimit( unsigned long userFramesPerBuffer, unsigned long absoluteMaximumBufferSizeFrames ) { static unsigned long primes_[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 0 }; /* zero terminated */ unsigned long result = userFramesPerBuffer; int i; assert( absoluteMaximumBufferSizeFrames > 67 ); /* assume maximum is large and we're only factoring by small primes */ /* search for the largest integer factor of userFramesPerBuffer less than or equal to absoluteMaximumBufferSizeFrames */ /* repeatedly divide by smallest prime factors until a buffer size smaller than absoluteMaximumBufferSizeFrames is found */ while( result > absoluteMaximumBufferSizeFrames ){ /* search for the smallest prime factor of result */ for( i=0; primes_[i] != 0; ++i ) { unsigned long p = primes_[i]; unsigned long divided = result / p; if( divided*p == result ) { result = divided; break; /* continue with outer while loop */ } } if( primes_[i] == 0 ) { /* loop failed to find a prime factor, return an approximate result */ unsigned long d = (userFramesPerBuffer + (absoluteMaximumBufferSizeFrames-1)) / absoluteMaximumBufferSizeFrames; return userFramesPerBuffer / d; } } return result; } static PaError SelectHostBufferSizeFramesAndHostBufferCount( unsigned long suggestedLatencyFrames, unsigned long userFramesPerBuffer, unsigned long minimumBufferCount, unsigned long preferredMaximumBufferSizeFrames, /* try not to exceed this. for example, don't exceed when coalescing buffers */ unsigned long absoluteMaximumBufferSizeFrames, /* never exceed this, a hard limit */ unsigned long *hostBufferSizeFrames, unsigned long *hostBufferCount ) { unsigned long effectiveUserFramesPerBuffer; unsigned long numberOfUserBuffersPerHostBuffer; if( userFramesPerBuffer == paFramesPerBufferUnspecified ){ effectiveUserFramesPerBuffer = PA_MME_HOST_BUFFER_GRANULARITY_FRAMES_WHEN_UNSPECIFIED_; }else{ if( userFramesPerBuffer > absoluteMaximumBufferSizeFrames ){ /* user has requested a user buffer that's larger than absoluteMaximumBufferSizeFrames. try to choose a buffer size that is equal or smaller than absoluteMaximumBufferSizeFrames but is also an integer factor of userFramesPerBuffer, so as to distribute computation evenly. the buffer processor will handle the block adaption between host and user buffer sizes. see http://www.portaudio.com/trac/ticket/189 for discussion. */ effectiveUserFramesPerBuffer = ComputeHostBufferSizeGivenHardUpperLimit( userFramesPerBuffer, absoluteMaximumBufferSizeFrames ); assert( effectiveUserFramesPerBuffer <= absoluteMaximumBufferSizeFrames ); /* try to ensure that duration of host buffering is at least as large as duration of user buffer. */ if( suggestedLatencyFrames < userFramesPerBuffer ) suggestedLatencyFrames = userFramesPerBuffer; }else{ effectiveUserFramesPerBuffer = userFramesPerBuffer; } } /* compute a host buffer count based on suggestedLatencyFrames and our granularity */ *hostBufferSizeFrames = effectiveUserFramesPerBuffer; *hostBufferCount = ComputeHostBufferCountForFixedBufferSizeFrames( suggestedLatencyFrames, *hostBufferSizeFrames, minimumBufferCount ); if( *hostBufferSizeFrames >= userFramesPerBuffer ) { /* If there are too many host buffers we would like to coalesce them by packing an integer number of user buffers into each host buffer. We try to coalesce such that hostBufferCount will lie between PA_MME_TARGET_HOST_BUFFER_COUNT_ and (PA_MME_TARGET_HOST_BUFFER_COUNT_*2)-1. We limit coalescing to avoid exceeding either absoluteMaximumBufferSizeFrames and preferredMaximumBufferSizeFrames. First, compute a coalescing factor: the number of user buffers per host buffer. The goal is to achieve PA_MME_TARGET_HOST_BUFFER_COUNT_ total buffer count. Since our latency is computed based on (*hostBufferCount - 1) we compute a coalescing factor based on (*hostBufferCount - 1) and (PA_MME_TARGET_HOST_BUFFER_COUNT_-1). The + (PA_MME_TARGET_HOST_BUFFER_COUNT_-2) term below is intended to round up. */ numberOfUserBuffersPerHostBuffer = ((*hostBufferCount - 1) + (PA_MME_TARGET_HOST_BUFFER_COUNT_-2)) / (PA_MME_TARGET_HOST_BUFFER_COUNT_ - 1); if( numberOfUserBuffersPerHostBuffer > 1 ) { unsigned long maxCoalescedBufferSizeFrames = (absoluteMaximumBufferSizeFrames < preferredMaximumBufferSizeFrames) /* minimum of our limits */ ? absoluteMaximumBufferSizeFrames : preferredMaximumBufferSizeFrames; unsigned long maxUserBuffersPerHostBuffer = maxCoalescedBufferSizeFrames / effectiveUserFramesPerBuffer; /* don't coalesce more than this */ if( numberOfUserBuffersPerHostBuffer > maxUserBuffersPerHostBuffer ) numberOfUserBuffersPerHostBuffer = maxUserBuffersPerHostBuffer; *hostBufferSizeFrames = effectiveUserFramesPerBuffer * numberOfUserBuffersPerHostBuffer; /* recompute hostBufferCount to approximate suggestedLatencyFrames now that hostBufferSizeFrames is larger */ *hostBufferCount = ComputeHostBufferCountForFixedBufferSizeFrames( suggestedLatencyFrames, *hostBufferSizeFrames, minimumBufferCount ); } } return paNoError; } static PaError CalculateMaxHostSampleFrameSizeBytes( int channelCount, PaSampleFormat hostSampleFormat, const PaWinMmeStreamInfo *streamInfo, int *hostSampleFrameSizeBytes ) { unsigned int i; /* PA WMME streams may aggregate multiple WMME devices. When the stream addresses more than one device in a single direction, maxDeviceChannelCount is the maximum number of channels used by a single device. */ int maxDeviceChannelCount = channelCount; int hostSampleSizeBytes = Pa_GetSampleSize( hostSampleFormat ); if( hostSampleSizeBytes < 0 ) { return hostSampleSizeBytes; /* the value of hostSampleSize here is an error code, not a sample size */ } if( streamInfo && ( streamInfo->flags & paWinMmeUseMultipleDevices ) ) { maxDeviceChannelCount = streamInfo->devices[0].channelCount; for( i=1; i< streamInfo->deviceCount; ++i ) { if( streamInfo->devices[i].channelCount > maxDeviceChannelCount ) maxDeviceChannelCount = streamInfo->devices[i].channelCount; } } *hostSampleFrameSizeBytes = hostSampleSizeBytes * maxDeviceChannelCount; return paNoError; } /* CalculateBufferSettings() fills the framesPerHostInputBuffer, hostInputBufferCount, framesPerHostOutputBuffer and hostOutputBufferCount parameters based on the values of the other parameters. */ static PaError CalculateBufferSettings( unsigned long *hostFramesPerInputBuffer, unsigned long *hostInputBufferCount, unsigned long *hostFramesPerOutputBuffer, unsigned long *hostOutputBufferCount, int inputChannelCount, PaSampleFormat hostInputSampleFormat, PaTime suggestedInputLatency, const PaWinMmeStreamInfo *inputStreamInfo, int outputChannelCount, PaSampleFormat hostOutputSampleFormat, PaTime suggestedOutputLatency, const PaWinMmeStreamInfo *outputStreamInfo, double sampleRate, unsigned long userFramesPerBuffer ) { PaError result = paNoError; if( inputChannelCount > 0 ) /* stream has input */ { int hostInputFrameSizeBytes; result = CalculateMaxHostSampleFrameSizeBytes( inputChannelCount, hostInputSampleFormat, inputStreamInfo, &hostInputFrameSizeBytes ); if( result != paNoError ) goto error; if( inputStreamInfo && ( inputStreamInfo->flags & paWinMmeUseLowLevelLatencyParameters ) ) { /* input - using low level latency parameters if provided */ if( inputStreamInfo->bufferCount <= 0 || inputStreamInfo->framesPerBuffer <= 0 ) { result = paIncompatibleHostApiSpecificStreamInfo; goto error; } *hostFramesPerInputBuffer = inputStreamInfo->framesPerBuffer; *hostInputBufferCount = inputStreamInfo->bufferCount; } else { /* input - not using low level latency parameters, so compute hostFramesPerInputBuffer and hostInputBufferCount based on userFramesPerBuffer and suggestedInputLatency. */ unsigned long minimumBufferCount = (outputChannelCount > 0) ? PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_ : PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_HALF_DUPLEX_; result = SelectHostBufferSizeFramesAndHostBufferCount( (unsigned long)(suggestedInputLatency * sampleRate), /* (truncate) */ userFramesPerBuffer, minimumBufferCount, (unsigned long)(PA_MME_MAX_HOST_BUFFER_SECS_ * sampleRate), /* in frames. preferred maximum */ (PA_MME_MAX_HOST_BUFFER_BYTES_ / hostInputFrameSizeBytes), /* in frames. a hard limit. note truncation due to division is intentional here to limit max bytes */ hostFramesPerInputBuffer, hostInputBufferCount ); if( result != paNoError ) goto error; } } else { *hostFramesPerInputBuffer = 0; *hostInputBufferCount = 0; } if( outputChannelCount > 0 ) /* stream has output */ { if( outputStreamInfo && ( outputStreamInfo->flags & paWinMmeUseLowLevelLatencyParameters ) ) { /* output - using low level latency parameters */ if( outputStreamInfo->bufferCount <= 0 || outputStreamInfo->framesPerBuffer <= 0 ) { result = paIncompatibleHostApiSpecificStreamInfo; goto error; } *hostFramesPerOutputBuffer = outputStreamInfo->framesPerBuffer; *hostOutputBufferCount = outputStreamInfo->bufferCount; if( inputChannelCount > 0 ) /* full duplex */ { /* harmonize hostFramesPerInputBuffer and hostFramesPerOutputBuffer */ if( *hostFramesPerInputBuffer != *hostFramesPerOutputBuffer ) { if( inputStreamInfo && ( inputStreamInfo->flags & paWinMmeUseLowLevelLatencyParameters ) ) { /* a custom StreamInfo was used for specifying both input and output buffer sizes. We require that the larger buffer size must be a multiple of the smaller buffer size */ if( *hostFramesPerInputBuffer < *hostFramesPerOutputBuffer ) { if( *hostFramesPerOutputBuffer % *hostFramesPerInputBuffer != 0 ) { result = paIncompatibleHostApiSpecificStreamInfo; goto error; } } else { assert( *hostFramesPerInputBuffer > *hostFramesPerOutputBuffer ); if( *hostFramesPerInputBuffer % *hostFramesPerOutputBuffer != 0 ) { result = paIncompatibleHostApiSpecificStreamInfo; goto error; } } } else { /* a custom StreamInfo was not used for specifying the input buffer size, so use the output buffer size, and approximately the suggested input latency. */ *hostFramesPerInputBuffer = *hostFramesPerOutputBuffer; *hostInputBufferCount = ComputeHostBufferCountForFixedBufferSizeFrames( (unsigned long)(suggestedInputLatency * sampleRate), *hostFramesPerInputBuffer, PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_ ); } } } } else { /* output - no low level latency parameters, so compute hostFramesPerOutputBuffer and hostOutputBufferCount based on userFramesPerBuffer and suggestedOutputLatency. */ int hostOutputFrameSizeBytes; result = CalculateMaxHostSampleFrameSizeBytes( outputChannelCount, hostOutputSampleFormat, outputStreamInfo, &hostOutputFrameSizeBytes ); if( result != paNoError ) goto error; /* compute the output buffer size and count */ result = SelectHostBufferSizeFramesAndHostBufferCount( (unsigned long)(suggestedOutputLatency * sampleRate), /* (truncate) */ userFramesPerBuffer, PA_MME_MIN_HOST_OUTPUT_BUFFER_COUNT_, (unsigned long)(PA_MME_MAX_HOST_BUFFER_SECS_ * sampleRate), /* in frames. preferred maximum */ (PA_MME_MAX_HOST_BUFFER_BYTES_ / hostOutputFrameSizeBytes), /* in frames. a hard limit. note truncation due to division is intentional here to limit max bytes */ hostFramesPerOutputBuffer, hostOutputBufferCount ); if( result != paNoError ) goto error; if( inputChannelCount > 0 ) /* full duplex */ { /* harmonize hostFramesPerInputBuffer and hostFramesPerOutputBuffer */ /* ensure that both input and output buffer sizes are the same. if they don't match at this stage, choose the smallest one and use that for input and output and recompute the corresponding buffer count accordingly. */ if( *hostFramesPerOutputBuffer != *hostFramesPerInputBuffer ) { if( hostFramesPerInputBuffer < hostFramesPerOutputBuffer ) { *hostFramesPerOutputBuffer = *hostFramesPerInputBuffer; *hostOutputBufferCount = ComputeHostBufferCountForFixedBufferSizeFrames( (unsigned long)(suggestedOutputLatency * sampleRate), *hostOutputBufferCount, PA_MME_MIN_HOST_OUTPUT_BUFFER_COUNT_ ); } else { *hostFramesPerInputBuffer = *hostFramesPerOutputBuffer; *hostInputBufferCount = ComputeHostBufferCountForFixedBufferSizeFrames( (unsigned long)(suggestedInputLatency * sampleRate), *hostFramesPerInputBuffer, PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_ ); } } } } } else { *hostFramesPerOutputBuffer = 0; *hostOutputBufferCount = 0; } error: return result; } typedef struct { HANDLE bufferEvent; void *waveHandles; unsigned int deviceCount; /* unsigned int channelCount; */ WAVEHDR **waveHeaders; /* waveHeaders[device][buffer] */ unsigned int bufferCount; unsigned int currentBufferIndex; unsigned int framesPerBuffer; unsigned int framesUsedInCurrentBuffer; }PaWinMmeSingleDirectionHandlesAndBuffers; /* prototypes for functions operating on PaWinMmeSingleDirectionHandlesAndBuffers */ static void InitializeSingleDirectionHandlesAndBuffers( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers ); static PaError InitializeWaveHandles( PaWinMmeHostApiRepresentation *winMmeHostApi, PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, unsigned long winMmeSpecificFlags, unsigned long bytesPerHostSample, double sampleRate, PaWinMmeDeviceAndChannelCount *devices, unsigned int deviceCount, PaWinWaveFormatChannelMask channelMask, int isInput ); static PaError TerminateWaveHandles( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, int isInput, int currentlyProcessingAnError ); static PaError InitializeWaveHeaders( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, unsigned long hostBufferCount, PaSampleFormat hostSampleFormat, unsigned long framesPerHostBuffer, PaWinMmeDeviceAndChannelCount *devices, int isInput ); static void TerminateWaveHeaders( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, int isInput ); static void InitializeSingleDirectionHandlesAndBuffers( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers ) { handlesAndBuffers->bufferEvent = 0; handlesAndBuffers->waveHandles = 0; handlesAndBuffers->deviceCount = 0; handlesAndBuffers->waveHeaders = 0; handlesAndBuffers->bufferCount = 0; } static PaError InitializeWaveHandles( PaWinMmeHostApiRepresentation *winMmeHostApi, PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, unsigned long winMmeSpecificFlags, unsigned long bytesPerHostSample, double sampleRate, PaWinMmeDeviceAndChannelCount *devices, unsigned int deviceCount, PaWinWaveFormatChannelMask channelMask, int isInput ) { PaError result; MMRESULT mmresult; signed int i, j; PaSampleFormat sampleFormat; int waveFormatTag; /* for error cleanup we expect that InitializeSingleDirectionHandlesAndBuffers() has already been called to zero some fields */ result = CreateEventWithPaError( &handlesAndBuffers->bufferEvent, NULL, FALSE, FALSE, NULL ); if( result != paNoError ) goto error; if( isInput ) handlesAndBuffers->waveHandles = (void*)PaUtil_AllocateMemory( sizeof(HWAVEIN) * deviceCount ); else handlesAndBuffers->waveHandles = (void*)PaUtil_AllocateMemory( sizeof(HWAVEOUT) * deviceCount ); if( !handlesAndBuffers->waveHandles ) { result = paInsufficientMemory; goto error; } handlesAndBuffers->deviceCount = deviceCount; for( i = 0; i < (signed int)deviceCount; ++i ) { if( isInput ) ((HWAVEIN*)handlesAndBuffers->waveHandles)[i] = 0; else ((HWAVEOUT*)handlesAndBuffers->waveHandles)[i] = 0; } /* @todo at the moment we only use 16 bit sample format */ sampleFormat = paInt16; waveFormatTag = SampleFormatAndWinWmmeSpecificFlagsToLinearWaveFormatTag( sampleFormat, winMmeSpecificFlags ); for( i = 0; i < (signed int)deviceCount; ++i ) { PaWinWaveFormat waveFormat; UINT winMmeDeviceId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, devices[i].device ); /* @todo: consider providing a flag or #define to not try waveformat extensible this could just initialize j to 1 the first time round. */ for( j = 0; j < 2; ++j ) { switch(j){ case 0: /* first, attempt to open the device using WAVEFORMATEXTENSIBLE, if this fails we fall back to WAVEFORMATEX */ PaWin_InitializeWaveFormatExtensible( &waveFormat, devices[i].channelCount, sampleFormat, waveFormatTag, sampleRate, channelMask ); break; case 1: /* retry with WAVEFORMATEX */ PaWin_InitializeWaveFormatEx( &waveFormat, devices[i].channelCount, sampleFormat, waveFormatTag, sampleRate ); break; } /* REVIEW: consider not firing an event for input when a full duplex stream is being used. this would probably depend on the neverDropInput flag. */ if( isInput ) { mmresult = waveInOpen( &((HWAVEIN*)handlesAndBuffers->waveHandles)[i], winMmeDeviceId, (WAVEFORMATEX*)&waveFormat, (DWORD_PTR)handlesAndBuffers->bufferEvent, (DWORD_PTR)0, CALLBACK_EVENT ); } else { mmresult = waveOutOpen( &((HWAVEOUT*)handlesAndBuffers->waveHandles)[i], winMmeDeviceId, (WAVEFORMATEX*)&waveFormat, (DWORD_PTR)handlesAndBuffers->bufferEvent, (DWORD_PTR)0, CALLBACK_EVENT ); } if( mmresult == MMSYSERR_NOERROR ) { break; /* success */ } else if( j == 0 ) { continue; /* try again with WAVEFORMATEX */ } else { switch( mmresult ) { case MMSYSERR_ALLOCATED: /* Specified resource is already allocated. */ result = paDeviceUnavailable; break; case MMSYSERR_NODRIVER: /* No device driver is present. */ result = paDeviceUnavailable; break; case MMSYSERR_NOMEM: /* Unable to allocate or lock memory. */ result = paInsufficientMemory; break; case MMSYSERR_BADDEVICEID: /* Specified device identifier is out of range. */ /* falls through */ case WAVERR_BADFORMAT: /* Attempted to open with an unsupported waveform-audio format. */ /* This can also occur if we try to open the device with an unsupported * number of channels. This is attempted when device*ChannelCountIsKnown is * set to 0. */ /* falls through */ default: result = paUnanticipatedHostError; if( isInput ) { PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); } else { PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); } } goto error; } } } return result; error: TerminateWaveHandles( handlesAndBuffers, isInput, 1 /* currentlyProcessingAnError */ ); return result; } static PaError TerminateWaveHandles( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, int isInput, int currentlyProcessingAnError ) { PaError result = paNoError; MMRESULT mmresult; signed int i; if( handlesAndBuffers->waveHandles ) { for( i = handlesAndBuffers->deviceCount-1; i >= 0; --i ) { if( isInput ) { if( ((HWAVEIN*)handlesAndBuffers->waveHandles)[i] ) mmresult = waveInClose( ((HWAVEIN*)handlesAndBuffers->waveHandles)[i] ); else mmresult = MMSYSERR_NOERROR; } else { if( ((HWAVEOUT*)handlesAndBuffers->waveHandles)[i] ) mmresult = waveOutClose( ((HWAVEOUT*)handlesAndBuffers->waveHandles)[i] ); else mmresult = MMSYSERR_NOERROR; } if( mmresult != MMSYSERR_NOERROR && !currentlyProcessingAnError ) /* don't update the error state if we're already processing an error */ { result = paUnanticipatedHostError; if( isInput ) { PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); } else { PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); } /* note that we don't break here, we try to continue closing devices */ } } PaUtil_FreeMemory( handlesAndBuffers->waveHandles ); handlesAndBuffers->waveHandles = 0; } if( handlesAndBuffers->bufferEvent ) { result = CloseHandleWithPaError( handlesAndBuffers->bufferEvent ); handlesAndBuffers->bufferEvent = 0; } return result; } static PaError InitializeWaveHeaders( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, unsigned long hostBufferCount, PaSampleFormat hostSampleFormat, unsigned long framesPerHostBuffer, PaWinMmeDeviceAndChannelCount *devices, int isInput ) { PaError result = paNoError; MMRESULT mmresult; WAVEHDR *deviceWaveHeaders; signed int i, j; /* for error cleanup we expect that InitializeSingleDirectionHandlesAndBuffers() has already been called to zero some fields */ /* allocate an array of pointers to arrays of wave headers, one array of wave headers per device */ handlesAndBuffers->waveHeaders = (WAVEHDR**)PaUtil_AllocateMemory( sizeof(WAVEHDR*) * handlesAndBuffers->deviceCount ); if( !handlesAndBuffers->waveHeaders ) { result = paInsufficientMemory; goto error; } for( i = 0; i < (signed int)handlesAndBuffers->deviceCount; ++i ) handlesAndBuffers->waveHeaders[i] = 0; handlesAndBuffers->bufferCount = hostBufferCount; for( i = 0; i < (signed int)handlesAndBuffers->deviceCount; ++i ) { int bufferBytes = Pa_GetSampleSize( hostSampleFormat ) * framesPerHostBuffer * devices[i].channelCount; if( bufferBytes < 0 ) { result = paInternalError; goto error; } /* Allocate an array of wave headers for device i */ deviceWaveHeaders = (WAVEHDR *) PaUtil_AllocateMemory( sizeof(WAVEHDR)*hostBufferCount ); if( !deviceWaveHeaders ) { result = paInsufficientMemory; goto error; } for( j=0; j < (signed int)hostBufferCount; ++j ) deviceWaveHeaders[j].lpData = 0; handlesAndBuffers->waveHeaders[i] = deviceWaveHeaders; /* Allocate a buffer for each wave header */ for( j=0; j < (signed int)hostBufferCount; ++j ) { deviceWaveHeaders[j].lpData = (char *)PaUtil_AllocateMemory( bufferBytes ); if( !deviceWaveHeaders[j].lpData ) { result = paInsufficientMemory; goto error; } deviceWaveHeaders[j].dwBufferLength = bufferBytes; deviceWaveHeaders[j].dwUser = 0xFFFFFFFF; /* indicates that *PrepareHeader() has not yet been called, for error clean up code */ if( isInput ) { mmresult = waveInPrepareHeader( ((HWAVEIN*)handlesAndBuffers->waveHandles)[i], &deviceWaveHeaders[j], sizeof(WAVEHDR) ); if( mmresult != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); goto error; } } else /* output */ { mmresult = waveOutPrepareHeader( ((HWAVEOUT*)handlesAndBuffers->waveHandles)[i], &deviceWaveHeaders[j], sizeof(WAVEHDR) ); if( mmresult != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); goto error; } } deviceWaveHeaders[j].dwUser = devices[i].channelCount; } } return result; error: TerminateWaveHeaders( handlesAndBuffers, isInput ); return result; } static void TerminateWaveHeaders( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, int isInput ) { signed int i, j; WAVEHDR *deviceWaveHeaders; if( handlesAndBuffers->waveHeaders ) { for( i = handlesAndBuffers->deviceCount-1; i >= 0 ; --i ) { deviceWaveHeaders = handlesAndBuffers->waveHeaders[i]; /* wave headers for device i */ if( deviceWaveHeaders ) { for( j = handlesAndBuffers->bufferCount-1; j >= 0; --j ) { if( deviceWaveHeaders[j].lpData ) { if( deviceWaveHeaders[j].dwUser != 0xFFFFFFFF ) { if( isInput ) waveInUnprepareHeader( ((HWAVEIN*)handlesAndBuffers->waveHandles)[i], &deviceWaveHeaders[j], sizeof(WAVEHDR) ); else waveOutUnprepareHeader( ((HWAVEOUT*)handlesAndBuffers->waveHandles)[i], &deviceWaveHeaders[j], sizeof(WAVEHDR) ); } PaUtil_FreeMemory( deviceWaveHeaders[j].lpData ); } } PaUtil_FreeMemory( deviceWaveHeaders ); } } PaUtil_FreeMemory( handlesAndBuffers->waveHeaders ); handlesAndBuffers->waveHeaders = 0; } } /* PaWinMmeStream - a stream data structure specifically for this implementation */ /* note that struct PaWinMmeStream is typedeffed to PaWinMmeStream above. */ struct PaWinMmeStream { PaUtilStreamRepresentation streamRepresentation; PaUtilCpuLoadMeasurer cpuLoadMeasurer; PaUtilBufferProcessor bufferProcessor; int primeStreamUsingCallback; PaWinMmeSingleDirectionHandlesAndBuffers input; PaWinMmeSingleDirectionHandlesAndBuffers output; /* Processing thread management -------------- */ HANDLE abortEvent; HANDLE processingThread; PA_THREAD_ID processingThreadId; char throttleProcessingThreadOnOverload; /* 0 -> don't throtte, non-0 -> throttle */ int processingThreadPriority; int highThreadPriority; int throttledThreadPriority; unsigned long throttledSleepMsecs; int isStopped; volatile int isActive; volatile int stopProcessing; /* stop thread once existing buffers have been returned */ volatile int abortProcessing; /* stop thread immediately */ DWORD allBuffersDurationMs; /* used to calculate timeouts */ }; /* updates deviceCount if PaWinMmeUseMultipleDevices is used */ static PaError ValidateWinMmeSpecificStreamInfo( const PaStreamParameters *streamParameters, const PaWinMmeStreamInfo *streamInfo, unsigned long *winMmeSpecificFlags, char *throttleProcessingThreadOnOverload, unsigned long *deviceCount ) { if( streamInfo ) { if( streamInfo->size != sizeof( PaWinMmeStreamInfo ) || streamInfo->version != 1 ) { return paIncompatibleHostApiSpecificStreamInfo; } *winMmeSpecificFlags = streamInfo->flags; if( streamInfo->flags & paWinMmeDontThrottleOverloadedProcessingThread ) *throttleProcessingThreadOnOverload = 0; if( streamInfo->flags & paWinMmeUseMultipleDevices ) { if( streamParameters->device != paUseHostApiSpecificDeviceSpecification ) return paInvalidDevice; *deviceCount = streamInfo->deviceCount; } } return paNoError; } static PaError RetrieveDevicesFromStreamParameters( struct PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *streamParameters, const PaWinMmeStreamInfo *streamInfo, PaWinMmeDeviceAndChannelCount *devices, unsigned long deviceCount ) { PaError result = paNoError; unsigned int i; int totalChannelCount; PaDeviceIndex hostApiDevice; if( streamInfo && streamInfo->flags & paWinMmeUseMultipleDevices ) { totalChannelCount = 0; for( i=0; i < deviceCount; ++i ) { /* validate that the device number is within range */ result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice, streamInfo->devices[i].device, hostApi ); if( result != paNoError ) return result; devices[i].device = hostApiDevice; devices[i].channelCount = streamInfo->devices[i].channelCount; totalChannelCount += devices[i].channelCount; } if( totalChannelCount != streamParameters->channelCount ) { /* channelCount must match total channels specified by multiple devices */ return paInvalidChannelCount; /* REVIEW use of this error code */ } } else { devices[0].device = streamParameters->device; devices[0].channelCount = streamParameters->channelCount; } return result; } static PaError ValidateInputChannelCounts( struct PaUtilHostApiRepresentation *hostApi, PaWinMmeDeviceAndChannelCount *devices, unsigned long deviceCount ) { unsigned int i; PaWinMmeDeviceInfo *inputDeviceInfo; PaError paerror; for( i=0; i < deviceCount; ++i ) { if( devices[i].channelCount < 1 ) return paInvalidChannelCount; inputDeviceInfo = (PaWinMmeDeviceInfo*)hostApi->deviceInfos[ devices[i].device ]; paerror = IsInputChannelCountSupported( inputDeviceInfo, devices[i].channelCount ); if( paerror != paNoError ) return paerror; } return paNoError; } static PaError ValidateOutputChannelCounts( struct PaUtilHostApiRepresentation *hostApi, PaWinMmeDeviceAndChannelCount *devices, unsigned long deviceCount ) { unsigned int i; PaWinMmeDeviceInfo *outputDeviceInfo; PaError paerror; for( i=0; i < deviceCount; ++i ) { if( devices[i].channelCount < 1 ) return paInvalidChannelCount; outputDeviceInfo = (PaWinMmeDeviceInfo*)hostApi->deviceInfos[ devices[i].device ]; paerror = IsOutputChannelCountSupported( outputDeviceInfo, devices[i].channelCount ); if( paerror != paNoError ) return paerror; } return paNoError; } /* the following macros are intended to improve the readability of the following code */ #define PA_IS_INPUT_STREAM_( stream ) ( stream ->input.waveHandles ) #define PA_IS_OUTPUT_STREAM_( stream ) ( stream ->output.waveHandles ) #define PA_IS_FULL_DUPLEX_STREAM_( stream ) ( stream ->input.waveHandles && stream ->output.waveHandles ) #define PA_IS_HALF_DUPLEX_STREAM_( stream ) ( !(stream ->input.waveHandles && stream ->output.waveHandles) ) static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStream** s, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData ) { PaError result; PaWinMmeHostApiRepresentation *winMmeHostApi = (PaWinMmeHostApiRepresentation*)hostApi; PaWinMmeStream *stream = 0; int bufferProcessorIsInitialized = 0; int streamRepresentationIsInitialized = 0; PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat; int inputChannelCount, outputChannelCount; PaSampleFormat inputSampleFormat, outputSampleFormat; double suggestedInputLatency, suggestedOutputLatency; PaWinMmeStreamInfo *inputStreamInfo, *outputStreamInfo; PaWinWaveFormatChannelMask inputChannelMask, outputChannelMask; unsigned long framesPerHostInputBuffer; unsigned long hostInputBufferCount; unsigned long framesPerHostOutputBuffer; unsigned long hostOutputBufferCount; unsigned long framesPerBufferProcessorCall; PaWinMmeDeviceAndChannelCount *inputDevices = 0; /* contains all devices and channel counts as local host api ids, even when PaWinMmeUseMultipleDevices is not used */ unsigned long winMmeSpecificInputFlags = 0; unsigned long inputDeviceCount = 0; PaWinMmeDeviceAndChannelCount *outputDevices = 0; unsigned long winMmeSpecificOutputFlags = 0; unsigned long outputDeviceCount = 0; /* contains all devices and channel counts as local host api ids, even when PaWinMmeUseMultipleDevices is not used */ char throttleProcessingThreadOnOverload = 1; if( inputParameters ) { inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; suggestedInputLatency = inputParameters->suggestedLatency; inputDeviceCount = 1; /* validate input hostApiSpecificStreamInfo */ inputStreamInfo = (PaWinMmeStreamInfo*)inputParameters->hostApiSpecificStreamInfo; result = ValidateWinMmeSpecificStreamInfo( inputParameters, inputStreamInfo, &winMmeSpecificInputFlags, &throttleProcessingThreadOnOverload, &inputDeviceCount ); if( result != paNoError ) return result; inputDevices = (PaWinMmeDeviceAndChannelCount*)alloca( sizeof(PaWinMmeDeviceAndChannelCount) * inputDeviceCount ); if( !inputDevices ) return paInsufficientMemory; result = RetrieveDevicesFromStreamParameters( hostApi, inputParameters, inputStreamInfo, inputDevices, inputDeviceCount ); if( result != paNoError ) return result; result = ValidateInputChannelCounts( hostApi, inputDevices, inputDeviceCount ); if( result != paNoError ) return result; hostInputSampleFormat = PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, inputSampleFormat ); if( inputDeviceCount != 1 ){ /* always use direct speakers when using multi-device multichannel mode */ inputChannelMask = PAWIN_SPEAKER_DIRECTOUT; } else { if( inputStreamInfo && inputStreamInfo->flags & paWinMmeUseChannelMask ) inputChannelMask = inputStreamInfo->channelMask; else inputChannelMask = PaWin_DefaultChannelMask( inputDevices[0].channelCount ); } } else { inputChannelCount = 0; inputSampleFormat = 0; suggestedInputLatency = 0.; inputStreamInfo = 0; hostInputSampleFormat = 0; } if( outputParameters ) { outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; suggestedOutputLatency = outputParameters->suggestedLatency; outputDeviceCount = 1; /* validate output hostApiSpecificStreamInfo */ outputStreamInfo = (PaWinMmeStreamInfo*)outputParameters->hostApiSpecificStreamInfo; result = ValidateWinMmeSpecificStreamInfo( outputParameters, outputStreamInfo, &winMmeSpecificOutputFlags, &throttleProcessingThreadOnOverload, &outputDeviceCount ); if( result != paNoError ) return result; outputDevices = (PaWinMmeDeviceAndChannelCount*)alloca( sizeof(PaWinMmeDeviceAndChannelCount) * outputDeviceCount ); if( !outputDevices ) return paInsufficientMemory; result = RetrieveDevicesFromStreamParameters( hostApi, outputParameters, outputStreamInfo, outputDevices, outputDeviceCount ); if( result != paNoError ) return result; result = ValidateOutputChannelCounts( hostApi, outputDevices, outputDeviceCount ); if( result != paNoError ) return result; hostOutputSampleFormat = PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, outputSampleFormat ); if( outputDeviceCount != 1 ){ /* always use direct speakers when using multi-device multichannel mode */ outputChannelMask = PAWIN_SPEAKER_DIRECTOUT; } else { if( outputStreamInfo && outputStreamInfo->flags & paWinMmeUseChannelMask ) outputChannelMask = outputStreamInfo->channelMask; else outputChannelMask = PaWin_DefaultChannelMask( outputDevices[0].channelCount ); } } else { outputChannelCount = 0; outputSampleFormat = 0; outputStreamInfo = 0; hostOutputSampleFormat = 0; suggestedOutputLatency = 0.; } /* IMPLEMENT ME: - alter sampleRate to a close allowable rate if possible / necessary */ /* validate platform specific flags */ if( (streamFlags & paPlatformSpecificFlags) != 0 ) return paInvalidFlag; /* unexpected platform specific flag */ /* always disable clipping and dithering if we are outputting a raw spdif stream */ if( (winMmeSpecificOutputFlags & paWinMmeWaveFormatDolbyAc3Spdif) || (winMmeSpecificOutputFlags & paWinMmeWaveFormatWmaSpdif) ){ streamFlags = streamFlags | paClipOff | paDitherOff; } result = CalculateBufferSettings( &framesPerHostInputBuffer, &hostInputBufferCount, &framesPerHostOutputBuffer, &hostOutputBufferCount, inputChannelCount, hostInputSampleFormat, suggestedInputLatency, inputStreamInfo, outputChannelCount, hostOutputSampleFormat, suggestedOutputLatency, outputStreamInfo, sampleRate, framesPerBuffer ); if( result != paNoError ) goto error; stream = (PaWinMmeStream*)PaUtil_AllocateMemory( sizeof(PaWinMmeStream) ); if( !stream ) { result = paInsufficientMemory; goto error; } InitializeSingleDirectionHandlesAndBuffers( &stream->input ); InitializeSingleDirectionHandlesAndBuffers( &stream->output ); stream->abortEvent = 0; stream->processingThread = 0; stream->throttleProcessingThreadOnOverload = throttleProcessingThreadOnOverload; PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation, ( (streamCallback) ? &winMmeHostApi->callbackStreamInterface : &winMmeHostApi->blockingStreamInterface ), streamCallback, userData ); streamRepresentationIsInitialized = 1; PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate ); if( inputParameters && outputParameters ) /* full duplex */ { if( framesPerHostInputBuffer < framesPerHostOutputBuffer ) { assert( (framesPerHostOutputBuffer % framesPerHostInputBuffer) == 0 ); /* CalculateBufferSettings() should guarantee this condition */ framesPerBufferProcessorCall = framesPerHostInputBuffer; } else { assert( (framesPerHostInputBuffer % framesPerHostOutputBuffer) == 0 ); /* CalculateBufferSettings() should guarantee this condition */ framesPerBufferProcessorCall = framesPerHostOutputBuffer; } } else if( inputParameters ) { framesPerBufferProcessorCall = framesPerHostInputBuffer; } else if( outputParameters ) { framesPerBufferProcessorCall = framesPerHostOutputBuffer; } stream->input.framesPerBuffer = framesPerHostInputBuffer; stream->output.framesPerBuffer = framesPerHostOutputBuffer; result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor, inputChannelCount, inputSampleFormat, hostInputSampleFormat, outputChannelCount, outputSampleFormat, hostOutputSampleFormat, sampleRate, streamFlags, framesPerBuffer, framesPerBufferProcessorCall, paUtilFixedHostBufferSize, streamCallback, userData ); if( result != paNoError ) goto error; bufferProcessorIsInitialized = 1; /* stream info input latency is the minimum buffering latency (unlike suggested and default which are *maximums*) */ stream->streamRepresentation.streamInfo.inputLatency = (double)(PaUtil_GetBufferProcessorInputLatencyFrames(&stream->bufferProcessor) + framesPerHostInputBuffer) / sampleRate; stream->streamRepresentation.streamInfo.outputLatency = (double)(PaUtil_GetBufferProcessorOutputLatencyFrames(&stream->bufferProcessor) + (framesPerHostOutputBuffer * (hostOutputBufferCount-1))) / sampleRate; stream->streamRepresentation.streamInfo.sampleRate = sampleRate; stream->primeStreamUsingCallback = ( (streamFlags&paPrimeOutputBuffersUsingStreamCallback) && streamCallback ) ? 1 : 0; /* time to sleep when throttling due to >100% cpu usage. -a quater of a buffer's duration */ stream->throttledSleepMsecs = (unsigned long)(stream->bufferProcessor.framesPerHostBuffer * stream->bufferProcessor.samplePeriod * .25 * 1000); stream->isStopped = 1; stream->isActive = 0; /* for maximum compatibility with multi-device multichannel drivers, we first open all devices, then we prepare all buffers, finally we start all devices ( in StartStream() ). teardown in reverse order. */ if( inputParameters ) { result = InitializeWaveHandles( winMmeHostApi, &stream->input, winMmeSpecificInputFlags, stream->bufferProcessor.bytesPerHostInputSample, sampleRate, inputDevices, inputDeviceCount, inputChannelMask, 1 /* isInput */ ); if( result != paNoError ) goto error; } if( outputParameters ) { result = InitializeWaveHandles( winMmeHostApi, &stream->output, winMmeSpecificOutputFlags, stream->bufferProcessor.bytesPerHostOutputSample, sampleRate, outputDevices, outputDeviceCount, outputChannelMask, 0 /* isInput */ ); if( result != paNoError ) goto error; } if( inputParameters ) { result = InitializeWaveHeaders( &stream->input, hostInputBufferCount, hostInputSampleFormat, framesPerHostInputBuffer, inputDevices, 1 /* isInput */ ); if( result != paNoError ) goto error; } if( outputParameters ) { result = InitializeWaveHeaders( &stream->output, hostOutputBufferCount, hostOutputSampleFormat, framesPerHostOutputBuffer, outputDevices, 0 /* not isInput */ ); if( result != paNoError ) goto error; stream->allBuffersDurationMs = (DWORD) (1000.0 * (framesPerHostOutputBuffer * stream->output.bufferCount) / sampleRate); } else { stream->allBuffersDurationMs = (DWORD) (1000.0 * (framesPerHostInputBuffer * stream->input.bufferCount) / sampleRate); } if( streamCallback ) { /* abort event is only needed for callback streams */ result = CreateEventWithPaError( &stream->abortEvent, NULL, TRUE, FALSE, NULL ); if( result != paNoError ) goto error; } *s = (PaStream*)stream; return result; error: if( stream ) { if( stream->abortEvent ) CloseHandle( stream->abortEvent ); TerminateWaveHeaders( &stream->output, 0 /* not isInput */ ); TerminateWaveHeaders( &stream->input, 1 /* isInput */ ); TerminateWaveHandles( &stream->output, 0 /* not isInput */, 1 /* currentlyProcessingAnError */ ); TerminateWaveHandles( &stream->input, 1 /* isInput */, 1 /* currentlyProcessingAnError */ ); if( bufferProcessorIsInitialized ) PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); if( streamRepresentationIsInitialized ) PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); PaUtil_FreeMemory( stream ); } return result; } /* return non-zero if all current buffers are done */ static int BuffersAreDone( WAVEHDR **waveHeaders, unsigned int deviceCount, int bufferIndex ) { unsigned int i; for( i=0; i < deviceCount; ++i ) { if( !(waveHeaders[i][ bufferIndex ].dwFlags & WHDR_DONE) ) { return 0; } } return 1; } static int CurrentInputBuffersAreDone( PaWinMmeStream *stream ) { return BuffersAreDone( stream->input.waveHeaders, stream->input.deviceCount, stream->input.currentBufferIndex ); } static int CurrentOutputBuffersAreDone( PaWinMmeStream *stream ) { return BuffersAreDone( stream->output.waveHeaders, stream->output.deviceCount, stream->output.currentBufferIndex ); } /* return non-zero if any buffers are queued */ static int NoBuffersAreQueued( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers ) { unsigned int i, j; if( handlesAndBuffers->waveHandles ) { for( i=0; i < handlesAndBuffers->bufferCount; ++i ) { for( j=0; j < handlesAndBuffers->deviceCount; ++j ) { if( !( handlesAndBuffers->waveHeaders[ j ][ i ].dwFlags & WHDR_DONE) ) { return 0; } } } } return 1; } #define PA_CIRCULAR_INCREMENT_( current, max )\ ( (((current) + 1) >= (max)) ? (0) : (current+1) ) #define PA_CIRCULAR_DECREMENT_( current, max )\ ( ((current) == 0) ? ((max)-1) : (current-1) ) static signed long GetAvailableFrames( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers ) { signed long result = 0; unsigned int i; if( BuffersAreDone( handlesAndBuffers->waveHeaders, handlesAndBuffers->deviceCount, handlesAndBuffers->currentBufferIndex ) ) { /* we could calculate the following in O(1) if we kept track of the last done buffer */ result = handlesAndBuffers->framesPerBuffer - handlesAndBuffers->framesUsedInCurrentBuffer; i = PA_CIRCULAR_INCREMENT_( handlesAndBuffers->currentBufferIndex, handlesAndBuffers->bufferCount ); while( i != handlesAndBuffers->currentBufferIndex ) { if( BuffersAreDone( handlesAndBuffers->waveHeaders, handlesAndBuffers->deviceCount, i ) ) { result += handlesAndBuffers->framesPerBuffer; i = PA_CIRCULAR_INCREMENT_( i, handlesAndBuffers->bufferCount ); } else break; } } return result; } static PaError AdvanceToNextInputBuffer( PaWinMmeStream *stream ) { PaError result = paNoError; MMRESULT mmresult; unsigned int i; for( i=0; i < stream->input.deviceCount; ++i ) { stream->input.waveHeaders[i][ stream->input.currentBufferIndex ].dwFlags &= ~WHDR_DONE; mmresult = waveInAddBuffer( ((HWAVEIN*)stream->input.waveHandles)[i], &stream->input.waveHeaders[i][ stream->input.currentBufferIndex ], sizeof(WAVEHDR) ); if( mmresult != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); } } stream->input.currentBufferIndex = PA_CIRCULAR_INCREMENT_( stream->input.currentBufferIndex, stream->input.bufferCount ); stream->input.framesUsedInCurrentBuffer = 0; return result; } static PaError AdvanceToNextOutputBuffer( PaWinMmeStream *stream ) { PaError result = paNoError; MMRESULT mmresult; unsigned int i; for( i=0; i < stream->output.deviceCount; ++i ) { mmresult = waveOutWrite( ((HWAVEOUT*)stream->output.waveHandles)[i], &stream->output.waveHeaders[i][ stream->output.currentBufferIndex ], sizeof(WAVEHDR) ); if( mmresult != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); } } stream->output.currentBufferIndex = PA_CIRCULAR_INCREMENT_( stream->output.currentBufferIndex, stream->output.bufferCount ); stream->output.framesUsedInCurrentBuffer = 0; return result; } /* requeue all but the most recent input with the driver. Used for catching up after a total input buffer underrun */ static PaError CatchUpInputBuffers( PaWinMmeStream *stream ) { PaError result = paNoError; unsigned int i; for( i=0; i < stream->input.bufferCount - 1; ++i ) { result = AdvanceToNextInputBuffer( stream ); if( result != paNoError ) break; } return result; } /* take the most recent output and duplicate it to all other output buffers and requeue them. Used for catching up after a total output buffer underrun. */ static PaError CatchUpOutputBuffers( PaWinMmeStream *stream ) { PaError result = paNoError; unsigned int i, j; unsigned int previousBufferIndex = PA_CIRCULAR_DECREMENT_( stream->output.currentBufferIndex, stream->output.bufferCount ); for( i=0; i < stream->output.bufferCount - 1; ++i ) { for( j=0; j < stream->output.deviceCount; ++j ) { if( stream->output.waveHeaders[j][ stream->output.currentBufferIndex ].lpData != stream->output.waveHeaders[j][ previousBufferIndex ].lpData ) { CopyMemory( stream->output.waveHeaders[j][ stream->output.currentBufferIndex ].lpData, stream->output.waveHeaders[j][ previousBufferIndex ].lpData, stream->output.waveHeaders[j][ stream->output.currentBufferIndex ].dwBufferLength ); } } result = AdvanceToNextOutputBuffer( stream ); if( result != paNoError ) break; } return result; } PA_THREAD_FUNC ProcessingThreadProc( void *pArg ) { PaWinMmeStream *stream = (PaWinMmeStream *)pArg; HANDLE events[3]; int eventCount = 0; DWORD result = paNoError; DWORD waitResult; DWORD timeout = (unsigned long)(stream->allBuffersDurationMs * 0.5); int hostBuffersAvailable; signed int hostInputBufferIndex, hostOutputBufferIndex; PaStreamCallbackFlags statusFlags; int callbackResult; int done = 0; unsigned int channel, i; unsigned long framesProcessed; /* prepare event array for call to WaitForMultipleObjects() */ if( stream->input.bufferEvent ) events[eventCount++] = stream->input.bufferEvent; if( stream->output.bufferEvent ) events[eventCount++] = stream->output.bufferEvent; events[eventCount++] = stream->abortEvent; statusFlags = 0; /** @todo support paInputUnderflow, paOutputOverflow and paNeverDropInput */ /* loop until something causes us to stop */ do{ /* wait for MME to signal that a buffer is available, or for the PA abort event to be signaled. When this indicates that one or more buffers are available NoBuffersAreQueued() and Current*BuffersAreDone are used below to poll for additional done buffers. NoBuffersAreQueued() will fail to identify an underrun/overflow if the driver doesn't mark all done buffers prior to signalling the event. Some drivers do this (eg RME Digi96, and others don't eg VIA PC 97 input). This isn't a huge problem, it just means that we won't always be able to detect underflow/overflow. */ waitResult = WaitForMultipleObjects( eventCount, events, FALSE /* wait all = FALSE */, timeout ); if( waitResult == WAIT_FAILED ) { result = paUnanticipatedHostError; /** @todo FIXME/REVIEW: can't return host error info from an asyncronous thread. see http://www.portaudio.com/trac/ticket/143 */ done = 1; } else if( waitResult == WAIT_TIMEOUT ) { /* if a timeout is encountered, continue */ } if( stream->abortProcessing ) { /* Pa_AbortStream() has been called, stop processing immediately */ done = 1; } else if( stream->stopProcessing ) { /* Pa_StopStream() has been called or the user callback returned non-zero, processing will continue until all output buffers are marked as done. The stream will stop immediately if it is input-only. */ if( PA_IS_OUTPUT_STREAM_(stream) ) { if( NoBuffersAreQueued( &stream->output ) ) done = 1; /* Will cause thread to return. */ } else { /* input only stream */ done = 1; /* Will cause thread to return. */ } } else { hostBuffersAvailable = 1; /* process all available host buffers */ do { hostInputBufferIndex = -1; hostOutputBufferIndex = -1; if( PA_IS_INPUT_STREAM_(stream) ) { if( CurrentInputBuffersAreDone( stream ) ) { if( NoBuffersAreQueued( &stream->input ) ) { /** @todo if all of the other buffers are also ready then we discard all but the most recent. This is an input buffer overflow. FIXME: these buffers should be passed to the callback in a paNeverDropInput stream. http://www.portaudio.com/trac/ticket/142 note that it is also possible for an input overflow to happen while the callback is processing a buffer. that is handled further down. */ result = CatchUpInputBuffers( stream ); if( result != paNoError ) done = 1; statusFlags |= paInputOverflow; } hostInputBufferIndex = stream->input.currentBufferIndex; } } if( PA_IS_OUTPUT_STREAM_(stream) ) { if( CurrentOutputBuffersAreDone( stream ) ) { /* ok, we have an output buffer */ if( NoBuffersAreQueued( &stream->output ) ) { /* if all of the other buffers are also ready, catch up by copying the most recently generated buffer into all but one of the output buffers. note that this catch up code only handles the case where all buffers have been played out due to this thread not having woken up at all. a more common case occurs when this thread is woken up, processes one buffer, but takes too long, and as a result all the other buffers have become un-queued. that case is handled further down. */ result = CatchUpOutputBuffers( stream ); if( result != paNoError ) done = 1; statusFlags |= paOutputUnderflow; } hostOutputBufferIndex = stream->output.currentBufferIndex; } } if( (PA_IS_FULL_DUPLEX_STREAM_(stream) && hostInputBufferIndex != -1 && hostOutputBufferIndex != -1) || (PA_IS_HALF_DUPLEX_STREAM_(stream) && ( hostInputBufferIndex != -1 || hostOutputBufferIndex != -1 ) ) ) { PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /** @todo implement inputBufferAdcTime */ if( PA_IS_OUTPUT_STREAM_(stream) ) { /* set timeInfo.currentTime and calculate timeInfo.outputBufferDacTime from the current wave out position */ MMTIME mmtime; double timeBeforeGetPosition, timeAfterGetPosition; double time; long framesInBufferRing; long writePosition; long playbackPosition; HWAVEOUT firstWaveOutDevice = ((HWAVEOUT*)stream->output.waveHandles)[0]; mmtime.wType = TIME_SAMPLES; timeBeforeGetPosition = PaUtil_GetTime(); waveOutGetPosition( firstWaveOutDevice, &mmtime, sizeof(MMTIME) ); timeAfterGetPosition = PaUtil_GetTime(); timeInfo.currentTime = timeAfterGetPosition; /* approximate time at which wave out position was measured as half way between timeBeforeGetPosition and timeAfterGetPosition */ time = timeBeforeGetPosition + (timeAfterGetPosition - timeBeforeGetPosition) * .5; framesInBufferRing = stream->output.bufferCount * stream->bufferProcessor.framesPerHostBuffer; playbackPosition = mmtime.u.sample % framesInBufferRing; writePosition = stream->output.currentBufferIndex * stream->bufferProcessor.framesPerHostBuffer + stream->output.framesUsedInCurrentBuffer; if( playbackPosition >= writePosition ){ timeInfo.outputBufferDacTime = time + ((double)( writePosition + (framesInBufferRing - playbackPosition) ) * stream->bufferProcessor.samplePeriod ); }else{ timeInfo.outputBufferDacTime = time + ((double)( writePosition - playbackPosition ) * stream->bufferProcessor.samplePeriod ); } } PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer ); PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, statusFlags ); /* reset status flags once they have been passed to the buffer processor */ statusFlags = 0; if( PA_IS_INPUT_STREAM_(stream) ) { PaUtil_SetInputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ ); channel = 0; for( i=0; iinput.deviceCount; ++i ) { /* we have stored the number of channels in the buffer in dwUser */ int channelCount = (int)stream->input.waveHeaders[i][ hostInputBufferIndex ].dwUser; PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, channel, stream->input.waveHeaders[i][ hostInputBufferIndex ].lpData + stream->input.framesUsedInCurrentBuffer * channelCount * stream->bufferProcessor.bytesPerHostInputSample, channelCount ); channel += channelCount; } } if( PA_IS_OUTPUT_STREAM_(stream) ) { PaUtil_SetOutputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ ); channel = 0; for( i=0; ioutput.deviceCount; ++i ) { /* we have stored the number of channels in the buffer in dwUser */ int channelCount = (int)stream->output.waveHeaders[i][ hostOutputBufferIndex ].dwUser; PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, channel, stream->output.waveHeaders[i][ hostOutputBufferIndex ].lpData + stream->output.framesUsedInCurrentBuffer * channelCount * stream->bufferProcessor.bytesPerHostOutputSample, channelCount ); channel += channelCount; } } callbackResult = paContinue; framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult ); stream->input.framesUsedInCurrentBuffer += framesProcessed; stream->output.framesUsedInCurrentBuffer += framesProcessed; PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed ); if( callbackResult == paContinue ) { /* nothing special to do */ } else if( callbackResult == paAbort ) { stream->abortProcessing = 1; done = 1; /** @todo FIXME: should probably reset the output device immediately once the callback returns paAbort see: http://www.portaudio.com/trac/ticket/141 */ result = paNoError; } else { /* User callback has asked us to stop with paComplete or other non-zero value */ stream->stopProcessing = 1; /* stop once currently queued audio has finished */ result = paNoError; } if( PA_IS_INPUT_STREAM_(stream) && stream->stopProcessing == 0 && stream->abortProcessing == 0 && stream->input.framesUsedInCurrentBuffer == stream->input.framesPerBuffer ) { if( NoBuffersAreQueued( &stream->input ) ) { /** @todo need to handle PaNeverDropInput here where necessary */ result = CatchUpInputBuffers( stream ); if( result != paNoError ) done = 1; statusFlags |= paInputOverflow; } result = AdvanceToNextInputBuffer( stream ); if( result != paNoError ) done = 1; } if( PA_IS_OUTPUT_STREAM_(stream) && !stream->abortProcessing ) { if( stream->stopProcessing && stream->output.framesUsedInCurrentBuffer < stream->output.framesPerBuffer ) { /* zero remaining samples in output output buffer and flush */ stream->output.framesUsedInCurrentBuffer += PaUtil_ZeroOutput( &stream->bufferProcessor, stream->output.framesPerBuffer - stream->output.framesUsedInCurrentBuffer ); /* we send the entire buffer to the output devices, but we could just send a partial buffer, rather than zeroing the unused samples. */ } if( stream->output.framesUsedInCurrentBuffer == stream->output.framesPerBuffer ) { /* check for underflow before enquing the just-generated buffer, but recover from underflow after enquing it. This ensures that the most recent audio segment is repeated */ int outputUnderflow = NoBuffersAreQueued( &stream->output ); result = AdvanceToNextOutputBuffer( stream ); if( result != paNoError ) done = 1; if( outputUnderflow && !done && !stream->stopProcessing ) { /* Recover from underflow in the case where the underflow occured while processing the buffer we just finished */ result = CatchUpOutputBuffers( stream ); if( result != paNoError ) done = 1; statusFlags |= paOutputUnderflow; } } } if( stream->throttleProcessingThreadOnOverload != 0 ) { if( stream->stopProcessing || stream->abortProcessing ) { if( stream->processingThreadPriority != stream->highThreadPriority ) { SetThreadPriority( stream->processingThread, stream->highThreadPriority ); stream->processingThreadPriority = stream->highThreadPriority; } } else if( PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ) > 1. ) { if( stream->processingThreadPriority != stream->throttledThreadPriority ) { SetThreadPriority( stream->processingThread, stream->throttledThreadPriority ); stream->processingThreadPriority = stream->throttledThreadPriority; } /* sleep to give other processes a go */ Sleep( stream->throttledSleepMsecs ); } else { if( stream->processingThreadPriority != stream->highThreadPriority ) { SetThreadPriority( stream->processingThread, stream->highThreadPriority ); stream->processingThreadPriority = stream->highThreadPriority; } } } } else { hostBuffersAvailable = 0; } } while( hostBuffersAvailable && stream->stopProcessing == 0 && stream->abortProcessing == 0 && !done ); } } while( !done ); stream->isActive = 0; if( stream->streamRepresentation.streamFinishedCallback != 0 ) stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData ); PaUtil_ResetCpuLoadMeasurer( &stream->cpuLoadMeasurer ); return result; } /* When CloseStream() is called, the multi-api layer ensures that the stream has already been stopped or aborted. */ static PaError CloseStream( PaStream* s ) { PaError result; PaWinMmeStream *stream = (PaWinMmeStream*)s; result = CloseHandleWithPaError( stream->abortEvent ); if( result != paNoError ) goto error; TerminateWaveHeaders( &stream->output, 0 /* not isInput */ ); TerminateWaveHeaders( &stream->input, 1 /* isInput */ ); TerminateWaveHandles( &stream->output, 0 /* not isInput */, 0 /* not currentlyProcessingAnError */ ); TerminateWaveHandles( &stream->input, 1 /* isInput */, 0 /* not currentlyProcessingAnError */ ); PaUtil_TerminateBufferProcessor( &stream->bufferProcessor ); PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation ); PaUtil_FreeMemory( stream ); error: /** @todo REVIEW: what is the best way to clean up a stream if an error is detected? */ return result; } static PaError StartStream( PaStream *s ) { PaError result; PaWinMmeStream *stream = (PaWinMmeStream*)s; MMRESULT mmresult; unsigned int i, j; int callbackResult; unsigned int channel; unsigned long framesProcessed; PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /** @todo implement this for stream priming */ PaUtil_ResetBufferProcessor( &stream->bufferProcessor ); if( PA_IS_INPUT_STREAM_(stream) ) { for( i=0; iinput.bufferCount; ++i ) { for( j=0; jinput.deviceCount; ++j ) { stream->input.waveHeaders[j][i].dwFlags &= ~WHDR_DONE; mmresult = waveInAddBuffer( ((HWAVEIN*)stream->input.waveHandles)[j], &stream->input.waveHeaders[j][i], sizeof(WAVEHDR) ); if( mmresult != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); goto error; } } } stream->input.currentBufferIndex = 0; stream->input.framesUsedInCurrentBuffer = 0; } if( PA_IS_OUTPUT_STREAM_(stream) ) { for( i=0; ioutput.deviceCount; ++i ) { if( (mmresult = waveOutPause( ((HWAVEOUT*)stream->output.waveHandles)[i] )) != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); goto error; } } for( i=0; ioutput.bufferCount; ++i ) { if( stream->primeStreamUsingCallback ) { stream->output.framesUsedInCurrentBuffer = 0; do{ PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, paPrimingOutput | ((stream->input.bufferCount > 0 ) ? paInputUnderflow : 0)); if( stream->input.bufferCount > 0 ) PaUtil_SetNoInput( &stream->bufferProcessor ); PaUtil_SetOutputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ ); channel = 0; for( j=0; joutput.deviceCount; ++j ) { /* we have stored the number of channels in the buffer in dwUser */ int channelCount = (int)stream->output.waveHeaders[j][i].dwUser; PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, channel, stream->output.waveHeaders[j][i].lpData + stream->output.framesUsedInCurrentBuffer * channelCount * stream->bufferProcessor.bytesPerHostOutputSample, channelCount ); /* we have stored the number of channels in the buffer in dwUser */ channel += channelCount; } callbackResult = paContinue; framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult ); stream->output.framesUsedInCurrentBuffer += framesProcessed; if( callbackResult != paContinue ) { /** @todo fix this, what do we do if callback result is non-zero during stream priming? for complete: play out primed waveHeaders as usual for abort: clean up immediately. */ } }while( stream->output.framesUsedInCurrentBuffer != stream->output.framesPerBuffer ); } else { for( j=0; joutput.deviceCount; ++j ) { ZeroMemory( stream->output.waveHeaders[j][i].lpData, stream->output.waveHeaders[j][i].dwBufferLength ); } } /* we queue all channels of a single buffer frame (accross all devices, because some multidevice multichannel drivers work better this way */ for( j=0; joutput.deviceCount; ++j ) { mmresult = waveOutWrite( ((HWAVEOUT*)stream->output.waveHandles)[j], &stream->output.waveHeaders[j][i], sizeof(WAVEHDR) ); if( mmresult != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); goto error; } } } stream->output.currentBufferIndex = 0; stream->output.framesUsedInCurrentBuffer = 0; } stream->isStopped = 0; stream->isActive = 1; stream->stopProcessing = 0; stream->abortProcessing = 0; result = ResetEventWithPaError( stream->input.bufferEvent ); if( result != paNoError ) goto error; result = ResetEventWithPaError( stream->output.bufferEvent ); if( result != paNoError ) goto error; if( stream->streamRepresentation.streamCallback ) { /* callback stream */ result = ResetEventWithPaError( stream->abortEvent ); if( result != paNoError ) goto error; /* Create thread that waits for audio buffers to be ready for processing. */ stream->processingThread = CREATE_THREAD; if( !stream->processingThread ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() ); goto error; } /** @todo could have mme specific stream parameters to allow the user to set the callback thread priorities */ stream->highThreadPriority = THREAD_PRIORITY_TIME_CRITICAL; stream->throttledThreadPriority = THREAD_PRIORITY_NORMAL; if( !SetThreadPriority( stream->processingThread, stream->highThreadPriority ) ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() ); goto error; } stream->processingThreadPriority = stream->highThreadPriority; } else { /* blocking read/write stream */ } if( PA_IS_INPUT_STREAM_(stream) ) { for( i=0; i < stream->input.deviceCount; ++i ) { mmresult = waveInStart( ((HWAVEIN*)stream->input.waveHandles)[i] ); PA_DEBUG(("Pa_StartStream: waveInStart returned = 0x%X.\n", mmresult)); if( mmresult != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); goto error; } } } if( PA_IS_OUTPUT_STREAM_(stream) ) { for( i=0; i < stream->output.deviceCount; ++i ) { if( (mmresult = waveOutRestart( ((HWAVEOUT*)stream->output.waveHandles)[i] )) != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); goto error; } } } return result; error: /** @todo FIXME: implement recovery as best we can This should involve rolling back to a state as-if this function had never been called */ return result; } static PaError StopStream( PaStream *s ) { PaError result = paNoError; PaWinMmeStream *stream = (PaWinMmeStream*)s; int timeout; DWORD waitResult; MMRESULT mmresult; signed int hostOutputBufferIndex; unsigned int channel, waitCount, i; /** @todo REVIEW: the error checking in this function needs review. the basic idea is to return from this function in a known state - for example there is no point avoiding calling waveInReset just because the thread times out. */ if( stream->processingThread ) { /* callback stream */ /* Tell processing thread to stop generating more data and to let current data play out. */ stream->stopProcessing = 1; /* Calculate timeOut longer than longest time it could take to return all buffers. */ timeout = (int)(stream->allBuffersDurationMs * 1.5); if( timeout < PA_MME_MIN_TIMEOUT_MSEC_ ) timeout = PA_MME_MIN_TIMEOUT_MSEC_; PA_DEBUG(("WinMME StopStream: waiting for background thread.\n")); waitResult = WaitForSingleObject( stream->processingThread, timeout ); if( waitResult == WAIT_TIMEOUT ) { /* try to abort */ stream->abortProcessing = 1; SetEvent( stream->abortEvent ); waitResult = WaitForSingleObject( stream->processingThread, timeout ); if( waitResult == WAIT_TIMEOUT ) { PA_DEBUG(("WinMME StopStream: timed out while waiting for background thread to finish.\n")); result = paTimedOut; } } CloseHandle( stream->processingThread ); stream->processingThread = NULL; } else { /* blocking read / write stream */ if( PA_IS_OUTPUT_STREAM_(stream) ) { if( stream->output.framesUsedInCurrentBuffer > 0 ) { /* there are still unqueued frames in the current buffer, so flush them */ hostOutputBufferIndex = stream->output.currentBufferIndex; PaUtil_SetOutputFrameCount( &stream->bufferProcessor, stream->output.framesPerBuffer - stream->output.framesUsedInCurrentBuffer ); channel = 0; for( i=0; ioutput.deviceCount; ++i ) { /* we have stored the number of channels in the buffer in dwUser */ int channelCount = (int)stream->output.waveHeaders[i][ hostOutputBufferIndex ].dwUser; PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, channel, stream->output.waveHeaders[i][ hostOutputBufferIndex ].lpData + stream->output.framesUsedInCurrentBuffer * channelCount * stream->bufferProcessor.bytesPerHostOutputSample, channelCount ); channel += channelCount; } PaUtil_ZeroOutput( &stream->bufferProcessor, stream->output.framesPerBuffer - stream->output.framesUsedInCurrentBuffer ); /* we send the entire buffer to the output devices, but we could just send a partial buffer, rather than zeroing the unused samples. */ AdvanceToNextOutputBuffer( stream ); } timeout = (stream->allBuffersDurationMs / stream->output.bufferCount) + 1; if( timeout < PA_MME_MIN_TIMEOUT_MSEC_ ) timeout = PA_MME_MIN_TIMEOUT_MSEC_; waitCount = 0; while( !NoBuffersAreQueued( &stream->output ) && waitCount <= stream->output.bufferCount ) { /* wait for MME to signal that a buffer is available */ waitResult = WaitForSingleObject( stream->output.bufferEvent, timeout ); if( waitResult == WAIT_FAILED ) { break; } else if( waitResult == WAIT_TIMEOUT ) { /* keep waiting */ } ++waitCount; } } } if( PA_IS_OUTPUT_STREAM_(stream) ) { for( i =0; i < stream->output.deviceCount; ++i ) { mmresult = waveOutReset( ((HWAVEOUT*)stream->output.waveHandles)[i] ); if( mmresult != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); } } } if( PA_IS_INPUT_STREAM_(stream) ) { for( i=0; i < stream->input.deviceCount; ++i ) { mmresult = waveInReset( ((HWAVEIN*)stream->input.waveHandles)[i] ); if( mmresult != MMSYSERR_NOERROR ) { result = paUnanticipatedHostError; PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); } } } stream->isStopped = 1; stream->isActive = 0; return result; } static PaError AbortStream( PaStream *s ) { PaError result = paNoError; PaWinMmeStream *stream = (PaWinMmeStream*)s; int timeout; DWORD waitResult; MMRESULT mmresult; unsigned int i; /** @todo REVIEW: the error checking in this function needs review. the basic idea is to return from this function in a known state - for example there is no point avoiding calling waveInReset just because the thread times out. */ if( stream->processingThread ) { /* callback stream */ /* Tell processing thread to abort immediately */ stream->abortProcessing = 1; SetEvent( stream->abortEvent ); } if( PA_IS_OUTPUT_STREAM_(stream) ) { for( i =0; i < stream->output.deviceCount; ++i ) { mmresult = waveOutReset( ((HWAVEOUT*)stream->output.waveHandles)[i] ); if( mmresult != MMSYSERR_NOERROR ) { PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ); return paUnanticipatedHostError; } } } if( PA_IS_INPUT_STREAM_(stream) ) { for( i=0; i < stream->input.deviceCount; ++i ) { mmresult = waveInReset( ((HWAVEIN*)stream->input.waveHandles)[i] ); if( mmresult != MMSYSERR_NOERROR ) { PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ); return paUnanticipatedHostError; } } } if( stream->processingThread ) { /* callback stream */ PA_DEBUG(("WinMME AbortStream: waiting for background thread.\n")); /* Calculate timeOut longer than longest time it could take to return all buffers. */ timeout = (int)(stream->allBuffersDurationMs * 1.5); if( timeout < PA_MME_MIN_TIMEOUT_MSEC_ ) timeout = PA_MME_MIN_TIMEOUT_MSEC_; waitResult = WaitForSingleObject( stream->processingThread, timeout ); if( waitResult == WAIT_TIMEOUT ) { PA_DEBUG(("WinMME AbortStream: timed out while waiting for background thread to finish.\n")); return paTimedOut; } CloseHandle( stream->processingThread ); stream->processingThread = NULL; } stream->isStopped = 1; stream->isActive = 0; return result; } static PaError IsStreamStopped( PaStream *s ) { PaWinMmeStream *stream = (PaWinMmeStream*)s; return stream->isStopped; } static PaError IsStreamActive( PaStream *s ) { PaWinMmeStream *stream = (PaWinMmeStream*)s; return stream->isActive; } static PaTime GetStreamTime( PaStream *s ) { (void) s; /* unused parameter */ return PaUtil_GetTime(); } static double GetStreamCpuLoad( PaStream* s ) { PaWinMmeStream *stream = (PaWinMmeStream*)s; return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ); } /* As separate stream interfaces are used for blocking and callback streams, the following functions can be guaranteed to only be called for blocking streams. */ static PaError ReadStream( PaStream* s, void *buffer, unsigned long frames ) { PaError result = paNoError; PaWinMmeStream *stream = (PaWinMmeStream*)s; void *userBuffer; unsigned long framesRead = 0; unsigned long framesProcessed; signed int hostInputBufferIndex; DWORD waitResult; DWORD timeout = (unsigned long)(stream->allBuffersDurationMs * 0.5); unsigned int channel, i; if( PA_IS_INPUT_STREAM_(stream) ) { /* make a local copy of the user buffer pointer(s). this is necessary because PaUtil_CopyInput() advances these pointers every time it is called. */ if( stream->bufferProcessor.userInputIsInterleaved ) { userBuffer = buffer; } else { userBuffer = (void*)alloca( sizeof(void*) * stream->bufferProcessor.inputChannelCount ); if( !userBuffer ) return paInsufficientMemory; for( i = 0; ibufferProcessor.inputChannelCount; ++i ) ((void**)userBuffer)[i] = ((void**)buffer)[i]; } do{ if( CurrentInputBuffersAreDone( stream ) ) { if( NoBuffersAreQueued( &stream->input ) ) { /** @todo REVIEW: consider what to do if the input overflows. do we requeue all of the buffers? should we be running a thread to make sure they are always queued? see: http://www.portaudio.com/trac/ticket/117 */ result = paInputOverflowed; } hostInputBufferIndex = stream->input.currentBufferIndex; PaUtil_SetInputFrameCount( &stream->bufferProcessor, stream->input.framesPerBuffer - stream->input.framesUsedInCurrentBuffer ); channel = 0; for( i=0; iinput.deviceCount; ++i ) { /* we have stored the number of channels in the buffer in dwUser */ int channelCount = (int)stream->input.waveHeaders[i][ hostInputBufferIndex ].dwUser; PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, channel, stream->input.waveHeaders[i][ hostInputBufferIndex ].lpData + stream->input.framesUsedInCurrentBuffer * channelCount * stream->bufferProcessor.bytesPerHostInputSample, channelCount ); channel += channelCount; } framesProcessed = PaUtil_CopyInput( &stream->bufferProcessor, &userBuffer, frames - framesRead ); stream->input.framesUsedInCurrentBuffer += framesProcessed; if( stream->input.framesUsedInCurrentBuffer == stream->input.framesPerBuffer ) { result = AdvanceToNextInputBuffer( stream ); if( result != paNoError ) break; } framesRead += framesProcessed; }else{ /* wait for MME to signal that a buffer is available */ waitResult = WaitForSingleObject( stream->input.bufferEvent, timeout ); if( waitResult == WAIT_FAILED ) { result = paUnanticipatedHostError; break; } else if( waitResult == WAIT_TIMEOUT ) { /* if a timeout is encountered, continue, perhaps we should give up eventually */ } } }while( framesRead < frames ); } else { result = paCanNotReadFromAnOutputOnlyStream; } return result; } static PaError WriteStream( PaStream* s, const void *buffer, unsigned long frames ) { PaError result = paNoError; PaWinMmeStream *stream = (PaWinMmeStream*)s; const void *userBuffer; unsigned long framesWritten = 0; unsigned long framesProcessed; signed int hostOutputBufferIndex; DWORD waitResult; DWORD timeout = (unsigned long)(stream->allBuffersDurationMs * 0.5); unsigned int channel, i; if( PA_IS_OUTPUT_STREAM_(stream) ) { /* make a local copy of the user buffer pointer(s). this is necessary because PaUtil_CopyOutput() advances these pointers every time it is called. */ if( stream->bufferProcessor.userOutputIsInterleaved ) { userBuffer = buffer; } else { userBuffer = (const void*)alloca( sizeof(void*) * stream->bufferProcessor.outputChannelCount ); if( !userBuffer ) return paInsufficientMemory; for( i = 0; ibufferProcessor.outputChannelCount; ++i ) ((const void**)userBuffer)[i] = ((const void**)buffer)[i]; } do{ if( CurrentOutputBuffersAreDone( stream ) ) { if( NoBuffersAreQueued( &stream->output ) ) { /** @todo REVIEW: consider what to do if the output underflows. do we requeue all the existing buffers with zeros? should we run a separate thread to keep the buffers enqueued at all times? see: http://www.portaudio.com/trac/ticket/117 */ result = paOutputUnderflowed; } hostOutputBufferIndex = stream->output.currentBufferIndex; PaUtil_SetOutputFrameCount( &stream->bufferProcessor, stream->output.framesPerBuffer - stream->output.framesUsedInCurrentBuffer ); channel = 0; for( i=0; ioutput.deviceCount; ++i ) { /* we have stored the number of channels in the buffer in dwUser */ int channelCount = (int)stream->output.waveHeaders[i][ hostOutputBufferIndex ].dwUser; PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, channel, stream->output.waveHeaders[i][ hostOutputBufferIndex ].lpData + stream->output.framesUsedInCurrentBuffer * channelCount * stream->bufferProcessor.bytesPerHostOutputSample, channelCount ); channel += channelCount; } framesProcessed = PaUtil_CopyOutput( &stream->bufferProcessor, &userBuffer, frames - framesWritten ); stream->output.framesUsedInCurrentBuffer += framesProcessed; if( stream->output.framesUsedInCurrentBuffer == stream->output.framesPerBuffer ) { result = AdvanceToNextOutputBuffer( stream ); if( result != paNoError ) break; } framesWritten += framesProcessed; } else { /* wait for MME to signal that a buffer is available */ waitResult = WaitForSingleObject( stream->output.bufferEvent, timeout ); if( waitResult == WAIT_FAILED ) { result = paUnanticipatedHostError; break; } else if( waitResult == WAIT_TIMEOUT ) { /* if a timeout is encountered, continue, perhaps we should give up eventually */ } } }while( framesWritten < frames ); } else { result = paCanNotWriteToAnInputOnlyStream; } return result; } static signed long GetStreamReadAvailable( PaStream* s ) { PaWinMmeStream *stream = (PaWinMmeStream*)s; if( PA_IS_INPUT_STREAM_(stream) ) return GetAvailableFrames( &stream->input ); else return paCanNotReadFromAnOutputOnlyStream; } static signed long GetStreamWriteAvailable( PaStream* s ) { PaWinMmeStream *stream = (PaWinMmeStream*)s; if( PA_IS_OUTPUT_STREAM_(stream) ) return GetAvailableFrames( &stream->output ); else return paCanNotWriteToAnInputOnlyStream; } /* NOTE: the following functions are MME-stream specific, and are called directly by client code. We need to check for many more error conditions here because we don't have the benefit of pa_front.c's parameter checking. */ static PaError GetWinMMEStreamPointer( PaWinMmeStream **stream, PaStream *s ) { PaError result; PaUtilHostApiRepresentation *hostApi; PaWinMmeHostApiRepresentation *winMmeHostApi; result = PaUtil_ValidateStreamPointer( s ); if( result != paNoError ) return result; result = PaUtil_GetHostApiRepresentation( &hostApi, paMME ); if( result != paNoError ) return result; winMmeHostApi = (PaWinMmeHostApiRepresentation*)hostApi; /* note, the following would be easier if there was a generic way of testing that a stream belongs to a specific host API */ if( PA_STREAM_REP( s )->streamInterface == &winMmeHostApi->callbackStreamInterface || PA_STREAM_REP( s )->streamInterface == &winMmeHostApi->blockingStreamInterface ) { /* s is a WinMME stream */ *stream = (PaWinMmeStream *)s; return paNoError; } else { return paIncompatibleStreamHostApi; } } int PaWinMME_GetStreamInputHandleCount( PaStream* s ) { PaWinMmeStream *stream; PaError result = GetWinMMEStreamPointer( &stream, s ); if( result == paNoError ) return (PA_IS_INPUT_STREAM_(stream)) ? stream->input.deviceCount : 0; else return result; } HWAVEIN PaWinMME_GetStreamInputHandle( PaStream* s, int handleIndex ) { PaWinMmeStream *stream; PaError result = GetWinMMEStreamPointer( &stream, s ); if( result == paNoError && PA_IS_INPUT_STREAM_(stream) && handleIndex >= 0 && (unsigned int)handleIndex < stream->input.deviceCount ) return ((HWAVEIN*)stream->input.waveHandles)[handleIndex]; else return 0; } int PaWinMME_GetStreamOutputHandleCount( PaStream* s) { PaWinMmeStream *stream; PaError result = GetWinMMEStreamPointer( &stream, s ); if( result == paNoError ) return (PA_IS_OUTPUT_STREAM_(stream)) ? stream->output.deviceCount : 0; else return result; } HWAVEOUT PaWinMME_GetStreamOutputHandle( PaStream* s, int handleIndex ) { PaWinMmeStream *stream; PaError result = GetWinMMEStreamPointer( &stream, s ); if( result == paNoError && PA_IS_OUTPUT_STREAM_(stream) && handleIndex >= 0 && (unsigned int)handleIndex < stream->output.deviceCount ) return ((HWAVEOUT*)stream->output.waveHandles)[handleIndex]; else return 0; } pd-0.46-7/portaudio/LICENSE.txt0000664000175000017500000000670412160204055014227 0ustar mspmspPortable header file to contain: >>>>> /* * PortAudio Portable Real-Time Audio Library * PortAudio API Header File * Latest version available at: http://www.portaudio.com * * Copyright (c) 1999-2006 Ross Bencina and Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ <<<<< Implementation files to contain: >>>>> /* * PortAudio Portable Real-Time Audio Library * Latest version at: http://www.portaudio.com * Implementation * Copyright (c) 1999-2000 * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * The text above constitutes the entire PortAudio license; however, * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also * requested that these non-binding requests be included along with the * license above. */ <<<<<pd-0.46-7/portaudio/portaudio-2.0.pc.in0000664000175000017500000000034712374250720015644 0ustar mspmspprefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: PortAudio Description: Portable audio I/O Requires: Version: 19 Libs: -L${libdir} -lportaudio @LIBS@ Cflags: -I${includedir} @THREAD_CFLAGS@ pd-0.46-7/portaudio/Makefile.in0000664000175000017500000001411612374250720014454 0ustar mspmsp# # PortAudio V19 Makefile.in # # Dominic Mazzoni # Modifications by Mikael Magnusson # Modifications by Stelios Bounanos # top_srcdir = @top_srcdir@ srcdir = @srcdir@ VPATH = @srcdir@ top_builddir = . PREFIX = @prefix@ prefix = $(PREFIX) exec_prefix = @exec_prefix@ bindir = @bindir@ libdir = @libdir@ includedir = @includedir@ CC = @CC@ CXX = @CXX@ CFLAGS = @CFLAGS@ @DEFS@ LIBS = @LIBS@ AR = @AR@ RANLIB = @RANLIB@ SHELL = @SHELL@ LIBTOOL = @LIBTOOL@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ SHARED_FLAGS = @SHARED_FLAGS@ LDFLAGS = @LDFLAGS@ DLL_LIBS = @DLL_LIBS@ CXXFLAGS = @CXXFLAGS@ NASM = @NASM@ NASMOPT = @NASMOPT@ LN_S = @LN_S@ LT_CURRENT=@LT_CURRENT@ LT_REVISION=@LT_REVISION@ LT_AGE=@LT_AGE@ OTHER_OBJS = @OTHER_OBJS@ INCLUDES = @INCLUDES@ PALIB = libportaudio.la PAINC = include/portaudio.h PA_LDFLAGS = $(LDFLAGS) $(SHARED_FLAGS) -rpath $(libdir) -no-undefined \ -export-symbols-regex "(Pa|PaMacCore|PaJack|PaAlsa|PaAsio|PaOSS)_.*" \ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) COMMON_OBJS = \ src/common/pa_allocation.o \ src/common/pa_converters.o \ src/common/pa_cpuload.o \ src/common/pa_dither.o \ src/common/pa_debugprint.o \ src/common/pa_front.o \ src/common/pa_process.o \ src/common/pa_stream.o \ src/common/pa_trace.o LOOPBACK_OBJS = \ qa/loopback/src/audio_analyzer.o \ qa/loopback/src/biquad_filter.o \ qa/loopback/src/paqa_tools.o \ qa/loopback/src/test_audio_analyzer.o \ qa/loopback/src/write_wav.o \ qa/loopback/src/paqa.o EXAMPLES = \ SELFTESTS = \ TESTS = \ # Most of these don't compile yet. Put them in TESTS, above, if # you want to try to compile them... ALL_TESTS = \ $(TESTS) \ bin/patest_sync \ bin/debug_convert \ bin/debug_dither_calc \ bin/debug_dual \ bin/debug_multi_in \ bin/debug_multi_out \ bin/debug_record \ bin/debug_record_reuse \ bin/debug_sine_amp \ bin/debug_sine \ bin/debug_sine_formats \ bin/debug_srate \ bin/debug_test1 OBJS := $(COMMON_OBJS) $(OTHER_OBJS) LTOBJS := $(OBJS:.o=.lo) SRC_DIRS = \ src/common \ src/hostapi/alsa \ src/hostapi/asihpi \ src/hostapi/asio \ src/hostapi/coreaudio \ src/hostapi/dsound \ src/hostapi/jack \ src/hostapi/oss \ src/hostapi/wasapi \ src/hostapi/wdmks \ src/hostapi/wmme \ src/os/unix \ src/os/win SUBDIRS = @ENABLE_CXX_TRUE@SUBDIRS += bindings/cpp all: lib/$(PALIB) all-recursive tests examples selftests tests: bin-stamp $(TESTS) examples: bin-stamp $(EXAMPLES) selftests: bin-stamp $(SELFTESTS) loopback: bin-stamp bin/paloopback # With ASIO enabled we must link libportaudio and all test programs with CXX lib/$(PALIB): lib-stamp $(LTOBJS) $(MAKEFILE) $(PAINC) @WITH_ASIO_FALSE@ $(LIBTOOL) --mode=link $(CC) $(PA_LDFLAGS) -o lib/$(PALIB) $(LTOBJS) $(DLL_LIBS) @WITH_ASIO_TRUE@ $(LIBTOOL) --mode=link --tag=CXX $(CXX) $(PA_LDFLAGS) -o lib/$(PALIB) $(LTOBJS) $(DLL_LIBS) $(ALL_TESTS): bin/%: lib/$(PALIB) $(MAKEFILE) $(PAINC) test/%.c @WITH_ASIO_FALSE@ $(LIBTOOL) --mode=link $(CC) -o $@ $(CFLAGS) $(top_srcdir)/test/$*.c lib/$(PALIB) $(LIBS) @WITH_ASIO_TRUE@ $(LIBTOOL) --mode=link --tag=CXX $(CXX) -o $@ $(CXXFLAGS) $(top_srcdir)/test/$*.c lib/$(PALIB) $(LIBS) $(EXAMPLES): bin/%: lib/$(PALIB) $(MAKEFILE) $(PAINC) examples/%.c @WITH_ASIO_FALSE@ $(LIBTOOL) --mode=link $(CC) -o $@ $(CFLAGS) $(top_srcdir)/examples/$*.c lib/$(PALIB) $(LIBS) @WITH_ASIO_TRUE@ $(LIBTOOL) --mode=link --tag=CXX $(CXX) -o $@ $(CXXFLAGS) $(top_srcdir)/examples/$*.c lib/$(PALIB) $(LIBS) $(SELFTESTS): bin/%: lib/$(PALIB) $(MAKEFILE) $(PAINC) qa/%.c @WITH_ASIO_FALSE@ $(LIBTOOL) --mode=link $(CC) -o $@ $(CFLAGS) $(top_srcdir)/qa/$*.c lib/$(PALIB) $(LIBS) @WITH_ASIO_TRUE@ $(LIBTOOL) --mode=link --tag=CXX $(CXX) -o $@ $(CXXFLAGS) $(top_srcdir)/qa/$*.c lib/$(PALIB) $(LIBS) bin/paloopback: lib/$(PALIB) $(MAKEFILE) $(PAINC) $(LOOPBACK_OBJS) @WITH_ASIO_FALSE@ $(LIBTOOL) --mode=link $(CC) -o $@ $(CFLAGS) $(LOOPBACK_OBJS) lib/$(PALIB) $(LIBS) @WITH_ASIO_TRUE@ $(LIBTOOL) --mode=link --tag=CXX $(CXX) -o $@ $(CXXFLAGS) $(LOOPBACK_OBJS) lib/$(PALIB) $(LIBS) install: lib/$(PALIB) portaudio-2.0.pc $(INSTALL) -d $(DESTDIR)$(libdir) $(LIBTOOL) --mode=install $(INSTALL) lib/$(PALIB) $(DESTDIR)$(libdir) $(INSTALL) -d $(DESTDIR)$(includedir) for include in $(INCLUDES); do \ $(INSTALL_DATA) -m 644 $(top_srcdir)/include/$$include $(DESTDIR)$(includedir)/$$include; \ done $(INSTALL) -d $(DESTDIR)$(libdir)/pkgconfig $(INSTALL) -m 644 portaudio-2.0.pc $(DESTDIR)$(libdir)/pkgconfig/portaudio-2.0.pc @echo "" @echo "------------------------------------------------------------" @echo "PortAudio was successfully installed." @echo "" @echo "On some systems (e.g. Linux) you should run 'ldconfig' now" @echo "to make the shared object available. You may also need to" @echo "modify your LD_LIBRARY_PATH environment variable to include" @echo "the directory $(libdir)" @echo "------------------------------------------------------------" @echo "" $(MAKE) install-recursive uninstall: $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$(PALIB) $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(includedir)/portaudio.h $(MAKE) uninstall-recursive clean: $(LIBTOOL) --mode=clean rm -f $(LTOBJS) $(LOOPBACK_OBJS) $(ALL_TESTS) lib/$(PALIB) $(RM) bin-stamp lib-stamp -$(RM) -r bin lib distclean: clean $(RM) config.log config.status Makefile libtool portaudio-2.0.pc %.o: %.c $(MAKEFILE) $(PAINC) $(CC) -c $(CFLAGS) $< -o $@ %.lo: %.c $(MAKEFILE) $(PAINC) $(LIBTOOL) --mode=compile $(CC) -c $(CFLAGS) $< -o $@ %.lo: %.cpp $(MAKEFILE) $(PAINC) $(LIBTOOL) --mode=compile --tag=CXX $(CXX) -c $(CXXFLAGS) $< -o $@ %.o: %.cpp $(MAKEFILE) $(PAINC) $(CXX) -c $(CXXFLAGS) $< -o $@ %.o: %.asm $(NASM) $(NASMOPT) -o $@ $< bin-stamp: -mkdir bin touch $@ lib-stamp: -mkdir lib -mkdir -p $(SRC_DIRS) touch $@ Makefile: Makefile.in config.status $(SHELL) config.status all-recursive: if test -n "$(SUBDIRS)" ; then for dir in "$(SUBDIRS)"; do $(MAKE) -C $$dir all; done ; fi install-recursive: if test -n "$(SUBDIRS)" ; then for dir in "$(SUBDIRS)"; do $(MAKE) -C $$dir install; done ; fi uninstall-recursive: if test -n "$(SUBDIRS)" ; then for dir in "$(SUBDIRS)"; do $(MAKE) -C $$dir uninstall; done ; fi pd-0.46-7/portaudio/config.guess0000775000175000017500000012673012374245151014737 0ustar mspmsp#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011 Free Software Foundation, Inc. timestamp='2011-05-11' # This file 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 2 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, write to the Free Software # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Per Bothner. Please send patches (context # diff format) to and include a ChangeLog # entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm:riscos:*:*|arm:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) case ${UNAME_MACHINE} in pc98) echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-gnu else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-gnueabi else echo ${UNAME_MACHINE}-unknown-linux-gnueabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) echo cris-axis-linux-gnu exit ;; crisv32:Linux:*:*) echo crisv32-axis-linux-gnu exit ;; frv:Linux:*:*) echo frv-unknown-linux-gnu exit ;; i*86:Linux:*:*) LIBC=gnu eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) echo or32-unknown-linux-gnu exit ;; padre:Linux:*:*) echo sparc-unknown-linux-gnu exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-tilera-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) echo x86_64-unknown-linux-gnu exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in i386) eval $set_cc_for_build if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then UNAME_PROCESSOR="x86_64" fi fi ;; unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: pd-0.46-7/portaudio/Makefile.dist0000664000175000017500000000754712222367057015027 0ustar mspmsp## distdir target by IOhannes m zmölnig ## portaudio's original build-system lacks a "distdir" target ## which prevents us from easily creating a distribution tarball ## for Pd! ## so we provide a simplified target here, to satisfy autotools needs # list of all files to be installed ## generated with `make distclean; find . -type f` DISTFILES=\ LICENSE.txt \ include/pa_asio.h \ include/pa_jack.h \ include/pa_linux_alsa.h \ include/pa_mac_core.h \ include/pa_win_waveformat.h \ include/pa_win_wmme.h \ include/portaudio.h \ src/common/pa_allocation.c \ src/common/pa_allocation.h \ src/common/pa_converters.c \ src/common/pa_converters.h \ src/common/pa_cpuload.c \ src/common/pa_cpuload.h \ src/common/pa_debugprint.c \ src/common/pa_debugprint.h \ src/common/pa_dither.c \ src/common/pa_dither.h \ src/common/pa_endianness.h \ src/common/pa_front.c \ src/common/pa_hostapi.h \ src/common/pa_memorybarrier.h \ src/common/pa_process.c \ src/common/pa_process.h \ src/common/pa_ringbuffer.c \ src/common/pa_ringbuffer.h \ src/common/pa_stream.c \ src/common/pa_stream.h \ src/common/pa_trace.c \ src/common/pa_trace.h \ src/common/pa_types.h \ src/common/pa_util.h \ src/hostapi/alsa/pa_linux_alsa.c \ src/hostapi/asio/iasiothiscallresolver.cpp \ src/hostapi/asio/iasiothiscallresolver.h \ src/hostapi/asio/pa_asio.cpp \ src/hostapi/coreaudio/notes.txt \ src/hostapi/coreaudio/pa_mac_core.c \ src/hostapi/coreaudio/pa_mac_core_blocking.c \ src/hostapi/coreaudio/pa_mac_core_blocking.h \ src/hostapi/coreaudio/pa_mac_core_internal.h \ src/hostapi/coreaudio/pa_mac_core_old.c \ src/hostapi/coreaudio/pa_mac_core_utilities.c \ src/hostapi/coreaudio/pa_mac_core_utilities.h \ src/hostapi/jack/pa_jack.c \ src/hostapi/oss/low_latency_tip.txt \ src/hostapi/oss/pa_unix_oss.c \ src/hostapi/oss/recplay.c \ src/hostapi/wmme/pa_win_wmme.c \ src/os/mac_osx/pa_mac_hostapis.c \ src/os/unix/pa_unix_hostapis.c \ src/os/unix/pa_unix_util.c \ src/os/unix/pa_unix_util.h \ src/os/win/pa_win_coinitialize.c \ src/os/win/pa_win_coinitialize.h \ src/os/win/pa_win_hostapis.c \ src/os/win/pa_win_util.c \ src/os/win/pa_win_waveformat.c \ src/os/win/pa_win_wdmks_utils.c \ src/os/win/pa_win_wdmks_utils.h \ src/os/win/pa_x86_plain_converters.c \ src/os/win/pa_x86_plain_converters.h \ aclocal.m4 \ configure.in \ configure \ Makefile.in \ Makefile.dist \ Makefile \ config.guess \ config.sub \ config.status \ install-sh \ ltmain.sh ## this is the actual target, stolen from an automake generated Makefile distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done ## some dummy targets, ## that are needed by autotools but are not provided by portaudio dvi check installcheck distuninstallcheck: pd-0.46-7/portaudio/configure.in0000664000175000017500000004366312374245151014733 0ustar mspmspdnl dnl portaudio V19 configure.in script dnl dnl Dominic Mazzoni, Arve Knudsen, Stelios Bounanos dnl dnl Require autoconf >= 2.13 AC_PREREQ(2.13) dnl Init autoconf and make sure configure is being called dnl from the right directory AC_INIT([include/portaudio.h]) dnl Define build, build_cpu, build_vendor, build_os AC_CANONICAL_BUILD dnl Define host, host_cpu, host_vendor, host_os AC_CANONICAL_HOST dnl Define target, target_cpu, target_vendor, target_os AC_CANONICAL_TARGET dnl Specify options AC_ARG_WITH(alsa, AS_HELP_STRING([--with-alsa], [Enable support for ALSA @<:@autodetect@:>@]), [with_alsa=$withval]) AC_ARG_WITH(jack, AS_HELP_STRING([--with-jack], [Enable support for JACK @<:@autodetect@:>@]), [with_jack=$withval]) AC_ARG_WITH(oss, AS_HELP_STRING([--with-oss], [Enable support for OSS @<:@autodetect@:>@]), [with_oss=$withval]) AC_ARG_WITH(asihpi, AS_HELP_STRING([--with-asihpi], [Enable support for ASIHPI @<:@autodetect@:>@]), [with_asihpi=$withval]) AC_ARG_WITH(winapi, AS_HELP_STRING([--with-winapi], [Select Windows API support (@<:@wmme|directx|asio|wasapi|wdmks@:>@@<:@,...@:>@) @<:@wmme@:>@]), [with_winapi=$withval], [with_winapi="wmme"]) case "$target_os" in *mingw* | *cygwin*) with_wmme=no with_directx=no with_asio=no with_wasapi=no with_wdmks=no for api in $(echo $with_winapi | sed 's/,/ /g'); do case "$api" in wmme|directx|asio|wasapi|wdmks) eval with_$api=yes ;; *) AC_MSG_ERROR([unknown Windows API \"$api\" (do you need --help?)]) ;; esac done ;; esac AC_ARG_WITH(asiodir, AS_HELP_STRING([--with-asiodir], [ASIO directory @<:@/usr/local/asiosdk2@:>@]), with_asiodir=$withval, with_asiodir="/usr/local/asiosdk2") AC_ARG_WITH(dxdir, AS_HELP_STRING([--with-dxdir], [DirectX directory @<:@/usr/local/dx7sdk@:>@]), with_dxdir=$withval, with_dxdir="/usr/local/dx7sdk") debug_output=no AC_ARG_ENABLE(debug-output, AS_HELP_STRING([--enable-debug-output], [Enable debug output @<:@no@:>@]), [if test "x$enableval" != "xno" ; then AC_DEFINE(PA_ENABLE_DEBUG_OUTPUT,,[Enable debugging messages]) debug_output=yes fi ]) AC_ARG_ENABLE(cxx, AS_HELP_STRING([--enable-cxx], [Enable C++ bindings @<:@no@:>@]), enable_cxx=$enableval, enable_cxx="no") AC_ARG_ENABLE(mac-debug, AS_HELP_STRING([--enable-mac-debug], [Enable Mac debug @<:@no@:>@]), enable_mac_debug=$enableval, enable_mac_debug="no") AC_ARG_ENABLE(mac-universal, AS_HELP_STRING([--enable-mac-universal], [Build Mac universal binaries @<:@yes@:>@]), enable_mac_universal=$enableval, enable_mac_universal="yes") dnl Continue to accept --host_os for compatibility but do not document dnl it (the correct way to change host_os is with --host=...). Moved dnl here because the empty help string generates a blank line which we dnl can use to separate PA options from libtool options. AC_ARG_WITH(host_os, [], host_os=$withval) dnl Checks for programs. AC_PROG_CC dnl ASIO and CXX bindings need a C++ compiler if [[ "$with_asio" = "yes" ] || [ "$enable_cxx" = "yes" ]] ; then AC_PROG_CXX fi AC_LIBTOOL_WIN32_DLL AC_PROG_LIBTOOL AC_PROG_INSTALL AC_PROG_LN_S AC_PATH_PROG(AR, ar, no) if [[ $AR = "no" ]] ; then AC_MSG_ERROR("Could not find ar - needed to create a library") fi dnl This must be one of the first tests we do or it will fail... AC_C_BIGENDIAN dnl checks for various host APIs and arguments to configure that dnl turn them on or off have_alsa=no if test "x$with_alsa" != "xno"; then AC_CHECK_LIB(asound, snd_pcm_open, have_alsa=yes, have_alsa=no) fi have_asihpi=no if test "x$with_asihpi" != "xno"; then AC_CHECK_LIB(hpi, HPI_SubSysCreate, have_asihpi=yes, have_asihpi=no, -lm) fi have_libossaudio=no have_oss=no if test "x$with_oss" != "xno"; then AC_CHECK_HEADERS([sys/soundcard.h linux/soundcard.h machine/soundcard.h], [have_oss=yes]) if test "x$have_oss" = "xyes"; then AC_CHECK_LIB(ossaudio, _oss_ioctl, have_libossaudio=yes, have_libossaudio=no) fi fi have_jack=no if test "x$with_jack" != "xno"; then PKG_CHECK_MODULES(JACK, jack, have_jack=yes, have_jack=no) fi dnl sizeof checks: we will need a 16-bit and a 32-bit type AC_CHECK_SIZEOF(short) AC_CHECK_SIZEOF(int) AC_CHECK_SIZEOF(long) save_LIBS="${LIBS}" AC_CHECK_LIB(rt, clock_gettime, [rt_libs=" -lrt"]) LIBS="${LIBS}${rt_libs}" DLL_LIBS="${DLL_LIBS}${rt_libs}" AC_CHECK_FUNCS([clock_gettime nanosleep]) LIBS="${save_LIBS}" dnl LT_RELEASE=19 LT_CURRENT=2 LT_REVISION=0 LT_AGE=0 AC_SUBST(LT_CURRENT) AC_SUBST(LT_REVISION) AC_SUBST(LT_AGE) dnl extra variables AC_SUBST(OTHER_OBJS) AC_SUBST(PADLL) AC_SUBST(SHARED_FLAGS) AC_SUBST(THREAD_CFLAGS) AC_SUBST(DLL_LIBS) AC_SUBST(CXXFLAGS) AC_SUBST(NASM) AC_SUBST(NASMOPT) AC_SUBST(INCLUDES) dnl -g is optional on darwin if ( echo "${host_os}" | grep ^darwin >> /dev/null ) && [[ "$enable_mac_universal" = "yes" ] && [ "$enable_mac_debug" != "yes" ]] ; then CFLAGS="-O2 -Wall -pedantic -pipe -fPIC -DNDEBUG" else CFLAGS=${CFLAGS:-"-g -O2 -Wall -pedantic -pipe -fPIC"} fi if [[ $ac_cv_c_bigendian = "yes" ]] ; then CFLAGS="$CFLAGS -DPA_BIG_ENDIAN" else CFLAGS="$CFLAGS -DPA_LITTLE_ENDIAN" fi add_objects() { for o in $@; do test "${OTHER_OBJS#*${o}*}" = "${OTHER_OBJS}" && OTHER_OBJS="$OTHER_OBJS $o" done } INCLUDES=portaudio.h dnl Include directories needed by all implementations CFLAGS="$CFLAGS -I\$(top_srcdir)/include -I\$(top_srcdir)/src/common" case "${host_os}" in darwin* ) dnl Mac OS X configuration AC_DEFINE(PA_USE_COREAUDIO,1) CFLAGS="$CFLAGS -I\$(top_srcdir)/src/os/unix -Werror" LIBS="-framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon" if test "x$enable_mac_universal" = "xyes" ; then case `xcodebuild -version | sed -n 's/Xcode \(.*\)/\1/p'` in [12]*|3.0|3.1) dnl In pre-3.2 versions of Xcode, xcodebuild doesn't dnl support -sdk, so we can't use that to look for dnl SDKs. However, in those versions of Xcode, the dnl SDKs are under /Developer/SDKs, so we can just look dnl there. Also, we assume they had no SDKs later dnl than 10.5, as 3.2 was the version that came with dnl 10.6, at least if the Wikipedia page for Xcode dnl is to be believed. if [[ -d /Developer/SDKs/MacOSX10.5.sdk ]] ; then mac_version_min="-mmacosx-version-min=10.3" mac_sysroot="-isysroot /Developer/SDKs/MacOSX10.5.sdk" else mac_version_min="-mmacosx-version-min=10.3" mac_sysroot="-isysroot /Developer/SDKs/MacOSX10.4u.sdk" fi ;; *) dnl In 3.2 and later, xcodebuild supports -sdk, and, in dnl 4.3 and later, the SDKs aren't under /Developer/SDKs dnl as there *is* no /Developer, so we use -sdk to check dnl what SDKs are available and to get the full path of dnl the SDKs. if xcodebuild -version -sdk macosx10.5 Path >/dev/null 2>&1 ; then mac_version_min="-mmacosx-version-min=10.3" mac_sysroot="-isysroot `xcodebuild -version -sdk macosx10.5 Path`" elif xcodebuild -version -sdk macosx10.6 Path >/dev/null 2>&1 ; then mac_version_min="-mmacosx-version-min=10.4" mac_sysroot="-isysroot `xcodebuild -version -sdk macosx10.6 Path`" elif xcodebuild -version -sdk macosx10.7 Path >/dev/null 2>&1 ; then mac_version_min="-mmacosx-version-min=10.4" mac_sysroot="-isysroot `xcodebuild -version -sdk macosx10.7 Path`" else AC_MSG_ERROR([Couldn't find 10.5, 10.6, or 10.7 SDK]) fi esac dnl Pick which architectures to build for based on what dnl the compiler supports. mac_arches="" for arch in i386 x86_64 ppc ppc64 do save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -arch $arch" AC_TRY_COMPILE([], [return 0;], [ if [[ -z "$mac_arches" ]] ; then mac_arches="-arch $arch" else mac_arches="$mac_arches -arch $arch" fi ]) CFLAGS="$save_CFLAGS" done else mac_arches="" mac_sysroot="" mac_version="" fi SHARED_FLAGS="$LIBS -dynamiclib $mac_arches $mac_sysroot $mac_version_min" CFLAGS="-std=c99 $CFLAGS $mac_arches $mac_sysroot $mac_version_min" OTHER_OBJS="src/os/unix/pa_unix_hostapis.o src/os/unix/pa_unix_util.o src/hostapi/coreaudio/pa_mac_core.o src/hostapi/coreaudio/pa_mac_core_utilities.o src/hostapi/coreaudio/pa_mac_core_blocking.o src/common/pa_ringbuffer.o" PADLL="libportaudio.dylib" ;; mingw* ) dnl MingW configuration PADLL="portaudio.dll" THREAD_CFLAGS="-mthreads" SHARED_FLAGS="-shared" CFLAGS="$CFLAGS -I\$(top_srcdir)/src/os/win -DPA_USE_WMME=0 -DPA_USE_ASIO=0 -DPA_USE_WDMKS=0 -DPA_USE_DS=0 -DPA_USE_WASAPI=0" if [[ "x$with_directx" = "xyes" ]]; then DXDIR="$with_dxdir" add_objects src/hostapi/dsound/pa_win_ds.o src/hostapi/dsound/pa_win_ds_dynlink.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o src/os/win/pa_win_coinitialize.o src/os/win/pa_win_waveformat.o LIBS="${LIBS} -lwinmm -lm -ldsound -lole32" DLL_LIBS="${DLL_LIBS} -lwinmm -lm -L$DXDIR/lib -ldsound -lole32" #VC98="\"/c/Program Files/Microsoft Visual Studio/VC98/Include\"" #CFLAGS="$CFLAGS -I$VC98 -DPA_NO_WMME -DPA_NO_ASIO" CFLAGS="$CFLAGS -I$DXDIR/include -UPA_USE_DS -DPA_USE_DS=1" fi if [[ "x$with_asio" = "xyes" ]]; then ASIODIR="$with_asiodir" add_objects src/hostapi/asio/pa_asio.o src/common/pa_ringbuffer.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o src/os/win/pa_win_coinitialize.o src/hostapi/asio/iasiothiscallresolver.o $ASIODIR/common/asio.o $ASIODIR/host/asiodrivers.o $ASIODIR/host/pc/asiolist.o LIBS="${LIBS} -lwinmm -lm -lole32 -luuid" DLL_LIBS="${DLL_LIBS} -lwinmm -lm -lole32 -luuid" CFLAGS="$CFLAGS -ffast-math -fomit-frame-pointer -I\$(top_srcdir)/src/hostapi/asio -I$ASIODIR/host/pc -I$ASIODIR/common -I$ASIODIR/host -UPA_USE_ASIO -DPA_USE_ASIO=1 -DWINDOWS" dnl Setting the windows version flags below resolves a conflict between Interlocked* dnl definitions in mingw winbase.h and Interlocked* hacks in ASIO SDK combase.h dnl combase.h is included by asiodrvr.h dnl PortAudio does not actually require Win XP (winver 501) APIs CFLAGS="$CFLAGS -D_WIN32_WINNT=0x0501 -DWINVER=0x0501" CXXFLAGS="$CFLAGS" fi if [[ "x$with_wdmks" = "xyes" ]]; then DXDIR="$with_dxdir" add_objects src/hostapi/wdmks/pa_win_wdmks.o src/common/pa_ringbuffer.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o src/os/win/pa_win_wdmks_util.o src/os/win/pa_win_waveformat.o LIBS="${LIBS} -lwinmm -lm -luuid -lsetupapi -lole32" DLL_LIBS="${DLL_LIBS} -lwinmm -lm -L$DXDIR/lib -luuid -lsetupapi -lole32" #VC98="\"/c/Program Files/Microsoft Visual Studio/VC98/Include\"" #CFLAGS="$CFLAGS -I$VC98 -DPA_NO_WMME -DPA_NO_ASIO" CFLAGS="$CFLAGS -I$DXDIR/include -UPA_USE_WDMKS -DPA_USE_WDMKS=1" fi if [[ "x$with_wmme" = "xyes" ]]; then add_objects src/hostapi/wmme/pa_win_wmme.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o src/os/win/pa_win_waveformat.o LIBS="${LIBS} -lwinmm -lm -lole32 -luuid" DLL_LIBS="${DLL_LIBS} -lwinmm" CFLAGS="$CFLAGS -UPA_USE_WMME -DPA_USE_WMME=1" fi if [[ "x$with_wasapi" = "xyes" ]]; then add_objects src/hostapi/wasapi/pa_win_wasapi.o src/common/pa_ringbuffer.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o src/os/win/pa_win_coinitialize.o src/os/win/pa_win_waveformat.o LIBS="${LIBS} -lwinmm -lm -lole32 -luuid" DLL_LIBS="${DLL_LIBS} -lwinmm -lole32" CFLAGS="$CFLAGS -I\$(top_srcdir)/src/hostapi/wasapi/mingw-include -UPA_USE_WASAPI -DPA_USE_WASAPI=1" fi ;; cygwin* ) dnl Cygwin configuration OTHER_OBJS="src/hostapi/wmme/pa_win_wmme.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o src/os/win/pa_win_waveformat.o" CFLAGS="$CFLAGS -I\$(top_srcdir)/src/os/win -DPA_USE_DS=0 -DPA_USE_WDMKS=0 -DPA_USE_ASIO=0 -DPA_USE_WASAPI=0 -DPA_USE_WMME=1" LIBS="-lwinmm -lm" PADLL="portaudio.dll" THREAD_CFLAGS="-mthreads" SHARED_FLAGS="-shared" DLL_LIBS="${DLL_LIBS} -lwinmm" ;; irix* ) dnl SGI IRIX audio library (AL) configuration (Pieter, oct 2-13, 2003). dnl The 'dmedia' library is needed to read the Unadjusted System Time (UST). dnl AC_CHECK_LIB(pthread, pthread_create, , AC_MSG_ERROR([IRIX posix thread library not found!])) AC_CHECK_LIB(audio, alOpenPort, , AC_MSG_ERROR([IRIX audio library not found!])) AC_CHECK_LIB(dmedia, dmGetUST, , AC_MSG_ERROR([IRIX digital media library not found!])) dnl See the '#ifdef PA_USE_SGI' in file pa_unix/pa_unix_hostapis.c dnl which selects the appropriate PaXXX_Initialize() function. dnl AC_DEFINE(PA_USE_SGI,1) CFLAGS="$CFLAGS -I\$(top_srcdir)/src/os/unix" dnl The _REENTRANT option for pthread safety. Perhaps not necessary but it 'll do no harm. dnl THREAD_CFLAGS="-D_REENTRANT" OTHER_OBJS="pa_sgi/pa_sgi.o src/os/unix/pa_unix_hostapis.o src/os/unix/pa_unix_util.o" dnl SGI books say -lpthread should be the last of the libs mentioned. dnl LIBS="-lm -ldmedia -laudio -lpthread" PADLL="libportaudio.so" SHARED_FLAGS="" ;; *) dnl Unix configuration CFLAGS="$CFLAGS -I\$(top_srcdir)/src/os/unix" AC_CHECK_LIB(pthread, pthread_create,[have_pthread="yes"], AC_MSG_ERROR([libpthread not found!])) if [[ "$have_alsa" = "yes" ] && [ "$with_alsa" != "no" ]] ; then DLL_LIBS="$DLL_LIBS -lasound" LIBS="$LIBS -lasound" OTHER_OBJS="$OTHER_OBJS src/hostapi/alsa/pa_linux_alsa.o" INCLUDES="$INCLUDES pa_linux_alsa.h" AC_DEFINE(PA_USE_ALSA,1) fi if [[ "$have_jack" = "yes" ] && [ "$with_jack" != "no" ]] ; then DLL_LIBS="$DLL_LIBS $JACK_LIBS" CFLAGS="$CFLAGS $JACK_CFLAGS" OTHER_OBJS="$OTHER_OBJS src/hostapi/jack/pa_jack.o src/common/pa_ringbuffer.o" INCLUDES="$INCLUDES pa_jack.h" AC_DEFINE(PA_USE_JACK,1) fi if [[ "$with_oss" != "no" ]] ; then OTHER_OBJS="$OTHER_OBJS src/hostapi/oss/pa_unix_oss.o" if [[ "$have_libossaudio" = "yes" ]] ; then DLL_LIBS="$DLL_LIBS -lossaudio" LIBS="$LIBS -lossaudio" fi AC_DEFINE(PA_USE_OSS,1) fi if [[ "$have_asihpi" = "yes" ] && [ "$with_asihpi" != "no" ]] ; then LIBS="$LIBS -lhpi" DLL_LIBS="$DLL_LIBS -lhpi" OTHER_OBJS="$OTHER_OBJS src/hostapi/asihpi/pa_linux_asihpi.o" AC_DEFINE(PA_USE_ASIHPI,1) fi DLL_LIBS="$DLL_LIBS -lm -lpthread" LIBS="$LIBS -lm -lpthread" PADLL="libportaudio.so" ## support sun cc compiler flags case "${host_os}" in solaris*) SHARED_FLAGS="-G" THREAD_CFLAGS="-mt" ;; *) SHARED_FLAGS="-fPIC" THREAD_CFLAGS="-pthread" ;; esac OTHER_OBJS="$OTHER_OBJS src/os/unix/pa_unix_hostapis.o src/os/unix/pa_unix_util.o" esac CFLAGS="$CFLAGS $THREAD_CFLAGS" test "$enable_shared" != "yes" && SHARED_FLAGS="" if test "$enable_cxx" = "yes"; then AC_CONFIG_SUBDIRS([bindings/cpp]) ENABLE_CXX_TRUE="" ENABLE_CXX_FALSE="#" else ENABLE_CXX_TRUE="#" ENABLE_CXX_FALSE="" fi AC_SUBST(ENABLE_CXX_TRUE) AC_SUBST(ENABLE_CXX_FALSE) if test "x$with_asio" = "xyes"; then WITH_ASIO_TRUE="" WITH_ASIO_FALSE="@ #" else WITH_ASIO_TRUE="@ #" WITH_ASIO_FALSE="" fi AC_SUBST(WITH_ASIO_TRUE) AC_SUBST(WITH_ASIO_FALSE) AC_OUTPUT([Makefile portaudio-2.0.pc]) AC_MSG_RESULT([ Configuration summary: Target ...................... $target C++ bindings ................ $enable_cxx Debug output ................ $debug_output]) case "$target_os" in *linux*) AC_MSG_RESULT([ ALSA ........................ $have_alsa ASIHPI ...................... $have_asihpi]) ;; esac case "$target_os" in *mingw* | *cygwin*) test "x$with_directx" = "xyes" && with_directx="$with_directx (${with_dxdir})" test "x$with_wdmks" = "xyes" && with_wdmks="$with_wdmks (${with_dxdir})" test "x$with_asio" = "xyes" && with_asio="$with_asio (${with_asiodir})" test "x$with_wasapi" = "xyes" AC_MSG_RESULT([ WMME ........................ $with_wmme DSound ...................... $with_directx ASIO ........................ $with_asio WASAPI ...................... $with_wasapi WDMKS ....................... $with_wdmks ]) ;; *darwin*) AC_MSG_RESULT([ Mac debug flags ............. $enable_mac_debug ]) ;; *) AC_MSG_RESULT([ OSS ......................... $have_oss JACK ........................ $have_jack ]) ;; esac pd-0.46-7/man/0000775000175000017500000000000012160204055011142 5ustar mspmsppd-0.46-7/man/pd.10000664000175000017500000000116312160204055011630 0ustar mspmsp.TH pd 1 "1996 Mar 20" GNU .SH NAME pd \- pure data .SH DESCRIPTION Pd is a graphical programming environment for real-time audio synthesis and related applications. It sports a rich set of real-time control and I/O features. .PP To get a list of allowable arguments to pd, type .IP .B pd -help .PP and for more documentation either start pd and get help, or consult .PP .B http://www.crca.ucsd.edu/~msp/Pd_documentation/index.htm .PP or seek a copy on your own machine, perhaps in .PP .B file:/usr/local/bin/pd/doc/1.manual/index.htm .PP or .PP .B file:/usr/bin/pd/doc/1.manual/index.htm .SH SEE ALSO pdsend(1), pdreceive(1) pd-0.46-7/man/Makefile.am0000664000175000017500000000005212160204055013173 0ustar mspmspdist_man_MANS = pd.1 pdsend.1 pdreceive.1 pd-0.46-7/man/pdreceive.10000664000175000017500000000211512160204055013171 0ustar mspmsp.TH pdreceive 1 "1996 Mar 20" GNU .SH NAME pdreceive \- receive messages from pd on this or a remote machine .SH SYNOPSIS .B pdreceive \fIport-number\fR [udp|tcp] .SH DESCRIPTION Pdreceive opens a socket (with the specified port number) and waits for messages to arrive from one or more instances of pd(1). Each message received is printed to the standard output with a trailing semicolon. The protocol used is easy to implement and is called FUDI. .PP The \fIport number\fR should agree with the port number of a "netsend" object within pd. The protocol is "tcp" by default; this does a handshake to guarantee that all messages arrive complete and in their correct order; if you are sending messages locally or point-to-point you can often get away with the faster udp protocol instead. .PP You can also use this to get messages from a Max "pdnetsend" object or even just a "pdsend" in another shell. If you're writing another program you're welcome to just grab the sources for pdsend/pdreceive and adapt them to your own ends; they're part of the Pd distribution. .SH SEE ALSO pd(1), pdsend(1) pd-0.46-7/man/pdsend.10000664000175000017500000000227512160204055012507 0ustar mspmsp.TH pdsend 1 "1996 Mar 20" GNU .SH NAME pdsend \- send messages to pd on this or a remote machine .SH SYNOPSIS .B pdsend \fIport-number\fR [\fIhostname\fR] [udp|tcp] .SH DESCRIPTION Pdsend sends messages to pd(1), via a socket conection, from pdsend's standard input. This input can be any stream of Pd messages separated by semicolons. This is probably the easiest way to control pd from another application. The protocol used is easy to implement and is called FUDI. .PP The \fIport number\fR should agree with the port number of a "netreceive" object within pd. The \fIhostname\fR is "localhost" by default and can be a domain name or an IP address. The protocol is "tcp" by default; this does a handshake to guarantee that all messages arrive complete and in their correct order; if you are sending messages locally or point-to-point you can often get away with the faster udp protocol instead. .PP You can also use this to talk to a Max "pdnetreceive" object or even just a "pdreceive" in another shell. If you're writing another program you're welcome to just grab the sources for pdsend/pdreceive and adapt them to your own ends; they're part of the Pd distribution. .SH SEE ALSO pd(1), pdreceive(1) pd-0.46-7/extra/0000775000175000017500000000000012574202336011523 5ustar mspmsppd-0.46-7/extra/makefile.subdir0000664000175000017500000000464512574135745014534 0ustar mspmsp# this is the UNIX-style complicated layout dir, simple goes to $(prefix)/pd prefix = /usr/local libpddir = $(prefix)/lib/pd .PHONY: current: pd_linux # ----------------------- Microsoft Visual C ----------------------- MSCC = cl MSLN = link pd_nt: $(NAME).dll .SUFFIXES: .dll PDNTCFLAGS = /W3 /WX /DNT /DPD /nologo -D_CRT_SECURE_NO_WARNINGS \ -D_CRT_NONSTDC_NO_DEPRECATE VC = "C:\\Program Files\\Microsoft Visual Studio 9.0\\VC" VSTK = "C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0A" PDNTINCLUDE = /I. /I..\\..\\src /I$(VC)\\include /I$(VSTK)\\include PDNTLDIR = $(VC)\\lib PDNTLIB = /NODEFAULTLIB:libcmt /NODEFAULTLIB:oldnames /NODEFAULTLIB:kernel32 \ /NODEFAULTLIB:uuid \ $(PDNTLDIR)\\libcmt.lib $(PDNTLDIR)\\oldnames.lib \ $(VSTK)\\lib\\kernel32.lib $(VSTK)\\lib\\uuid.lib \ ..\\..\\bin\\pd.lib .c.dll: $(MSCC) $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c $(MSLN) /nologo /dll /export:$(CSYM)_setup $*.obj $(PDNTLIB) # ----------------------- LINUX i386 ----------------------- pd_linux: $(NAME).pd_linux .SUFFIXES: .pd_linux LINUXCFLAGS = -DPD -O2 -funroll-loops -fomit-frame-pointer -fPIC \ -Wall -W -Wshadow -Wstrict-prototypes \ -Wno-unused -Wno-unused-parameter -Wno-parentheses -Wno-switch $(CFLAGS) LINUXINCLUDE = -I../../src .c.pd_linux: $(CC) $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c $(CC) -shared -o $*.pd_linux $*.o -lc -lm rm -f $*.o # ----------------------- Mac OSX ----------------------- d_ppc: $(NAME).d_ppc d_fat: $(NAME).d_fat DARWINARCH= -arch i386 -arch x86_64 -arch ppc .SUFFIXES: .d_ppc .d_fat DARWINCFLAGS = -DPD -O2 -Wall -W -Wshadow -Wstrict-prototypes \ -Wno-unused -Wno-parentheses -Wno-switch .c.d_ppc: $(CC) $(DARWINCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c $(CC) -bundle -undefined suppress -flat_namespace -o $*.pd_darwin $*.o rm -f $*.o .c.d_fat: $(CC) $(DARWINARCH) $(DARWINCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c $(CC) $(DARWINARCH) -bundle -undefined suppress -flat_namespace \ -o $*.d_fat $*.o rm -f $*.o # ---------------------------------------------------------- distclean clean: clean-externals rm -f *.o *.pd_* *.l_* *.d_* *.m_* so_locations # ---------------------------------------------------------- # ---------------------------------------------------------- install: install -d $(DESTDIR)$(libpddir)/extra/$(NAME) install -m644 -p *.*_* $(DESTDIR)$(libpddir)/extra/$(NAME) install -m644 -p *.pd $(DESTDIR)$(libpddir)/extra/$(NAME) pd-0.46-7/extra/sigmund~/0000775000175000017500000000000012574202336013367 5ustar mspmsppd-0.46-7/extra/sigmund~/GNUmakefile.am0000664000175000017500000000126612374250720016040 0ustar mspmsp## Makefile.am -- Process this file with automake to produce Makefile.in NAME=sigmund~ external_LTLIBRARIES = sigmund~.la SOURCES = sigmund~.c PATCHES = sigmund~-help.pd OTHERDATA = EXTRA_DIST = makefile ############################### # you shouldn't need to add anything below here dist_external_DATA = $(PATCHES) $(OTHERDATA) AUTOMAKE_OPTIONS = foreign AM_CPPFLAGS = -I$(top_srcdir)/src -DPD AM_CFLAGS = @ARCH_CFLAGS@ AM_LIBS = $(LIBM) AM_LDFLAGS = -module -avoid-version -shared @ARCH_LDFLAGS@ -shrext .@EXTERNAL_EXTENSION@ -L$(top_srcdir)/src externaldir = $(pkglibdir)/extra/$(NAME) if MINGW AM_LIBS += -lpd endif libtool: $(LIBTOOL_DEPS) $(SHELL) ./config.status --recheck pd-0.46-7/extra/sigmund~/makefile0000664000175000017500000000007512160204055015060 0ustar mspmspNAME=sigmund~ CSYM=sigmund_tilde include ../makefile.subdir pd-0.46-7/extra/sigmund~/sigmund~-help.pd0000664000175000017500000001737512374250720016521 0ustar mspmsp#N canvas 166 52 580 693 12; #X text 42 4 sigmund~ - sinusoidal analysis and pitch tracking; #N canvas 432 117 573 597 using-with-tables 0; #X obj 29 368 print peak; #N canvas 0 50 450 300 (subpatch) 0; #X array insignal 1024 float 2; #X coords 0 1 1023 -1 200 140 1; #X restore 83 426 graph; #X obj 314 513 phasor~; #X obj 294 429 loadbang; #X obj 314 461 440; #X floatatom 313 488 5 0 0 0 - - -, f 5; #X obj 305 544 tabwrite~ insignal; #X obj 290 516 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X text 114 11 Using sigmund~ on arrays; #X text 42 33 If invoked with the "-t" flag (as a creation argument) \, sigmund~ analyzes waveforms stored in arrays. Instead of an incoming signal \, feed it "list" messages with the following arguments:; #X text 37 118 table name (a symbol); #X text 38 137 number of points; #X obj 29 342 sigmund~ -t -npeak 10 -maxfreq 5000 peaks; #X msg 29 316 list insignal 1024 0 44100 0; #X text 37 158 index of first point; #X text 39 179 sample rate; #X text 38 200 debug flag (print debugging info if nonzero); #X text 23 232 In this mode \, only the "env" \, "pitch" \, and "peaks" outputs are meaningful.; #X text 31 294 click here to test:; #X connect 2 0 6 0; #X connect 3 0 4 0; #X connect 4 0 5 0; #X connect 5 0 2 0; #X connect 5 0 7 0; #X connect 7 0 6 0; #X connect 12 0 0 0; #X connect 13 0 12 0; #X restore 330 592 pd using-with-tables; #X obj 40 551 phasor~; #X obj 40 464 loadbang; #X floatatom 40 510 5 0 120 0 - - -, f 5; #X floatatom 39 600 5 0 0 0 - - -, f 5; #X floatatom 245 602 5 0 0 0 - - -, f 5; #X obj 40 529 mtof; #X obj 40 487 69; #X text 38 618 pitch; #X text 222 621 envelope; #X text 13 28 Sigmund~ analyzes an incoming sound into sinusoidal components \, which may be reported individually or combined to form a pitch estimate. Possible outputs are specified as creation arguments:; #X text 56 95 pitch - output pitch continuously; #N canvas 517 73 588 728 setting-parameters 0; #X msg 182 66 print; #X floatatom 192 92 5 0 0 0 - - -, f 5; #X msg 192 113 minpower \$1; #X obj 182 139 sigmund~ -minpower 40; #X text 39 14 You can set parameters either by creation arguments \, or else using messages. The "print" message gives you the current values of all the parameters:; #X text 28 169 npts: number of points used in an analysis. Must be a power of two \, at least 128 The minimum frequency that can be tracked is about 2(sample_rate)/npts.; #X text 26 219 hop: number of points between analyses. Must be a power of two \, at least the DSP vector size (usually 64). This regulates the number of analyses done per unit of time.; #X text 28 271 npeak: maximum number of sinusoidal peaks to look for. The computation time is quadratic in the number of peaks actually found (this number only sets an upper limit). Use it to balance CPU time with quality of results.; #X text 30 336 maxfreq: maximum frequency of sinusoidal peaks to look for. This can be useful in situations where background noise creates high-frequency \, spurious peaks..; #X text 37 388 vibrato: maximum deviation from "pitch" to accept as normal vibrato (affects "notes" output only). If the value is too small. vibratos will appear as trills. If too large \, very small melodic intervals may not be reported as new notes.; #X text 33 457 stabletime: time period to wait before reporting a note (affects "notes" output only). The "pitch" must be present and must not vary more than "vibrato" for this entire period to report a note. If too large \, the "notes" will be unnecessarily delayed. If too small \, spurious notes get output.; #X text 34 606 growth: minimum measured RMS growth to report a new note (affects "notes" output only). The RMS level must rise by this many dB (within a time period given by "stabletime") to report a repetition of a note at or near the previously output pitch.; #X text 33 555 minpower: minimum measured RMS level to report a pitch (affects "notes" output only). Signals quieter than this will be assumed to be crosstalk and ignored.; #X connect 0 0 3 0; #X connect 1 0 2 0; #X connect 2 0 3 0; #X restore 330 570 pd setting-parameters; #N canvas 67 50 641 815 sinusoid-tracking 0; #X obj 124 267 sigmund~ -npeak 10 peaks; #X obj 124 214 phasor~; #X obj 124 144 loadbang; #X floatatom 124 190 5 0 120 0 - - -, f 5; #X obj 124 295 route 0 1 2 3 4 5 6 7 8 9; #X obj 82 339 unpack 0 0 0 0; #X floatatom 82 461 5 0 0 0 - - -, f 5; #X floatatom 122 431 5 0 0 0 - - -, f 5; #X floatatom 162 406 5 0 0 0 - - -, f 5; #X obj 124 167 440; #X floatatom 203 380 5 0 0 0 - - -, f 5; #X obj 322 349 unpack 0 0 0 0; #X floatatom 322 471 5 0 0 0 - - -, f 5; #X floatatom 362 441 5 0 0 0 - - -, f 5; #X floatatom 402 416 5 0 0 0 - - -, f 5; #X floatatom 443 390 5 0 0 0 - - -, f 5; #X text 385 475 frequency (Hz.); #X text 419 442 peak amplitude (linear); #X text 464 416 cosine component; #X text 499 390 sine component; #X text 79 505 loudest partial; #X text 332 508 quietest partial; #X text 36 4 You can ask for sinusoidal peaks in decreasing order of amplitude or arranged into maximally continuous tracks for resynthesis. (Or you can ask for both.) If you ask for peaks \, out come lists of five numbers \, one for each sinusoid at each analysis period. The first is the index number of the sinusoid (so you can use "route" to claw them apart). The other four are as shown:; #X obj 204 611 osc~ 440; #X obj 204 635 *~; #X obj 205 689 unpack 0 0 0 0; #X floatatom 205 782 5 0 0 0 - - -, f 5; #X floatatom 245 760 5 0 0 0 - - -, f 5; #X floatatom 285 737 5 0 0 0 - - -, f 5; #X floatatom 326 713 5 0 0 0 - - -, f 5; #X obj 246 638 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X text 43 535 If you ask for "tracks" \, the output is four numbers: index \, frequency \, and amplitude as before \, and finally a flag which is one for a new track \, zero for a continuation \, minus one for an empty track.; #X obj 205 662 sigmund~ -npts 16384 -hop 8192 -npeak 1 tracks; #X connect 0 0 4 0; #X connect 1 0 0 0; #X connect 2 0 9 0; #X connect 3 0 1 0; #X connect 4 0 5 0; #X connect 4 9 11 0; #X connect 5 0 6 0; #X connect 5 1 7 0; #X connect 5 2 8 0; #X connect 5 3 10 0; #X connect 9 0 3 0; #X connect 11 0 12 0; #X connect 11 1 13 0; #X connect 11 2 14 0; #X connect 11 3 15 0; #X connect 23 0 24 0; #X connect 24 0 32 0; #X connect 25 0 26 0; #X connect 25 1 27 0; #X connect 25 2 28 0; #X connect 25 3 29 0; #X connect 30 0 24 1; #X connect 32 0 25 0; #X restore 330 547 pd sinusoid-tracking; #X text 52 165 tracks - output sinusoidal peaks organized into tracks ; #X text 56 111 notes - output pitch at the beginning of notes; #X text 339 524 more details:; #X text 10 184 Parameters you may set (in creation arguments or messages): ; #X text 60 207 npts - number of points in each analysis window (1024) ; #X text 60 225 hop - number of points between each analysis (512); #X text 60 242 npeak - number of sinusoidal peaks (20); #X text 61 318 vibrato - depth of vibrato to expect in 1/2-tones (1) ; #X obj 39 574 sigmund~ -hop 4096 pitch env; #X text 54 147 peaks - output all sinusoidal peaks in order of amplitude ; #X text 11 395 The npts and hop parameters are in samples \, and are powers of two. The example below specifies a huge hop of 4096 (to slow the output down) and to output "pitch" and "env". (Those are the default outputs.); #X text 61 260 maxfreq - maximum sinusoid frequency in Hz. (1000000) ; #X text 55 128 env - output amplitude continuously; #X text 121 281 (... the 4 parameters below affect only note detection \, not raw pitch:), f 36; #X text 60 337 stabletime - time (msec) to wait to report notes (50) ; #X text 62 355 minpower - minimum power (dB) to report a note (50) ; #X text 62 374 growth - growth (dB) to report a repeated note (7); #X text 383 656 updated for Pd v0.46; #X connect 2 0 23 0; #X connect 3 0 8 0; #X connect 4 0 7 0; #X connect 7 0 2 0; #X connect 8 0 4 0; #X connect 23 0 5 0; #X connect 23 1 6 0; pd-0.46-7/extra/sigmund~/sigmund~.c0000664000175000017500000015055212441410277015405 0ustar mspmsp/* Copyright (c) 2005 Miller Puckette. BSD licensed. No warranties. */ /* fix parameter settings not to report pitch if evidence too scanty? note-on detection triggered by falling envelope (a posteriori) reentrancy bug setting loud flag (other parameters too?) tweaked freqs still not stable enough implement block ("-b") mode */ #ifdef PD #include "m_pd.h" #endif #ifdef MSP #include "ext.h" #include "z_dsp.h" #include "ext_support.h" #include "ext_proto.h" #include "ext_obex.h" typedef double t_floatarg; #define t_resizebytes(a, b, c) t_resizebytes((char *)(a), (b), (c)) #endif /* From here to the next "#ifdef PD" or "#ifdef Max" should be extractable and usable in other contexts. The one external requirement is a real single-precision FFT, invoked as in the Mayer one: */ #ifdef _MSC_VER /* this is only needed with Microsoft's compiler */ __declspec(dllimport) extern #endif void mayer_realfft(int npoints, t_sample *buf); /* this routine is passed a buffer of npoints values, and returns the N/2+1 real parts of the DFT (frequency zero through Nyquist), followed by the N/2-1 imaginary points, in order of decreasing frequency. Pd 0.41, for example, defines this in the file d_fft_mayer.c or d_fft_fftsg.c. */ #include #include #include #ifdef _WIN32 #include #elif ! defined(_MSC_VER) #include #endif #include #ifdef _MSC_VER #pragma warning( disable : 4244 ) #pragma warning( disable : 4305 ) #endif typedef struct peak { t_float p_freq; t_float p_amp; t_float p_ampreal; t_float p_ampimag; t_float p_pit; t_float p_db; t_float p_salience; t_float p_tmp; } t_peak; /********************** service routines **************************/ /* these three are dapted from elsewhere in Pd but included here for cmolpeteness */ static int sigmund_ilog2(int n) { int ret = -1; while (n) { n >>= 1; ret++; } return (ret); } static t_float sigmund_ftom(t_float f) { return (f > 0 ? 17.3123405046 * log(.12231220585 * f) : -1500); } #define LOGTEN 2.302585092994 static t_float sigmund_powtodb(t_float f) { if (f <= 0) return (0); else { t_float val = 100 + 10./LOGTEN * log(f); return (val < 0 ? 0 : val); } } /* parameters for von Hann window (change these to get Hamming if desired) */ #define W_ALPHA 0.5 #define W_BETA 0.5 #define NEGBINS 4 /* number of bins of negative frequency we'll need */ #define PI 3.141592653589793 #define LOG2 0.693147180559945 #define LOG10 2.302585092994046 static t_float sinx(t_float theta, t_float sintheta) { if (theta > -0.003 && theta < 0.003) return (1); else return (sintheta/theta); } static t_float window_hann_mag(t_float pidetune, t_float sinpidetune) { return (W_ALPHA * sinx(pidetune, sinpidetune) - 0.5 * W_BETA * (sinx(pidetune+PI, sinpidetune) + sinx(pidetune-PI, sinpidetune))); } static t_float window_mag(t_float pidetune, t_float cospidetune) { return (sinx(pidetune + (PI/2), cospidetune) + sinx(pidetune - (PI/2), -cospidetune)); } /*********** Routines to analyze a window into sinusoidal peaks *************/ static int sigmund_cmp_freq(const void *p1, const void *p2) { if ((*(t_peak **)p1)->p_freq > (*(t_peak **)p2)->p_freq) return (1); else if ((*(t_peak **)p1)->p_freq < (*(t_peak **)p2)->p_freq) return (-1); else return (0); } static void sigmund_tweak(int npts, t_float *ftreal, t_float *ftimag, int npeak, t_peak *peaks, t_float fperbin, int loud) { t_peak **peakptrs = (t_peak **)alloca(sizeof (*peakptrs) * (npeak+1)); t_peak negpeak; int peaki, j, k; t_float ampreal[3], ampimag[3]; t_float binperf = 1./fperbin; t_float phaseperbin = (npts-0.5)/npts, oneovern = 1./npts; if (npeak < 1) return; for (peaki = 0; peaki < npeak; peaki++) peakptrs[peaki+1] = &peaks[peaki]; qsort(peakptrs+1, npeak, sizeof (*peakptrs), sigmund_cmp_freq); peakptrs[0] = &negpeak; negpeak.p_ampreal = peakptrs[1]->p_ampreal; negpeak.p_ampimag = -peakptrs[1]->p_ampimag; negpeak.p_freq = -peakptrs[1]->p_freq; for (peaki = 1; peaki <= npeak; peaki++) { int cbin = peakptrs[peaki]->p_freq*binperf + 0.5; int nsub = (peaki == npeak ? 1:2); t_float windreal, windimag, windpower, detune, pidetune, sinpidetune, cospidetune, ampcorrect, ampout, ampoutreal, ampoutimag, freqout; /* post("3 nsub %d amp %f freq %f", nsub, peakptrs[peaki]->p_amp, peakptrs[peaki]->p_freq); */ if (cbin < 0 || cbin > 2*npts - 3) continue; for (j = 0; j < 3; j++) ampreal[j] = ftreal[cbin+2*j-2], ampimag[j] = ftimag[cbin+2*j-2]; /* post("a %f %f", ampreal[1], ampimag[1]); */ for (j = 0; j < nsub; j++) { t_peak *neighbor = peakptrs[(peaki-1) + 2*j]; t_float neighborreal = npts * neighbor->p_ampreal; t_float neighborimag = npts * neighbor->p_ampimag; for (k = 0; k < 3; k++) { t_float freqdiff = (0.5*PI) * ((cbin + 2*k-2) -binperf * neighbor->p_freq); t_float sx = sinx(freqdiff, sin(freqdiff)); t_float phasere = cos(freqdiff * phaseperbin); t_float phaseim = sin(freqdiff * phaseperbin); ampreal[k] -= sx * (phasere * neighborreal - phaseim * neighborimag); ampimag[k] -= sx * (phaseim * neighborreal + phasere * neighborimag); } /* post("b %f %f", ampreal[1], ampimag[1]); */ } windreal = W_ALPHA * ampreal[1] - (0.5 * W_BETA) * (ampreal[0] + ampreal[2]); windimag = W_ALPHA * ampimag[1] - (0.5 * W_BETA) * (ampimag[0] + ampimag[2]); windpower = windreal * windreal + windimag * windimag; detune = ( W_BETA*(ampreal[0] - ampreal[2]) * (2.0*W_ALPHA * ampreal[1] - W_BETA * (ampreal[0] + ampreal[2])) + W_BETA*(ampimag[0] - ampimag[2]) * (2.0*W_ALPHA * ampimag[1] - W_BETA * (ampimag[0] + ampimag[2])) ) / (4.0 * windpower); if (detune > 0.5) detune = 0.5; else if (detune < -0.5) detune = -0.5; /* if (loud > 0) post("tweak: windpower %f, bin %d, detune %f", windpower, cbin, detune); */ pidetune = PI * detune; sinpidetune = sin(pidetune); cospidetune = cos(pidetune); ampcorrect = 1.0 / window_hann_mag(pidetune, sinpidetune); ampout = oneovern * ampcorrect *sqrt(windpower); ampoutreal = oneovern * ampcorrect * (windreal * cospidetune - windimag * sinpidetune); ampoutimag = oneovern * ampcorrect * (windreal * sinpidetune + windimag * cospidetune); freqout = (cbin + 2*detune) * fperbin; /* if (loud > 1) post("amp %f, freq %f", ampout, freqout); */ peakptrs[peaki]->p_freq = freqout; peakptrs[peaki]->p_amp = ampout; peakptrs[peaki]->p_ampreal = ampoutreal; peakptrs[peaki]->p_ampimag = ampoutimag; } } static void sigmund_remask(int maxbin, int bestindex, t_float powmask, t_float maxpower, t_float *maskbuf) { int bin; int bin1 = (bestindex > 52 ? bestindex-50:2); int bin2 = (maxbin < bestindex + 50 ? bestindex + 50 : maxbin); for (bin = bin1; bin < bin2; bin++) { t_float bindiff = bin - bestindex; t_float mymask; mymask = powmask/ (1. + bindiff * bindiff * bindiff * bindiff); if (bindiff < 2 && bindiff > -2) mymask = 2*maxpower; if (mymask > maskbuf[bin]) maskbuf[bin] = mymask; } } #define PEAKMASKFACTOR 1. #define PEAKTHRESHFACTOR 0.6 static void sigmund_getrawpeaks(int npts, t_float *insamps, int npeak, t_peak *peakv, int *nfound, t_float *power, t_float srate, int loud, t_float hifreq) { t_float oneovern = 1.0/ (t_float)npts; t_float fperbin = 0.5 * srate * oneovern, totalpower = 0; int npts2 = 2*npts, i, bin; int peakcount = 0; t_float *fp1, *fp2; t_float *rawreal, *rawimag, *maskbuf, *powbuf; t_float *bigbuf = alloca(sizeof (t_float ) * (2*NEGBINS + 6*npts)); int maxbin = hifreq/fperbin; if (maxbin > npts - NEGBINS) maxbin = npts - NEGBINS; /* if (loud) post("tweak %d", tweak); */ maskbuf = bigbuf + npts2; powbuf = maskbuf + npts; rawreal = powbuf + npts+NEGBINS; rawimag = rawreal+npts+NEGBINS; for (i = 0; i < npts; i++) maskbuf[i] = 0; for (i = 0; i < npts; i++) bigbuf[i] = insamps[i]; for (i = npts; i < 2*npts; i++) bigbuf[i] = 0; mayer_realfft(npts2, bigbuf); for (i = 0; i < npts; i++) rawreal[i] = bigbuf[i]; for (i = 1; i < npts-1; i++) rawimag[i] = bigbuf[npts2-i]; rawreal[-1] = rawreal[1]; rawreal[-2] = rawreal[2]; rawreal[-3] = rawreal[3]; rawreal[-4] = rawreal[4]; rawimag[0] = rawimag[npts-1] = 0; rawimag[-1] = -rawimag[1]; rawimag[-2] = -rawimag[2]; rawimag[-3] = -rawimag[3]; rawimag[-4] = -rawimag[4]; #if 1 for (i = 0, fp1 = rawreal, fp2 = rawimag; i < maxbin; i++, fp1++, fp2++) { t_float x1 = fp1[1] - fp1[-1], x2 = fp2[1] - fp2[-1], p = powbuf[i] = x1*x1+x2*x2; if (i >= 2) totalpower += p; } powbuf[maxbin] = powbuf[maxbin+1] = 0; *power = 0.5 * totalpower *oneovern * oneovern; #endif for (peakcount = 0; peakcount < npeak; peakcount++) { t_float pow1, maxpower = 0, windreal, windimag, windpower, detune, pidetune, sinpidetune, cospidetune, ampcorrect, ampout, ampoutreal, ampoutimag, freqout, powmask; int bestindex = -1; for (bin = 2, fp1 = rawreal+2, fp2 = rawimag+2; bin < maxbin; bin++, fp1++, fp2++) { pow1 = powbuf[bin]; if (pow1 > maxpower && pow1 > maskbuf[bin]) { t_float thresh = PEAKTHRESHFACTOR * (powbuf[bin-2]+powbuf[bin+2]); if (pow1 > thresh) maxpower = pow1, bestindex = bin; } } if (totalpower <= 0 || maxpower < 1e-10*totalpower || bestindex < 0) break; fp1 = rawreal+bestindex; fp2 = rawimag+bestindex; powmask = maxpower * PEAKMASKFACTOR; /* if (loud > 2) post("maxpower %f, powmask %f, param1 %f", maxpower, powmask, param1); */ sigmund_remask(maxbin, bestindex, powmask, maxpower, maskbuf); /* if (loud > 1) post("best index %d, total power %f", bestindex, totalpower); */ windreal = fp1[1] - fp1[-1]; windimag = fp2[1] - fp2[-1]; windpower = windreal * windreal + windimag * windimag; detune = ((fp1[1] * fp1[1] - fp1[-1]*fp1[-1]) + (fp2[1] * fp2[1] - fp2[-1]*fp2[-1])) / (2 * windpower); if (detune > 0.5) detune = 0.5; else if (detune < -0.5) detune = -0.5; /* if (loud > 1) post("windpower %f, index %d, detune %f", windpower, bestindex, detune); */ pidetune = PI * detune; sinpidetune = sin(pidetune); cospidetune = cos(pidetune); ampcorrect = 1.0 / window_mag(pidetune, cospidetune); ampout = ampcorrect *sqrt(windpower); ampoutreal = ampcorrect * (windreal * cospidetune - windimag * sinpidetune); ampoutimag = ampcorrect * (windreal * sinpidetune + windimag * cospidetune); /* the frequency is the sum of the bin frequency and detuning */ peakv[peakcount].p_freq = (freqout = (bestindex + 2*detune)) * fperbin; peakv[peakcount].p_amp = oneovern * ampout; peakv[peakcount].p_ampreal = oneovern * ampoutreal; peakv[peakcount].p_ampimag = oneovern * ampoutimag; } sigmund_tweak(npts, rawreal, rawimag, peakcount, peakv, fperbin, loud); sigmund_tweak(npts, rawreal, rawimag, peakcount, peakv, fperbin, loud); for (i = 0; i < peakcount; i++) { peakv[i].p_pit = sigmund_ftom(peakv[i].p_freq); peakv[i].p_db = sigmund_powtodb(peakv[i].p_amp); } *nfound = peakcount; } /*************** Routines for finding fundamental pitch *************/ #define PITCHNPEAK 12 #define HALFTONEINC 0.059 #define SUBHARMONICS 16 #define DBPERHALFTONE 0.0 static void sigmund_getpitch(int npeak, t_peak *peakv, t_float *freqp, t_float npts, t_float srate, t_float nharmonics, t_float amppower, int loud) { t_float fperbin = 0.5 * srate / npts; int npit = 48 * sigmund_ilog2(npts), i, j, k, nsalient; t_float bestbin, bestweight, sumamp, sumweight, sumfreq, freq; t_float *weights = (t_float *)alloca(sizeof(t_float) * npit); t_peak *bigpeaks[PITCHNPEAK]; if (npeak < 1) { freq = 0; goto done; } for (i = 0; i < npit; i++) weights[i] = 0; for (i = 0; i < npeak; i++) { peakv[i].p_tmp = 0; peakv[i].p_salience = peakv[i].p_db - DBPERHALFTONE * peakv[i].p_pit; } for (nsalient = 0; nsalient < PITCHNPEAK; nsalient++) { t_peak *bestpeak = 0; t_float bestsalience = -1e20; for (j = 0; j < npeak; j++) if (peakv[j].p_tmp == 0 && peakv[j].p_salience > bestsalience) { bestsalience = peakv[j].p_salience; bestpeak = &peakv[j]; } if (!bestpeak) break; bigpeaks[nsalient] = bestpeak; bestpeak->p_tmp = 1; /* post("peak f=%f a=%f", bestpeak->p_freq, bestpeak->p_amp); */ } sumweight = 0; for (i = 0; i < nsalient; i++) { t_peak *thispeak = bigpeaks[i]; t_float weightindex = (48./LOG2) * log(thispeak->p_freq/(2.*fperbin)); t_float loudness = pow(thispeak->p_amp, amppower); /* post("index %f, uncertainty %f", weightindex, pitchuncertainty); */ for (j = 0; j < SUBHARMONICS; j++) { t_float subindex = weightindex - (48./LOG2) * log(j + 1.); int loindex = subindex - 0.5; int hiindex = loindex+2; if (hiindex < 0) break; if (hiindex >= npit) continue; if (loindex < 0) loindex = 0; for (k = loindex; k <= hiindex; k++) weights[k] += loudness * nharmonics / (nharmonics + j); } sumweight += loudness; } bestbin = -1; bestweight = -1e20; for (i = 0; i < npit; i++) if (weights[i] > bestweight) bestweight = weights[i], bestbin = i; if (bestweight < sumweight * 0.4) bestbin = -1; if (bestbin < 0) { freq = 0; goto done; } if (bestbin > 0 && bestbin < npit-1) { int ibest = bestbin; bestbin += (weights[ibest+1] - weights[ibest-1]) / (weights[ibest+1] + weights[ibest] + weights[ibest-1]); } freq = 2*fperbin * exp((LOG2/48.)*bestbin); for (sumamp = sumweight = sumfreq = 0, i = 0; i < nsalient; i++) { t_peak *thispeak = bigpeaks[i]; t_float thisloudness = thispeak->p_amp; t_float thisfreq = thispeak->p_freq; t_float harmonic = thisfreq/freq; t_float intpart = (int)(0.5 + harmonic); t_float inharm = harmonic - intpart; #if 0 if (loud) post("freq %f intpart %f inharm %f", freq, intpart, inharm); #endif if (intpart >= 1 && intpart <= 16 && inharm < 0.015 * intpart && inharm > - (0.015 * intpart)) { t_float weight = thisloudness * intpart; sumweight += weight; sumfreq += weight*thisfreq/intpart; #if 0 if (loud) post("weight %f freq %f", weight, thisfreq); #endif } } if (sumweight > 0) freq = sumfreq / sumweight; done: if (!(freq >= 0 || freq <= 0)) { /* post("freq nan cancelled"); */ freq = 0; } *freqp = freq; } /*************** gather peak lists into sinusoidal tracks *************/ static void sigmund_peaktrack(int ninpeak, t_peak *inpeakv, int noutpeak, t_peak *outpeakv, float maxerror, int loud) { int incnt, outcnt; for (outcnt = 0; outcnt < noutpeak; outcnt++) outpeakv[outcnt].p_tmp = -1; /* first pass. Match each "in" peak with the closest previous "out" peak, but no two to the same one. */ for (incnt = 0; incnt < ninpeak; incnt++) { t_float besterror = 1e20; int bestcnt = -1; inpeakv[incnt].p_tmp = -1; for (outcnt = 0; outcnt < noutpeak; outcnt++) { t_float thiserror; if (outpeakv[outcnt].p_amp == 0) continue; thiserror = inpeakv[incnt].p_freq - outpeakv[outcnt].p_freq; if (thiserror < 0) thiserror = -thiserror; if (thiserror < besterror) { besterror = thiserror; bestcnt = outcnt; } } if (bestcnt >= 0 && besterror < maxerror && outpeakv[bestcnt].p_tmp < 0) { outpeakv[bestcnt] = inpeakv[incnt]; inpeakv[incnt].p_tmp = 0; outpeakv[bestcnt].p_tmp = 0; } } /* second pass. Unmatched "in" peaks assigned to free "out" peaks */ for (incnt = 0; incnt < ninpeak; incnt++) if (inpeakv[incnt].p_tmp < 0) { for (outcnt = 0; outcnt < noutpeak; outcnt++) if (outpeakv[outcnt].p_tmp < 0) { outpeakv[outcnt] = inpeakv[incnt]; inpeakv[incnt].p_tmp = 0; outpeakv[outcnt].p_tmp = 1; break; } } for (outcnt = 0; outcnt < noutpeak; outcnt++) if (outpeakv[outcnt].p_tmp == -1) outpeakv[outcnt].p_amp = 0; } /**************** parse continuous pitch into note starts ***************/ #define NHISTPOINT 100 typedef struct _histpoint { t_float h_freq; t_float h_power; } t_histpoint; typedef struct _notefinder { t_float n_age; t_float n_hifreq; t_float n_lofreq; int n_peaked; t_histpoint n_hist[NHISTPOINT]; int n_histphase; } t_notefinder; static void notefinder_init(t_notefinder *x) { int i; x->n_peaked = x->n_age = 0; x->n_hifreq = x->n_lofreq = 0; x->n_histphase = 0; for (i = 0; i < NHISTPOINT; i++) x->n_hist[i].h_freq =x->n_hist[i].h_power = 0; } static void notefinder_doit(t_notefinder *x, t_float freq, t_float power, t_float *note, t_float vibrato, int stableperiod, t_float powerthresh, t_float growththresh, int loud) { /* calculate frequency ratio between allowable vibrato extremes (equal to twice the vibrato deviation from center) */ t_float vibmultiple = exp((2*LOG2/12) * vibrato); int oldhistphase, i, k; if (stableperiod > NHISTPOINT - 1) stableperiod = NHISTPOINT - 1; else if (stableperiod < 1) stableperiod = 1; if (++x->n_histphase == NHISTPOINT) x->n_histphase = 0; x->n_hist[x->n_histphase].h_freq = freq; x->n_hist[x->n_histphase].h_power = power; x->n_age++; *note = 0; #if 0 if (loud) { post("stable %d, age %d, vibmultiple %f, powerthresh %f, hifreq %f", stableperiod, (int)x->n_age ,vibmultiple, powerthresh, x->n_hifreq); post("histfreq %f %f %f %f", x->n_hist[x->n_histphase].h_freq, x->n_hist[(x->n_histphase+NHISTPOINT-1)%NHISTPOINT].h_freq, x->n_hist[(x->n_histphase+NHISTPOINT-2)%NHISTPOINT].h_freq, x->n_hist[(x->n_histphase+NHISTPOINT-3)%NHISTPOINT].h_freq); post("power %f %f %f %f", x->n_hist[x->n_histphase].h_power, x->n_hist[(x->n_histphase+NHISTPOINT-1)%NHISTPOINT].h_power, x->n_hist[(x->n_histphase+NHISTPOINT-2)%NHISTPOINT].h_power, x->n_hist[(x->n_histphase+NHISTPOINT-3)%NHISTPOINT].h_power); for (i = 0, k = x->n_histphase; i < stableperiod; i++) { post("pit %5.1f pow %f", sigmund_ftom(x->n_hist[k].h_freq), x->n_hist[k].h_power); if (--k < 0) k = NHISTPOINT - 1; } } #endif /* look for shorter notes than "stableperiod" in length. The amplitude must rise and then fall while the pitch holds steady. */ if (x->n_hifreq <= 0 && x->n_age > stableperiod) { t_float maxpow = 0, freqatmaxpow = 0, localhifreq = -1e20, locallofreq = 1e20; int startphase = x->n_histphase - stableperiod + 1; if (startphase < 0) startphase += NHISTPOINT; for (i = 0, k = startphase; i < stableperiod; i++) { if (x->n_hist[k].h_freq <= 0) break; if (x->n_hist[k].h_power > maxpow) maxpow = x->n_hist[k].h_power, freqatmaxpow = x->n_hist[k].h_freq; if (x->n_hist[k].h_freq > localhifreq) localhifreq = x->n_hist[k].h_freq; if (x->n_hist[k].h_freq < locallofreq) locallofreq = x->n_hist[k].h_freq; if (localhifreq > locallofreq * vibmultiple) break; if (maxpow > power * growththresh && maxpow > x->n_hist[startphase].h_power * growththresh && localhifreq < vibmultiple * locallofreq && freqatmaxpow > 0 && maxpow > powerthresh) { x->n_hifreq = x->n_lofreq = *note = freqatmaxpow; x->n_age = 0; x->n_peaked = 0; /* post("got short note"); */ return; } if (++k >= NHISTPOINT) k = 0; } } if (x->n_hifreq > 0) { /* test if we're within "vibrato" range, and if so update range */ if (freq * vibmultiple >= x->n_hifreq && x->n_lofreq * vibmultiple >= freq) { if (freq > x->n_hifreq) x->n_hifreq = freq; if (freq < x->n_lofreq) x->n_lofreq = freq; } else if (x->n_hifreq > 0 && x->n_age > stableperiod) { /* if we've been out of range at least 1/2 the last "stableperiod+1" analyses, clear the note */ int nbad = 0; for (i = 0, k = x->n_histphase; i < stableperiod + 1; i++) { if (--k < 0) k = NHISTPOINT - 1; if (x->n_hist[k].h_freq * vibmultiple <= x->n_hifreq || x->n_lofreq * vibmultiple <= x->n_hist[k].h_freq) nbad++; } if (2 * nbad >= stableperiod + 1) { x->n_hifreq = x->n_lofreq = 0; x->n_age = 0; } } } oldhistphase = x->n_histphase - stableperiod; if (oldhistphase < 0) oldhistphase += NHISTPOINT; /* look for envelope attacks */ if (x->n_hifreq > 0 && x->n_peaked) { if (freq > 0 && power > powerthresh && power > x->n_hist[oldhistphase].h_power * exp((LOG10*0.1)*growththresh)) { /* clear it and fall through for new stable-note test */ x->n_peaked = 0; x->n_hifreq = x->n_lofreq = 0; x->n_age = 0; } } else if (!x->n_peaked) { if (x->n_hist[oldhistphase].h_power > powerthresh && x->n_hist[oldhistphase].h_power > power) x->n_peaked = 1; } /* test for a new note using a stability criterion. */ if (freq >= 0 && (x->n_hifreq <= 0 || freq > x->n_hifreq || freq < x->n_lofreq)) { t_float testfhi = freq, testflo = freq, maxpow = x->n_hist[x->n_histphase].h_freq; for (i = 0, k = x->n_histphase; i < stableperiod-1; i++) { if (--k < 0) k = NHISTPOINT - 1; if (x->n_hist[k].h_freq > testfhi) testfhi = x->n_hist[k].h_freq; if (x->n_hist[k].h_freq < testflo) testflo = x->n_hist[k].h_freq; if (x->n_hist[k].h_power > maxpow) maxpow = x->n_hist[k].h_power; } #if 0 if (loud) post("freq %.2g testfhi %.2g testflo %.2g maxpow %.2g", freq, testfhi, testflo, maxpow); #endif if (testflo > 0 && testfhi <= vibmultiple * testflo && maxpow > powerthresh) { /* report new note */ t_float sumf = 0, sumw = 0, thisw; for (i = 0, k = x->n_histphase; i < stableperiod; i++) { thisw = x->n_hist[k].h_power; sumw += thisw; sumf += thisw*x->n_hist[k].h_freq; if (--k < 0) k = NHISTPOINT - 1; } x->n_hifreq = x->n_lofreq = *note = (sumw > 0 ? sumf/sumw : 0); #if 0 /* debugging printout */ for (i = 0; i < stableperiod; i++) { int k3 = x->n_histphase - i; if (k3 < 0) k3 += NHISTPOINT; startpost("%5.1f ", sigmund_ftom(x->n_hist[k3].h_freq)); } post(""); #endif x->n_age = 0; x->n_peaked = 0; return; } } *note = 0; return; } /**************** object structure for Pd and Max. *********************/ /* From here onward, the code is specific to eithr Pd, Max, or both. If neither "PD 'nor "MSP" is defined, none of this is compiled, so that the whole file can be included in other, non-PD and non-Max projects. */ #if (defined(PD) || defined (MSP)) #define NHIST 100 #define MODE_STREAM 1 #define MODE_BLOCK 2 /* unimplemented */ #define MODE_TABLE 3 #define NPOINTS_DEF 1024 #define NPOINTS_MIN 128 #define HOP_DEF 512 #define NPEAK_DEF 20 #define VIBRATO_DEF 1 #define STABLETIME_DEF 50 #define MINPOWER_DEF 50 #define GROWTH_DEF 7 #define OUT_PITCH 0 #define OUT_ENV 1 #define OUT_NOTE 2 #define OUT_PEAKS 3 #define OUT_TRACKS 4 #define OUT_SMSPITCH 5 #define OUT_SMSNONPITCH 6 typedef struct _varout { #ifdef PD t_outlet *v_outlet; #endif /* PD */ #ifdef MSP void *v_outlet; #endif /* MSP */ int v_what; } t_varout; typedef struct _sigmund { #ifdef PD t_object x_obj; t_clock *x_clock; t_float x_f; /* for main signal inlet */ #endif /* PD */ #ifdef MSP t_pxobject x_obj; void *obex; void *x_clock; t_sample *x_inbuf2; /* extra input buffer to eat clock/DSP jitter */ #endif /* MSP */ t_varout *x_varoutv; int x_nvarout; t_float x_sr; /* sample rate */ int x_mode; /* MODE_STREAM, etc. */ int x_npts; /* number of points in analysis window */ int x_npeak; /* number of peaks to find */ int x_loud; /* debug level */ t_sample *x_inbuf; /* input buffer */ int x_infill; /* number of points filled */ int x_countdown; /* countdown to start filling buffer */ int x_hop; /* samples between analyses */ t_float x_maxfreq; /* highest-frequency peak to report */ t_float x_vibrato; /* vibrato depth in half tones */ t_float x_stabletime; /* period of stability needed for note */ t_float x_growth; /* growth to set off a new note */ t_float x_minpower; /* minimum power, in DB, for a note */ t_float x_param1; /* three parameters for temporary use */ t_float x_param2; t_float x_param3; t_notefinder x_notefinder; /* note parsing state */ t_peak *x_trackv; /* peak tracking state */ int x_ntrack; /* number of peaks tracked */ unsigned int x_dopitch:1; /* which things to calculate */ unsigned int x_donote:1; unsigned int x_dotracks:1; } t_sigmund; static void sigmund_preinit(t_sigmund *x) { x->x_npts = NPOINTS_DEF; x->x_param1 = 6; x->x_param2 = 0.5; x->x_param3 = 0; x->x_hop = HOP_DEF; x->x_mode = MODE_STREAM; x->x_npeak = NPEAK_DEF; x->x_vibrato = VIBRATO_DEF; x->x_stabletime = STABLETIME_DEF; x->x_growth = GROWTH_DEF; x->x_minpower = MINPOWER_DEF; x->x_maxfreq = 1000000; x->x_loud = 0; x->x_sr = 1; x->x_nvarout = 0; x->x_varoutv = (t_varout *)getbytes(0); x->x_trackv = 0; x->x_ntrack = 0; x->x_dopitch = x->x_donote = x->x_dotracks = 0; x->x_inbuf = 0; #ifdef MSP x->x_inbuf2 = 0; #endif } static void sigmund_npts(t_sigmund *x, t_floatarg f) { int nwas = x->x_npts, npts = f; /* check parameter ranges */ if (npts < NPOINTS_MIN) post("sigmund~: minimum points %d", NPOINTS_MIN), npts = NPOINTS_MIN; if (npts != (1 << sigmund_ilog2(npts))) post("sigmund~: adjusting analysis size to %d points", (npts = (1 << sigmund_ilog2(npts)))); if (npts != nwas) x->x_countdown = x->x_infill = 0; if (x->x_mode == MODE_STREAM) { if (x->x_inbuf) { x->x_inbuf = (t_sample *)t_resizebytes(x->x_inbuf, sizeof(*x->x_inbuf) * nwas, sizeof(*x->x_inbuf) * npts); #ifdef MSP x->x_inbuf2 = (t_sample *)t_resizebytes(x->x_inbuf2, sizeof(*x->x_inbuf2) * nwas, sizeof(*x->x_inbuf2) * npts); #endif } else { x->x_inbuf = (t_sample *)getbytes(sizeof(*x->x_inbuf) * npts); memset((char *)(x->x_inbuf), 0, sizeof(*x->x_inbuf) * npts); #ifdef MSP x->x_inbuf2 = (t_sample *)getbytes(sizeof(*x->x_inbuf2) * npts); memset((char *)(x->x_inbuf2), 0, sizeof(*x->x_inbuf2) * npts); #endif } } else x->x_inbuf = 0; x->x_npts = npts; } static void sigmund_hop(t_sigmund *x, t_floatarg f) { x->x_hop = f; /* check parameter ranges */ if (x->x_hop != (1 << sigmund_ilog2(x->x_hop))) post("sigmund~: adjusting analysis size to %d points", (x->x_hop = (1 << sigmund_ilog2(x->x_hop)))); } static void sigmund_npeak(t_sigmund *x, t_floatarg f) { if (f < 1) f = 1; x->x_npeak = f; } static void sigmund_maxfreq(t_sigmund *x, t_floatarg f) { x->x_maxfreq = f; } static void sigmund_vibrato(t_sigmund *x, t_floatarg f) { if (f < 0) f = 0; x->x_vibrato = f; } static void sigmund_stabletime(t_sigmund *x, t_floatarg f) { if (f < 0) f = 0; x->x_stabletime = f; } static void sigmund_growth(t_sigmund *x, t_floatarg f) { if (f < 0) f = 0; x->x_growth = f; } static void sigmund_minpower(t_sigmund *x, t_floatarg f) { if (f < 0) f = 0; x->x_minpower = f; } static void sigmund_doit(t_sigmund *x, int npts, t_float *arraypoints, int loud, t_float srate) { t_peak *peakv = (t_peak *)alloca(sizeof(t_peak) * x->x_npeak); int nfound, i, cnt; t_float freq = 0, power, note = 0; sigmund_getrawpeaks(npts, arraypoints, x->x_npeak, peakv, &nfound, &power, srate, loud, x->x_maxfreq); if (x->x_dopitch) sigmund_getpitch(nfound, peakv, &freq, npts, srate, x->x_param1, x->x_param2, loud); if (x->x_donote) notefinder_doit(&x->x_notefinder, freq, power, ¬e, x->x_vibrato, 1 + x->x_stabletime * 0.001 * srate / (t_float)x->x_hop, exp(LOG10*0.1*(x->x_minpower - 100)), x->x_growth, loud); if (x->x_dotracks) sigmund_peaktrack(nfound, peakv, x->x_ntrack, x->x_trackv, 2* srate / npts, loud); for (cnt = x->x_nvarout; cnt--;) { t_varout *v = &x->x_varoutv[cnt]; switch (v->v_what) { case OUT_PITCH: outlet_float(v->v_outlet, sigmund_ftom(freq)); break; case OUT_ENV: outlet_float(v->v_outlet, sigmund_powtodb(power)); break; case OUT_NOTE: if (note > 0) outlet_float(v->v_outlet, sigmund_ftom(note)); break; case OUT_PEAKS: for (i = 0; i < nfound; i++) { t_atom at[5]; SETFLOAT(at, (t_float)i); SETFLOAT(at+1, peakv[i].p_freq); SETFLOAT(at+2, 2*peakv[i].p_amp); SETFLOAT(at+3, 2*peakv[i].p_ampreal); SETFLOAT(at+4, 2*peakv[i].p_ampimag); outlet_list(v->v_outlet, 0, 5, at); } break; case OUT_TRACKS: for (i = 0; i < x->x_ntrack; i++) { t_atom at[4]; SETFLOAT(at, (t_float)i); SETFLOAT(at+1, x->x_trackv[i].p_freq); SETFLOAT(at+2, 2*x->x_trackv[i].p_amp); SETFLOAT(at+3, x->x_trackv[i].p_tmp); outlet_list(v->v_outlet, 0, 4, at); } break; } } } static t_int *sigmund_perform(t_int *w); static void sigmund_dsp(t_sigmund *x, t_signal **sp) { if (x->x_mode == MODE_STREAM) { if (x->x_hop % sp[0]->s_n) post("sigmund: adjusting hop size to %d", (x->x_hop = sp[0]->s_n * (x->x_hop / sp[0]->s_n))); x->x_sr = sp[0]->s_sr; dsp_add(sigmund_perform, 3, x, sp[0]->s_vec, sp[0]->s_n); } } static void sigmund_print(t_sigmund *x) { post("sigmund~ settings:"); post("npts %d", (int)x->x_npts); post("hop %d", (int)x->x_hop); post("npeak %d", (int)x->x_npeak); post("maxfreq %g", x->x_maxfreq); post("vibrato %g", x->x_vibrato); post("stabletime %g", x->x_stabletime); post("growth %g", x->x_growth); post("minpower %g", x->x_minpower); x->x_loud = 1; } static void sigmund_free(t_sigmund *x) { if (x->x_inbuf) { freebytes(x->x_inbuf, x->x_npts * sizeof(*x->x_inbuf)); #ifdef MSP freebytes(x->x_inbuf2, x->x_npts * sizeof(*x->x_inbuf2)); #endif } if (x->x_trackv) freebytes(x->x_trackv, x->x_ntrack * sizeof(*x->x_trackv)); clock_free(x->x_clock); } #endif /* PD or MSP */ /*************************** Glue for Pd ************************/ #ifdef PD static t_class *sigmund_class; static void sigmund_tick(t_sigmund *x); static void sigmund_clear(t_sigmund *x); static void sigmund_npts(t_sigmund *x, t_floatarg f); static void sigmund_hop(t_sigmund *x, t_floatarg f); static void sigmund_npeak(t_sigmund *x, t_floatarg f); static void sigmund_maxfreq(t_sigmund *x, t_floatarg f); static void sigmund_vibrato(t_sigmund *x, t_floatarg f); static void sigmund_stabletime(t_sigmund *x, t_floatarg f); static void sigmund_growth(t_sigmund *x, t_floatarg f); static void sigmund_minpower(t_sigmund *x, t_floatarg f); static void sigmund_tick(t_sigmund *x) { if (x->x_infill == x->x_npts) { sigmund_doit(x, x->x_npts, x->x_inbuf, x->x_loud, x->x_sr); if (x->x_hop >= x->x_npts) { x->x_infill = 0; x->x_countdown = x->x_hop - x->x_npts; } else { memmove(x->x_inbuf, x->x_inbuf + x->x_hop, (x->x_infill = x->x_npts - x->x_hop) * sizeof(*x->x_inbuf)); x->x_countdown = 0; } if (x->x_loud) x->x_loud--; } } static t_int *sigmund_perform(t_int *w) { t_sigmund *x = (t_sigmund *)(w[1]); t_sample *in = (t_sample *)(w[2]); int n = (int)(w[3]); if (x->x_hop % n) return (w+4); if (x->x_countdown > 0) x->x_countdown -= n; else if (x->x_infill != x->x_npts) { int j; t_float *fp = x->x_inbuf + x->x_infill; for (j = 0; j < n; j++) *fp++ = *in++; x->x_infill += n; if (x->x_infill == x->x_npts) clock_delay(x->x_clock, 0); } return (w+4); } static void *sigmund_new(t_symbol *s, int argc, t_atom *argv) { t_sigmund *x = (t_sigmund *)pd_new(sigmund_class); sigmund_preinit(x); while (argc > 0) { t_symbol *firstarg = atom_getsymbolarg(0, argc, argv); if (!strcmp(firstarg->s_name, "-t")) { x->x_mode = MODE_TABLE; argc--, argv++; } else if (!strcmp(firstarg->s_name, "-s")) { x->x_mode = MODE_STREAM; argc--, argv++; } #if 0 else if (!strcmp(firstarg->s_name, "-b")) { x->x_mode = MODE_BLOCK; argc--, argv++; } #endif else if (!strcmp(firstarg->s_name, "-npts") && argc > 1) { x->x_npts = atom_getfloatarg(1, argc, argv); argc -= 2; argv += 2; } else if (!strcmp(firstarg->s_name, "-hop") && argc > 1) { sigmund_hop(x, atom_getfloatarg(1, argc, argv)); argc -= 2; argv += 2; } else if (!strcmp(firstarg->s_name, "-npeak") && argc > 1) { sigmund_npeak(x, atom_getfloatarg(1, argc, argv)); argc -= 2; argv += 2; } else if (!strcmp(firstarg->s_name, "-maxfreq") && argc > 1) { sigmund_maxfreq(x, atom_getfloatarg(1, argc, argv)); argc -= 2; argv += 2; } else if (!strcmp(firstarg->s_name, "-vibrato") && argc > 1) { sigmund_vibrato(x, atom_getfloatarg(1, argc, argv)); argc -= 2; argv += 2; } else if (!strcmp(firstarg->s_name, "-stabletime") && argc > 1) { sigmund_stabletime(x, atom_getfloatarg(1, argc, argv)); argc -= 2; argv += 2; } else if (!strcmp(firstarg->s_name, "-growth") && argc > 1) { sigmund_growth(x, atom_getfloatarg(1, argc, argv)); argc -= 2; argv += 2; } else if (!strcmp(firstarg->s_name, "-minpower") && argc > 1) { sigmund_minpower(x, atom_getfloatarg(1, argc, argv)); argc -= 2; argv += 2; } else if (!strcmp(firstarg->s_name, "pitch")) { int n2 = x->x_nvarout+1; x->x_varoutv = (t_varout *)t_resizebytes(x->x_varoutv, x->x_nvarout*sizeof(t_varout), n2*sizeof(t_varout)); x->x_varoutv[x->x_nvarout].v_outlet = outlet_new(&x->x_obj, &s_float); x->x_varoutv[x->x_nvarout].v_what = OUT_PITCH; x->x_nvarout = n2; x->x_dopitch = 1; argc--, argv++; } else if (!strcmp(firstarg->s_name, "env")) { int n2 = x->x_nvarout+1; x->x_varoutv = (t_varout *)t_resizebytes(x->x_varoutv, x->x_nvarout*sizeof(t_varout), n2*sizeof(t_varout)); x->x_varoutv[x->x_nvarout].v_outlet = outlet_new(&x->x_obj, &s_float); x->x_varoutv[x->x_nvarout].v_what = OUT_ENV; x->x_nvarout = n2; argc--, argv++; } else if (!strcmp(firstarg->s_name, "note") || !strcmp(firstarg->s_name, "notes")) { int n2 = x->x_nvarout+1; x->x_varoutv = (t_varout *)t_resizebytes(x->x_varoutv, x->x_nvarout*sizeof(t_varout), n2*sizeof(t_varout)); x->x_varoutv[x->x_nvarout].v_outlet = outlet_new(&x->x_obj, &s_float); x->x_varoutv[x->x_nvarout].v_what = OUT_NOTE; x->x_nvarout = n2; x->x_dopitch = x->x_donote = 1; argc--, argv++; } else if (!strcmp(firstarg->s_name, "peaks")) { int n2 = x->x_nvarout+1; x->x_varoutv = (t_varout *)t_resizebytes(x->x_varoutv, x->x_nvarout*sizeof(t_varout), n2*sizeof(t_varout)); x->x_varoutv[x->x_nvarout].v_outlet = outlet_new(&x->x_obj, &s_list); x->x_varoutv[x->x_nvarout].v_what = OUT_PEAKS; x->x_nvarout = n2; argc--, argv++; } else if (!strcmp(firstarg->s_name, "tracks")) { int n2 = x->x_nvarout+1; x->x_varoutv = (t_varout *)t_resizebytes(x->x_varoutv, x->x_nvarout*sizeof(t_varout), n2*sizeof(t_varout)); x->x_varoutv[x->x_nvarout].v_outlet = outlet_new(&x->x_obj, &s_list); x->x_varoutv[x->x_nvarout].v_what = OUT_TRACKS; x->x_nvarout = n2; x->x_dotracks = 1; argc--, argv++; } else { pd_error(x, "sigmund: %s: unknown flag or argument missing", firstarg->s_name); argc--, argv++; } } if (!x->x_nvarout) { x->x_varoutv = (t_varout *)t_resizebytes(x->x_varoutv, 0, 2*sizeof(t_varout)); x->x_varoutv[0].v_outlet = outlet_new(&x->x_obj, &s_float); x->x_varoutv[0].v_what = OUT_PITCH; x->x_varoutv[1].v_outlet = outlet_new(&x->x_obj, &s_float); x->x_varoutv[1].v_what = OUT_ENV; x->x_nvarout = 2; x->x_dopitch = 1; } if (x->x_dotracks) { x->x_ntrack = x->x_npeak; x->x_trackv = (t_peak *)getbytes(x->x_ntrack * sizeof(*x->x_trackv)); } x->x_clock = clock_new(&x->x_obj.ob_pd, (t_method)sigmund_tick); x->x_infill = 0; x->x_countdown = 0; sigmund_npts(x, x->x_npts); notefinder_init(&x->x_notefinder); sigmund_clear(x); return (x); } static void sigmund_list(t_sigmund *x, t_symbol *s, int argc, t_atom *argv) { t_symbol *syminput = atom_getsymbolarg(0, argc, argv); int npts = atom_getintarg(1, argc, argv); int onset = atom_getintarg(2, argc, argv); t_float srate = atom_getfloatarg(3, argc, argv); int loud = atom_getfloatarg(4, argc, argv); int arraysize, totstorage, nfound, i; t_garray *a; t_float *arraypoints, pit; t_word *wordarray = 0; if (argc < 5) { post( "sigmund: array-name, npts, array-onset, samplerate, loud"); return; } if (npts < 64 || npts != (1 << ilog2(npts))) { error("sigmund: bad npoints"); return; } if (onset < 0) { error("sigmund: negative onset"); return; } arraypoints = alloca(sizeof(t_float)*npts); if (!(a = (t_garray *)pd_findbyclass(syminput, garray_class)) || !garray_getfloatwords(a, &arraysize, &wordarray) || arraysize < onset + npts) { error("%s: array missing or too small", syminput->s_name); return; } if (arraysize < npts) { error("sigmund~: too few points in array"); return; } for (i = 0; i < npts; i++) arraypoints[i] = wordarray[i+onset].w_float; sigmund_doit(x, npts, arraypoints, loud, srate); } static void sigmund_clear(t_sigmund *x) { if (x->x_trackv) memset(x->x_trackv, 0, x->x_ntrack * sizeof(*x->x_trackv)); x->x_infill = x->x_countdown = 0; } /* these are for testing; their meanings vary... */ static void sigmund_param1(t_sigmund *x, t_floatarg f) { x->x_param1 = f; } static void sigmund_param2(t_sigmund *x, t_floatarg f) { x->x_param2 = f; } static void sigmund_param3(t_sigmund *x, t_floatarg f) { x->x_param3 = f; } static void sigmund_printnext(t_sigmund *x, t_float f) { x->x_loud = f; } void sigmund_tilde_setup(void) { sigmund_class = class_new(gensym("sigmund~"), (t_newmethod)sigmund_new, (t_method)sigmund_free, sizeof(t_sigmund), 0, A_GIMME, 0); class_addlist(sigmund_class, sigmund_list); class_addmethod(sigmund_class, (t_method)sigmund_dsp, gensym("dsp"), 0); CLASS_MAINSIGNALIN(sigmund_class, t_sigmund, x_f); class_addmethod(sigmund_class, (t_method)sigmund_param1, gensym("param1"), A_FLOAT, 0); class_addmethod(sigmund_class, (t_method)sigmund_param2, gensym("param2"), A_FLOAT, 0); class_addmethod(sigmund_class, (t_method)sigmund_param3, gensym("param3"), A_FLOAT, 0); class_addmethod(sigmund_class, (t_method)sigmund_npts, gensym("npts"), A_FLOAT, 0); class_addmethod(sigmund_class, (t_method)sigmund_hop, gensym("hop"), A_FLOAT, 0); class_addmethod(sigmund_class, (t_method)sigmund_maxfreq, gensym("maxfreq"), A_FLOAT, 0); class_addmethod(sigmund_class, (t_method)sigmund_npeak, gensym("npeak"), A_FLOAT, 0); class_addmethod(sigmund_class, (t_method)sigmund_vibrato, gensym("vibrato"), A_FLOAT, 0); class_addmethod(sigmund_class, (t_method)sigmund_stabletime, gensym("stabletime"), A_FLOAT, 0); class_addmethod(sigmund_class, (t_method)sigmund_growth, gensym("growth"), A_FLOAT, 0); class_addmethod(sigmund_class, (t_method)sigmund_minpower, gensym("minpower"), A_FLOAT, 0); class_addmethod(sigmund_class, (t_method)sigmund_print, gensym("print"), 0); class_addmethod(sigmund_class, (t_method)sigmund_printnext, gensym("printnext"), A_FLOAT, 0); post("sigmund~ version 0.07"); } #endif /* PD */ /************************ Max/MSP glue **********************************/ /* -------------------------- MSP glue ------------------------- */ #ifdef MSP static void *sigmund_class; /* Max/MSP has laxer sync between DSP and "tick"s - so in the perf routine we keep a circular buffer that is rectified into inbuf only when the tick comes. */ static void sigmund_tick(t_sigmund *x) { int i, j, npts = x->x_npts; if (!x->x_inbuf) return; for (i = x->x_infill, j = 0; i < npts; i++, j++) x->x_inbuf[j] = x->x_inbuf2[i]; for (i = 0; j < npts; i++, j++) x->x_inbuf[j] = x->x_inbuf2[i]; sigmund_doit(x, x->x_npts, x->x_inbuf, x->x_loud, x->x_sr); x->x_loud = 0; } static t_int *sigmund_perform(t_int *w) { t_sigmund *x = (t_sigmund *)(w[1]); t_float *in = (t_float *)(w[2]); int n = (int)(w[3]), j; int infill = x->x_infill; t_float *fp = x->x_inbuf2 + infill; if (x->x_obj.z_disabled) /* return if in muted MSP subpatch -Rd */ return (w+4); if (infill < 0 || infill >= x->x_npts) infill = 0; /* for some reason this sometimes happens: */ if (!x->x_inbuf2) return (w+4); for (j = 0; j < n; j++) { *fp++ = *in++; if (++infill == x->x_npts) infill = 0, fp = x->x_inbuf2; } x->x_infill = infill; if (x->x_countdown <= 0) { x->x_countdown = x->x_hop; clock_delay(x->x_clock, 0); } x->x_countdown -= n; return (w+4); } static void *sigmund_new(t_symbol *s, long ac, t_atom *av) { t_sigmund *x; t_varout *g; int i, j; if (!(x = (t_sigmund *)object_alloc(sigmund_class))) return (0); sigmund_preinit(x); attr_args_process(x, ac, av); dsp_setup((t_pxobject *)x, 1); object_obex_store(x, gensym("dumpout"), outlet_new(x, NULL)); for (i = 0; i < ac; i++) if (av[i].a_type == A_SYM) { char *s = av[i].a_w.w_sym->s_name; if (!strcmp(s, "pitch")) { int n2 = x->x_nvarout+1; x->x_varoutv = (t_varout *)t_resizebytes(x->x_varoutv, x->x_nvarout*sizeof(t_varout), n2*sizeof(t_varout)); x->x_varoutv[x->x_nvarout].v_what = OUT_PITCH; x->x_nvarout = n2; x->x_dopitch = 1; } else if (!strcmp(s, "env")) { int n2 = x->x_nvarout+1; x->x_varoutv = (t_varout *)t_resizebytes(x->x_varoutv, x->x_nvarout*sizeof(t_varout), n2*sizeof(t_varout)); x->x_varoutv[x->x_nvarout].v_what = OUT_ENV; x->x_nvarout = n2; } else if (!strcmp(s, "note") || !strcmp(s, "notes")) { int n2 = x->x_nvarout+1; x->x_varoutv = (t_varout *)t_resizebytes(x->x_varoutv, x->x_nvarout*sizeof(t_varout), n2*sizeof(t_varout)); x->x_varoutv[x->x_nvarout].v_what = OUT_NOTE; x->x_nvarout = n2; x->x_dopitch = x->x_donote = 1; } else if (!strcmp(s, "peaks")) { int n2 = x->x_nvarout+1; x->x_varoutv = (t_varout *)t_resizebytes(x->x_varoutv, x->x_nvarout*sizeof(t_varout), n2*sizeof(t_varout)); x->x_varoutv[x->x_nvarout].v_what = OUT_PEAKS; x->x_nvarout = n2; } else if (!strcmp(s, "tracks")) { int n2 = x->x_nvarout+1; x->x_varoutv = (t_varout *)t_resizebytes(x->x_varoutv, x->x_nvarout*sizeof(t_varout), n2*sizeof(t_varout)); x->x_varoutv[x->x_nvarout].v_what = OUT_TRACKS; x->x_nvarout = n2; x->x_dotracks = 1; } else if (s[0] != '@') post("sigmund: ignoring unknown argument '%s'" ,s); } if (!x->x_nvarout) { x->x_varoutv = (t_varout *)t_resizebytes(x->x_varoutv, 0, 2*sizeof(t_varout)); x->x_varoutv[0].v_what = OUT_PITCH; x->x_varoutv[1].v_what = OUT_ENV; x->x_nvarout = 2; x->x_dopitch = 1; } for (j = 0, g = x->x_varoutv + x->x_nvarout-1; j < x->x_nvarout; j++, g--) g->v_outlet = ((g->v_what == OUT_PITCH || g->v_what == OUT_ENV || g->v_what == OUT_NOTE) ? floatout((t_object *)x) : listout((t_object *)x)); if (x->x_dotracks) { x->x_ntrack = x->x_npeak; x->x_trackv = (t_peak *)getbytes(x->x_ntrack * sizeof(*x->x_trackv)); } x->x_clock = clock_new(x, (method)sigmund_tick); x->x_infill = 0; x->x_countdown = 0; sigmund_npts(x, x->x_npts); notefinder_init(&x->x_notefinder); return (x); } /* Attribute setters. */ void sigmund_npts_set(t_sigmund *x, void *attr, long ac, t_atom *av) { if (ac && av) sigmund_npts(x, atom_getfloat(av)); } void sigmund_hop_set(t_sigmund *x, void *attr, long ac, t_atom *av) { if (ac && av) sigmund_hop(x, atom_getfloat(av)); } void sigmund_npeak_set(t_sigmund *x, void *attr, long ac, t_atom *av) { if (ac && av) sigmund_npeak(x, atom_getfloat(av)); } void sigmund_maxfreq_set(t_sigmund *x, void *attr, long ac, t_atom *av) { if (ac && av) sigmund_maxfreq(x, atom_getfloat(av)); } void sigmund_vibrato_set(t_sigmund *x, void *attr, long ac, t_atom *av) { if (ac && av) sigmund_vibrato(x, atom_getfloat(av)); } void sigmund_stabletime_set(t_sigmund *x, void *attr, long ac, t_atom *av) { if (ac && av) sigmund_stabletime(x, atom_getfloat(av)); } void sigmund_growth_set(t_sigmund *x, void *attr, long ac, t_atom *av) { if (ac && av) sigmund_growth(x, atom_getfloat(av)); } void sigmund_minpower_set(t_sigmund *x, void *attr, long ac, t_atom *av) { if (ac && av) sigmund_minpower(x, atom_getfloat(av)); } /* end attr setters */ void sigmund_assist(t_sigmund *x, void *b, long m, long a, char *s) { } int main() { t_class *c; long attrflags = 0; t_symbol *sym_long = gensym("long"), *sym_float32 = gensym("float32"); c = class_new("sigmund~", (method)sigmund_new, (method)sigmund_free, sizeof(t_sigmund), (method)0L, A_GIMME, 0); class_obexoffset_set(c, calcoffset(t_sigmund, obex)); class_addattr(c, attr_offset_new("npts", sym_long, attrflags, (method)0L, (method)sigmund_npts_set, calcoffset(t_sigmund, x_npts))); class_addattr(c ,attr_offset_new("hop", sym_long, attrflags, (method)0L, (method)sigmund_hop_set, calcoffset(t_sigmund, x_hop))); class_addattr(c ,attr_offset_new("maxfreq", sym_float32, attrflags, (method)0L, (method)sigmund_maxfreq_set, calcoffset(t_sigmund, x_maxfreq))); class_addattr(c ,attr_offset_new("npeak", sym_long, attrflags, (method)0L, (method)sigmund_npeak_set, calcoffset(t_sigmund, x_npeak))); class_addattr(c ,attr_offset_new("vibrato", sym_float32, attrflags, (method)0L, (method)sigmund_vibrato_set, calcoffset(t_sigmund, x_vibrato))); class_addattr(c ,attr_offset_new("stabletime", sym_float32, attrflags, (method)0L, (method)sigmund_stabletime_set, calcoffset(t_sigmund, x_stabletime))); class_addattr(c ,attr_offset_new("growth", sym_float32, attrflags, (method)0L, (method)sigmund_growth_set, calcoffset(t_sigmund, x_growth))); class_addattr(c ,attr_offset_new("minpower", sym_float32, attrflags, (method)0L, (method)sigmund_minpower_set, calcoffset(t_sigmund, x_minpower))); class_addmethod(c, (method)sigmund_dsp, "dsp", A_CANT, 0); class_addmethod(c, (method)sigmund_print, "print", 0); class_addmethod(c, (method)sigmund_print, "printnext", A_DEFFLOAT, 0); class_addmethod(c, (method)sigmund_assist, "assist", A_CANT, 0); class_addmethod(c, (method)object_obex_dumpout, "dumpout", A_CANT, 0); class_addmethod(c, (method)object_obex_quickref, "quickref", A_CANT, 0); class_dspinit(c); class_register(CLASS_BOX, c); sigmund_class = c; post("sigmund~ version 0.07"); return (0); } #endif /* MSP */ pd-0.46-7/extra/rev2~-help.pd0000664000175000017500000000675612160204055014057 0ustar mspmsp#N canvas 167 160 766 354 12; #X floatatom 73 185 0 0 120 0 - - -; #X floatatom 106 323 0 0 120 0 - - -; #N canvas 0 0 539 448 tests 0; #X obj 67 33 inlet; #X obj 309 189 inlet; #X obj 235 207 line~; #X obj 235 230 cos~; #X obj 235 68 loadbang; #X msg 235 91 -0.25; #X obj 235 276 *~; #X obj 186 309 hip~ 5; #X floatatom 308 218 0 0 0 0 - - -; #X obj 308 264 osc~ 440; #X obj 308 241 mtof; #X obj 235 253 *~ 0.1; #X obj 308 299 *~; #X obj 326 325 *~; #X obj 292 330 *~; #X msg 279 150 -0.25 \, 0.25 \$1; #X obj 41 148 biquad~ 0 0 1 -1 0; #X obj 63 70 t b; #X obj 104 72 del 3; #X obj 57 101 1; #X obj 96 101 0; #X obj 41 355 outlet~; #X obj 279 126 inlet; #X obj 40 175 *~; #X connect 0 0 17 0; #X connect 1 0 8 0; #X connect 2 0 3 0; #X connect 3 0 11 0; #X connect 4 0 5 0; #X connect 5 0 2 0; #X connect 6 0 7 0; #X connect 7 0 21 0; #X connect 8 0 10 0; #X connect 9 0 6 1; #X connect 9 0 12 0; #X connect 9 0 12 1; #X connect 9 0 13 0; #X connect 10 0 9 0; #X connect 11 0 6 0; #X connect 12 0 13 1; #X connect 12 0 6 1; #X connect 12 0 14 0; #X connect 12 0 14 1; #X connect 13 0 6 1; #X connect 14 0 6 1; #X connect 15 0 2 0; #X connect 16 0 23 0; #X connect 17 0 18 0; #X connect 17 0 19 0; #X connect 18 0 20 0; #X connect 19 0 16 0; #X connect 19 0 23 1; #X connect 20 0 16 0; #X connect 20 0 23 1; #X connect 22 0 15 0; #X connect 23 0 21 0; #X restore 17 154 pd tests; #X msg 56 35 10; #X msg 54 62 20; #X msg 53 90 100; #X msg 52 115 500; #X obj 17 15 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X text 37 9 impulse; #N canvas 0 0 450 300 output 0; #X obj 54 202 dac~; #X obj 132 119 pack 0 100; #X obj 132 142 line~; #X obj 54 165 *~; #X obj 132 97 dbtorms; #X obj 33 42 inlet~; #X obj 177 42 inlet; #X obj 177 74 clip 0 120; #X msg 257 133 \; pd dsp 1; #X obj 98 42 inlet~; #X obj 94 168 *~; #X connect 1 0 2 0; #X connect 2 0 3 1; #X connect 2 0 10 1; #X connect 3 0 0 0; #X connect 4 0 1 0; #X connect 5 0 3 0; #X connect 6 0 7 0; #X connect 6 0 8 0; #X connect 7 0 4 0; #X connect 9 0 10 0; #X connect 10 0 0 1; #X restore 18 324 pd output; #X floatatom 97 127 0 0 0 0 - - -; #X text 136 96 tone; #X text 135 112 pitch; #X text 114 185 level \, dB; #X floatatom 117 209 0 0 100 0 - - -; #X text 158 209 liveness \, 0-100; #X text 505 330 modified for Pd version 0.37; #X floatatom 161 235 0 0 120 0 - - -; #X floatatom 205 259 0 0 120 0 - - -; #X text 192 235 crossover frequency \, Hz.; #X text 238 260 HF damping \, percent; #X obj 30 290 rev2~ 100 90 3000 20; #X text 141 324 output level \, dB; #X text 281 8 REV2~ - a simple 1-in \, 4-out reverberator; #X text 95 35 tone; #X text 96 52 bursts; #X text 231 37 The creation arguments (level \, liveness \, crossover frequency \, HF damping) may also be supplied in four inlets as shown. The "liveness" (actually the internal feedback percentage) should be 100 for infinite reverb \, 90 for longish \, and 80 for short. The crossover frequency and HF damping work together: at frequencies above crossover \, the feedback is diminished by the "damping" as a percentage. So zero HF damping means equal reverb time at all frequencies \, and 100% damping means almost nothing above the crossover frequency gets through.; #X text 132 130 (60 for; #X text 115 150 middle C); #X connect 0 0 21 1; #X connect 1 0 9 2; #X connect 2 0 9 0; #X connect 2 0 21 0; #X connect 3 0 2 1; #X connect 4 0 2 1; #X connect 5 0 2 1; #X connect 6 0 2 1; #X connect 7 0 2 0; #X connect 10 0 2 2; #X connect 14 0 21 2; #X connect 17 0 21 3; #X connect 18 0 21 4; #X connect 21 0 9 0; #X connect 21 1 9 1; pd-0.46-7/extra/rev1-stage.pd0000664000175000017500000000436212160204055014022 0ustar mspmsp#N canvas 86 133 729 452 10; #X obj 27 238 inlet~; #X obj 347 28 loadbang; #X obj 171 281 * -1; #X obj 36 353 +~; #X obj 69 395 +~; #X obj 69 424 outlet~; #X obj 409 96 pow; #X obj 372 118 *; #X floatatom 372 159; #X obj 37 262 *~ 0; #X obj 177 175 pow; #X text 408 162 delay \, msec; #X floatatom 177 238; #X obj 190 150 * 0.001; #X text 182 221 gain for this stage; #X obj 49 332 *~ 0; #X obj 47 375 *~ 0; #X obj 177 203 *; #X floatatom 409 119; #X text 25 13 Allpass filter for mono reverberator. Arg 1 = delay name \, arg2 = stage number \, arg 3 = delay time; #X obj 373 76 8; #X obj 409 75 1.79; #X obj 68 185 0.7; #X obj 363 50 t b b b b; #X obj 177 108 0; #X obj 372 207 abs; #X obj 372 229 moses 0.01; #X obj 443 229 print wrong-delay-time; #X obj 233 391 inlet~; #X obj 219 419 +~; #X obj 219 443 outlet~; #X text 74 83 decay after; #X text 85 98 1 second; #X obj 83 119 r \$1-decay; #X obj 259 256 r \$1-clear; #X obj 206 301 0; #X obj 259 275 t b; #X obj 259 338 delay; #X obj 259 316 + 5; #X obj 79 280 delread~ \$2 \$4; #X obj 36 447 delwrite~ \$2 \$4; #X obj 259 296 f \$4; #X obj 371 184 - \$4; #X obj 446 75 float \$3; #X obj 207 321 1; #X obj 79 301 *~ 1; #X obj 207 188 sqrt; #X floatatom 35 148; #X connect 0 0 9 0; #X connect 1 0 23 0; #X connect 2 0 16 1; #X connect 3 0 16 0; #X connect 3 0 40 0; #X connect 4 0 5 0; #X connect 4 0 29 0; #X connect 6 0 7 1; #X connect 6 0 18 0; #X connect 7 0 8 0; #X connect 7 0 13 0; #X connect 8 0 42 0; #X connect 9 0 3 0; #X connect 10 0 17 0; #X connect 13 0 10 1; #X connect 15 0 3 1; #X connect 16 0 4 0; #X connect 17 0 12 0; #X connect 17 0 9 1; #X connect 20 0 7 0; #X connect 21 0 6 0; #X connect 21 0 46 0; #X connect 22 0 2 0; #X connect 22 0 15 1; #X connect 23 0 24 0; #X connect 23 0 22 0; #X connect 23 1 20 0; #X connect 23 2 21 0; #X connect 23 3 43 0; #X connect 24 0 10 0; #X connect 25 0 26 0; #X connect 26 1 27 0; #X connect 28 0 29 1; #X connect 29 0 30 0; #X connect 33 0 10 0; #X connect 33 0 47 0; #X connect 34 0 36 0; #X connect 35 0 45 1; #X connect 36 0 35 0; #X connect 36 0 41 0; #X connect 37 0 44 0; #X connect 38 0 37 0; #X connect 39 0 45 0; #X connect 41 0 38 0; #X connect 42 0 25 0; #X connect 43 0 6 1; #X connect 44 0 45 1; #X connect 45 0 15 0; #X connect 45 0 4 1; #X connect 46 0 17 1; pd-0.46-7/extra/hilbert~-help.pd0000664000175000017500000000120612160204055014613 0ustar mspmsp#N canvas 156 234 600 488 12; #X obj 67 124 hilbert~; #X obj 66 85 osc~ 440; #X graph graph1 0 -1 882 1 279 209 579 39; #X array out-left 882 float; #X array out-right 882 float; #X pop; #X obj 67 274 tabwrite~ out-left; #X obj 118 248 tabwrite~ out-right; #X msg 137 188 bang \; pd dsp 1; #X floatatom 66 57; #X text 71 319 The Hilbert transform (the name is abused here according to computer music tradition) puts out a phase quadrature version of the input signal suitable for signal sideband modulation via complex-mod~.; #X connect 0 0 3 0; #X connect 0 1 4 0; #X connect 1 0 0 0; #X connect 5 0 3 0; #X connect 5 0 4 0; #X connect 6 0 1 0; pd-0.46-7/extra/choice/0000775000175000017500000000000012574202336012755 5ustar mspmsppd-0.46-7/extra/choice/choice.c0000664000175000017500000000655712222367057014372 0ustar mspmsp/* choice -- match incoming list against a collection of stored templates. */ /* Copyright 1999 Miller Puckette. Permission is granted to use this software for any purpose provided you keep this copyright notice intact. THE AUTHOR AND HIS EMPLOYERS MAKE NO WARRANTY, EXPRESS OR IMPLIED, IN CONNECTION WITH THIS SOFTWARE. This file is downloadable from http://www.crca.ucsd.edu/~msp . */ #include "m_pd.h" #include static t_class *choice_class; #define DIMENSION 10 typedef struct _elem { t_float e_age; t_float e_weight[DIMENSION]; } t_elem; typedef struct _choice { t_object x_obj; t_elem *x_vec; int x_n; int x_nonrepeat; } t_choice; static void *choice_new(t_float fnonrepeat) { t_choice *x = (t_choice *)pd_new(choice_class); outlet_new(&x->x_obj, gensym("float")); x->x_vec = (t_elem *)getbytes(0); x->x_n = 0; x->x_nonrepeat = (fnonrepeat != 0); return (x); } static void choice_clear(t_choice *x) { x->x_vec = (t_elem *)resizebytes(x->x_vec, x->x_n * sizeof(t_elem), 0); x->x_n = 0; } static void choice_print(t_choice *x) { int j; for (j = 0; j < x->x_n; j++) { t_elem *e = x->x_vec + j; t_float *w = e->e_weight; post("%2d age %2d \ w %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f", j, (int)(e->e_age), w[0], w[1], w[2], w[3], w[4], w[5], w[6], w[7], w[8], w[9]); } } static void choice_add(t_choice *x, t_symbol *s, int argc, t_atom *argv) { int oldn = x->x_n, newn = oldn + 1, i; t_elem *e; t_float sum, normal; x->x_vec = (t_elem *)resizebytes(x->x_vec, oldn * sizeof(t_elem), newn * sizeof(t_elem)); x->x_n = newn; e = x->x_vec + oldn; e->e_age = 2; for (i = 0, sum = 0; i < DIMENSION; i++) { t_float f = atom_getfloatarg(i, argc, argv); e->e_weight[i] = f; sum += f*f; } normal = (t_float)(sum > 0 ? 1./sqrt(sum) : 1); for (i = 0; i < DIMENSION; i++) e->e_weight[i] *= normal; } static void choice_list(t_choice *x, t_symbol *s, int argc, t_atom *argv) { int i, j; t_float bestsum = 0; int bestindex = -1; t_float invec[DIMENSION]; for (i = 0; i < DIMENSION; i++) invec[i] = atom_getfloatarg(i, argc, argv); for (j = 0; j < x->x_n; j++) { t_elem *e = x->x_vec + j; t_float sum; for (i = 0, sum = 0; i < DIMENSION; i++) sum += e->e_weight[i] * invec[i]; if (x->x_nonrepeat) sum *= (t_float)(log(e->e_age)); if (sum > bestsum) { bestsum = sum; sum = 1; bestindex = j; } } if (bestindex >= 0) { for (j = 0; j < x->x_n; j++) x->x_vec[j].e_age += 1.; x->x_vec[bestindex].e_age = 1; } outlet_float(x->x_obj.ob_outlet, (t_float)bestindex); } static void choice_free(t_choice *x) { freebytes(x->x_vec, x->x_n * sizeof(t_elem)); } void choice_setup(void) { choice_class = class_new(gensym("choice"), (t_newmethod)choice_new, (t_method)choice_free, sizeof(t_choice), 0, A_DEFFLOAT, 0); class_addmethod(choice_class, (t_method)choice_add, gensym("add"), A_GIMME, 0); class_addmethod(choice_class, (t_method)choice_clear, gensym("clear"), 0); class_addmethod(choice_class, (t_method)choice_print, gensym("print"), 0); class_addlist(choice_class, choice_list); } pd-0.46-7/extra/choice/GNUmakefile.am0000664000175000017500000000125612374250720015425 0ustar mspmsp## Makefile.am -- Process this file with automake to produce Makefile.in NAME=choice external_LTLIBRARIES = choice.la SOURCES = choice.c PATCHES = choice-help.pd OTHERDATA = EXTRA_DIST = makefile ############################### # you shouldn't need to add anything below here dist_external_DATA = $(PATCHES) $(OTHERDATA) AUTOMAKE_OPTIONS = foreign AM_CPPFLAGS = -I$(top_srcdir)/src -DPD AM_CFLAGS = @ARCH_CFLAGS@ AM_LIBS = $(LIBM) AM_LDFLAGS = -module -avoid-version -shared @ARCH_LDFLAGS@ -shrext .@EXTERNAL_EXTENSION@ -L$(top_srcdir)/src externaldir = $(pkglibdir)/extra/$(NAME) if MINGW AM_LIBS += -lpd endif libtool: $(LIBTOOL_DEPS) $(SHELL) ./config.status --recheck pd-0.46-7/extra/choice/choice-help.pd0000664000175000017500000000441712160204055015457 0ustar mspmsp#N canvas 16 5 609 600 12; #X obj 8 195 choice; #X msg 41 86 print; #X msg 29 63 clear; #X msg 8 34 add 1 0 0 \, add 0 1 0 \, add 0 0 1 \, add 1 1 1 \, add 1 1 0; #X obj 77 171 pack 0 0 0; #X floatatom 182 125 0 0 0 0 - - -; #X floatatom 148 125 0 0 0 0 - - -; #X floatatom 115 125 0 0 0 0 - - -; #X obj 77 147 f; #X msg 77 125 bang; #X floatatom 8 216 0 0 0 0 - - -; #X obj 71 196 choice 1; #X floatatom 71 217 0 0 0 0 - - -; #X obj 76 4 choice; #X text 135 3 - search for a best match to an incoming list; #X text 19 243 The choice object holds a list of vectors \, each having up to ten elements. When sent a list of numbers \, it outputs the index of the known vector that matches most closely. The quality of the match is the dot product of the two vectors after normalizing them \, i.e. \, the vector whose direction is closest to that of the input wins. ; #X text 19 340 If given a nonzero creation argument \, choice tries to avoid repetitious outputs by weighting less recently output vectors preferentially.; #X text 20 389 You can use this to choose interactively between a number of behaviors depending on their attributes. For example \, you might have stored a number of melodies \, of which some are syncopated \, some chromatic \, some are more than 100 years old \, some are bugle calls \, and some are Christmas carols. You could then ask to find a syncopated bugle call (1 \, 0 \, 0 \, 1 \, 0) and you'll get the thing most closely matching the request.; #X text 19 514 You can use numbers other than 0 and 1 to indicate relative strengths of the attributes \, or even use negative numbers to indicate opposites \, either in the incoming lists or in the stored ones.; #X text 320 572 updated for Pd version-0.30; #X text 79 62 delete all stored vectors; #X text 498 34 add vectors; #X text 94 84 debugging printout; #X text 69 104 tweak the numbers and hit "bang" to input a list; #X text 151 197 creation argument to avoid repeated outout; #X text 108 219 output is the index of best match \, counting from zero; #X connect 0 0 10 0; #X connect 1 0 0 0; #X connect 2 0 0 0; #X connect 2 0 11 0; #X connect 3 0 0 0; #X connect 3 0 11 0; #X connect 4 0 0 0; #X connect 4 0 11 0; #X connect 5 0 4 2; #X connect 6 0 4 1; #X connect 7 0 8 1; #X connect 8 0 4 0; #X connect 9 0 8 0; #X connect 11 0 12 0; pd-0.46-7/extra/choice/makefile0000664000175000017500000000006412160204055014444 0ustar mspmspNAME=choice CSYM=choice include ../makefile.subdir pd-0.46-7/extra/rev1~-help.pd0000664000175000017500000000635312160204055014047 0ustar mspmsp#N canvas 55 21 1008 526 12; #X obj 148 439 dac~; #X obj 58 72 line~; #X msg 58 49 0 \, 10000 5; #X obj 58 118 cos~; #X msg 146 70 1; #X obj 146 47 loadbang; #X obj 58 95 clip~ 0 0.25; #X floatatom 173 264 0 0 0; #X obj 251 134 line~; #X obj 251 157 cos~; #X msg 324 54 -0.25 \, 0.25 100; #X obj 251 8 loadbang; #X msg 251 31 -0.25; #X obj 251 203 *~; #X obj 58 140 hip~ 5; #X floatatom 162 328 0 0 0; #X obj 162 373 pack 0 100; #X obj 162 396 line~; #X obj 148 416 *~; #X obj 162 350 dbtorms; #X msg 324 77 -0.25 \, 0.25 400; #X floatatom 324 145 0 0 0; #X obj 324 191 osc~ 440; #X obj 324 168 mtof; #X msg 324 31 -0.25 \, 0.25 20; #X obj 251 180 *~ 0.1; #X msg 324 100 -0.25 \, 0.25 1000; #X msg 324 122 -0.25 \, 0.25 2000; #X obj 324 226 *~; #X obj 342 252 *~; #X obj 58 439 dac~; #X floatatom 68 323 0 0 0; #X obj 68 368 pack 0 100; #X obj 68 391 line~; #X obj 58 416 *~; #X obj 68 346 dbtorms; #X msg 324 8 0; #X obj 308 257 *~; #X obj 58 26 metro 2000; #X floatatom 58 4 0 0 0; #X msg 220 265 bang; #X obj 284 322 env~ 32768; #X floatatom 284 344 0 0 0; #X text 166 244 1 sec; #X text 143 226 dB after; #X text 220 245 clear; #X text 1 51 impulse; #X text 362 7 tone; #X text 484 31 beeps; #X text 428 167 This is an experimental reverberator design composed of a series of allpass filters with exponentially growing delay times. Each allpass filter has a gain of 0.7. The reverb time is adjusted by adjusting the input gains of the allpass filters. The last unit is modified so that its first two "echos" mimic those of an allpass but its loop gain depends on reverb time.; #X text 430 299 Reverb time is controlled by specifying the dB gain (100 normal) after one second \, so that 100 corresponds to infinite reverb time \, 70 to two seconds \, 40 to one second \, and 0 to 0 ; #X text 671 499 modified for Pd version 0.30.; #X msg 560 34 \; pd dsp 1; #X text 427 475 The rev1~ module eats about 18% of my 300mHz P2 machine. ; #X obj 148 289 rev1~; #X text 428 381 The "clear" button impolitely clears out all the delay lines \, You may immediately resume pumping the reverberator \, but the input signal should be cleanly enveloped. The output \, too \, must be enveloped and may not be opened until 5 msec after the "clear" message is sent.; #X connect 1 0 6 0; #X connect 2 0 1 0; #X connect 3 0 14 0; #X connect 4 0 1 0; #X connect 5 0 4 0; #X connect 6 0 3 0; #X connect 7 0 54 1; #X connect 8 0 9 0; #X connect 9 0 25 0; #X connect 10 0 8 0; #X connect 11 0 12 0; #X connect 12 0 8 0; #X connect 13 0 14 0; #X connect 14 0 34 0; #X connect 14 0 54 0; #X connect 15 0 19 0; #X connect 16 0 17 0; #X connect 17 0 18 1; #X connect 18 0 0 0; #X connect 19 0 16 0; #X connect 20 0 8 0; #X connect 21 0 23 0; #X connect 22 0 13 1; #X connect 22 0 28 0; #X connect 22 0 28 1; #X connect 22 0 29 0; #X connect 23 0 22 0; #X connect 24 0 8 0; #X connect 25 0 13 0; #X connect 26 0 8 0; #X connect 27 0 8 0; #X connect 28 0 29 1; #X connect 28 0 13 1; #X connect 28 0 37 0; #X connect 28 0 37 1; #X connect 29 0 13 1; #X connect 31 0 35 0; #X connect 32 0 33 0; #X connect 33 0 34 1; #X connect 34 0 30 0; #X connect 35 0 32 0; #X connect 36 0 8 0; #X connect 37 0 13 1; #X connect 38 0 2 0; #X connect 39 0 38 0; #X connect 40 0 54 2; #X connect 41 0 42 0; #X connect 54 0 18 0; #X connect 54 0 41 0; pd-0.46-7/extra/pique/0000775000175000017500000000000012574202336012646 5ustar mspmsppd-0.46-7/extra/pique/GNUmakefile.am0000664000175000017500000000125212374250720015312 0ustar mspmsp## Makefile.am -- Process this file with automake to produce Makefile.in NAME=pique external_LTLIBRARIES = pique.la SOURCES = pique.c PATCHES = pique-help.pd OTHERDATA = EXTRA_DIST = makefile ############################### # you shouldn't need to add anything below here dist_external_DATA = $(PATCHES) $(OTHERDATA) AUTOMAKE_OPTIONS = foreign AM_CPPFLAGS = -I$(top_srcdir)/src -DPD AM_CFLAGS = @ARCH_CFLAGS@ AM_LIBS = $(LIBM) AM_LDFLAGS = -module -avoid-version -shared @ARCH_LDFLAGS@ -shrext .@EXTERNAL_EXTENSION@ -L$(top_srcdir)/src externaldir = $(pkglibdir)/extra/$(NAME) if MINGW AM_LIBS += -lpd endif libtool: $(LIBTOOL_DEPS) $(SHELL) ./config.status --recheck pd-0.46-7/extra/pique/pique-help.pd0000664000175000017500000000217112160204055015234 0ustar mspmsp#N canvas 143 0 729 407 12; #X obj 47 11 pique; #X text 105 12 -- find peaks in an FFT spectrum; #X obj 214 174 rfft~; #X obj 131 129 osc~ 2000; #X graph graph2 0 -64 63 64 519 179 719 39; #X array fft-real 64 float; #X pop; #X graph graph3 0 -64 63 64 519 327 719 187; #X array fft-imag 64 float; #X pop; #X obj 214 215 tabwrite~ fft-real; #X obj 245 240 tabwrite~ fft-imag; #X obj 315 158 metro 1000; #X obj 315 116 loadbang; #X msg 315 138 1; #X obj 91 349 pique; #X msg 91 322 64 fft-real fft-imag 10; #X obj 91 376 print; #X obj 205 132 osc~ 5000; #X text 25 37 pique takes unwindowed FFT analyses as input (they should be stored in arrays) and outputs a list of peaks \, giving their peak number \, frequency \, amplitude \, and phase (as a cosine/sine pair.); #X text 13 289 message argumnets: number of FFT points \, fft real part \, fft imaginary part \, maximum number of peaks to report.; #X text 578 387 updated for Pd 0.31.; #X connect 2 0 6 0; #X connect 2 1 7 0; #X connect 3 0 2 0; #X connect 8 0 6 0; #X connect 8 0 7 0; #X connect 9 0 10 0; #X connect 10 0 8 0; #X connect 11 0 13 0; #X connect 12 0 11 0; #X connect 14 0 2 0; pd-0.46-7/extra/pique/makefile0000664000175000017500000000006212160204055014333 0ustar mspmspNAME=pique CSYM=pique include ../makefile.subdir pd-0.46-7/extra/pique/pique.c0000664000175000017500000002172212222367057014143 0ustar mspmsp/* Copyright (c) 1999 Miller Puckette. The contents of this file are free for any use, but BOTH THE AUTHOR AND UCSD DISCLAIM ALL WARRANTIES related to it. Although not written in Java, this still should not be used to control any machinery containing a sharp blade or combustible materiel, or as part of any life support system or weapon. */ #include "m_pd.h" #include #include /* These pragmas are only used for MSVC, not MinGW or Cygwin */ #ifdef _MSC_VER #pragma warning( disable : 4244 ) #pragma warning( disable : 4305 ) #endif static t_class *pique_class; typedef struct _pique { t_object x_obj; int x_n; t_float x_errthresh; t_float *x_freq; t_float *x_amp; t_float *x_ampre; t_float *x_ampim; } t_pique; static void *pique_new(t_floatarg f) { int n = f; t_pique *x = (t_pique *)pd_new(pique_class); if (n < 1) n = 100; x->x_n = n; x->x_errthresh = 0; x->x_freq = t_getbytes(n * sizeof(*x->x_freq)); x->x_amp = t_getbytes(n * sizeof(*x->x_amp)); x->x_ampre = t_getbytes(n * sizeof(*x->x_ampre)); x->x_ampim = t_getbytes(n * sizeof(*x->x_ampim)); outlet_new(&x->x_obj, &s_list); return (x); } static t_float hanning(t_float pidetune, t_float sinpidetune) { t_float pi = 3.141592653589793; if (pidetune < 0.01 && pidetune > -0.01) return (1); else if (pidetune > 3.14 && pidetune < 3.143) return (0.5); else if (pidetune < -3.14 && pidetune > -3.143) return (0.5); else return (sinpidetune/pidetune - 0.5 * (sinpidetune/(pidetune+pi) + sinpidetune/(pidetune-pi))); } static t_float peakerror(t_word *fpreal, t_word *fpimag, t_float pidetune, t_float norm, t_float peakreal, t_float peakimag) { t_float sinpidetune = sin(pidetune); t_float cospidetune = cos(pidetune); t_float windowshould = hanning(pidetune, sinpidetune); t_float realshould = windowshould * ( peakreal * cospidetune + peakimag * sinpidetune); t_float imagshould = windowshould * ( peakimag * cospidetune - peakreal * sinpidetune); t_float realgot = norm * (fpreal[0].w_float - 0.5 * (fpreal[1].w_float + fpreal[-1].w_float)); t_float imaggot = norm * (fpimag[0].w_float - 0.5 * (fpimag[1].w_float + fpimag[-1].w_float)); t_float realdev = realshould - realgot, imagdev = imagshould - imaggot; /* post("real %f->%f; imag %f->%f", realshould, realgot, imagshould, imaggot); */ return (realdev * realdev + imagdev * imagdev); } static void pique_doit(int npts, t_word *fpreal, t_word *fpimag, int npeak, int *nfound, t_float *fpfreq, t_float *fpamp, t_float *fpampre, t_float *fpampim, t_float errthresh) { t_float srate = sys_getsr(); /* not sure how to get this correctly */ t_float oneovern = 1.0/ (t_float)npts; t_float fperbin = srate * oneovern; t_float pow1, pow2 = 0, pow3 = 0, pow4 = 0, pow5 = 0; t_float re1, re2 = 0, re3 = fpreal->w_float; t_float im1, im2 = 0, im3 = 0, powthresh, relativeerror; int count, peakcount = 0, n2 = (npts >> 1); t_float *fp1, *fp2; t_word *wp1, *wp2; for (count = n2, wp1 = fpreal, wp2 = fpimag, powthresh = 0; count--; wp1++, wp2++) powthresh += (wp1->w_float) * (wp1->w_float) + (wp2->w_float) * (wp2->w_float) ; powthresh *= 0.00001; for (count = 1; count < n2; count++) { t_float windreal, windimag, pi = 3.141592653589793; t_float detune, pidetune, sinpidetune, cospidetune, ampcorrect, freqout, ampout, ampoutreal, ampoutimag; t_float rpeak, rpeaknext, rpeakprev; t_float ipeak, ipeaknext, ipeakprev; t_float errleft, errright; fpreal++; fpimag++; re1 = re2; re2 = re3; re3 = fpreal->w_float; im1 = im2; im2 = im3; im3 = fpimag->w_float; if (count < 2) continue; pow1 = pow2; pow2 = pow3; pow3 = pow4; pow4 = pow5; /* get Hanning-windowed spectrum by convolution */ windreal = re2 - 0.5 * (re1 + re3); windimag = im2 - 0.5 * (im1 + im3); pow5 = windreal * windreal + windimag * windimag; /* if (count < 30) post("power %f", pow5); */ if (count < 5) continue; /* check for a peak. The actual bin is count-3. */ if (pow3 <= pow2 || pow3 <= pow4 || pow3 <= pow1 || pow3 <= pow5 || pow3 < powthresh) continue; /* go back for the raw FFT values around the peak. */ rpeak = fpreal[-3].w_float; rpeaknext = fpreal[-2].w_float; rpeakprev = fpreal[-4].w_float; ipeak = fpimag[-3].w_float; ipeaknext = fpimag[-2].w_float; ipeakprev = fpimag[-4].w_float; /* recalculate Hanning-windowed spectrum by convolution */ windreal = rpeak - 0.5 * (rpeaknext + rpeakprev); windimag = ipeak - 0.5 * (ipeaknext + ipeakprev); detune = ((rpeakprev - rpeaknext) * (2.0 * rpeak - rpeakprev - rpeaknext) + (ipeakprev - ipeaknext) * (2.0 * ipeak - ipeakprev - ipeaknext)) / (4.0 * pow3); /* if (count < 30) post("detune %f", detune); */ if (detune > 0.7 || detune < -0.7) continue; /* the frequency is the sum of the bin frequency and detuning */ freqout = fperbin * ((t_float)(count-3) + detune); pidetune = pi * detune; sinpidetune = sin(pidetune); cospidetune = cos(pidetune); ampcorrect = 1.0 / hanning(pidetune, sinpidetune); /* Multiply by 2 to get real-sinusoid peak amplitude and divide by N to normalize FFT */ ampcorrect *= 2. * oneovern; /* amplitude is peak height, corrected for Hanning window shape */ ampout = ampcorrect * sqrt(pow3); ampoutreal = ampcorrect * (windreal * cospidetune - windimag * sinpidetune); ampoutimag = ampcorrect * (windreal * sinpidetune + windimag * cospidetune); if (errthresh > 0) { /* post("peak %f %f", freqout, ampout); */ errleft = peakerror(fpreal-4, fpimag-4, pidetune+pi, 2. * oneovern, ampoutreal, ampoutimag); errright = peakerror(fpreal-2, fpimag-2, pidetune-pi, 2. * oneovern, ampoutreal, ampoutimag); relativeerror = (errleft + errright)/(ampout * ampout); if (relativeerror > errthresh) continue; } /* post("power %f, error %f, relative %f", pow3, errleft + errright, relativeerror); */ *fpfreq++ = freqout; *fpamp++ = ampout; *fpampre++ = ampoutreal; *fpampim++ = ampoutimag; if (++peakcount == npeak) break; } *nfound = peakcount; } static void pique_list(t_pique *x, t_symbol *s, int argc, t_atom *argv) { int npts = atom_getintarg(0, argc, argv); t_symbol *symreal = atom_getsymbolarg(1, argc, argv); t_symbol *symimag = atom_getsymbolarg(2, argc, argv); int npeak = atom_getintarg(3, argc, argv); int n; t_garray *a; t_word *fpreal, *fpimag; if (npts < 8 || npeak < 1) error("pique: bad npoints or npeak"); if (npeak > x->x_n) npeak = x->x_n; if (!(a = (t_garray *)pd_findbyclass(symreal, garray_class)) || !garray_getfloatwords(a, &n, &fpreal) || n < npts) error("%s: missing or bad array", symreal->s_name); else if (!(a = (t_garray *)pd_findbyclass(symimag, garray_class)) || !garray_getfloatwords(a, &n, &fpimag) || n < npts) error("%s: missing or bad array", symimag->s_name); else { int nfound, i; t_float *fpfreq = x->x_freq; t_float *fpamp = x->x_amp; t_float *fpampre = x->x_ampre; t_float *fpampim = x->x_ampim; pique_doit(npts, fpreal, fpimag, npeak, &nfound, fpfreq, fpamp, fpampre, fpampim, x->x_errthresh); for (i = 0; i < nfound; i++, fpamp++, fpfreq++, fpampre++, fpampim++) { t_atom at[5]; SETFLOAT(at, (t_float)i); SETFLOAT(at+1, *fpfreq); SETFLOAT(at+2, *fpamp); SETFLOAT(at+3, *fpampre); SETFLOAT(at+4, *fpampim); outlet_list(x->x_obj.ob_outlet, &s_list, 5, at); } } } static void pique_errthresh(t_pique *x, t_floatarg f) { x->x_errthresh = f; } static void pique_free(t_pique *x) { int n = x->x_n; t_freebytes(x->x_freq, n * sizeof(*x->x_freq)); t_freebytes(x->x_amp, n * sizeof(*x->x_amp)); t_freebytes(x->x_ampre, n * sizeof(*x->x_ampre)); t_freebytes(x->x_ampim, n * sizeof(*x->x_ampim)); } void pique_setup(void) { pique_class = class_new(gensym("pique"), (t_newmethod)pique_new, (t_method)pique_free, sizeof(t_pique),0, A_DEFFLOAT, 0); class_addlist(pique_class, pique_list); class_addmethod(pique_class, (t_method)pique_errthresh, gensym("errthresh"), A_FLOAT, 0); post("pique 0.1 for PD version 23"); } pd-0.46-7/extra/lrshift~/0000775000175000017500000000000012574202336013374 5ustar mspmsppd-0.46-7/extra/lrshift~/GNUmakefile.am0000664000175000017500000000126612374250720016045 0ustar mspmsp## Makefile.am -- Process this file with automake to produce Makefile.in NAME=lrshift~ external_LTLIBRARIES = lrshift~.la SOURCES = lrshift~.c PATCHES = lrshift~-help.pd OTHERDATA = EXTRA_DIST = makefile ############################### # you shouldn't need to add anything below here dist_external_DATA = $(PATCHES) $(OTHERDATA) AUTOMAKE_OPTIONS = foreign AM_CPPFLAGS = -I$(top_srcdir)/src -DPD AM_CFLAGS = @ARCH_CFLAGS@ AM_LIBS = $(LIBM) AM_LDFLAGS = -module -avoid-version -shared @ARCH_LDFLAGS@ -shrext .@EXTERNAL_EXTENSION@ -L$(top_srcdir)/src externaldir = $(pkglibdir)/extra/$(NAME) if MINGW AM_LIBS += -lpd endif libtool: $(LIBTOOL_DEPS) $(SHELL) ./config.status --recheck pd-0.46-7/extra/lrshift~/lrshift~.c0000664000175000017500000000344212222367057015416 0ustar mspmsp#include "m_pd.h" /* ------------------------ lrshift~ ----------------------------- */ static t_class *lrshift_tilde_class; typedef struct _lrshift_tilde { t_object x_obj; int x_n; t_float x_f; } t_lrshift_tilde; static t_int *leftshift_perform(t_int *w) { t_sample *in = (t_sample *)(w[1]); t_sample *out= (t_sample *)(w[2]); int n = (int)(w[3]); int shift = (int)(w[4]); in += shift; n -= shift; while (n--) *out++ = *in++; while (shift--) *out++ = 0; return (w+5); } static t_int *rightshift_perform(t_int *w) { t_sample *in = (t_sample *)(w[1]); t_sample *out= (t_sample *)(w[2]); int n = (int)(w[3]); int shift = (int)(w[4]); n -= shift; in -= shift; while (n--) *--out = *--in; while (shift--) *--out = 0; return (w+5); } static void lrshift_tilde_dsp(t_lrshift_tilde *x, t_signal **sp) { int n = sp[0]->s_n; int shift = x->x_n; if (shift > n) shift = n; if (shift < -n) shift = -n; if (shift < 0) dsp_add(rightshift_perform, 4, sp[0]->s_vec + n, sp[1]->s_vec + n, n, -shift); else dsp_add(leftshift_perform, 4, sp[0]->s_vec, sp[1]->s_vec, n, shift); } static void *lrshift_tilde_new(t_floatarg f) { t_lrshift_tilde *x = (t_lrshift_tilde *)pd_new(lrshift_tilde_class); x->x_n = f; x->x_f = 0; outlet_new(&x->x_obj, gensym("signal")); return (x); } void lrshift_tilde_setup(void) { lrshift_tilde_class = class_new(gensym("lrshift~"), (t_newmethod)lrshift_tilde_new, 0, sizeof(t_lrshift_tilde), 0, A_DEFFLOAT, 0); CLASS_MAINSIGNALIN(lrshift_tilde_class, t_lrshift_tilde, x_f); class_addmethod(lrshift_tilde_class, (t_method)lrshift_tilde_dsp, gensym("dsp"), 0); } pd-0.46-7/extra/lrshift~/lrshift~-help.pd0000664000175000017500000000204512441361773016525 0ustar mspmsp#N canvas 143 0 673 325 12; #X msg 268 277 bang; #X obj 244 303 print~; #X msg 185 278 bang; #X obj 161 304 print~; #X text 53 117 click here first; #X msg 72 270 bang; #X obj 48 296 print~; #X text 162 222 shift left; #X text 243 224 shift right; #X obj 161 252 lrshift~ 1; #X obj 244 251 lrshift~ -1; #X text 39 37 Acting at whatever vector size the window is running at \, lrshift~ shifts samples to the left (toward the beginning sample) or to the right. The argument gives the direction and the amount of the shift. The rightmost (or leftmost) samples are set to zero.; #N canvas 0 0 450 300 (subpatch) 0; #X array shiftin 64 float 0; #X coords 0 1 63 0 200 140 1; #X restore 448 118 graph; #X text 115 11 -- shift signal vector elements left or right; #X msg 54 138 \; pd dsp 1 \; shiftin 1 1; #X obj 48 204 tabreceive~ shiftin; #X text 525 308 Updated for Pd 0.31.; #X obj 47 11 lrshift~; #X connect 0 0 1 0; #X connect 2 0 3 0; #X connect 5 0 6 0; #X connect 9 0 3 0; #X connect 10 0 1 0; #X connect 15 0 6 0; #X connect 15 0 9 0; #X connect 15 0 10 0; pd-0.46-7/extra/lrshift~/makefile0000664000175000017500000000007512160204055015065 0ustar mspmspNAME=lrshift~ CSYM=lrshift_tilde include ../makefile.subdir pd-0.46-7/extra/zzzz/0000775000175000017500000000000012572430572012555 5ustar mspmsppd-0.46-7/extra/bonk~/0000775000175000017500000000000012574202336012652 5ustar mspmsppd-0.46-7/extra/bonk~/bonk~-help.pd0000664000175000017500000001663012374250720015260 0ustar mspmsp#N canvas 2 52 1082 583 12; #X obj 382 492 spigot; #X msg 484 293 bang; #X obj 483 454 bonk~; #X msg 483 357 print; #X obj 435 428 adc~; #X msg 637 506 \; pd dsp 1; #X obj 300 492 spigot; #N canvas 366 126 604 404 synth 0; #X obj 112 24 r bonk-cooked; #X obj 112 49 unpack; #X obj 112 99 * 12; #X obj 112 124 div 7; #X obj 112 74 + 1; #X obj 112 174 mtof; #X obj 112 224 osc~; #X obj 112 249 cos~; #X obj 112 149 + 47; #X obj 209 247 line~; #X obj 209 272 *~; #X obj 209 297 lop~ 500; #X obj 112 274 *~; #X obj 103 361 dac~; #X obj 253 165 dbtorms; #X obj 253 115 * 0.5; #X obj 253 140 + 50; #X obj 211 189 f; #X msg 173 159 bang; #X obj 258 83 inlet; #X obj 111 307 hip~ 5; #X msg 34 24 0 60; #X obj 112 199 sig~; #X msg 209 222 \$1 \, 0 200; #X connect 0 0 1 0; #X connect 1 0 4 0; #X connect 2 0 3 0; #X connect 3 0 8 0; #X connect 4 0 2 0; #X connect 5 0 18 0; #X connect 5 0 22 0; #X connect 6 0 7 0; #X connect 7 0 12 0; #X connect 8 0 5 0; #X connect 9 0 10 0; #X connect 9 0 10 1; #X connect 10 0 11 0; #X connect 11 0 12 1; #X connect 12 0 20 0; #X connect 14 0 17 1; #X connect 15 0 16 0; #X connect 16 0 14 0; #X connect 17 0 23 0; #X connect 18 0 17 0; #X connect 19 0 15 0; #X connect 20 0 13 1; #X connect 20 0 13 0; #X connect 21 0 1 0; #X connect 22 0 6 0; #X connect 23 0 9 0; #X restore 869 523 pd synth; #X floatatom 869 500 0 0 0 0 - - -; #X msg 869 470 0; #X msg 900 470 90; #X text 625 472 click here; #X text 626 485 to start DSP; #X text 5 285 In this patch \, after starting DSP \, you can print out the raw or cooked output using the two "spigots" or listen to a synthesizer output by raising its volume.; #X text 770 469 output volume; #X text 784 487 (0-100); #X msg 483 138 mask 4 0.7; #X text 578 120 Describes how energy in each frequency band masks later energy in the band. Here the masking is total for 4 analysis periods and then drops by 0.7 each period.; #X text 528 286 Poll the current spectrum via "raw" outlet \, You can set a very high threshold if you don't want attacks mixed in.; #X msg 483 331 debug 0; #X text 561 331 turn debugging on or off.; #X obj 349 493 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 431 493 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 382 522 print cooked; #X obj 300 522 print raw; #X text 162 491 enable printout:; #X text 560 202 Minimum "velocity" to output (quieter notes are ignored.) ; #X obj 485 481 s bonk-cooked; #X text 8 145 Bonk's two outputs are the raw spectrum of the attack (provided as a list of 11 numbers giving the signal "loudness" in the 11 frequency bands used) \, and the "cooked" output which gives only an instrument number (counting up from zero) and a "velocity". This "velocity" is the sum of the square roots of the amplitudes of the bands \, normalized so that 100 is an attack of amplitude of about 1 The instrument number is significant only if Bonk has a "template set" in memory.; #X text 580 35 Set low and high thresholds. Signal growth must exceed the high one and then fall to the low one to make an attack. The unit is the sum of the proportional growth in the 11 filter bands. Proportional growth is essentially the logarithmic time derivative.; #X msg 483 384 print 1; #X text 551 386 print out filterbank settings; #X text 9 33 The Bonk object takes an audio signal input and looks for "attacks" defined as sharp changes in the spectral envelope of the incoming sound. Optionally \, and less reliably \, you can have Bonk check the attack against a collection of stored templates to try to guess which of two or more instruments was hit. Bonk is described theoretically in the 1998 ICMC proceedings \, reprinted on crca.ucsd.edu/~msp .; #N canvas 2 52 699 717 creation-arguments 0; #X text 228 14 creation arguments for bonk~; #X text 70 272 -npts 256; #X text 44 244 default value:; #X text 70 308 -hop 128; #X text 70 342 -nfilters 11; #X text 68 380 -halftones 6; #X text 76 514 -overlap 1; #X text 79 567 -firstbin 1; #X text 71 454 -minbandwidth 1.5; #X text 122 147 All frequency parameters are specified in 'bins'. One bin is the sample rate divided by the window size. The minimum possible bandwidth is 1.5 bins. Higher bandwidths give numerically more robust outputs.; #X text 43 229 Arguments and; #X text 212 270 window size in points; #X text 210 306 analysis period ("hop size") in points; #X text 212 340 number of filters to use; #X text 212 379 desired bandwidth of filters in halftones \, effective in the exponentially spaced region. (At lower center frequencies the bandwidth is supported by the "minbandwidth" parameter below).; #X text 212 511 overlap factor between filters. If 1 \, the filters are spaced to line up at their half-power points. Other values specify more or fewer filters proportionally.; #X text 121 49 bonk~ uses a filterbank whose center frequencies are spaced equally at low frequencies and proportionally at high ones - i.e. \, they increase linearly \, then exponentially. They are determined by the filters' bandwidths and overlap. The bandwidths are specified proportionally to frequency but bounded below by a specified minimum. ; #X text 210 455 minimum bandwidth in bins. If the bandwidth specified by "halftones" is smaller than this \, this value is used. This must be at least 1.5.; #X text 212 567 center frequency \, in bins \, of the lowest filter. The others are computed from this.; #X restore 147 414 pd creation-arguments; #N canvas 660 173 579 589 templates 0; #X msg 76 197 learn 0; #X msg 76 227 forget; #X msg 76 257 write templates.txt; #X msg 76 287 read templates.txt; #X msg 76 107 debounce 0; #X msg 76 137 learn 10; #X obj 62 431 outlet; #X text 155 133 Forget all templates and start learning new ones. The argument gives the number of times you will hit each instrument (10 recommended.) Turn on the output volume above for audible feedback as you train Bonk. "Learn 0" exits learn mode.; #X text 155 217 Forget the last template. In Learn mode \, use "forget" to erase and record over a template.; #X text 220 253 Write templates to a file in text-editable format. ; #X text 221 283 Read templates from a file.; #X text 157 104 Minimum time (msec) between attacks in learn mode; #X connect 0 0 6 0; #X connect 1 0 6 0; #X connect 2 0 6 0; #X connect 3 0 6 0; #X connect 4 0 6 0; #X connect 5 0 6 0; #X restore 500 421 pd templates; #X msg 483 68 thresh 2.5 5; #X msg 483 173 attack-frames 1; #X text 608 174 number of frames over which to measure growth; #X text 605 422 more messages for managing templates; #X msg 483 201 minvel 7; #X msg 483 228 spew 0; #X text 550 230 Turn spew mode on/off; #X msg 483 255 useloudness 0; #X text 597 254 experimental: use alternative loudness units; #X text 212 9 BONK~ - attack detection and spectral envelope measurement ; #X text 734 552 Updated for Pd version 0.42; #X text 5 344 By default bonk's analysis is carried out on a 256-point window (6 msec at 44.1 kHz) and the analysis period is 128 samples. These and other parameters may be overridden using creation arguments as shown in the subpatch below:; #X text 552 356 Print out settings and templates.; #X connect 0 0 23 0; #X connect 1 0 2 0; #X connect 2 0 6 0; #X connect 2 1 0 0; #X connect 2 1 27 0; #X connect 3 0 2 0; #X connect 4 0 2 0; #X connect 6 0 24 0; #X connect 8 0 7 0; #X connect 9 0 8 0; #X connect 10 0 8 0; #X connect 16 0 2 0; #X connect 19 0 2 0; #X connect 21 0 6 1; #X connect 22 0 0 1; #X connect 30 0 2 0; #X connect 34 0 2 0; #X connect 35 0 2 0; #X connect 36 0 2 0; #X connect 39 0 2 0; #X connect 40 0 2 0; #X connect 42 0 2 0; pd-0.46-7/extra/bonk~/bonk~.c0000664000175000017500000014773412574135745014176 0ustar mspmsp/* ########################################################################### # bonk~ - a Max/MSP external # by miller puckette and ted apel # http://crca.ucsd.edu/~msp/ # Max/MSP port by barry threw # http://www.barrythrew.com # me@barrythrew.com # San Francisco, CA # (c) 2008 # for Kesumo - http://www.kesumo.com ########################################################################### // bonk~ detects attacks in an audio signal ########################################################################### This software is copyrighted by Miller Puckette and others. The following terms (the "Standard Improved BSD License") apply to all files associated with the software unless explicitly disclaimed in individual files: Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* dolist: decay and other times in msec */ #include #include #include /* These pragmas are only used for MSVC, not MinGW or Cygwin */ #ifdef _MSC_VER #pragma warning (disable: 4305 4244) #endif #ifdef MSP #include "ext.h" #include "z_dsp.h" #include "math.h" #include "ext_support.h" #include "ext_proto.h" #include "ext_obex.h" typedef double t_floatarg; /* from m_pd.h */ #define flog log #define fexp exp #define fsqrt sqrt #define t_resizebytes(a, b, c) t_resizebytes((char *)(a), (b), (c)) void *bonk_class; #define getbytes t_getbytes #define freebytes t_freebytes #endif /* MSP */ #ifdef PD #include "m_pd.h" static t_class *bonk_class; #endif #ifdef _WIN32 #include #elif ! defined(_MSC_VER) #include #endif /* ------------------------ bonk~ ----------------------------- */ #define DEFNPOINTS 256 #define MAXCHANNELS 8 #define MINPOINTS 64 #define DEFPERIOD 128 #define DEFNFILTERS 11 #define DEFHALFTONES 6 #define DEFOVERLAP 1 #define DEFFIRSTBIN 1 #define DEFMINBANDWIDTH 1.5 #define DEFHITHRESH 5 #define DEFLOTHRESH 2.5 #define DEFMASKTIME 4 #define DEFMASKDECAY 0.7 #define DEFDEBOUNCEDECAY 0 #define DEFMINVEL 7 #define DEFATTACKBINS 1 #define MAXATTACKWAIT 4 typedef struct _filterkernel { int k_filterpoints; int k_hoppoints; int k_skippoints; int k_nhops; t_float k_centerfreq; /* center frequency, bins */ t_float k_bandwidth; /* bandwidth, bins */ t_float *k_stuff; } t_filterkernel; typedef struct _filterbank { int b_nfilters; /* number of filters in bank */ int b_npoints; /* input vector size */ t_float b_halftones; /* filter bandwidth in halftones */ t_float b_overlap; /* overlap; default 1 for 1/2-power pts */ t_float b_firstbin; /* freq of first filter in bins, default 1 */ t_float b_minbandwidth; /* minimum bandwidth, default 1.5 */ t_filterkernel *b_vec; /* filter kernels */ int b_refcount; /* number of bonk~ objects using this */ struct _filterbank *b_next; /* next in linked list */ } t_filterbank; #if 0 /* this is the design for 1.0: */ static t_filterkernel bonk_filterkernels[] = {{256, 2, .01562}, {256, 4, .01562}, {256, 6, .01562}, {180, 6, .02222}, {128, 6, .01803}, {90, 6, .02222}, {64, 6, .02362}, {46, 6, .02773}, {32, 6, .03227}, {22, 6, .03932}, {16, 6, .04489}}; #endif #if 0 /* here's the 1.1 rev: */ static t_filterkernel bonk_filterkernels[] = {{256, 1, .01562, 0}, {256, 3, .01562, 0}, {256, 5, .01562, 0}, {212, 6, .01886, 0}, {150, 6, .01885, 0}, {106, 6, .02179, 0}, {76, 6, .0236, 0}, {54, 6, .02634, 0}, {38, 6, .03047, 0}, {26, 6, .03667, 0}, {18, 6, .04458, 0}}; #define NFILTERS \ ((int)(sizeof(bonk_filterkernels) / sizeof(bonk_filterkernels[0]))) #endif #if 0 /* and 1.2 */ #define NFILTERS 11 static t_filterkernel bonk_filterkernels[NFILTERS]; #endif /* and 1.3 */ #define MAXNFILTERS 50 #define MASKHIST 8 static t_filterbank *bonk_filterbanklist; typedef struct _hist { t_float h_power; t_float h_before; t_float h_outpower; int h_countup; t_float h_mask[MASKHIST]; } t_hist; typedef struct template { t_float t_amp[MAXNFILTERS]; } t_template; typedef struct _insig { t_hist g_hist[MAXNFILTERS]; /* history for each filter */ #ifdef PD t_outlet *g_outlet; /* outlet for raw data */ #endif #ifdef MSP void *g_outlet; /* outlet for raw data */ #endif t_float *g_inbuf; /* buffered input samples */ t_float *g_invec; /* new input samples */ } t_insig; typedef struct _bonk { #ifdef PD t_object x_obj; t_outlet *x_cookedout; t_clock *x_clock; t_canvas *x_canvas; /* ptr to current canvas --fbar */ #endif /* PD */ #ifdef MSP t_pxobject x_obj; void *obex; void *x_cookedout; void *x_clock; #endif /* MSP */ /* parameters */ int x_npoints; /* number of points in input buffer */ int x_period; /* number of input samples between analyses */ int x_nfilters; /* number of filters requested */ t_float x_halftones; /* nominal halftones between filters */ t_float x_overlap; t_float x_firstbin; t_float x_minbandwidth; t_float x_hithresh; /* threshold for total growth to trigger */ t_float x_lothresh; /* threshold for total growth to re-arm */ t_float x_minvel; /* minimum velocity we output */ t_float x_maskdecay; int x_masktime; int x_useloudness; /* use loudness spectra instead of power */ t_float x_debouncedecay; t_float x_debouncevel; double x_learndebounce; /* debounce time (in "learn" mode only) */ int x_attackbins; /* number of bins to wait for attack */ t_filterbank *x_filterbank; t_hist x_hist[MAXNFILTERS]; t_template *x_template; t_insig *x_insig; int x_ninsig; int x_ntemplate; int x_infill; int x_countdown; int x_willattack; int x_attacked; int x_debug; int x_learn; int x_learncount; /* countup for "learn" mode */ int x_spew; /* if true, always generate output! */ int x_maskphase; /* phase, 0 to MASKHIST-1, for mask history */ t_float x_sr; /* current sample rate in Hz. */ int x_hit; /* next "tick" called because of a hit, not a poll */ } t_bonk; #ifdef MSP static void *bonk_new(t_symbol *s, long ac, t_atom *av); static void bonk_tick(t_bonk *x); static void bonk_doit(t_bonk *x); static t_int *bonk_perform(t_int *w); static void bonk_dsp(t_bonk *x, t_signal **sp); void bonk_assist(t_bonk *x, void *b, long m, long a, char *s); static void bonk_free(t_bonk *x); void bonk_setup(void); int main(); static void bonk_thresh(t_bonk *x, t_floatarg f1, t_floatarg f2); static void bonk_print(t_bonk *x, t_floatarg f); static void bonk_bang(t_bonk *x); static void bonk_write(t_bonk *x, t_symbol *s); static void bonk_dowrite(t_bonk *x, t_symbol *s); static void bonk_writefile(t_bonk *x, char *filename, short path); static void bonk_read(t_bonk *x, t_symbol *s); static void bonk_doread(t_bonk *x, t_symbol *s); static void bonk_openfile(t_bonk *x, char *filename, short path); void bonk_minvel_set(t_bonk *x, void *attr, long ac, t_atom *av); void bonk_lothresh_set(t_bonk *x, void *attr, long ac, t_atom *av); void bonk_hithresh_set(t_bonk *x, void *attr, long ac, t_atom *av); void bonk_masktime_set(t_bonk *x, void *attr, long ac, t_atom *av); void bonk_maskdecay_set(t_bonk *x, void *attr, long ac, t_atom *av); void bonk_debouncedecay_set(t_bonk *x, void *attr, long ac, t_atom *av); void bonk_debug_set(t_bonk *x, void *attr, long ac, t_atom *av); void bonk_spew_set(t_bonk *x, void *attr, long ac, t_atom *av); void bonk_useloudness_set(t_bonk *x, void *attr, long ac, t_atom *av); void bonk_attackbins_set(t_bonk *x, void *attr, long ac, t_atom *av); void bonk_learn_set(t_bonk *x, void *attr, long ac, t_atom *av); t_float qrsqrt(t_float f); double clock_getsystime(); double clock_gettimesince(double prevsystime); char *strcpy(char *s1, const char *s2); #endif static void bonk_tick(t_bonk *x); #define HALFWIDTH 0.75 /* half peak bandwidth at half power point in bins */ #define SLIDE 0.25 /* relative slide between filter subwindows */ static t_filterbank *bonk_newfilterbank(int npoints, int nfilters, t_float halftones, t_float overlap, t_float firstbin, t_float minbandwidth) { int i, j; t_float cf, bw, h, relspace; t_filterbank *b = (t_filterbank *)getbytes(sizeof(*b)); b->b_npoints = npoints; b->b_nfilters = nfilters; b->b_halftones = halftones; b->b_overlap = overlap; b->b_firstbin = firstbin; b->b_minbandwidth = minbandwidth; b->b_refcount = 0; b->b_next = bonk_filterbanklist; bonk_filterbanklist = b; b->b_vec = (t_filterkernel *)getbytes(nfilters * sizeof(*b->b_vec)); h = exp((log(2.)/12.)*halftones); /* specced interval between filters */ relspace = (h - 1)/(h + 1); /* nominal spacing-per-f for fbank */ if (minbandwidth < 2*HALFWIDTH) minbandwidth = 2*HALFWIDTH; if (firstbin < minbandwidth/(2*HALFWIDTH)) firstbin = minbandwidth/(2*HALFWIDTH); cf = firstbin; bw = cf * relspace * overlap; if (bw < (0.5*minbandwidth)) bw = (0.5*minbandwidth); for (i = 0; i < nfilters; i++) { t_float *fp, newcf, newbw; t_float normalizer = 0; int filterpoints, skippoints, hoppoints, nhops; filterpoints = npoints * HALFWIDTH/bw; if (cf > npoints/2) { post("bonk~: only using %d filters (ran past Nyquist)", i+1); break; } if (filterpoints < 4) { post("bonk~: only using %d filters (kernels got too short)", i+1); break; } else if (filterpoints > npoints) filterpoints = npoints; hoppoints = SLIDE * npoints * HALFWIDTH/bw; nhops = 1. + (npoints-filterpoints)/(t_float)hoppoints; skippoints = 0.5 * (npoints-filterpoints - (nhops-1) * hoppoints); b->b_vec[i].k_stuff = (t_float *)getbytes(2 * sizeof(t_float) * filterpoints); b->b_vec[i].k_filterpoints = filterpoints; b->b_vec[i].k_nhops = nhops; b->b_vec[i].k_hoppoints = hoppoints; b->b_vec[i].k_skippoints = skippoints; b->b_vec[i].k_centerfreq = cf; b->b_vec[i].k_bandwidth = bw; for (fp = b->b_vec[i].k_stuff, j = 0; j < filterpoints; j++, fp+= 2) { t_float phase = j * cf * (2*3.141592653589793 / npoints); t_float wphase = j * (2*3.141592653589793 / filterpoints); t_float window = sin(0.5*wphase); fp[0] = window * cos(phase); fp[1] = window * sin(phase); normalizer += window; } normalizer = 1/(normalizer * sqrt(nhops)); for (fp = b->b_vec[i].k_stuff, j = 0; j < filterpoints; j++, fp+= 2) fp[0] *= normalizer, fp[1] *= normalizer; #if 0 post("i %d cf %.2f bw %.2f nhops %d, hop %d, skip %d, npoints %d", i, cf, bw, nhops, hoppoints, skippoints, filterpoints); #endif newcf = (cf + bw/overlap)/(1 - relspace); newbw = newcf * overlap * relspace; if (newbw < 0.5*minbandwidth) { newbw = 0.5*minbandwidth; newcf = cf + minbandwidth / overlap; } cf = newcf; bw = newbw; } for (; i < nfilters; i++) b->b_vec[i].k_stuff = 0, b->b_vec[i].k_filterpoints = 0; return (b); } static void bonk_freefilterbank(t_filterbank *b) { t_filterbank *b2, *b3; int i; if (bonk_filterbanklist == b) bonk_filterbanklist = b->b_next; else for (b2 = bonk_filterbanklist; b3 = b2->b_next; b2 = b3) if (b3 == b) { b2->b_next = b3->b_next; break; } for (i = 0; i < b->b_nfilters; i++) if (b->b_vec[i].k_stuff) freebytes(b->b_vec[i].k_stuff, b->b_vec[i].k_filterpoints * sizeof(t_float)); freebytes(b, sizeof(*b)); } static void bonk_donew(t_bonk *x, int npoints, int period, int nsig, int nfilters, t_float halftones, t_float overlap, t_float firstbin, t_float minbandwidth, t_float samplerate) { int i, j; t_hist *h; t_float *fp; t_insig *g; t_filterbank *fb; for (j = 0, g = x->x_insig; j < nsig; j++, g++) { for (i = 0, h = g->g_hist; i--; h++) { h->h_power = h->h_before = 0, h->h_countup = 0; for (j = 0; j < MASKHIST; j++) h->h_mask[j] = 0; } /* we ought to check for failure to allocate memory here */ g->g_inbuf = (t_float *)getbytes(npoints * sizeof(t_float)); for (i = npoints, fp = g->g_inbuf; i--; fp++) *fp = 0; } if (!period) period = npoints/2; x->x_npoints = npoints; x->x_period = period; x->x_ninsig = nsig; x->x_nfilters = nfilters; x->x_halftones = halftones; x->x_template = (t_template *)getbytes(0); x->x_ntemplate = 0; x->x_infill = 0; x->x_countdown = 0; x->x_willattack = 0; x->x_attacked = 0; x->x_maskphase = 0; x->x_debug = 0; x->x_hithresh = DEFHITHRESH; x->x_lothresh = DEFLOTHRESH; x->x_masktime = DEFMASKTIME; x->x_maskdecay = DEFMASKDECAY; x->x_learn = 0; x->x_learndebounce = clock_getsystime(); x->x_learncount = 0; x->x_debouncedecay = DEFDEBOUNCEDECAY; x->x_minvel = DEFMINVEL; x->x_useloudness = 0; x->x_debouncevel = 0; x->x_attackbins = DEFATTACKBINS; x->x_sr = samplerate; x->x_filterbank = 0; x->x_hit = 0; for (fb = bonk_filterbanklist; fb; fb = fb->b_next) if (fb->b_nfilters == x->x_nfilters && fb->b_halftones == x->x_halftones && fb->b_firstbin == firstbin && fb->b_overlap == overlap && fb->b_npoints == x->x_npoints && fb->b_minbandwidth == minbandwidth) { fb->b_refcount++; x->x_filterbank = fb; break; } if (!x->x_filterbank) x->x_filterbank = bonk_newfilterbank(npoints, nfilters, halftones, overlap, firstbin, minbandwidth), x->x_filterbank->b_refcount++; } static void bonk_tick(t_bonk *x) { t_atom at[MAXNFILTERS], *ap, at2[3]; int i, j, k, n; t_hist *h; t_float *pp, vel = 0., temperature = 0.; t_float *fp; t_template *tp; int nfit, ninsig = x->x_ninsig, ntemplate = x->x_ntemplate, nfilters = x->x_nfilters; t_insig *gp; #ifdef _MSC_VER t_float powerout[MAXNFILTERS*MAXCHANNELS]; #else t_float *powerout = alloca(x->x_nfilters * x->x_ninsig * sizeof(*powerout)); #endif for (i = ninsig, pp = powerout, gp = x->x_insig; i--; gp++) { for (j = 0, h = gp->g_hist; j < nfilters; j++, h++, pp++) { t_float power = h->h_outpower; t_float intensity = *pp = (power > 0. ? 100. * qrsqrt(qrsqrt(power)) : 0.); vel += intensity; temperature += intensity * (t_float)j; } } if (vel > 0) temperature /= vel; else temperature = 0; vel *= 0.5 / ninsig; /* fudge factor */ if (x->x_hit) { /* if hit nonzero it's a clock callback. if in "learn" mode update the template list; in any event match the hit to known templates. */ if (vel < x->x_debouncevel) { if (x->x_debug) post("bounce cancelled: vel %f debounce %f", vel, x->x_debouncevel); return; } if (vel < x->x_minvel) { if (x->x_debug) post("low velocity cancelled: vel %f, minvel %f", vel, x->x_minvel); return; } x->x_debouncevel = vel; if (x->x_learn) { double lasttime = x->x_learndebounce; double msec = clock_gettimesince(lasttime); if ((!ntemplate) || (msec > 200)) { int countup = x->x_learncount; /* normalize to 100 */ t_float norm; for (i = nfilters * ninsig, norm = 0, pp = powerout; i--; pp++) norm += *pp * *pp; if (norm < 1.0e-15) norm = 1.0e-15; norm = 100. * qrsqrt(norm); /* check if this is the first strike for a new template */ if (!countup) { int oldn = ntemplate; x->x_ntemplate = ntemplate = oldn + ninsig; x->x_template = (t_template *)t_resizebytes(x->x_template, oldn * sizeof(x->x_template[0]), ntemplate * sizeof(x->x_template[0])); for (i = ninsig, pp = powerout; i--; oldn++) for (j = nfilters, fp = x->x_template[oldn].t_amp; j--; pp++, fp++) *fp = *pp * norm; } else { int oldn = ntemplate - ninsig; if (oldn < 0) post("bonk_tick bug"); for (i = ninsig, pp = powerout; i--; oldn++) { for (j = nfilters, fp = x->x_template[oldn].t_amp; j--; pp++, fp++) *fp = (countup * *fp + *pp * norm) /(countup + 1.0); } } countup++; if (countup == x->x_learn) countup = 0; x->x_learncount = countup; } else return; } x->x_learndebounce = clock_getsystime(); if (ntemplate) { t_float bestfit = -1e30; int templatecount; nfit = -1; for (i = 0, templatecount = 0, tp = x->x_template; templatecount < ntemplate; i++) { t_float dotprod = 0; for (k = 0, pp = powerout; k < ninsig && templatecount < ntemplate; k++, tp++, templatecount++) { for (j = nfilters, fp = tp->t_amp; j--; fp++, pp++) { if (*fp < 0 || *pp < 0) post("bonk_tick bug 2"); dotprod += *fp * *pp; } } if (dotprod > bestfit) { bestfit = dotprod; nfit = i; } } if (nfit < 0) post("bonk_tick bug"); } else nfit = 0; } else nfit = -1; /* hit is zero; this is the "bang" method. */ x->x_attacked = 1; if (x->x_debug) post("bonk out: number %d, vel %f, temperature %f", nfit, vel, temperature); SETFLOAT(at2, nfit); SETFLOAT(at2+1, vel); SETFLOAT(at2+2, temperature); outlet_list(x->x_cookedout, 0, 3, at2); for (n = 0, gp = x->x_insig + (ninsig-1), pp = powerout + nfilters * (ninsig-1); n < ninsig; n++, gp--, pp -= nfilters) { t_float *pp2; for (i = 0, ap = at, pp2 = pp; i < nfilters; i++, ap++, pp2++) { ap->a_type = A_FLOAT; ap->a_w.w_float = *pp2; } outlet_list(gp->g_outlet, 0, nfilters, at); } } static void bonk_doit(t_bonk *x) { int i, j, ch, n; t_filterkernel *k; t_hist *h; t_float growth = 0, *fp1, *fp3, *fp4, hithresh, lothresh; int ninsig = x->x_ninsig, nfilters = x->x_nfilters, maskphase = x->x_maskphase, nextphase, oldmaskphase; t_insig *gp; nextphase = maskphase + 1; if (nextphase >= MASKHIST) nextphase = 0; x->x_maskphase = nextphase; oldmaskphase = nextphase - x->x_attackbins; if (oldmaskphase < 0) oldmaskphase += MASKHIST; if (x->x_useloudness) hithresh = qrsqrt(qrsqrt(x->x_hithresh)), lothresh = qrsqrt(qrsqrt(x->x_lothresh)); else hithresh = x->x_hithresh, lothresh = x->x_lothresh; for (ch = 0, gp = x->x_insig; ch < ninsig; ch++, gp++) { for (i = 0, k = x->x_filterbank->b_vec, h = gp->g_hist; i < nfilters; i++, k++, h++) { t_float power = 0, maskpow = h->h_mask[maskphase]; t_float *inbuf= gp->g_inbuf + k->k_skippoints; int countup = h->h_countup; int filterpoints = k->k_filterpoints; /* if the user asked for more filters that fit under the Nyquist frequency, some filters won't actually be filled in so we skip running them. */ if (!filterpoints) { h->h_countup = 0; h->h_mask[nextphase] = 0; h->h_power = 0; continue; } /* run the filter repeatedly, sliding it forward by hoppoints, for nhop times */ for (fp1 = inbuf, n = 0; n < k->k_nhops; fp1 += k->k_hoppoints, n++) { t_float rsum = 0, isum = 0; for (fp3 = fp1, fp4 = k->k_stuff, j = filterpoints; j--;) { t_float g = *fp3++; rsum += g * *fp4++; isum += g * *fp4++; } power += rsum * rsum + isum * isum; } if (!x->x_willattack) h->h_before = maskpow; if (power > h->h_mask[oldmaskphase]) { if (x->x_useloudness) growth += qrsqrt(qrsqrt( power/(h->h_mask[oldmaskphase] + 1.0e-15))) - 1.; else growth += power/(h->h_mask[oldmaskphase] + 1.0e-15) - 1.; } if (!x->x_willattack && countup >= x->x_masktime) maskpow *= x->x_maskdecay; if (power > maskpow) { maskpow = power; countup = 0; } countup++; h->h_countup = countup; h->h_mask[nextphase] = maskpow; h->h_power = power; } } if (x->x_willattack) { if (x->x_willattack > MAXATTACKWAIT || growth < x->x_lothresh) { /* if haven't yet, and if not in spew mode, report a hit */ if (!x->x_spew && !x->x_attacked) { for (ch = 0, gp = x->x_insig; ch < ninsig; ch++, gp++) for (i = nfilters, h = gp->g_hist; i--; h++) h->h_outpower = h->h_mask[nextphase]; x->x_hit = 1; clock_delay(x->x_clock, 0); } } if (growth < x->x_lothresh) x->x_willattack = 0; else x->x_willattack++; } else if (growth > x->x_hithresh) { if (x->x_debug) post("attack: growth = %f", growth); x->x_willattack = 1; x->x_attacked = 0; for (ch = 0, gp = x->x_insig; ch < ninsig; ch++, gp++) for (i = nfilters, h = gp->g_hist; i--; h++) h->h_mask[nextphase] = h->h_power, h->h_countup = 0; } /* if in "spew" mode just always output */ if (x->x_spew) { for (ch = 0, gp = x->x_insig; ch < ninsig; ch++, gp++) for (i = nfilters, h = gp->g_hist; i--; h++) h->h_outpower = h->h_power; x->x_hit = 0; clock_delay(x->x_clock, 0); } x->x_debouncevel *= x->x_debouncedecay; } static t_int *bonk_perform(t_int *w) { t_bonk *x = (t_bonk *)(w[1]); int n = (int)(w[2]); int onset = 0; if (x->x_countdown >= n) x->x_countdown -= n; else { int i, j, ninsig = x->x_ninsig; t_insig *gp; if (x->x_countdown > 0) { n -= x->x_countdown; onset += x->x_countdown; x->x_countdown = 0; } while (n > 0) { int infill = x->x_infill; int m = (n < (x->x_npoints - infill) ? n : (x->x_npoints - infill)); for (i = 0, gp = x->x_insig; i < ninsig; i++, gp++) { t_float *fp = gp->g_inbuf + infill; t_float *in1 = gp->g_invec + onset; for (j = 0; j < m; j++) *fp++ = *in1++; } infill += m; x->x_infill = infill; if (infill == x->x_npoints) { bonk_doit(x); /* shift or clear the input buffer and update counters */ if (x->x_period > x->x_npoints) x->x_countdown = x->x_period - x->x_npoints; else x->x_countdown = 0; if (x->x_period < x->x_npoints) { int overlap = x->x_npoints - x->x_period; t_float *fp1, *fp2; for (n = 0, gp = x->x_insig; n < ninsig; n++, gp++) for (i = overlap, fp1 = gp->g_inbuf, fp2 = fp1 + x->x_period; i--;) *fp1++ = *fp2++; x->x_infill = overlap; } else x->x_infill = 0; } n -= m; onset += m; } } return (w+3); } static void bonk_dsp(t_bonk *x, t_signal **sp) { int i, n = sp[0]->s_n, ninsig = x->x_ninsig; t_insig *gp; x->x_sr = sp[0]->s_sr; for (i = 0, gp = x->x_insig; i < ninsig; i++, gp++) gp->g_invec = (*(sp++))->s_vec; dsp_add(bonk_perform, 2, x, n); } static void bonk_thresh(t_bonk *x, t_floatarg f1, t_floatarg f2) { if (f1 > f2) post("bonk: warning: low threshold greater than hi threshold"); x->x_lothresh = (f1 <= 0 ? 0.0001 : f1); x->x_hithresh = (f2 <= 0 ? 0.0001 : f2); } #ifdef PD static void bonk_mask(t_bonk *x, t_floatarg f1, t_floatarg f2) { int ticks = f1; if (ticks < 0) ticks = 0; if (f2 < 0) f2 = 0; else if (f2 > 1) f2 = 1; x->x_masktime = ticks; x->x_maskdecay = f2; } static void bonk_debounce(t_bonk *x, t_floatarg f1) { if (f1 < 0) f1 = 0; else if (f1 > 1) f1 = 1; x->x_debouncedecay = f1; } static void bonk_minvel(t_bonk *x, t_floatarg f) { if (f < 0) f = 0; x->x_minvel = f; } static void bonk_debug(t_bonk *x, t_floatarg f) { x->x_debug = (f != 0); } static void bonk_spew(t_bonk *x, t_floatarg f) { x->x_spew = (f != 0); } static void bonk_useloudness(t_bonk *x, t_floatarg f) { x->x_useloudness = (f != 0); } static void bonk_attackbins(t_bonk *x, t_floatarg f) { if (f < 1) f = 1; else if (f > MASKHIST) f = MASKHIST; x->x_attackbins = f; } static void bonk_learn(t_bonk *x, t_floatarg f) { int n = f; if (n < 0) n = 0; if (n) { x->x_template = (t_template *)t_resizebytes(x->x_template, x->x_ntemplate * sizeof(x->x_template[0]), 0); x->x_ntemplate = 0; } x->x_learn = n; x->x_learncount = 0; } #endif static void bonk_print(t_bonk *x, t_floatarg f) { int i; post("thresh %f %f", x->x_lothresh, x->x_hithresh); post("mask %d %f", x->x_masktime, x->x_maskdecay); post("attack-frames %d", x->x_attackbins); post("debounce %f", x->x_debouncedecay); post("minvel %f", x->x_minvel); post("spew %d", x->x_spew); post("useloudness %d", x->x_useloudness); #if 0 /* LATER rewrite without hard-coded 11 filters */ if (x->x_ntemplate) { post("templates:"); for (i = 0; i < x->x_ntemplate; i++) post( "%2d %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f %5.2f", i, x->x_template[i].t_amp[0], x->x_template[i].t_amp[1], x->x_template[i].t_amp[2], x->x_template[i].t_amp[3], x->x_template[i].t_amp[4], x->x_template[i].t_amp[5], x->x_template[i].t_amp[6], x->x_template[i].t_amp[7], x->x_template[i].t_amp[8], x->x_template[i].t_amp[9], x->x_template[i].t_amp[10]); } else post("no templates"); #endif post("number of templates %d", x->x_ntemplate); if (x->x_learn) post("learn mode"); if (f != 0) { int j, ninsig = x->x_ninsig; t_insig *gp; for (j = 0, gp = x->x_insig; j < ninsig; j++, gp++) { t_hist *h; if (ninsig > 1) post("input %d:", j+1); for (i = x->x_nfilters, h = gp->g_hist; i--; h++) post("pow %f mask %f before %f count %d", h->h_power, h->h_mask[x->x_maskphase], h->h_before, h->h_countup); } post("filter details (frequencies are in units of %.2f-Hz. bins):", x->x_sr/x->x_npoints); for (j = 0; j < x->x_nfilters; j++) post("%2d cf %.2f bw %.2f nhops %d hop %d skip %d npoints %d", j, x->x_filterbank->b_vec[j].k_centerfreq, x->x_filterbank->b_vec[j].k_bandwidth, x->x_filterbank->b_vec[j].k_nhops, x->x_filterbank->b_vec[j].k_hoppoints, x->x_filterbank->b_vec[j].k_skippoints, x->x_filterbank->b_vec[j].k_filterpoints); } if (x->x_debug) post("debug mode"); } static void bonk_forget(t_bonk *x) { int ntemplate = x->x_ntemplate, newn = ntemplate - x->x_ninsig; if (newn < 0) newn = 0; x->x_template = (t_template *)t_resizebytes(x->x_template, x->x_ntemplate * sizeof(x->x_template[0]), newn * sizeof(x->x_template[0])); x->x_ntemplate = newn; x->x_learncount = 0; } static void bonk_bang(t_bonk *x) { int i, ch; t_insig *gp; x->x_hit = 0; for (ch = 0, gp = x->x_insig; ch < x->x_ninsig; ch++, gp++) { t_hist *h; for (i = 0, h = gp->g_hist; i < x->x_nfilters; i++, h++) h->h_outpower = h->h_power; } bonk_tick(x); } #ifdef PD static void bonk_read(t_bonk *x, t_symbol *s) { t_float vec[MAXNFILTERS]; int i, ntemplate = 0, remaining; t_float *fp, *fp2; /* fbar: canvas_open code taken from g_array.c */ FILE *fd; char buf[MAXPDSTRING], *bufptr; int filedesc; if ((filedesc = canvas_open(x->x_canvas, s->s_name, "", buf, &bufptr, MAXPDSTRING, 0)) < 0 || !(fd = fdopen(filedesc, "r"))) { post("%s: open failed", s->s_name); return; } x->x_template = (t_template *)t_resizebytes(x->x_template, x->x_ntemplate * sizeof(t_template), 0); while (1) { for (i = x->x_nfilters, fp = vec; i--; fp++) if (fscanf(fd, "%f", fp) < 1) goto nomore; x->x_template = (t_template *)t_resizebytes(x->x_template, ntemplate * sizeof(t_template), (ntemplate + 1) * sizeof(t_template)); for (i = x->x_nfilters, fp = vec, fp2 = x->x_template[ntemplate].t_amp; i--;) *fp2++ = *fp++; ntemplate++; } nomore: if (remaining = (ntemplate % x->x_ninsig)) { post("bonk_read: %d templates not a multiple of %d; dropping extras"); x->x_template = (t_template *)t_resizebytes(x->x_template, ntemplate * sizeof(t_template), (ntemplate - remaining) * sizeof(t_template)); ntemplate = ntemplate - remaining; } post("bonk: read %d templates\n", ntemplate); x->x_ntemplate = ntemplate; fclose(fd); } #endif #ifdef MSP static void bonk_read(t_bonk *x, t_symbol *s) { defer(x, (method)bonk_doread, s, 0, NULL); } static void bonk_doread(t_bonk *x, t_symbol *s) { long filetype = 'TEXT', outtype; char filename[512]; short path; if (s == gensym("")) { if (open_dialog(filename, &path, &outtype, &filetype, 1)) return; } else { strcpy(filename, s->s_name); if (locatefile_extended(filename, &path, &outtype, &filetype, 1)) { object_error((t_object *) x, "%s: not found", s->s_name); return; } } // we have a file bonk_openfile(x, filename, path); } static void bonk_openfile(t_bonk *x, char *filename, short path) { t_float vec[MAXNFILTERS]; int i, ntemplate = 0, remaining; t_float *fp, *fp2; t_filehandle fh; char **texthandle; char *tokptr; long size; if (path_opensysfile(filename, path, &fh, READ_PERM)) { object_error((t_object *) x, "error opening %s", filename); return; } sysfile_geteof(fh, &size); texthandle = sysmem_newhandleclear(size + 1); sysfile_readtextfile(fh, texthandle, 0, TEXT_LB_NATIVE); sysfile_close(fh); x->x_template = (t_template *)t_resizebytes(x->x_template, x->x_ntemplate * sizeof(t_template), 0); tokptr = strtok(*texthandle, " \n"); while(tokptr != NULL) { for (i = x->x_nfilters, fp = vec; i--; fp++) { if (sscanf(tokptr, "%f", fp) < 1) goto nomore; tokptr = strtok(NULL, " \n"); } x->x_template = (t_template *)t_resizebytes(x->x_template, ntemplate * sizeof(t_template), (ntemplate + 1) * sizeof(t_template)); for (i = x->x_nfilters, fp = vec, fp2 = x->x_template[ntemplate].t_amp; i--;) *fp2++ = *fp++; ntemplate++; } nomore: if (remaining = (ntemplate % x->x_ninsig)) { post("bonk_read: %d templates not a multiple of %d; dropping extras"); x->x_template = (t_template *)t_resizebytes(x->x_template, ntemplate * sizeof(t_template), (ntemplate - remaining) * sizeof(t_template)); ntemplate = ntemplate - remaining; } sysmem_freehandle(texthandle); post("bonk: read %d templates\n", ntemplate); x->x_ntemplate = ntemplate; } #endif #ifdef PD static void bonk_write(t_bonk *x, t_symbol *s) { FILE *fd; char buf[MAXPDSTRING]; /* fbar */ int i, ntemplate = x->x_ntemplate; t_template *tp = x->x_template; t_float *fp; /* fbar: canvas-code as in g_array.c */ canvas_makefilename(x->x_canvas, s->s_name, buf, MAXPDSTRING); sys_bashfilename(buf, buf); if (!(fd = fopen(buf, "w"))) { post("%s: couldn't create", s->s_name); return; } for (; ntemplate--; tp++) { for (i = x->x_nfilters, fp = tp->t_amp; i--; fp++) fprintf(fd, "%6.2f ", *fp); fprintf(fd, "\n"); } post("bonk: wrote %d templates\n", x->x_ntemplate); fclose(fd); } #endif #ifdef MSP static void bonk_write(t_bonk *x, t_symbol *s) { defer(x, (method)bonk_dowrite, s, 0, NULL); } static void bonk_dowrite(t_bonk *x, t_symbol *s) { long filetype = 'TEXT', outtype; char filename[MAX_FILENAME_CHARS]; short path; if (s == gensym("")) { sprintf(filename, "bonk_template.txt"); saveas_promptset("Save template as..."); if (saveasdialog_extended(filename, &path, &outtype, &filetype, 0)) return; } else { strcpy(filename, s->s_name); path = path_getdefault(); } bonk_writefile(x, filename, path); } void bonk_writefile(t_bonk *x, char *filename, short path) { int i, ntemplate = x->x_ntemplate; t_template *tp = x->x_template; t_float *fp; long err; long buflen; t_filehandle fh; char buf[20]; err = path_createsysfile(filename, path, 'TEXT', &fh); if (err) return; for (; ntemplate--; tp++) { for (i = x->x_nfilters, fp = tp->t_amp; i--; fp++) { snprintf(buf, 20, "%6.2f ", *fp); buflen = strlen(buf); sysfile_write(fh, &buflen, buf); } buflen = 1; sysfile_write(fh, &buflen, "\n"); } sysfile_close(fh); } #endif static void bonk_free(t_bonk *x) { int i, ninsig = x->x_ninsig; t_insig *gp = x->x_insig; #ifdef MSP dsp_free((t_pxobject *)x); #endif for (i = 0, gp = x->x_insig; i < ninsig; i++, gp++) freebytes(gp->g_inbuf, x->x_npoints * sizeof(t_float)); clock_free(x->x_clock); if (!--(x->x_filterbank->b_refcount)) bonk_freefilterbank(x->x_filterbank); } /* -------------------------- Pd glue ------------------------- */ #ifdef PD static void *bonk_new(t_symbol *s, int argc, t_atom *argv) { t_bonk *x = (t_bonk *)pd_new(bonk_class); int nsig = 1, period = DEFPERIOD, npts = DEFNPOINTS, nfilters = DEFNFILTERS, j; t_float halftones = DEFHALFTONES, overlap = DEFOVERLAP, firstbin = DEFFIRSTBIN, minbandwidth = DEFMINBANDWIDTH; t_insig *g; x->x_canvas = canvas_getcurrent(); /* fbar: bind current canvas to x */ if (argc > 0 && argv[0].a_type == A_FLOAT) { /* old style args for compatibility */ period = atom_getfloatarg(0, argc, argv); nsig = atom_getfloatarg(1, argc, argv); } else while (argc > 0) { t_symbol *firstarg = atom_getsymbolarg(0, argc, argv); if (!strcmp(firstarg->s_name, "-npts") && argc > 1) { npts = atom_getfloatarg(1, argc, argv); argc -= 2; argv += 2; } else if (!strcmp(firstarg->s_name, "-hop") && argc > 1) { period = atom_getfloatarg(1, argc, argv); argc -= 2; argv += 2; } else if (!strcmp(firstarg->s_name, "-nsigs") && argc > 1) { nsig = atom_getfloatarg(1, argc, argv); argc -= 2; argv += 2; } else if (!strcmp(firstarg->s_name, "-nfilters") && argc > 1) { nfilters = atom_getfloatarg(1, argc, argv); argc -= 2; argv += 2; } else if (!strcmp(firstarg->s_name, "-halftones") && argc > 1) { halftones = atom_getfloatarg(1, argc, argv); argc -= 2; argv += 2; } else if (!strcmp(firstarg->s_name, "-overlap") && argc > 1) { overlap = atom_getfloatarg(1, argc, argv); argc -= 2; argv += 2; } else if (!strcmp(firstarg->s_name, "-firstbin") && argc > 1) { firstbin = atom_getfloatarg(1, argc, argv); argc -= 2; argv += 2; } else if (!strcmp(firstarg->s_name, "-minbandwidth") && argc > 1) { minbandwidth = atom_getfloatarg(1, argc, argv); argc -= 2; argv += 2; } else if (!strcmp(firstarg->s_name, "-spew") && argc > 1) { x->x_spew = (atom_getfloatarg(1, argc, argv) != 0); argc -= 2; argv += 2; } else { pd_error(x, "usage is: bonk [-npts #] [-hop #] [-nsigs #] [-nfilters #] [-halftones #]"); post( "... [-overlap #] [-firstbin #] [-spew #]"); argc = 0; } } x->x_npoints = (npts >= MINPOINTS ? npts : DEFNPOINTS); x->x_period = (period >= 1 ? period : npts/2); x->x_nfilters = (nfilters >= 1 ? nfilters : DEFNFILTERS); if (halftones < 0.01) halftones = DEFHALFTONES; else if (halftones > 12) halftones = 12; if (nsig < 1) nsig = 1; else if (nsig > MAXCHANNELS) nsig = MAXCHANNELS; if (firstbin < 0.5) firstbin = 0.5; if (overlap < 1) overlap = 1; x->x_clock = clock_new(x, (t_method)bonk_tick); x->x_insig = (t_insig *)getbytes(nsig * sizeof(*x->x_insig)); for (j = 0, g = x->x_insig; j < nsig; j++, g++) { g->g_outlet = outlet_new(&x->x_obj, gensym("list")); if (j) inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); } x->x_cookedout = outlet_new(&x->x_obj, gensym("list")); bonk_donew(x, npts, period, nsig, nfilters, halftones, overlap, firstbin, minbandwidth, sys_getsr()); return (x); } void bonk_tilde_setup(void) { bonk_class = class_new(gensym("bonk~"), (t_newmethod)bonk_new, (t_method)bonk_free, sizeof(t_bonk), 0, A_GIMME, 0); class_addmethod(bonk_class, nullfn, gensym("signal"), 0); class_addmethod(bonk_class, (t_method)bonk_dsp, gensym("dsp"), 0); class_addbang(bonk_class, bonk_bang); class_addmethod(bonk_class, (t_method)bonk_learn, gensym("learn"), A_FLOAT, 0); class_addmethod(bonk_class, (t_method)bonk_forget, gensym("forget"), 0); class_addmethod(bonk_class, (t_method)bonk_thresh, gensym("thresh"), A_FLOAT, A_FLOAT, 0); class_addmethod(bonk_class, (t_method)bonk_mask, gensym("mask"), A_FLOAT, A_FLOAT, 0); class_addmethod(bonk_class, (t_method)bonk_debounce, gensym("debounce"), A_FLOAT, 0); class_addmethod(bonk_class, (t_method)bonk_minvel, gensym("minvel"), A_FLOAT, 0); class_addmethod(bonk_class, (t_method)bonk_print, gensym("print"), A_DEFFLOAT, 0); class_addmethod(bonk_class, (t_method)bonk_debug, gensym("debug"), A_DEFFLOAT, 0); class_addmethod(bonk_class, (t_method)bonk_spew, gensym("spew"), A_DEFFLOAT, 0); class_addmethod(bonk_class, (t_method)bonk_useloudness, gensym("useloudness"), A_DEFFLOAT, 0); class_addmethod(bonk_class, (t_method)bonk_attackbins, gensym("attack-bins"), A_DEFFLOAT, 0); class_addmethod(bonk_class, (t_method)bonk_attackbins, gensym("attack-frames"), A_DEFFLOAT, 0); class_addmethod(bonk_class, (t_method)bonk_read, gensym("read"), A_SYMBOL, 0); class_addmethod(bonk_class, (t_method)bonk_write, gensym("write"), A_SYMBOL, 0); post("bonk version 1.5"); } #endif /* -------------------------- MSP glue ------------------------- */ #ifdef MSP int main() { t_class *c; t_object *attr; long attrflags = 0; t_symbol *sym_long = gensym("long"), *sym_float32 = gensym("float32"); c = class_new("bonk~", (method)bonk_new, (method)bonk_free, sizeof(t_bonk), (method)0L, A_GIMME, 0); class_obexoffset_set(c, calcoffset(t_bonk, obex)); attr = attr_offset_new("npoints", sym_long, attrflags, (method)0L, (method)0L, calcoffset(t_bonk, x_npoints)); class_addattr(c, attr); attr = attr_offset_new("hop", sym_long, attrflags, (method)0L, (method)0L, calcoffset(t_bonk, x_period)); class_addattr(c, attr); attr = attr_offset_new("nfilters", sym_long, attrflags, (method)0L, (method)0L, calcoffset(t_bonk, x_nfilters)); class_addattr(c, attr); attr = attr_offset_new("halftones", sym_float32, attrflags, (method)0L, (method)0L, calcoffset(t_bonk, x_halftones)); class_addattr(c, attr); attr = attr_offset_new("overlap", sym_float32, attrflags, (method)0L, (method)0L, calcoffset(t_bonk, x_overlap)); class_addattr(c, attr); attr = attr_offset_new("firstbin", sym_float32, attrflags, (method)0L, (method)0L, calcoffset(t_bonk, x_firstbin)); class_addattr(c, attr); attr = attr_offset_new("minbandwidth", sym_float32, attrflags, (method)0L, (method)0L, calcoffset(t_bonk, x_minbandwidth)); class_addattr(c, attr); attr = attr_offset_new("minvel", sym_float32, attrflags, (method)0L, (method)bonk_minvel_set, calcoffset(t_bonk, x_minvel)); class_addattr(c, attr); attr = attr_offset_new("lothresh", sym_float32, attrflags, (method)0L, (method)bonk_lothresh_set, calcoffset(t_bonk, x_lothresh)); class_addattr(c, attr); attr = attr_offset_new("hithresh", sym_float32, attrflags, (method)0L, (method)bonk_hithresh_set, calcoffset(t_bonk, x_hithresh)); class_addattr(c, attr); attr = attr_offset_new("masktime", sym_long, attrflags, (method)0L, (method)bonk_masktime_set, calcoffset(t_bonk, x_masktime)); class_addattr(c, attr); attr = attr_offset_new("maskdecay", sym_float32, attrflags, (method)0L, (method)bonk_maskdecay_set, calcoffset(t_bonk, x_maskdecay)); class_addattr(c, attr); attr = attr_offset_new("debouncedecay", sym_float32, attrflags, (method)0L, (method)bonk_debouncedecay_set, calcoffset(t_bonk, x_debouncedecay)); class_addattr(c, attr); attr = attr_offset_new("debug", sym_long, attrflags, (method)0L, (method)bonk_debug_set, calcoffset(t_bonk, x_debug)); class_addattr(c, attr); attr = attr_offset_new("spew", sym_long, attrflags, (method)0L, (method)bonk_spew_set, calcoffset(t_bonk, x_spew)); class_addattr(c, attr); attr = attr_offset_new("useloudness", sym_long, attrflags, (method)0L, (method)bonk_useloudness_set, calcoffset(t_bonk, x_useloudness)); class_addattr(c, attr); attr = attr_offset_new("attackframes", sym_long, attrflags, (method)0L, (method)bonk_attackbins_set, calcoffset(t_bonk, x_attackbins)); class_addattr(c, attr); attr = attr_offset_new("learn", sym_long, attrflags, (method)0L, (method)bonk_learn_set, calcoffset(t_bonk, x_learn)); class_addattr(c, attr); class_addmethod(c, (method)bonk_dsp, "dsp", A_CANT, 0); class_addmethod(c, (method)bonk_bang, "bang", A_CANT, 0); class_addmethod(c, (method)bonk_forget, "forget", 0); class_addmethod(c, (method)bonk_thresh, "thresh", A_FLOAT, A_FLOAT, 0); class_addmethod(c, (method)bonk_print, "print", A_DEFFLOAT, 0); class_addmethod(c, (method)bonk_read, "read", A_DEFSYM, 0); class_addmethod(c, (method)bonk_write, "write", A_DEFSYM, 0); class_addmethod(c, (method)bonk_assist, "assist", A_CANT, 0); class_addmethod(c, (method)object_obex_dumpout, "dumpout", A_CANT, 0); class_addmethod(c, (method)object_obex_quickref, "quickref", A_CANT, 0); class_dspinit(c); class_register(CLASS_BOX, c); bonk_class = c; post("bonk~ v1.5"); return (0); } static void *bonk_new(t_symbol *s, long ac, t_atom *av) { short j; t_bonk *x; if (x = (t_bonk *)object_alloc(bonk_class)) { t_insig *g; x->x_npoints = DEFNPOINTS; x->x_period = DEFPERIOD; x->x_nfilters = DEFNFILTERS; x->x_halftones = DEFHALFTONES; x->x_firstbin = DEFFIRSTBIN; x->x_minbandwidth = DEFMINBANDWIDTH; x->x_overlap = DEFOVERLAP; x->x_ninsig = 1; x->x_hithresh = DEFHITHRESH; x->x_lothresh = DEFLOTHRESH; x->x_masktime = DEFMASKTIME; x->x_maskdecay = DEFMASKDECAY; x->x_debouncedecay = DEFDEBOUNCEDECAY; x->x_minvel = DEFMINVEL; x->x_attackbins = DEFATTACKBINS; if (!x->x_period) x->x_period = x->x_npoints/2; x->x_template = (t_template *)getbytes(0); x->x_ntemplate = 0; x->x_infill = 0; x->x_countdown = 0; x->x_willattack = 0; x->x_attacked = 0; x->x_maskphase = 0; x->x_debug = 0; x->x_learn = 0; x->x_learndebounce = clock_getsystime(); x->x_learncount = 0; x->x_useloudness = 0; x->x_debouncevel = 0; x->x_sr = sys_getsr(); if (ac) { switch (av[0].a_type) { case A_LONG: x->x_ninsig = av[0].a_w.w_long; break; } } if (x->x_ninsig < 1) x->x_ninsig = 1; if (x->x_ninsig > MAXCHANNELS) x->x_ninsig = MAXCHANNELS; attr_args_process(x, ac, av); x->x_insig = (t_insig *)getbytes(x->x_ninsig * sizeof(*x->x_insig)); dsp_setup((t_pxobject *)x, x->x_ninsig); object_obex_store(x, gensym("dumpout"), outlet_new(x, NULL)); x->x_cookedout = listout((t_object *)x); for (j = 0, g = x->x_insig + x->x_ninsig-1; j < x->x_ninsig; j++, g--) { g->g_outlet = listout((t_object *)x); } x->x_clock = clock_new(x, (method)bonk_tick); bonk_donew(x, x->x_npoints, x->x_period, x->x_ninsig, x->x_nfilters, x->x_halftones, x->x_overlap, x->x_firstbin, x->x_minbandwidth, sys_getsr()); } return (x); } /* Attribute setters. */ void bonk_minvel_set(t_bonk *x, void *attr, long ac, t_atom *av) { if (ac && av) { t_float f = atom_getfloat(av); if (f < 0) f = 0; x->x_minvel = f; } } void bonk_lothresh_set(t_bonk *x, void *attr, long ac, t_atom *av) { if (ac && av) { t_float f = atom_getfloat(av); if (f > x->x_hithresh) post("bonk: warning: low threshold greater than hi threshold"); x->x_lothresh = (f <= 0 ? 0.0001 : f); } } void bonk_hithresh_set(t_bonk *x, void *attr, long ac, t_atom *av) { if (ac && av) { t_float f = atom_getfloat(av); if (f < x->x_lothresh) post("bonk: warning: low threshold greater than hi threshold"); x->x_hithresh = (f <= 0 ? 0.0001 : f); } } void bonk_masktime_set(t_bonk *x, void *attr, long ac, t_atom *av) { if (ac && av) { int n = atom_getlong(av); x->x_masktime = (n < 0) ? 0 : n; } } void bonk_maskdecay_set(t_bonk *x, void *attr, long ac, t_atom *av) { if (ac && av) { t_float f = atom_getfloat(av); f = (f < 0) ? 0 : f; f = (f > 1) ? 1 : f; x->x_maskdecay = f; } } void bonk_debouncedecay_set(t_bonk *x, void *attr, long ac, t_atom *av) { if (ac && av) { t_float f = atom_getfloat(av); f = (f < 0) ? 0 : f; f = (f > 1) ? 1 : f; x->x_debouncedecay = f; } } void bonk_debug_set(t_bonk *x, void *attr, long ac, t_atom *av) { if (ac && av) { int n = atom_getlong(av); x->x_debug = (n != 0); } } void bonk_spew_set(t_bonk *x, void *attr, long ac, t_atom *av) { if (ac && av) { int n = atom_getlong(av); x->x_spew = (n != 0); } } void bonk_useloudness_set(t_bonk *x, void *attr, long ac, t_atom *av) { if (ac && av) { int n = atom_getlong(av); x->x_useloudness = (n != 0); } } void bonk_attackbins_set(t_bonk *x, void *attr, long ac, t_atom *av) { if (ac && av) { int n = atom_getlong(av); n = (n < 1) ? 1 : n; n = (n > MASKHIST) ? MASKHIST : n; x->x_attackbins = n; } } void bonk_learn_set(t_bonk *x, void *attr, long ac, t_atom *av) { if (ac && av) { int n = atom_getlong(av); if (n != 0) { x->x_template = (t_template *)t_resizebytes(x->x_template, x->x_ntemplate * sizeof(x->x_template[0]), 0); x->x_ntemplate = 0; } x->x_learn = n; x->x_learncount = 0; } } /* end attr setters */ void bonk_assist(t_bonk *x, void *b, long m, long a, char *s) { } /* get current system time */ double clock_getsystime() { return gettime(); } /* elapsed time in milliseconds since the given system time */ double clock_gettimesince(double prevsystime) { return ((gettime() - prevsystime)); } t_float qrsqrt(t_float f) { return 1/sqrt(f); } #endif /* MSP */ pd-0.46-7/extra/bonk~/templates.txt0000664000175000017500000000047012160204055015401 0ustar mspmsp 10.47 9.65 14.95 23.77 28.32 38.84 53.21 41.20 31.25 21.70 16.48 6.52 13.93 27.82 58.05 24.11 35.26 35.98 37.78 22.54 13.56 10.75 30.45 28.86 29.42 21.94 29.92 35.70 38.49 32.01 28.19 27.38 22.10 66.77 46.27 28.82 25.95 22.84 20.61 20.33 14.18 6.86 8.92 7.37 pd-0.46-7/extra/bonk~/GNUmakefile.am0000664000175000017500000000126712374250720015324 0ustar mspmsp## Makefile.am -- Process this file with automake to produce Makefile.in NAME=bonk~ external_LTLIBRARIES = bonk~.la SOURCES = bonk~.c PATCHES = bonk~-help.pd OTHERDATA = templates.txt EXTRA_DIST = makefile ############################### # you shouldn't need to add anything below here dist_external_DATA = $(PATCHES) $(OTHERDATA) AUTOMAKE_OPTIONS = foreign AM_CPPFLAGS = -I$(top_srcdir)/src -DPD AM_CFLAGS = @ARCH_CFLAGS@ AM_LIBS = $(LIBM) AM_LDFLAGS = -module -avoid-version -shared @ARCH_LDFLAGS@ -shrext .@EXTERNAL_EXTENSION@ -L$(top_srcdir)/src externaldir = $(pkglibdir)/extra/$(NAME) if MINGW AM_LIBS += -lpd endif libtool: $(LIBTOOL_DEPS) $(SHELL) ./config.status --recheck pd-0.46-7/extra/bonk~/makefile0000664000175000017500000000006712160204055014344 0ustar mspmspNAME=bonk~ CSYM=bonk_tilde include ../makefile.subdir pd-0.46-7/extra/complex-mod~.pd0000664000175000017500000000121212160204055014455 0ustar mspmsp#N canvas 206 108 428 341 12; #X obj 142 87 inlet~; #X obj 315 166 cos~; #X obj 351 144 +~ -0.25; #X obj 351 166 cos~; #X obj 225 87 inlet~; #X obj 142 215 *~; #X obj 225 216 *~; #X obj 142 251 -~; #X obj 142 284 outlet~; #X obj 212 285 outlet~; #X obj 212 252 +~; #X text 140 310 positive; #X text 213 311 negative; #X obj 315 114 phasor~; #X obj 315 88 inlet~; #X connect 0 0 5 0; #X connect 1 0 5 1; #X connect 2 0 3 0; #X connect 3 0 6 1; #X connect 4 0 6 0; #X connect 5 0 7 0; #X connect 5 0 10 0; #X connect 6 0 7 1; #X connect 6 0 10 1; #X connect 7 0 8 0; #X connect 10 0 9 0; #X connect 13 0 2 0; #X connect 13 0 1 0; #X connect 14 0 13 0; pd-0.46-7/extra/README.txt0000664000175000017500000000214412160204055013211 0ustar mspmspThis is the README file for the "extras" library, consisting of Pd objects which are too specialized or otherwise non-canonical for inclusion into Pd proper. These files are open source; see LICENSE.txt in this distribution for details. Note however that "expr" is GPL (the rest is all BSD). This package should run in Pd under linux, MSW, or Mac OSX. You can additionally compile fiddle~. bonk~, and paf~ for Max/MSP. contents: externs: fiddle~ -- pitch tracker bonk~ - percussion detector choose - find the "best fit" of incoming vector with stored profiles paf~ -- phase aligned formant generator loop~ -- sample looper expr -- arithmetic expression evaluation (Shahrokh Yadegari) pique - fft-based peak finder lrshift~ - left or right shift an audio vector abstractions: hilbert~ - Hilbert transform for SSB modulation complex-mod~ - ring modulation for complex (real+imaginary) audio signals rev1~, etc. - reverberators These objects are part of the regular Pd distribution as of Pd version 0.30. Macintosh versions of fiddle~, bonk~, and paf~ are available from http://www.crca.ucsd.edu/~tapel - msp@ucsd.edu pd-0.46-7/extra/bob~/0000755000175000017500000000000012574202336012461 5ustar mspmsppd-0.46-7/extra/bob~/output~.pd0000664000175000017500000000332212503363527014550 0ustar mspmsp#N canvas -1 -1 615 578 12; #X obj 353 490 t b; #X obj 353 437 f; #X obj 353 515 f; #X msg 467 514 0; #X obj 353 467 moses 1; #X obj 467 486 t b f; #X obj 433 447 moses 1; #X obj 29 97 dbtorms; #X obj 85 170 inlet~; #X msg 299 310 \; pd dsp 1; #X obj 29 170 line~; #X obj 64 242 *~; #X obj 64 272 dac~; #X obj 29 127 pack 0 50; #X text 121 146 audio in; #X text 138 464 test if less than 1 -->; #X text 104 491 if true convert to bang -->; #X text 100 96 <-- convert from dB to linear units; #X floatatom 323 219 3 0 100 0 dB - -; #X obj 350 240 bng 15 250 50 0 empty empty mute -38 7 0 12 -262144 -1 -1; #X text 118 126 <-- make a ramp to avoid clicks or zipper noise; #X obj 147 170 inlet~; #X obj 154 241 *~; #X text 373 378 MUTE logic:; #X obj 323 174 r \$0-master-lvl; #X obj 353 541 s \$0-master-lvl; #X obj 323 279 s \$0-master-out; #X obj 29 71 r \$0-master-out; #X obj 433 418 r \$0-master-out; #X text 60 10 Level control abstraction \, used in many of the Pd example patches. The "level" and "mute" controls show up on the parent \, calling patch.; #X text 66 517 previous nonzero master-lvl -->; #X text 138 421 recall previous; #X text 138 439 value of master-lvl -->; #X text 39 319 automatically start DSP -->; #X connect 0 0 2 0; #X connect 1 0 4 0; #X connect 2 0 25 0; #X connect 3 0 25 0; #X connect 4 0 0 0; #X connect 4 1 5 0; #X connect 5 0 3 0; #X connect 6 1 2 1; #X connect 7 0 13 0; #X connect 8 0 11 1; #X connect 10 0 22 0; #X connect 10 0 11 0; #X connect 11 0 12 0; #X connect 13 0 10 0; #X connect 18 0 9 0; #X connect 18 0 26 0; #X connect 19 0 1 0; #X connect 21 0 22 1; #X connect 22 0 12 1; #X connect 24 0 18 0; #X connect 27 0 7 0; #X connect 28 0 1 1; #X connect 28 0 6 0; #X coords 0 0 1 1 65 55 1 300 200; pd-0.46-7/extra/bob~/GNUmakefile.am0000664000175000017500000000126012503557716015137 0ustar mspmsp## Makefile.am -- Process this file with automake to produce Makefile.in NAME=bob~ external_LTLIBRARIES = bob~.la SOURCES = bob~.c PATCHES = bob~-help.pd output~.pd OTHERDATA = EXTRA_DIST = makefile ############################### # you shouldn't need to add anything below here dist_external_DATA = $(PATCHES) $(OTHERDATA) AUTOMAKE_OPTIONS = foreign AM_CPPFLAGS = -I$(top_srcdir)/src -DPD AM_CFLAGS = @ARCH_CFLAGS@ AM_LIBS = $(LIBM) AM_LDFLAGS = -module -avoid-version -shared @ARCH_LDFLAGS@ -shrext .@EXTERNAL_EXTENSION@ -L$(top_srcdir)/src externaldir = $(pkglibdir)/extra/$(NAME) if MINGW AM_LIBS += -lpd endif libtool: $(LIBTOOL_DEPS) $(SHELL) ./config.status --recheck pd-0.46-7/extra/bob~/README.txt0000664000175000017500000000210612455546336014171 0ustar mspmspThe bob~ object. BSD licensed; Copyright notice is in bob~ source code. Imitates a Moog resonant filter by Runge-Kutte numerical integration of a differential equation approximately describing the dynamics of the circuit. Useful references: Tim Stilson Analyzing the Moog VCF with Considerations for Digital Implementation https://ccrma.stanford.edu/~stilti/papers/moogvcf.ps.gz (sections 1 and 2 are a reasonably good introduction but the model they use is highly idealized.) Timothy E. Stinchcombe Analysis of the Moog Transistor Ladder and Derivative Filters (long, but a very thorough description of how the filter works including its nonlinearities) Antti Huovilainen Non-linear digital implementation of the moog ladder filter (comes close to giving a differential equation for a reasonably realistic model of the filter). Th differential equations are: y1' = k * (S(x - r * y4) - S(y1)) y2' = k * (S(y1) - S(y2)) y3' = k * (S(y2) - S(y3)) y4' = k * (S(y3) - S(y4)) where k controls the cutoff frequency, r is feedback (<= 4 for stability), and S(x) is a saturation function. pd-0.46-7/extra/bob~/bob~.c0000644000175000017500000001742112467456101013574 0ustar mspmsp/* bob~ - use a differential equation solver to imitate an analogue circuit */ /* copyright 2015 Miller Puckette - BSD license */ #include "m_pd.h" #include #define DIM 4 #define FLOAT double /* if CALCERROR is defined we compute an error estaimate to verify the filter, outputting it from a second outlet on demand. This doubles the computation time, so it's only compiled in for testing. */ /* #define CALCERROR */ typedef struct _params { FLOAT p_input; FLOAT p_cutoff; FLOAT p_resonance; FLOAT p_saturation; FLOAT p_derivativeswere[DIM]; } t_params; /* imitate the (tanh) clipping function of a transistor pair. We hope/assume the C compiler is smart enough to inline this so use a function instead of a #define. */ #if 0 static FLOAT clip(FLOAT value, FLOAT saturation, FLOAT saturationinverse) { return (saturation * tanh(value * saturationinverse)); } #else /* cheaper way - to 4th order, tanh is x - x*x*x/3; this cubic's plateaus are at +/- 1 so clip to 1 and evaluate the cubic. This is pretty coarse - for instance if you clip a sinusoid this way you can sometimes hear the discontinuity in 4th derivative at the clip point */ static FLOAT clip(FLOAT value, FLOAT saturation, FLOAT saturationinverse) { float v2 = (value*saturationinverse > 1 ? 1 : (value*saturationinverse < -1 ? -1: value*saturationinverse)); return (saturation * (v2 - (1./3.) * v2 * v2 * v2)); } #endif static void calc_derivatives(FLOAT *dstate, FLOAT *state, t_params *params) { FLOAT k = ((float)(2*3.14159)) * params->p_cutoff; FLOAT sat = params->p_saturation, satinv = 1./sat; FLOAT satstate0 = clip(state[0], sat, satinv); FLOAT satstate1 = clip(state[1], sat, satinv); FLOAT satstate2 = clip(state[2], sat, satinv); dstate[0] = k * (clip(params->p_input - params->p_resonance * state[3], sat, satinv) - satstate0); dstate[1] = k * (satstate0 - satstate1); dstate[2] = k * (satstate1 - satstate2); dstate[3] = k * (satstate2 - clip(state[3], sat, satinv)); } static void solver_euler(FLOAT *state, FLOAT *errorestimate, FLOAT stepsize, t_params *params) { FLOAT cumerror = 0; int i; FLOAT derivatives[DIM]; calc_derivatives(derivatives, state, params); *errorestimate = 0; for (i = 0; i < DIM; i++) { state[i] += stepsize * derivatives[i]; *errorestimate += (derivatives[i] > params->p_derivativeswere[i] ? derivatives[i] - params->p_derivativeswere[i] : params->p_derivativeswere[i] - derivatives[i]); } for (i = 0; i < DIM; i++) params->p_derivativeswere[i] = derivatives[i]; } static void solver_rungekutte(FLOAT *state, FLOAT *errorestimate, FLOAT stepsize, t_params *params) { FLOAT cumerror = 0; int i; FLOAT deriv1[DIM], deriv2[DIM], deriv3[DIM], deriv4[DIM], tempstate[DIM]; FLOAT oldstate[DIM], backstate[DIM]; #if CALCERROR for (i = 0; i < DIM; i++) oldstate[i] = state[i]; #endif *errorestimate = 0; calc_derivatives(deriv1, state, params); for (i = 0; i < DIM; i++) tempstate[i] = state[i] + 0.5 * stepsize * deriv1[i]; calc_derivatives(deriv2, tempstate, params); for (i = 0; i < DIM; i++) tempstate[i] = state[i] + 0.5 * stepsize * deriv2[i]; calc_derivatives(deriv3, tempstate, params); for (i = 0; i < DIM; i++) tempstate[i] = state[i] + stepsize * deriv3[i]; calc_derivatives(deriv4, tempstate, params); for (i = 0; i < DIM; i++) state[i] += (1./6.) * stepsize * (deriv1[i] + 2 * deriv2[i] + 2 * deriv3[i] + deriv4[i]); #if CALCERROR calc_derivatives(deriv1, state, params); for (i = 0; i < DIM; i++) tempstate[i] = state[i] - 0.5 * stepsize * deriv1[i]; calc_derivatives(deriv2, tempstate, params); for (i = 0; i < DIM; i++) tempstate[i] = state[i] - 0.5 * stepsize * deriv2[i]; calc_derivatives(deriv3, tempstate, params); for (i = 0; i < DIM; i++) tempstate[i] = state[i] - stepsize * deriv3[i]; calc_derivatives(deriv4, tempstate, params); for (i = 0; i < DIM; i++) { backstate[i] = state[i ]- (1./6.) * stepsize * (deriv1[i] + 2 * deriv2[i] + 2 * deriv3[i] + deriv4[i]); *errorestimate += (backstate[i] > oldstate[i] ? backstate[i] - oldstate[i] : oldstate[i] - backstate[i]); } #endif } typedef struct _bob { t_object x_obj; t_float x_f; t_outlet *x_out1; /* signal output */ #ifdef CALCERROR t_outlet *x_out2; /* error estimate */ FLOAT x_cumerror; #endif t_params x_params; FLOAT x_state[DIM]; FLOAT x_sr; int x_oversample; int x_errorcount; } t_bob; static t_class *bob_class; static void bob_saturation(t_bob *x, t_float saturation) { if (saturation <= 1e-3) saturation = 1e-3; x->x_params.p_saturation = saturation; } static void bob_oversample(t_bob *x, t_float oversample) { if (oversample <= 1) oversample = 1; x->x_oversample = oversample; } static void bob_clear(t_bob *x) { int i; for (i = 0; i < DIM; i++) x->x_state[i] = x->x_params.p_derivativeswere[i] = 0; } static void bob_error(t_bob *x) { #ifdef CALCERROR outlet_float(x->x_out2, (x->x_errorcount ? x->x_cumerror/x->x_errorcount : 0)); x->x_cumerror = 0; x->x_errorcount = 0; #else post("error estimate unavailable (not compiled in)"); #endif } static void bob_print(t_bob *x) { int i; for (i = 0; i < DIM; i++) post("state %d: %f", i, x->x_state[i]); post("saturation %f", x->x_params.p_saturation); post("oversample %d", x->x_oversample); } static void *bob_new( void) { t_bob *x = (t_bob *)pd_new(bob_class); x->x_out1 = outlet_new(&x->x_obj, gensym("signal")); inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); x->x_f = 0; bob_clear(x); bob_saturation(x, 3); bob_oversample(x, 2); #ifdef CALCERROR x->x_cumerror = 0; x->x_errorcount = 0; x->x_out2 = outlet_new(&x->x_obj, gensym("float")); #endif return (x); } static t_int *bob_perform(t_int *w) { t_bob *x = (t_bob *)(w[1]); t_float *in1 = (t_float *)(w[2]); t_float *cutoffin = (t_float *)(w[3]); t_float *resonancein = (t_float *)(w[4]); t_float *out = (t_float *)(w[5]); int n = (int)(w[6]), i, j; FLOAT stepsize = 1./(x->x_oversample * x->x_sr); FLOAT errorestimate; for (i = 0; i < n; i++) { x->x_params.p_input = *in1++; x->x_params.p_cutoff = *cutoffin++; if ((x->x_params.p_resonance = *resonancein++) < 0) x->x_params.p_resonance = 0; for (j = 0; j < x->x_oversample; j++) solver_rungekutte(x->x_state, &errorestimate, stepsize, &x->x_params); *out++ = x->x_state[0]; #if CALCERROR x->x_cumerror += errorestimate; x->x_errorcount++; #endif } return (w+7); } static void bob_dsp(t_bob *x, t_signal **sp) { x->x_sr = sp[0]->s_sr; dsp_add(bob_perform, 6, x, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec, sp[0]->s_n); } void bob_tilde_setup(void) { int i; bob_class = class_new(gensym("bob~"), (t_newmethod)bob_new, 0, sizeof(t_bob), 0, 0); class_addmethod(bob_class, (t_method)bob_saturation, gensym("saturation"), A_FLOAT, 0); class_addmethod(bob_class, (t_method)bob_oversample, gensym("oversample"), A_FLOAT, 0); class_addmethod(bob_class, (t_method)bob_clear, gensym("clear"), 0); class_addmethod(bob_class, (t_method)bob_print, gensym("print"), 0); class_addmethod(bob_class, (t_method)bob_error, gensym("error"), 0); class_addmethod(bob_class, (t_method)bob_dsp, gensym("dsp"), A_CANT, 0); CLASS_MAINSIGNALIN(bob_class, t_bob, x_f); } pd-0.46-7/extra/bob~/bob~-help.pd0000644000175000017500000001141612467460560014705 0ustar mspmsp#N canvas 27 58 1062 722 12; #X obj 231 347 env~ 8192, f 4; #X floatatom 230 387 5 0 0 0 - - -, f 5; #X floatatom 408 193 5 0 200 0 - - -, f 5; #X obj 39 260 env~ 8192, f 5; #X floatatom 39 300 5 0 0 0 - - -, f 5; #X obj 279 317 bob~; #X obj 408 215 / 25; #X msg 950 229 print; #X obj 87 259 output~; #X floatatom 291 179 5 0 150 0 - - -, f 5; #X obj 291 201 mtof; #X obj 292 246 pack 0 50; #X obj 292 271 line~; #X msg 886 227 clear; #X obj 280 349 output~; #X floatatom 291 224 7 0 0 0 - - -, f 7; #X floatatom 611 177 5 0 999 0 - - -, f 5; #X msg 611 223 saturation \$1; #X obj 611 127 loadbang; #X obj 611 199 / 100; #X text 885 183 clear or print; #X text 889 202 filter state; #X floatatom 748 197 5 1 10 0 - - -, f 5; #X text 744 122 oversampling; #X msg 748 224 oversample \$1; #X text 419 88 "resonance"; #X text 418 105 (>4 to oscillate); #X obj 748 145 loadbang; #X msg 748 170 2; #X text 456 211 scaled to 0-8; #X text 455 193 0-200 control; #X text 263 86 resonant or cutoff frequency, f 16; #X text 300 60 ----- filter parameters ----; #X text 609 59 ------ optimizations / setup params -------; #X text 899 161 debugging:; #X text 603 88 saturation point; #X text 600 105 of "transistors"; #X msg 611 152 300; #X obj 408 142 loadbang; #X msg 408 167 10; #X text 521 625 "Clear" momentarily shorts out the capacitors in case the filter has gone unstable and stopped working.; #X text 523 410 By default bob~ does one step of 4th-order Runge-Kutte integration per audio sample. This works OK for resonant/cutoff frequencies up to about 1/2 Nyquist. To improve accuracy and/or to extend the range of the filter to higher cutoff frequencies you can oversample by any factor - but note that computation time rises accordingly. At high cutoff frequencies/resonance values the RK approximation can go unstable. You can combat this by raising the oversampling factor.; #X obj 407 243 line~; #N canvas 743 303 450 300 test 0; #X obj 102 122 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 313 127 min~; #X obj 357 103 -~ 1; #X obj 357 128 *~ -50; #X floatatom 102 102 5 0 128 0 - - -, f 5; #X obj 235 72 mtof; #X obj 102 141 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1 1; #X text 196 32 test signal; #X text 147 102 pitch; #X text 119 140 sawtooth; #X obj 312 70 phasor~ 220; #X obj 233 107 osc~ 220; #X obj 102 160 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X text 121 120 sine; #X text 120 159 noise; #X floatatom 103 181 3 0 100 0 - - -, f 3; #X obj 62 24 loadbang; #X msg 62 49 57; #X msg 48 163 80; #X text 133 180 dB out; #X msg 60 111 1; #X obj 362 189 noise~; #X obj 204 207 *~ 0; #X obj 316 184 *~ 0; #X obj 315 217 *~ 0; #X obj 208 238 +~; #X obj 208 263 outlet~; #X connect 0 0 22 1; #X connect 1 0 23 0; #X connect 2 0 3 0; #X connect 3 0 1 1; #X connect 4 0 5 0; #X connect 5 0 10 0; #X connect 5 0 11 0; #X connect 6 0 23 1; #X connect 10 0 1 0; #X connect 10 0 2 0; #X connect 11 0 22 0; #X connect 12 0 24 1; #X connect 16 0 17 0; #X connect 16 0 18 0; #X connect 16 0 20 0; #X connect 17 0 4 0; #X connect 18 0 15 0; #X connect 20 0 6 0; #X connect 21 0 24 0; #X connect 22 0 25 0; #X connect 23 0 25 1; #X connect 24 0 25 1; #X connect 25 0 26 0; #X coords 0 -1 1 1 95 100 2 100 100; #X restore 101 96 pd test; #X text 228 410 output monitor; #X text 35 321 input monitor; #X obj 291 130 loadbang; #X msg 291 155 69; #X text 47 65 ----- test input ----; #X text 356 366 <--- adjust output "dB" to hear filter output.; #X text 21 558 The design is based on papers by Tim Stilson \, Timothy E. Stinchcombe \, and Antti Huovilainen. See README.txt for pointers. ; #X text 23 459 The three audio inputs are the signal to filter \, the cutoff/resonant frequency in cycles per second \, and "resonance" (the sharpness of the filter). Nominally \, a resonance of 4 should be the limit of stability -- above that \, the filter oscillates.; #X text 24 10 bob~ - Runge-Kutte numerical simulation of the Moog analog resonant filter, f 79; #X text 876 676 updated for Pd 0.47; #X text 522 565 The saturation parameter determines at what signal level the "transistors" in the model saturate. The maximum output amplitude is about 2/3 of that value.; #X connect 0 0 1 0; #X connect 2 0 6 0; #X connect 3 0 4 0; #X connect 5 0 0 0; #X connect 5 0 14 0; #X connect 5 0 14 1; #X connect 6 0 42 0; #X connect 7 0 5 0; #X connect 9 0 10 0; #X connect 10 0 15 0; #X connect 11 0 12 0; #X connect 12 0 5 1; #X connect 13 0 5 0; #X connect 15 0 11 0; #X connect 16 0 19 0; #X connect 17 0 5 0; #X connect 18 0 37 0; #X connect 19 0 17 0; #X connect 22 0 24 0; #X connect 24 0 5 0; #X connect 27 0 28 0; #X connect 28 0 22 0; #X connect 37 0 16 0; #X connect 38 0 39 0; #X connect 39 0 2 0; #X connect 42 0 5 2; #X connect 43 0 8 0; #X connect 43 0 8 1; #X connect 43 0 3 0; #X connect 43 0 5 0; #X connect 46 0 47 0; #X connect 47 0 9 0; pd-0.46-7/extra/bob~/makefile0000664000175000017500000000006512503557716014173 0ustar mspmspNAME=bob~ CSYM=bob_tilde include ../makefile.subdir pd-0.46-7/extra/complex-mod~-help.pd0000664000175000017500000000157012160204055015412 0ustar mspmsp#N canvas 136 85 600 480 12; #X graph graph1 0 -1 882 1 279 209 579 39; #X array mod-output 882 float; #X pop; #X msg 84 256 bang \; pd dsp 1; #X floatatom 67 56; #X obj 67 186 complex-mod~; #X obj 67 84 phasor~ 440; #X obj 67 115 cos~; #X obj 106 138 cos~; #X obj 106 114 -~ 0.25; #X floatatom 145 152; #X text 93 351 The complex modulator takes two signals in which it considers to be the real and imaginary part of a complex-valued signal. It then does a complex multiplication by a sinusoud to shift all frequencies up or down by any frequency shift in Hz. See also hilbert~.; #X obj 69 298 tabwrite~ mod-output; #X text 149 204 right outlet; #X text 151 220 gives the other; #X text 149 236 sideband; #X connect 1 0 10 0; #X connect 2 0 4 0; #X connect 3 0 10 0; #X connect 4 0 5 0; #X connect 4 0 7 0; #X connect 5 0 3 0; #X connect 6 0 3 1; #X connect 7 0 6 0; #X connect 8 0 3 2; pd-0.46-7/extra/Makefile.am0000664000175000017500000000071512503557716013571 0ustar mspmspSUBDIRS=bob~ bonk~ choice expr~ fiddle~ loop~ lrshift~ pd~ pique sigmund~ stdout DIST_SUBDIRS=$(SUBDIRS) PATCHES =complex-mod~.pd hilbert~.pd rev1-final.pd rev1~.pd rev1-stage.pd rev2~.pd rev3~.pd HELPPATCHES=complex-mod~-help.pd hilbert~-help.pd rev1~-help.pd rev2~-help.pd rev3~-help.pd EXTRA_DIST = makefile.subdir README.txt libpdextradir = $(pkglibdir)/extra dist_libpdextra_DATA = $(PATCHES) $(HELPPATCHES) pd-0.46-7/extra/rev1-final.pd0000664000175000017500000000460312160204055014006 0ustar mspmsp#N canvas 133 53 729 468 10; #X obj 72 240 inlet~; #X obj 347 28 loadbang; #X obj 90 376 +~; #X obj 52 408 +~; #X obj 52 437 outlet~; #X obj 409 96 pow; #X obj 372 118 *; #X floatatom 372 159; #X obj 82 264 *~ 0; #X obj 177 175 pow; #X text 386 140 delay \, msec; #X floatatom 201 237; #X obj 190 150 * 0.001; #X text 206 220 gain for this stage; #X obj 103 327 *~ 0; #X obj 201 202 *; #X text 25 13 Allpass filter for mono reverberator. Arg 1 = delay name \, arg2 = stage number \, arg 3 = delay time; #X obj 373 76 8; #X obj 409 75 1.79; #X obj 114 175 0.7; #X obj 363 50 t b b b b; #X obj 177 108 0; #X obj 372 207 abs; #X obj 372 229 moses 0.01; #X obj 443 229 print wrong-delay-time; #X obj 233 391 inlet~; #X obj 219 419 +~; #X obj 219 443 outlet~; #X text 74 83 decay after; #X text 85 98 1 second; #X obj 83 119 r \$1-decay; #X obj 327 262 r \$1-clear; #X obj 240 298 0; #X obj 327 281 t b; #X obj 327 344 delay; #X obj 327 322 + 5; #X obj 158 279 delread~ \$2 \$4; #X obj 90 397 delwrite~ \$2 \$4; #X obj 327 302 f \$4; #X obj 371 184 - \$4; #X obj 446 75 float \$3; #X obj 241 318 1; #X obj 158 300 *~ 1; #X obj 52 298 *~ 0; #X obj 10 209 t b f f; #X obj 28 233 *; #X obj 10 256 -; #X obj 41 258 * -1; #X obj 11 297 *~ 0; #X obj 214 181 sqrt; #X connect 0 0 8 0; #X connect 1 0 20 0; #X connect 2 0 37 0; #X connect 3 0 4 0; #X connect 3 0 26 0; #X connect 5 0 6 1; #X connect 6 0 7 0; #X connect 6 0 12 0; #X connect 7 0 39 0; #X connect 8 0 43 0; #X connect 8 0 48 0; #X connect 9 0 15 0; #X connect 9 0 14 1; #X connect 12 0 9 1; #X connect 14 0 2 1; #X connect 14 0 3 1; #X connect 15 0 11 0; #X connect 15 0 8 1; #X connect 17 0 6 0; #X connect 18 0 5 0; #X connect 18 0 49 0; #X connect 19 0 44 0; #X connect 19 0 47 0; #X connect 20 0 21 0; #X connect 20 0 19 0; #X connect 20 1 17 0; #X connect 20 2 18 0; #X connect 20 3 40 0; #X connect 21 0 9 0; #X connect 22 0 23 0; #X connect 23 1 24 0; #X connect 25 0 26 1; #X connect 26 0 27 0; #X connect 30 0 9 0; #X connect 31 0 33 0; #X connect 32 0 42 1; #X connect 33 0 32 0; #X connect 33 0 38 0; #X connect 34 0 41 0; #X connect 35 0 34 0; #X connect 36 0 42 0; #X connect 38 0 35 0; #X connect 39 0 22 0; #X connect 40 0 5 1; #X connect 41 0 42 1; #X connect 42 0 14 0; #X connect 43 0 3 0; #X connect 44 0 46 0; #X connect 44 1 45 0; #X connect 44 2 45 1; #X connect 45 0 46 1; #X connect 46 0 48 1; #X connect 47 0 43 1; #X connect 48 0 2 0; #X connect 49 0 15 1; pd-0.46-7/extra/loop~/0000775000175000017500000000000012574202336012672 5ustar mspmsppd-0.46-7/extra/loop~/loop~-help.pd0000664000175000017500000000445512160204055015313 0ustar mspmsp#N canvas 234 90 647 662 12; #X floatatom 41 204 0 0 0 0 - - -; #X obj 254 382 print~; #X msg 254 347 bang; #X obj 41 338 loop~; #X floatatom 66 279 0 0 0 0 - - -; #X msg 55 252 bang; #X obj 183 382 print~; #X msg 183 347 bang; #N canvas 0 0 450 300 (subpatch) 0; #X array array2 150000 float 0; #X coords 0 1 150000 -1 200 150 1; #X restore 393 464 graph; #X msg 393 622 \; array2 resize 150000; #X obj 25 613 soundfiler; #X obj 16 453 tabread4~ array2; #X obj 16 407 *~; #X obj 16 522 dac~; #X obj 16 499 hip~ 5; #X obj 62 411 samphold~; #X obj 16 430 +~; #X floatatom 96 303 0 0 0 0 - - -; #X obj 96 326 *~ 1000; #X msg 43 568 read ../doc/sound/bell.aiff array2; #X msg 47 229 set 0.5; #X text 95 196 left signal input is transposition (1 is normal \, 2 is up an octave \, etc); #X text 82 4 loop~ - phase generator for looping samplers; #X text 116 228 set phase (0 to 1); #X text 104 253 reset phase to 0; #X text 104 278 right signal input is window size in samples; #X text 134 302 here's how to handle onsets; #X obj 16 476 *~; #X floatatom 167 432 0 0 0 0 - - -; #X obj 167 501 line~; #X obj 167 455 dbtorms; #X obj 167 478 pack 0 50; #X text 201 431 output level 0-100; #X text 187 326 print outputs; #X text 33 32 loop~ takes input signals to set a window size and transposition \, and outputs a phase and a sampled window size. The window size only changes at phase zero crossings and the phase output is adjusted so that changing window size doesn't change the transposition.; #X text 33 112 You can send "bang" or "set" message to force the phase to zero--you should mute the output before doing so. This may be desirable if you've set a large window size but then want to decrease it without waiting for the next phase crossing.; #X msg 43 591 read ../doc/sound/voice.wav array2; #X connect 0 0 3 0; #X connect 2 0 1 0; #X connect 3 0 6 0; #X connect 3 0 12 0; #X connect 3 0 15 1; #X connect 3 1 1 0; #X connect 3 1 12 1; #X connect 4 0 3 1; #X connect 5 0 3 0; #X connect 7 0 6 0; #X connect 11 0 27 0; #X connect 12 0 16 0; #X connect 14 0 13 0; #X connect 14 0 13 1; #X connect 15 0 16 1; #X connect 16 0 11 0; #X connect 17 0 18 0; #X connect 18 0 15 0; #X connect 19 0 10 0; #X connect 20 0 3 0; #X connect 27 0 14 0; #X connect 28 0 30 0; #X connect 29 0 27 1; #X connect 30 0 31 0; #X connect 31 0 29 0; #X connect 36 0 10 0; pd-0.46-7/extra/loop~/loop~.c0000664000175000017500000000741012222367057014211 0ustar mspmsp/* loop~ -- loop generator for sampling */ /* Copyright 1997-1999 Miller Puckette. Permission is granted to use this software for any purpose provided you keep this copyright notice intact. THE AUTHOR AND HIS EMPLOYERS MAKE NO WARRANTY, EXPRESS OR IMPLIED, IN CONNECTION WITH THIS SOFTWARE. This file is downloadable from http://www.crca.ucsd.edu/~msp . */ #ifdef PD #include "m_pd.h" #else #define t_sample float #define t_float float #endif typedef struct _loopctl { double l_phase; t_sample l_invwindow; t_sample l_window; int l_resync; } t_loopctl; static void loopctl_run(t_loopctl *x, t_sample *transposein, t_sample *windowin, t_sample *rawout, t_sample *windowout, int n) { t_sample window, invwindow; double phase = x->l_phase; if (x->l_resync) { window = *windowin; if (window < 0) { if (window > -1) window = -1; invwindow = -1/window; } else { if (window < 1) window = 1; invwindow = 1/window; } x->l_resync = 0; } else { window = x->l_window; phase = x->l_phase; invwindow = x->l_invwindow; } while (n--) { double phaseinc = invwindow * *transposein++; double newphase; t_sample nwind = *windowin++; if (phaseinc >= 1 || phaseinc < 0) phaseinc = 0; newphase = phase + phaseinc; if (newphase >= 1) { window = nwind; if (window < 0) { if (window > -1) window = -1; invwindow = -1/window; } else { if (window < 1) window = 1; invwindow = 1/window; } newphase -= 1.; } phase = newphase; *rawout++ = (t_sample)phase; *windowout++ = window; } x->l_invwindow = invwindow; x->l_window = window; x->l_phase = phase; } static void loopctl_init(t_loopctl *x) { x->l_window = 1; x->l_invwindow = 1; x->l_phase = 0; } static void loopctl_set(t_loopctl *x, t_float val) { if (val < 0 || val > 1) val = 0; x->l_phase = val; x->l_resync = 1; } #ifdef PD typedef struct _loop { t_object x_obj; t_float x_f; t_loopctl x_loopctl; } t_loop; static t_class *loop_class; static void *loop_new(void) { t_loop *x = (t_loop *)pd_new(loop_class); loopctl_init(&x->x_loopctl); inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); outlet_new(&x->x_obj, gensym("signal")); outlet_new(&x->x_obj, gensym("signal")); return (x); } static t_int *loop_perform(t_int *w) { t_loopctl *ctl = (t_loopctl *)(w[1]); t_sample *in1 = (t_sample *)(w[2]); t_sample *in2 = (t_sample *)(w[3]); t_sample *out1 = (t_sample *)(w[4]); t_sample *out2 = (t_sample *)(w[5]); int n = (int)(w[6]); loopctl_run(ctl, in1, in2, out1, out2, n); return (w+7); } static void loop_dsp(t_loop *x, t_signal **sp) { dsp_add(loop_perform, 6, &x->x_loopctl, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec, sp[0]->s_n); } static void loop_set(t_loop *x, t_floatarg val) { loopctl_set(&x->x_loopctl, val); } static void loop_bang(t_loop *x) { loopctl_set(&x->x_loopctl, 0); } void loop_tilde_setup(void) { loop_class = class_new(gensym("loop~"), (t_newmethod)loop_new, 0, sizeof(t_loop), 0, 0); class_addmethod(loop_class, (t_method)loop_dsp, gensym("dsp"), A_CANT, 0); CLASS_MAINSIGNALIN(loop_class, t_loop, x_f); class_addmethod(loop_class, (t_method)loop_set, gensym("set"), A_DEFFLOAT, 0); class_addbang(loop_class, loop_bang); } #endif /* PD */ pd-0.46-7/extra/loop~/GNUmakefile.am0000664000175000017500000000127012374250720015336 0ustar mspmsp## Makefile.am -- Process this file with automake to produce Makefile.in NAME=loop~ external_LTLIBRARIES = loop~.la SOURCES = loop~.c PATCHES = loop~-help.pd test-loop~.pd OTHERDATA = EXTRA_DIST = makefile ############################### # you shouldn't need to add anything below here dist_external_DATA = $(PATCHES) $(OTHERDATA) AUTOMAKE_OPTIONS = foreign AM_CPPFLAGS = -I$(top_srcdir)/src -DPD AM_CFLAGS = @ARCH_CFLAGS@ AM_LIBS = $(LIBM) AM_LDFLAGS = -module -avoid-version -shared @ARCH_LDFLAGS@ -shrext .@EXTERNAL_EXTENSION@ -L$(top_srcdir)/src externaldir = $(pkglibdir)/extra/$(NAME) if MINGW AM_LIBS += -lpd endif libtool: $(LIBTOOL_DEPS) $(SHELL) ./config.status --recheck pd-0.46-7/extra/loop~/test-loop~.pd0000664000175000017500000000273112160204055015335 0ustar mspmsp#N canvas 33 0 680 609 12; #X floatatom 52 262 0 0 0 0 - - -; #X obj 261 346 print~; #X msg 47 373 bang; #X msg 274 313 bang; #X obj 52 306 loop~; #X floatatom 102 245 0 0 0 0 - - -; #N canvas 0 0 450 300 graph1 0; #X array array1 44100 float 0; #X coords 0 10 44100 0 200 150 1; #X restore 65 17 graph; #X msg 43 204 \; array1 resize 44100; #X obj 25 401 tabwrite~ array1; #X msg 208 371 bang; #X obj 176 402 tabwrite~ array1; #X msg 194 261 bang; #X obj 204 347 print~; #X msg 217 314 bang; #N canvas 0 0 450 300 graph1 0; #X array array2 150000 float 0; #X coords 0 1 150000 -1 200 150 1; #X restore 332 398 graph; #X msg 326 274 \; array2 resize 150000; #X obj 103 529 tabread4~ array2; #X obj 64 481 *~; #X obj 107 581 dac~; #X obj 105 552 hip~ 5; #X obj 123 482 samphold~; #X obj 102 506 +~; #X floatatom 106 430 0 0 0 0 - - -; #X obj 108 453 *~ 1000; #X obj 312 215 soundfiler; #X msg 330 170 read ../doc/sound/bell.aiff array2; #X msg 330 193 read ../doc/sound/vocal.aiff array2; #X connect 0 0 4 0; #X connect 2 0 8 0; #X connect 3 0 1 0; #X connect 4 0 12 0; #X connect 4 0 17 0; #X connect 4 0 8 0; #X connect 4 0 20 1; #X connect 4 1 10 0; #X connect 4 1 1 0; #X connect 4 1 17 1; #X connect 5 0 4 1; #X connect 9 0 10 0; #X connect 11 0 4 0; #X connect 13 0 12 0; #X connect 16 0 19 0; #X connect 17 0 21 0; #X connect 19 0 18 0; #X connect 19 0 18 1; #X connect 20 0 21 1; #X connect 21 0 16 0; #X connect 22 0 23 0; #X connect 23 0 20 0; #X connect 25 0 24 0; #X connect 26 0 24 0; pd-0.46-7/extra/loop~/makefile0000664000175000017500000000006712160204055014364 0ustar mspmspNAME=loop~ CSYM=loop_tilde include ../makefile.subdir pd-0.46-7/extra/pd~/0000775000175000017500000000000012574202336012324 5ustar mspmsppd-0.46-7/extra/pd~/z.pd0000644000175000017500000000053411024115761013114 0ustar mspmsp#N canvas 686 241 450 300 10; #X obj 65 58 r foo; #X obj 62 100 print foo; #X obj 244 59 adc~; #X obj 238 102 env~ 8192; #X floatatom 236 140 5 0 0 0 - - -; #X obj 155 234 dac~; #X obj 155 191 osc~ 440; #X obj 287 204 stdout; #X msg 307 153 a b c; #X connect 0 0 1 0; #X connect 2 0 3 0; #X connect 3 0 4 0; #X connect 6 0 5 0; #X connect 8 0 7 0; pd-0.46-7/extra/pd~/pd~-subprocess.pd0000664000175000017500000000401112374245151015634 0ustar mspmsp#N canvas 1233 66 646 598 12; #X obj 202 395 r foo; #X obj 202 423 print foo; #X obj 87 174 adc~; #X obj 72 442 stdout; #X msg 72 364 a b c; #X msg 455 441 \; pd dsp 1; #X obj 87 201 env~ 8192; #X floatatom 87 250 5 0 0 0 - - -, f 5; #X obj 87 226 i; #X obj 263 253 dac~; #X obj 262 185 osc~ 440; #X obj 262 219 *~; #X obj 297 220 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1 1; #X obj 332 186 osc~ 440; #X obj 332 220 *~; #X obj 367 221 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X msg 86 411 bang; #X obj 455 417 loadbang; #X obj 160 201 env~ 8192; #X floatatom 160 250 5 0 0 0 - - -, f 5; #X obj 160 226 i; #X msg 86 388 4; #X text 62 8 This is a test patch to demonstrate the Pd~ object. It's intended as the patch to run in the sub-process. The sub-process (which is a separate instance of Pd) can be called from a Max or Pd super-process. ; #X text 63 73 Audio inlets and outlets on the Pd~ object (in the super-process) talk to adc~ and dac~ objects here - so \, for instance \, the first adc~ here is the first inlet of the pd~ object \, and the first chanel of dac~ goes to the second outlet of pd~ (because the first one is for messages \, as shown further below.); #X text 58 283 Any message sent to a stdout object in this sub-process (below) appears on the first \, message outlet of the pd~ object in the super-process. The super-process can send messages to any "receive" object in this sub-process.; #X text 137 478 We turn DSP on at load for convenience - control objects in this patch will still work without it (unlike in the super-process \, where DSP must be on for time to move forward in the sub-process.) ; #X text 351 538 Updated for Pd version 0.42.; #X connect 0 0 1 0; #X connect 2 0 6 0; #X connect 2 1 18 0; #X connect 4 0 3 0; #X connect 6 0 8 0; #X connect 8 0 7 0; #X connect 10 0 11 0; #X connect 11 0 9 0; #X connect 12 0 11 1; #X connect 13 0 14 0; #X connect 14 0 9 1; #X connect 15 0 14 1; #X connect 16 0 3 0; #X connect 17 0 5 0; #X connect 18 0 20 0; #X connect 20 0 19 0; #X connect 21 0 3 0; pd-0.46-7/extra/pd~/pdsched.c0000664000175000017500000000703712374250720014107 0ustar mspmsp/* Copyright 2008 Miller Puckette. Berkeley license; see the file LICENSE.txt in this distribution. */ /* A plug-in scheduler that turns Pd into a filter that inputs and outputs audio and messages. */ /* todo: fix schedlib code to use extent2 figure out about if (sys_externalschedlib) { return; } in s_audio.c make buffer size ynamically growable */ #include "m_pd.h" #include "s_stuff.h" #include "m_imp.h" #include #define BUFSIZE 65536 static char inbuf[BUFSIZE]; #if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__GNU__) void glob_watchdog(t_pd *dummy); static void pollwatchdog( void) { static int sched_diddsp, sched_nextpingtime; sched_diddsp++; if (sys_nogui && sys_hipriority && (sched_diddsp - sched_nextpingtime > 0)) { glob_watchdog(0); /* ping every 2 seconds */ sched_nextpingtime = sched_diddsp + 2 * (int)(sys_dacsr /(double)sys_schedblocksize); } } #endif int pd_extern_sched(char *flags) { int naudioindev, audioindev[MAXAUDIOINDEV], chindev[MAXAUDIOINDEV]; int naudiooutdev, audiooutdev[MAXAUDIOOUTDEV], choutdev[MAXAUDIOOUTDEV]; int i, j, rate, advance, callback, chin, chout, fill = 0, c, blocksize; t_binbuf *b = binbuf_new(); sys_get_audio_params(&naudioindev, audioindev, chindev, &naudiooutdev, audiooutdev, choutdev, &rate, &advance, &callback, &blocksize); chin = (naudioindev < 1 ? 0 : chindev[0]); chout = (naudiooutdev < 1 ? 0 : choutdev[0]); /* fprintf(stderr, "Pd plug-in scheduler called, chans %d %d, sr %d\n", chin, chout, (int)rate); */ sys_setchsr(chin, chout, rate); sys_audioapi = API_NONE; while ((c = getchar()) != EOF) { if (c == ';') { int n; t_atom *ap; binbuf_text(b, inbuf, fill); n = binbuf_getnatom(b); ap = binbuf_getvec(b); fill = 0; if (n > 0 && ap[0].a_type == A_FLOAT) { /* a list -- take it as incoming signals. */ int chan, nchan = n/DEFDACBLKSIZE; t_sample *fp; for (i = chan = 0, fp = sys_soundin; chan < nchan; chan++) for (j = 0; j < DEFDACBLKSIZE; j++) *fp++ = atom_getfloat(ap++); for (; chan < chin; chan++) for (j = 0; j < DEFDACBLKSIZE; j++) *fp++ = 0; sched_tick(); sys_pollgui(); #if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__GNU__) pollwatchdog(); #endif printf(";\n"); for (i = chout*DEFDACBLKSIZE, fp = sys_soundout; i--; fp++) { printf("%g\n", *fp); *fp = 0; } printf(";\n"); fflush(stdout); } else if (n > 1 && ap[0].a_type == A_SYMBOL) { t_pd *whom = ap[0].a_w.w_symbol->s_thing; if (!whom) error("%s: no such object", ap[0].a_w.w_symbol->s_name); else if (ap[1].a_type == A_SYMBOL) typedmess(whom, ap[1].a_w.w_symbol, n-2, ap+2); else pd_list(whom, 0, n-1, ap+1); } } else if (fill < BUFSIZE) inbuf[fill++] = c; else if (fill == BUFSIZE) fprintf(stderr, "pd-extern: input buffer overflow\n"); } return (0); } pd-0.46-7/extra/pd~/pd~-help.pd0000664000175000017500000000575112160204055014377 0ustar mspmsp#N canvas 12 0 566 872 12; #X msg 31 406 foo bar baz; #X obj 189 466 osc~ 440; #X obj 127 645 env~ 8192; #X floatatom 127 694 5 0 0 0 - - -; #X msg 434 807 \; pd dsp 1; #X msg 24 332 pd~ stop; #X obj 127 670 i; #X obj 241 643 env~ 8192; #X floatatom 241 693 5 0 0 0 - - -; #X obj 241 669 i; #X obj 123 489 *~; #X obj 158 490 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 189 490 *~; #X obj 224 491 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 434 781 loadbang; #X obj 14 691 print x; #X msg 15 309 pd~ start pd~-subprocess.pd; #X obj 14 532 pd~ -ninsig 2 -noutsig 2 -fifo 20; #X obj 37 20 pd~; #X text 69 22 - run a pd sub-process; #X text 27 57 The pd~ object starts and manages a Pd sub-process that can communicate with the super-process (this one) via audio channels and/or Pd messages. In this way you can take advantage of multi-core CPUs \, and/or use Pd features from within Max (if you're using the Max version of pd~).; #X text 24 251 Sending a new "start" message will stop the sub-process and start a new one. If you just want to stop the sub-process \, send "stop".; #X text 33 353 Any message besides "pd~" is sent to the sub-process. For instance \, the message below sends "bar baz" to any object in the sub-process named "foo" \, such as a "receive" object.; #X text 43 430 Audio signals appear in adc~ objects in the sub-process. The sub-process doesn't open real audio devices.; #X text 281 473 Creation args:; #X text 265 490 -insig sets input audio channels; #X text 266 508 -outsig sets output channels; #X text 269 542 -fifo sets round-trip delay in blocks; #X text 272 559 -pddir sets Pd directory \, e.g. \,; #X text 299 574 .../Pd-0.42.app/Contents/Resources; #X text 272 590 -scheddir sets scheduler dir \, e.g. \,; #X text 297 607 .../.../Resources/extra/pd~; #X text 267 524 -sr sets sample rate; #X text 20 716 The first outlet reports messages the sub-process sends us via "stdout" objects. Any other outlets are signals corresponding to "dac~" objects in the sub-process.; #X text 10 784 ATTENTION: DSP must be running in this process for the sub-process to run. This is because its clock is slaved to audio I/O it gets from us!; #X text 359 849 Updated for Pd version 0.42.; #X text 24 138 Messages with "pd~" selector control the sub-process. "pd~ start" takes as arguments any startup arguments you wish to send the sub-process. For example \, specify "-nogui" to stop the sub-process's GUI from appearing. You don't have to specify the number of channels in and out \, since that's set by creation arguments below. Audio config arguments arguments (-audiobuf \, -audiodev \, etc.) are ignored.; #X connect 0 0 17 0; #X connect 1 0 10 0; #X connect 1 0 12 0; #X connect 2 0 6 0; #X connect 5 0 17 0; #X connect 6 0 3 0; #X connect 7 0 9 0; #X connect 9 0 8 0; #X connect 10 0 17 0; #X connect 11 0 10 1; #X connect 12 0 17 1; #X connect 13 0 12 1; #X connect 14 0 4 0; #X connect 16 0 17 0; #X connect 17 0 15 0; #X connect 17 1 2 0; #X connect 17 2 7 0; pd-0.46-7/extra/pd~/GNUmakefile.am0000664000175000017500000000135712374250720014776 0ustar mspmsp## Makefile.am -- Process this file with automake to produce Makefile.in NAME=pd~ external_LTLIBRARIES = pd~.la pdsched.la PATCHES = pd~-help.pd pd~-subprocess.pd OTHERDATA = pd__la_SOURCES = pd~.c pdsched_la_SOURCES = pdsched.c EXTRA_DIST = makefile notes.txt ############################### # you shouldn't need to add anything below here dist_external_DATA = $(PATCHES) $(OTHERDATA) AUTOMAKE_OPTIONS = foreign AM_CPPFLAGS = -I$(top_srcdir)/src -DPD AM_CFLAGS = @ARCH_CFLAGS@ AM_LIBS = $(LIBM) AM_LDFLAGS = -module -avoid-version -shared @ARCH_LDFLAGS@ -shrext .@EXTERNAL_EXTENSION@ -L$(top_srcdir)/src externaldir = $(pkglibdir)/extra/$(NAME) if MINGW AM_LIBS += -lpd endif libtool: $(LIBTOOL_DEPS) $(SHELL) ./config.status --recheck pd-0.46-7/extra/pd~/pd~.c0000664000175000017500000006066712574135745013321 0ustar mspmsp/* pd~.c - embed a Pd process within Pd or Max. Copyright 2008 Miller Puckette BSD license; see README.txt in this distribution for details. */ #ifdef _WIN32 #include #include #include #include typedef int socklen_t; #define EADDRINUSE WSAEADDRINUSE #else #include #include #include #include #include #include #include #include #endif #include #include #ifdef _MSC_VER #pragma warning (disable: 4305 4244) #define snprintf sprintf_s #define stat _stat #endif #ifdef MSP #include "ext.h" #include "z_dsp.h" #include "math.h" #include "ext_support.h" #include "ext_proto.h" #include "ext_obex.h" typedef double t_floatarg; #define w_symbol w_sym #define A_SYMBOL A_SYM #define getbytes t_getbytes #define freebytes t_freebytes #define PDERROR error( void *pd_tilde_class; #define MAXPDSTRING 4096 #define DEFDACBLKSIZE 64 #endif /* MSP */ #ifdef PD #include "m_pd.h" #include "s_stuff.h" static t_class *pd_tilde_class; #define PDERROR pd_error(x, #endif #if defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__GNU__) #ifdef __x86_64__ static char pd_tilde_dllextent[] = ".l_ia64", pd_tilde_dllextent2[] = ".pd_linux"; #else static char pd_tilde_dllextent[] = ".l_i386", pd_tilde_dllextent2[] = ".pd_linux"; #endif #endif #ifdef __APPLE__ static char pd_tilde_dllextent[] = ".d_fat", pd_tilde_dllextent2[] = ".pd_darwin"; #endif #if defined(_WIN32) || defined(__CYGWIN__) static char pd_tilde_dllextent[] = ".m_i386", pd_tilde_dllextent2[] = ".dll"; #endif /* ------------------------ pd_tilde~ ----------------------------- */ #define MSGBUFSIZE 65536 typedef struct _pd_tilde { #ifdef PD t_object x_obj; t_clock *x_clock; t_outlet *x_outlet1; /* for messages back from subproc */ t_canvas *x_canvas; #endif /* PD */ #ifdef MSP t_pxobject x_obj; void *x_outlet1; void *x_clock; #endif /* MSP */ FILE *x_infd; FILE *x_outfd; char *x_msgbuf; int x_msgbufsize; int x_infill; int x_childpid; int x_ninsig; int x_noutsig; int x_fifo; t_float x_sr; t_symbol *x_pddir; t_symbol *x_schedlibdir; t_sample **x_insig; t_sample **x_outsig; } t_pd_tilde; #ifdef MSP static void *pd_tilde_new(t_symbol *s, long ac, t_atom *av); static void pd_tilde_tick(t_pd_tilde *x); static t_int *pd_tilde_perform(t_int *w); static void pd_tilde_dsp(t_pd_tilde *x, t_signal **sp); void pd_tilde_assist(t_pd_tilde *x, void *b, long m, long a, char *s); static void pd_tilde_free(t_pd_tilde *x); void pd_tilde_setup(void); int main(); void pd_tilde_minvel_set(t_pd_tilde *x, void *attr, long ac, t_atom *av); char *strcpy(char *s1, const char *s2); #endif static void pd_tilde_tick(t_pd_tilde *x); static void pd_tilde_close(t_pd_tilde *x) { #ifdef _WIN32 int termstat; #endif if (x->x_outfd) fclose(x->x_outfd); if (x->x_infd) fclose(x->x_infd); if (x->x_childpid > 0) #ifdef _WIN32 _cwait(&termstat, x->x_childpid, WAIT_CHILD); #else waitpid(x->x_childpid, 0, 0); #endif if (x->x_msgbuf) free(x->x_msgbuf); x->x_infd = x->x_outfd = 0; x->x_childpid = -1; x->x_msgbuf = 0; x->x_msgbufsize = 0; } static void pd_tilde_readmessages(t_pd_tilde *x) { int gotsomething = 0, setclock = 0, wasempty = (x->x_infill == 0); FILE *infd = x->x_infd; while (1) { int c = getc(infd); if (c == EOF) { PDERROR "pd~: read failed: %s", strerror(errno)); pd_tilde_close(x); break; } if (x->x_infill >= x->x_msgbufsize) { char *z = realloc(x->x_msgbuf, x->x_msgbufsize+MSGBUFSIZE); if (!z) { PDERROR "pd~: failed to grow input buffer"); pd_tilde_close(x); break; } x->x_msgbuf = z; x->x_msgbufsize += MSGBUFSIZE; } x->x_msgbuf[x->x_infill++] = c; if (c == ';') { if (!gotsomething) break; gotsomething = 0; } else if (!isspace(c)) gotsomething = setclock = 1; } if (setclock) clock_delay(x->x_clock, 0); else if (wasempty) x->x_infill = 0; } #define FIXEDARG 11 #define MAXARG 100 #ifdef _WIN32 #define EXTENT ".com" #else #define EXTENT "" #endif static void pd_tilde_donew(t_pd_tilde *x, char *pddir, char *schedlibdir, char *patchdir, int argc, t_atom *argv, int ninsig, int noutsig, int fifo, t_float samplerate) { int i, pid, pipe1[2], pipe2[2]; char pdexecbuf[MAXPDSTRING], schedbuf[MAXPDSTRING], tmpbuf[MAXPDSTRING]; char *execargv[FIXEDARG+MAXARG+1], ninsigstr[20], noutsigstr[20], sampleratestr[40]; struct stat statbuf; x->x_infd = x->x_outfd = 0; x->x_childpid = -1; if (argc > MAXARG) { post("pd~: args truncated to %d items", MAXARG); argc = MAXARG; } sprintf(ninsigstr, "%d", ninsig); sprintf(noutsigstr, "%d", noutsig); sprintf(sampleratestr, "%f", (float)samplerate); snprintf(tmpbuf, MAXPDSTRING, "%s/bin/pd" EXTENT, pddir); sys_bashfilename(tmpbuf, pdexecbuf); if (stat(pdexecbuf, &statbuf) < 0) { snprintf(tmpbuf, MAXPDSTRING, "%s/../../../bin/pd" EXTENT, pddir); sys_bashfilename(tmpbuf, pdexecbuf); if (stat(pdexecbuf, &statbuf) < 0) { snprintf(tmpbuf, MAXPDSTRING, "%s/pd" EXTENT, pddir); sys_bashfilename(tmpbuf, pdexecbuf); if (stat(pdexecbuf, &statbuf) < 0) { PDERROR "pd~: can't stat %s", pdexecbuf); goto fail1; } } } /* check that the scheduler dynamic linkable exists w either sffix */ snprintf(tmpbuf, MAXPDSTRING, "%s/pdsched%s", schedlibdir, pd_tilde_dllextent); sys_bashfilename(tmpbuf, schedbuf); if (stat(schedbuf, &statbuf) < 0) { snprintf(tmpbuf, MAXPDSTRING, "%s/pdsched%s", schedlibdir, pd_tilde_dllextent2); sys_bashfilename(tmpbuf, schedbuf); if (stat(schedbuf, &statbuf) < 0) { PDERROR "pd~: can't stat %s", schedbuf); goto fail1; } } /* but the sub-process wants the scheduler name without the suffix */ snprintf(tmpbuf, MAXPDSTRING, "%s/pdsched", schedlibdir); sys_bashfilename(tmpbuf, schedbuf); /* was: snprintf(cmdbuf, MAXPDSTRING, "'%s' -schedlib '%s'/pdsched -path '%s' -inchannels %d -outchannels %d -r %g %s\n", pdexecbuf, schedlibdir, patchdir, ninsig, noutsig, samplerate, pdargs); */ execargv[0] = pdexecbuf; execargv[1] = "-schedlib"; execargv[2] = schedbuf; execargv[3] = "-path"; execargv[4] = patchdir; execargv[5] = "-inchannels"; execargv[6] = ninsigstr; execargv[7] = "-outchannels"; execargv[8] = noutsigstr; execargv[9] = "-r"; execargv[10] = sampleratestr; /* convert atom arguments to strings (temporarily allocating space) */ for (i = 0; i < argc; i++) { #ifdef PD atom_string(&argv[i], tmpbuf, MAXPDSTRING); #endif #ifdef MSP /* because Mac pathnames sometimes have an evil preceeding colon character, we test for and silently eat them */ if (argv[i].a_type == A_SYM) strncpy(tmpbuf, (*argv->a_w.w_sym->s_name == ':'? argv->a_w.w_sym->s_name+1 : argv->a_w.w_sym->s_name), MAXPDSTRING-3); else if (argv[i].a_type == A_LONG) sprintf(tmpbuf, "%ld", argv->a_w.w_long); else if (argv[i].a_type == A_FLOAT) sprintf(tmpbuf, "%f", argv->a_w.w_float); #endif execargv[FIXEDARG+i] = malloc(strlen(tmpbuf) + 1); strcpy(execargv[FIXEDARG+i], tmpbuf); } execargv[argc+FIXEDARG] = 0; #if 0 for (i = 0; i < argc+FIXEDARG; i++) fprintf(stderr, "%s ", execargv[i]); fprintf(stderr, "\n"); #endif #ifdef _WIN32 if (_pipe(pipe1, 65536, O_BINARY | O_NOINHERIT) < 0) #else if (pipe(pipe1) < 0) #endif { PDERROR "pd~: can't create pipe"); goto fail1; } #ifdef _WIN32 if (_pipe(pipe2, 65536, O_BINARY | O_NOINHERIT) < 0) #else if (pipe(pipe2) < 0) #endif { PDERROR "pd~: can't create pipe"); goto fail2; } #ifdef _WIN32 { int stdinwas = _dup(0), stdoutwas = _dup(1); if (pipe2[1] == 0) pipe2[1] = _dup(pipe2[1]); if (pipe1[0] != 0) _dup2(pipe1[0], 0); if (pipe2[1] != 1) _dup2(pipe2[1], 1); pid = _spawnv(P_NOWAIT, execargv[0], execargv); if (pid < 0) { post("%s: couldn't start subprocess (%s)\n", execargv[0], strerror(errno)); goto fail1; } _dup2(stdinwas, 0); _dup2(stdoutwas, 1); _close(stdinwas); _close(stdoutwas); } #else /* _WIN32 */ if ((pid = fork()) < 0) { PDERROR "pd~: can't fork"); goto fail3; } else if (pid == 0) { /* child process */ /* the first dup2 below would bash pipe2[1] if it happens to be zero so in that case renumber it */ if (pipe2[1] == 0) pipe2[1] = dup(pipe2[1]); if (pipe1[0] != 0) { dup2(pipe1[0], 0); close (pipe1[0]); } if (pipe2[1] != 1) { dup2(pipe2[1], 1); close (pipe2[1]); } if (pipe1[1] >= 2) close(pipe1[1]); if (pipe2[0] >= 2) close(pipe2[0]); execv(execargv[0], execargv); _exit(1); } #endif /* _WIN32 */ /* done with fork/exec or spawn; parent continues here */ close(pipe1[0]); close(pipe2[1]); #ifndef _WIN32 /* this was done in windows via the O_NOINHERIT flag */ fcntl(pipe1[1], F_SETFD, FD_CLOEXEC); fcntl(pipe2[0], F_SETFD, FD_CLOEXEC); #endif x->x_outfd = fdopen(pipe1[1], "w"); x->x_infd = fdopen(pipe2[0], "r"); x->x_childpid = pid; for (i = 0; i < fifo; i++) fprintf(x->x_outfd, "%s", ";\n0;\n"); fflush(x->x_outfd); if (!(x->x_msgbuf = calloc(MSGBUFSIZE, 1))) { PDERROR "pd~: can't allocate message buffer"); goto fail3; } x->x_msgbufsize = MSGBUFSIZE; x->x_infill = 0; pd_tilde_readmessages(x); return; fail3: close(pipe2[0]); close(pipe2[1]); if (x->x_childpid > 0) #ifdef _WIN32 { int termstat; _cwait(&termstat, x->x_childpid, WAIT_CHILD); } #else waitpid(x->x_childpid, 0, 0); #endif fail2: close(pipe1[0]); close(pipe1[1]); fail1: x->x_infd = x->x_outfd = 0; x->x_childpid = -1; return; } static t_int *pd_tilde_perform(t_int *w) { t_pd_tilde *x = (t_pd_tilde *)(w[1]); int n = (int)(w[2]), i, j, numbuffill = 0, c; char numbuf[80]; FILE *infd = x->x_infd; if (!infd) goto zeroit; fprintf(x->x_outfd, ";\n"); if (!x->x_ninsig) fprintf(x->x_outfd, "0\n"); else for (i = 0; i < x->x_ninsig; i++) { t_sample *fp = x->x_insig[i]; for (j = 0; j < n; j++) fprintf(x->x_outfd, "%g\n", *fp++); for (; j < DEFDACBLKSIZE; j++) fprintf(x->x_outfd, "0\n"); } fprintf(x->x_outfd, ";\n"); fflush(x->x_outfd); i = j = 0; while (1) { while (1) { c = getc(infd); if (c == EOF) { if (errno) PDERROR "pd~: %s", strerror(errno)); else PDERROR "pd~: subprocess exited"); pd_tilde_close(x); goto zeroit; } else if (!isspace(c) && c != ';') { if (numbuffill < (80-1)) numbuf[numbuffill++] = c; } else { t_sample z; if (numbuffill) { numbuf[numbuffill] = 0; if (sscanf(numbuf, "%f", &z) < 1) continue; if (i < x->x_noutsig) x->x_outsig[i][j] = z; if (++j >= DEFDACBLKSIZE) j = 0, i++; } numbuffill = 0; break; } } /* message terminated */ if (c == ';') break; } for (; i < x->x_noutsig; i++, j = 0) { for (; j < DEFDACBLKSIZE; j++) x->x_outsig[i][j] = 0; } pd_tilde_readmessages(x); return (w+3); zeroit: for (i = 0; i < x->x_noutsig; i++) { for (j = 0; j < DEFDACBLKSIZE; j++) x->x_outsig[i][j] = 0; } return (w+3); } static void pd_tilde_dsp(t_pd_tilde *x, t_signal **sp) { int i, n = (x->x_ninsig || x->x_noutsig ? sp[0]->s_n : 1); t_sample **g; for (i = 0, g = x->x_insig; i < x->x_ninsig; i++, g++) *g = (*(sp++))->s_vec; for (i = 0, g = x->x_outsig; i < x->x_noutsig; i++, g++) *g = (*(sp++))->s_vec; dsp_add(pd_tilde_perform, 2, x, n); } static void pd_tilde_pdtilde(t_pd_tilde *x, t_symbol *s, int argc, t_atom *argv) { t_symbol *sel = ((argc > 0 && argv->a_type == A_SYMBOL) ? argv->a_w.w_symbol : gensym("?")), *schedlibdir; char *patchdir; if (sel == gensym("start")) { char pdargstring[MAXPDSTRING]; if (x->x_infd) pd_tilde_close(x); pdargstring[0] = 0; argc--; argv++; #ifdef PD patchdir = canvas_getdir(x->x_canvas)->s_name; #endif #ifdef MSP patchdir = "."; #endif schedlibdir = x->x_schedlibdir; if (schedlibdir == gensym(".") && x->x_pddir != gensym(".")) { char *pds = x->x_pddir->s_name, scheddirstring[MAXPDSTRING]; int l = strlen(pds); if (l >= 4 && (!strcmp(pds+l-3, "bin") || !strcmp(pds+l-4, "bin/"))) snprintf(scheddirstring, MAXPDSTRING, "%s/../extra/pd~", pds); else snprintf(scheddirstring, MAXPDSTRING, "%s/extra/pd~", pds); schedlibdir = gensym(scheddirstring); } pd_tilde_donew(x, x->x_pddir->s_name, schedlibdir->s_name, patchdir, argc, argv, x->x_ninsig, x->x_noutsig, x->x_fifo, x->x_sr); } else if (sel == gensym("stop")) { if (x->x_infd) pd_tilde_close(x); } else if (sel == gensym("pddir")) { if ((argc > 1) && argv[1].a_type == A_SYMBOL) { t_symbol *sym = argv[1].a_w.w_symbol; #ifdef MSP if (sym->s_name[0] == ':') sym = gensym(s->s_name+1); #endif x->x_pddir = sym; } else PDERROR "pd~ pddir: needs symbol argument"); } else PDERROR "pd~: unknown control message: %s", sel->s_name); } static void pd_tilde_free(t_pd_tilde *x) { #ifdef MSP dsp_free((t_pxobject *)x); #endif pd_tilde_close(x); clock_free(x->x_clock); } /* -------------------------- Pd glue ------------------------- */ #ifdef PD static void pd_tilde_tick(t_pd_tilde *x) { int messstart = 0, i, n; t_atom *vec; t_binbuf *b; if (!x->x_msgbuf) return; b = binbuf_new(); binbuf_text(b, x->x_msgbuf, x->x_infill); /* binbuf_print(b); */ n = binbuf_getnatom(b); vec = binbuf_getvec(b); for (i = 0; i < n; i++) { if (vec[i].a_type == A_SEMI) { if (i > messstart && vec[messstart].a_type == A_SYMBOL) outlet_anything(x->x_outlet1, vec[messstart].a_w.w_symbol, i-(messstart+1), vec+(messstart+1)); else if (i > messstart) outlet_list(x->x_outlet1, 0, i-messstart, vec+messstart); messstart = i+1; } } binbuf_free(b); x->x_infill = 0; } static void pd_tilde_anything(t_pd_tilde *x, t_symbol *s, int argc, t_atom *argv) { char msgbuf[MAXPDSTRING]; if (!x->x_outfd) return; fprintf(x->x_outfd, "%s ", s->s_name); while (argc--) { atom_string(argv++, msgbuf, MAXPDSTRING); fprintf(x->x_outfd, "%s ", msgbuf); } fprintf(x->x_outfd, ";\n"); } static void *pd_tilde_new(t_symbol *s, int argc, t_atom *argv) { t_pd_tilde *x = (t_pd_tilde *)pd_new(pd_tilde_class); int ninsig = 2, noutsig = 2, j, fifo = 5; t_float sr = sys_getsr(); t_sample **g; t_symbol *pddir = sys_libdir, *scheddir = gensym(class_gethelpdir(pd_tilde_class)); /* fprintf(stderr, "pd %s, sched %s\n", pddir->s_name, scheddir->s_name); */ while (argc > 0) { t_symbol *firstarg = atom_getsymbolarg(0, argc, argv); if (!strcmp(firstarg->s_name, "-sr") && argc > 1) { sr = atom_getfloatarg(1, argc, argv); argc -= 2; argv += 2; } else if (!strcmp(firstarg->s_name, "-ninsig") && argc > 1) { ninsig = atom_getfloatarg(1, argc, argv); argc -= 2; argv += 2; } else if (!strcmp(firstarg->s_name, "-noutsig") && argc > 1) { noutsig = atom_getfloatarg(1, argc, argv); argc -= 2; argv += 2; } else if (!strcmp(firstarg->s_name, "-fifo") && argc > 1) { fifo = atom_getfloatarg(1, argc, argv); argc -= 2; argv += 2; } else if (!strcmp(firstarg->s_name, "-pddir") && argc > 1) { pddir = atom_getsymbolarg(1, argc, argv); argc -= 2; argv += 2; } else if (!strcmp(firstarg->s_name, "-scheddir") && argc > 1) { scheddir = atom_getsymbolarg(1, argc, argv); argc -= 2; argv += 2; } else break; } if (argc) { pd_error(x, "usage: pd~ [-sr #] [-ninsig #] [-noutsig #] [-fifo #] [-pddir <>]"); post( "... [-scheddir <>]"); } x->x_clock = clock_new(x, (t_method)pd_tilde_tick); x->x_insig = (t_sample **)getbytes(ninsig * sizeof(*x->x_insig)); x->x_outsig = (t_sample **)getbytes(noutsig * sizeof(*x->x_outsig)); x->x_ninsig = ninsig; x->x_noutsig = noutsig; x->x_fifo = fifo; x->x_sr = sr; x->x_pddir = pddir; x->x_schedlibdir = scheddir; x->x_infd = 0; x->x_outfd = 0; x->x_outfd = 0; x->x_childpid = -1; x->x_msgbuf = 0; x->x_canvas = canvas_getcurrent(); for (j = 1, g = x->x_insig; j < ninsig; j++, g++) inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); x->x_outlet1 = outlet_new(&x->x_obj, 0); for (j = 0, g = x->x_outsig; j < noutsig; j++, g++) outlet_new(&x->x_obj, &s_signal); #ifndef _WIN32 signal(SIGPIPE, SIG_IGN); #endif return (x); } void pd_tilde_setup(void) { pd_tilde_class = class_new(gensym("pd~"), (t_newmethod)pd_tilde_new, (t_method)pd_tilde_free, sizeof(t_pd_tilde), 0, A_GIMME, 0); class_addmethod(pd_tilde_class, nullfn, gensym("signal"), 0); class_addmethod(pd_tilde_class, (t_method)pd_tilde_dsp, gensym("dsp"), 0); class_addmethod(pd_tilde_class, (t_method)pd_tilde_pdtilde, gensym("pd~"), A_GIMME, 0); class_addanything(pd_tilde_class, pd_tilde_anything); post("pd~ version 0.3"); } #endif /* -------------------------- MSP glue ------------------------- */ #ifdef MSP #define LOTS 10000 static void pd_tilde_tick(t_pd_tilde *x) { int messstart = 0, i, n = 0; t_atom vec[LOTS]; long z1 = 0, z2 = 0; void *b; if (!x->x_msgbuf) return; b = binbuf_new(); binbuf_text(b, &x->x_msgbuf, x->x_infill); /* binbuf_print(b); */ while (!binbuf_getatom(b, &z1, &z2, vec+n)) if (++n >= LOTS) break; for (i = 0; i < n; i++) { if (vec[i].a_type == A_SEMI) { if (i > messstart + 1) { void *whom; if (vec[messstart].a_type == A_SYM) outlet_anything(x->x_outlet1, vec[messstart].a_w.w_sym, i-messstart-1, vec+(messstart+1)); else if (vec[messstart].a_type == A_FLOAT && i == messstart+1) outlet_float(x->x_outlet1, vec[messstart].a_w.w_float); else if (vec[messstart].a_type == A_LONG && i == messstart+1) outlet_int(x->x_outlet1, vec[messstart].a_w.w_long); else outlet_list(x->x_outlet1, gensym("list"), i-messstart, vec+(messstart)); } messstart = i+1; } } binbuf_free(b); x->x_infill = 0; } static void pd_tilde_anything(t_pd_tilde *x, t_symbol *s, long ac, t_atom *av) { char msgbuf[MAXPDSTRING], *sp, *ep = msgbuf+MAXPDSTRING; if (!x->x_outfd) return; msgbuf[0] = 0; strncpy(msgbuf, s->s_name, MAXPDSTRING); msgbuf[MAXPDSTRING-1] = 0; sp = msgbuf + strlen(msgbuf); while (ac--) { if (sp < ep-1) sp[0] = ' ', sp[1] = 0, sp++; if (sp < ep - 80) { if (av->a_type == A_SYM && strlen(av->a_w.w_sym->s_name) < ep - sp-20) strcpy(sp, av->a_w.w_sym->s_name); else if (av->a_type == A_LONG) sprintf(sp, "%ld" ,av->a_w.w_long); else if (av->a_type == A_FLOAT) sprintf(sp, "%g" ,av->a_w.w_float); } sp += strlen(sp); av++; } fprintf(x->x_outfd, "%s;\n", msgbuf); } int main() { t_class *c; c = class_new("pd_tilde~", (method)pd_tilde_new, (method)pd_tilde_free, sizeof(t_pd_tilde), (method)0L, A_GIMME, 0); class_addmethod(c, (method)pd_tilde_dsp, "dsp", A_CANT, 0); class_addmethod(c, (method)pd_tilde_assist, "assist", A_CANT, 0); class_addmethod(c, (method)pd_tilde_pdtilde, "pd~", A_GIMME, 0); class_addmethod(c, (method)pd_tilde_anything, "anything", A_GIMME, 0); class_dspinit(c); class_register(CLASS_BOX, c); pd_tilde_class = c; post("pd~ version 0.3"); return (0); } static void *pd_tilde_new(t_symbol *s, long ac, t_atom *av) { int ninsig = 2, noutsig = 2, fifo = 5, j; t_float sr = sys_getsr(); t_symbol *pddir = gensym("."), *scheddir = gensym("."); t_pd_tilde *x; if (x = (t_pd_tilde *)object_alloc(pd_tilde_class)) { while (ac > 0 && av[0].a_type == A_SYM) { char *flag = av[0].a_w.w_sym->s_name; if (!strcmp(flag, "-sr") && ac > 1) { sr = (av[1].a_type == A_FLOAT ? av[1].a_w.w_float : (av[1].a_type == A_LONG ? av[1].a_w.w_long : 0)); ac -= 2; av += 2; } else if (!strcmp(flag, "-ninsig") && ac > 1) { ninsig = (av[1].a_type == A_FLOAT ? av[1].a_w.w_float : (av[1].a_type == A_LONG ? av[1].a_w.w_long : 0)); ac -= 2; av += 2; } else if (!strcmp(flag, "-noutsig") && ac > 1) { noutsig = (av[1].a_type == A_FLOAT ? av[1].a_w.w_float : (av[1].a_type == A_LONG ? av[1].a_w.w_long : 0)); ac -= 2; av += 2; } else if (!strcmp(flag, "-fifo") && ac > 1) { fifo = (av[1].a_type == A_FLOAT ? av[1].a_w.w_float : (av[1].a_type == A_LONG ? av[1].a_w.w_long : 0)); ac -= 2; av += 2; } else if (!strcmp(flag, "-pddir") && ac > 1) { pddir = (av[1].a_type == A_SYM ? av[1].a_w.w_sym : gensym(".")); ac -= 2; av += 2; } else if (!strcmp(flag, "-scheddir") && ac > 1) { scheddir = (av[1].a_type == A_SYM ? av[1].a_w.w_sym : gensym(".")); ac -= 2; av += 2; } else break; } if (ac) post("pd~: warning: ignoring extra arguments"); dsp_setup((t_pxobject *)x, ninsig); x->x_outlet1 = outlet_new(&x->x_obj, 0); for (j = 0; j < noutsig; j++) outlet_new((t_pxobject *)x, "signal"); x->x_clock = clock_new(x, (method)pd_tilde_tick); x->x_insig = (t_sample **)getbytes(ninsig * sizeof(*x->x_insig)); x->x_outsig = (t_sample **)getbytes(noutsig * sizeof(*x->x_outsig)); x->x_ninsig = ninsig; x->x_noutsig = noutsig; x->x_fifo = fifo; x->x_sr = sr; x->x_pddir = pddir; x->x_schedlibdir = scheddir; x->x_infd = 0; x->x_outfd = 0; x->x_outfd = 0; x->x_childpid = -1; x->x_msgbuf = 0; } return (x); } void pd_tilde_assist(t_pd_tilde *x, void *b, long m, long a, char *s) { } #endif /* MSP */ pd-0.46-7/extra/pd~/makefile0000664000175000017500000000065312374245151014030 0ustar mspmspNAME=pd~ CSYM=pd_tilde include ../makefile.subdir pd_linux: pdsched.pd_linux pd_nt: pdsched.dll d_fat: pdsched.d_fat d_ppc: pdsched.d_ppc pdsched.pd_linux: pdsched.c $(CC) $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c $(CC) -shared -o $*.pd_linux $*.o -lc -lm rm -f $*.o pdsched.dll: pdsched.c $(MSCC) $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c $(MSLN) /nologo /dll /export:pd_extern_sched $*.obj $(PDNTLIB) rm -f $*.obj pd-0.46-7/extra/pd~/notes.txt0000664000175000017500000000024612160204055014206 0ustar mspmsppd -schedlib `pwd`/pdsched dolist: pd~ to delay starting subproc until asked figure out about setting nchannels from command line fix maximum nchannels in and out pd-0.46-7/extra/hilbert~.pd0000664000175000017500000000161012160204055013664 0ustar mspmsp#N canvas 269 0 593 306 12; #X obj 105 92 biquad~ 0.83774 -0.06338 0.06338 -0.83774 1; #X obj 105 66 biquad~ 1.94632 -0.94657 0.94657 -1.94632 1; #X obj 86 149 biquad~ -0.02569 0.260502 -0.260502 0.02569 1; #X obj 86 175 biquad~ 1.8685 -0.870686 0.870686 -1.8685 1; #X obj 86 39 inlet~; #X obj 105 121 outlet~; #X obj 86 202 outlet~; #X text 34 232 This is a pair of 4th-order all-pass filters whose outputs somehow manage to be about 90 degrees out of phase from each other. Both have different phases from the original. Adapted from a 4X patch by Emmanuel Favreau \, circa 1982; #X obj 502 39 inlet; #X text 461 13 bang to clear; #X text 80 16 signal in; #X msg 502 112 clear; #X connect 0 0 5 0; #X connect 1 0 0 0; #X connect 2 0 3 0; #X connect 3 0 6 0; #X connect 4 0 1 0; #X connect 4 0 2 0; #X connect 8 0 11 0; #X connect 11 0 1 0; #X connect 11 0 0 0; #X connect 11 0 2 0; #X connect 11 0 3 0; pd-0.46-7/extra/rev2~.pd0000664000175000017500000001307012374250720013123 0ustar mspmsp#N canvas 327 141 850 684 12; #X obj 161 497 +~; #X obj 520 105 inlet; #X obj 184 407 *~; #X obj 486 412 *~; #X obj 285 412 *~; #X obj 387 412 *~; #X obj 443 546 -~; #X obj 364 545 -~; #X obj 239 537 +~; #X obj 161 534 +~; #X obj 162 444 +~; #X obj 262 440 +~; #X obj 464 501 -~; #X obj 387 499 +~; #X obj 239 500 -~; #X obj 452 105 inlet; #X obj 609 429 line~; #X obj 509 374 line~; #X obj 16 121 delread~ \$0-del1 58.6435; #X obj 94 143 delread~ \$0-del2 69.4325; #X obj 176 165 delread~ \$0-del3 74.5234; #X obj 258 189 delread~ \$0-del4 86.1244; #X obj 530 500 *~; #X obj 599 501 *~; #X obj 161 641 delwrite~ \$0-del1 58.6435; #X obj 240 617 delwrite~ \$0-del2 69.4325; #X obj 365 595 delwrite~ \$0-del3 74.5234; #X obj 444 573 delwrite~ \$0-del4 86.1244; #X obj 609 357 dbtorms; #X obj 609 403 pack 0 30; #X obj 520 211 pack 0 50; #X obj 9 390 inlet~; #X obj 530 525 outlet~; #X obj 599 525 outlet~; #X obj 520 187 / 200; #X obj 520 162 clip 0 100; #X obj 52 236 lop~; #X obj 452 137 f \$1; #X obj 520 138 f \$2; #X obj 625 143 f \$3; #X obj 696 143 f \$4; #X obj 367 106 loadbang; #X obj 667 500 *~; #X obj 735 501 *~; #X obj 667 525 outlet~; #X obj 735 525 outlet~; #X obj 625 167 moses 1; #X msg 631 193 3000; #X obj 705 193 clip 0 100; #N canvas 341 84 355 597 early-reflect 1; #X obj 84 119 -~; #X obj 49 119 +~; #X obj 50 195 +~; #X obj 85 196 -~; #X obj 84 275 -~; #X obj 49 274 +~; #X obj 82 349 -~; #X obj 48 350 +~; #X obj 83 428 -~; #X obj 49 428 +~; #X obj 65 7 inlet~; #X obj 49 508 outlet~; #X obj 119 507 outlet~; #X obj 110 66 delwrite~ \$0-ref1 43.5337; #X obj 110 90 delread~ \$0-ref1 43.5337; #X obj 107 145 delwrite~ \$0-ref2 25.796; #X obj 107 169 delread~ \$0-ref2 25.796; #X obj 106 223 delwrite~ \$0-ref3 19.392; #X obj 106 247 delread~ \$0-ref3 19.392; #X obj 102 300 delwrite~ \$0-ref4 16.364; #X obj 102 324 delread~ \$0-ref4 16.364; #X obj 119 452 delwrite~ \$0-ref6 4.2546; #X obj 119 477 delread~ \$0-ref6 4.2546; #X obj 106 376 delwrite~ \$0-ref5 7.645; #X obj 106 400 delread~ \$0-ref5 7.645; #X connect 0 0 15 0; #X connect 1 0 3 0; #X connect 1 0 2 0; #X connect 2 0 5 0; #X connect 2 0 4 0; #X connect 3 0 17 0; #X connect 4 0 19 0; #X connect 5 0 7 0; #X connect 5 0 6 0; #X connect 6 0 23 0; #X connect 7 0 9 0; #X connect 7 0 8 0; #X connect 8 0 21 0; #X connect 9 0 11 0; #X connect 10 0 1 0; #X connect 10 0 0 0; #X connect 10 0 13 0; #X connect 14 0 1 1; #X connect 14 0 0 1; #X connect 16 0 2 1; #X connect 16 0 3 1; #X connect 18 0 5 1; #X connect 18 0 4 1; #X connect 20 0 7 1; #X connect 20 0 6 1; #X connect 22 0 12 0; #X connect 24 0 9 1; #X connect 24 0 8 1; #X restore 9 416 pd early-reflect; #X obj 618 216 f; #X obj 618 105 inlet; #X obj 696 109 inlet; #X obj 705 216 f; #X obj 705 239 * 0.01; #X obj 705 263 pack 0 50; #X obj 705 287 line~; #X obj 29 269 -~; #X obj 28 300 *~; #X obj 16 331 +~; #X obj 132 240 lop~; #X obj 106 274 -~; #X obj 105 309 *~; #X obj 95 333 +~; #X obj 214 245 lop~; #X obj 188 273 -~; #X obj 187 314 *~; #X obj 176 339 +~; #X obj 308 249 lop~; #X obj 281 274 -~; #X obj 281 318 *~; #X obj 258 342 +~; #X obj 609 379 * 0.125; #X text 403 10 control inlets:; #X text 9 9 rev2 - simple \, cheap reverberator with; #X text 400 29 1: output level \, dB \, 0-100; #X text 8 30 one signal inlet and four signal outlets.; #X text 399 79 4: high frequency damping \, 0-100; #X text 400 62 3: crossover frequency in Hz. (3000 default); #X text 400 45 2: liveness \, 0-100 \, usually between 85 and 100; #X connect 0 0 9 0; #X connect 0 0 7 0; #X connect 1 0 38 0; #X connect 2 0 10 1; #X connect 3 0 12 1; #X connect 3 0 13 1; #X connect 3 0 43 0; #X connect 4 0 11 1; #X connect 5 0 13 0; #X connect 5 0 12 0; #X connect 5 0 42 0; #X connect 6 0 27 0; #X connect 7 0 26 0; #X connect 8 0 25 0; #X connect 9 0 24 0; #X connect 10 0 14 0; #X connect 10 0 0 0; #X connect 10 0 22 0; #X connect 11 0 0 1; #X connect 11 0 14 1; #X connect 11 0 23 0; #X connect 12 0 8 1; #X connect 12 0 6 1; #X connect 13 0 9 1; #X connect 13 0 7 1; #X connect 14 0 8 0; #X connect 14 0 6 0; #X connect 15 0 37 0; #X connect 16 0 22 1; #X connect 16 0 23 1; #X connect 16 0 42 1; #X connect 16 0 43 1; #X connect 17 0 4 1; #X connect 17 0 2 1; #X connect 17 0 5 1; #X connect 17 0 3 1; #X connect 18 0 36 0; #X connect 18 0 57 1; #X connect 18 0 59 0; #X connect 19 0 60 0; #X connect 19 0 61 1; #X connect 19 0 63 0; #X connect 20 0 67 0; #X connect 20 0 64 0; #X connect 20 0 65 1; #X connect 21 0 71 0; #X connect 21 0 69 1; #X connect 21 0 68 0; #X connect 22 0 32 0; #X connect 23 0 33 0; #X connect 28 0 72 0; #X connect 29 0 16 0; #X connect 30 0 17 0; #X connect 31 0 49 0; #X connect 34 0 30 0; #X connect 35 0 34 0; #X connect 36 0 57 0; #X connect 37 0 28 0; #X connect 38 0 35 0; #X connect 39 0 46 0; #X connect 40 0 48 0; #X connect 41 0 37 0; #X connect 41 0 38 0; #X connect 41 0 39 0; #X connect 41 0 40 0; #X connect 42 0 44 0; #X connect 43 0 45 0; #X connect 46 0 47 0; #X connect 46 1 50 0; #X connect 47 0 50 0; #X connect 48 0 53 0; #X connect 49 0 10 0; #X connect 49 1 11 0; #X connect 50 0 36 1; #X connect 50 0 60 1; #X connect 50 0 64 1; #X connect 50 0 68 1; #X connect 51 0 50 0; #X connect 52 0 40 0; #X connect 53 0 54 0; #X connect 54 0 55 0; #X connect 55 0 56 0; #X connect 56 0 58 1; #X connect 56 0 62 1; #X connect 56 0 66 1; #X connect 56 0 70 1; #X connect 57 0 58 0; #X connect 58 0 59 1; #X connect 59 0 2 0; #X connect 60 0 61 0; #X connect 61 0 62 0; #X connect 62 0 63 1; #X connect 63 0 4 0; #X connect 64 0 65 0; #X connect 65 0 66 0; #X connect 66 0 67 1; #X connect 67 0 5 0; #X connect 68 0 69 0; #X connect 69 0 70 0; #X connect 70 0 71 1; #X connect 71 0 3 0; #X connect 72 0 29 0; pd-0.46-7/extra/rev3~-help.pd0000664000175000017500000000711312425324111014044 0ustar mspmsp#N canvas 321 265 765 380 12; #X floatatom 99 212 0 0 120 0 - - -; #X floatatom 105 340 0 0 120 0 - - -; #N canvas 0 50 539 448 tests 0; #X obj 67 33 inlet; #X obj 309 189 inlet; #X obj 235 207 line~; #X obj 235 230 cos~; #X obj 235 68 loadbang; #X msg 235 91 -0.25; #X obj 235 276 *~; #X obj 186 309 hip~ 5; #X floatatom 308 218 0 0 0 0 - - -; #X obj 308 264 osc~ 440; #X obj 308 241 mtof; #X obj 235 253 *~ 0.1; #X obj 308 299 *~; #X obj 326 325 *~; #X obj 292 330 *~; #X msg 279 150 -0.25 \, 0.25 \$1; #X obj 41 148 biquad~ 0 0 1 -1 0; #X obj 63 70 t b; #X obj 104 72 del 3; #X obj 57 101 1; #X obj 96 101 0; #X obj 41 355 outlet~; #X obj 279 126 inlet; #X obj 51 192 *~; #X connect 0 0 17 0; #X connect 1 0 8 0; #X connect 2 0 3 0; #X connect 3 0 11 0; #X connect 4 0 5 0; #X connect 5 0 2 0; #X connect 6 0 7 0; #X connect 7 0 21 0; #X connect 8 0 10 0; #X connect 9 0 6 1; #X connect 9 0 12 0; #X connect 9 0 12 1; #X connect 9 0 13 0; #X connect 10 0 9 0; #X connect 11 0 6 0; #X connect 12 0 13 1; #X connect 12 0 6 1; #X connect 12 0 14 0; #X connect 12 0 14 1; #X connect 13 0 6 1; #X connect 14 0 6 1; #X connect 15 0 2 0; #X connect 16 0 23 0; #X connect 17 0 18 0; #X connect 17 0 19 0; #X connect 18 0 20 0; #X connect 19 0 16 0; #X connect 19 0 23 1; #X connect 20 0 16 0; #X connect 20 0 23 1; #X connect 22 0 15 0; #X connect 23 0 21 0; #X restore 16 171 pd tests; #X msg 55 52 10; #X msg 53 79 20; #X msg 52 107 100; #X msg 51 132 500; #X obj 16 32 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X text 36 26 impulse; #N canvas 0 50 450 300 output 0; #X obj 54 202 dac~; #X obj 132 119 pack 0 100; #X obj 132 142 line~; #X obj 54 165 *~; #X obj 132 97 dbtorms; #X obj 33 42 inlet~; #X obj 177 42 inlet; #X obj 177 74 clip 0 120; #X msg 257 133 \; pd dsp 1; #X obj 98 42 inlet~; #X obj 94 168 *~; #X connect 1 0 2 0; #X connect 2 0 3 1; #X connect 2 0 10 1; #X connect 3 0 0 0; #X connect 4 0 1 0; #X connect 5 0 3 0; #X connect 6 0 7 0; #X connect 6 0 8 0; #X connect 7 0 4 0; #X connect 9 0 10 0; #X connect 10 0 0 1; #X restore 17 340 pd output; #X floatatom 96 144 0 0 0 0 - - -; #X text 135 113 tone; #X text 134 129 pitch; #X text 140 212 level \, dB; #X floatatom 134 234 0 0 100 0 - - -; #X text 175 234 liveness \, 0-100; #X floatatom 169 258 4 0 5000 0 - - -, f 4; #X floatatom 204 281 0 0 100 0 - - -; #X text 217 256 crossover frequency \, Hz.; #X text 240 283 HF damping \, percent; #X text 140 341 output level \, dB; #X text 94 52 tone; #X text 95 69 bursts; #X text 131 147 (60 for; #X text 114 167 middle C); #X obj 29 307 rev3~ 100 90 3000 20; #X text 263 4 REV3~ - hard-core \, 2-in \, 4-out reverberator; #X text 236 56 The creation arguments (level \, liveness \, crossover frequency \, HF damping) may also be supplied in four inlets as shown. The "liveness" (actually the internal feedback percentage) should be 100 for infinite reverb \, 90 for longish \, and 80 for short. The crossover frequency and HF damping work together: at frequencies above crossover \, the feedback is diminished by the "damping" as a percentage. So zero HF damping means equal reverb time at all frequencies \, and 100% damping means almost nothing above the crossover frequency gets through.; #X text 236 29 (A more expensive \, presumably better \, one than rev2~.) ; #X text 470 352 modified for Pd version 0.37-1; #X connect 0 0 25 2; #X connect 1 0 9 2; #X connect 2 0 9 0; #X connect 2 0 25 0; #X connect 3 0 2 1; #X connect 4 0 2 1; #X connect 5 0 2 1; #X connect 6 0 2 1; #X connect 7 0 2 0; #X connect 10 0 2 2; #X connect 14 0 25 3; #X connect 16 0 25 4; #X connect 17 0 25 5; #X connect 25 0 9 0; #X connect 25 1 9 1; pd-0.46-7/extra/rev3~.pd0000664000175000017500000003053212516575177013144 0ustar mspmsp#N canvas 325 130 810 570 12; #X obj 520 105 inlet; #X obj 452 105 inlet; #X obj 370 335 line~; #X obj 232 394 *~; #X obj 301 395 *~; #X obj 370 284 dbtorms; #X obj 370 309 pack 0 30; #X obj 520 211 pack 0 50; #X obj 232 419 outlet~; #X obj 301 419 outlet~; #X obj 520 162 clip 0 100; #X obj 452 137 f \$1; #X obj 520 138 f \$2; #X obj 625 143 f \$3; #X obj 696 143 f \$4; #X obj 367 106 loadbang; #X obj 369 394 *~; #X obj 437 395 *~; #X obj 369 419 outlet~; #X obj 437 419 outlet~; #X obj 625 167 moses 1; #X msg 631 193 3000; #X obj 705 193 clip 0 100; #X obj 616 218 f; #X obj 618 105 inlet; #X obj 696 109 inlet; #X obj 705 216 f; #X obj 705 239 * 0.01; #X obj 705 263 pack 0 50; #X text 403 10 control inlets:; #X text 400 29 1: output level \, dB \, 0-100; #X text 399 79 4: high frequency damping \, 0-100; #X text 400 62 3: crossover frequency in Hz. (3000 default); #X text 400 45 2: liveness \, 0-100 \, usually between 85 and 100; #X obj 616 242 s \$0-lop; #N canvas 2 141 918 880 doit 0; #X obj 218 386 *~; #X obj 341 396 *~; #X obj 267 389 *~; #X obj 305 392 *~; #X obj 28 175 lop~; #X obj 27 204 -~; #X obj 27 291 *~; #X obj 16 319 +~; #X obj 75 182 lop~; #X obj 76 214 -~; #X obj 77 294 *~; #X obj 67 318 +~; #X obj 124 187 lop~; #X obj 124 214 -~; #X obj 125 297 *~; #X obj 116 322 +~; #X obj 176 191 lop~; #X obj 175 218 -~; #X obj 175 301 *~; #X obj 168 326 +~; #X obj 15 372 *~; #X obj 169 383 *~; #X obj 67 376 *~; #X obj 115 380 *~; #X obj 207 160 r \$0-lop; #X obj 183 246 r \$0-damp; #X obj 183 271 line~; #X obj 17 14 delread~ \$0-del1 10; #X obj 117 56 delread~ \$0-del3 13.4567; #X obj 68 35 delread~ \$0-del2 11.6356; #X obj 171 77 delread~ \$0-del4 16.7345; #X obj 524 407 *~; #X obj 631 409 *~; #X obj 560 408 *~; #X obj 595 409 *~; #X obj 377 399 *~; #X obj 488 406 *~; #X obj 414 402 *~; #X obj 451 405 *~; #X obj 654 354 line~; #X obj 708 387 r \$0-fb; #X obj 218 100 delread~ \$0-del5 20.1862; #X obj 267 121 delread~ \$0-del6 25.7417; #X obj 304 142 delread~ \$0-del7 31.4693; #X obj 341 163 delread~ \$0-del8 38.2944; #X obj 376 184 delread~ \$0-del9 46.6838; #X obj 414 205 delread~ \$0-del10 55.4567; #X obj 488 247 delread~ \$0-del12 76.8243; #X obj 524 268 delread~ \$0-del13 88.5623; #X obj 561 289 delread~ \$0-del14 101.278; #X obj 595 310 delread~ \$0-del15 115.397; #X obj 632 331 delread~ \$0-del16 130.502; #X obj 25 346 inlet~; #X obj 87 346 inlet~; #X obj 69 440 +~; #X obj 105 440 -~; #X obj 141 440 +~; #X obj 177 440 -~; #X obj 214 440 +~; #X obj 250 440 -~; #X obj 286 440 +~; #X obj 322 440 -~; #X obj 359 440 +~; #X obj 395 440 -~; #X obj 431 440 +~; #X obj 467 440 -~; #X obj 504 440 +~; #X obj 540 440 -~; #X obj 576 440 +~; #X obj 612 440 -~; #X obj 69 474 +~; #X obj 177 474 -~; #X obj 105 474 +~; #X obj 141 474 -~; #X obj 214 474 +~; #X obj 322 474 -~; #X obj 250 474 +~; #X obj 286 474 -~; #X obj 359 474 +~; #X obj 467 474 -~; #X obj 395 474 +~; #X obj 431 474 -~; #X obj 504 474 +~; #X obj 612 474 -~; #X obj 540 474 +~; #X obj 576 474 -~; #X obj 69 518 +~; #X obj 105 518 +~; #X obj 322 518 -~; #X obj 286 518 -~; #X obj 141 518 +~; #X obj 177 518 +~; #X obj 214 518 -~; #X obj 250 518 -~; #X obj 360 518 +~; #X obj 396 518 +~; #X obj 613 518 -~; #X obj 577 518 -~; #X obj 432 518 +~; #X obj 468 518 +~; #X obj 505 518 -~; #X obj 541 518 -~; #X obj 70 575 +~; #X obj 106 575 +~; #X obj 469 575 -~; #X obj 433 575 -~; #X obj 142 575 +~; #X obj 178 575 +~; #X obj 361 575 -~; #X obj 397 575 -~; #X obj 215 575 +~; #X obj 251 575 +~; #X obj 287 575 +~; #X obj 323 575 +~; #X obj 614 575 -~; #X obj 578 575 -~; #X obj 506 575 -~; #X obj 542 575 -~; #X obj 628 606 outlet~; #X obj 698 606 outlet~; #X obj 768 607 outlet~; #X obj 838 607 outlet~; #X obj 451 226 delread~ \$0-del11 65.1755; #X obj 614 629 delwrite~ \$0-del16 130.502; #X obj 361 776 delwrite~ \$0-del9 46.6838; #X obj 398 755 delwrite~ \$0-del10 55.4567; #X obj 434 734 delwrite~ \$0-del11 65.1755; #X obj 470 713 delwrite~ \$0-del12 76.8243; #X obj 506 692 delwrite~ \$0-del13 88.5623; #X obj 542 671 delwrite~ \$0-del14 101.278; #X obj 579 650 delwrite~ \$0-del15 115.397; #X obj 323 606 delwrite~ \$0-del8 38.2944; #X obj 287 628 delwrite~ \$0-del7 31.4693; #X obj 252 650 delwrite~ \$0-del6 25.7417; #X obj 215 672 delwrite~ \$0-del5 20.1862; #X obj 71 761 delwrite~ \$0-del1 10; #X obj 106 737 delwrite~ \$0-del2 11.6356; #X obj 141 715 delwrite~ \$0-del3 13.4567; #X obj 179 693 delwrite~ \$0-del4 16.7345; #X connect 0 0 58 0; #X connect 0 0 59 0; #X connect 1 0 60 1; #X connect 1 0 61 1; #X connect 2 0 58 1; #X connect 2 0 59 1; #X connect 3 0 60 0; #X connect 3 0 61 0; #X connect 4 0 5 0; #X connect 5 0 6 0; #X connect 6 0 7 1; #X connect 7 0 20 0; #X connect 8 0 9 0; #X connect 9 0 10 0; #X connect 10 0 11 1; #X connect 11 0 22 0; #X connect 12 0 13 0; #X connect 13 0 14 0; #X connect 14 0 15 1; #X connect 15 0 23 0; #X connect 16 0 17 0; #X connect 17 0 18 0; #X connect 18 0 19 1; #X connect 19 0 21 0; #X connect 20 0 54 0; #X connect 20 0 55 0; #X connect 21 0 56 1; #X connect 21 0 57 1; #X connect 22 0 55 1; #X connect 22 0 54 1; #X connect 23 0 56 0; #X connect 23 0 57 0; #X connect 24 0 16 1; #X connect 24 0 12 1; #X connect 24 0 8 1; #X connect 24 0 4 1; #X connect 25 0 26 0; #X connect 26 0 18 1; #X connect 26 0 14 1; #X connect 26 0 10 1; #X connect 26 0 6 1; #X connect 27 0 4 0; #X connect 27 0 5 1; #X connect 27 0 7 0; #X connect 28 0 15 0; #X connect 28 0 12 0; #X connect 28 0 13 1; #X connect 29 0 8 0; #X connect 29 0 9 1; #X connect 29 0 11 0; #X connect 30 0 19 0; #X connect 30 0 17 1; #X connect 30 0 16 0; #X connect 31 0 66 0; #X connect 31 0 67 0; #X connect 32 0 68 1; #X connect 32 0 69 1; #X connect 33 0 66 1; #X connect 33 0 67 1; #X connect 34 0 68 0; #X connect 34 0 69 0; #X connect 35 0 62 0; #X connect 35 0 63 0; #X connect 36 0 64 1; #X connect 36 0 65 1; #X connect 37 0 62 1; #X connect 37 0 63 1; #X connect 38 0 64 0; #X connect 38 0 65 0; #X connect 39 0 2 1; #X connect 39 0 0 1; #X connect 39 0 3 1; #X connect 39 0 1 1; #X connect 39 0 21 1; #X connect 39 0 23 1; #X connect 39 0 22 1; #X connect 39 0 20 1; #X connect 39 0 35 1; #X connect 39 0 38 1; #X connect 39 0 36 1; #X connect 39 0 31 1; #X connect 39 0 33 1; #X connect 39 0 34 1; #X connect 39 0 32 1; #X connect 39 0 37 1; #X connect 40 0 39 0; #X connect 41 0 0 0; #X connect 42 0 2 0; #X connect 43 0 3 0; #X connect 44 0 1 0; #X connect 45 0 35 0; #X connect 46 0 37 0; #X connect 47 0 36 0; #X connect 48 0 31 0; #X connect 49 0 33 0; #X connect 50 0 34 0; #X connect 51 0 32 0; #X connect 52 0 20 0; #X connect 53 0 22 0; #X connect 54 0 70 0; #X connect 54 0 73 0; #X connect 55 0 72 0; #X connect 55 0 71 0; #X connect 56 0 70 1; #X connect 56 0 73 1; #X connect 57 0 72 1; #X connect 57 0 71 1; #X connect 58 0 74 0; #X connect 58 0 77 0; #X connect 59 0 76 0; #X connect 59 0 75 0; #X connect 60 0 74 1; #X connect 60 0 77 1; #X connect 61 0 76 1; #X connect 61 0 75 1; #X connect 62 0 78 0; #X connect 62 0 81 0; #X connect 63 0 80 0; #X connect 63 0 79 0; #X connect 64 0 78 1; #X connect 64 0 81 1; #X connect 65 0 80 1; #X connect 65 0 79 1; #X connect 66 0 82 0; #X connect 66 0 85 0; #X connect 67 0 84 0; #X connect 67 0 83 0; #X connect 68 0 82 1; #X connect 68 0 85 1; #X connect 69 0 84 1; #X connect 69 0 83 1; #X connect 70 0 86 0; #X connect 70 0 92 0; #X connect 71 0 91 0; #X connect 71 0 88 0; #X connect 72 0 87 0; #X connect 72 0 93 0; #X connect 73 0 90 0; #X connect 73 0 89 0; #X connect 74 0 86 1; #X connect 74 0 92 1; #X connect 75 0 91 1; #X connect 75 0 88 1; #X connect 76 0 87 1; #X connect 76 0 93 1; #X connect 77 0 90 1; #X connect 77 0 89 1; #X connect 78 0 94 0; #X connect 78 0 100 0; #X connect 79 0 99 0; #X connect 79 0 96 0; #X connect 80 0 95 0; #X connect 80 0 101 0; #X connect 81 0 98 0; #X connect 81 0 97 0; #X connect 82 0 94 1; #X connect 82 0 100 1; #X connect 83 0 99 1; #X connect 83 0 96 1; #X connect 84 0 95 1; #X connect 84 0 101 1; #X connect 85 0 98 1; #X connect 85 0 97 1; #X connect 86 0 102 0; #X connect 86 0 108 0; #X connect 87 0 103 0; #X connect 87 0 109 0; #X connect 88 0 113 0; #X connect 88 0 114 0; #X connect 89 0 112 0; #X connect 89 0 115 0; #X connect 90 0 106 0; #X connect 90 0 105 0; #X connect 91 0 107 0; #X connect 91 0 104 0; #X connect 92 0 110 0; #X connect 92 0 116 0; #X connect 93 0 111 0; #X connect 93 0 117 0; #X connect 94 0 108 1; #X connect 94 0 102 1; #X connect 95 0 109 1; #X connect 95 0 103 1; #X connect 96 0 114 1; #X connect 96 0 113 1; #X connect 97 0 115 1; #X connect 97 0 112 1; #X connect 98 0 105 1; #X connect 98 0 106 1; #X connect 99 0 104 1; #X connect 99 0 107 1; #X connect 100 0 116 1; #X connect 100 0 110 1; #X connect 101 0 117 1; #X connect 101 0 111 1; #X connect 102 0 135 0; #X connect 103 0 136 0; #X connect 104 0 127 0; #X connect 105 0 126 0; #X connect 106 0 137 0; #X connect 107 0 138 0; #X connect 108 0 124 0; #X connect 109 0 125 0; #X connect 110 0 134 0; #X connect 111 0 133 0; #X connect 112 0 132 0; #X connect 113 0 131 0; #X connect 114 0 121 0; #X connect 114 0 123 0; #X connect 115 0 120 0; #X connect 115 0 130 0; #X connect 116 0 118 0; #X connect 116 0 128 0; #X connect 117 0 119 0; #X connect 117 0 129 0; #X connect 122 0 38 0; #X restore 164 317 pd doit; #X obj 164 242 inlet~; #X obj 221 242 inlet~; #X obj 520 241 s \$0-fb; #X obj 705 290 s \$0-damp; #X text 57 490 rev3 - 16-delay reverberator. Like rev2~ but presumably higher-quality and takes two audio inputs.; #X obj 520 187 / 400; #N canvas 2 52 400 576 early 0; #X obj 84 10 inlet~; #X obj 159 10 inlet~; #N canvas 19 394 468 181 write1 0; #X obj 83 25 inlet~; #X obj 116 66 delwrite~ \$0-early1 1.42763; #X obj 84 99 outlet~; #X connect 0 0 1 0; #X connect 0 0 2 0; #X restore 160 67 pd write1; #N canvas 323 263 472 159 read1 0; #X obj 77 12 inlet~; #X obj 78 56 delread~ \$0-early1 1.42763; #X obj 78 81 outlet~; #X connect 1 0 2 0; #X restore 160 92 pd read1; #X obj 84 121 +~; #X obj 138 122 -~; #X obj 82 205 +~; #X obj 136 206 -~; #X obj 84 289 +~; #X obj 138 290 -~; #N canvas 20 395 468 181 write2 0; #X obj 83 25 inlet~; #X obj 84 99 outlet~; #X obj 116 65 delwrite~ \$0-early2 3.23873; #X connect 0 0 1 0; #X connect 0 0 2 0; #X restore 158 151 pd write2; #N canvas 322 262 472 159 read2 0; #X obj 77 12 inlet~; #X obj 78 81 outlet~; #X obj 78 56 delread~ \$0-early2 3.23873; #X connect 2 0 1 0; #X restore 158 176 pd read2; #N canvas 19 394 468 181 write3 0; #X obj 83 25 inlet~; #X obj 84 99 outlet~; #X obj 116 66 delwrite~ \$0-early3 5.2345; #X connect 0 0 1 0; #X connect 0 0 2 0; #X restore 160 236 pd write3; #N canvas 322 262 472 159 read3 0; #X obj 77 12 inlet~; #X obj 78 81 outlet~; #X obj 78 56 delread~ \$0-early3 5.2345; #X connect 2 0 1 0; #X restore 160 260 pd read3; #N canvas 20 395 468 181 write4 0; #X obj 83 25 inlet~; #X obj 84 99 outlet~; #X obj 117 66 delwrite~ \$0-early4 7.82312; #X connect 0 0 1 0; #X connect 0 0 2 0; #X restore 153 320 pd write4; #N canvas 321 261 472 159 read4 0; #X obj 77 12 inlet~; #X obj 78 81 outlet~; #X obj 78 56 delread~ \$0-early4 7.82312; #X connect 2 0 1 0; #X restore 153 345 pd read4; #X obj 84 406 outlet~; #X obj 174 409 outlet~; #X obj 84 381 *~ 0.3535; #X obj 173 384 *~ 0.3535; #X connect 0 0 4 0; #X connect 0 0 5 0; #X connect 1 0 2 0; #X connect 2 0 3 0; #X connect 3 0 5 1; #X connect 3 0 4 1; #X connect 4 0 6 0; #X connect 4 0 7 0; #X connect 5 0 10 0; #X connect 6 0 8 0; #X connect 6 0 9 0; #X connect 7 0 12 0; #X connect 8 0 18 0; #X connect 9 0 14 0; #X connect 10 0 11 0; #X connect 11 0 7 1; #X connect 11 0 6 1; #X connect 12 0 13 0; #X connect 13 0 9 1; #X connect 13 0 8 1; #X connect 14 0 15 0; #X connect 15 0 19 0; #X connect 18 0 16 0; #X connect 19 0 17 0; #X restore 163 279 pd early; #X connect 0 0 12 0; #X connect 1 0 11 0; #X connect 2 0 3 1; #X connect 2 0 4 1; #X connect 2 0 16 1; #X connect 2 0 17 1; #X connect 3 0 8 0; #X connect 4 0 9 0; #X connect 5 0 6 0; #X connect 6 0 2 0; #X connect 7 0 38 0; #X connect 10 0 41 0; #X connect 11 0 5 0; #X connect 12 0 10 0; #X connect 13 0 20 0; #X connect 14 0 22 0; #X connect 15 0 11 0; #X connect 15 0 12 0; #X connect 15 0 13 0; #X connect 15 0 14 0; #X connect 16 0 18 0; #X connect 17 0 19 0; #X connect 20 0 21 0; #X connect 20 1 23 0; #X connect 21 0 23 0; #X connect 22 0 26 0; #X connect 23 0 34 0; #X connect 24 0 23 0; #X connect 25 0 14 0; #X connect 26 0 27 0; #X connect 27 0 28 0; #X connect 28 0 39 0; #X connect 35 0 3 0; #X connect 35 1 4 0; #X connect 35 2 16 0; #X connect 35 3 17 0; #X connect 36 0 42 0; #X connect 37 0 42 1; #X connect 41 0 7 0; #X connect 42 0 35 0; #X connect 42 1 35 1; pd-0.46-7/extra/stdout/0000775000175000017500000000000012574202336013045 5ustar mspmsppd-0.46-7/extra/stdout/stdout.c0000664000175000017500000000307012374245151014533 0ustar mspmsp/* stdout -- write messages to standard output. Copyright 2008 Miller Puckette BSD license; see README.txt in this distribution for details. */ #include "m_pd.h" #include #include static t_class *stdout_class; typedef struct _stdout { t_object x_obj; } t_stdout; static void *stdout_new(t_float fnonrepeat) { t_stdout *x = (t_stdout *)pd_new(stdout_class); return (x); } static void stdout_anything(t_stdout *x, t_symbol *s, int argc, t_atom *argv) { char msgbuf[MAXPDSTRING], *sp, *ep = msgbuf+MAXPDSTRING; msgbuf[0] = 0; strncpy(msgbuf, s->s_name, MAXPDSTRING); msgbuf[MAXPDSTRING-1] = 0; sp = msgbuf + strlen(msgbuf); while (argc--) { if (sp < ep-1) sp[0] = ' ', sp[1] = 0, sp++; atom_string(argv++, sp, ep-sp); sp += strlen(sp); } printf("%s;\n", msgbuf); /* for some reason in MS windows we have to flush standard out here - otherwise these outputs get out of order from the ones from pdsched.c over in ../pd~. I'm guessing mingw (with its different C runtime support) will handle this correctly and so am only ifdeffing this on Microsoft C compiler. It's an efficiency hit, possibly a serious one. */ #ifdef _MSC_VER fflush(stdout); #endif } static void stdout_free(t_stdout *x) { fflush(stdout); } void stdout_setup(void) { stdout_class = class_new(gensym("stdout"), (t_newmethod)stdout_new, (t_method)stdout_free, sizeof(t_stdout), 0, 0); class_addanything(stdout_class, stdout_anything); } pd-0.46-7/extra/stdout/GNUmakefile.am0000664000175000017500000000125612374250720015515 0ustar mspmsp## Makefile.am -- Process this file with automake to produce Makefile.in NAME=stdout external_LTLIBRARIES = stdout.la SOURCES = stdout.c PATCHES = stdout-help.pd OTHERDATA = EXTRA_DIST = makefile ############################### # you shouldn't need to add anything below here dist_external_DATA = $(PATCHES) $(OTHERDATA) AUTOMAKE_OPTIONS = foreign AM_CPPFLAGS = -I$(top_srcdir)/src -DPD AM_CFLAGS = @ARCH_CFLAGS@ AM_LIBS = $(LIBM) AM_LDFLAGS = -module -avoid-version -shared @ARCH_LDFLAGS@ -shrext .@EXTERNAL_EXTENSION@ -L$(top_srcdir)/src externaldir = $(pkglibdir)/extra/$(NAME) if MINGW AM_LIBS += -lpd endif libtool: $(LIBTOOL_DEPS) $(SHELL) ./config.status --recheck pd-0.46-7/extra/stdout/stdout-help.pd0000664000175000017500000000136312160204055015634 0ustar mspmsp#N canvas 121 60 488 321 12; #X msg 126 203 walk the dog; #X msg 117 156 1; #X obj 117 240 stdout; #X text 269 287 updated for Pd version 0.42; #X obj 14 13 stdout; #X text 67 14 - write messages to standard output; #X msg 122 179 1 2; #X obj 119 291 pd~; #X text 44 291 see also:; #X text 34 39 Sends messages to Pd's standard output. This is useful in conjunction with the pd~ object \, which starts a pd sub-process. Messages sent to the sub-process standard output appear on the output of the pd~ object in the owning process. This might also be useful in other situations. Note that there's no corresponding "stdin" object - there seems to be no one canonical way such a thing should act.; #X connect 0 0 2 0; #X connect 1 0 2 0; #X connect 6 0 2 0; pd-0.46-7/extra/stdout/makefile0000664000175000017500000000006412160204055014534 0ustar mspmspNAME=stdout CSYM=stdout include ../makefile.subdir pd-0.46-7/extra/fiddle~/0000775000175000017500000000000012574202336013150 5ustar mspmsppd-0.46-7/extra/fiddle~/fiddle~.c0000664000175000017500000016662312222367057014761 0ustar mspmsp/* Copyright (c) 1997-1999 Miller Puckette and Ted Apel. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ /* * Fiddle is a pitch tracker hardwired to have hop size ("H") equal to * half its window size ("N"). * * This version should compile for Max "0.26," JMAX, Pd, or Max/MSP. * * The "lastanalysis" field holds the shifted FT of the previous H * samples. The buffer contains in effect points 1/2, 3/2, ..., (N-1)/2 * of the DTFT of a real vector of length N, half of whose points are zero, * i.e., only the first H points are used. Put another way, we get the * the odd-numbered points of the FFT of the H points, zero padded to 4*H in * length. The integer points 0, 1, ..., H-1 * are found by interpolating these others, using the fact that the * half-integer points are band-limited (they only have positive frequencies.) * To facilitate the interpolation the "lastanalysis" buffer contains * FILTSIZE extra points (1/2-FILTSIZE, ..., -1/2) at the beginning and * FILTSIZE again at the end ((N+1)/2, ..., FILTSIZE+(N-1)/2). The buffer * therefore has N+4*FILTSIZE floating-point numbers in it. * * after doing this I found out that you can just do a real FFT * of the H new points, zero-padded to contain N points, and using a similar * but simpler interpolation scheme you can still get 2N points of the DTFT * of the N points. Jean Laroche is a big fat hen. * */ /* These pragmas are only used for MSVC, not MinGW or Cygwin */ #ifdef _MSC_VER #pragma warning (disable: 4305 4244) #endif /* this #ifdef does nothing, but its there... */ #ifdef _WIN32 #define flog log #define fexp exp #define fsqrt sqrt #else #define flog log #define fexp exp #define fsqrt sqrt #endif char fiddle_version[] = "fiddle version 1.1 TEST4"; #ifdef JMAX #include "fts.h" #include #include typedef float t_float; typedef float t_floatarg; typedef fts_symbol_t t_symbol; static void *getbytes(size_t nbytes) { void *ret; if (nbytes < 1) nbytes = 1; ret = (void *)malloc(nbytes); return (ret); } static void *resizebytes(void *old, size_t oldsize, size_t newsize) { void *ret; if (newsize < 1) newsize = 1; ret = (void *)realloc((char *)old, newsize); return (ret); } static void freebytes(void *fatso, size_t nbytes) { free(fatso); } #define CLASSNAME "fiddle" #define OUTLETpower 5 #define OUTLETmicropitch1 4 #define OUTLETmicropitch2 3 #define OUTLETmicropitch3 2 #define OUTLETattack 1 #define OUTLETpitch 0 static fts_symbol_t *dsp_symbol = 0; #define error post #endif /* FTS */ #ifdef MAX26 #define t_floatarg double #include "m_extern.h" #include "d_graph.h" #include "d_ugen.h" #endif /* MAX26 */ #ifdef PD #include "m_pd.h" #endif /* PD */ #ifdef MSP #define flog log #define fexp exp #define fsqrt sqrt #endif /* MSP */ #ifdef MSP #define t_floatarg double #include "ext.h" #include "z_dsp.h" #include "fft_mayer.proto.h" #endif /* MSP */ #include #define MINBIN 3 #define DEFAMPLO 40 #define DEFAMPHI 50 #define DEFATTACKTIME 100 #define DEFATTACKTHRESH 10 #define DEFVIBTIME 50 #define DEFVIBDEPTH 0.5 #define GLISS 0.7f #define DBFUDGE 30.8f #define MINFREQINBINS 5 /* minimum frequency in bins for reliable output */ #define MAXNPITCH 3 #define MAXHIST 3 /* find N hottest peaks in histogram */ #define MAXPOINTS 8192 #define MINPOINTS 128 #define DEFAULTPOINTS 1024 #define HISTORY 20 #define MAXPEAK 100 /* maximum number of peaks */ #define DEFNPEAK 20 /* default number of peaks */ #define MAXNPEAK (MAXLOWPEAK + MAXSTRONGPEAK) #define MINBW (0.03f) /* consider BW >= 0.03 FFT bins */ #define BINPEROCT 48 /* bins per octave */ #define BPERO_OVER_LOG2 69.24936196f /* BINSPEROCT/log(2) */ #define FACTORTOBINS (t_float)(4/0.0145453) /* 4 / (pow(2.,1/48.) - 1) */ #define BINGUARD 10 /* extra bins to throw in front */ #define PARTIALDEVIANCE 0.023f /* acceptable partial detuning in % */ #define LOGTODB 4.34294481903f /* 20/log(10) */ #define KNOCKTHRESH 10.f /* don't know how to describe this */ static t_float sigfiddle_partialonset[] = { 0, 48, 76.0782000346154967102, 96, 111.45254855459339269887, 124.07820003461549671089, 134.75303625876499715823, 144, 152.15640006923099342109, 159.45254855459339269887, 166.05271769459026829915, 172.07820003461549671088, 177.62110647077242370064, 182.75303625876499715892, 187.53074858920888940907, 192, }; #define NPARTIALONSET ((int)(sizeof(sigfiddle_partialonset)/sizeof(t_float))) static int sigfiddle_intpartialonset[] = { 0, 48, 76, 96, 111, 124, 135, 144, 152, 159, 166, 172, 178, 183, 188, 192, }; /* these coefficients, which come from the "upsamp" subdirectory, are a filter kernel for upsampling by a factor of two, assuming the sound to be upsampled has no energy above half the Nyquist, i.e., that it's already 2x oversampled compared to the theoretically possible sample rate. I got these by trial and error. */ #define FILT1 ((t_float)(.5 * 1.227054)) #define FILT2 ((t_float)(.5 * -0.302385)) #define FILT3 ((t_float)(.5 * 0.095326)) #define FILT4 ((t_float)(.5 * -0.022748)) #define FILT5 ((t_float)(.5 * 0.002533)) #define FILTSIZE 5 typedef struct peakout /* a peak for output */ { t_float po_freq; /* frequency in hz */ t_float po_amp; /* amplitude */ } t_peakout; typedef struct peak /* a peak for analysis */ { t_float p_freq; /* frequency in bins */ t_float p_width; /* peak width in bins */ t_float p_pow; /* peak power */ t_float p_loudness; /* 4th root of power */ t_float *p_fp; /* pointer back to spectrum */ } t_peak; typedef struct histopeak { t_float h_pitch; /* estimated pitch */ t_float h_value; /* value of peak */ t_float h_loud; /* combined strength of found partials */ int h_index; /* index of bin holding peak */ int h_used; /* true if an x_hist entry points here */ } t_histopeak; typedef struct pitchhist /* struct for keeping history by pitch */ { t_float h_pitch; /* pitch to output */ t_float h_amps[HISTORY]; /* past amplitudes */ t_float h_pitches[HISTORY]; /* past pitches */ t_float h_noted; /* last pitch output */ int h_age; /* number of frames pitch has been there */ t_histopeak *h_wherefrom; /* new histogram peak to incorporate */ void *h_outlet; } t_pitchhist; typedef struct sigfiddle /* instance struct */ { #ifdef JMAX fts_object_t x_h; /* object header */ fts_alarm_t x_clock; /* callback for timeouts */ #endif #ifdef MAX26 t_head x_h; /* header for tilde objects */ t_sig *x_io[IN1+OUT0]; /* number of signal inputs and outputs */ void *x_clock; /* a "clock" object */ #endif #ifdef PD t_object x_ob; /* object header */ t_clock *x_clock; /* callback for timeouts */ #endif #ifdef MSP t_pxobject x_obj; void *x_clock; long x_downsample; /* downsample feature because of MSP's large sig vector sizes */ #endif t_float *x_inbuf; /* buffer to analyze, npoints/2 elems */ t_float *x_lastanalysis; /* FT of last buffer (see main comment) */ t_float *x_spiral; /* 1/4-wave complex exponential */ t_peakout *x_peakbuf; /* spectral peaks for output */ int x_npeakout; /* number of spectral peaks to output */ int x_npeakanal; /* number of spectral peaks to analyze */ int x_phase; /* number of points since last output */ int x_histphase; /* phase into amplitude history vector */ int x_hop; /* period of output, npoints/2 */ t_float x_sr; /* sample rate */ t_pitchhist x_hist[MAXNPITCH]; /* history of current pitches */ int x_nprint; /* how many periods to print */ int x_npitch; /* number of simultaneous pitches */ t_float x_dbs[HISTORY]; /* DB history, indexed by "histphase" */ t_float x_peaked; /* peak since last attack */ int x_dbage; /* number of bins DB has met threshold */ int x_auto; /* true if generating continuous output */ /* parameters */ t_float x_amplo; t_float x_amphi; int x_attacktime; int x_attackbins; t_float x_attackthresh; int x_vibtime; int x_vibbins; t_float x_vibdepth; t_float x_npartial; /* outlets & clock */ void *x_envout; int x_attackvalue; void *x_attackout; void *x_noteout; void *x_peakout; } t_sigfiddle; #if CHECKER t_float fiddle_checker[1024]; #endif #ifdef MSP /* Mac compiler requires prototypes for everything */ int sigfiddle_ilog2(int n); t_float fiddle_mtof(t_float f); t_float fiddle_ftom(t_float f); void sigfiddle_doit(t_sigfiddle *x); void sigfiddle_debug(t_sigfiddle *x); void sigfiddle_print(t_sigfiddle *x); void sigfiddle_assist(t_sigfiddle *x, void *b, long m, long a, char *s); void sigfiddle_amprange(t_sigfiddle *x, double amplo, double amphi); void sigfiddle_reattack(t_sigfiddle *x, t_floatarg attacktime, t_floatarg attackthresh); void sigfiddle_vibrato(t_sigfiddle *x, t_floatarg vibtime, t_floatarg vibdepth); void sigfiddle_npartial(t_sigfiddle *x, double npartial); void sigfiddle_auto(t_sigfiddle *x, t_floatarg f); void sigfiddle_setnpoints(t_sigfiddle *x, t_floatarg f); int sigfiddle_doinit(t_sigfiddle *x, long npoints, long npitch, long npeakanal, long npeakout); static t_int *fiddle_perform(t_int *w); void sigfiddle_dsp(t_sigfiddle *x, t_signal **sp); void sigfiddle_tick(t_sigfiddle *x); void sigfiddle_bang(t_sigfiddle *x); void sigfiddle_ff(t_sigfiddle *x); void *sigfiddle_new(long npoints, long npitch, long npeakanal, long npeakout); void msp_fft(t_float *buf, long np, long inv); t_float msp_ffttemp[MAXPOINTS*2]; int errno; #endif int sigfiddle_ilog2(int n) { int ret = -1; while (n) { n >>= 1; ret++; } return (ret); } t_float fiddle_mtof(t_float f) { return (8.17579891564 * exp(.0577622650 * f)); } t_float fiddle_ftom(t_float f) { return (17.3123405046 * log(.12231220585 * f)); } #define ftom fiddle_ftom #define mtof fiddle_mtof void sigfiddle_doit(t_sigfiddle *x) { #ifdef MSP /* prevents interrupt-level stack overflow crash with Netscape. */ static t_float spect1[4*MAXPOINTS]; static t_float spect2[MAXPOINTS + 4*FILTSIZE]; #else t_float spect1[4*MAXPOINTS]; t_float spect2[MAXPOINTS + 4*FILTSIZE]; #endif #if CHECKER t_float checker3[4*MAXPOINTS]; #endif t_peak peaklist[MAXPEAK + 1], *pk1; t_peakout *pk2; t_histopeak histvec[MAXHIST], *hp1; int i, j, k, hop = x->x_hop, n = 2*hop, npeak, npitch, logn = sigfiddle_ilog2(n), newphase, oldphase; t_float *fp, *fp1, *fp2, *fp3, total_power, total_loudness, total_db; t_float maxbin = BINPEROCT * (logn-2), *histogram = spect2 + BINGUARD; t_pitchhist *phist; t_float hzperbin = x->x_sr / (2.0f * n); int npeakout = x->x_npeakout, npeakanal = x->x_npeakanal; int npeaktot = (npeakout > npeakanal ? npeakout : npeakanal); oldphase = x->x_histphase; newphase = x->x_histphase + 1; if (newphase == HISTORY) newphase = 0; x->x_histphase = newphase; /* * multiply the H points by a 1/4-wave complex exponential, * and take FFT of the result. */ for (i = 0, fp1 = x->x_inbuf, fp2 = x->x_spiral, fp3 = spect1; i < hop; i++, fp1++, fp2 += 2, fp3 += 2) fp3[0] = fp1[0] * fp2[0], fp3[1] = fp1[0] * fp2[1]; #ifdef MAX26 fft(spect1, hop, 0); #endif #ifdef PD pd_fft(spect1, hop, 0); #endif #ifdef JMAX fts_cfft_inplc((complex *)spect1, hop); #endif #ifdef MSP msp_fft(spect1,hop,0); #endif /* * now redistribute the points to get in effect the odd-numbered * points of the FFT of the H points, zero padded to 4*H in length. */ for (i = 0, fp1 = spect1, fp2 = spect2 + (2*FILTSIZE); i < (hop>>1); i++, fp1 += 2, fp2 += 4) fp2[0] = fp1[0], fp2[1] = fp1[1]; for (i = 0, fp1 = spect1 + n - 2, fp2 = spect2 + (2*FILTSIZE+2); i < (hop>>1); i++, fp1 -= 2, fp2 += 4) fp2[0] = fp1[0], fp2[1] = -fp1[1]; for (i = 0, fp1 = spect2 + (2*FILTSIZE), fp2 = spect2 + (2*FILTSIZE-2); ix_lastanalysis + 2*FILTSIZE, fp3 = spect2 + 2*FILTSIZE; i < (hop>>1); i++) { t_float re, im; re= FILT1 * ( fp2[ -2] -fp2[ 1] +fp3[ -2] -fp3[ 1]) + FILT2 * ( fp2[ -3] -fp2[ 2] +fp3[ -3] -fp3[ 2]) + FILT3 * (-fp2[ -6] +fp2[ 5] -fp3[ -6] +fp3[ 5]) + FILT4 * (-fp2[ -7] +fp2[ 6] -fp3[ -7] +fp3[ 6]) + FILT5 * ( fp2[-10] -fp2[ 9] +fp3[-10] -fp3[ 9]); im= FILT1 * ( fp2[ -1] +fp2[ 0] +fp3[ -1] +fp3[ 0]) + FILT2 * (-fp2[ -4] -fp2[ 3] -fp3[ -4] -fp3[ 3]) + FILT3 * (-fp2[ -5] -fp2[ 4] -fp3[ -5] -fp3[ 4]) + FILT4 * ( fp2[ -8] +fp2[ 7] +fp3[ -8] +fp3[ 7]) + FILT5 * ( fp2[ -9] +fp2[ 8] +fp3[ -9] +fp3[ 8]); fp1[0] = 0.7071f * (re + im); fp1[1] = 0.7071f * (im - re); fp1[4] = fp2[0] + fp3[1]; fp1[5] = fp2[1] - fp3[0]; fp1 += 8, fp2 += 2, fp3 += 2; re= FILT1 * ( fp2[ -2] -fp2[ 1] -fp3[ -2] +fp3[ 1]) + FILT2 * ( fp2[ -3] -fp2[ 2] -fp3[ -3] +fp3[ 2]) + FILT3 * (-fp2[ -6] +fp2[ 5] +fp3[ -6] -fp3[ 5]) + FILT4 * (-fp2[ -7] +fp2[ 6] +fp3[ -7] -fp3[ 6]) + FILT5 * ( fp2[-10] -fp2[ 9] -fp3[-10] +fp3[ 9]); im= FILT1 * ( fp2[ -1] +fp2[ 0] -fp3[ -1] -fp3[ 0]) + FILT2 * (-fp2[ -4] -fp2[ 3] +fp3[ -4] +fp3[ 3]) + FILT3 * (-fp2[ -5] -fp2[ 4] +fp3[ -5] +fp3[ 4]) + FILT4 * ( fp2[ -8] +fp2[ 7] -fp3[ -8] -fp3[ 7]) + FILT5 * ( fp2[ -9] +fp2[ 8] -fp3[ -9] -fp3[ 8]); fp1[0] = 0.7071f * (re + im); fp1[1] = 0.7071f * (im - re); fp1[4] = fp2[0] - fp3[1]; fp1[5] = fp2[1] + fp3[0]; fp1 += 8, fp2 += 2, fp3 += 2; } #if 0 if (x->x_nprint) { for (i = 0, fp = spect1; i < 16; i++, fp+= 4) post("spect %d %f %f --> %f", i, fp[0], fp[1], sqrt(fp[0] * fp[0] + fp[1] * fp[1])); } #endif /* copy new spectrum out */ for (i = 0, fp1 = spect2, fp2 = x->x_lastanalysis; i < n + 4*FILTSIZE; i++) *fp2++ = *fp1++; for (i = 0; i < MINBIN; i++) spect1[4*i + 2] = spect1[4*i + 3] = 0; /* starting at bin MINBIN, compute hanning windowed power spectrum */ for (i = MINBIN, fp1 = spect1+4*MINBIN, total_power = 0; i < n-2; i++, fp1 += 4) { t_float re = fp1[0] - 0.5 * (fp1[-8] + fp1[8]); t_float im = fp1[1] - 0.5 * (fp1[-7] + fp1[9]); fp1[3] = (total_power += (fp1[2] = re * re + im * im)); } if (total_power > 1e-9f) { total_db = (100.f - DBFUDGE) + LOGTODB * log(total_power/n); total_loudness = fsqrt(fsqrt(total_power)); if (total_db < 0) total_db = 0; } else total_db = total_loudness = 0; /* store new db in history vector */ x->x_dbs[newphase] = total_db; if (total_db < x->x_amplo) goto nopow; #if 1 if (x->x_nprint) post("power %f", total_power); #endif #if CHECKER /* verify that our FFT resampling thing is putting out good results */ for (i = 0; i < hop; i++) { checker3[2*i] = fiddle_checker[i]; checker3[2*i + 1] = 0; checker3[n + 2*i] = fiddle_checker[i] = x->x_inbuf[i]; checker3[n + 2*i + 1] = 0; } for (i = 2*n; i < 4*n; i++) checker3[i] = 0; fft(checker3, 2*n, 0); if (x->x_nprint) { for (i = 0, fp = checker3; i < 16; i++, fp += 2) post("spect %d %f %f --> %f", i, fp[0], fp[1], sqrt(fp[0] * fp[0] + fp[1] * fp[1])); } #endif npeak = 0; /* search for peaks */ for (i = MINBIN, fp = spect1+4*MINBIN, pk1 = peaklist; i < n-2 && npeak < npeaktot; i++, fp += 4) { t_float height = fp[2], h1 = fp[-2], h2 = fp[6]; t_float totalfreq, pfreq, f1, f2, m, var, stdev; if (height < h1 || height < h2 || h1 < 0.00001f*total_power || h2 < 0.00001f*total_power) continue; /* use an informal phase vocoder to estimate the frequency. Do this for the two adjacent bins too. */ pfreq= ((fp[-8] - fp[8]) * (2.0f * fp[0] - fp[8] - fp[-8]) + (fp[-7] - fp[9]) * (2.0f * fp[1] - fp[9] - fp[-7])) / (2.0f * height); f1= ((fp[-12] - fp[4]) * (2.0f * fp[-4] - fp[4] - fp[-12]) + (fp[-11] - fp[5]) * (2.0f * fp[-3] - fp[5] - fp[-11])) / (2.0f * h1) - 1; f2= ((fp[-4] - fp[12]) * (2.0f * fp[4] - fp[12] - fp[-4]) + (fp[-3] - fp[13]) * (2.0f * fp[5] - fp[13] - fp[-3])) / (2.0f * h2) + 1; /* get sample mean and variance of the three */ m = 0.333333f * (pfreq + f1 + f2); var = 0.5f * ((pfreq-m)*(pfreq-m) + (f1-m)*(f1-m) + (f2-m)*(f2-m)); totalfreq = i + m; if (var * total_power > KNOCKTHRESH * height || var < 1e-30) { #if 0 if (x->x_nprint) post("cancel: %.2f hz, index %.1f, power %.5f, stdev=%.2f", totalfreq * hzperbin, BPERO_OVER_LOG2 * log(totalfreq) - 96, height, sqrt(var)); #endif continue; } stdev = fsqrt(var); if (totalfreq < 4) { if (x->x_nprint) post("oops: was %d, freq %f, m %f, stdev %f h %f", i, totalfreq, m, stdev, height); totalfreq = 4; } pk1->p_width = stdev; pk1->p_pow = height; pk1->p_loudness = fsqrt(fsqrt(height)); pk1->p_fp = fp; pk1->p_freq = totalfreq; npeak++; #if 1 if (x->x_nprint) { post("peak: %.2f hz. index %.1f, power %.5f, stdev=%.2f", pk1->p_freq * hzperbin, BPERO_OVER_LOG2 * log(pk1->p_freq) - 96, height, stdev); } #endif pk1++; } /* prepare the raw peaks for output */ for (i = 0, pk1 = peaklist, pk2 = x->x_peakbuf; i < npeak; i++, pk1++, pk2++) { t_float loudness = pk1->p_loudness; if (i >= npeakout) break; pk2->po_freq = hzperbin * pk1->p_freq; pk2->po_amp = (2. / (t_float)n) * (loudness * loudness); } for (; i < npeakout; i++, pk2++) pk2->po_amp = pk2->po_freq = 0; /* now, working back into spect2, make a sort of "liklihood" * spectrum. Proceeding in 48ths of an octave, from 2 to * n/2 (in bins), the likelihood of each pitch range is contributed * to by every peak in peaklist that's an integer multiple of it * in frequency. */ if (npeak > npeakanal) npeak = npeakanal; /* max # peaks to analyze */ for (i = 0, fp1 = histogram; i < maxbin; i++) *fp1++ = 0; for (i = 0, pk1 = peaklist; i < npeak; i++, pk1++) { t_float pit = BPERO_OVER_LOG2 * flog(pk1->p_freq) - 96.0; t_float binbandwidth = FACTORTOBINS * pk1->p_width/pk1->p_freq; t_float putbandwidth = (binbandwidth < 2 ? 2 : binbandwidth); t_float weightbandwidth = (binbandwidth < 1.0 ? 1.0 : binbandwidth); /* t_float weightamp = 1.0f + 3.0f * pk1->p_pow / pow; */ t_float weightamp = 4. * pk1->p_loudness / total_loudness; for (j = 0, fp2 = sigfiddle_partialonset; j < NPARTIALONSET; j++, fp2++) { t_float bin = pit - *fp2; if (bin < maxbin) { t_float para, pphase, score = 30.0 * weightamp / ((j+x->x_npartial) * weightbandwidth); int firstbin = bin + 0.5f - 0.5f * putbandwidth; int lastbin = bin + 0.5f + 0.5f * putbandwidth; int ibw = lastbin - firstbin; if (firstbin < -BINGUARD) break; para = 1.0f / (putbandwidth * putbandwidth); for (k = 0, fp3 = histogram + firstbin, pphase = firstbin-bin; k <= ibw; k++, fp3++, pphase += 1.0f) { *fp3 += score * (1.0f - para * pphase * pphase); } } } } #if 1 if (x->x_nprint) { for (i = 0; i < 6*5; i++) { t_float fhz = hzperbin * exp ((8*i + 96) * (1./BPERO_OVER_LOG2)); if (!(i % 6)) post("-- bin %d pitch %f freq %f----", 8*i, ftom(fhz), fhz);; post("%3d %3d %3d %3d %3d %3d %3d %3d", (int)(histogram[8*i]), (int)(histogram[8*i+1]), (int)(histogram[8*i+2]), (int)(histogram[8*i+3]), (int)(histogram[8*i+4]), (int)(histogram[8*i+5]), (int)(histogram[8*i+6]), (int)(histogram[8*i+7])); } } #endif /* * Next we find up to NPITCH strongest peaks in the histogram. * if a peak is related to a stronger one via an interval in * the sigfiddle_partialonset array, we suppress it. */ for (npitch = 0; npitch < x->x_npitch; npitch++) { int indx; t_float best; if (npitch) { for (best = 0, indx = -1, j=1; j < maxbin-1; j++) { if (histogram[j] > best && histogram[j] > histogram[j-1] && histogram[j] > histogram[j+1]) { for (k = 0; k < npitch; k++) if (histvec[k].h_index == j) goto peaknogood; for (k = 0; k < NPARTIALONSET; k++) { if (j - sigfiddle_intpartialonset[k] < 0) break; if (histogram[j - sigfiddle_intpartialonset[k]] > histogram[j]) goto peaknogood; } for (k = 0; k < NPARTIALONSET; k++) { if (j + sigfiddle_intpartialonset[k] >= maxbin) break; if (histogram[j + sigfiddle_intpartialonset[k]] > histogram[j]) goto peaknogood; } indx = j; best = histogram[j]; } peaknogood: ; } } else { for (best = 0, indx = -1, j=0; j < maxbin; j++) if (histogram[j] > best) indx = j, best = histogram[j]; } if (indx < 0) break; histvec[npitch].h_value = best; histvec[npitch].h_index = indx; } #if 1 if (x->x_nprint) { for (i = 0; i < npitch; i++) { post("index %d freq %f --> value %f", histvec[i].h_index, exp((1./BPERO_OVER_LOG2) * (histvec[i].h_index + 96)), histvec[i].h_value); post("next %f , prev %f", exp((1./BPERO_OVER_LOG2) * (histvec[i].h_index + 97)), exp((1./BPERO_OVER_LOG2) * (histvec[i].h_index + 95)) ); } } #endif /* for each histogram peak, we now search back through the * FFT peaks. A peak is a pitch if either there are several * harmonics that match it, or else if (a) the fundamental is * present, and (b) the sum of the powers of the contributing peaks * is at least 1/100 of the total power. * * A peak is a contributor if its frequency is within 25 cents of * a partial from 1 to 16. * * Finally, we have to be at least 5 bins in frequency, which * corresponds to 2-1/5 periods fitting in the analysis window. */ for (i = 0; i < npitch; i++) { t_float cumpow = 0, cumstrength = 0, freqnum = 0, freqden = 0; int npartials = 0, nbelow8 = 0; /* guessed-at frequency in bins */ t_float putfreq = fexp((1.0 / BPERO_OVER_LOG2) * (histvec[i].h_index + 96.0f)); for (j = 0; j < npeak; j++) { t_float fpnum = peaklist[j].p_freq/putfreq; int pnum = fpnum + 0.5f; t_float fipnum = pnum; t_float deviation; if (pnum > 16 || pnum < 1) continue; deviation = 1.0f - fpnum/fipnum; if (deviation > -PARTIALDEVIANCE && deviation < PARTIALDEVIANCE) { /* * we figure this is a partial since it's within 1/4 of * a halftone of a multiple of the putative frequency. */ t_float stdev, weight; npartials++; if (pnum < 8) nbelow8++; cumpow += peaklist[j].p_pow; cumstrength += fsqrt(fsqrt(peaklist[j].p_pow)); stdev = (peaklist[j].p_width > MINBW ? peaklist[j].p_width : MINBW); weight = 1.0f / ((stdev*fipnum) * (stdev*fipnum)); freqden += weight; freqnum += weight * peaklist[j].p_freq/fipnum; #if 1 if (x->x_nprint) { post("peak %d partial %d f=%f w=%f", j, pnum, peaklist[j].p_freq/fipnum, weight); } #endif } #if 1 else if (x->x_nprint) post("peak %d partial %d dev %f", j, pnum, deviation); #endif } if ((nbelow8 < 4 || npartials < 7) && cumpow < 0.01f * total_power) histvec[i].h_value = 0; else { t_float pitchpow = (cumstrength * cumstrength) * (cumstrength * cumstrength); t_float freqinbins = freqnum/freqden; /* check for minimum output frequency */ if (freqinbins < MINFREQINBINS) histvec[i].h_value = 0; else { /* we passed all tests... save the values we got */ histvec[i].h_pitch = ftom(hzperbin * freqnum/freqden); histvec[i].h_loud = (100.0f -DBFUDGE) + (LOGTODB) * log(pitchpow/n); } } } #if 1 if (x->x_nprint) { for (i = 0; i < npitch; i++) { if (histvec[i].h_value > 0) post("index %d pit %f loud %f", histvec[i].h_index, histvec[i].h_pitch, histvec[i].h_loud); else post("-- cancelled --"); } } #endif /* now try to find continuous pitch tracks that match the new * pitches. First mark each peak unmatched. */ for (i = 0, hp1 = histvec; i < npitch; i++, hp1++) hp1->h_used = 0; /* for each old pitch, try to match a new one to it. */ for (i = 0, phist = x->x_hist; i < x->x_npitch; i++, phist++) { t_float thispitch = phist->h_pitches[oldphase]; phist->h_pitch = 0; /* no output, thanks */ phist->h_wherefrom = 0; if (thispitch == 0.0f) continue; for (j = 0, hp1 = histvec; j < npitch; j++, hp1++) if ((hp1->h_value > 0) && hp1->h_pitch > thispitch - GLISS && hp1->h_pitch < thispitch + GLISS) { phist->h_wherefrom = hp1; hp1->h_used = 1; } } for (i = 0, hp1 = histvec; i < npitch; i++, hp1++) if ((hp1->h_value > 0) && !hp1->h_used) { for (j = 0, phist = x->x_hist; j < x->x_npitch; j++, phist++) if (!phist->h_wherefrom) { phist->h_wherefrom = hp1; phist->h_age = 0; phist->h_noted = 0; hp1->h_used = 1; goto happy; } break; happy: ; } /* copy the pitch info into the history vector */ for (i = 0, phist = x->x_hist; i < x->x_npitch; i++, phist++) { if (phist->h_wherefrom) { phist->h_amps[newphase] = phist->h_wherefrom->h_loud; phist->h_pitches[newphase] = phist->h_wherefrom->h_pitch; (phist->h_age)++; } else { phist->h_age = 0; phist->h_amps[newphase] = phist->h_pitches[newphase] = 0; } } #if 1 if (x->x_nprint) { post("vibrato %d %f", x->x_vibbins, x->x_vibdepth); for (i = 0, phist = x->x_hist; i < x->x_npitch; i++, phist++) { post("noted %f, age %d", phist->h_noted, phist->h_age); #ifndef I860 post("values %f %f %f %f %f", phist->h_pitches[newphase], phist->h_pitches[(newphase + HISTORY-1)%HISTORY], phist->h_pitches[(newphase + HISTORY-2)%HISTORY], phist->h_pitches[(newphase + HISTORY-3)%HISTORY], phist->h_pitches[(newphase + HISTORY-4)%HISTORY]); #endif } } #endif /* look for envelope attacks */ x->x_attackvalue = 0; if (x->x_peaked) { if (total_db > x->x_amphi) { int binlook = newphase - x->x_attackbins; if (binlook < 0) binlook += HISTORY; if (total_db > x->x_dbs[binlook] + x->x_attackthresh) { x->x_attackvalue = 1; x->x_peaked = 0; } } } else { int binlook = newphase - x->x_attackbins; if (binlook < 0) binlook += HISTORY; if (x->x_dbs[binlook] > x->x_amphi && x->x_dbs[binlook] > total_db) x->x_peaked = 1; } /* for each current frequency track, test for a new note using a * stability criterion. Later perhaps we should also do as in * pitch~ and check for unstable notes a posteriori when * there's a new attack with no note found since the last onset; * but what's an attack &/or onset when we're polyphonic? */ for (i = 0, phist = x->x_hist; i < x->x_npitch; i++, phist++) { /* * if we've found a pitch but we've now strayed from it turn * it off. */ if (phist->h_noted) { if (phist->h_pitches[newphase] > phist->h_noted + x->x_vibdepth || phist->h_pitches[newphase] < phist->h_noted - x->x_vibdepth) phist->h_noted = 0; } else { if (phist->h_wherefrom && phist->h_age >= x->x_vibbins) { t_float centroid = 0; int not = 0; for (j = 0, k = newphase; j < x->x_vibbins; j++) { centroid += phist->h_pitches[k]; k--; if (k < 0) k = HISTORY-1; } centroid /= x->x_vibbins; for (j = 0, k = newphase; j < x->x_vibbins; j++) { /* calculate deviation from norm */ t_float dev = centroid - phist->h_pitches[k]; k--; if (k < 0) k = HISTORY-1; if (dev > x->x_vibdepth || -dev > x->x_vibdepth) not = 1; } if (!not) { phist->h_pitch = phist->h_noted = centroid; } } } } return; nopow: for (i = 0; i < x->x_npitch; i++) { x->x_hist[i].h_pitch = x->x_hist[i].h_noted = x->x_hist[i].h_pitches[newphase] = x->x_hist[i].h_amps[newphase] = 0; x->x_hist[i].h_age = 0; } x->x_peaked = 1; x->x_dbage = 0; } void sigfiddle_debug(t_sigfiddle *x) { x->x_nprint = 1; } void sigfiddle_print(t_sigfiddle *x) { post("npoints %d,", 2 * x->x_hop); post("amp-range %f %f,", x->x_amplo, x->x_amphi); post("reattack %d %f,", x->x_attacktime, x->x_attackthresh); post("vibrato %d %f", x->x_vibtime, x->x_vibdepth); post("npartial %f", x->x_npartial); post("auto %d", x->x_auto); } void sigfiddle_amprange(t_sigfiddle *x, t_floatarg amplo, t_floatarg amphi) { if (amplo < 0) amplo = 0; if (amphi < amplo) amphi = amplo + 1; x->x_amplo = amplo; x->x_amphi = amphi; } void sigfiddle_reattack(t_sigfiddle *x, t_floatarg attacktime, t_floatarg attackthresh) { if (attacktime < 0) attacktime = 0; if (attackthresh <= 0) attackthresh = 1000; x->x_attacktime = attacktime; x->x_attackthresh = attackthresh; x->x_attackbins = (x->x_sr * 0.001 * attacktime) / x->x_hop; if (x->x_attackbins >= HISTORY) x->x_attackbins = HISTORY - 1; } void sigfiddle_vibrato(t_sigfiddle *x, t_floatarg vibtime, t_floatarg vibdepth) { if (vibtime < 0) vibtime = 0; if (vibdepth <= 0) vibdepth = 1000; x->x_vibtime = vibtime; x->x_vibdepth = vibdepth; x->x_vibbins = (x->x_sr * 0.001 * vibtime) / x->x_hop; if (x->x_vibbins >= HISTORY) x->x_vibbins = HISTORY - 1; if (x->x_vibbins < 1) x->x_vibbins = 1; } void sigfiddle_npartial(t_sigfiddle *x, t_floatarg npartial) { if (npartial < 0.1) npartial = 0.1; x->x_npartial = npartial; } void sigfiddle_auto(t_sigfiddle *x, t_floatarg f) { x->x_auto = (f != 0); } static void sigfiddle_freebird(t_sigfiddle *x) { if (x->x_inbuf) { freebytes(x->x_inbuf, sizeof(t_float) * x->x_hop); x->x_inbuf = 0; } if (x->x_lastanalysis) { freebytes(x->x_lastanalysis, sizeof(t_float) * (2 * x->x_hop + 4 * FILTSIZE)); x->x_lastanalysis = 0; } if (x->x_spiral) { freebytes(x->x_spiral, sizeof(t_float) * 2 * x->x_hop); x->x_spiral = 0; } x->x_hop = 0; } int sigfiddle_setnpoints(t_sigfiddle *x, t_floatarg fnpoints) { int i, npoints = fnpoints; sigfiddle_freebird(x); if (npoints < MINPOINTS || npoints > MAXPOINTS) { error("fiddle~: npoints out of range; using %d", npoints = DEFAULTPOINTS); } if (npoints != (1 << sigfiddle_ilog2(npoints))) { error("fiddle~: npoints not a power of 2; using %d", npoints = (1 << sigfiddle_ilog2(npoints))); } x->x_hop = npoints >> 1; if (!(x->x_inbuf = (t_float *)getbytes(sizeof(t_float) * x->x_hop))) goto fail; if (!(x->x_lastanalysis = (t_float *)getbytes( sizeof(t_float) * (2 * x->x_hop + 4 * FILTSIZE)))) goto fail; if (!(x->x_spiral = (t_float *)getbytes(sizeof(t_float) * 2 * x->x_hop))) goto fail; for (i = 0; i < x->x_hop; i++) x->x_inbuf[i] = 0; for (i = 0; i < npoints + 4 * FILTSIZE; i++) x->x_lastanalysis[i] = 0; for (i = 0; i < x->x_hop; i++) x->x_spiral[2*i] = cos((3.14159*i)/(npoints)), x->x_spiral[2*i+1] = -sin((3.14159*i)/(npoints)); x->x_phase = 0; return (1); fail: sigfiddle_freebird(x); return (0); } int sigfiddle_doinit(t_sigfiddle *x, long npoints, long npitch, long npeakanal, long npeakout) { t_float *buf1, *buf2, *buf3; t_peakout *buf4; int i; if (!npeakanal && !npeakout) npeakanal = DEFNPEAK, npeakout = 0; if (!npeakanal < 0) npeakanal = 0; else if (npeakanal > MAXPEAK) npeakanal = MAXPEAK; if (!npeakout < 0) npeakout = 0; else if (npeakout > MAXPEAK) npeakout = MAXPEAK; if (npitch <= 0) npitch = 0; else if (npitch > MAXNPITCH) npitch = MAXNPITCH; if (npeakanal && !npitch) npitch = 1; if (!npoints) npoints = DEFAULTPOINTS; if (!sigfiddle_setnpoints(x, npoints)) { error("fiddle~: out of memory"); return (0); } if (!(buf4 = (t_peakout *)getbytes(sizeof(*buf4) * npeakout))) { sigfiddle_freebird(x); error("fiddle~: out of memory"); return (0); } for (i = 0; i < npeakout; i++) buf4[i].po_freq = buf4[i].po_amp = 0; x->x_peakbuf = buf4; x->x_npeakout = npeakout; x->x_npeakanal = npeakanal; x->x_phase = 0; x->x_histphase = 0; x->x_sr = 44100; /* this and the next are filled in later */ for (i = 0; i < MAXNPITCH; i++) { int j; x->x_hist[i].h_pitch = x->x_hist[i].h_noted = 0; x->x_hist[i].h_age = 0; x->x_hist[i].h_wherefrom = 0; x->x_hist[i].h_outlet = 0; for (j = 0; j < HISTORY; j++) x->x_hist[i].h_amps[j] = x->x_hist[i].h_pitches[j] = 0; } x->x_nprint = 0; x->x_npitch = npitch; for (i = 0; i < HISTORY; i++) x->x_dbs[i] = 0; x->x_dbage = 0; x->x_peaked = 0; x->x_auto = 1; x->x_amplo = DEFAMPLO; x->x_amphi = DEFAMPHI; x->x_attacktime = DEFATTACKTIME; x->x_attackbins = 1; /* real value calculated afterward */ x->x_attackthresh = DEFATTACKTHRESH; x->x_vibtime = DEFVIBTIME; x->x_vibbins = 1; /* real value calculated afterward */ x->x_vibdepth = DEFVIBDEPTH; x->x_npartial = 7; x->x_attackvalue = 0; return (1); } /* formalities for JMAX */ #ifdef JMAX void sigfiddle_debug13(fts_object_t *o, int winlet, fts_symbol_t s, int ac, const fts_atom_t *at) { t_sigfiddle *x = (t_sigfiddle *)o; sigfiddle_debug(x); } void sigfiddle_print13(fts_object_t *o, int winlet, fts_symbol_t s, int ac, const fts_atom_t *at) { t_sigfiddle *x = (t_sigfiddle *)o; sigfiddle_print(x); } void sigfiddle_amprange13(fts_object_t *o, int winlet, fts_symbol_t s, int ac, const fts_atom_t *at) { t_sigfiddle *x = (t_sigfiddle *)o; t_float lo = (t_float) fts_get_float_arg(ac, at, 0, 0); t_float hi = (t_float) fts_get_float_arg(ac, at, 1, 0); sigfiddle_amprange(x, lo, hi); } void sigfiddle_reattack13(fts_object_t *o, int winlet, fts_symbol_t s, int ac, const fts_atom_t *at) { t_sigfiddle *x = (t_sigfiddle *)o; long msec = fts_get_float_arg(ac, at, 0, 0); t_float db = (t_float) fts_get_float_arg(ac, at, 1, 0); sigfiddle_reattack(x, msec, db); } void sigfiddle_vibrato13(fts_object_t *o, int winlet, fts_symbol_t s, int ac, const fts_atom_t *at) { t_sigfiddle *x = (t_sigfiddle *)o; long msec = fts_get_float_arg(ac, at, 0, 0); t_float halftones = (t_float) fts_get_float_arg(ac, at, 1, 0); sigfiddle_vibrato(x, msec, halftones); } void sigfiddle_npartial13(fts_object_t *o, int winlet, fts_symbol_t s, int ac, const fts_atom_t *at) { t_sigfiddle *x = (t_sigfiddle *)o; t_float npartial = (t_float) fts_get_float_arg(ac, at, 0, 0); sigfiddle_npartial(x, npartial); } void ftl_sigfiddle(fts_word_t *a) { t_sigfiddle *x = (t_sigfiddle *)fts_word_get_long(a); t_float *in = (t_float *)fts_word_get_long(a + 1); long n_tick = fts_word_get_long(a + 2); int count; t_float *fp, *fp2; for (count = 0, fp = x->x_inbuf + x->x_phase; count < n_tick; count++) *fp++ = *in++; if (fp == x->x_inbuf + x->x_hop) { sigfiddle_doit(x); x->x_phase = 0; fts_alarm_set_delay(&x->x_clock, 0L); /* output bang */ fts_alarm_arm(&x->x_clock); if (x->x_nprint) x->x_nprint--; } else x->x_phase += n_tick; } void sigfiddle_put(fts_object_t *o, int winlet, fts_symbol_t *s, int ac, const fts_atom_t *at) { t_sigfiddle *x = (t_sigfiddle *)o; fts_dsp_descr_t *dsp = (fts_dsp_descr_t *)fts_get_long_arg(ac, at, 0, 0); fts_atom_t a[3]; x->x_sr = fts_dsp_get_input_srate(dsp, 0); sigfiddle_reattack(x, x->x_attacktime, x->x_attackthresh); sigfiddle_vibrato(x, x->x_vibtime, x->x_vibdepth); fts_set_long(a, (long)x); fts_set_symbol(a+1, fts_dsp_get_input_name(dsp, 0)); fts_set_long(a+2, fts_dsp_get_input_size(dsp, 0)); dsp_add_funcall(dsp_symbol, 3, a); } void sigfiddle_tick(fts_alarm_t *alarm, void *p) { fts_object_t *o = (fts_object_t *)p; t_sigfiddle *x = (t_sigfiddle *)p; int i; t_pitchhist *ph; fts_outlet_float(o, OUTLETpower, x->x_dbs[x->x_histphase]); for (i = 0, ph = x->x_hist; i < x->x_npitch; i++, ph++) { fts_atom_t at[2]; fts_set_float(at, ph->h_pitches[x->x_histphase]); fts_set_float(at+1, ph->h_amps[x->x_histphase]); fts_outlet_list(o, OUTLETmicropitch3 - i, 2, at); } if (x->x_attackvalue) fts_outlet_bang(o, OUTLETattack); for (i = 0, ph = x->x_hist; i < x->x_npitch; i++, ph++) if (ph->h_pitch) fts_outlet_float(o, OUTLETpitch, ph->h_pitch); } static void sigfiddle_delete(fts_object_t *o, int winlet, fts_symbol_t *s, int ac, const fts_atom_t *at) { t_sigfiddle *x = (t_sigfiddle *)o; fts_free(x->x_inbuf); fts_free(x->x_lastanalysis); fts_free(x->x_spiral); dsp_list_remove(o); } static void sigfiddle_init(fts_object_t *o, int winlet, fts_symbol_t *s, int ac, const fts_atom_t *at) { t_sigfiddle *x = (t_sigfiddle *)o; t_float *buf1, *buf2, *buf3; int i, hop; long npoints = fts_get_long_arg(ac, at, 1, 0); long npitch = fts_get_long_arg(ac, at, 2, 0); long npeakanal = fts_get_long_arg(ac, at, 3, 0); long npeakout = fts_get_long_arg(ac, at, 4, 0); if (!sigfiddle_doinit(x, npoints, npitch, npeakanal, npeakout)) { post("fiddle~: initialization failed"); return; } hop = npoints>>1; if (fts_fft_declaresize(hop) != fts_Success) post("fiddle~: bad FFT size"); fts_alarm_init(&(x->x_clock), 0, sigfiddle_tick, x); dsp_list_insert(o); } static fts_status_t sigfiddle_instantiate(fts_class_t *cl, int ac, const fts_atom_t *at) { int i; fts_type_t a[5]; fts_class_init(cl, sizeof(t_sigfiddle), 1, 6, 0); /* 1 inlet + 6 outlets */ /* the system methods */ a[0] = fts_Symbol; a[1] = fts_Long | fts_OptArg; a[2] = fts_Long | fts_OptArg; fts_method_define(cl, fts_SystemInlet, fts_s_init, sigfiddle_init, 3, a); fts_method_define(cl, fts_SystemInlet, fts_s_delete, sigfiddle_delete, 0, a); a[0] = fts_Object; fts_method_define(cl, fts_SystemInlet, fts_s_put, sigfiddle_put, 1, a); /* class' own methods */ fts_method_define(cl, 0, fts_new_symbol("print"), sigfiddle_print13, 0, a); fts_method_define(cl, 0, fts_new_symbol("debug"), sigfiddle_debug13, 0, a); fts_method_define(cl, 0, fts_new_symbol("amp-range"), sigfiddle_amprange13, 0, a); fts_method_define(cl, 0, fts_new_symbol("reattack"), sigfiddle_reattack13, 0, a); fts_method_define(cl, 0, fts_new_symbol("vibrato"), sigfiddle_vibrato13, 0, a); fts_method_define(cl, 0, fts_new_symbol("npartial"), sigfiddle_npartial13, 0, a); /* classes signal inlets */ dsp_sig_inlet(cl, 0); /* declare signal input #0 */ /* classes outlets */ a[0] = fts_Float; fts_outlet_type_define(cl, OUTLETpitch, fts_s_float, 1, a); /* declare outlet #0 */ fts_outlet_type_define(cl, OUTLETattack, fts_s_bang, 0, a); /* declare outlet #1 */ a[0] = fts_VarArgs; fts_outlet_type_define(cl, OUTLETmicropitch1, fts_s_list, 1, a); /* declare outlet #2 */ fts_outlet_type_define(cl, OUTLETmicropitch2, fts_s_list, 1, a); /* declare outlet #3 */ fts_outlet_type_define(cl, OUTLETmicropitch3, fts_s_list, 1, a); /* declare outlet #4 */ a[0] = fts_Float; fts_outlet_type_define(cl, OUTLETpower, fts_s_float, 1, a); /* declare outlet #5 */ dsp_symbol = fts_new_symbol("fiddle"); dsp_declare_function(dsp_symbol, ftl_sigfiddle); /* DSP properties */ fts_class_put_prop(cl, fts_s_dsp_is_sink, fts_true); return(fts_Success); } void fiddle_config(void) { sys_log(fiddle_version); fts_metaclass_create(fts_new_symbol(CLASSNAME), sigfiddle_instantiate, fts_always_equiv); } fts_module_t fiddle_module = {"fiddle", "sonic meat fiddle", fiddle_config, 0}; #endif /* JMAX */ #ifdef PD static t_int *fiddle_perform(t_int *w) { t_float *in = (t_float *)(w[1]); t_sigfiddle *x = (t_sigfiddle *)(w[2]); int n = (int)(w[3]); int count; t_float *fp; if (!x->x_hop) goto nono; for (count = 0, fp = x->x_inbuf + x->x_phase; count < n; count++) *fp++ = *in++; if (fp == x->x_inbuf + x->x_hop) { sigfiddle_doit(x); x->x_phase = 0; if (x->x_auto) clock_delay(x->x_clock, 0L); if (x->x_nprint) x->x_nprint--; } else x->x_phase += n; nono: return (w+4); } void sigfiddle_dsp(t_sigfiddle *x, t_signal **sp) { x->x_sr = sp[0]->s_sr; sigfiddle_reattack(x, x->x_attacktime, x->x_attackthresh); sigfiddle_vibrato(x, x->x_vibtime, x->x_vibdepth); dsp_add(fiddle_perform, 3, sp[0]->s_vec, x, sp[0]->s_n); } /* This is the callback function for the clock, but also acts as the "bang" method; you can leave "auto" on to get this called automatically (the default) or turn auto off and bang it yourself. */ void sigfiddle_bang(t_sigfiddle *x) { int i; t_pitchhist *ph; if (x->x_npeakout) { int npeakout = x->x_npeakout; t_peakout *po; for (i = 0, po = x->x_peakbuf; i < npeakout; i++, po++) { t_atom at[3]; SETFLOAT(at, i+1); SETFLOAT(at+1, po->po_freq); SETFLOAT(at+2, po->po_amp); outlet_list(x->x_peakout, 0, 3, at); } } outlet_float(x->x_envout, x->x_dbs[x->x_histphase]); for (i = 0, ph = x->x_hist; i < x->x_npitch; i++, ph++) { t_atom at[2]; SETFLOAT(at, ph->h_pitches[x->x_histphase]); SETFLOAT(at+1, ph->h_amps[x->x_histphase]); outlet_list(ph->h_outlet, 0, 2, at); } if (x->x_attackvalue) outlet_bang(x->x_attackout); for (i = 0, ph = x->x_hist; i < x->x_npitch; i++, ph++) if (ph->h_pitch) outlet_float(x->x_noteout, ph->h_pitch); } void sigfiddle_ff(t_sigfiddle *x) /* cleanup on free */ { if (x->x_inbuf) { freebytes(x->x_inbuf, sizeof(t_float) * x->x_hop); freebytes(x->x_lastanalysis, sizeof(t_float) * (2*x->x_hop + 4 * FILTSIZE)); freebytes(x->x_spiral, sizeof(t_float) * 2*x->x_hop); freebytes(x->x_peakbuf, sizeof(*x->x_peakbuf) * x->x_npeakout); clock_free(x->x_clock); } } static t_class *sigfiddle_class; void *sigfiddle_new(t_floatarg npoints, t_floatarg npitch, t_floatarg fnpeakanal, t_floatarg fnpeakout) { t_sigfiddle *x = (t_sigfiddle *)pd_new(sigfiddle_class); int i; int npeakanal = fnpeakanal, npeakout = fnpeakout; if (!sigfiddle_doinit(x, npoints, npitch, npeakanal, npeakout)) { x->x_inbuf = 0; /* prevent the free routine from cleaning up */ pd_free(&x->x_ob.ob_pd); return (0); } x->x_noteout = outlet_new(&x->x_ob, gensym("float")); x->x_attackout = outlet_new(&x->x_ob, gensym("bang")); for (i = 0; i < x->x_npitch; i++) x->x_hist[i].h_outlet = outlet_new(&x->x_ob, gensym("list")); x->x_envout = outlet_new(&x->x_ob, gensym("float")); if (x->x_npeakout) x->x_peakout = outlet_new(&x->x_ob, gensym("list")); else x->x_peakout = 0; x->x_clock = clock_new(&x->x_ob.ob_pd, (t_method)sigfiddle_bang); return (x); } void fiddle_tilde_setup(void) { sigfiddle_class = class_new(gensym("fiddle~"), (t_newmethod)sigfiddle_new, (t_method)sigfiddle_ff, sizeof(t_sigfiddle), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); class_addmethod(sigfiddle_class, (t_method)sigfiddle_dsp, gensym("dsp"), 0); class_addmethod(sigfiddle_class, (t_method)sigfiddle_debug, gensym("debug"), 0); class_addmethod(sigfiddle_class, (t_method)sigfiddle_setnpoints, gensym("npoints"), A_FLOAT, 0); class_addmethod(sigfiddle_class, (t_method)sigfiddle_amprange, gensym("amp-range"), A_FLOAT, A_FLOAT, 0); class_addmethod(sigfiddle_class, (t_method)sigfiddle_reattack, gensym("reattack"), A_FLOAT, A_FLOAT, 0); class_addmethod(sigfiddle_class, (t_method)sigfiddle_vibrato, gensym("vibrato"), A_FLOAT, A_FLOAT, 0); class_addmethod(sigfiddle_class, (t_method)sigfiddle_npartial, gensym("npartial"), A_FLOAT, 0); class_addmethod(sigfiddle_class, (t_method)sigfiddle_auto, gensym("auto"), A_FLOAT, 0); class_addmethod(sigfiddle_class, (t_method)sigfiddle_print, gensym("print"), 0); class_addmethod(sigfiddle_class, nullfn, gensym("signal"), 0); class_addbang(sigfiddle_class, sigfiddle_bang); class_addcreator((t_newmethod)sigfiddle_new, gensym("fiddle"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); post(fiddle_version); } void fiddle_setup(void) { fiddle_tilde_setup(); } #endif /* PD */ #ifdef MAX26 void cu_fiddle(t_float *in1, t_sigfiddle *x, int n) { int count; t_float *fp, *fp2; for (count = 0, fp = x->x_inbuf + x->x_phase; count < n; count++) *fp++ = *in1++; if (fp == x->x_inbuf + x->x_hop) { sigfiddle_doit(x); x->x_phase = 0; if (x->x_auto) clock_delay(x->x_clock, 0L); if (x->x_nprint) x->x_nprint--; } else x->x_phase += n; } void sigfiddle_put(t_sigfiddle *x, long whether) { if (whether) { u_stdout(x); x->x_sr = x->x_io[0]->s_sr; sigfiddle_reattack(x, x->x_attacktime, x->x_attackthresh); sigfiddle_vibrato(x, x->x_vibtime, x->x_vibdepth); dspchain_addc(cu_fiddle, 3, x->x_io[0]->s_shit, x, x->x_io[0]->s_n); } } void sigfiddle_tick(t_sigfiddle *x) /* callback function for the clock */ { int i; t_pitchhist *ph; outlet_float(x->x_envout, x->x_dbs[x->x_histphase]); for (i = 0, ph = x->x_hist; i < x->x_npitch; i++, ph++) { t_atom at[2]; SETFLOAT(at, ph->h_pitches[x->x_histphase]); SETFLOAT(at+1, ph->h_amps[x->x_histphase]); outlet_list(ph->h_outlet, NIL, 2, at); } if (x->x_attackvalue) outlet_bang(x->x_attackout); for (i = 0, ph = x->x_hist; i < x->x_npitch; i++, ph++) if (ph->h_pitch) outlet_float(x->x_noteout, ph->h_pitch); } void sigfiddle_ff(t_sigfiddle *x) /* cleanup on free */ { if (x->x_inbuf) { freebytes(x->x_inbuf, sizeof(t_float) * x->x_hop); freebytes(x->x_lastanalysis, sizeof(t_float) * (2*x->x_hop + 4 * FILTSIZE)); freebytes(x->x_spiral, sizeof(t_float) * 2*x->x_hop); clock_free(x->x_clock); u_clean(x); } } t_externclass *sigfiddle_class; void *sigfiddle_new(long npoints, long npitch, long npeakanal, long npeakout) { t_sigfiddle *x = (t_sigfiddle *)obj_new(&sigfiddle_class, 0); int i; if (!sigfiddle_doinit(x, npoints, npitch, npeakanal, npeakout)) { x->x_inbuf = 0; /* prevent the free routine from cleaning up */ obj_free(x); return (0); } u_setup(x, IN1, OUT0); x->x_envout = outlet_new(x, gensym("float")); for (i = 0; i < x->x_npitch; i++) x->x_hist[i].h_outlet = outlet_new(x, gensym("list")); x->x_attackout = outlet_new(x, gensym("bang")); x->x_noteout = outlet_new(x, gensym("float")); x->x_clock = clock_new(x, sigfiddle_tick); return (x); } void fiddle_setup() { c_extern(&sigfiddle_class, sigfiddle_new, sigfiddle_ff, gensym("fiddle"), sizeof(t_sigfiddle), 0, A_DEFLONG, A_DEFLONG, A_DEFLONG, A_DEFLONG, 0); c_addmess(sigfiddle_put, gensym("put"), A_CANT, 0); c_addmess(sigfiddle_debug, gensym("debug"), 0); c_addmess(sigfiddle_amprange, gensym("amp-range"), A_FLOAT, A_FLOAT, 0); c_addmess(sigfiddle_reattack, gensym("reattack"), A_FLOAT, A_FLOAT, 0); c_addmess(sigfiddle_vibrato, gensym("vibrato"), A_LONG, A_FLOAT, 0); c_addmess(sigfiddle_npartial, gensym("npartial"), A_FLOAT, 0); c_addmess(sigfiddle_print, gensym("print"), 0); u_inletmethod(0); /* one signal input */ #ifdef MAX post(fiddle_version); #endif } #endif /* MAX26 */ /************* Beginning of MSP Code ******************************/ #ifdef MSP static t_int *fiddle_perform(t_int *w) { t_float *in = (t_float *)(w[1]); t_sigfiddle *x = (t_sigfiddle *)(w[2]); int n = (int)(w[3]); int count,inc = x->x_downsample; t_float *fp; if (x->x_obj.z_disabled) goto skip; for (count = 0, fp = x->x_inbuf + x->x_phase; count < n; count+=inc) { *fp++ = *in; in += inc; } if (fp == x->x_inbuf + x->x_hop) { sigfiddle_doit(x); x->x_phase = 0; if (x->x_auto) clock_delay(x->x_clock, 0L); if (x->x_nprint) x->x_nprint--; } else x->x_phase += n; skip: return (w+4); } void sigfiddle_dsp(t_sigfiddle *x, t_signal **sp) { if (sp[0]->s_n > x->x_hop) { x->x_downsample = sp[0]->s_n / x->x_hop; post("* warning: fiddle~: will downsample input by %ld",x->x_downsample); x->x_sr = sp[0]->s_sr / x->x_downsample; } else { x->x_downsample = 1; x->x_sr = sp[0]->s_sr; } sigfiddle_reattack(x, x->x_attacktime, x->x_attackthresh); sigfiddle_vibrato(x, x->x_vibtime, x->x_vibdepth); dsp_add(fiddle_perform, 3, sp[0]->s_vec, x, sp[0]->s_n); } void sigfiddle_tick(t_sigfiddle *x) /* callback function for the clock MSP*/ { int i; t_pitchhist *ph; if (x->x_npeakout) { int npeakout = x->x_npeakout; t_peakout *po; for (i = 0, po = x->x_peakbuf; i < npeakout; i++, po++) { t_atom at[3]; SETINT(at, i+1); SETFLOAT(at+1, po->po_freq); SETFLOAT(at+2, po->po_amp); outlet_list(x->x_peakout, 0, 3, at); } } outlet_float(x->x_envout, x->x_dbs[x->x_histphase]); for (i = 0, ph = x->x_hist; i < x->x_npitch; i++, ph++) { t_atom at[2]; SETFLOAT(at, ph->h_pitches[x->x_histphase]); SETFLOAT(at+1, ph->h_amps[x->x_histphase]); outlet_list(ph->h_outlet, 0, 2, at); } if (x->x_attackvalue) outlet_bang(x->x_attackout); for (i = 0, ph = x->x_hist; i < x->x_npitch; i++, ph++) if (ph->h_pitch) outlet_float(x->x_noteout, ph->h_pitch); } void sigfiddle_bang(t_sigfiddle *x) { int i; t_pitchhist *ph; if (x->x_npeakout) { int npeakout = x->x_npeakout; t_peakout *po; for (i = 0, po = x->x_peakbuf; i < npeakout; i++, po++) { t_atom at[3]; SETLONG(at, i+1); SETFLOAT(at+1, po->po_freq); SETFLOAT(at+2, po->po_amp); outlet_list(x->x_peakout, 0, 3, at); } } outlet_float(x->x_envout, x->x_dbs[x->x_histphase]); for (i = 0, ph = x->x_hist; i < x->x_npitch; i++, ph++) { t_atom at[2]; SETFLOAT(at, ph->h_pitches[x->x_histphase]); SETFLOAT(at+1, ph->h_amps[x->x_histphase]); outlet_list(ph->h_outlet, 0, 2, at); } if (x->x_attackvalue) outlet_bang(x->x_attackout); for (i = 0, ph = x->x_hist; i < x->x_npitch; i++, ph++) if (ph->h_pitch) outlet_float(x->x_noteout, ph->h_pitch); } void sigfiddle_ff(t_sigfiddle *x) /* cleanup on free MSP */ { if (x->x_inbuf) { t_freebytes(x->x_inbuf, sizeof(t_float) * x->x_hop); t_freebytes(x->x_lastanalysis, sizeof(t_float) * (2*x->x_hop + 4 * FILTSIZE)); t_freebytes(x->x_spiral, sizeof(t_float) * 2*x->x_hop); t_freebytes(x->x_peakbuf, sizeof(*x->x_peakbuf) * x->x_npeakout); } dsp_free((t_pxobject *)x); } void *sigfiddle_class; void *sigfiddle_new(long npoints, long npitch, long npeakanal, long npeakout) { t_sigfiddle *x = (t_sigfiddle *)newobject(sigfiddle_class); int i; if (!sigfiddle_doinit(x, npoints, npitch, npeakanal, npeakout)) { x->x_inbuf = 0; /* prevent the free routine from cleaning up */ return (0); } dsp_setup((t_pxobject *)x,1); x->x_clock = clock_new(x, (method)sigfiddle_tick); if (x->x_npeakout) x->x_peakout = listout((t_object *)x); else x->x_peakout = 0; x->x_envout = floatout((t_object *)x); for (i = 0; i < x->x_npitch; i++) x->x_hist[i].h_outlet = listout((t_object *)x); x->x_attackout = bangout((t_object *)x); x->x_noteout = floatout((t_object *)x); return (x); } void main() { setup(&sigfiddle_class, sigfiddle_new, (method)sigfiddle_ff, (short)sizeof(t_sigfiddle), 0L, A_DEFLONG, A_DEFLONG, A_DEFLONG, A_DEFLONG, 0); addmess((method)sigfiddle_dsp, "dsp", A_CANT, 0); addmess((method)sigfiddle_debug, "debug", 0); addmess((method)sigfiddle_setnpoints, "npoints", A_FLOAT, 0); addmess((method)sigfiddle_amprange, "amp-range", A_FLOAT, A_FLOAT, 0); addmess((method)sigfiddle_reattack, "reattack", A_FLOAT, A_FLOAT, 0); addmess((method)sigfiddle_vibrato, "vibrato", A_FLOAT, A_FLOAT, 0); addmess((method)sigfiddle_npartial, "npartial", A_FLOAT, 0); addmess((method)sigfiddle_auto, "auto", A_FLOAT, 0); addmess((method)sigfiddle_print, "print", 0); addmess((method)sigfiddle_assist, "assist", A_CANT, 0); addbang((method)sigfiddle_bang); dsp_initclass(); rescopy('STR#',3748); post(fiddle_version); } void sigfiddle_assist(t_sigfiddle *x, void *b, long m, long a, char *s) { assist_string(3748,m,a,1,2,s); } void msp_fft(t_float *buf, long np, long inv) { t_float *src,*real,*rp,*imag,*ip; long i; /* // because this fft algorithm uses separate real and imaginary // buffers // we must split the real and imaginary parts into two buffers, // then do the opposite on output // a more ambitious person would either do an in-place conversion // or rewrite the fft algorithm */ real = rp = msp_ffttemp; imag = ip = real + MAXPOINTS; src = buf; for (i = 0; i < np; i++) { *rp++ = *src++; *ip++ = *src++; } if (inv) ifft(np,real,imag); else fft(np,real,imag); rp = real; ip = imag; src = buf; for (i = 0; i < np; i++) { *src++ = *rp++; *src++ = *ip++; } } #endif /* MSP */ pd-0.46-7/extra/fiddle~/GNUmakefile.am0000664000175000017500000000126212374250720015615 0ustar mspmsp## Makefile.am -- Process this file with automake to produce Makefile.in NAME=fiddle~ external_LTLIBRARIES = fiddle~.la SOURCES = fiddle~.c PATCHES = fiddle~-help.pd OTHERDATA = EXTRA_DIST = makefile ############################### # you shouldn't need to add anything below here dist_external_DATA = $(PATCHES) $(OTHERDATA) AUTOMAKE_OPTIONS = foreign AM_CPPFLAGS = -I$(top_srcdir)/src -DPD AM_CFLAGS = @ARCH_CFLAGS@ AM_LIBS = $(LIBM) AM_LDFLAGS = -module -avoid-version -shared @ARCH_LDFLAGS@ -shrext .@EXTERNAL_EXTENSION@ -L$(top_srcdir)/src externaldir = $(pkglibdir)/extra/$(NAME) if MINGW AM_LIBS += -lpd endif libtool: $(LIBTOOL_DEPS) $(SHELL) ./config.status --recheck pd-0.46-7/extra/fiddle~/makefile0000664000175000017500000000007312160204055014637 0ustar mspmspNAME=fiddle~ CSYM=fiddle_tilde include ../makefile.subdir pd-0.46-7/extra/fiddle~/fiddle~-help.pd0000664000175000017500000001205112160204055016036 0ustar mspmsp#N canvas 93 26 980 745 10; #X obj 262 522 phasor~; #X obj 531 616 unpack; #X floatatom 531 666 0 0 0 0 - - -; #X msg 437 449 print; #X obj 262 500 sig~; #X floatatom 262 478 0 0 0 0 - - -; #X obj 262 456 mtof; #X floatatom 262 434 0 0 0 0 - - -; #X floatatom 545 643 0 0 0 0 - - -; #X obj 531 576 route 1 2 3 4; #X obj 614 616 unpack; #X floatatom 614 666 0 0 0 0 - - -; #X floatatom 628 643 0 0 0 0 - - -; #X obj 698 616 unpack; #X floatatom 698 666 0 0 0 0 - - -; #X floatatom 712 643 0 0 0 0 - - -; #X obj 389 616 unpack; #X floatatom 389 666 0 0 0 0 - - -; #X floatatom 403 643 0 0 0 0 - - -; #X obj 334 545 *~; #X obj 322 394 loadbang; #X obj 353 522 sig~; #X floatatom 353 500 0 0 0 0 - - -; #X msg 322 478 1; #X msg 353 478 0; #X floatatom 466 666 0 0 0 0 - - -; #X obj 281 666 print attack; #X obj 190 666 print pitch; #X msg 555 45 \; pd dsp 1; #X text 460 39 click here; #X text 460 61 to start DSP; #X text 226 4 FIDDLE - pitch estimator and sinusoidal peak finder; #X text 8 70 The Fiddle object estimates the pitch and amplitude of an incoming sound \, both continuously and as a stream of discrete "note" events. Fiddle optionally outputs a list of detected sinusoidal peaks used to make the pitch determination. Fiddle is described theoretically in the 1998 ICMC proceedings \, reprinted on http://man104nfs.ucsd.edu/~mpuckett. ; #X text 8 170 Fiddle's creation arguments specify an analysis window size \, the maximum polyphony (i.e. \, the number of simultaneous "pitches" to try to find) \, the number of peaks in the spectrum to consider \, and the number of peaks \, if any \, to output "raw." The outlets give discrete pitch (a number) \, detected attacks in the amplitude envelope (a bang) \, one or more voices of continuous pitch and amplitude \, overall amplitude \, and optionally a sequence of messages with the peaks.; #X text 8 296 The analysis hop size is half the window size so in the example shown here \, one analysis is done every 512 samples (11.6 msec at 44K1) \, and the analysis uses the most recent 1024 samples (23.2 msec at 44K1). The minimum frequency that Fiddle will report is 2-1/2 cycles per analysis windows \, or about 108 Hz. (just below MIDI 45.); #X text 669 535 number of pitch outlets (1-3 \, default 1); #X text 669 557 number of peaks to find (1-100 \, default 20); #X text 669 579 number of peaks to output (default 0.); #X msg 441 107 amp-range 40 50; #X msg 439 227 reattack 100 10; #X msg 438 282 npartial 7; #X msg 438 170 vibrato 50 0.5; #X text 560 91 a low and high amplitude threshold: if signal amplitude is below the low threshold \, no pitches or peaks are output. The high threshold is a minimum at which "cooked" outputs may appear.; #X text 560 152 A period in milliseconds (50) over which the raw pitch may not deviate more than an interval in half-tones (0.5) from the average pitch to report it as a note to the "cooked" pitch outlet. ; #X text 560 213 A period in milliseconds (100) over which a re-attack is reported if the amplitude rises more than (1) dB. The re-attack will result in a "bang" in the attack outlet and may give rise to repeated notes in the cooked pitch output.; #X text 142 432 test input pitch; #X text 330 444 test input; #X text 330 457 amplitude; #X obj 410 545 fiddle~ 1024 1 20 3; #X text 538 690 individual sinusoidal components; #X text 466 688 amplitude; #X text 476 703 (dB); #X text 389 688 raw pitch; #X text 376 712 and amplitude; #X text 364 729 (up to 3 outputs); #X text 287 686 bang on; #X text 287 708 attack; #X text 185 686 cooked pitch; #X text 202 703 output; #X text 545 545 ------ arguments:; #X msg 262 412 57; #X msg 440 331 auto 1; #X msg 440 353 auto 0; #X msg 439 418 bang; #X text 561 416 poll current values --- useful if not in auto mode \,; #X text 560 274 Higher partials are weighed less strongly than lower ones in determining the pitch. This specifies the number of the partial (7) which will be weighted half as strongly as the fundamental.; #X text 560 335 start and stop "auto" mode (on by default.) If off \, output only appears on "bang" (poll mode).; #X text 561 448 print out all settings; #X text 669 513 window size (128-2048 \, default 1024); #X msg 440 375 npoints 2048; #X text 562 384 number of points in analysis window (power of 2 \, 128-2048); #X msg 439 396 npoints 1024; #X connect 0 0 19 0; #X connect 1 0 2 0; #X connect 1 1 8 0; #X connect 3 0 48 0; #X connect 4 0 0 0; #X connect 5 0 4 0; #X connect 6 0 5 0; #X connect 7 0 6 0; #X connect 9 0 1 0; #X connect 9 1 10 0; #X connect 9 2 13 0; #X connect 10 0 11 0; #X connect 10 1 12 0; #X connect 13 0 14 0; #X connect 13 1 15 0; #X connect 16 0 17 0; #X connect 16 1 18 0; #X connect 19 0 48 0; #X connect 20 0 60 0; #X connect 20 0 23 0; #X connect 21 0 19 1; #X connect 22 0 21 0; #X connect 23 0 22 0; #X connect 24 0 22 0; #X connect 38 0 48 0; #X connect 39 0 48 0; #X connect 40 0 48 0; #X connect 41 0 48 0; #X connect 48 0 27 0; #X connect 48 1 26 0; #X connect 48 2 16 0; #X connect 48 3 25 0; #X connect 48 4 9 0; #X connect 60 0 7 0; #X connect 61 0 48 0; #X connect 62 0 48 0; #X connect 63 0 48 0; #X connect 69 0 48 0; #X connect 71 0 48 0; pd-0.46-7/extra/rev1~.pd0000664000175000017500000000325112374250720013122 0ustar mspmsp#N canvas 65 115 537 339 10; #X obj 345 154 dbtorms; #X obj 316 120 min 100; #X obj 316 100 inlet; #X obj 45 16 inlet~; #X obj 254 298 outlet~; #X obj 432 106 inlet; #X obj 432 130 t b; #X obj 269 145 t b f; #X obj 281 185 -; #X obj 282 254 line~; #X obj 282 233 pack 0 100; #X obj 269 166 105; #X obj 256 276 *~; #X obj 282 210 * 0.01; #X text 282 65 reverb decay speed; #X text 278 79 (dB left after 1 sec); #X text 425 84 bang to clear; #X obj 44 41 rev1-stage \$0 \$0-del1 0 8; #X obj 44 64 rev1-stage \$0 \$0-del2 1 14.32; #X obj 44 87 rev1-stage \$0 \$0-del3 2 25.6328; #X obj 44 110 rev1-stage \$0 \$0-del4 3 45.8827; #X obj 44 133 rev1-stage \$0 \$0-del5 4 82.1301; #X obj 44 156 rev1-stage \$0 \$0-del6 5 147.013; #X obj 44 179 rev1-stage \$0 \$0-del7 6 263.153; #X obj 44 202 rev1-stage \$0 \$0-del8 7 471.044; #X obj 44 225 rev1-stage \$0 \$0-del9 8 843.168; #X obj 44 248 rev1-final \$0 \$0-del10 9 1509.27; #X obj 346 177 s \$0-decay; #X obj 432 153 s \$0-clear; #X connect 0 0 27 0; #X connect 1 0 0 0; #X connect 1 0 7 0; #X connect 2 0 1 0; #X connect 3 0 17 0; #X connect 5 0 6 0; #X connect 6 0 28 0; #X connect 7 0 11 0; #X connect 7 1 8 1; #X connect 8 0 13 0; #X connect 9 0 12 1; #X connect 10 0 9 0; #X connect 11 0 8 0; #X connect 12 0 4 0; #X connect 13 0 10 0; #X connect 17 0 18 0; #X connect 17 1 18 1; #X connect 18 0 19 0; #X connect 18 1 19 1; #X connect 19 0 20 0; #X connect 19 1 20 1; #X connect 20 0 21 0; #X connect 20 1 21 1; #X connect 21 0 22 0; #X connect 21 1 22 1; #X connect 22 0 23 0; #X connect 22 1 23 1; #X connect 23 0 24 0; #X connect 23 1 24 1; #X connect 24 0 25 0; #X connect 24 1 25 1; #X connect 25 0 26 0; #X connect 25 1 26 1; #X connect 26 1 12 0; pd-0.46-7/extra/expr~/0000775000175000017500000000000012574202336012677 5ustar mspmsppd-0.46-7/extra/expr~/vexp.c0000664000175000017500000025251312574135745014046 0ustar mspmsp/* * jMax * Copyright (C) 1994, 1995, 1998, 1999 by IRCAM-Centre Georges Pompidou, Paris, France. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * See file LICENSE for further informations on licensing terms. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Based on Max/ISPW by Miller Puckette. * * Authors: Maurizio De Cecco, Francois Dechelle, Enzo Maggi, Norbert Schnell. * */ /* "expr" was written by Shahrokh Yadegari c. 1989. -msp */ /* "expr~" and "fexpr~" conversion by Shahrokh Yadegari c. 1999,2000 */ /* * Feb 2002 - added access to variables * multiple expression support * new short hand forms for fexpr~ * now $y or $y1 = $y1[-1] and $y2 = $y2[-1] * --sdy * * July 2002 * fixed bugs introduced in last changes in store and ET_EQ * --sdy * */ /* * vexp.c -- a variable expression evaluator * * This modules implements an expression evaluator using the * operator-precedence parsing. It transforms an infix expression * to a prefix stack ready to be evaluated. The expression sysntax * is close to that of C. There are a few operators that are not * supported and functions are also recognized. Strings can be * passed to functions when they are quoted in '"'s. "[]" are implememted * as an easy way of accessing the content of tables, and the syntax * table_name[index]. * Variables (inlets) are specified with the following syntax: $x#, * where x is either i(integers), f(floats), and s(strings); and # * is a digit that coresponds to the inlet number. The string variables * can be used as strings when they are quoted and can also be used as * table names when they are followed by "[]". * * signal vectors have been added to this implementation: * $v# denotes a signal vector * $x#[index] is the value of a sample at the index of a the signal vector * $x# is the shorthand for $x#[0] * $y[index] is the value of the sample output at the index of a the * signal output * "index" for $x#[index] has to have this range (0 <= index < vectorsize) * "index" for $y[index] has to have this range (0 < index < vectorsize) */ #include #include #include #include "vexp.h" #ifdef MSP #undef isdigit #define isdigit(x) (x >= '0' && x <= '9') #endif char *atoif(char *s, long int *value, long int *type); static struct ex_ex *ex_lex(struct expr *expr, long int *n); struct ex_ex *ex_match(struct ex_ex *eptr, long int op); struct ex_ex *ex_parse(struct expr *expr, struct ex_ex *iptr, struct ex_ex *optr, long int *argc); struct ex_ex *ex_eval(struct expr *expr, struct ex_ex *eptr, struct ex_ex *optr, int i); int expr_donew(struct expr *exprr, int ac, t_atom *av); struct ex_ex *eval_func(struct expr *expr,struct ex_ex *eptr, struct ex_ex *optr, int i); struct ex_ex *eval_tab(struct expr *expr, struct ex_ex *eptr, struct ex_ex *optr, int i); struct ex_ex *eval_var(struct expr *expr, struct ex_ex *eptr, struct ex_ex *optr, int i); struct ex_ex *eval_store(struct expr *expr, struct ex_ex *eptr, struct ex_ex *optr, int i); struct ex_ex *eval_sigidx(struct expr *expr, struct ex_ex *eptr, struct ex_ex *optr, int i); static int cal_sigidx(struct ex_ex *optr, /* The output value */ int i, t_float rem_i, /* integer and fractinal part of index */ int idx, /* index of current fexpr~ processing */ int vsize, /* vector size */ t_float *curvec, t_float *prevec); /* current and previous table */ t_ex_func *find_func(char *s); void ex_dzdetect(struct expr *expr); #define MAX_ARGS 10 extern t_ex_func ex_funcs[]; struct ex_ex nullex; void set_tokens (char *s); int getoken (struct expr *expr, struct ex_ex *eptr); void ex_print (struct ex_ex *eptr); #ifdef MSP void atom_string(t_atom *a, char *buf, unsigned int bufsize); void atom_string(t_atom *a, char *buf, unsigned int bufsize) { char tbuf[30]; switch(a->a_type) { case A_SEMI: strcpy(buf, ";"); break; case A_COMMA: strcpy(buf, ","); break; #ifdef PD case A_POINTER: strcpy(buf, "(pointer)"); break; #endif case A_FLOAT: sprintf(tbuf, "%g", a->a_w.w_float); if (strlen(tbuf) < bufsize-1) strcpy(buf, tbuf); else if (a->a_w.w_float < 0) strcpy(buf, "-"); else strcat(buf, "+"); break; case A_LONG: sprintf(tbuf, "%d", a->a_w.w_long); if (strlen(tbuf) < bufsize-1) strcpy(buf, tbuf); else if (a->a_w.w_float < 0) strcpy(buf, "-"); else strcat(buf, "+"); break; case A_SYMBOL: { char *sp; unsigned int len; int quote; for (sp = a->a_w.w_symbol->s_name, len = 0, quote = 0; *sp; sp++, len++) if (*sp == ';' || *sp == ',' || *sp == '\\' || (*sp == '$' && sp == a->a_w.w_symbol->s_name && sp[1] >= '0' && sp[1] <= '9')) quote = 1; if (quote) { char *bp = buf, *ep = buf + (bufsize-2); sp = a->a_w.w_symbol->s_name; while (bp < ep && *sp) { if (*sp == ';' || *sp == ',' || *sp == '\\' || (*sp == '$' && bp == buf && sp[1] >= '0' && sp[1] <= '9')) *bp++ = '\\'; *bp++ = *sp++; } if (*sp) *bp++ = '*'; *bp = 0; /* post("quote %s -> %s", a->a_w.w_symbol->s_name, buf); */ } else { if (len < bufsize-1) strcpy(buf, a->a_w.w_symbol->s_name); else { strncpy(buf, a->a_w.w_symbol->s_name, bufsize - 2); strcpy(buf + (bufsize - 2), "*"); } } } break; #ifdef PD case A_DOLLAR: sprintf(buf, "$%d", a->a_w.w_index); break; case A_DOLLSYM: sprintf(buf, "$%s", a->a_w.w_symbol->s_name); break; #else /* MAX */ case A_DOLLAR: sprintf(buf, "$%s", a->a_w.w_symbol->s_name); break; #endif default: post("atom_string bug"); } } #endif /* MSP */ /* * expr_donew -- create a new "expr" object. * returns 1 on failure, 0 on success. */ int expr_donew(struct expr *expr, int ac, t_atom *av) { struct ex_ex *list; struct ex_ex *ret; long max_node = 0; /* maximum number of nodes needed */ char *exp_string; int exp_strlen; t_binbuf *b; int i; memset(expr->exp_var, 0, MAX_VARS * sizeof (*expr->exp_var)); #ifdef PD b = binbuf_new(); binbuf_add(b, ac, av); binbuf_gettext(b, &exp_string, &exp_strlen); #else /* MSP */ { char *buf = getbytes(0), *newbuf; int length = 0; char string[250]; t_atom *ap; int indx; for (ap = av, indx = 0; indx < ac; indx++, ap = ++av) { int newlength; if ((ap->a_type == A_SEMI || ap->a_type == A_COMMA) && length && buf[length-1] == ' ') length--; atom_string(ap, string, 250); newlength = length + strlen(string) + 1; if (!(newbuf = t_resizebytes(buf, length, newlength))) break; buf = newbuf; strcpy(buf + length, string); length = newlength; if (ap->a_type == A_SEMI) buf[length-1] = '\n'; else buf[length-1] = ' '; } if (length && buf[length-1] == ' ') { if (newbuf = t_resizebytes(buf, length, length-1)) { buf = newbuf; length--; } } exp_string = buf; exp_strlen = length; } #endif exp_string = (char *)t_resizebytes(exp_string, exp_strlen,exp_strlen+1); exp_string[exp_strlen] = 0; expr->exp_string = exp_string; expr->exp_str = exp_string; expr->exp_nexpr = 0; ret = (struct ex_ex *) 0; /* * if ret == 0 it means that we have no expression * so we let the pass go through to build a single null stack */ while (*expr->exp_str || !ret) { list = ex_lex(expr, &max_node); if (!list) { /* syntax error */ goto error; } expr->exp_stack[expr->exp_nexpr] = (struct ex_ex *)fts_malloc(max_node * sizeof (struct ex_ex)); expr->exp_nexpr++; ret = ex_match(list, (long)0); if (expr->exp_nexpr > MAX_VARS) /* we cannot exceed MAX_VARS '$' variables */ { post_error((fts_object_t *) expr, "expr: too many variables (maximum %d allowed)", MAX_VARS); goto error; } if (!ret) /* syntax error */ goto error; ret = ex_parse(expr, list, expr->exp_stack[expr->exp_nexpr - 1], (long *)0); if (!ret) goto error; } *ret = nullex; t_freebytes(exp_string, exp_strlen+1); return (0); error: for (i = 0; i < expr->exp_nexpr; i++) { fts_free(expr->exp_stack[i]); expr->exp_stack[i] = 0; } expr->exp_nexpr = 0; if (list) fts_free(list); t_freebytes(exp_string, exp_strlen+1); return (1); } /* * ex_lex -- This routine is a bit more than a lexical parser since it will * also do some syntax checking. It reads the string s and will * return a linked list of struct ex_ex. * It will also put the number of the nodes in *n. */ struct ex_ex * ex_lex(struct expr *expr, long int *n) { struct ex_ex *list_arr; struct ex_ex *exptr; long non = 0; /* number of nodes */ long maxnode = 0; list_arr = (struct ex_ex *)fts_malloc(sizeof (struct ex_ex) * MINODES); if (! list_arr) { post("ex_lex: no mem\n"); return ((struct ex_ex *)0); } exptr = list_arr; maxnode = MINODES; while (8) { if (non >= maxnode) { maxnode += MINODES; list_arr = fts_realloc((void *)list_arr, sizeof (struct ex_ex) * maxnode); if (!list_arr) { post("ex_lex: no mem\n"); return ((struct ex_ex *)0); } exptr = &(list_arr)[non]; } if (getoken(expr, exptr)) { fts_free(list_arr); return ((struct ex_ex *)0); } non++; if (!exptr->ex_type) break; exptr++; } *n = non; return list_arr; } /* * ex_match -- this routine walks through the eptr and matches the * perentheses and brackets, it also converts the function * names to a pointer to the describing structure of the * specified function */ /* operator to match */ struct ex_ex * ex_match(struct ex_ex *eptr, long int op) { int firstone = 1; struct ex_ex *ret; t_ex_func *fun; for (; 8; eptr++, firstone = 0) { switch (eptr->ex_type) { case 0: if (!op) return (eptr); post("expr syntax error: an open %s not matched\n", op == OP_RP ? "parenthesis" : "bracket"); return (exNULL); case ET_INT: case ET_FLT: case ET_II: case ET_FI: case ET_SI: case ET_VI: case ET_SYM: case ET_VSYM: continue; case ET_YO: if (eptr[1].ex_type != ET_OP || eptr[1].ex_op != OP_LB) eptr->ex_type = ET_YOM1; continue; case ET_XI: if (eptr[1].ex_type != ET_OP || eptr[1].ex_op != OP_LB) eptr->ex_type = ET_XI0; continue; case ET_TBL: case ET_FUNC: case ET_LP: /* CHANGE case ET_RP: */ case ET_LB: /* CHANGE case ET_RB: */ post("ex_match: unexpected type, %ld\n", eptr->ex_type); return (exNULL); case ET_OP: if (op == eptr->ex_op) return (eptr); /* * if we are looking for a right peranthesis * or a right bracket and find the other kind, * it has to be a syntax error */ if ((eptr->ex_op == OP_RP && op == OP_RB) || (eptr->ex_op == OP_RB && op == OP_RP)) { post("expr syntax error: prenthesis or brackets not matched\n"); return (exNULL); } /* * Up to now we have marked the unary minuses as * subrtacts. Any minus that is the first one in * chain or is preceeded by anything except ')' and * ']' is a unary minus. */ if (eptr->ex_op == OP_SUB) { ret = eptr - 1; if (firstone || (ret->ex_type == ET_OP && ret->ex_op != OP_RB && ret->ex_op != OP_RP)) eptr->ex_op = OP_UMINUS; } else if (eptr->ex_op == OP_LP) { ret = ex_match(eptr + 1, OP_RP); if (!ret) return (ret); eptr->ex_type = ET_LP; eptr->ex_ptr = (char *) ret; eptr = ret; } else if (eptr->ex_op == OP_LB) { ret = ex_match(eptr + 1, OP_RB); if (!ret) return (ret); eptr->ex_type = ET_LB; eptr->ex_ptr = (char *) ret; eptr = ret; } continue; case ET_STR: if (eptr[1].ex_op == OP_LB) { char *tmp; eptr->ex_type = ET_TBL; tmp = eptr->ex_ptr; if (ex_getsym(tmp, (t_symbol **)&(eptr->ex_ptr))) { post("expr: syntax error: problms with ex_getsym\n"); return (exNULL); } fts_free((void *)tmp); } else if (eptr[1].ex_op == OP_LP) { fun = find_func(eptr->ex_ptr); if (!fun) { post( "expr: error: function %s not found\n", eptr->ex_ptr); return (exNULL); } eptr->ex_type = ET_FUNC; eptr->ex_ptr = (char *) fun; } else { char *tmp; if (eptr[1].ex_type && eptr[1].ex_type!=ET_OP){ post("expr: syntax error: bad string '%s'\n", eptr->ex_ptr); return (exNULL); } /* it is a variable */ eptr->ex_type = ET_VAR; tmp = eptr->ex_ptr; if (ex_getsym(tmp, (t_symbol **)&(eptr->ex_ptr))) { post("expr: variable '%s' not found",tmp); return (exNULL); } } continue; default: post("ex_match: bad type\n"); return (exNULL); } } /* NOTREACHED */ } /* * ex_parse -- This function if called when we have already done some * parsing on the expression, and we have already matched * our brackets and parenthesis. The main job of this * function is to convert the infix expression to the * prefix form. * First we find the operator with the lowest precedence and * put it on the stack ('optr', it is really just an array), then * we call ourself (ex_parse()), on its arguments (unary operators * only have one operator.) * When "argc" is set it means that we are parsing the arguments * of a function and we will increment *argc anytime we find * a a segment that can qualify as an argument (counting commas). * * returns 0 on syntax error */ /* number of argument separated by comma */ struct ex_ex * ex_parse(struct expr *x, struct ex_ex *iptr, struct ex_ex *optr, long int *argc) { struct ex_ex *eptr; struct ex_ex *lowpre = 0; /* pointer to the lowest precedence */ struct ex_ex savex; long pre = HI_PRE; long count; if (!iptr) { post("ex_parse: input is null, iptr = 0x%lx\n", iptr); return (exNULL); } if (!iptr->ex_type) return (exNULL); /* * the following loop finds the lowest precedence operator in the * the input token list, comma is explicitly checked here since * that is a special operator and is only legal in functions */ for (eptr = iptr, count = 0; eptr->ex_type; eptr++, count++) switch (eptr->ex_type) { case ET_SYM: case ET_VSYM: if (!argc) { post("expr: syntax error: symbols allowed for functions only\n"); ex_print(eptr); return (exNULL); } case ET_INT: case ET_FLT: case ET_II: case ET_FI: case ET_XI0: case ET_YOM1: case ET_VI: case ET_VAR: if (!count && !eptr[1].ex_type) { *optr++ = *eptr; return (optr); } break; case ET_XI: case ET_YO: case ET_SI: case ET_TBL: if (eptr[1].ex_type != ET_LB) { post("expr: syntax error: brackets missing\n"); ex_print(eptr); return (exNULL); } /* if this table is the only token, parse the table */ if (!count && !((struct ex_ex *) eptr[1].ex_ptr)[1].ex_type) { savex = *((struct ex_ex *) eptr[1].ex_ptr); *((struct ex_ex *) eptr[1].ex_ptr) = nullex; *optr++ = *eptr; lowpre = ex_parse(x, &eptr[2], optr, (long *)0); *((struct ex_ex *) eptr[1].ex_ptr) = savex; return(lowpre); } eptr = (struct ex_ex *) eptr[1].ex_ptr; break; case ET_OP: if (eptr->ex_op == OP_COMMA) { if (!argc || !count || !eptr[1].ex_type) { post("expr: syntax error: illegal comma\n"); ex_print(eptr[1].ex_type ? eptr : iptr); return (exNULL); } } if (!eptr[1].ex_type) { post("expr: syntax error: missing operand\n"); ex_print(iptr); return (exNULL); } if ((eptr->ex_op & PRE_MASK) <= pre) { pre = eptr->ex_op & PRE_MASK; lowpre = eptr; } break; case ET_FUNC: if (eptr[1].ex_type != ET_LP) { post("expr: ex_parse: no parenthesis\n"); return (exNULL); } /* if this function is the only token, parse it */ if (!count && !((struct ex_ex *) eptr[1].ex_ptr)[1].ex_type) { long ac; if (eptr[1].ex_ptr == (char *) &eptr[2]) { post("expr: syntax error: missing argument\n"); ex_print(eptr); return (exNULL); } ac = 0; savex = *((struct ex_ex *) eptr[1].ex_ptr); *((struct ex_ex *) eptr[1].ex_ptr) = nullex; *optr++ = *eptr; lowpre = ex_parse(x, &eptr[2], optr, &ac); if (!lowpre) return (exNULL); ac++; if (ac != ((t_ex_func *)eptr->ex_ptr)->f_argc){ post("expr: syntax error: function '%s' needs %ld arguments\n", ((t_ex_func *)eptr->ex_ptr)->f_name, ((t_ex_func *)eptr->ex_ptr)->f_argc); return (exNULL); } *((struct ex_ex *) eptr[1].ex_ptr) = savex; return (lowpre); } eptr = (struct ex_ex *) eptr[1].ex_ptr; break; case ET_LP: case ET_LB: if (!count && !((struct ex_ex *) eptr->ex_ptr)[1].ex_type) { if (eptr->ex_ptr == (char *)(&eptr[1])) { post("expr: syntax error: empty '%s'\n", eptr->ex_type==ET_LP?"()":"[]"); ex_print(eptr); return (exNULL); } savex = *((struct ex_ex *) eptr->ex_ptr); *((struct ex_ex *) eptr->ex_ptr) = nullex; lowpre = ex_parse(x, &eptr[1], optr, (long *)0); *((struct ex_ex *) eptr->ex_ptr) = savex; return (lowpre); } eptr = (struct ex_ex *)eptr->ex_ptr; break; case ET_STR: default: ex_print(eptr); post("expr: ex_parse: type = 0x%lx\n", eptr->ex_type); return (exNULL); } if (pre == HI_PRE) { post("expr: syntax error: missing operation\n"); ex_print(iptr); return (exNULL); } if (count < 2) { post("expr: syntax error: mission operand\n"); ex_print(iptr); return (exNULL); } if (count == 2) { if (lowpre != iptr) { post("expr: ex_parse: unary operator should be first\n"); return (exNULL); } if (!unary_op(lowpre->ex_op)) { post("expr: syntax error: not a uniary operator\n"); ex_print(iptr); return (exNULL); } *optr++ = *lowpre; eptr = ex_parse(x, &lowpre[1], optr, argc); return (eptr); } if (lowpre == iptr) { post("expr: syntax error: mission operand\n"); ex_print(iptr); return (exNULL); } savex = *lowpre; *lowpre = nullex; if (savex.ex_op != OP_COMMA) *optr++ = savex; else (*argc)++; eptr = ex_parse(x, iptr, optr, argc); if (eptr) { eptr = ex_parse(x, &lowpre[1], eptr, argc); *lowpre = savex; } return (eptr); } /* * this is the devide zero check for a a non devide operator */ #define DZC(ARG1,OPR,ARG2) (ARG1 OPR ARG2) #define EVAL(OPR); \ eptr = ex_eval(expr, ex_eval(expr, eptr, &left, idx), &right, idx); \ switch (left.ex_type) { \ case ET_INT: \ switch(right.ex_type) { \ case ET_INT: \ if (optr->ex_type == ET_VEC) { \ op = optr->ex_vec; \ scalar = (t_float)DZC(left.ex_int, OPR, right.ex_int); \ for (j = 0; j < expr->exp_vsize; j++) \ *op++ = scalar; \ } else { \ optr->ex_type = ET_INT; \ optr->ex_int = DZC(left.ex_int, OPR, right.ex_int); \ } \ break; \ case ET_FLT: \ if (optr->ex_type == ET_VEC) { \ op = optr->ex_vec; \ scalar = DZC(((t_float)left.ex_int), OPR, right.ex_flt);\ for (j = 0; j < expr->exp_vsize; j++) \ *op++ = scalar; \ } else { \ optr->ex_type = ET_FLT; \ optr->ex_flt = DZC(((t_float)left.ex_int), OPR, \ right.ex_flt); \ } \ break; \ case ET_VEC: \ case ET_VI: \ if (optr->ex_type != ET_VEC) { \ if (optr->ex_type == ET_VI) { \ post("expr~: Int. error %d", __LINE__); \ abort(); \ } \ optr->ex_type = ET_VEC; \ optr->ex_vec = (t_float *) \ fts_malloc(sizeof (t_float)*expr->exp_vsize); \ } \ scalar = left.ex_int; \ rp = right.ex_vec; \ op = optr->ex_vec; \ for (i = 0; i < expr->exp_vsize; i++) { \ *op++ = DZC (scalar, OPR, *rp); \ rp++; \ } \ break; \ case ET_SYM: \ default: \ post_error((fts_object_t *) expr, \ "expr: ex_eval(%d): bad right type %ld\n", \ __LINE__, right.ex_type); \ nullret = 1; \ } \ break; \ case ET_FLT: \ switch(right.ex_type) { \ case ET_INT: \ if (optr->ex_type == ET_VEC) { \ op = optr->ex_vec; \ scalar = DZC((t_float) left.ex_flt, OPR, right.ex_int); \ for (j = 0; j < expr->exp_vsize; j++) \ *op++ = scalar; \ } else { \ optr->ex_type = ET_FLT; \ optr->ex_flt = DZC(left.ex_flt, OPR, right.ex_int); \ } \ break; \ case ET_FLT: \ if (optr->ex_type == ET_VEC) { \ op = optr->ex_vec; \ scalar = DZC(left.ex_flt, OPR, right.ex_flt); \ for (j = 0; j < expr->exp_vsize; j++) \ *op++ = scalar; \ } else { \ optr->ex_type = ET_FLT; \ optr->ex_flt= DZC(left.ex_flt, OPR, right.ex_flt); \ } \ break; \ case ET_VEC: \ case ET_VI: \ if (optr->ex_type != ET_VEC) { \ if (optr->ex_type == ET_VI) { \ post("expr~: Int. error %d", __LINE__); \ abort(); \ } \ optr->ex_type = ET_VEC; \ optr->ex_vec = (t_float *) \ fts_malloc(sizeof (t_float)*expr->exp_vsize); \ } \ scalar = left.ex_flt; \ rp = right.ex_vec; \ op = optr->ex_vec; \ for (i = 0; i < expr->exp_vsize; i++) { \ *op++ = DZC(scalar, OPR, *rp); \ rp++; \ } \ break; \ case ET_SYM: \ default: \ post_error((fts_object_t *) expr, \ "expr: ex_eval(%d): bad right type %ld\n", \ __LINE__, right.ex_type); \ nullret = 1; \ } \ break; \ case ET_VEC: \ case ET_VI: \ if (optr->ex_type != ET_VEC) { \ if (optr->ex_type == ET_VI) { \ post("expr~: Int. error %d", __LINE__); \ abort(); \ } \ optr->ex_type = ET_VEC; \ optr->ex_vec = (t_float *) \ fts_malloc(sizeof (t_float)*expr->exp_vsize); \ } \ op = optr->ex_vec; \ lp = left.ex_vec; \ switch(right.ex_type) { \ case ET_INT: \ scalar = right.ex_int; \ for (i = 0; i < expr->exp_vsize; i++) { \ *op++ = DZC(*lp, OPR, scalar); \ lp++; \ } \ break; \ case ET_FLT: \ scalar = right.ex_flt; \ for (i = 0; i < expr->exp_vsize; i++) { \ *op++ = DZC(*lp, OPR, scalar); \ lp++; \ } \ break; \ case ET_VEC: \ case ET_VI: \ rp = right.ex_vec; \ for (i = 0; i < expr->exp_vsize; i++) { \ /* \ * on a RISC processor one could copy \ * 8 times in each round to get a considerable \ * improvement \ */ \ *op++ = DZC(*lp, OPR, *rp); \ rp++; lp++; \ } \ break; \ case ET_SYM: \ default: \ post_error((fts_object_t *) expr, \ "expr: ex_eval(%d): bad right type %ld\n", \ __LINE__, right.ex_type); \ nullret = 1; \ } \ break; \ case ET_SYM: \ default: \ post_error((fts_object_t *) expr, \ "expr: ex_eval(%d): bad left type %ld\n", \ __LINE__, left.ex_type); \ } \ break; /* * evaluate a unary operator, TYPE is applied to float operands */ #define EVAL_UNARY(OPR, TYPE) \ eptr = ex_eval(expr, eptr, &left, idx); \ switch(left.ex_type) { \ case ET_INT: \ if (optr->ex_type == ET_VEC) { \ ex_mkvector(optr->ex_vec,(t_float)(OPR left.ex_int),\ expr->exp_vsize);\ break; \ } \ optr->ex_type = ET_INT; \ optr->ex_int = OPR left.ex_int; \ break; \ case ET_FLT: \ if (optr->ex_type == ET_VEC) { \ ex_mkvector(optr->ex_vec, OPR (TYPE left.ex_flt),\ expr->exp_vsize);\ break; \ } \ optr->ex_type = ET_FLT; \ optr->ex_flt = OPR (TYPE left.ex_flt); \ break; \ case ET_VI: \ case ET_VEC: \ j = expr->exp_vsize; \ if (optr->ex_type != ET_VEC) { \ optr->ex_type = ET_VEC; \ optr->ex_vec = (t_float *) \ fts_malloc(sizeof (t_float)*expr->exp_vsize); \ } \ op = optr->ex_vec; \ lp = left.ex_vec; \ j = expr->exp_vsize; \ for (i = 0; i < j; i++) \ *op++ = OPR (TYPE *lp++); \ break; \ default: \ post_error((fts_object_t *) expr, \ "expr: ex_eval(%d): bad left type %ld\n", \ __LINE__, left.ex_type); \ nullret++; \ } \ break; void ex_mkvector(t_float *fp, t_float x, int size) { while (size--) *fp++ = x; } /* * ex_dzdetect -- divide by zero detected */ void ex_dzdetect(struct expr *expr) { char *etype; if (!expr->exp_error & EE_DZ) { if (IS_EXPR(expr)) etype = "expr"; else if (IS_EXPR_TILDE(expr)) etype = "expr~"; else if (IS_FEXPR_TILDE(expr)) etype = "fexpr~"; else { post ("expr -- ex_dzdetect internal error"); etype = ""; } post ("%s divide by zero detected", etype); expr->exp_error |= EE_DZ; } } /* * ex_eval -- evaluate the array of prefix expression * ex_eval returns the pointer to the first unevaluated node * in the array. This is a recursive routine. */ /* SDY all the returns in this function need to be changed so that the code ends up at the end to check for newly allocated right and left vectors which need to be freed look into the variable nullret */ struct ex_ex * ex_eval(struct expr *expr, struct ex_ex *eptr, struct ex_ex *optr, int idx) /* the expr object data pointer */ /* the operation stack */ /* the result pointer */ /* the sample numnber processed for fexpr~ */ { int i, j; t_float *lp, *rp, *op; /* left, right, and out pointer to vectors */ t_float scalar; int nullret = 0; /* did we have an error */ struct ex_ex left, right; /* left and right operands */ left.ex_type = 0; left.ex_int = 0; right.ex_type = 0; right.ex_int = 0; if (!eptr) return (exNULL); switch (eptr->ex_type) { case ET_INT: if (optr->ex_type == ET_VEC) ex_mkvector(optr->ex_vec, (t_float) eptr->ex_int, expr->exp_vsize); else *optr = *eptr; return (++eptr); case ET_FLT: if (optr->ex_type == ET_VEC) ex_mkvector(optr->ex_vec, eptr->ex_flt, expr->exp_vsize); else *optr = *eptr; return (++eptr); case ET_SYM: if (optr->ex_type == ET_VEC) { post_error((fts_object_t *) expr, "expr: ex_eval: cannot turn string to vector\n"); return (exNULL); } *optr = *eptr; return (++eptr); case ET_II: if (eptr->ex_int == -1) { post_error((fts_object_t *) expr, "expr: ex_eval: inlet number not set\n"); return (exNULL); } if (optr->ex_type == ET_VEC) { ex_mkvector(optr->ex_vec, (t_float)expr->exp_var[eptr->ex_int].ex_int, expr->exp_vsize); } else { optr->ex_type = ET_INT; optr->ex_int = expr->exp_var[eptr->ex_int].ex_int; } return (++eptr); case ET_FI: if (eptr->ex_int == -1) { post_error((fts_object_t *) expr, "expr: ex_eval: inlet number not set\n"); return (exNULL); } if (optr->ex_type == ET_VEC) { ex_mkvector(optr->ex_vec, expr->exp_var[eptr->ex_int].ex_flt, expr->exp_vsize); } else { optr->ex_type = ET_FLT; optr->ex_flt = expr->exp_var[eptr->ex_int].ex_flt; } return (++eptr); case ET_VSYM: if (optr->ex_type == ET_VEC) { post_error((fts_object_t *) expr, "expr: IntErr. vsym in for vec out\n"); return (exNULL); } if (eptr->ex_int == -1) { post_error((fts_object_t *) expr, "expr: ex_eval: inlet number not set\n"); return (exNULL); } optr->ex_type = ET_SYM; optr->ex_ptr = expr->exp_var[eptr->ex_int].ex_ptr; return(++eptr); case ET_VI: if (optr->ex_type != ET_VEC) *optr = expr->exp_var[eptr->ex_int]; else if (optr->ex_vec != expr->exp_var[eptr->ex_int].ex_vec) memcpy(optr->ex_vec, expr->exp_var[eptr->ex_int].ex_vec, expr->exp_vsize * sizeof (t_float)); return(++eptr); case ET_VEC: if (optr->ex_type != ET_VEC) { optr->ex_type = ET_VEC; optr->ex_vec = eptr->ex_vec; eptr->ex_type = ET_INT; eptr->ex_int = 0; } else if (optr->ex_vec != eptr->ex_vec) { memcpy(optr->ex_vec, eptr->ex_vec, expr->exp_vsize * sizeof (t_float)); /* do we need to free here? or can we free higher up */ /* SDY the next lines do not make sense */ post("calling fts_free\n"); abort(); fts_free(optr->ex_vec); optr->ex_type = ET_INT; eptr->ex_int = 0; } else { /* this should not happen */ post("expr int. error, optr->ex_vec = %d",optr->ex_vec); abort(); } return(++eptr); case ET_XI0: /* short hand for $x?[0] */ /* SDY delete the following check */ if (!IS_FEXPR_TILDE(expr) || optr->ex_type==ET_VEC) { post("%d:exp->exp_flags = %d", __LINE__,expr->exp_flags); abort(); } optr->ex_type = ET_FLT; optr->ex_flt = expr->exp_var[eptr->ex_int].ex_vec[idx]; return(++eptr); case ET_YOM1: /* * short hand for $y?[-1] * if we are calculating the first sample of the vector * we need to look at the previous results buffer */ optr->ex_type = ET_FLT; if (idx == 0) optr->ex_flt = expr->exp_p_res[eptr->ex_int][expr->exp_vsize - 1]; else optr->ex_flt=expr->exp_tmpres[eptr->ex_int][idx-1]; return(++eptr); case ET_YO: case ET_XI: /* SDY delete the following */ if (!IS_FEXPR_TILDE(expr) || optr->ex_type==ET_VEC) { post("%d:expr->exp_flags = %d", __LINE__,expr->exp_flags); abort(); } return (eval_sigidx(expr, eptr, optr, idx)); case ET_TBL: case ET_SI: return (eval_tab(expr, eptr, optr, idx)); case ET_FUNC: return (eval_func(expr, eptr, optr, idx)); case ET_VAR: return (eval_var(expr, eptr, optr, idx)); case ET_OP: break; case ET_STR: case ET_LP: case ET_LB: default: post_error((fts_object_t *) expr, "expr: ex_eval: unexpected type %d\n", eptr->ex_type); return (exNULL); } if (!eptr[1].ex_type) { post_error((fts_object_t *) expr, "expr: ex_eval: not enough nodes 1\n"); return (exNULL); } if (!unary_op(eptr->ex_op) && !eptr[2].ex_type) { post_error((fts_object_t *) expr, "expr: ex_eval: not enough nodes 2\n"); return (exNULL); } switch((eptr++)->ex_op) { case OP_STORE: return (eval_store(expr, eptr, optr, idx)); case OP_NOT: EVAL_UNARY(!, +); case OP_NEG: EVAL_UNARY(~, (long)); case OP_UMINUS: EVAL_UNARY(-, +); case OP_MUL: EVAL(*); case OP_ADD: EVAL(+); case OP_SUB: EVAL(-); case OP_LT: EVAL(<); case OP_LE: EVAL(<=); case OP_GT: EVAL(>); case OP_GE: EVAL(>=); case OP_EQ: EVAL(==); case OP_NE: EVAL(!=); /* * following operators convert their argument to integer */ #undef DZC #define DZC(ARG1,OPR,ARG2) (((int)ARG1) OPR ((int)ARG2)) case OP_SL: EVAL(<<); case OP_SR: EVAL(>>); case OP_AND: EVAL(&); case OP_XOR: EVAL(^); case OP_OR: EVAL(|); case OP_LAND: EVAL(&&); case OP_LOR: EVAL(||); /* * for modulo we need to convert to integer and check for divide by zero */ #undef DZC #define DZC(ARG1,OPR,ARG2) (((ARG2)?(((int)ARG1) OPR ((int)ARG2)) \ : (ex_dzdetect(expr),0))) case OP_MOD: EVAL(%); /* * define the divide by zero check for divide */ #undef DZC #define DZC(ARG1,OPR,ARG2) (((ARG2)?(ARG1 OPR ARG2):(ex_dzdetect(expr),0))) case OP_DIV: EVAL(/); case OP_LP: case OP_RP: case OP_LB: case OP_RB: case OP_COMMA: case OP_SEMI: default: post_error((fts_object_t *) expr, "expr: ex_print: bad op 0x%x\n", eptr->ex_op); return (exNULL); } /* * the left and right nodes could have been transformed to vectors * down the chain */ if (left.ex_type == ET_VEC) fts_free(left.ex_vec); if (right.ex_type == ET_VEC) fts_free(right.ex_vec); if (nullret) return (exNULL); else return (eptr); } /* * eval_func -- evaluate a function, call ex_eval() on all the arguments * so that all of them are terminal nodes. The call the * appropriate function */ struct ex_ex * eval_func(struct expr *expr, struct ex_ex *eptr, struct ex_ex *optr, int idx) /* the expr object data pointer */ /* the operation stack */ /* the result pointer */ { int i; struct ex_ex args[MAX_ARGS]; t_ex_func *f; f = (t_ex_func *)(eptr++)->ex_ptr; if (!f || !f->f_name) { return (exNULL); } if (f->f_argc > MAX_ARGS) { post_error((fts_object_t *) expr, "expr: eval_func: asking too many arguments\n"); return (exNULL); } for (i = 0; i < f->f_argc; i++) { args[i].ex_type = 0; args[i].ex_int = 0; eptr = ex_eval(expr, eptr, &args[i], idx); } (*f->f_func)(expr, f->f_argc, args, optr); for (i = 0; i < f->f_argc; i++) { if (args[i].ex_type == ET_VEC) fts_free(args[i].ex_vec); } return (eptr); } /* * eval_store -- evaluate the '=' operator, * make sure the first operator is a legal left operator * and call ex_eval on the right operator */ struct ex_ex * eval_store(struct expr *expr, struct ex_ex *eptr, struct ex_ex *optr, int idx) /* the expr object data pointer */ /* the operation stack */ /* the result pointer */ { struct ex_ex arg; int isvalue; char *tbl = (char *) 0; char *var = (char *) 0; int badleft = 0; post("store called\n"); ex_print(eptr); eptr = ex_eval(expr, ++eptr, optr, idx); return (eptr); #ifdef notdef /* SDY */ arg.ex_type = ET_INT; arg.ex_int = 0; if (eptr->ex_type == ET_VAR) { var = (char *) eptr->ex_ptr; eptr = ex_eval(expr, ++eptr, &arg, idx); (void)max_ex_var_store(expr, (t_symbol *)var, &arg, optr); if (arg.ex_type == ET_VEC) fts_free(arg.ex_vec); } if (eptr->ex_type == ET_SI) { eptr++; if (eptr->ex_type = } /* the left operator should either be a value or a array member */ switch (eptr->ex_type) { case ET_SI: if ((eptr + 1)->ex_type == OP_LB) { } if (!expr->exp_var[eptr->ex_int].ex_ptr) { if (!(expr->exp_error & EE_NOTABLE)) { post("expr: syntax error: no string for inlet %d", eptr->ex_int + 1); post("expr: No more table errors will be reported"); post("expr: till the next reset"); expr->exp_error |= EE_NOTABLE; } badleft++; } else tbl = (char *) expr->exp_var[eptr->ex_int].ex_ptr; break; case ET_TBL: } #endif /* SDY */ } /* * eval_tab -- evaluate a table operation */ struct ex_ex * eval_tab(struct expr *expr, struct ex_ex *eptr, struct ex_ex *optr, int idx) /* the expr object data pointer */ /* the operation stack */ /* the result pointer */ { struct ex_ex arg; char *tbl = (char *) 0; int notable = 0; if (eptr->ex_type == ET_SI) { if (!expr->exp_var[eptr->ex_int].ex_ptr) { /* SDY post_error() does not work in MAX/MSP yet post_error((fts_object_t *) expr, "expr: syntax error: no string for inlet %d\n", eptr->ex_int + 1); */ if (!(expr->exp_error & EE_NOTABLE)) { post("expr: syntax error: no string for inlet %d", eptr->ex_int + 1); post("expr: No more table errors will be reported"); post("expr: till the next reset"); expr->exp_error |= EE_NOTABLE; } notable++; } else tbl = (char *) expr->exp_var[eptr->ex_int].ex_ptr; } else if (eptr->ex_type == ET_TBL) tbl = (char *) eptr->ex_ptr; else { post_error((fts_object_t *) expr, "expr: eval_tbl: bad type %ld\n", eptr->ex_type); notable++; } arg.ex_type = 0; arg.ex_int = 0; eptr = ex_eval(expr, ++eptr, &arg, idx); optr->ex_type = ET_INT; optr->ex_int = 0; if (!notable) (void)max_ex_tab(expr, (t_symbol *)tbl, &arg, optr); if (arg.ex_type == ET_VEC) fts_free(arg.ex_vec); return (eptr); } /* * eval_var -- evaluate a variable */ struct ex_ex * eval_var(struct expr *expr, struct ex_ex *eptr, struct ex_ex *optr, int idx) /* the expr object data pointer */ /* the operation stack */ /* the result pointer */ { struct ex_ex arg; char *var = (char *) 0; int novar = 0; if (eptr->ex_type == ET_SI) { if (!expr->exp_var[eptr->ex_int].ex_ptr) { /* SDY post_error() does not work in MAX/MSP yet post_error((fts_object_t *) expr, "expr: syntax error: no string for inlet %d\n", eptr->ex_int + 1); */ if (!(expr->exp_error & EE_NOVAR)) { post("expr: syntax error: no string for inlet %d", eptr->ex_int + 1); post("expr: No more table errors will be reported"); post("expr: till the next reset"); expr->exp_error |= EE_NOVAR; } novar++; } else var = (char *) expr->exp_var[eptr->ex_int].ex_ptr; } else if (eptr->ex_type == ET_VAR) var = (char *) eptr->ex_ptr; else { post_error((fts_object_t *) expr, "expr: eval_tbl: bad type %ld\n", eptr->ex_type); novar++; } optr->ex_type = ET_INT; optr->ex_int = 0; if (!novar) (void)max_ex_var(expr, (t_symbol *)var, optr); return (++eptr); } /* * eval_sigidx -- evaluate the value of an indexed signal for fexpr~ */ struct ex_ex * eval_sigidx(struct expr *expr, struct ex_ex *eptr, struct ex_ex *optr, int idx) /* the expr object data pointer */ /* the operation stack */ /* the result pointer */ /* the index */ { struct ex_ex arg; struct ex_ex *reteptr; int i = 0, j = 0; t_float fi = 0, /* index in float */ rem_i = 0; /* remains of the float */ char *tbl; arg.ex_type = 0; arg.ex_int = 0; reteptr = ex_eval(expr, eptr + 1, &arg, idx); if (arg.ex_type == ET_FLT) { fi = arg.ex_flt; /* float index */ i = (int) arg.ex_flt; /* integer index */ rem_i = arg.ex_flt - i; /* remains of integer */ } else if (arg.ex_type == ET_INT) { fi = arg.ex_int; /* float index */ i = arg.ex_int; rem_i = 0; } else { post("eval_sigidx: bad res type (%d)", arg.ex_type); } optr->ex_type = ET_FLT; /* * indexing an input vector */ if (eptr->ex_type == ET_XI) { if (fi > 0) { if (!(expr->exp_error & EE_BI_INPUT)) { expr->exp_error |= EE_BI_INPUT; post("expr: input vector index > 0, (vector x%d[%f])", eptr->ex_int + 1, i + rem_i); post("fexpr~: index assumed to be = 0"); post("fexpr~: no error report till next reset"); ex_print(eptr); } /* just replace it with zero */ i = 0; rem_i = 0; } if (cal_sigidx(optr, i, rem_i, idx, expr->exp_vsize, expr->exp_var[eptr->ex_int].ex_vec, expr->exp_p_var[eptr->ex_int])) { if (!(expr->exp_error & EE_BI_INPUT)) { expr->exp_error |= EE_BI_INPUT; post("expr: input vector index < -VectorSize, (vector x%d[%f])", eptr->ex_int + 1, fi); ex_print(eptr); post("fexpr~: index assumed to be = -%d", expr->exp_vsize); post("fexpr~: no error report till next reset"); } } /* * indexing an output vector */ } else if (eptr->ex_type == ET_YO) { /* for output vectors index of zero is not legal */ if (fi >= 0) { if (!(expr->exp_error & EE_BI_OUTPUT)) { expr->exp_error |= EE_BI_OUTPUT; post("fexpr~: bad output index, (%f)", fi); ex_print(eptr); post("fexpr~: no error report till next reset"); post("fexpr~: index assumed to be = -1"); } i = -1; } if (eptr->ex_int >= expr->exp_nexpr) { post("fexpr~: $y%d illegal: not that many exprs", eptr->ex_int); optr->ex_flt = 0; return (reteptr); } if (cal_sigidx(optr, i, rem_i, idx, expr->exp_vsize, expr->exp_tmpres[eptr->ex_int], expr->exp_p_res[eptr->ex_int])) { if (!(expr->exp_error & EE_BI_OUTPUT)) { expr->exp_error |= EE_BI_OUTPUT; post("fexpr~: bad output index, (%f)", fi); ex_print(eptr); post("fexpr~: index assumed to be = -%d", expr->exp_vsize); } } } else { optr->ex_flt = 0; post("fexpr~:eval_sigidx: internal error - unknown vector (%d)", eptr->ex_type); } return (reteptr); } /* * cal_sigidx -- given two tables (one current one previous) calculate an * evaluation of a float index into the vectors by linear * interpolation * return 0 on success, 1 on failure (index out of bound) */ static int cal_sigidx(struct ex_ex *optr, /* The output value */ int i, t_float rem_i,/* integer and fractinal part of index */ int idx, /* index of current fexpr~ processing */ int vsize, /* vector size */ t_float *curvec, t_float *prevec) /* current and previous table */ { int n; n = i + idx; if (n > 0) { /* from the curvec */ if (rem_i) optr->ex_flt = curvec[n] + rem_i * (curvec[n] - curvec[n - 1]); else optr->ex_flt = curvec[n]; return (0); } if (n == 0) { /* * this is the case that the remaining float * is between two tables */ if (rem_i) optr->ex_flt = *curvec + rem_i * (*curvec - prevec[vsize - 1]); else optr->ex_flt = *curvec; return (0); } /* find the index in the saved buffer */ n = vsize + n; if (n > 0) { if (rem_i) optr->ex_flt = prevec[n] + rem_i * (prevec[n] - prevec[n - 1]); else optr->ex_flt = prevec[n]; return (0); } /* out of bound */ optr->ex_flt = *prevec; return (1); } /* * getoken -- return 1 on syntax error otherwise 0 */ int getoken(struct expr *expr, struct ex_ex *eptr) { char *p; long i; if (!expr->exp_str) { post("expr: getoken: expression string not set\n"); return (0); } retry: if (!*expr->exp_str) { eptr->ex_type = 0; eptr->ex_int = 0; return (0); } if (*expr->exp_str == ';') { expr->exp_str++; eptr->ex_type = 0; eptr->ex_int = 0; return (0); } eptr->ex_type = ET_OP; switch (*expr->exp_str++) { case '\\': case ' ': case '\t': goto retry; case ';': post("expr: syntax error: ';' not implemented\n"); return (1); case ',': eptr->ex_op = OP_COMMA; break; case '(': eptr->ex_op = OP_LP; break; case ')': eptr->ex_op = OP_RP; break; case ']': eptr->ex_op = OP_RB; break; case '~': eptr->ex_op = OP_NEG; break; /* we will take care of unary minus later */ case '*': eptr->ex_op = OP_MUL; break; case '/': eptr->ex_op = OP_DIV; break; case '%': eptr->ex_op = OP_MOD; break; case '+': eptr->ex_op = OP_ADD; break; case '-': eptr->ex_op = OP_SUB; break; case '^': eptr->ex_op = OP_XOR; break; case '[': eptr->ex_op = OP_LB; break; case '!': if (*expr->exp_str == '=') { eptr->ex_op = OP_NE; expr->exp_str++; } else eptr->ex_op = OP_NOT; break; case '<': switch (*expr->exp_str) { case '<': eptr->ex_op = OP_SL; expr->exp_str++; break; case '=': eptr->ex_op = OP_LE; expr->exp_str++; break; default: eptr->ex_op = OP_LT; break; } break; case '>': switch (*expr->exp_str) { case '>': eptr->ex_op = OP_SR; expr->exp_str++; break; case '=': eptr->ex_op = OP_GE; expr->exp_str++; break; default: eptr->ex_op = OP_GT; break; } break; case '=': if (*expr->exp_str++ != '=') { post("expr: syntax error: =\n"); return (1); } eptr->ex_op = OP_EQ; break; /* do not allow the store till the function is fixed if (*expr->exp_str != '=') eptr->ex_op = OP_STORE; else { expr->exp_str++; eptr->ex_op = OP_EQ; } break; */ case '&': if (*expr->exp_str == '&') { expr->exp_str++; eptr->ex_op = OP_LAND; } else eptr->ex_op = OP_AND; break; case '|': if ((*expr->exp_str == '|')) { expr->exp_str++; eptr->ex_op = OP_LOR; } else eptr->ex_op = OP_OR; break; case '$': switch (*expr->exp_str++) { case 'I': case 'i': eptr->ex_type = ET_II; break; case 'F': case 'f': eptr->ex_type = ET_FI; break; case 'S': case 's': eptr->ex_type = ET_SI; break; case 'V': case 'v': if (IS_EXPR_TILDE(expr)) { eptr->ex_type = ET_VI; break; } post("$v? works only for expr~"); post("expr: syntax error: %s\n", &expr->exp_str[-2]); return (1); case 'X': case 'x': if (IS_FEXPR_TILDE(expr)) { eptr->ex_type = ET_XI; if (isdigit(*expr->exp_str)) break; /* for $x[] is a shorhand for $x1[] */ eptr->ex_int = 0; goto noinletnum; } post("$x? works only for fexpr~"); post("expr: syntax error: %s\n", &expr->exp_str[-2]); return (1); case 'y': case 'Y': if (IS_FEXPR_TILDE(expr)) { eptr->ex_type = ET_YO; /*$y takes no number */ if (isdigit(*expr->exp_str)) break; /* for $y[] is a shorhand for $y1[] */ eptr->ex_int = 0; goto noinletnum; } post("$y works only for fexpr~"); default: post("expr: syntax error: %s\n", &expr->exp_str[-2]); return (1); } p = atoif(expr->exp_str, &eptr->ex_op, &i); if (!p) { post("expr: syntax error: %s\n", &expr->exp_str[-2]); return (1); } if (i != ET_INT) { post("expr: syntax error: %s\n", expr->exp_str); return (1); } /* * make the user inlets one based rather than zero based * therefore we decrement the number that user has supplied */ if (!eptr->ex_op || (eptr->ex_op)-- > MAX_VARS) { post("expr: syntax error: inlet or outlet out of range: %s\n", expr->exp_str); return (1); } /* * until we can change the input type of inlets on * the fly (at pd_new() * time) the first input to expr~ is always a vectore * and $f1 or $i1 is * illegal for fexr~ */ if (eptr->ex_op == 0 && (IS_FEXPR_TILDE(expr) || IS_EXPR_TILDE(expr)) && (eptr->ex_type==ET_II || eptr->ex_type==ET_FI || eptr->ex_type==ET_SI)) { post("first inlet of expr~/fexpr~ can only be a vector"); return (1); } /* record the inlet or outlet type and check for consistency */ if (eptr->ex_type == ET_YO ) { /* it is an outlet for fexpr~*/ /* no need to do anything */ ; } else if (!expr->exp_var[eptr->ex_op].ex_type) expr->exp_var[eptr->ex_op].ex_type = eptr->ex_type; else if (expr->exp_var[eptr->ex_op].ex_type != eptr->ex_type) { post("expr: syntax error: inlets can only have one type: %s\n", expr->exp_str); return (1); } expr->exp_str = p; noinletnum: break; case '"': { struct ex_ex ex; p = expr->exp_str; if (!*expr->exp_str || *expr->exp_str == '"') { post("expr: syntax error: empty symbol: %s\n", --expr->exp_str); return (1); } if (getoken(expr, &ex)) return (1); switch (ex.ex_type) { case ET_STR: if (ex_getsym(ex.ex_ptr, (t_symbol **)&(eptr->ex_ptr))) { post("expr: syntax error: getoken: problms with ex_getsym\n"); return (1); } eptr->ex_type = ET_SYM; break; case ET_SI: *eptr = ex; eptr->ex_type = ET_VSYM; break; default: post("expr: syntax error: bad symbol name: %s\n", p); return (1); } if (*expr->exp_str++ != '"') { post("expr: syntax error: missing '\"'\n"); return (1); } break; } case '.': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': p = atoif(--expr->exp_str, &eptr->ex_int, &eptr->ex_type); if (!p) return (1); expr->exp_str = p; break; default: /* * has to be a string, it should either be a * function or a table */ p = --expr->exp_str; for (i = 0; name_ok(*p); i++) p++; if (!i) { post("expr: syntax error: %s\n", expr->exp_str); return (1); } eptr->ex_ptr = (char *)fts_malloc(i + 1); strncpy(eptr->ex_ptr, expr->exp_str, (int) i); (eptr->ex_ptr)[i] = 0; expr->exp_str = p; /* * we mark this as a string and later we will change this * to either a function or a table */ eptr->ex_type = ET_STR; break; } return (0); } /* * atoif -- ascii to float or integer (understands hex numbers also) */ char * atoif(char *s, long int *value, long int *type) { char *p; long int_val = 0; int flt = 0; t_float pos = 0; t_float flt_val = 0; int base = 10; p = s; if (*p == '0' && (p[1] == 'x' || p[1] == 'X')) { base = 16; p += 2; } while (8) { switch (*p) { case '.': if (flt || base != 10) { post("expr: syntax error: %s\n", s); return ((char *) 0); } flt++; pos = 10; flt_val = int_val; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (flt) { flt_val += (*p - '0') / pos; pos *= 10; } else { int_val *= base; int_val += (*p - '0'); } break; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': if (base != 16 || flt) { post("expr: syntax error: %s\n", s); return ((char *) 0); } int_val *= base; int_val += (*p - 'a' + 10); break; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': if (base != 16 || flt) { post("expr: syntax error: %s\n", s); return ((char *) 0); } int_val *= base; int_val += (*p - 'A' + 10); break; default: if (flt) { *type = ET_FLT; *((t_float *) value) = flt_val; } else { *type = ET_INT; *value = int_val; } return (p); } p++; } } /* * find_func -- returns a pointer to the found function structure * otherwise it returns 0 */ t_ex_func * find_func(char *s) { t_ex_func *f; for (f = ex_funcs; f->f_name; f++) if (!strcmp(f->f_name, s)) return (f); return ((t_ex_func *) 0); } /* * ex_print -- print an expression array */ void ex_print(struct ex_ex *eptr) { while (eptr->ex_type) { switch (eptr->ex_type) { case ET_INT: post("%ld ", eptr->ex_int); break; case ET_FLT: post("%f ", eptr->ex_flt); break; case ET_STR: post("%s ", eptr->ex_ptr); break; case ET_TBL: case ET_VAR: post("%s ", ex_symname((fts_symbol_t )eptr->ex_ptr)); break; case ET_SYM: post("\"%s\" ", ex_symname((fts_symbol_t )eptr->ex_ptr)); break; case ET_VSYM: post("\"$s%ld\" ", eptr->ex_int + 1); break; case ET_FUNC: post("%s ", ((t_ex_func *)eptr->ex_ptr)->f_name); break; case ET_LP: post("%c", '('); break; /* CHANGE case ET_RP: post("%c ", ')'); break; */ case ET_LB: post("%c", '['); break; /* CHANGE case ET_RB: post("%c ", ']'); break; */ case ET_II: post("$i%ld ", eptr->ex_int + 1); break; case ET_FI: post("$f%ld ", eptr->ex_int + 1); break; case ET_SI: post("$s%lx ", eptr->ex_ptr); break; case ET_VI: post("$v%lx ", eptr->ex_vec); break; case ET_VEC: post("vec = %ld ", eptr->ex_vec); break; case ET_YOM1: case ET_YO: post("$y%d", eptr->ex_int + 1); break; case ET_XI: case ET_XI0: post("$x%d", eptr->ex_int + 1); break; case ET_OP: switch (eptr->ex_op) { case OP_LP: post("%c", '('); break; case OP_RP: post("%c ", ')'); break; case OP_LB: post("%c", '['); break; case OP_RB: post("%c ", ']'); break; case OP_NOT: post("%c", '!'); break; case OP_NEG: post("%c", '~'); break; case OP_UMINUS: post("%c", '-'); break; case OP_MUL: post("%c", '*'); break; case OP_DIV: post("%c", '/'); break; case OP_MOD: post("%c", '%'); break; case OP_ADD: post("%c", '+'); break; case OP_SUB: post("%c", '-'); break; case OP_SL: post("%s", "<<"); break; case OP_SR: post("%s", ">>"); break; case OP_LT: post("%c", '<'); break; case OP_LE: post("%s", "<="); break; case OP_GT: post("%c", '>'); break; case OP_GE: post("%s", ">="); break; case OP_EQ: post("%s", "=="); break; case OP_STORE: post("%s", "="); break; case OP_NE: post("%s", "!="); break; case OP_AND: post("%c", '&'); break; case OP_XOR: post("%c", '^'); break; case OP_OR: post("%c", '|'); break; case OP_LAND: post("%s", "&&"); break; case OP_LOR: post("%s", "||"); break; case OP_COMMA: post("%c", ','); break; case OP_SEMI: post("%c", ';'); break; default: post("expr: ex_print: bad op 0x%lx\n", eptr->ex_op); } break; default: post("expr: ex_print: bad type 0x%lx\n", eptr->ex_type); } eptr++; } post("\n"); } #ifdef _WIN32 void ABORT( void) {bug("expr");} #endif pd-0.46-7/extra/expr~/LICENSE.txt0000664000175000017500000001674112160204055014522 0ustar mspmsp GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. pd-0.46-7/extra/expr~/vexp_fun.c0000664000175000017500000014656012374250720014707 0ustar mspmsp/* * jMax * Copyright (C) 1994, 1995, 1998, 1999 by IRCAM-Centre Georges Pompidou, Paris, France. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * See file LICENSE for further informations on licensing terms. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Based on Max/ISPW by Miller Puckette. * * Authors: Maurizio De Cecco, Francois Dechelle, Enzo Maggi, Norbert Schnell. * */ /* "expr" was written by Shahrokh Yadegari c. 1989. -msp * * Nov. 2001 --sdy * conversion for expr~ * * Jan, 2002 --sdy * added fmod() * * May 2002 * added floor and ceil for expr -- Orm Finnendahl * * July 2002 --sdy * added the following math funtions: * cbrt - cube root * erf - error function * erfc - complementary error function * expm1 - exponential minus 1, * log1p - logarithm of 1 plus * isinf - is the value infinite, * finite - is the value finite * isnan -- is the resut a nan (Not a number) * copysign - copy sign of a number * ldexp - multiply floating-point number by integral power of 2 * imodf - get signed integral value from floating-point number * modf - get signed fractional value from floating-point number * drem - floating-point remainder function * * The following are done but not popular enough in math libss * to be included yet * hypoth - Euclidean distance function * trunc * round * nearbyint - */ /* * vexp_func.c -- this file include all the functions for vexp. * the first two arguments to the function are the number * of argument and an array of arguments (argc, argv) * the last argument is a pointer to a struct ex_ex for * the result. Up do this point, the content of the * struct ex_ex that these functions receive are either * ET_INT (long), ET_FLT (t_float), or ET_SYM (char **, it is * char ** and not char * since NewHandle of Mac returns * a char ** for relocatability.) The common practice in * these functions is that they figure out the type of their * result according to the type of the arguments. In general * the ET_SYM is used an ET_INT when we expect a value. * It is the users responsibility not to pass strings to the * function. */ #include #include #define __STRICT_BSD__ #include #undef __STRICT_BSD__ #include "vexp.h" /* forward declarations */ static void ex_min(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_max(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_toint(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_rint(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_tofloat(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_pow(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_exp(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_log(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_ln(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_sin(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_cos(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_asin(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_acos(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_tan(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_atan(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_sinh(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_cosh(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_asinh(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_acosh(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_tanh(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_atanh(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_atan2(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_sqrt(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_fact(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_random(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_abs(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_fmod(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_ceil(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_floor(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_if(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_ldexp(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_imodf(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_modf(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); #ifndef _WIN32 static void ex_cbrt(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_erf(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_erfc(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_expm1(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_log1p(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_isinf(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_finite(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_isnan(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_copysign(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_drem(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); #endif #ifdef notdef /* the following will be added once they are more popular in math libraries */ static void ex_round(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_trunc(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_nearbyint(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); static void ex_hypoth(t_expr *expr, long argc, struct ex_ex *argv, struct ex_ex *optr); #endif t_ex_func ex_funcs[] = { {"min", ex_min, 2}, {"max", ex_max, 2}, {"int", ex_toint, 1}, {"rint", ex_rint, 1}, {"float", ex_tofloat, 1}, {"fmod", ex_fmod, 2}, {"floor", ex_floor, 2}, {"ceil", ex_ceil, 2}, {"pow", ex_pow, 2}, {"sqrt", ex_sqrt, 1}, {"exp", ex_exp, 1}, {"log10", ex_log, 1}, {"ln", ex_ln, 1}, {"log", ex_ln, 1}, {"sin", ex_sin, 1}, {"cos", ex_cos, 1}, {"tan", ex_tan, 1}, {"asin", ex_asin, 1}, {"acos", ex_acos, 1}, {"atan", ex_atan, 1}, {"atan2", ex_atan2, 2}, {"sinh", ex_sinh, 1}, {"cosh", ex_cosh, 1}, {"tanh", ex_tanh, 1}, {"fact", ex_fact, 1}, {"random", ex_random, 2}, /* random number */ {"abs", ex_abs, 1}, {"if", ex_if, 3}, {"ldexp ", ex_ldexp, 1}, {"imodf ", ex_imodf, 1}, {"modf", ex_modf, 1}, #ifndef _WIN32 {"cbrt", ex_cbrt, 1}, {"erf", ex_erf, 1}, {"erfc", ex_erfc, 1}, {"expm1", ex_expm1, 1}, {"log1p", ex_log1p, 1}, {"isinf", ex_isinf, 1}, {"finite", ex_finite, 1}, {"isnan", ex_isnan, 1}, {"copysig", ex_copysign, 1}, {"drem", ex_drem, 1}, {"asinh", ex_asinh, 1}, {"acosh", ex_acosh, 1}, {"atanh", ex_atanh, 1}, /* hyperbolic atan */ #endif #ifdef PD {"size", ex_size, 1}, {"sum", ex_sum, 1}, {"Sum", ex_Sum, 3}, {"avg", ex_avg, 1}, {"Avg", ex_Avg, 3}, {"store", ex_store, 3}, #endif #ifdef notdef /* the following will be added once they are more popular in math libraries */ {"round", ex_round, 1}, {"trunc", ex_trunc, 1}, {"nearbyint", ex_nearbyint, 1}, {"hypoth", ex_hypoth, 1}, #endif {0, 0, 0} }; /* * FUN_EVAL -- do type checking, evaluate a function, * if fltret is set return float * otherwise return value based on regular typechecking, */ #define FUNC_EVAL(left, right, func, leftfuncast, rightfuncast, optr, fltret) \ switch (left->ex_type) { \ case ET_INT: \ switch(right->ex_type) { \ case ET_INT: \ if (optr->ex_type == ET_VEC) { \ op = optr->ex_vec; \ scalar = (t_float)func(leftfuncast left->ex_int, \ rightfuncast right->ex_int); \ j = e->exp_vsize; \ while (j--) \ *op++ = scalar; \ } else { \ if (fltret) { \ optr->ex_type = ET_FLT; \ optr->ex_flt = (t_float)func(leftfuncast \ left->ex_int, rightfuncast right->ex_int); \ } else { \ optr->ex_type = ET_INT; \ optr->ex_int = (int)func(leftfuncast \ left->ex_int, rightfuncast right->ex_int); \ } \ } \ break; \ case ET_FLT: \ if (optr->ex_type == ET_VEC) { \ op = optr->ex_vec; \ scalar = (t_float)func(leftfuncast left->ex_int, \ rightfuncast right->ex_flt); \ j = e->exp_vsize; \ while (j--) \ *op++ = scalar; \ } else { \ optr->ex_type = ET_FLT; \ optr->ex_flt = (t_float)func(leftfuncast left->ex_int, \ rightfuncast right->ex_flt); \ } \ break; \ case ET_VEC: \ case ET_VI: \ if (optr->ex_type != ET_VEC) { \ if (optr->ex_type == ET_VI) { \ post("expr~: Int. error %d", __LINE__); \ abort(); \ } \ optr->ex_type = ET_VEC; \ optr->ex_vec = (t_float *) \ fts_malloc(sizeof (t_float)*e->exp_vsize); \ } \ scalar = left->ex_int; \ rp = right->ex_vec; \ op = optr->ex_vec; \ j = e->exp_vsize; \ while (j--) { \ *op++ = (t_float)func(leftfuncast scalar, \ rightfuncast *rp); \ rp++; \ } \ break; \ case ET_SYM: \ default: \ post_error((fts_object_t *) e, \ "expr: FUNC_EVAL(%d): bad right type %ld\n", \ __LINE__, right->ex_type);\ } \ break; \ case ET_FLT: \ switch(right->ex_type) { \ case ET_INT: \ if (optr->ex_type == ET_VEC) { \ op = optr->ex_vec; \ scalar = (t_float)func(leftfuncast left->ex_flt, \ rightfuncast right->ex_int); \ j = e->exp_vsize; \ while (j--) \ *op++ = scalar; \ } else { \ optr->ex_type = ET_FLT; \ optr->ex_flt = (t_float)func(leftfuncast left->ex_flt, \ rightfuncast right->ex_int); \ } \ break; \ case ET_FLT: \ if (optr->ex_type == ET_VEC) { \ op = optr->ex_vec; \ scalar = (t_float)func(leftfuncast left->ex_flt, \ rightfuncast right->ex_flt); \ j = e->exp_vsize; \ while (j--) \ *op++ = scalar; \ } else { \ optr->ex_type = ET_FLT; \ optr->ex_flt = (t_float)func(leftfuncast left->ex_flt, \ rightfuncast right->ex_flt); \ } \ break; \ case ET_VEC: \ case ET_VI: \ if (optr->ex_type != ET_VEC) { \ if (optr->ex_type == ET_VI) { \ post("expr~: Int. error %d", __LINE__); \ abort(); \ } \ optr->ex_type = ET_VEC; \ optr->ex_vec = (t_float *) \ fts_malloc(sizeof (t_float) * e->exp_vsize);\ } \ scalar = left->ex_flt; \ rp = right->ex_vec; \ op = optr->ex_vec; \ j = e->exp_vsize; \ while (j--) { \ *op++ = (t_float)func(leftfuncast scalar, \ rightfuncast *rp); \ rp++; \ } \ break; \ case ET_SYM: \ default: \ post_error((fts_object_t *) e, \ "expr: FUNC_EVAL(%d): bad right type %ld\n", \ __LINE__, right->ex_type);\ } \ break; \ case ET_VEC: \ case ET_VI: \ if (optr->ex_type != ET_VEC) { \ if (optr->ex_type == ET_VI) { \ post("expr~: Int. error %d", __LINE__); \ abort(); \ } \ optr->ex_type = ET_VEC; \ optr->ex_vec = (t_float *) \ fts_malloc(sizeof (t_float) * e->exp_vsize); \ } \ op = optr->ex_vec; \ lp = left->ex_vec; \ switch(right->ex_type) { \ case ET_INT: \ scalar = right->ex_int; \ j = e->exp_vsize; \ while (j--) { \ *op++ = (t_float)func(leftfuncast *lp, \ rightfuncast scalar); \ lp++; \ } \ break; \ case ET_FLT: \ scalar = right->ex_flt; \ j = e->exp_vsize; \ while (j--) { \ *op++ = (t_float)func(leftfuncast *lp, \ rightfuncast scalar); \ lp++; \ } \ break; \ case ET_VEC: \ case ET_VI: \ rp = right->ex_vec; \ j = e->exp_vsize; \ while (j--) { \ /* \ * on a RISC processor one could copy \ * 8 times in each round to get a considerable \ * improvement \ */ \ *op++ = (t_float)func(leftfuncast *lp, \ rightfuncast *rp); \ rp++; lp++; \ } \ break; \ case ET_SYM: \ default: \ post_error((fts_object_t *) e, \ "expr: FUNC_EVAL(%d): bad right type %ld\n", \ __LINE__, right->ex_type);\ } \ break; \ case ET_SYM: \ default: \ post_error((fts_object_t *) e, \ "expr: FUNC_EVAL(%d): bad left type %ld\n", \ __LINE__, left->ex_type); \ } /* * FUNC_EVAL_UNARY - evaluate a unary function, * if fltret is set return t_float * otherwise return value based on regular typechecking, */ #define FUNC_EVAL_UNARY(left, func, leftcast, optr, fltret) \ switch(left->ex_type) { \ case ET_INT: \ if (optr->ex_type == ET_VEC) { \ ex_mkvector(optr->ex_vec, \ (t_float)(func (leftcast left->ex_int)), e->exp_vsize);\ break; \ } \ if (fltret) { \ optr->ex_type = ET_FLT; \ optr->ex_flt = (t_float) func(leftcast left->ex_int); \ break; \ } \ optr->ex_type = ET_INT; \ optr->ex_int = (int) func(leftcast left->ex_int); \ break; \ case ET_FLT: \ if (optr->ex_type == ET_VEC) { \ ex_mkvector(optr->ex_vec, \ (t_float)(func (leftcast left->ex_flt)), e->exp_vsize);\ break; \ } \ optr->ex_type = ET_FLT; \ optr->ex_flt = (t_float) func(leftcast left->ex_flt); \ break; \ case ET_VI: \ case ET_VEC: \ if (optr->ex_type != ET_VEC) { \ optr->ex_type = ET_VEC; \ optr->ex_vec = (t_float *) \ fts_malloc(sizeof (t_float)*e->exp_vsize); \ } \ op = optr->ex_vec; \ lp = left->ex_vec; \ j = e->exp_vsize; \ while (j--) \ *op++ = (t_float)(func (leftcast *lp++)); \ break; \ default: \ post_error((fts_object_t *) e, \ "expr: FUNV_EVAL_UNARY(%d): bad left type %ld\n",\ __LINE__, left->ex_type); \ } #undef min #undef max #define min(x,y) (x > y ? y : x) #define max(x,y) (x > y ? x : y) #define FUNC_DEF(ex_func, func, castleft, castright, fltret); \ static void \ ex_func(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)\ { \ struct ex_ex *left, *right; \ t_float *op; /* output pointer */ \ t_float *lp, *rp; /* left and right vector pointers */ \ t_float scalar; \ int j; \ \ left = argv++; \ right = argv; \ FUNC_EVAL(left, right, func, castleft, castright, optr, fltret); \ } #define FUNC_DEF_UNARY(ex_func, func, cast, fltret); \ static void \ ex_func(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr)\ { \ struct ex_ex *left; \ t_float *op; /* output pointer */ \ t_float *lp, *rp; /* left and right vector pointers */ \ t_float scalar; \ int j; \ \ left = argv++; \ \ FUNC_EVAL_UNARY(left, func, cast, optr, fltret); \ } /* * ex_min -- if any of the arguments are or the output are vectors, a vector * of floats is generated otherwise the type of the result is the * type of the smaller value */ static void ex_min(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { struct ex_ex *left, *right; t_float *op; /* output pointer */ t_float *lp, *rp; /* left and right vector pointers */ t_float scalar; int j; left = argv++; right = argv; FUNC_EVAL(left, right, min, (double), (double), optr, 0); } /* * ex_max -- if any of the arguments are or the output are vectors, a vector * of floats is generated otherwise the type of the result is the * type of the larger value */ static void ex_max(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { struct ex_ex *left, *right; t_float *op; /* output pointer */ t_float *lp, *rp; /* left and right vector pointers */ t_float scalar; int j; left = argv++; right = argv; FUNC_EVAL(left, right, max, (double), (double), optr, 0); } /* * ex_toint -- convert to integer */ static void ex_toint(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { struct ex_ex *left; t_float *op; /* output pointer */ t_float *lp, *rp; /* left and right vector pointers */ t_float scalar; int j; left = argv++; #define toint(x) ((int)(x)) FUNC_EVAL_UNARY(left, toint, (int), optr, 0); } #ifdef _WIN32 /* No rint in NT land ??? */ double rint(double x); double rint(double x) { return (floor(x + 0.5)); } #endif /* * ex_rint -- rint() round to the nearest int according to the common * rounding mechanism */ static void ex_rint(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { struct ex_ex *left; t_float *op; /* output pointer */ t_float *lp, *rp; /* left and right vector pointers */ t_float scalar; int j; left = argv++; FUNC_EVAL_UNARY(left, rint, (double), optr, 1); } /* * ex_tofloat -- convert to t_float */ static void ex_tofloat(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { struct ex_ex *left; t_float *op; /* output pointer */ t_float *lp, *rp; /* left and right vector pointers */ t_float scalar; int j; left = argv++; #define tofloat(x) ((t_float)(x)) FUNC_EVAL_UNARY(left, tofloat, (int), optr, 1); } /* * ex_pow -- the power of */ static void ex_pow(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { struct ex_ex *left, *right; t_float *op; /* output pointer */ t_float *lp, *rp; /* left and right vector pointers */ t_float scalar; int j; left = argv++; right = argv; FUNC_EVAL(left, right, pow, (double), (double), optr, 1); } /* * ex_sqrt -- square root */ static void ex_sqrt(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { struct ex_ex *left; t_float *op; /* output pointer */ t_float *lp, *rp; /* left and right vector pointers */ t_float scalar; int j; left = argv++; FUNC_EVAL_UNARY(left, sqrt, (double), optr, 1); } /* * ex_exp -- e to the power of */ static void ex_exp(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { struct ex_ex *left; t_float *op; /* output pointer */ t_float *lp, *rp; /* left and right vector pointers */ t_float scalar; int j; left = argv++; FUNC_EVAL_UNARY(left, exp, (double), optr, 1); } /* * ex_log -- 10 based logarithm */ static void ex_log(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { struct ex_ex *left; t_float *op; /* output pointer */ t_float *lp, *rp; /* left and right vector pointers */ t_float scalar; int j; left = argv++; FUNC_EVAL_UNARY(left, log10, (double), optr, 1); } /* * ex_ln -- natural log */ static void ex_ln(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { struct ex_ex *left; t_float *op; /* output pointer */ t_float *lp, *rp; /* left and right vector pointers */ t_float scalar; int j; left = argv++; FUNC_EVAL_UNARY(left, log, (double), optr, 1); } static void ex_sin(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { struct ex_ex *left; t_float *op; /* output pointer */ t_float *lp, *rp; /* left and right vector pointers */ t_float scalar; int j; left = argv++; FUNC_EVAL_UNARY(left, sin, (double), optr, 1); } static void ex_cos(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { struct ex_ex *left; t_float *op; /* output pointer */ t_float *lp, *rp; /* left and right vector pointers */ t_float scalar; int j; left = argv++; FUNC_EVAL_UNARY(left, cos, (double), optr, 1); } static void ex_tan(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { struct ex_ex *left; t_float *op; /* output pointer */ t_float *lp, *rp; /* left and right vector pointers */ t_float scalar; int j; left = argv++; FUNC_EVAL_UNARY(left, tan, (double), optr, 1); } static void ex_asin(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { struct ex_ex *left; t_float *op; /* output pointer */ t_float *lp, *rp; /* left and right vector pointers */ t_float scalar; int j; left = argv++; FUNC_EVAL_UNARY(left, asin, (double), optr, 1); } static void ex_acos(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { struct ex_ex *left; t_float *op; /* output pointer */ t_float *lp, *rp; /* left and right vector pointers */ t_float scalar; int j; left = argv++; FUNC_EVAL_UNARY(left, acos, (double), optr, 1); } static void ex_atan(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { struct ex_ex *left; t_float *op; /* output pointer */ t_float *lp, *rp; /* left and right vector pointers */ t_float scalar; int j; left = argv++; FUNC_EVAL_UNARY(left, atan, (double), optr, 1); } /* *ex_atan2 -- */ static void ex_atan2(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { struct ex_ex *left, *right; t_float *op; /* output pointer */ t_float *lp, *rp; /* left and right vector pointers */ t_float scalar; int j; left = argv++; right = argv; FUNC_EVAL(left, right, atan2, (double), (double), optr, 1); } /* * ex_fmod -- floating point modulo */ static void ex_fmod(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { struct ex_ex *left, *right; t_float *op; /* output pointer */ t_float *lp, *rp; /* left and right vector pointers */ t_float scalar; int j; left = argv++; right = argv; FUNC_EVAL(left, right, fmod, (double), (double), optr, 1); } /* * ex_floor -- floor */ static void ex_floor(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { struct ex_ex *left; t_float *op; /* output pointer */ t_float *lp, *rp; /* left and right vector pointers */ t_float scalar; int j; left = argv++; FUNC_EVAL_UNARY(left, floor, (double), optr, 1); } /* * ex_ceil -- ceil */ static void ex_ceil(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { struct ex_ex *left; t_float *op; /* output pointer */ t_float *lp, *rp; /* left and right vector pointers */ t_float scalar; int j; left = argv++; FUNC_EVAL_UNARY(left, ceil, (double), optr, 1); } static void ex_sinh(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { struct ex_ex *left; t_float *op; /* output pointer */ t_float *lp, *rp; /* left and right vector pointers */ t_float scalar; int j; left = argv++; FUNC_EVAL_UNARY(left, sinh, (double), optr, 1); } static void ex_cosh(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { struct ex_ex *left; t_float *op; /* output pointer */ t_float *lp, *rp; /* left and right vector pointers */ t_float scalar; int j; left = argv++; FUNC_EVAL_UNARY(left, cosh, (double), optr, 1); } static void ex_tanh(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { struct ex_ex *left; t_float *op; /* output pointer */ t_float *lp, *rp; /* left and right vector pointers */ t_float scalar; int j; left = argv++; FUNC_EVAL_UNARY(left, tanh, (double), optr, 1); } #ifndef _WIN32 static void ex_asinh(t_expr *e, long argc, struct ex_ex *argv, struct ex_ex *optr) { struct ex_ex *left; t_float *op; /* output pointer */ t_float *lp, *rp; /* left and right vector pointers */ t_float scalar; int j; left = argv++; FUNC_EVAL_UNARY(left, asinh, (double), optr, 1); } static void ex_acosh(t_expr *e, long argc, struct ex_ex *argv, struct ex_ex *optr) { struct ex_ex *left; t_float *op; /* output pointer */ t_float *lp, *rp; /* left and right vector pointers */ t_float scalar; int j; left = argv++; FUNC_EVAL_UNARY(left, acosh, (double), optr, 1); } static void ex_atanh(t_expr *e, long argc, struct ex_ex *argv, struct ex_ex *optr) { struct ex_ex *left; t_float *op; /* output pointer */ t_float *lp, *rp; /* left and right vector pointers */ t_float scalar; int j; left = argv++; FUNC_EVAL_UNARY(left, atanh, (double), optr, 1); } #endif static int ex_dofact(int i) { int ret = 0; if (i) ret = 1; else return (0); do { ret *= i; } while (--i); return(ret); } static void ex_fact(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { struct ex_ex *left; t_float *op; /* output pointer */ t_float *lp, *rp; /* left and right vector pointers */ t_float scalar; int j; left = argv++; FUNC_EVAL_UNARY(left, ex_dofact, (int), optr, 0); } static int ex_dorandom(int i1, int i2) { return(i1 + (((i2 - i1) * (rand() & 0x7fffL)) >> 15)); } /* * ex_random -- return a random number */ static void ex_random(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { struct ex_ex *left, *right; t_float *op; /* output pointer */ t_float *lp, *rp; /* left and right vector pointers */ t_float scalar; int j; left = argv++; right = argv; FUNC_EVAL(left, right, ex_dorandom, (int), (int), optr, 0); } static void ex_abs(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { struct ex_ex *left; t_float *op; /* output pointer */ t_float *lp, *rp; /* left and right vector pointers */ t_float scalar; int j; left = argv++; FUNC_EVAL_UNARY(left, fabs, (double), optr, 0); } /* *ex_if -- floating point modulo */ static void ex_if(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { struct ex_ex *left, *right, *cond, *res; t_float *op; /* output pointer */ t_float *lp, *rp; /* left and right vector pointers */ t_float *cp; /* condition pointer */ t_float leftvalue, rightvalue; int j; cond = argv++; left = argv++; right = argv; switch (cond->ex_type) { case ET_VEC: case ET_VI: if (optr->ex_type != ET_VEC) { if (optr->ex_type == ET_VI) { /* SDY remove this test */ post("expr~: Int. error %d", __LINE__); return; } optr->ex_type = ET_VEC; optr->ex_vec = (t_float *) fts_malloc(sizeof (t_float) * e->exp_vsize); } op = optr->ex_vec; j = e->exp_vsize; cp = cond->ex_vec; switch (left->ex_type) { case ET_INT: leftvalue = left->ex_int; switch (right->ex_type) { case ET_INT: rightvalue = right->ex_int; while (j--) { if (*cp++) *op++ = leftvalue; else *op++ = rightvalue; } return; case ET_FLT: rightvalue = right->ex_flt; while (j--) { if (*cp++) *op++ = leftvalue; else *op++ = rightvalue; } return; case ET_VEC: case ET_VI: rp = right->ex_vec; while (j--) { if (*cp++) *op++ = leftvalue; else *op++ = *rp; rp++; } return; case ET_SYM: default: post_error((fts_object_t *) e, "expr: FUNC_EVAL(%d): bad right type %ld\n", __LINE__, right->ex_type); return; } case ET_FLT: leftvalue = left->ex_flt; switch (right->ex_type) { case ET_INT: rightvalue = right->ex_int; while (j--) { if (*cp++) *op++ = leftvalue; else *op++ = rightvalue; } return; case ET_FLT: rightvalue = right->ex_flt; while (j--) { if (*cp++) *op++ = leftvalue; else *op++ = rightvalue; } return; case ET_VEC: case ET_VI: rp = right->ex_vec; while (j--) { if (*cp++) *op++ = leftvalue; else *op++ = *rp; rp++; } return; case ET_SYM: default: post_error((fts_object_t *) e, "expr: FUNC_EVAL(%d): bad right type %ld\n", __LINE__, right->ex_type); return; } case ET_VEC: case ET_VI: lp = left->ex_vec; switch (right->ex_type) { case ET_INT: rightvalue = right->ex_int; while (j--) { if (*cp++) *op++ = *lp; else *op++ = rightvalue; lp++; } return; case ET_FLT: rightvalue = right->ex_flt; while (j--) { if (*cp++) *op++ = *lp; else *op++ = rightvalue; lp++; } return; case ET_VEC: case ET_VI: rp = right->ex_vec; while (j--) { if (*cp++) *op++ = *lp; else *op++ = *rp; lp++; rp++; } return; case ET_SYM: default: post_error((fts_object_t *) e, "expr: FUNC_EVAL(%d): bad right type %ld\n", __LINE__, right->ex_type); return; } case ET_SYM: default: post_error((fts_object_t *) e, "expr: FUNC_EVAL(%d): bad left type %ld\n", __LINE__, left->ex_type); return; } case ET_INT: if (cond->ex_int) res = left; else res = right; break; case ET_FLT: if (cond->ex_flt) res = left; else res = right; break; case ET_SYM: default: post_error((fts_object_t *) e, "expr: FUNC_EVAL(%d): bad condition type %ld\n", __LINE__, cond->ex_type); return; } switch(res->ex_type) { case ET_INT: if (optr->ex_type == ET_VEC) { ex_mkvector(optr->ex_vec, (t_float)res->ex_int, e->exp_vsize); return; } *optr = *res; return; case ET_FLT: if (optr->ex_type == ET_VEC) { ex_mkvector(optr->ex_vec, (t_float)res->ex_flt, e->exp_vsize); return; } *optr = *res; return; case ET_VEC: case ET_VI: if (optr->ex_type != ET_VEC) { if (optr->ex_type == ET_VI) { /* SDY remove this test */ post("expr~: Int. error %d", __LINE__); return; } optr->ex_type = ET_VEC; optr->ex_vec = (t_float *) fts_malloc(sizeof (t_float) * e->exp_vsize); } memcpy(optr->ex_vec, res->ex_vec, e->exp_vsize*sizeof(t_float)); return; case ET_SYM: default: post_error((fts_object_t *) e, "expr: FUNC_EVAL(%d): bad res type %ld\n", __LINE__, res->ex_type); return; } } /* * ex_imodf - extract signed integral value from floating-point number */ static double imodf(double x) { double xx; modf(x, &xx); return (xx); } FUNC_DEF_UNARY(ex_imodf, imodf, (double), 1); /* * ex_modf - extract signed fractional value from floating-point number * * using fracmodf because fmodf() is alrady defined in a .h file */ static double fracmodf(double x) { double xx; return(modf(x, &xx)); } FUNC_DEF_UNARY(ex_modf, fracmodf, (double), 1); /* * ex_ldexp - multiply floating-point number by integral power of 2 */ FUNC_DEF(ex_ldexp, ldexp, (double), (int), 1); #ifndef _WIN32 /* * ex_cbrt - cube root */ FUNC_DEF_UNARY(ex_cbrt, cbrt, (double), 1); /* * ex_erf - error function */ FUNC_DEF_UNARY(ex_erf, erf, (double), 1); /* * ex_erfc - complementary error function */ FUNC_DEF_UNARY(ex_erfc, erfc, (double), 1); /* * ex_expm1 - exponential minus 1, */ FUNC_DEF_UNARY(ex_expm1, expm1, (double), 1); /* * ex_log1p - logarithm of 1 plus */ FUNC_DEF_UNARY(ex_log1p, log1p, (double), 1); /* * ex_isinf - is the value infinite, */ FUNC_DEF_UNARY(ex_isinf, isinf, (double), 0); /* * ex_finite - is the value finite */ FUNC_DEF_UNARY(ex_finite, isfinite, (double), 0); /* * ex_isnan -- is the resut a nan (Not a number) */ FUNC_DEF_UNARY(ex_isnan, isnan, (double), 0); /* * ex_copysign - copy sign of a number */ FUNC_DEF(ex_copysign, copysign, (double), (double), 1); /* * ex_drem - floating-point remainder function */ FUNC_DEF(ex_drem, remainder, (double), (double), 1); #endif #ifdef notdef /* the following will be added once they are more popular in math libraries */ /* * ex_hypoth - Euclidean distance function */ FUNC_DEF(ex_hypoth, hypoth, (double), (double), 1); /* * ex_round - round to nearest integer, away from zero */ FUNC_DEF_UNARY(ex_round, round, (double), 1); /* * ex_trunc - round to interger, towards zero */ FUNC_DEF_UNARY(ex_trunc, trunc, (double), 1); /* * ex_nearbyint - round to nearest integer */ FUNC_DEF_UNARY(ex_nearbyint, nearbyint, (double), 1); #endif pd-0.46-7/extra/expr~/GNUmakefile.am0000664000175000017500000000410612374250720015344 0ustar mspmsp## Makefile.am -- Process this file with automake to produce Makefile.in NAME=expr~ external_LTLIBRARIES = expr~.la expr__la_SOURCES = vexp.c vexp_fun.c vexp_if.c PATCHES = ../expr-help.pd OTHERDATA = LICENSE.txt README.txt EXTRA_DIST = makefile ############################### # you shouldn't need to add anything below here dist_external_DATA = $(PATCHES) $(OTHERDATA) noinst_HEADERS = fts_to_pd.h vexp.h AUTOMAKE_OPTIONS = foreign AM_CPPFLAGS = -I$(top_srcdir)/src -DPD AM_CFLAGS = @ARCH_CFLAGS@ AM_LIBS = $(LIBM) AM_LDFLAGS = -module -avoid-version -shared @ARCH_LDFLAGS@ -shrext .@EXTERNAL_EXTENSION@ -L$(top_srcdir)/src externaldir = $(pkglibdir)/extra/$(NAME) # install-exec-hook seems to be called before $(DESTDIR)$(externaldir) is created... # so we install everything in the install-data-hook install-data-hook: cd $(DESTDIR)$(externaldir) && ( \ rm -f expr.@EXTERNAL_EXTENSION@; \ rm -f fexpr~.@EXTERNAL_EXTENSION@; \ rm -f ../expr.@EXTERNAL_EXTENSION@; \ rm -f ../expr~.@EXTERNAL_EXTENSION@; \ rm -f ../fexpr~.@EXTERNAL_EXTENSION@; \ rm -f ../expr-help.pd; \ rm -f ../expr~-help.pd; \ rm -f ../fexpr~-help.pd; \ $(LN_S) expr~.@EXTERNAL_EXTENSION@ expr.@EXTERNAL_EXTENSION@; \ $(LN_S) expr~.@EXTERNAL_EXTENSION@ fexpr~.@EXTERNAL_EXTENSION@; \ cd ..; \ $(LN_S) $(NAME)/expr.@EXTERNAL_EXTENSION@ expr.@EXTERNAL_EXTENSION@; \ $(LN_S) $(NAME)/expr~.@EXTERNAL_EXTENSION@ expr~.@EXTERNAL_EXTENSION@; \ $(LN_S) $(NAME)/fexpr~.@EXTERNAL_EXTENSION@ fexpr~.@EXTERNAL_EXTENSION@; \ $(LN_S) $(NAME)/expr-help.pd expr-help.pd; \ $(LN_S) $(NAME)/expr-help.pd expr~-help.pd; \ $(LN_S) $(NAME)/expr-help.pd fexpr~-help.pd; \ ) uninstall-hook: cd $(DESTDIR)$(externaldir) && ( \ rm -f expr.@EXTERNAL_EXTENSION@ fexpr~.@EXTERNAL_EXTENSION@; \ cd ..; \ rm -f expr~.@EXTERNAL_EXTENSION@ expr.@EXTERNAL_EXTENSION@ fexpr~.@EXTERNAL_EXTENSION@; \ rm -f expr-help.pd expr~-help.pd fexpr~-help.pd; \ ) if MINGW AM_LIBS += -lpd endif libtool: $(LIBTOOL_DEPS) $(SHELL) ./config.status --recheck pd-0.46-7/extra/expr~/README.txt0000664000175000017500000000675612160204055014402 0ustar mspmsp You can get more information on the expr object at http://www.crca.ucsd.edu/~yadegari/expr.html ----------- New if Version 0.4 -access to variables (made by value object) -multiple expression separated by ; -added the following shorthands: $y or $y1 = $y1[-1] and $y2 = $y2[-1] -new functions: if - conditional evaluation cbrt - cube root erf - error function erfc - complementary error function expm1 - exponential minus 1, log1p - logarithm of 1 plus isinf - is the value infinite, finite - is the value finite isnan -- is the resut a nan (Not a number) copysign - copy sign of a number ldexp - multiply floating-point number by integral power of 2 imodf - get signed integral value from floating-point number modf - get signed fractional value from floating-point number drem - floating-point remainder function Thanks to Orm Finnendahl for adding the following functions: fmod - floating-point remainder function ceil - ceiling function: smallest integral value not less than argument floor - largest integral value not greater than argument ------------ New in Version 0.3 -Full function functionality ------------ The object "expr" is used for expression evaluaion of control data. Expr~ and fexpr~ are extentions to the expr object to work with vectors. The expr~ object is designed to efficiently combine signal and control stream processing by vector operations on the basis of the block size of the environment. fexpr~ object provides a flexible mechanism for building FIR and IIR filters by evaluating expressions on a sample by sample basis and providing access to prior samples of the input and output audio streams. When fractional offset is used, fexpr~ uses linear interpolation to determine the value of the indexed sample. fexpr~ evaluates the expression for every single sample and at every evaluation previous samples (limited by the audio vector size) can be accessed. $x is used to denote a singnal input whose samples we would like to access. The syntax is $x followed by the inlet number and indexed by brackets, for example $x1[-1] specifies the previous sample of the first inlet. Therefore, if we are to build a simple filter which replaces every sample by the average of that sample and its previous one, we would use "fexpr~ ($x1[0]+$x1[-1])/2 ". For ease of when the brackets are omitted, the current sample is implied, so we can right the previous filter expression as follows: " fexpr~ ($x1+$x1[-1])/2". To build IIR filters $y is used to access the previous samples of the output stream. The three objects expr, expr~, and fexpr~ are implemented in the same object so the files expr~.pd_linux and fexpr~.pd_linux are links to expr.pd_linux This release has been compiled and tested on Linux 6.0. -------- Here are some syntax information: (refer to help-expr.pd for examples) Syntyax: The syntax is very close to how expression are written in C. Variables are specified as follows where the '#' stands for the inlet number: $i#: integer input variable $f#: float input variable $s#: symbol input variable Used for expr~ only: $v#: signal (vector) input (vector by vector evaluation) Used for fexpr~ only: $x#[n]: the sample from inlet # indexed by n, where n has to satisfy 0 => n >= -vector size, ($x# is a shorthand for $x#[0], specifying the current sample) $y#[n]: the output value indexed by n, where n has to satisfy 0 > n >= -vector size, $y[n] is a shorthand for $y1[n] I'll appreciate hearing about bugs, comments, suggestions, ... Shahrokh Yadegari (sdy@ucsd.edu) 7/10/02 pd-0.46-7/extra/expr~/fts_to_pd.h0000664000175000017500000000164712160204055015030 0ustar mspmsp/* fts_to_pd.h -- alias some fts names to compile in Pd. copyright 1999 Miller Puckette; permission is granted to use this file for any purpose. */ #define fts_malloc malloc #define fts_calloc calloc #define fts_free free #define fts_realloc realloc #define fts_atom_t t_atom #define fts_object_t t_object typedef t_symbol *fts_symbol_t; #ifdef MSP #define t_atom Atom #define t_symbol Symbol #define pd_new(x) newobject(x); #define pd_free(x) freeobject(x); #define t_outlet void #define t_binbuf void typedef t_class *t_pd; typedef float t_floatarg; #include #include #include #include #include void pd_error(void *object, char *fmt, ...); #endif /* MSP */ #define post_error pd_error #define fts_is_floatg(x) ((x)->a_type == A_FLOAT) #define fts_new_symbol_copy gensym #define fts_symbol_name(x) ((x)->s_name) pd-0.46-7/extra/expr~/vexp_if.c0000600000175000017500000011265212515035730014475 0ustar mspmsp/* * jMax * Copyright (C) 1994, 1995, 1998, 1999 by IRCAM-Centre Georges Pompidou, Paris, France. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * See file LICENSE for further informations on licensing terms. * * 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Based on Max/ISPW by Miller Puckette. * * Authors: Maurizio De Cecco, Francois Dechelle, Enzo Maggi, Norbert Schnell. * */ /* "expr" was written by Shahrokh Yadegari c. 1989. -msp */ /* "expr~" and "fexpr~" conversion by Shahrokh Yadegari c. 1999,2000 */ /* * Feb 2002 - added access to variables * multiple expression support * new short hand forms for fexpr~ * now $y or $y1 = $y1[-1] and $y2 = $y2[-1] * --sdy */ #include #include #include #include "vexp.h" static char *exp_version = "0.4"; extern struct ex_ex *ex_eval(struct expr *expr, struct ex_ex *eptr, struct ex_ex *optr, int n); #ifdef PD static t_class *expr_class; static t_class *expr_tilde_class; static t_class *fexpr_tilde_class; #else /* MSP */ void *expr_tilde_class; #endif /*------------------------- expr class -------------------------------------*/ extern int expr_donew(struct expr *expr, int ac, t_atom *av); /*#define EXPR_DEBUG*/ static void expr_bang(t_expr *x); t_int *expr_perform(t_int *w); static void expr_list(t_expr *x, t_symbol *s, int argc, const fts_atom_t *argv) { int i; if (argc > MAX_VARS) argc = MAX_VARS; for (i = 0; i < argc; i++) { if (argv[i].a_type == A_FLOAT) { if (x->exp_var[i].ex_type == ET_FI) x->exp_var[i].ex_flt = argv[i].a_w.w_float; else if (x->exp_var[i].ex_type == ET_II) x->exp_var[i].ex_int = argv[i].a_w.w_float; else if (x->exp_var[i].ex_type) pd_error(x, "expr: type mismatch"); } else if (argv[i].a_type == A_SYMBOL) { if (x->exp_var[i].ex_type == ET_SI) x->exp_var[i].ex_ptr = (char *)argv[i].a_w.w_symbol; else if (x->exp_var[i].ex_type) pd_error(x, "expr: type mismatch"); } } expr_bang(x); } static void expr_flt(t_expr *x, t_float f, int in) { if (in > MAX_VARS) return; if (x->exp_var[in].ex_type == ET_FI) x->exp_var[in].ex_flt = f; else if (x->exp_var[in].ex_type == ET_II) x->exp_var[in].ex_int = f; } static t_class *exprproxy_class; typedef struct _exprproxy { t_pd p_pd; int p_index; t_expr *p_owner; struct _exprproxy *p_next; } t_exprproxy; t_exprproxy *exprproxy_new(t_expr *owner, int indx); void exprproxy_float(t_exprproxy *p, t_floatarg f); t_exprproxy * exprproxy_new(t_expr *owner, int indx) { t_exprproxy *x = (t_exprproxy *)pd_new(exprproxy_class); x->p_owner = owner; x->p_index = indx; x->p_next = owner->exp_proxy; owner->exp_proxy = x; return (x); } void exprproxy_float(t_exprproxy *p, t_floatarg f) { t_expr *x = p->p_owner; int in = p->p_index; if (in > MAX_VARS) return; if (x->exp_var[in].ex_type == ET_FI) x->exp_var[in].ex_flt = f; else if (x->exp_var[in].ex_type == ET_II) x->exp_var[in].ex_int = f; } /* method definitions */ static void expr_ff(t_expr *x) { t_exprproxy *y; int i; y = x->exp_proxy; while (y) { x->exp_proxy = y->p_next; #ifdef PD pd_free(&y->p_pd); #else /*MSP */ /* SDY find out what needs to be called for MSP */ #endif y = x->exp_proxy; } for (i = 0 ; i < x->exp_nexpr; i++); if (x->exp_stack[i]) fts_free(x->exp_stack[i]); /* * SDY free all the allocated buffers here for expr~ and fexpr~ * check to see if there are others */ for (i = 0; i < MAX_VARS; i++) { if (x->exp_p_var[i]) fts_free(x->exp_p_var[i]); if (x->exp_p_res[i]) fts_free(x->exp_p_res[i]); if (x->exp_tmpres[i]) fts_free(x->exp_tmpres[i]); } } static void expr_bang(t_expr *x) { int i; #ifdef EXPR_DEBUG { struct ex_ex *eptr; for (i = 0, eptr = x->exp_var; ; eptr++, i++) { if (!eptr->ex_type) break; switch (eptr->ex_type) { case ET_II: fprintf(stderr,"ET_II: %d \n", eptr->ex_int); break; case ET_FI: fprintf(stderr,"ET_FT: %f \n", eptr->ex_flt); break; default: fprintf(stderr,"oups\n"); } } } #endif /* banging a signal or filter object means nothing */ if (!IS_EXPR(x)) return; for (i = x->exp_nexpr - 1; i > -1 ; i--) { if (!ex_eval(x, x->exp_stack[i], &x->exp_res[i], 0)) { /*fprintf(stderr,"expr_bang(error evaluation)\n"); */ /* SDY now that we have mutiple ones, on error we should * continue return; */ } switch(x->exp_res[i].ex_type) { case ET_INT: outlet_float(x->exp_outlet[i], (t_float) x->exp_res[i].ex_int); break; case ET_FLT: outlet_float(x->exp_outlet[i], x->exp_res[i].ex_flt); break; case ET_SYM: /* CHANGE this will have to be taken care of */ default: post("expr: bang: unrecognized result %ld\n", x->exp_res[i].ex_type); } } } static t_expr * #ifdef PD expr_new(t_symbol *s, int ac, t_atom *av) #else /* MSP */ Nexpr_new(t_symbol *s, int ac, t_atom *av) #endif { struct expr *x; int i, ninlet; struct ex_ex *eptr; t_atom fakearg; int dsp_index; /* keeping track of the dsp inlets */ /* * SDY - we may need to call dsp_setup() in this function */ if (!ac) { ac = 1; av = &fakearg; SETFLOAT(&fakearg, 0); } #ifdef PD /* * figure out if we are expr, expr~, or fexpr~ */ if (!strcmp("expr", s->s_name)) { x = (t_expr *)pd_new(expr_class); SET_EXPR(x); } else if (!strcmp("expr~", s->s_name)) { x = (t_expr *)pd_new(expr_tilde_class); SET_EXPR_TILDE(x); } else if (!strcmp("fexpr~", s->s_name)) { x = (t_expr *)pd_new(fexpr_tilde_class); SET_FEXPR_TILDE(x); } else { post("expr_new: bad object name '%s'", s->s_name); /* assume expr */ x = (t_expr *)pd_new(expr_class); SET_EXPR(x); } #else /* MSP */ /* for now assume an expr~ */ x = (t_expr *)pd_new(expr_tilde_class); SET_EXPR_TILDE(x); #endif /* * initialize the newly allocated object */ x->exp_proxy = 0; x->exp_nivec = 0; x->exp_nexpr = 0; x->exp_error = 0; for (i = 0; i < MAX_VARS; i++) { x->exp_stack[i] = (struct ex_ex *)0; x->exp_outlet[i] = (t_outlet *)0; x->exp_res[i].ex_type = 0; x->exp_res[i].ex_int = 0; x->exp_p_res[i] = (t_float *)0; x->exp_var[i].ex_type = 0; x->exp_var[i].ex_int = 0; x->exp_p_var[i] = (t_float *)0; x->exp_tmpres[i] = (t_float *)0; x->exp_vsize = 0; } x->exp_f = 0; /* save the control value to be transformed to signal */ if (expr_donew(x, ac, av)) { pd_error(x, "expr: syntax error"); /* SDY the following coredumps why? pd_free(&x->exp_ob.ob_pd); */ return (0); } ninlet = 1; for (i = 0, eptr = x->exp_var; i < MAX_VARS ; i++, eptr++) if (eptr->ex_type) { ninlet = i + 1; } /* * create the new inlets */ for (i = 1, eptr = x->exp_var + 1, dsp_index=1; iex_type) { case 0: /* nothing is using this inlet */ if (i < ninlet) #ifdef PD floatinlet_new(&x->exp_ob, &eptr->ex_flt); #else /* MSP */ inlet_new(&x->exp_ob, "float"); #endif break; case ET_II: case ET_FI: p = exprproxy_new(x, i); #ifdef PD inlet_new(&x->exp_ob, &p->p_pd, &s_float, &s_float); #else /* MSP */ inlet_new(&x->exp_ob, "float"); #endif break; case ET_SI: #ifdef PD symbolinlet_new(&x->exp_ob, (t_symbol **)&eptr->ex_ptr); #else /* MSP */ inlet_new(&x->exp_ob, "symbol"); #endif break; case ET_XI: case ET_VI: if (!IS_EXPR(x)) { dsp_index++; #ifdef PD inlet_new(&x->exp_ob, &x->exp_ob.ob_pd, &s_signal, &s_signal); #else /* MSP */ inlet_new(&x->exp_ob, "signal"); #endif break; } else post("expr: internal error expr_new"); default: pd_error(x, "expr: bad type (%lx) inlet = %d\n", eptr->ex_type, i + 1); break; } } if (IS_EXPR(x)) { for (i = 0; i < x->exp_nexpr; i++) x->exp_outlet[i] = outlet_new(&x->exp_ob, 0); } else { for (i = 0; i < x->exp_nexpr; i++) x->exp_outlet[i] = outlet_new(&x->exp_ob, gensym("signal")); x->exp_nivec = dsp_index; } /* * for now assume a 64 sample size block but this may change once * expr_dsp is called */ x->exp_vsize = 64; for (i = 0; i < x->exp_nexpr; i++) { x->exp_p_res[i] = fts_calloc(x->exp_vsize, sizeof (t_float)); x->exp_tmpres[i] = fts_calloc(x->exp_vsize, sizeof (t_float)); } for (i = 0; i < MAX_VARS; i++) x->exp_p_var[i] = fts_calloc(x->exp_vsize, sizeof (t_float)); return (x); } t_int * expr_perform(t_int *w) { int i, j; t_expr *x = (t_expr *)w[1]; struct ex_ex res; int n; /* sanity check */ if (IS_EXPR(x)) { post("expr_perform: bad x->exp_flags = %d", x->exp_flags); abort(); } if (x->exp_flags & EF_STOP) { for (i = 0; i < x->exp_nexpr; i++) memset(x->exp_res[i].ex_vec, 0, x->exp_vsize * sizeof (t_float)); return (w + 2); } if (IS_EXPR_TILDE(x)) { /* * if we have only one expression, we can right on * on the output directly, otherwise we have to copy * the data because, outputs could be the same buffer as * inputs */ if ( x->exp_nexpr == 1) ex_eval(x, x->exp_stack[0], &x->exp_res[0], 0); else { res.ex_type = ET_VEC; for (i = 0; i < x->exp_nexpr; i++) { res.ex_vec = x->exp_tmpres[i]; ex_eval(x, x->exp_stack[i], &res, 0); } n = x->exp_vsize * sizeof(t_float); for (i = 0; i < x->exp_nexpr; i++) memcpy(x->exp_res[i].ex_vec, x->exp_tmpres[i], n); } return (w + 2); } if (!IS_FEXPR_TILDE(x)) { post("expr_perform: bad x->exp_flags = %d - expecting fexpr", x->exp_flags); return (w + 2); } /* * since the output buffer could be the same as one of the inputs * we need to keep the output in a different buffer */ for (i = 0; i < x->exp_vsize; i++) for (j = 0; j < x->exp_nexpr; j++) { res.ex_type = 0; res.ex_int = 0; ex_eval(x, x->exp_stack[j], &res, i); switch (res.ex_type) { case ET_INT: x->exp_tmpres[j][i] = (t_float) res.ex_int; break; case ET_FLT: x->exp_tmpres[j][i] = res.ex_flt; break; default: post("expr_perform: bad result type %d", res.ex_type); } } /* * copy inputs and results to the save buffers * inputs need to be copied first as the output buffer can be * same as an input buffer */ n = x->exp_vsize * sizeof(t_float); for (i = 0; i < MAX_VARS; i++) if (x->exp_var[i].ex_type == ET_XI) memcpy(x->exp_p_var[i], x->exp_var[i].ex_vec, n); for (i = 0; i < x->exp_nexpr; i++) { memcpy(x->exp_p_res[i], x->exp_tmpres[i], n); memcpy(x->exp_res[i].ex_vec, x->exp_tmpres[i], n); } return (w + 2); } static void expr_dsp(t_expr *x, t_signal **sp) { int i, nv; int newsize; x->exp_error = 0; /* reset all errors */ newsize = (x->exp_vsize != sp[0]->s_n); x->exp_vsize = sp[0]->s_n; /* record the vector size */ for (i = 0; i < x->exp_nexpr; i++) { x->exp_res[i].ex_type = ET_VEC; x->exp_res[i].ex_vec = sp[x->exp_nivec + i]->s_vec; } for (i = 0, nv = 0; i < MAX_VARS; i++) /* * the first inlet is always a signal * * SDY We are warning the user till this limitation * is taken away from pd */ if (!i || x->exp_var[i].ex_type == ET_VI || x->exp_var[i].ex_type == ET_XI) { if (nv >= x->exp_nivec) { post("expr_dsp int. err nv = %d, x->exp_nive = %d", nv, x->exp_nivec); abort(); } x->exp_var[i].ex_vec = sp[nv]->s_vec; nv++; } /* we always have one inlet but we may not use it */ if (nv != x->exp_nivec && (nv != 0 || x->exp_nivec != 1)) { post("expr_dsp internal error 2 nv = %d, x->exp_nive = %d", nv, x->exp_nivec); abort(); } dsp_add(expr_perform, 1, (t_int *) x); /* * The buffer are now being allocated for expr~ and fexpr~ * because if we have more than one expression we need the * temporary buffers, The save buffers are not really needed if (!IS_FEXPR_TILDE(x)) return; */ /* * if we have already allocated the buffers and we have a * new size free all the buffers */ if (x->exp_p_res[0]) { if (!newsize) return; /* * if new size, reallocate all the previous buffers for fexpr~ */ for (i = 0; i < x->exp_nexpr; i++) { fts_free(x->exp_p_res[i]); fts_free(x->exp_tmpres[i]); } for (i = 0; i < MAX_VARS; i++) fts_free(x->exp_p_var[i]); } for (i = 0; i < x->exp_nexpr; i++) { x->exp_p_res[i] = fts_calloc(x->exp_vsize, sizeof (t_float)); x->exp_tmpres[i] = fts_calloc(x->exp_vsize, sizeof (t_float)); } for (i = 0; i < MAX_VARS; i++) x->exp_p_var[i] = fts_calloc(x->exp_vsize, sizeof (t_float)); } /* * expr_verbose -- toggle the verbose switch */ static void expr_verbose(t_expr *x) { if (x->exp_flags & EF_VERBOSE) { x->exp_flags &= ~EF_VERBOSE; post ("verbose off"); } else { x->exp_flags |= EF_VERBOSE; post ("verbose on"); } } /* * expr_start -- turn on expr processing for now only used for fexpr~ */ static void expr_start(t_expr *x) { x->exp_flags &= ~EF_STOP; } /* * expr_stop -- turn on expr processing for now only used for fexpr~ */ static void expr_stop(t_expr *x) { x->exp_flags |= EF_STOP; } static void fexpr_set_usage(void) { post("fexpr~: set val ..."); post("fexpr~: set {xy}[#] val ..."); } /* * fexpr_tilde_set -- set previous values of the buffers * set val val ... - sets the first elements of output buffers * set x val ... - sets the elements of the first input buffer * set x# val ... - sets the elements of the #th input buffers * set y val ... - sets the elements of the first output buffer * set y# val ... - sets the elements of the #th output buffers */ static void fexpr_tilde_set(t_expr *x, t_symbol *s, int argc, t_atom *argv) { t_symbol *sx; int vecno; int i, nargs; if (!argc) return; sx = atom_getsymbolarg(0, argc, argv); switch(sx->s_name[0]) { case 'x': if (!sx->s_name[1]) vecno = 0; else { vecno = atoi(sx->s_name + 1); if (!vecno) { post("fexpr~.set: bad set x vector number"); fexpr_set_usage(); return; } if (vecno >= MAX_VARS) { post("fexpr~.set: no more than %d inlets", MAX_VARS); return; } vecno--; } if (x->exp_var[vecno].ex_type != ET_XI) { post("fexpr~-set: no signal at inlet %d", vecno + 1); return; } nargs = argc - 1; if (!nargs) { post("fexpr~-set: no argument to set"); return; } if (nargs > x->exp_vsize) { post("fexpr~.set: %d set values larger than vector size(%d)", nargs, x->exp_vsize); post("fexpr~.set: only the first %d values will be set", x->exp_vsize); nargs = x->exp_vsize; } for (i = 0; i < nargs; i++) { x->exp_p_var[vecno][x->exp_vsize - i - 1] = atom_getfloatarg(i + 1, argc, argv); } return; case 'y': if (!sx->s_name[1]) vecno = 0; else { vecno = atoi(sx->s_name + 1); if (!vecno) { post("fexpr~.set: bad set y vector number"); fexpr_set_usage(); return; } vecno--; } if (vecno >= x->exp_nexpr) { post("fexpr~.set: only %d outlets", x->exp_nexpr); return; } nargs = argc - 1; if (!nargs) { post("fexpr~-set: no argument to set"); return; } if (nargs > x->exp_vsize) { post("fexpr~-set: %d set values larger than vector size(%d)", nargs, x->exp_vsize); post("fexpr~.set: only the first %d values will be set", x->exp_vsize); nargs = x->exp_vsize; } for (i = 0; i < nargs; i++) { x->exp_p_res[vecno][x->exp_vsize - i - 1] = atom_getfloatarg(i + 1, argc, argv); } return; case 0: if (argc > x->exp_nexpr) { post("fexpr~.set: only %d outlets available", x->exp_nexpr); post("fexpr~.set: the extra set values are ignored"); } for (i = 0; i < x->exp_nexpr && i < argc; i++) x->exp_p_res[i][x->exp_vsize - 1] = atom_getfloatarg(i, argc, argv); return; default: fexpr_set_usage(); return; } return; } /* * fexpr_tilde_clear - clear the past buffers */ static void fexpr_tilde_clear(t_expr *x, t_symbol *s, int argc, t_atom *argv) { t_symbol *sx; int vecno; int i, nargs; /* * if no arguement clear all input and output buffers */ if (!argc) { for (i = 0; i < x->exp_nexpr; i++) memset(x->exp_p_res[i], 0, x->exp_vsize*sizeof(t_float)); for (i = 0; i < MAX_VARS; i++) if (x->exp_var[i].ex_type == ET_XI) memset(x->exp_p_var[i], 0, x->exp_vsize*sizeof(t_float)); return; } if (argc > 1) { post("fexpr~ usage: 'clear' or 'clear {xy}[#]'"); return; } sx = atom_getsymbolarg(0, argc, argv); switch(sx->s_name[0]) { case 'x': if (!sx->s_name[1]) vecno = 0; else { vecno = atoi(sx->s_name + 1); if (!vecno) { post("fexpr~.clear: bad clear x vector number"); return; } if (vecno >= MAX_VARS) { post("fexpr~.clear: no more than %d inlets", MAX_VARS); return; } vecno--; } if (x->exp_var[vecno].ex_type != ET_XI) { post("fexpr~-clear: no signal at inlet %d", vecno + 1); return; } memset(x->exp_p_var[vecno], 0, x->exp_vsize*sizeof(t_float)); return; case 'y': if (!sx->s_name[1]) vecno = 0; else { vecno = atoi(sx->s_name + 1); if (!vecno) { post("fexpr~.clear: bad clear y vector number"); return; } vecno--; } if (vecno >= x->exp_nexpr) { post("fexpr~.clear: only %d outlets", x->exp_nexpr); return; } memset(x->exp_p_res[vecno], 0, x->exp_vsize*sizeof(t_float)); return; return; default: post("fexpr~ usage: 'clear' or 'clear {xy}[#]'"); return; } return; } #ifdef PD void expr_setup(void) { /* * expr initialization */ expr_class = class_new(gensym("expr"), (t_newmethod)expr_new, (t_method)expr_ff, sizeof(t_expr), 0, A_GIMME, 0); class_addlist(expr_class, expr_list); exprproxy_class = class_new(gensym("exprproxy"), 0, 0, sizeof(t_exprproxy), CLASS_PD, 0); class_addfloat(exprproxy_class, exprproxy_float); /* * expr~ initialization */ expr_tilde_class = class_new(gensym("expr~"), (t_newmethod)expr_new, (t_method)expr_ff, sizeof(t_expr), 0, A_GIMME, 0); class_addmethod(expr_tilde_class, nullfn, gensym("signal"), 0); CLASS_MAINSIGNALIN(expr_tilde_class, t_expr, exp_f); class_addmethod(expr_tilde_class,(t_method)expr_dsp, gensym("dsp"), 0); class_sethelpsymbol(expr_tilde_class, gensym("expr")); /* * fexpr~ initialization */ fexpr_tilde_class = class_new(gensym("fexpr~"), (t_newmethod)expr_new, (t_method)expr_ff, sizeof(t_expr), 0, A_GIMME, 0); class_addmethod(fexpr_tilde_class, nullfn, gensym("signal"), 0); class_addmethod(fexpr_tilde_class,(t_method)expr_start, gensym("start"), 0); class_addmethod(fexpr_tilde_class,(t_method)expr_stop, gensym("stop"), 0); class_addmethod(fexpr_tilde_class,(t_method)expr_dsp,gensym("dsp"), 0); class_addmethod(fexpr_tilde_class, (t_method)fexpr_tilde_set, gensym("set"), A_GIMME, 0); class_addmethod(fexpr_tilde_class, (t_method)fexpr_tilde_clear, gensym("clear"), A_GIMME, 0); class_addmethod(fexpr_tilde_class,(t_method)expr_verbose, gensym("verbose"), 0); class_sethelpsymbol(fexpr_tilde_class, gensym("expr")); post( "expr, expr~, fexpr~ version %s under GNU Lesser General Public License ", exp_version); } void expr_tilde_setup(void) { expr_setup(); } void fexpr_tilde_setup(void) { expr_setup(); } #else /* MSP */ void main(void) { setup((t_messlist **)&expr_tilde_class, (method)Nexpr_new, (method)expr_ff, (short)sizeof(t_expr), 0L, A_GIMME, 0); addmess((method)expr_dsp, "dsp", A_CANT, 0); // dsp method dsp_initclass(); } #endif /* -- the following functions use Pd internals and so are in the "if" file. */ int ex_getsym(char *p, fts_symbol_t *s) { *s = gensym(p); return (0); } const char * ex_symname(fts_symbol_t s) { return (fts_symbol_name(s)); } /* * max_ex_tab -- evaluate this table access * eptr is the name of the table and arg is the index we * have to put the result in optr * return 1 on error and 0 otherwise * * Arguments: * the expr object * table * the argument * the result pointer */ int max_ex_tab(struct expr *expr, fts_symbol_t s, struct ex_ex *arg, struct ex_ex *optr) { #ifdef PD t_garray *garray; int size, indx; t_word *wvec; if (!s || !(garray = (t_garray *)pd_findbyclass(s, garray_class)) || !garray_getfloatwords(garray, &size, &wvec)) { optr->ex_type = ET_FLT; optr->ex_flt = 0; pd_error(expr, "no such table '%s'", s->s_name); return (1); } optr->ex_type = ET_FLT; switch (arg->ex_type) { case ET_INT: indx = arg->ex_int; break; case ET_FLT: /* strange interpolation code deleted here -msp */ indx = arg->ex_flt; break; default: /* do something with strings */ pd_error(expr, "expr: bad argument for table '%s'\n", fts_symbol_name(s)); indx = 0; } if (indx < 0) indx = 0; else if (indx >= size) indx = size - 1; optr->ex_flt = wvec[indx].w_float; #else /* MSP */ /* * table lookup not done for MSP yet */ post("max_ex_tab: not complete for MSP yet!"); optr->ex_type = ET_FLT; optr->ex_flt = 0; #endif return (0); } int max_ex_var(struct expr *expr, fts_symbol_t var, struct ex_ex *optr) { optr->ex_type = ET_FLT; if (value_getfloat(var, &(optr->ex_flt))) { optr->ex_type = ET_FLT; optr->ex_flt = 0; pd_error(expr, "no such var '%s'", var->s_name); return (1); } return (0); } #ifdef PD /* this goes to the end of this file as the following functions * should be defined in the expr object in MSP */ #define ISTABLE(sym, garray, size, vec) \ if (!sym || !(garray = (t_garray *)pd_findbyclass(sym, garray_class)) || \ !garray_getfloatwords(garray, &size, &vec)) { \ optr->ex_type = ET_FLT; \ optr->ex_int = 0; \ error("no such table '%s'", sym?(sym->s_name):"(null)"); \ return; \ } /* * ex_size -- find the size of a table */ void ex_size(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { t_symbol *s; t_garray *garray; int size; t_word *wvec; if (argv->ex_type != ET_SYM) { post("expr: size: need a table name\n"); optr->ex_type = ET_INT; optr->ex_int = 0; return; } s = (fts_symbol_t ) argv->ex_ptr; ISTABLE(s, garray, size, wvec); optr->ex_type = ET_INT; optr->ex_int = size; } /* * ex_sum -- calculate the sum of all elements of a table */ void ex_sum(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { t_symbol *s; t_garray *garray; int size; t_word *wvec; t_float sum; int indx; if (argv->ex_type != ET_SYM) { post("expr: sum: need a table name\n"); optr->ex_type = ET_INT; optr->ex_int = 0; return; } s = (fts_symbol_t ) argv->ex_ptr; ISTABLE(s, garray, size, wvec); for (indx = 0, sum = 0; indx < size; indx++) sum += wvec[indx].w_float; optr->ex_type = ET_FLT; optr->ex_flt = sum; } /* * ex_Sum -- calculate the sum of table with the given boundries */ void ex_Sum(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { t_symbol *s; t_garray *garray; int size; t_word *wvec; t_float sum; int indx, n1, n2; if (argv->ex_type != ET_SYM) { post("expr: sum: need a table name\n"); optr->ex_type = ET_INT; optr->ex_int = 0; return; } s = (fts_symbol_t ) argv->ex_ptr; ISTABLE(s, garray, size, wvec); if (argv->ex_type != ET_INT || argv[1].ex_type != ET_INT) { post("expr: Sum: boundries have to be fix values\n"); optr->ex_type = ET_INT; optr->ex_int = 0; return; } n1 = argv->ex_int; n2 = argv[1].ex_int; for (indx = n1, sum = 0; indx < n2; indx++) if (indx >= 0 && indx < size) sum += wvec[indx].w_float; optr->ex_type = ET_FLT; optr->ex_flt = sum; } /* * ex_avg -- calculate the avarage of a table */ void ex_avg(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { /* SDY - look into this function */ #if 0 fts_symbol_t s; fts_integer_vector_t *tw = 0; if (argv->ex_type != ET_SYM) { post("expr: avg: need a table name\n"); optr->ex_type = ET_INT; optr->ex_int = 0; } s = (fts_symbol_t ) argv->ex_ptr; tw = table_integer_vector_get_by_name(s); if (tw) { optr->ex_type = ET_INT; if (! fts_integer_vector_get_size(tw)) optr->ex_int = 0; else optr->ex_int = fts_integer_vector_get_sum(tw) / fts_integer_vector_get_size(tw); } else { optr->ex_type = ET_INT; optr->ex_int = 0; post("expr: avg: no such table %s\n", fts_symbol_name(s)); } #endif } /* * ex_Avg -- calculate the avarage of table with the given boundries */ void ex_Avg(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { /* SDY - look into this function */ #if 0 fts_symbol_t s; fts_integer_vector_t *tw = 0; if (argv->ex_type != ET_SYM) { post("expr: Avg: need a table name\n"); optr->ex_type = ET_INT; optr->ex_int = 0; } s = (fts_symbol_t ) (argv++)->ex_ptr; tw = table_integer_vector_get_by_name(s); if (! tw) { optr->ex_type = ET_INT; optr->ex_int = 0; post("expr: Avg: no such table %s\n", fts_symbol_name(s)); return; } if (argv->ex_type != ET_INT || argv[1].ex_type != ET_INT) { post("expr: Avg: boundries have to be fix values\n"); optr->ex_type = ET_INT; optr->ex_int = 0; return; } optr->ex_type = ET_INT; if (argv[1].ex_int - argv->ex_int <= 0) optr->ex_int = 0; else optr->ex_int = (fts_integer_vector_get_sub_sum(tw, argv->ex_int, argv[1].ex_int) / (argv[1].ex_int - argv->ex_int)); #endif } /* * ex_store -- store a value in a table * if the index is greater the size of the table, * we will make a modulo the size of the table */ void ex_store(t_expr *e, long int argc, struct ex_ex *argv, struct ex_ex *optr) { /* SDY - look into this function */ #if 0 fts_symbol_t s; fts_integer_vector_t *tw = 0; if (argv->ex_type != ET_SYM) { post("expr: store: need a table name\n"); } s = (fts_symbol_t ) (argv++)->ex_ptr; tw = table_integer_vector_get_by_name(s); if (! tw) { optr->ex_type = ET_INT; optr->ex_int = 0; post("expr: store: no such table %s\n", fts_symbol_name(s)); return; } if (argv->ex_type != ET_INT || argv[1].ex_type != ET_INT) { post("expr: store: arguments have to be integer\n"); optr->ex_type = ET_INT; optr->ex_int = 0; } fts_integer_vector_set_element(tw, argv->ex_int < 0 ? 0 : argv->ex_int % fts_integer_vector_get_size(tw), argv[1].ex_int); *optr = argv[1]; #endif } #else /* MSP */ void pd_error(void *object, char *fmt, ...) { va_list ap; t_int arg[8]; int i; static int saidit = 0; va_start(ap, fmt); /* SDY vsprintf(error_string, fmt, ap); */ post(fmt, ap); va_end(ap); /* SDY fprintf(stderr, "error: %s\n", error_string); error_object = object; */ if (!saidit) { post("... you might be able to track this down from the Find menu."); saidit = 1; } } #endif pd-0.46-7/extra/expr~/makefile0000664000175000017500000001007412574135745014412 0ustar mspmspcurrent: expr.pd_linux expr~.pd_linux fexpr~.pd_linux \ ../expr.pd_linux ../expr~.pd_linux ../fexpr~.pd_linux install: install_linux clean: clean_linux PDEXTERN=/usr/local/lib/pd/extra # ----------------------- Microsoft Visual C ----------------------- MSCC = cl MSLN = link COPY = copy DELETE = del .SUFFIXES:.obj pd_nt: expr.dll NTOBJ = vexp.obj vexp_fun.obj vexp_if.obj PDNTCFLAGS = /W3 /DNT /DPD /nologo VC = "C:\\Program Files\\Microsoft Visual Studio 9.0\\VC" VSTK = "C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0A" PDNTINCLUDE = /I. /I..\\..\\src /I$(VC)\\include PDNTLDIR = $(VC)\\lib PDNTLIB = /NODEFAULTLIB:libcmt /NODEFAULTLIB:oldnames /NODEFAULTLIB:kernel32 \ $(PDNTLDIR)\\libcmt.lib $(PDNTLDIR)\\oldnames.lib \ $(VSTK)\\lib\\kernel32.lib \ ..\\..\\bin\\pd.lib .c.obj: $(MSCC) $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c expr.dll: $(NTOBJ) $(MSLN) /dll /export:expr_setup /export:expr_tilde_setup \ /export:fexpr_tilde_setup /OUT:expr.dll $(NTOBJ) $(PDNTLIB) $(COPY) expr.dll ..\expr.dll $(COPY) expr.dll ..\expr~.dll $(COPY) expr.dll ..\fexpr~.dll # ----------------------- LINUX i386 ----------------------- LINUXOBJ = vexp.pd_linux_o vexp_fun.pd_linux_o vexp_if.pd_linux_o .SUFFIXES: .pd_linux_o LINUXCFLAGS = -DPD -O2 -funroll-loops -fomit-frame-pointer -fPIC \ -fno-strict-aliasing -Wall -W -Wshadow -Wstrict-prototypes \ -Wno-unused -Wno-unused-parameter -Wno-parentheses -Wno-switch LINUXINCLUDE = -I../../src .c.pd_linux_o: $(CC) -g $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.pd_linux_o -c $*.c expr.pd_linux: $(LINUXOBJ) $(CC) -shared -o expr.pd_linux $(LINUXOBJ) -lc -lm expr~.pd_linux: expr.pd_linux -ln -s expr.pd_linux expr~.pd_linux fexpr~.pd_linux: expr.pd_linux -ln -s expr.pd_linux fexpr~.pd_linux ../expr.pd_linux: expr.pd_linux -ln -s expr~/expr.pd_linux ../expr.pd_linux ../expr~.pd_linux: expr.pd_linux -ln -s expr~/expr.pd_linux ../expr~.pd_linux ../fexpr~.pd_linux: expr.pd_linux -ln -s expr~/expr.pd_linux ../fexpr~.pd_linux install_linux: install expr.pd_linux $(PDEXTERN) rm -f $(PDEXTERN)/expr~.pd_linux rm -f $(PDEXTERN)/fexpr~.pd_linux cd $(PDEXTERN); ln -s expr.pd_linux expr~.pd_linux cd $(PDEXTERN); ln -s expr.pd_linux fexpr~.pd_linux clean_linux: rm -f *.pd_linux_o *.o # ----------------------- MAC OSX ----------------------- MACOSXOBJ3 = vexp.d_ppc_o vexp_fun.d_ppc_o vexp_if.d_ppc_o MACOSXOBJ = vexp.d_fat_o vexp_fun.d_fat_o vexp_if.d_fat_o .SUFFIXES: .d_ppc_o .d_fat_o MACOSXCFLAGS = -DMACOSX -DPD -O2 -Wall -W -Wshadow -Wstrict-prototypes \ -Wno-unused -Wno-parentheses -Wno-switch MACOSXINCLUDE = -I../../src DARWINARCH= -arch i386 -arch x86_64 -arch ppc d_ppc: expr.d_ppc expr~.d_ppc fexpr~.d_ppc .c.d_ppc_o: $(CC) -g $(MACOSXCFLAGS) $(MACOSXINCLUDE) -o $*.d_ppc_o -c $*.c expr.d_ppc: $(MACOSXOBJ3) $(CC) -bundle -undefined suppress -flat_namespace \ -o expr.d_ppc $(MACOSXOBJ3) -lm rm -f ../expr.d_ppc -ln -s expr~/expr.d_ppc .. expr~.d_ppc: expr.d_ppc -ln -s expr.d_ppc expr~.d_ppc rm -f ../expr~.d_ppc -ln -s expr~/expr~.d_ppc .. fexpr~.d_ppc: expr.d_ppc -ln -s expr.d_ppc fexpr~.d_ppc rm -f ../fexpr~.d_ppc -ln -s expr~/fexpr~.d_ppc .. install_d_fat: install expr.d_fat $(PDEXTERN) rm -f $(PDEXTERN)/expr~.d_fat rm -f $(PDEXTERN)/fexpr~.d_fat cd $(PDEXTERN); \ -ln -s expr.d_fat expr~.d_fat; \ -ln -s expr.d_fat fexpr~.d_fat d_fat: expr.d_fat expr~.d_fat fexpr~.d_fat .c.d_fat_o: $(CC) -g $(MACOSXCFLAGS) $(MACOSXINCLUDE) $(DARWINARCH) \ -o $*.d_fat_o -c $*.c expr.d_fat: $(MACOSXOBJ) $(CC) $(DARWINARCH) -bundle -undefined suppress -flat_namespace \ -o expr.d_fat $(MACOSXOBJ) -lm rm -f ../expr.d_fat -ln -s expr~/expr.d_fat .. expr~.d_fat: expr.d_fat -ln -s expr.d_fat expr~.d_fat rm -f ../expr~.d_fat -ln -s expr~/expr~.d_fat .. fexpr~.d_fat: expr.d_fat -ln -s expr.d_fat fexpr~.d_fat rm -f ../fexpr~.d_fat -ln -s expr~/fexpr~.d_fat .. install_d_ppc: install expr.d_ppc $(PDEXTERN) rm -f $(PDEXTERN)/expr~.d_ppc rm -f $(PDEXTERN)/fexpr~.d_ppc cd $(PDEXTERN); \ -ln -s expr.d_ppc expr~.d_ppc; \ -ln -s expr.d_ppc fexpr~.d_ppc clean_d_ppc: rm -f *.d_ppc_o *.o pd-0.46-7/extra/expr~/vexp.h0000664000175000017500000002363512222367057014045 0ustar mspmsp/* * jMax * Copyright (C) 1994, 1995, 1998, 1999 by IRCAM-Centre Georges Pompidou, Paris, France. * * This is licensed under LGPL -- see the file, LICENSE.txt in this directory. * * Based on Max/ISPW by Miller Puckette. * * Authors: Maurizio De Cecco, Francois Dechelle, Enzo Maggi, Norbert Schnell. * */ /* "expr" was written by Shahrokh Yadegari c. 1989. -msp */ /* "expr~" and "fexpr~" conversion by Shahrokh Yadegari c. 1999,2000 */ #define MSP #ifdef PD #undef MSP #endif #ifdef PD #include "m_pd.h" #else /* MSP */ #include "ext.h" #include "z_dsp.h" #endif #include "fts_to_pd.h" /* This is put in fts_to_pd.h #ifdef MSP #define t_atom Atom #define t_symbol Symbol #define pd_new(x) newobject(x); #define t_outlet void #endif */ /* * Currently the maximum number of variables (inlets) that are supported * is 10. */ #define MAX_VARS 9 #define MINODES 10 /* was 200 */ /* terminal defines */ /* * operations * (x<<16|y) x defines the level of precedence, * the lower the number the lower the precedence * separators are defines as operators just for convenience */ #define OP_SEMI ((long)(1<<16|1)) /* ; */ #define OP_COMMA ((long)(2<<16|2)) /* , */ #define OP_LOR ((long)(3<<16|3)) /* || */ #define OP_LAND ((long)(4<<16|4)) /* && */ #define OP_OR ((long)(5<<16|5)) /* | */ #define OP_XOR ((long)(6<<16|6)) /* ^ */ #define OP_AND ((long)(7<<16|7)) /* & */ #define OP_NE ((long)(8<<16|8)) /* != */ #define OP_EQ ((long)(8<<16|9)) /* == */ #define OP_GE ((long)(9<<16|10)) /* >= */ #define OP_GT ((long)(9<<16|11)) /* > */ #define OP_LE ((long)(9<<16|12)) /* <= */ #define OP_LT ((long)(9<<16|13)) /* < */ #define OP_SR ((long)(10<<16|14)) /* >> */ #define OP_SL ((long)(10<<16|15)) /* << */ #define OP_SUB ((long)(11<<16|16)) /* - */ #define OP_ADD ((long)(11<<16|17)) /* + */ #define OP_MOD ((long)(12<<16|18)) /* % */ #define OP_DIV ((long)(12<<16|19)) /* / */ #define OP_MUL ((long)(12<<16|20)) /* * */ #define OP_UMINUS ((long)(13<<16|21)) /* - unary minus */ #define OP_NEG ((long)(13<<16|22)) /* ~ one complement */ #define OP_NOT ((long)(13<<16|23)) /* ! */ #define OP_RB ((long)(14<<16|24)) /* ] */ #define OP_LB ((long)(14<<16|25)) /* [ */ #define OP_RP ((long)(14<<16|26)) /* ) */ #define OP_LP ((long)(14<<16|27)) /* ( */ #define OP_STORE ((long)(15<<16|28)) /* = */ #define HI_PRE ((long)(100<<16)) /* infinite precedence */ #define PRE_MASK ((long)0xffff0000) /* precedence level mask */ struct ex_ex; #define name_ok(c) (((c)=='_') || ((c)>='a' && (c)<='z') || \ ((c)>='A' && (c)<='Z') || ((c) >= '0' && (c) <= '9')) #define unary_op(x) ((x) == OP_NOT || (x) == OP_NEG || (x) == OP_UMINUS) struct ex_ex { union { long v_int; t_float v_flt; t_float *v_vec; /* this is an for allocated vector */ long op; char *ptr; } ex_cont; /* content */ #define ex_int ex_cont.v_int #define ex_flt ex_cont.v_flt #define ex_vec ex_cont.v_vec #define ex_op ex_cont.op #define ex_ptr ex_cont.ptr long ex_type; /* type of the node */ }; #define exNULL ((struct ex_ex *)0) /* defines for ex_type */ #define ET_INT 1 /* an int */ #define ET_FLT 2 /* a float */ #define ET_OP 3 /* operator */ #define ET_STR 4 /* string */ #define ET_TBL 5 /* a table, the content is a pointer */ #define ET_FUNC 6 /* a function */ #define ET_SYM 7 /* symbol ("string") */ #define ET_VSYM 8 /* variable symbol ("$s?") */ /* we treat parenthesis and brackets */ /* special to keep a pointer to their */ /* match in the content */ #define ET_LP 9 /* left parenthesis */ #define ET_LB 10 /* left bracket */ #define ET_II 11 /* and integer inlet */ #define ET_FI 12 /* float inlet */ #define ET_SI 13 /* string inlet */ #define ET_VI 14 /* signal inlet */ #define ET_VEC 15 /* allocated signal vector */ /* special types for fexpr~ */ #define ET_YO 16 /* vector output for fexpr~ */ #define ET_YOM1 17 /* shorthand for $y?[-1] */ #define ET_XI 18 /* vector input for fexpr~ */ #define ET_XI0 20 /* shorthand for $x?[0] */ #define ET_VAR 21 /* variable */ /* defines for ex_flags */ #define EF_TYPE_MASK 0x07 /* first three bits define the type of expr */ #define EF_EXPR 0x01 /* expr - control in and out */ #define EF_EXPR_TILDE 0x02 /* expr~ signal and control in, signal out */ #define EF_FEXPR_TILDE 0x04 /* fexpr~ filter expression */ #define EF_STOP 0x08 /* is it stopped used for expr~ and fexpr~ */ #define EF_VERBOSE 0x10 /* verbose mode */ #define IS_EXPR(x) ((((x)->exp_flags&EF_TYPE_MASK)|EF_EXPR) == EF_EXPR) #define IS_EXPR_TILDE(x) \ ((((x)->exp_flags&EF_TYPE_MASK)|EF_EXPR_TILDE)==EF_EXPR_TILDE) #define IS_FEXPR_TILDE(x) \ ((((x)->exp_flags&EF_TYPE_MASK)|EF_FEXPR_TILDE)==EF_FEXPR_TILDE) #define SET_EXPR(x) (x)->exp_flags |= EF_EXPR; \ (x)->exp_flags &= ~EF_EXPR_TILDE; \ (x)->exp_flags &= ~EF_FEXPR_TILDE; #define SET_EXPR_TILDE(x) (x)->exp_flags &= ~EF_EXPR; \ (x)->exp_flags |= EF_EXPR_TILDE; \ (x)->exp_flags &= ~EF_FEXPR_TILDE; #define SET_FEXPR_TILDE(x) (x)->exp_flags &= ~EF_EXPR; \ (x)->exp_flags &= ~EF_EXPR_TILDE; \ (x)->exp_flags |= EF_FEXPR_TILDE; /* * defines for expr_error */ #define EE_DZ 0x01 /* divide by zero error */ #define EE_BI_OUTPUT 0x02 /* Bad output index */ #define EE_BI_INPUT 0x04 /* Bad input index */ #define EE_NOTABLE 0x08 /* NO TABLE */ #define EE_NOVAR 0x10 /* NO VARIABLE */ typedef struct expr { #ifdef PD t_object exp_ob; #else /* MSP */ t_pxobject exp_ob; #endif int exp_flags; /* are we expr~, fexpr~, or expr */ int exp_error; /* reported errors */ int exp_nexpr; /* number of expressions */ char *exp_string; /* the full expression string */ char *exp_str; /* current parsing position */ t_outlet *exp_outlet[MAX_VARS]; #ifdef PD struct _exprproxy *exp_proxy; #else /* MAX */ void *exp_proxy[MAX_VARS]; long exp_proxy_id; #endif struct ex_ex *exp_stack[MAX_VARS]; struct ex_ex exp_var[MAX_VARS]; struct ex_ex exp_res[MAX_VARS]; /* the evluation result */ t_float *exp_p_var[MAX_VARS]; t_float *exp_p_res[MAX_VARS]; /* the previous evaluation result */ t_float *exp_tmpres[MAX_VARS]; /* temporty result for fexpr~ */ int exp_vsize; /* the size of the signal vector */ int exp_nivec; /* # of vector inlets */ t_float exp_f; /* control value to be transformed to signal */ } t_expr; typedef struct ex_funcs { char *f_name; /* function name */ void (*f_func)(t_expr *, long, struct ex_ex *, struct ex_ex *); /* the real function performing the function (void, no return!!!) */ long f_argc; /* number of arguments */ } t_ex_func; /* function prototypes for pd-related functions called withing vexp.h */ extern int max_ex_tab(struct expr *expr, t_symbol *s, struct ex_ex *arg, struct ex_ex *optr); extern int max_ex_var(struct expr *expr, t_symbol *s, struct ex_ex *optr); extern int ex_getsym(char *p, t_symbol **s); extern const char *ex_symname(t_symbol *s); void ex_mkvector(t_float *fp, t_float x, int size); extern void ex_size(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); extern void ex_sum(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); extern void ex_Sum(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); extern void ex_avg(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); extern void ex_Avg(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); extern void ex_store(t_expr *expr, long int argc, struct ex_ex *argv, struct ex_ex *optr); int value_getonly(t_symbol *s, t_float *f); /* These pragmas are only used for MSVC, not MinGW or Cygwin */ #ifdef _MSC_VER #pragma warning (disable: 4305 4244) #endif #ifdef _WIN32 #define abort ABORT void ABORT(void); #endif pd-0.46-7/extra/expr-help.pd0000664000175000017500000004022612160204055013747 0ustar mspmsp#N canvas 165 94 1012 579 12; #X text 66 10 expression evaluation family - expr \, expr~ \, fexpr~ ; #X text 63 239 Syntyax:; #X text 64 311 $f#: float input variable; #X text 65 326 $s#: symbol input variable; #X text 553 90 Used for expr~ only:; #X text 553 105 $v#: signal (vector) input (vector by vector evaluation) ; #X text 550 164 Used for fexpr~ only:; #X text 550 220 $y[n]: the output value indexed by n where n has to satisfy 0 > n >= -vector size.; #X text 550 248 (the vector size can be changed by the "block~" object.) ; #X text 550 179 $x#[n]: the sample from inlet # indexed by n where n has to satisfy 0 => n >= -vector size \, ($x# is a shorthand for $x#[0] \, specifying the current sample); #X text 63 151 expr~ is used for expression evaluaion of signal data on the vector by vector basis; #X text 63 136 expr is used for expression evaluaion of control data ; #X text 67 39 For a more detailed documentaion refer to http://www.crca.ucsd.edu/~yadegari/expr.html ; #X text 64 254 The syntax is very close to how expressions are written in C. Variables are specified as follows where the '#' stands for the inlet number:; #X text 65 297 $i#: integer input variable; #X text 63 179 fexpr~ is used for expression evaluaion on sample level data \; i.e. \, filter design. Warning: fexpr~ is very cpu intensive. ; #X text 633 12 updated for Pd 0.35 test 26 and expr* 0.4; #X text 67 85 you can define multiple expressoins in the same object. semicolon is used to separates the expressions.; #X text 635 294 $y -> $y1[-1]; #X text 550 263 Shorthands: $x -> $x1[0]; #X text 635 279 $x1 -> $x1[0] $x2 -> $x2[0] .....; #X text 635 309 $y1 -> $y1[-1] $y2 -> $y2[-1] .....; #N canvas 0 0 828 385 Examples 0; #X obj 33 151 expr 1; #X floatatom 197 119 0 0 0 0 - - -; #X floatatom 33 181 0 0 0 0 - - -; #X msg 33 123 bang; #X obj 101 149 expr 2 + 3; #X msg 101 122 bang; #X floatatom 101 177 0 0 0 0 - - -; #X floatatom 196 177 0 0 0 0 - - -; #X obj 196 149 expr 2+$f1; #X floatatom 34 220 0 0 0 0 - - -; #X floatatom 34 277 0 0 0 0 - - -; #X obj 34 249 expr $f1 * $f2; #X floatatom 113 220 0 0 0 0 - - -; #N canvas 0 0 450 300 (subpatch) 0; #X array array1 10 float 0; #X coords 0 10 10 0 200 150 1; #X restore 584 180 graph; #X floatatom 35 315 0 0 0 0 - - -; #X floatatom 35 371 0 0 0 0 - - -; #X floatatom 194 219 0 0 0 0 - - -; #X floatatom 194 276 0 0 0 0 - - -; #X obj 194 248 expr $s2[$f1]; #X msg 267 220 symbol array1; #X obj 35 343 expr sin(2 * 3.14159 * $f1 / 360); #X msg 330 281 \; array1 1 4 2 8 5 6 1 4 2 8 5 6; #X floatatom 310 184 5 0 0 0 - - -; #X floatatom 395 186 5 0 0 0 - - -; #X floatatom 480 184 5 0 0 0 - - -; #X floatatom 310 105 5 0 0 0 - - -; #X obj 310 132 expr $f1 \; if ($f1 > 0 \, $f1 * 2 \, 0) \; if ($f1 <= 0 \, $f1 / 2 \, 0); #X text 34 56 Examples of expr object; #X text 304 88 an example of multiple expressions and the use of 'if' ; #X connect 0 0 2 0; #X connect 1 0 8 0; #X connect 3 0 0 0; #X connect 4 0 6 0; #X connect 5 0 4 0; #X connect 8 0 7 0; #X connect 9 0 11 0; #X connect 11 0 10 0; #X connect 12 0 11 1; #X connect 14 0 20 0; #X connect 16 0 18 0; #X connect 18 0 17 0; #X connect 19 0 18 1; #X connect 20 0 15 0; #X connect 25 0 26 0; #X connect 26 0 22 0; #X connect 26 1 23 0; #X connect 26 2 24 0; #X restore 307 398 pd Examples of expr; #N canvas 23 24 882 676 Examples 0; #X text -88 101 expr~ examples:; #X obj -24 355 print~; #X msg 13 334 bang; #X obj -24 276 sig~ 440; #X floatatom 49 293 0 0 0 0 - - -; #X floatatom -24 253 0 0 0 0 - - -; #X obj -24 316 expr~ $v1*$f2; #X obj 85 356 print~; #X msg 101 335 bang; #X floatatom 85 268 0 0 0 0 - - -; #X floatatom 158 270 0 0 0 0 - - -; #X floatatom 357 291 0 0 0 0 - - -; #X floatatom 244 267 0 0 0 0 - - -; #X obj 244 294 osc~; #X msg 369 47 \; pd dsp 0; #X msg 291 49 \; pd dsp 1; #X text 294 26 audio on; #X text 377 25 audio off; #X text -45 236 vector times scalar; #X text 87 236 vector; #X obj 243 354 dac~; #X text 241 245 frequency; #X text 373 273 amplitude; #X obj 85 315 expr~ $v1*$v2; #X floatatom 207 471 5 0 0 0 - - -; #X obj -40 520 tabsend~ a1; #N canvas 0 0 450 300 (subpatch) 0; #X array a1 64 float 0; #X coords 0 1 63 -1 200 140 1; #X restore -39 542 graph; #X obj -40 497 expr~ max(min($v1 \, $f2/10) \, -$f2/10); #X text -38 123 NOTES: the first inlet of expr~ cannot be a $f1 or $i1 \, this may change in later releases; #X text -87 420 A simple limiter example; #X obj 356 158 vsl 15 128 0 127 0 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 1; #X obj 243 315 expr~ $v1*$f2/128; #X text -82 28 make sure you turn on audio for the expr~ examples; #X obj -40 473 osc~ 2756.25; #X text 122 436 Move the value below between 0 and 10; #X text 126 451 to change the limiter threshold; #X obj 417 522 tabsend~ a2; #X obj 580 518 tabsend~ a3; #X obj 417 439 osc~ 2756.25; #N canvas 0 0 450 300 (subpatch) 0; #X array a2 64 float 1; #A 0 -0.797042 -0.728354 -0.551199 -0.29486 -5.74798e-08 0.28779 0.525076 0.677165 0.723186 0.658973 0.49724 0.265198 -5.86755e-06 -0.257244 -0.467812 -0.601285 -0.639938 -0.581051 -0.436842 -0.232108 -4.49318e-08 0.223344 0.404462 0.517604 0.548393 0.495593 0.370771 0.195993 -4.2964e-06 -0.186556 -0.335875 -0.427214 -0.449737 -0.4037 -0.299884 -0.157342 -3.00576e-08 0.14734 0.262927 0.331275 0.34523 0.306564 0.225106 0.116645 -2.503e-06 -0.106219 -0.186565 -0.231035 -0.236249 -0.205455 -0.147412 -0.0744387 -1.36289e-08 0.0637127 0.10778 0.127799 0.124205 0.101679 0.0677997 0.0312617 -5.8003e-07 -0.0203835 -0.0275998 -0.0229047; #X coords 0 1 63 -1 200 140 1; #X restore 347 554 graph; #N canvas 0 0 450 300 (subpatch) 0; #X array a3 64 float 0; #X coords 0 1 63 -1 200 140 1; #X restore 569 554 graph; #X obj 417 473 expr~ $v1 *$v2 \; if ($v2 > 0 \, 0 \, $v1*$v2); #X obj 580 439 osc~ 100; #X connect 2 0 1 0; #X connect 3 0 6 0; #X connect 4 0 6 1; #X connect 5 0 3 0; #X connect 6 0 1 0; #X connect 8 0 7 0; #X connect 9 0 23 0; #X connect 10 0 23 1; #X connect 11 0 31 1; #X connect 12 0 13 0; #X connect 13 0 31 0; #X connect 23 0 7 0; #X connect 24 0 27 1; #X connect 27 0 25 0; #X connect 30 0 11 0; #X connect 31 0 20 0; #X connect 31 0 20 1; #X connect 33 0 27 0; #X connect 38 0 41 0; #X connect 41 0 36 0; #X connect 41 1 37 0; #X connect 42 0 41 1; #X restore 307 433 pd Examples of expr~; #X text 40 399 For expr examples click here ->; #X text 41 433 For expr~ examples click here ->; #X text 40 471 For fexpr~ examples click here ->; #N canvas 0 0 1059 688 examples 0; #X msg 519 84 \; pd dsp 0; #X msg 428 84 \; pd dsp 1; #X text 426 64 audio on; #X text 518 65 audio off; #X floatatom 126 304 0 0 0 0 - - -; #X floatatom 259 323 0 0 0 0 - - -; #X msg 226 283 -10; #X text 53 103 fexpr~ examples:; #X obj 125 571 print~; #X msg 247 552 bang; #X floatatom 125 475 0 0 0 0 - - -; #X obj 126 347 fexpr~ ($x1[$f2]+$x1)/2; #X obj 125 532 fexpr~ $x1+$y[-1]; #X floatatom 635 366 0 0 0 0 - - -; #X floatatom 795 387 0 0 0 0 - - -; #X obj 630 456 dac~; #X obj 632 407 fexpr~ ($x1[$f2/1000]+$x1)/2; #X msg 864 317 0 10000; #X obj 795 368 line 0; #X msg 798 318 -10000; #X obj 120 389 dac~; #X text 96 227 Simple FIR filter; #X text 557 134 Simple FIR filter using fractional offset; #X msg 704 318 -10000 10000; #X obj 635 387 osc~ 2205; #X msg 644 343 1102.5; #X msg 862 342 0 10000; #X msg 796 343 -20000; #X msg 702 343 -20000 10000; #X msg 635 318 2205; #X msg 548 312 start; #X msg 550 334 stop; #X msg 57 284 start; #X msg 56 309 stop; #X msg 75 469 start; #X msg 74 494 stop; #X obj 491 335 loadbang; #X obj 18 495 loadbang; #X obj 1 309 loadbang; #X text 617 291 frequency; #X text 707 300 of the simple filter; #X msg 293 282 -20; #X obj 126 325 osc~ 2205; #X msg 156 281 1102.5; #X msg 110 281 2205; #X msg 260 282 0; #X text 123 445 simple accumulator defined as and an IIR filter; #X text 52 148 NOTE: fexpr~ could use lots of CPU power \, by default fexpr~ is on when it is loaded. In this page we are turning them off with loadbang \, so to hear them you have to turn them on explicitly. You can use the "start" and "stop" messages to start and stop fexpr~ and expr~; #X text 706 288 index defining the frequency; #X text 95 240 -10 offset will fully filter audio frequency of 2205 \, and -20 offset will filter audio at frequency of 1102.5; #X text 559 215 Thus \, the offset -10000 will filter audio at frequency of 2205 and the offset value -20000 will filter the audio at frequency of 1102.5.; #X text 558 161 When fractional offset is used \, fexpr~ determines indexed by linear interpolation. In the following example the offset value is divided by 1000 \, thus we can continuously change the offset without an audible click in the output.; #X text 288 318 If you change this value you; #X text 290 330 hear a click; #X text 51 87 make sure you turn on audio for the fexpr~ examples; #X text 55 -323 Used for fexpr~ only:; #X text 55 -267 $y[n]: the output value indexed by n where n has to satisfy 0 > n >= -vector size.; #X text 55 -239 (the vector size can be changed by the "block~" object.) ; #X text 55 -308 $x#[n]: the sample from inlet # indexed by n where n has to satisfy 0 => n >= -vector size \, ($x# is a shorthand for $x#[0] \, specifying the current sample); #X text 140 -193 $y -> $y1[-1]; #X text 55 -224 Shorthands: $x -> $x1[0]; #X text 140 -208 $x1 -> $x1[0] $x2 -> $x2[0] .....; #X text 140 -178 $y1 -> $y1[-1] $y2 -> $y2[-1] .....; #X text 64 -125 fexpr~ responds to the following methods; #X text 66 -106 clear - clears all the previous input and output buffers ; #X text 65 -92 clear x# - clears the previous values of the #th input ; #X text 66 -79 clear y# - clears the previous values of the #th output ; #X text 66 -33 set x# val-1 val-2 ... - sets the as many supplied values of the #th input; #X text 513 -22 e.g. \, set x2 3.4 0.4 sets x2[-1]=3.4 and x2[-2]=0.4 ; #X text 66 -2 set y# val-1 val-2 ... - sets the as many supplied values of the #th input; #X text 514 4 e.g. \, set y3 1.1 3.3 4.5 sets y3[-1]=1.1 y3[-2]=3.3 and y3[-3]=4.5; #X text 64 -54 set val val ... - sets the first past values of each output; #X text 513 -59 e.g. \, set 0.1 2.2 0.4 sets y1[-1]=0.1 y2[-1]=2.2 \, and y3[-1]=0.4; #X msg 244 475 set 4000; #X obj 125 504 sig~ 0.001; #X msg 245 498 clear; #X text 22 442 comment; #X text 14 431 1 first click the start button; #X text 307 494 2 click the set or the clear button; #X text 304 547 3 then click bang to see how set and clear work; #X connect 4 0 42 0; #X connect 5 0 11 1; #X connect 6 0 5 0; #X connect 9 0 8 0; #X connect 10 0 74 0; #X connect 11 0 20 0; #X connect 11 0 20 1; #X connect 12 0 8 0; #X connect 13 0 24 0; #X connect 14 0 16 1; #X connect 16 0 15 0; #X connect 16 0 15 1; #X connect 17 0 18 0; #X connect 18 0 14 0; #X connect 19 0 18 0; #X connect 23 0 18 0; #X connect 24 0 16 0; #X connect 25 0 13 0; #X connect 26 0 18 0; #X connect 27 0 18 0; #X connect 28 0 18 0; #X connect 29 0 13 0; #X connect 30 0 16 0; #X connect 31 0 16 0; #X connect 32 0 11 0; #X connect 33 0 11 0; #X connect 34 0 12 0; #X connect 35 0 12 0; #X connect 36 0 31 0; #X connect 37 0 35 0; #X connect 38 0 33 0; #X connect 41 0 5 0; #X connect 42 0 11 0; #X connect 43 0 4 0; #X connect 44 0 4 0; #X connect 45 0 5 0; #X connect 73 0 12 0; #X connect 74 0 12 0; #X connect 75 0 12 0; #X restore 306 472 pd examples of fexpr~; #X text 42 504 For using fexpr~ for solving; #X text 43 520 differential equations click here ->; #N canvas 112 22 944 449 lorenz 0; #X obj 176 67 v pr; #X obj 307 68 v r; #X obj 233 69 v b; #X floatatom 176 38 5 0 0 0 - - -; #X floatatom 307 40 5 0 0 0 - - -; #X msg 177 13 10; #X obj 231 10 expr 8./3; #X msg 128 136 set 1.2 2.3 4.4; #X floatatom 233 39 7 0 0 0 - - -; #X msg 75 46 stop; #X msg 75 67 start; #X floatatom 399 40 5 0 0 0 - - -; #X obj 399 69 v dt; #X msg 310 12 18; #X msg 395 13 0.01; #X obj 68 296 dac~; #X obj 128 -41 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 -1; #X text 201 -41 <- turn audio on and bang here; #X text 463 42 <- experiment with these numbers; #X text 472 72 if you hear a buzz \, you have probably gone unstable bang on the top again; #X obj 489 15 line; #X obj 128 241 /~ 20; #X obj 234 238 /~ 20; #X obj 340 237 /~ 20; #X msg 484 -11 0.01 \, 0.04 5000; #X obj 128 185 fexpr~ $y1+(pr*$y2-pr*$y1)*dt \; $y2 +(-$y1*$y3 + r*$y1-$y2)*dt \; $y3+($y1*$y2 - b*$y3)*dt; #X obj 14 65 loadbang; #X text 113 -100 This is an example of how fexpr~ could be used for solving differential equations \, in this case the lorenz equations which generate chotic signals; #X text 361 182 Note the following shorthands:; #X text 360 198 $y1 -> $y1[-1] \, $y2 -> $y2[-1] \, .....; #X text 248 136 the 'set' commands sets the initial previous values ; #X obj 128 298 tabsend~ lorenz1a; #X obj 234 278 tabsend~ lorenz2a; #X obj 339 259 tabsend~ lorenz3a; #N canvas 0 0 450 300 (subpatch) 0; #X array lorenz1a 64 float 0; #X coords 0 1 63 -1 200 140 1; #X restore 73 437 graph; #N canvas 0 0 450 300 (subpatch) 0; #X array lorenz2a 64 float 0; #X coords 0 1 63 -1 200 140 1; #X restore 331 435 graph; #N canvas 0 0 450 300 (subpatch) 0; #X array lorenz3a 64 float 0; #X coords 0 1 63 -1 200 140 1; #X restore 592 436 graph; #X text 301 315 You can see the graphs if you scroll down; #X text 301 328 but the redrawings may cause clicks in the audio; #X connect 3 0 0 0; #X connect 4 0 1 0; #X connect 5 0 3 0; #X connect 6 0 8 0; #X connect 7 0 25 0; #X connect 8 0 2 0; #X connect 9 0 25 0; #X connect 10 0 25 0; #X connect 11 0 12 0; #X connect 13 0 4 0; #X connect 14 0 11 0; #X connect 16 0 5 0; #X connect 16 0 6 0; #X connect 16 0 13 0; #X connect 16 0 14 0; #X connect 16 0 7 0; #X connect 16 0 10 0; #X connect 20 0 11 0; #X connect 21 0 31 0; #X connect 21 0 15 0; #X connect 21 0 15 1; #X connect 22 0 32 0; #X connect 23 0 33 0; #X connect 24 0 20 0; #X connect 25 0 21 0; #X connect 25 1 22 0; #X connect 25 2 23 0; #X connect 26 0 9 0; #X restore 308 518 pd lorenz equations for audition; #N canvas 97 36 978 656 lorenz 0; #X obj 176 67 v pr; #X obj 307 68 v r; #X obj 233 69 v b; #X floatatom 176 38 5 0 0 0 - - -; #X floatatom 307 40 5 0 0 0 - - -; #X msg 177 13 10; #X obj 231 10 expr 8./3; #N canvas 0 0 450 300 (subpatch) 0; #X array lorenz1 2048 float 0; #X coords 0 -1 2047 1 200 140 1; #X restore 82 357 graph; #N canvas 0 0 450 300 (subpatch) 0; #X array lorenz2 2048 float 0; #X coords 0 -1 2047 1 200 140 1; #X restore 327 353 graph; #N canvas 0 0 450 300 (subpatch) 0; #X array lorenz3 2048 float 0; #X coords 0 -1 2047 1 200 140 1; #X restore 570 347 graph; #X msg 128 136 set 1.2 2.3 4.4; #X floatatom 233 39 7 0 0 0 - - -; #X msg 75 46 stop; #X msg 75 67 start; #X floatatom 399 40 5 0 0 0 - - -; #X obj 399 69 v dt; #X msg 310 12 18; #X msg 395 13 0.01; #X obj 128 -41 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 -1; #X text 201 -41 <- turn audio on and bang here; #X text 463 42 <- experiment with these numbers; #X text 472 72 if you hear a buzz \, you have probably gone unstable bang on the top again; #X obj 489 15 line; #X obj 128 241 /~ 20; #X obj 234 238 /~ 20; #X obj 340 237 /~ 20; #X msg 484 -11 0.01 \, 0.04 5000; #X obj 14 65 loadbang; #X text 113 -100 This is an example of how fexpr~ could be used for solving differential equations \, in this case the lorenz equations which generate chotic signals; #X text 361 182 Note the following shorthands:; #X text 360 198 $y1 -> $y1[-1] \, $y2 -> $y2[-1] \, .....; #X text 248 136 the 'set' commands sets the initial previous values ; #X obj 128 298 tabsend~ lorenz1; #X obj 234 278 tabsend~ lorenz2; #X obj 339 259 tabsend~ lorenz3; #X obj 627 280 block~ 2048; #X text 669 133 Lorenz Equations; #X obj 128 185 fexpr~ $y1+pr * ($y2-$y1)*dt \; $y2 +(-$y1*$y3 + r*$y1-$y2)*dt \; $y3+($y1*$y2 - b*$y3)*dt; #X text 672 197 dZ/dt = -bZ; #X text 669 167 dX/dt = pr * (X - Y); #X text 668 147 written with 3 state variable X \, Y \, and Z; #X text 670 182 dY/dt = -XZ + rX - y; #X connect 3 0 0 0; #X connect 4 0 1 0; #X connect 5 0 3 0; #X connect 6 0 11 0; #X connect 10 0 37 0; #X connect 11 0 2 0; #X connect 12 0 37 0; #X connect 13 0 37 0; #X connect 14 0 15 0; #X connect 16 0 4 0; #X connect 17 0 14 0; #X connect 18 0 5 0; #X connect 18 0 6 0; #X connect 18 0 16 0; #X connect 18 0 17 0; #X connect 18 0 10 0; #X connect 18 0 13 0; #X connect 22 0 14 0; #X connect 23 0 32 0; #X connect 24 0 33 0; #X connect 25 0 34 0; #X connect 26 0 22 0; #X connect 27 0 12 0; #X connect 37 0 23 0; #X connect 37 1 24 0; #X connect 37 2 25 0; #X restore 308 541 pd lorenz equations for visualization; #X text 68 24 by Shahrokh Yadegari; pd-0.46-7/doc/0000775000175000017500000000000012160204055011134 5ustar mspmsppd-0.46-7/doc/7.stuff/0000775000175000017500000000000012160204055012430 5ustar mspmsppd-0.46-7/doc/7.stuff/soundfile-tools/0000775000175000017500000000000012374250720015565 5ustar mspmsppd-0.46-7/doc/7.stuff/soundfile-tools/3.phase.vocoder.pd0000664000175000017500000003257412160204055021017 0ustar mspmsp#N canvas 223 113 913 495 12; #X floatatom 457 258 0 0 0; #X floatatom 793 114 0 0 0; #X floatatom 654 114 0 0 0; #N canvas 249 280 600 398 loc&precess 0; #X floatatom 218 312 0 0 0; #X msg 369 239 set \$1; #X obj 367 282 outlet; #X obj 114 364 outlet; #X obj 233 96 r location; #X msg 113 321 set \$1; #X obj 368 203 r speed; #X obj 75 95 r see-location; #X obj 92 139 t b f; #X obj 113 292 f; #X obj 73 173 int; #X obj 73 206 sel 0; #X msg 209 139 1; #X msg 275 138 0; #X obj 150 245 del 300; #X connect 1 0 2 0; #X connect 4 0 8 0; #X connect 5 0 3 0; #X connect 6 0 1 0; #X connect 7 0 8 0; #X connect 8 0 10 0; #X connect 8 1 9 1; #X connect 9 0 5 0; #X connect 10 0 11 0; #X connect 11 0 12 0; #X connect 11 0 14 0; #X connect 12 0 10 1; #X connect 13 0 10 1; #X connect 14 0 13 0; #X connect 14 0 9 0; #X restore 654 91 pd loc&precess; #N canvas 0 0 600 400 setlocprecess 0; #X obj 235 113 inlet; #X obj 100 109 inlet; #X obj 231 144 s speed; #X obj 101 144 s location; #X connect 0 0 2 0; #X connect 1 0 3 0; #X restore 654 138 pd setlocprecess; #X obj 457 279 s transpo; #X obj 457 216 r transpo; #X msg 457 237 set \$1; #X msg 673 387 \; location 0 \; speed 200; #X text 200 8 PHASE VOCODER; #X text 609 18 set location; #X text 609 36 and stop; #X text 609 54 precession; #X text 785 53 precession; #X text 785 71 speed in; #X text 785 89 hundredths; #X text 457 179 transposition; #X text 457 197 in cents; #X text 666 360 contraction; #X text 784 360 expansion; #X msg 776 387 \; location 0 \; speed 10; #X text 30 349 100 maximum; #X text 30 331 output meter; #X floatatom 610 218 0 5 60; #X text 645 218 <--set me to change length; #N canvas 0 0 265 196 length 0; #X obj 46 23 inlet; #X obj 48 101 * 44100; #X msg 84 125 \; array2 resize \$1; #X obj 46 48 min 60; #X obj 60 75 s output-length; #X obj 46 159 s maxoutsize; #X connect 0 0 3 0; #X connect 1 0 2 0; #X connect 1 0 5 0; #X connect 3 0 1 0; #X connect 3 0 4 0; #X restore 610 239 pd length; #N canvas 219 38 198 151 /SUBPATCH/ 0; #X obj 77 118 outlet; #X obj 77 72 loadbang; #X msg 77 95 10; #X connect 1 0 2 0; #X connect 2 0 0 0; #X restore 610 197 pd; #X text 610 259 length in seconds of the output; #X text 610 277 buffer... maximum 60; #N canvas 42 0 1083 546 guts 0; #X msg 24 129 bang; #X obj 24 405 openpanel; #X obj 139 30 inlet; #X obj 450 385 dac~; #X obj 450 329 *~; #X obj 465 306 line~; #X obj 465 283 r master-amp; #X msg 728 129 bang; #X obj 728 150 savepanel; #X obj 219 164 spigot; #X msg 206 102 0; #X msg 238 102 1; #X obj 503 444 outlet; #X obj 292 251 tabwrite~ array2; #X obj 449 246 +~; #X obj 450 356 hip~ 7; #X msg 446 97 bang; #X obj 446 118 tabplay~ array2; #X msg 728 175 write \$1 array2; #X obj 728 200 soundfiler; #X obj 505 386 env~ 16384; #X obj 591 101 route normalized; #X msg 591 284 write -normalize \$1 array2; #X msg 591 242 bang; #X obj 591 263 savepanel; #X obj 591 308 soundfiler; #X obj 24 450 soundfiler; #X msg 24 428 read -resize -maxsize 1e+06 \$1 array1; #X floatatom 24 473 0 0 0; #X obj 680 345 loadbang; #X msg 680 368 \; window-size 2048 \; transpo 0; #N canvas 9 7 835 599 fft-analysis 0; #X obj 267 304 *~; #X obj 235 304 *~; #X obj 235 326 -~; #X obj 333 305 *~; #X obj 302 305 *~; #X obj 302 328 +~; #X obj 348 131 *~; #X obj 317 131 *~; #X obj 288 131 *~; #X obj 256 131 *~; #X obj 256 153 +~; #X obj 225 183 *~; #X obj 88 570 *~; #X obj 375 256 rfft~; #X obj 396 55 rfft~; #X obj 488 652 *~; #X obj 702 295 r window-size; #X obj 770 211 r sample-rate; #X obj 624 239 f; #X obj 617 53 r sample-rate; #X obj 592 30 r window-size; #X obj 615 100 t b f; #X obj 592 124 /; #X obj 519 652 *~; #X obj 89 549 *~; #X obj 106 525 rifft~; #X obj 89 596 outlet~; #X obj 639 457 print~; #X msg 639 428 bang; #X text 155 526 inverse real FFT; #X obj 603 215 bang~; #X obj 528 434 line~; #X obj 592 146 * 1000; #X text 645 139 window size (msec); #X obj 617 78 * 4; #X obj 647 162 r speed; #X obj 726 164 r location; #X obj 655 240 +; #X obj 648 204 *; #X msg 726 193 0; #X obj 624 349 +; #X obj 615 305 t f f; #X msg 528 406 \$1 \, \$2 \$3; #X obj 528 378 pack 0 0 0; #X obj 770 234 / 1000; #X obj 624 276 *; #X text 654 276 reading location (samples); #X obj 652 390 / 4; #X text 684 395 hop size (samples); #X obj 578 476 sig~; #X obj 546 474 +~; #X text 653 85 (overlap times parent SR); #X text 653 71 local sample rate; #X obj 23 52 tabreceive~ phase-real; #X obj 194 183 *~; #X obj 194 205 +~; #X obj 194 231 rsqrt~; #X obj 317 153 -~; #X obj 237 261 *~; #X obj 298 261 *~; #X obj 203 52 tabreceive~ phase-imag; #X obj 108 390 sig~; #X obj 90 319 t b f; #X msg 90 340 1; #X obj 104 364 /; #X obj 232 447 tabsend~ phase-real; #X obj 262 418 tabsend~ phase-imag; #X obj 107 136 sig~ 1.5e-20; #X obj 647 184 * 0.01; #X obj 708 217 s speed; #X obj 479 256 s see-location; #X floatatom 688 368 0 0 0; #X obj 686 347 *; #X obj 848 245 r transpo; #X obj 848 264 * 0.01; #X obj 849 285 + 69; #X obj 851 307 mtof; #X obj 851 327 / 440; #X obj 705 324 t b f; #X obj 90 297 r window-size; #X floatatom 855 361 0 0 0; #X obj 564 556 tabreceive~ hanning; #X obj 549 500 tabread4~ array1; #X obj 514 524 tabread4~ array1; #X obj 612 608 r running; #X obj 612 632 switch~ 2048 4; #X connect 0 0 2 1; #X connect 1 0 2 0; #X connect 2 0 65 0; #X connect 2 0 25 0; #X connect 3 0 5 1; #X connect 4 0 5 0; #X connect 5 0 66 0; #X connect 5 0 25 1; #X connect 6 0 57 1; #X connect 7 0 57 0; #X connect 8 0 10 1; #X connect 9 0 10 0; #X connect 10 0 58 1; #X connect 10 0 54 0; #X connect 10 0 54 1; #X connect 11 0 55 1; #X connect 12 0 26 0; #X connect 13 0 1 1; #X connect 13 0 3 1; #X connect 13 1 0 1; #X connect 13 1 4 1; #X connect 14 0 9 1; #X connect 14 0 7 1; #X connect 14 1 6 1; #X connect 14 1 8 1; #X connect 15 0 14 0; #X connect 16 0 72 0; #X connect 17 0 44 0; #X connect 18 0 37 0; #X connect 18 0 45 0; #X connect 18 0 70 0; #X connect 19 0 34 0; #X connect 20 0 22 0; #X connect 21 0 22 0; #X connect 21 1 22 1; #X connect 22 0 32 0; #X connect 23 0 13 0; #X connect 24 0 12 0; #X connect 25 0 24 1; #X connect 28 0 27 0; #X connect 30 0 18 0; #X connect 31 0 27 0; #X connect 31 0 50 0; #X connect 31 0 83 0; #X connect 32 0 43 2; #X connect 32 0 38 1; #X connect 34 0 21 0; #X connect 35 0 68 0; #X connect 36 0 39 0; #X connect 36 0 18 1; #X connect 37 0 18 1; #X connect 38 0 37 1; #X connect 39 0 69 0; #X connect 40 0 43 1; #X connect 41 0 43 0; #X connect 41 1 40 0; #X connect 42 0 31 0; #X connect 43 0 42 0; #X connect 44 0 45 1; #X connect 45 0 41 0; #X connect 47 0 49 0; #X connect 49 0 50 1; #X connect 50 0 82 0; #X connect 53 0 9 0; #X connect 53 0 6 0; #X connect 54 0 55 0; #X connect 55 0 56 0; #X connect 56 0 58 0; #X connect 56 0 59 0; #X connect 57 0 59 1; #X connect 57 0 11 0; #X connect 57 0 11 1; #X connect 58 0 1 0; #X connect 58 0 4 0; #X connect 59 0 0 0; #X connect 59 0 3 0; #X connect 60 0 7 0; #X connect 60 0 8 0; #X connect 61 0 24 0; #X connect 62 0 63 0; #X connect 62 1 64 1; #X connect 63 0 64 0; #X connect 64 0 61 0; #X connect 67 0 10 0; #X connect 68 0 38 0; #X connect 71 0 47 0; #X connect 71 0 40 1; #X connect 72 0 71 0; #X connect 73 0 74 0; #X connect 74 0 75 0; #X connect 75 0 76 0; #X connect 76 0 77 0; #X connect 77 0 78 0; #X connect 77 0 80 0; #X connect 78 0 72 0; #X connect 78 1 72 1; #X connect 79 0 62 0; #X connect 81 0 23 1; #X connect 81 0 15 1; #X connect 81 0 12 1; #X connect 82 0 23 0; #X connect 83 0 15 0; #X connect 84 0 85 0; #X restore 291 222 pd fft-analysis; #X msg 203 187 bang; #X obj 38 225 samplerate~; #X obj 38 247 s sample-rate; #N canvas 260 23 647 768 phase-tables 0; #N canvas 0 0 450 300 graph2 0; #X array phase-imag 4096 float 0; #X coords 0 1 4096 -1 400 300 1; #X restore 234 396 graph; #N canvas 0 0 450 300 graph3 0; #X array phase-real 4096 float 0; #X coords 0 1 4096 -1 400 300 1; #X restore 232 23 graph; #X msg 229 769 \; phase-real resize 4096 \; phase-imag resize 4096 ; #X restore 681 423 pd phase-tables; #N canvas 138 111 767 761 hanning-window 0; #X obj 125 281 phasor~; #X obj 125 319 cos~; #X obj 31 448 tabwrite~ hanning; #X obj 41 345 -~; #X obj 38 298 sig~ 1; #X msg 51 246 0; #X text 193 19 CALCULATE HANNING; #X text 193 37 WINDOW TABLE; #N canvas 0 0 450 300 graph1 0; #X array hanning 4096 float 0; #X coords 0 1 4096 -1 400 300 1; #X restore 375 384 graph; #X obj 126 233 sig~; #X text 239 202 sample rate / window size; #X msg 31 196 bang; #X obj 90 367 sig~ 0.5; #X obj 67 409 *~; #X obj 128 109 samplerate~; #X obj 34 31 r window-size; #X obj 34 72 t b f; #X msg 375 746 \; hanning resize 4096; #X obj 126 180 /; #X connect 0 0 1 0; #X connect 1 0 3 1; #X connect 3 0 13 0; #X connect 4 0 3 0; #X connect 5 0 0 1; #X connect 9 0 0 0; #X connect 11 0 2 0; #X connect 11 0 5 0; #X connect 12 0 13 1; #X connect 13 0 2 0; #X connect 14 0 18 0; #X connect 15 0 16 0; #X connect 16 0 14 0; #X connect 16 0 11 0; #X connect 16 1 18 1; #X connect 18 0 9 0; #X restore 681 447 pd hanning-window; #X obj 100 335 delay; #X obj 160 332 + 100; #X obj 139 51 route read run start hear save stop; #X obj 895 245 timer; #X obj 895 269 * 44.1; #X obj 232 314 r maxoutsize; #X obj 217 338 f; #X msg 217 360 \; array2 resize \$1; #X msg 100 358 \; action stop; #X obj 186 30 r action; #X obj 910 172 r running; #X obj 894 195 f; #X obj 894 219 sel 1; #X obj 895 344 moses; #X obj 946 345 r maxoutsize; #X msg 895 366 \; array2 resize \$1; #X msg 918 293 \; running 0; #X msg 293 277 \; running 1; #X obj 160 310 / 44.1; #X msg 751 10 bang; #X obj 277 92 r location; #X obj 277 115 r speed; #X obj 278 137 r transpo; #X msg 43 283 \; pd dsp 1; #X obj 503 414 int; #X connect 0 0 1 0; #X connect 1 0 27 0; #X connect 2 0 39 0; #X connect 4 0 15 0; #X connect 5 0 4 1; #X connect 6 0 5 0; #X connect 7 0 8 0; #X connect 8 0 18 0; #X connect 9 0 10 0; #X connect 9 0 32 0; #X connect 10 0 9 1; #X connect 11 0 9 1; #X connect 14 0 4 0; #X connect 15 0 3 0; #X connect 15 0 3 1; #X connect 15 0 20 0; #X connect 16 0 17 0; #X connect 17 0 14 1; #X connect 18 0 19 0; #X connect 20 0 61 0; #X connect 21 0 23 0; #X connect 21 1 7 0; #X connect 22 0 25 0; #X connect 23 0 24 0; #X connect 24 0 22 0; #X connect 26 0 28 0; #X connect 27 0 26 0; #X connect 29 0 30 0; #X connect 31 0 13 0; #X connect 31 0 14 0; #X connect 32 0 33 0; #X connect 32 0 37 0; #X connect 32 0 40 0; #X connect 32 0 43 0; #X connect 32 0 13 0; #X connect 32 0 54 0; #X connect 32 0 60 0; #X connect 33 0 34 0; #X connect 37 0 45 0; #X connect 38 0 37 1; #X connect 39 0 0 0; #X connect 39 1 10 0; #X connect 39 1 32 0; #X connect 39 2 11 0; #X connect 39 3 16 0; #X connect 39 4 21 0; #X connect 39 5 56 0; #X connect 40 0 41 0; #X connect 41 0 53 0; #X connect 41 0 50 0; #X connect 42 0 43 1; #X connect 42 0 55 0; #X connect 43 0 44 0; #X connect 46 0 39 0; #X connect 47 0 48 1; #X connect 48 0 49 0; #X connect 49 0 40 1; #X connect 50 0 52 0; #X connect 51 0 50 1; #X connect 55 0 38 0; #X connect 56 0 48 0; #X connect 57 0 9 0; #X connect 58 0 9 0; #X connect 59 0 9 0; #X connect 61 0 12 0; #X restore 30 290 pd guts; #X msg 30 164 run the transformation; #X msg 30 227 hear the output buffer again; #X text 30 124 click below to:; #X msg 30 248 save the output buffer; #X floatatom 30 311 0 0 0; #X msg 30 143 read an input file; #X msg 30 269 save normalized to max amplitude; #N canvas 213 187 495 352 input-sample 0; #N canvas 0 0 450 300 graph1 0; #X array array1 63024 float 0; #X coords 0 1 63023 -1 400 300 1; #X restore 55 22 graph; #X text 146 379 INPUT SAMPLE; #X restore 41 401 pd input-sample; #N canvas 192 180 507 343 output-sample 0; #N canvas 0 0 450 300 graph2 0; #X array array2 2.646e+06 float 0; #X coords 0 1 2.646e+06 -1 400 300 1; #X restore 58 13 graph; #X text 155 375 OUTPUT SAMPLE; #X restore 41 426 pd output-sample; #X floatatom 385 382 0 0 120; #N canvas 194 37 397 591 output 0; #X obj 64 196 t b; #X obj 64 147 f; #X obj 64 99 inlet; #X text 68 78 mute; #X obj 64 220 f; #X msg 130 235 0; #X msg 64 123 bang; #X obj 64 172 moses 1; #X obj 130 211 t b f; #X obj 93 427 outlet; #X msg 93 403 set \$1; #X obj 180 158 moses 1; #X obj 217 429 dbtorms; #X obj 217 454 pack 0 100; #X obj 180 133 r master-lvl; #X obj 93 369 r master-lvl; #X obj 80 276 s master-lvl; #X obj 217 478 s master-amp; #X obj 201 235 loadbang; #X msg 201 260 \; master-lvl 90; #X connect 0 0 4 0; #X connect 1 0 7 0; #X connect 2 0 6 0; #X connect 4 0 16 0; #X connect 5 0 16 0; #X connect 6 0 1 0; #X connect 7 0 0 0; #X connect 7 1 8 0; #X connect 8 0 5 0; #X connect 10 0 9 0; #X connect 11 1 4 1; #X connect 12 0 13 0; #X connect 13 0 17 0; #X connect 14 0 1 1; #X connect 14 0 11 0; #X connect 15 0 10 0; #X connect 15 0 12 0; #X connect 18 0 19 0; #X restore 385 361 pd output; #X msg 385 340 mute; #X obj 385 403 s master-lvl; #X text 427 339 <-- mute button; #X text 422 381 <--set me; #X text 385 423 LINE OUT LEVEL in dB (100 norm); #X text 14 25 This is a Fourier-based analysis/resynthesis tool.; #X text 22 45 You can move forward or backward in the sample \, or "freeze" at any point using the "precession" and "location" controls. Transposition is in hundredths of a half-tone.; #X msg 30 185 start transformation when I change controls; #X msg 30 206 stop the transformation; #X text 731 329 examples:; #X msg 614 94 -40; #X connect 0 0 5 0; #X connect 1 0 4 1; #X connect 2 0 4 0; #X connect 3 0 2 0; #X connect 3 1 1 0; #X connect 6 0 7 0; #X connect 7 0 0 0; #X connect 23 0 25 0; #X connect 26 0 23 0; #X connect 29 0 34 0; #X connect 30 0 29 0; #X connect 31 0 29 0; #X connect 33 0 29 0; #X connect 35 0 29 0; #X connect 36 0 29 0; #X connect 39 0 42 0; #X connect 40 0 39 0; #X connect 41 0 40 0; #X connect 48 0 29 0; #X connect 49 0 29 0; #X connect 51 0 2 0; pd-0.46-7/doc/7.stuff/soundfile-tools/2.bandpass.pd0000664000175000017500000001233612160204055020043 0ustar mspmsp#N canvas 73 28 846 432 12; #N canvas 213 187 495 352 input-sample 0; #N canvas 0 0 450 300 graph1 0; #X array array1 155948 float 0; #X coords 0 1 155948 -1 400 300 1; #X restore 55 22 graph; #X text 149 386 INPUT SAMPLE; #X restore 238 282 pd input-sample; #N canvas 192 180 507 343 output-sample 0; #N canvas 0 0 450 300 graph2 0; #X array array2 160358 float 0; #X coords 0 1 160358 -1 400 300 1; #X restore 59 13 graph; #X text 158 381 OUTPUT SAMPLE; #X restore 237 305 pd output-sample; #N canvas 116 150 735 425 guts 0; #X msg 25 131 bang; #X obj 25 354 openpanel; #X obj 142 31 inlet; #X obj 458 378 dac~; #X obj 458 335 *~; #X obj 473 312 line~; #X obj 473 290 r master-amp; #X msg 726 87 bang; #X obj 726 109 savepanel; #X obj 275 165 spigot; #X msg 260 131 0; #X msg 291 131 1; #X obj 513 408 outlet; #X obj 324 131 r frequency; #X obj 263 320 tabwrite~ array2; #X msg 263 194 bang; #X obj 438 283 +~; #X msg 143 131 \; pd dsp 1; #X obj 458 356 hip~ 7; #X obj 275 223 tabplay~ array1; #X msg 453 127 bang; #X obj 453 149 tabplay~ array2; #X msg 726 130 write \$1 array2; #X obj 726 151 soundfiler; #X obj 142 52 route read run start hear save; #N canvas 0 0 368 259 audio-transformation 0; #X obj 111 70 r frequency; #X obj 96 21 inlet~; #X obj 96 178 outlet~; #X obj 179 123 r q; #X obj 111 94 pack 0 100; #X obj 110 119 line~; #X obj 96 153 vcf~; #X connect 0 0 4 0; #X connect 1 0 6 0; #X connect 3 0 6 2; #X connect 4 0 5 0; #X connect 5 0 6 1; #X connect 6 0 2 0; #X restore 275 244 pd audio-transformation; #X obj 513 387 env~ 16384; #X obj 585 88 route normalized; #X msg 585 184 write -normalize \$1 array2; #X msg 585 142 bang; #X obj 585 163 savepanel; #X obj 585 209 soundfiler; #X obj 25 406 soundfiler; #X msg 25 383 read -resize -maxsize 1e+06 \$1 array1; #X msg 25 452 \; array2 resize \$1; #X obj 25 430 + 4410; #X floatatom 94 428 0 0 0; #X obj 413 132 r q; #X connect 0 0 1 0; #X connect 1 0 33 0; #X connect 2 0 24 0; #X connect 4 0 18 0; #X connect 5 0 4 1; #X connect 6 0 5 0; #X connect 7 0 8 0; #X connect 8 0 22 0; #X connect 9 0 10 0; #X connect 9 0 15 0; #X connect 10 0 9 1; #X connect 11 0 9 1; #X connect 13 0 9 0; #X connect 15 0 14 0; #X connect 15 0 19 0; #X connect 16 0 4 0; #X connect 18 0 3 0; #X connect 18 0 3 1; #X connect 18 0 26 0; #X connect 19 0 25 0; #X connect 20 0 21 0; #X connect 21 0 16 1; #X connect 22 0 23 0; #X connect 24 0 0 0; #X connect 24 1 15 0; #X connect 24 1 10 0; #X connect 24 1 17 0; #X connect 24 2 11 0; #X connect 24 2 17 0; #X connect 24 3 20 0; #X connect 24 4 27 0; #X connect 25 0 14 0; #X connect 25 0 16 0; #X connect 26 0 12 0; #X connect 27 0 29 0; #X connect 27 1 7 0; #X connect 28 0 31 0; #X connect 29 0 30 0; #X connect 30 0 28 0; #X connect 32 0 35 0; #X connect 32 0 36 0; #X connect 33 0 32 0; #X connect 35 0 34 0; #X connect 37 0 9 0; #X restore 34 236 pd guts; #X msg 34 131 run the transformation; #X msg 34 173 hear the output buffer again; #X text 34 91 click below to:; #X msg 34 194 save the output buffer; #X floatatom 562 334 0 0 120; #N canvas 194 37 397 591 output 0; #X obj 65 199 t b; #X obj 65 150 f; #X obj 65 100 inlet; #X text 70 79 mute; #X obj 65 224 f; #X msg 132 240 0; #X msg 65 125 bang; #X obj 65 175 moses 1; #X obj 132 215 t b f; #X obj 94 434 outlet; #X msg 94 409 set \$1; #X obj 183 160 moses 1; #X obj 221 437 dbtorms; #X obj 221 461 pack 0 100; #X obj 183 136 r master-lvl; #X obj 94 375 r master-lvl; #X obj 81 281 s master-lvl; #X obj 221 486 s master-amp; #X obj 204 240 loadbang; #X msg 204 264 \; master-lvl 90; #X connect 0 0 4 0; #X connect 1 0 7 0; #X connect 2 0 6 0; #X connect 4 0 16 0; #X connect 5 0 16 0; #X connect 6 0 1 0; #X connect 7 0 0 0; #X connect 7 1 8 0; #X connect 8 0 5 0; #X connect 10 0 9 0; #X connect 11 1 4 1; #X connect 12 0 13 0; #X connect 13 0 17 0; #X connect 14 0 1 1; #X connect 14 0 11 0; #X connect 15 0 10 0; #X connect 15 0 12 0; #X connect 18 0 19 0; #X restore 562 313 pd output; #X msg 562 292 mute; #X obj 562 355 s master-lvl; #X text 604 291 <-- mute button; #X floatatom 34 257 0 0 0; #X text 35 300 100 maximum; #X text 35 282 output meter; #X text 600 335 <--set me; #X msg 34 110 read an input file; #X msg 34 215 save normalized to max amplitude; #X msg 34 152 start transformation when I change f or q; #X floatatom 479 164 0 0 0; #X obj 479 185 s frequency; #X text 479 85 center; #X floatatom 482 229 0 0 10000; #X text 482 210 "q"; #X obj 482 252 s q; #X obj 479 143 mtof; #X floatatom 479 122 0 0 128; #X text 536 163 <- set in Hz; #X text 533 230 <--set selectivity; #X text 479 103 frequency; #X text 534 123 <- set in MIDI units; #X text 31 341 Note -- you can shift-click on the controls to change them in hundredths. You can also click and type numbers in \, followed by the "enter" key.; #X text 16 5 Bandpass filter. Read in a sample first \, then you can either set a frequency and hit the "run" button or else hit the "start..." button and start the transformation by dragging on the frequency or q control.; #X text 552 377 OUTPUT LEVEL in dB (100 norm); #X connect 2 0 12 0; #X connect 3 0 2 0; #X connect 4 0 2 0; #X connect 6 0 2 0; #X connect 7 0 10 0; #X connect 8 0 7 0; #X connect 9 0 8 0; #X connect 16 0 2 0; #X connect 17 0 2 0; #X connect 18 0 2 0; #X connect 19 0 20 0; #X connect 22 0 24 0; #X connect 25 0 19 0; #X connect 26 0 25 0; pd-0.46-7/doc/7.stuff/soundfile-tools/README.txt0000664000175000017500000000012612160204055017253 0ustar mspmspHere are some standard audio transformations packaged to work with mono soundfiles. pd-0.46-7/doc/7.stuff/soundfile-tools/4.looper.pd0000664000175000017500000002056112374250720017560 0ustar mspmsp#N canvas 0 16 878 417 12; #N canvas 213 187 495 352 input-sample 0; #N canvas 0 0 450 300 graph1 0; #X array array1 63024 float 0; #X coords 0 1 63023 -1 400 300 1; #X restore 56 23 graph; #X text 151 393 INPUT SAMPLE; #X restore 143 301 pd input-sample; #N canvas 192 180 507 343 output-sample 0; #N canvas 0 0 450 300 graph2 0; #X array array2 441000 float 0; #X coords 0 1 440999 -1 400 300 1; #X restore 60 13 graph; #X text 161 388 OUTPUT SAMPLE; #X restore 143 325 pd output-sample; #N canvas 41 102 912 552 guts 0; #X msg 25 133 bang; #X obj 15 468 openpanel; #X obj 144 28 inlet; #X obj 478 392 dac~; #X obj 478 342 *~; #X obj 494 301 line~; #X obj 494 276 r master-amp; #X msg 759 352 bang; #X obj 759 377 savepanel; #X obj 274 203 spigot; #X msg 248 133 0; #X msg 281 133 1; #X obj 555 384 outlet; #X obj 268 325 tabwrite~ array2; #X msg 262 232 bang; #X obj 456 312 +~; #X obj 478 367 hip~ 7; #X msg 480 228 bang; #X obj 480 253 tabplay~ array2; #X msg 759 402 write \$1 array2; #X obj 759 427 soundfiler; #N canvas 92 118 921 631 audio-transformation 0; #X obj 320 509 outlet~; #X obj 221 41 r transposition; #X obj 287 175 r looplength; #X obj 221 66 / 120; #X obj 235 139 pow; #X obj 221 91 t b f; #X msg 221 115 2; #X text 305 107 2 to the power (octaves); #X text 304 123 gives speed change for the; #X text 305 141 desired transposition; #X text 280 65 transposition in octaves; #X obj 470 264 * 441; #X floatatom 470 234 0 0 0; #X obj 426 352 samphold~; #X obj 545 335 -~ 0.5; #X obj 545 461 clip~ -0.5 0.5; #X obj 545 437 *~ 1; #X obj 545 486 cos~; #X obj 545 365 wrap~; #X obj 545 400 -~ 0.5; #X obj 545 532 *~ -0.5; #X obj 545 508 -~ 1; #X floatatom 617 406 0 0 0; #X obj 601 254 r smoothing; #X obj 470 208 r startpoint; #X obj 617 431 max 1; #X obj 602 308 max 0.001; #X obj 602 334 t b f; #X obj 602 358 1; #X obj 617 382 /; #X obj 320 482 *~; #X obj 320 456 tabread4~ array1; #X obj 320 430 +~; #X obj 227 472 print~; #X msg 227 443 bang; #X obj 601 61 loadbang; #X msg 598 91 \; transposition 0 \; looplength 0 \; startpoint 0 \; smoothing 0; #X obj 236 263 loop~; #X obj 285 233 * 441; #X obj 284 307 *~; #X obj 133 41 loadbang; #X obj 78 174 r running; #X obj 78 203 sel 1; #X obj 602 282 * 0.01; #X obj 286 202 max 0.01; #X connect 1 0 3 0; #X connect 2 0 44 0; #X connect 3 0 5 0; #X connect 4 0 37 0; #X connect 5 0 6 0; #X connect 5 1 4 1; #X connect 6 0 4 0; #X connect 11 0 13 0; #X connect 12 0 11 0; #X connect 13 0 32 1; #X connect 14 0 18 0; #X connect 15 0 17 0; #X connect 16 0 15 0; #X connect 17 0 21 0; #X connect 18 0 19 0; #X connect 19 0 16 0; #X connect 20 0 30 1; #X connect 21 0 20 0; #X connect 22 0 25 0; #X connect 23 0 43 0; #X connect 24 0 12 0; #X connect 25 0 16 1; #X connect 26 0 27 0; #X connect 27 0 28 0; #X connect 27 1 29 1; #X connect 28 0 29 0; #X connect 29 0 22 0; #X connect 30 0 0 0; #X connect 31 0 30 0; #X connect 32 0 31 0; #X connect 32 0 33 0; #X connect 34 0 33 0; #X connect 35 0 36 0; #X connect 37 0 13 1; #X connect 37 0 39 0; #X connect 37 0 14 0; #X connect 37 1 39 1; #X connect 38 0 37 1; #X connect 39 0 32 0; #X connect 40 0 3 0; #X connect 41 0 42 0; #X connect 42 0 37 0; #X connect 43 0 26 0; #X connect 44 0 38 0; #X restore 274 283 pd audio-transformation; #X obj 553 331 env~ 16384; #X obj 665 317 route normalized; #X msg 667 457 write -normalize \$1 array2; #X msg 667 407 bang; #X obj 667 432 savepanel; #X obj 667 482 soundfiler; #X obj 15 518 soundfiler; #X msg 15 493 read -resize -maxsize 1e+06 \$1 array1; #X obj 330 100 r transposition; #X obj 330 125 r looplength; #X obj 330 175 r smoothing; #X obj 708 110 timer; #X obj 708 135 * 44.1; #X obj 724 37 r running; #X obj 708 60 f; #X obj 708 85 sel 1; #X obj 708 227 moses; #X obj 753 227 r maxoutsize; #X msg 708 252 \; array2 resize \$1; #X msg 685 37 bang; #X obj 144 53 route read run start hear save stop; #X obj 312 427 delay; #X obj 331 404 + 100; #X obj 145 329 r maxoutsize; #X obj 86 329 f; #X msg 86 354 \; array2 resize \$1; #X msg 312 452 \; action stop; #X obj 331 379 / 44.1; #X msg 62 271 \; pd dsp 1; #X msg 334 240 \; running 1; #X obj 202 28 r action; #X msg 733 160 \; running 0 \; pd dsp 0; #X obj 330 150 r startpoint; #X obj 553 357 int; #X connect 0 0 1 0; #X connect 1 0 29 0; #X connect 2 0 42 0; #X connect 4 0 16 0; #X connect 5 0 4 1; #X connect 6 0 5 0; #X connect 7 0 8 0; #X connect 8 0 19 0; #X connect 9 0 10 0; #X connect 9 0 14 0; #X connect 10 0 9 1; #X connect 11 0 9 1; #X connect 14 0 13 0; #X connect 14 0 46 0; #X connect 14 0 43 0; #X connect 14 0 50 0; #X connect 14 0 51 0; #X connect 14 0 33 0; #X connect 15 0 4 0; #X connect 15 0 22 0; #X connect 16 0 3 0; #X connect 16 0 3 1; #X connect 17 0 18 0; #X connect 18 0 15 1; #X connect 19 0 20 0; #X connect 21 0 13 0; #X connect 21 0 15 0; #X connect 22 0 55 0; #X connect 23 0 25 0; #X connect 23 1 7 0; #X connect 24 0 27 0; #X connect 25 0 26 0; #X connect 26 0 24 0; #X connect 29 0 28 0; #X connect 30 0 9 0; #X connect 31 0 9 0; #X connect 32 0 9 0; #X connect 33 0 34 0; #X connect 34 0 53 0; #X connect 34 0 38 0; #X connect 35 0 36 1; #X connect 36 0 37 0; #X connect 37 0 33 1; #X connect 38 0 40 0; #X connect 39 0 38 1; #X connect 41 0 36 0; #X connect 42 0 0 0; #X connect 42 1 14 0; #X connect 42 1 10 0; #X connect 42 2 11 0; #X connect 42 3 17 0; #X connect 42 4 23 0; #X connect 42 5 41 0; #X connect 43 0 48 0; #X connect 44 0 43 1; #X connect 45 0 46 1; #X connect 45 0 49 0; #X connect 46 0 47 0; #X connect 49 0 44 0; #X connect 52 0 42 0; #X connect 54 0 9 0; #X connect 55 0 12 0; #X restore 19 228 pd guts; #X msg 19 96 run the transformation; #X msg 19 163 hear the output buffer again; #X text 19 55 click below to:; #X msg 19 185 save the output buffer; #X floatatom 367 337 0 0 120; #N canvas 194 37 397 591 output 0; #X obj 66 203 t b; #X obj 66 152 f; #X obj 66 102 inlet; #X text 71 81 mute; #X obj 66 228 f; #X msg 134 244 0; #X msg 66 127 bang; #X obj 66 178 moses 1; #X obj 134 218 t b f; #X obj 96 442 outlet; #X msg 96 416 set \$1; #X obj 186 163 moses 1; #X obj 224 444 dbtorms; #X obj 224 469 pack 0 100; #X obj 186 138 r master-lvl; #X obj 96 382 r master-lvl; #X obj 83 286 s master-lvl; #X obj 224 494 s master-amp; #X obj 208 244 loadbang; #X msg 208 269 \; master-lvl 90; #X connect 0 0 4 0; #X connect 1 0 7 0; #X connect 2 0 6 0; #X connect 4 0 16 0; #X connect 5 0 16 0; #X connect 6 0 1 0; #X connect 7 0 0 0; #X connect 7 1 8 0; #X connect 8 0 5 0; #X connect 10 0 9 0; #X connect 11 1 4 1; #X connect 12 0 13 0; #X connect 13 0 17 0; #X connect 14 0 1 1; #X connect 14 0 11 0; #X connect 15 0 10 0; #X connect 15 0 12 0; #X connect 18 0 19 0; #X restore 367 316 pd output; #X msg 367 294 mute; #X obj 367 359 s master-lvl; #X text 410 293 <-- mute button; #X floatatom 19 250 0 0 0; #X text 20 294 100 maximum; #X text 20 276 output meter; #X text 405 336 <--set me; #X msg 19 74 read an input file; #X text 367 379 LINE OUT LEVEL in dB (100 norm); #X msg 19 206 save normalized to max amplitude; #X floatatom 368 73 0 0 1000; #X floatatom 369 19 0 0 0; #X obj 369 47 s transposition; #X floatatom 369 170 0 0 100; #X obj 369 192 s smoothing; #X obj 368 95 s looplength; #X text 418 73 <- loop length \, hundredths of a second; #X floatatom 369 122 0 0 60000; #X obj 369 144 s startpoint; #X text 420 123 <- start point \, hundredths of a second; #X text 419 171 <- envelope smoothing \, 0-100; #X text 38 9 looping sample player.; #X msg 19 118 start looping when I change something; #X msg 19 140 stop looping; #X floatatom 368 239 0 0 60; #N canvas 0 0 265 196 length 0; #X obj 48 24 inlet; #X obj 49 104 * 44100; #X msg 86 130 \; array2 resize \$1; #X obj 48 49 min 60; #X obj 62 78 s output-length; #X obj 48 164 s maxoutsize; #X connect 0 0 3 0; #X connect 1 0 2 0; #X connect 1 0 5 0; #X connect 3 0 1 0; #X connect 3 0 4 0; #X restore 368 260 pd length; #N canvas 219 38 198 151 /SUBPATCH/ 0; #X obj 79 122 outlet; #X obj 79 74 loadbang; #X msg 79 98 10; #X connect 1 0 2 0; #X connect 2 0 0 0; #X restore 368 217 pd; #X text 455 241 length in seconds of the output; #X text 453 259 buffer... maximum 60; #X text 404 241 <- set; #X text 408 20 <- transposition up or down \, 10ths of a half step ; #X connect 2 0 12 0; #X connect 3 0 2 0; #X connect 4 0 2 0; #X connect 6 0 2 0; #X connect 7 0 10 0; #X connect 8 0 7 0; #X connect 9 0 8 0; #X connect 16 0 2 0; #X connect 18 0 2 0; #X connect 19 0 24 0; #X connect 20 0 21 0; #X connect 22 0 23 0; #X connect 26 0 27 0; #X connect 31 0 2 0; #X connect 32 0 2 0; #X connect 33 0 34 0; #X connect 35 0 33 0; pd-0.46-7/doc/7.stuff/soundfile-tools/1.ring-mod.pd0000664000175000017500000001170712160204055017764 0ustar mspmsp#N canvas 73 28 687 421 12; #N canvas 213 187 495 352 input-sample 0; #N canvas 0 0 450 300 graph1 0; #X array array1 91065 float 0; #X coords 0 1 91065 -1 400 300 1; #X restore 56 23 graph; #X text 151 393 INPUT SAMPLE; #X restore 179 299 pd input-sample; #N canvas 192 180 507 343 output-sample 0; #N canvas 0 0 450 300 graph2 0; #X array array2 95475 float 0; #X coords 0 1 95475 -1 400 300 1; #X restore 60 13 graph; #X text 161 388 OUTPUT SAMPLE; #X restore 179 323 pd output-sample; #N canvas 110 33 827 602 guts 0; #X msg 25 133 bang; #X obj 25 360 openpanel; #X obj 144 31 inlet; #X obj 441 403 dac~; #X obj 441 342 *~; #X obj 456 318 line~; #X obj 456 296 r master-amp; #X msg 597 130 bang; #X obj 597 155 savepanel; #X obj 231 164 spigot; #X msg 233 132 0; #X msg 265 132 1; #X obj 497 427 outlet; #X obj 299 132 r frequency; #X obj 219 321 tabwrite~ array2; #X msg 219 193 bang; #X obj 420 289 +~; #X msg 96 129 \; pd dsp 1; #X obj 441 370 hip~ 7; #X obj 231 223 tabplay~ array1; #X msg 439 131 bang; #X obj 439 160 tabplay~ array2; #X msg 597 180 write \$1 array2; #X obj 597 205 soundfiler; #X obj 144 53 route read run start hear save; #N canvas 0 0 368 263 audio-transformation 0; #X obj 113 95 osc~; #X obj 97 116 *~; #X obj 97 138 hip~ 7; #X obj 113 71 r frequency; #X obj 97 22 inlet~; #X obj 97 169 outlet~; #X obj 97 47 hip~ 7; #X connect 0 0 1 1; #X connect 1 0 2 0; #X connect 2 0 5 0; #X connect 3 0 0 0; #X connect 4 0 6 0; #X connect 6 0 1 0; #X restore 231 251 pd audio-transformation; #X obj 497 402 env~ 16384; #X obj 570 91 route normalized; #X msg 571 300 write -normalize \$1 array2; #X msg 571 250 bang; #X obj 571 276 savepanel; #X obj 571 325 soundfiler; #X obj 25 413 soundfiler; #X msg 25 390 read -resize -maxsize 1e+06 \$1 array1; #X msg 25 460 \; array2 resize \$1; #X obj 25 437 + 4410; #X floatatom 96 436 0 0 0; #X connect 0 0 1 0; #X connect 1 0 33 0; #X connect 2 0 24 0; #X connect 4 0 18 0; #X connect 5 0 4 1; #X connect 6 0 5 0; #X connect 7 0 8 0; #X connect 8 0 22 0; #X connect 9 0 10 0; #X connect 9 0 15 0; #X connect 10 0 9 1; #X connect 11 0 9 1; #X connect 13 0 9 0; #X connect 15 0 14 0; #X connect 15 0 19 0; #X connect 16 0 4 0; #X connect 18 0 3 0; #X connect 18 0 3 1; #X connect 18 0 26 0; #X connect 19 0 25 0; #X connect 20 0 21 0; #X connect 21 0 16 1; #X connect 22 0 23 0; #X connect 24 0 0 0; #X connect 24 1 15 0; #X connect 24 1 10 0; #X connect 24 1 17 0; #X connect 24 2 11 0; #X connect 24 2 17 0; #X connect 24 3 20 0; #X connect 24 4 27 0; #X connect 25 0 14 0; #X connect 25 0 16 0; #X connect 26 0 12 0; #X connect 27 0 29 0; #X connect 27 1 7 0; #X connect 28 0 31 0; #X connect 29 0 30 0; #X connect 30 0 28 0; #X connect 32 0 35 0; #X connect 32 0 36 0; #X connect 33 0 32 0; #X connect 35 0 34 0; #X restore 28 265 pd guts; #X msg 28 155 run the transformation; #X msg 28 199 hear the output buffer again; #X text 28 113 click below to:; #X msg 28 221 save the output buffer; #X floatatom 404 257 0 0 0; #N canvas 194 37 397 591 output 0; #X obj 66 203 t b; #X obj 66 152 f; #X obj 66 102 inlet; #X text 71 81 mute; #X obj 66 228 f; #X msg 134 244 0; #X msg 66 127 bang; #X obj 66 178 moses 1; #X obj 134 218 t b f; #X obj 96 442 outlet; #X msg 96 416 set \$1; #X obj 186 163 moses 1; #X obj 224 444 dbtorms; #X obj 224 469 pack 0 100; #X obj 186 138 r master-lvl; #X obj 96 382 r master-lvl; #X obj 83 286 s master-lvl; #X obj 224 494 s master-amp; #X obj 208 244 loadbang; #X msg 208 269 \; master-lvl 90; #X connect 0 0 4 0; #X connect 1 0 7 0; #X connect 2 0 6 0; #X connect 4 0 16 0; #X connect 5 0 16 0; #X connect 6 0 1 0; #X connect 7 0 0 0; #X connect 7 1 8 0; #X connect 8 0 5 0; #X connect 10 0 9 0; #X connect 11 1 4 1; #X connect 12 0 13 0; #X connect 13 0 17 0; #X connect 14 0 1 1; #X connect 14 0 11 0; #X connect 15 0 10 0; #X connect 15 0 12 0; #X connect 18 0 19 0; #X restore 404 235 pd output; #X msg 404 213 mute; #X obj 404 279 s master-lvl; #X text 448 212 <-- mute button; #X msg 28 177 start transformation when I change frequency; #X floatatom 392 117 0 0 0; #X obj 392 139 s frequency; #X text 392 97 modulation frequency (Hz.); #X floatatom 28 287 0 0 0; #X text 10 330 100 maximum; #X text 10 311 output meter; #X text 429 115 <--set me; #X text 443 255 <--set me; #X msg 28 133 read an input file; #X msg 28 243 save normalized to max amplitude; #X text 29 8 Ring modulator. Read in a sample first \, then you can either set a frequency and hit the "run" button or else hit the "start..." button and start the transformation by dragging on the frequency control. The output level should be "100" for unit gain.; #X text 22 361 Outputs are saved as "wav" files \, although you can edit the patch to make "aiff" or "nextstep" instead. Any of the three are OK for source files.; #X text 397 302 LINE OUT LEVEL in dB (100 max); #X connect 2 0 16 0; #X connect 3 0 2 0; #X connect 4 0 2 0; #X connect 6 0 2 0; #X connect 7 0 10 0; #X connect 8 0 7 0; #X connect 9 0 8 0; #X connect 12 0 2 0; #X connect 13 0 14 0; #X connect 21 0 2 0; #X connect 22 0 2 0; pd-0.46-7/doc/7.stuff/soundfile-tools/6.vocoder.pd0000664000175000017500000001725312160204055017720 0ustar mspmsp#N canvas 73 102 706 428 12; #X floatatom 462 162 0 0 100; #X msg 462 137 set \$1; #X text 29 322 100 maximum; #X text 29 304 output meter; #N canvas 145 136 937 540 guts 0; #X msg 5 296 bang; #X obj 5 321 openpanel; #X obj 136 29 inlet; #X obj 452 375 dac~; #X obj 452 323 *~; #X obj 467 300 line~; #X obj 467 280 r master-amp; #X msg 689 157 bang; #X obj 689 177 savepanel; #X obj 506 393 outlet; #X obj 297 238 tabwrite~ array2; #X obj 454 238 +~; #X obj 452 343 hip~ 7; #X msg 446 108 bang; #X obj 446 133 tabplay~ array2; #X msg 689 197 write \$1 array2; #X obj 689 218 soundfiler; #X obj 506 373 env~ 16384; #X obj 587 129 route normalized; #X msg 587 250 write -normalize \$1 array2; #X msg 587 209 bang; #X obj 587 230 savepanel; #X obj 587 274 soundfiler; #X obj 5 365 soundfiler; #X msg 5 343 read -resize -maxsize 1e+06 \$1 array1; #X obj 676 338 loadbang; #N canvas 0 0 690 470 fft-analysis 0; #X obj 275 314 *~; #X obj 257 348 *~; #X obj 218 348 *~; #X obj 105 163 *~; #X obj 66 156 *~; #X obj 66 182 +~; #X obj 216 104 *~; #X obj 253 104 inlet~; #X obj 216 130 rfft~; #X obj 42 371 *~; #X floatatom 458 208 0 0 0; #X obj 334 177 *~; #X obj 66 104 *~; #X obj 103 104 inlet~; #X obj 45 65 tabreceive~ hanning; #X obj 66 130 rfft~; #X obj 218 374 rifft~; #X obj 42 397 outlet~; #X obj 297 177 *~; #X obj 297 203 +~; #X obj 307 314 sig~ 0.001; #X text 122 214 modulus; #X obj 66 208 sqrt~; #X obj 275 288 *~; #X obj 457 58 r squelch; #X obj 329 418 block~ 1024 4; #X obj 297 229 rsqrt~; #X obj 341 203 sig~ 1e-20; #X obj 297 255 clip~; #X obj 458 130 t f f; #X obj 458 156 *; #X obj 458 182 * 0.01; #X obj 456 94 max 1; #X obj 559 58 loadbang; #X obj 458 234 max 0; #X connect 0 0 1 1; #X connect 0 0 2 1; #X connect 1 0 16 1; #X connect 2 0 16 0; #X connect 3 0 5 1; #X connect 4 0 5 0; #X connect 5 0 22 0; #X connect 6 0 8 0; #X connect 7 0 6 1; #X connect 8 0 18 0; #X connect 8 0 18 1; #X connect 8 0 2 0; #X connect 8 1 11 0; #X connect 8 1 11 1; #X connect 8 1 1 0; #X connect 9 0 17 0; #X connect 10 0 34 0; #X connect 11 0 19 1; #X connect 12 0 15 0; #X connect 13 0 12 1; #X connect 14 0 12 0; #X connect 14 0 6 0; #X connect 14 0 9 0; #X connect 15 0 4 0; #X connect 15 0 4 1; #X connect 15 1 3 0; #X connect 15 1 3 1; #X connect 16 0 9 1; #X connect 18 0 19 0; #X connect 19 0 26 0; #X connect 20 0 0 1; #X connect 22 0 23 0; #X connect 23 0 0 0; #X connect 24 0 32 0; #X connect 26 0 28 0; #X connect 27 0 26 0; #X connect 28 0 23 1; #X connect 29 0 30 0; #X connect 29 0 30 1; #X connect 30 0 31 0; #X connect 31 0 10 0; #X connect 32 0 29 0; #X connect 33 0 32 0; #X connect 34 0 28 2; #X restore 296 194 pd fft-analysis; #X msg 202 86 bang; #N canvas 46 0 723 534 hanning-window 0; #X obj 122 273 phasor~; #X obj 122 311 cos~; #X obj 31 436 tabwrite~ hanning; #X obj 40 336 -~; #X obj 37 290 sig~ 1; #X msg 50 240 0; #X text 188 18 CALCULATE HANNING; #X text 188 36 WINDOW TABLE; #N canvas 0 0 450 300 graph1 0; #X array hanning 1024 float 0; #X coords 0 1 1023 -1 400 300 1; #X restore 342 235 graph; #X obj 123 227 sig~; #X text 156 173 sample rate / window size; #X msg 31 191 bang; #X obj 88 357 sig~ 0.5; #X obj 66 399 *~; #X obj 124 106 samplerate~; #X obj 33 31 r window-size; #X obj 123 175 /; #X msg 262 106 \; hanning resize \$1; #X obj 31 70 t b f f; #X connect 0 0 1 0; #X connect 1 0 3 1; #X connect 3 0 13 0; #X connect 4 0 3 0; #X connect 5 0 0 1; #X connect 9 0 0 0; #X connect 11 0 2 0; #X connect 11 0 5 0; #X connect 12 0 13 1; #X connect 13 0 2 0; #X connect 14 0 16 0; #X connect 15 0 18 0; #X connect 16 0 9 0; #X connect 18 0 14 0; #X connect 18 0 11 0; #X connect 18 1 16 1; #X connect 18 2 17 0; #X restore 673 403 pd hanning-window; #X obj 181 29 r action; #X msg 150 163 \; pd dsp 1; #X msg 389 106 stop; #X msg 58 455 \; array2 resize \$1; #X obj 58 434 + 4410; #X obj 136 50 route read AND run hear save stop; #X obj 58 412 min; #X obj 107 380 t b f; #X obj 107 270 openpanel; #X obj 107 314 soundfiler; #X msg 107 293 read -resize -maxsize 1e+06 \$1 array3; #X msg 106 239 bang; #X msg 676 360 \; window-size 1024 \;; #X obj 296 145 tabplay~ array1; #X obj 314 167 tabplay~ array3; #X connect 0 0 1 0; #X connect 1 0 24 0; #X connect 2 0 34 0; #X connect 4 0 12 0; #X connect 5 0 4 1; #X connect 6 0 5 0; #X connect 7 0 8 0; #X connect 8 0 15 0; #X connect 11 0 4 0; #X connect 12 0 3 0; #X connect 12 0 3 1; #X connect 12 0 17 0; #X connect 13 0 14 0; #X connect 14 0 11 1; #X connect 15 0 16 0; #X connect 17 0 9 0; #X connect 18 0 20 0; #X connect 18 1 7 0; #X connect 19 0 22 0; #X connect 20 0 21 0; #X connect 21 0 19 0; #X connect 23 0 35 0; #X connect 24 0 23 0; #X connect 25 0 41 0; #X connect 26 0 10 0; #X connect 26 0 11 0; #X connect 27 0 10 0; #X connect 27 0 30 0; #X connect 27 0 42 0; #X connect 27 0 43 0; #X connect 29 0 34 0; #X connect 31 0 14 0; #X connect 33 0 32 0; #X connect 34 0 0 0; #X connect 34 1 40 0; #X connect 34 2 27 0; #X connect 34 3 13 0; #X connect 34 4 18 0; #X connect 34 5 31 0; #X connect 35 0 33 0; #X connect 36 0 35 0; #X connect 36 1 35 1; #X connect 37 0 39 0; #X connect 38 0 36 0; #X connect 39 0 38 0; #X connect 40 0 37 0; #X connect 42 0 26 0; #X connect 43 0 26 1; #X restore 29 263 pd guts; #X msg 29 158 run the transformation; #X msg 29 200 hear the output buffer again; #X text 29 97 click below to:; #X msg 29 221 save the output buffer; #X floatatom 29 284 0 0 0; #X msg 29 242 save normalized to max amplitude; #N canvas 130 10 488 287 input-sample 0; #N canvas 0 0 450 300 graph1 0; #X array array1 188955 float 0; #X coords 0 1 188954 -1 400 100 1; #X restore 53 21 graph; #N canvas 0 0 450 300 graph3 0; #X array array3 225280 float 0; #X coords 0 1 225279 -1 400 100 1; #X restore 54 146 graph; #X text 227 279 INPUT SAMPLES; #X restore 169 368 pd input-sample; #N canvas 192 180 507 343 output-sample 0; #N canvas 0 0 450 300 graph2 0; #X array array2 193365 float 0; #X coords 0 1 193364 -1 400 300 1; #X restore 56 12 graph; #X text 151 365 OUTPUT SAMPLE; #X restore 168 393 pd output-sample; #X floatatom 408 365 0 0 0; #N canvas 194 37 397 591 output 0; #X obj 62 191 t b; #X obj 62 144 f; #X obj 62 96 inlet; #X text 67 76 mute; #X obj 62 215 f; #X msg 127 229 0; #X msg 62 120 bang; #X obj 62 167 moses 1; #X obj 127 206 t b f; #X obj 90 416 outlet; #X msg 90 392 set \$1; #X obj 175 154 moses 1; #X obj 211 418 dbtorms; #X obj 211 442 pack 0 100; #X obj 175 130 r master-lvl; #X obj 90 359 r master-lvl; #X obj 78 269 s master-lvl; #X obj 211 466 s master-amp; #X obj 195 229 loadbang; #X msg 195 253 \; master-lvl 90; #X connect 0 0 4 0; #X connect 1 0 7 0; #X connect 2 0 6 0; #X connect 4 0 16 0; #X connect 5 0 16 0; #X connect 6 0 1 0; #X connect 7 0 0 0; #X connect 7 1 8 0; #X connect 8 0 5 0; #X connect 10 0 9 0; #X connect 11 1 4 1; #X connect 12 0 13 0; #X connect 13 0 17 0; #X connect 14 0 1 1; #X connect 14 0 11 0; #X connect 15 0 10 0; #X connect 15 0 12 0; #X connect 18 0 19 0; #X restore 408 344 pd output; #X msg 408 323 mute; #X obj 408 386 s master-lvl; #X text 449 322 <-- mute button; #X text 444 363 <--set me; #X text 408 406 LINE OUT LEVEL in dB (100 norm); #X msg 29 179 stop the transformation; #X text 193 9 (old-fashioned) VOCODER; #X text 28 31 This takes in two soundfiles and uses the first to "vocode" the second. THe resulting sound is as long as the shorter of the two inputs.; #X msg 29 116 read the analysis sound from file; #X msg 29 137 AND read the sound to be processed from file; #X text 462 97 SQUELCH; #X obj 462 116 r squelch; #X obj 462 187 s squelch; #X text 526 161 1-100 or so; #X connect 0 0 27 0; #X connect 1 0 0 0; #X connect 4 0 9 0; #X connect 5 0 4 0; #X connect 6 0 4 0; #X connect 8 0 4 0; #X connect 10 0 4 0; #X connect 13 0 16 0; #X connect 14 0 13 0; #X connect 15 0 14 0; #X connect 20 0 4 0; #X connect 23 0 4 0; #X connect 24 0 4 0; #X connect 26 0 1 0; pd-0.46-7/doc/7.stuff/soundfile-tools/5.reverb.pd0000664000175000017500000001243212374250720017544 0ustar mspmsp#N canvas 186 43 739 364 12; #N canvas 213 187 495 352 input-sample 0; #N canvas 0 0 450 300 graph1 0; #X array array1 63024 float 0; #X coords 0 1 63023 -1 400 300 1; #X restore 54 22 graph; #X text 145 376 INPUT SAMPLE; #X restore 154 226 pd input-sample; #N canvas 192 180 507 343 output-sample 0; #N canvas 0 0 450 300 graph2 0; #X array array2 504024 float 0; #X coords 0 1 504023 -1 400 300 1; #X restore 57 13 graph; #X text 154 372 OUTPUT SAMPLE; #X restore 155 249 pd output-sample; #N canvas 116 150 735 421 guts 0; #X msg 24 128 bang; #X obj 24 345 openpanel; #X obj 138 30 inlet; #X obj 446 368 dac~; #X obj 446 327 *~; #X obj 461 304 line~; #X obj 461 283 r master-amp; #X msg 707 85 bang; #X obj 707 106 savepanel; #X obj 268 161 spigot; #X msg 253 128 0; #X msg 284 128 1; #X obj 500 398 outlet; #X obj 316 128 r frequency; #X obj 256 312 tabwrite~ array2; #X msg 256 189 bang; #X obj 427 276 +~; #X msg 139 128 \; pd dsp 1; #X obj 446 347 hip~ 7; #X obj 268 217 tabplay~ array1; #X msg 442 124 bang; #X obj 442 145 tabplay~ array2; #X msg 707 126 write \$1 array2; #X obj 707 147 soundfiler; #X obj 138 51 route read run start hear save; #N canvas 0 0 632 395 audio-transformation 0; #X obj 101 49 inlet~; #X obj 105 268 outlet~; #X obj 101 148 rev1~ xxx; #X obj 339 79 r revgain; #X obj 338 102 dbtorms; #X obj 338 130 pack 0 50; #X obj 338 154 line~; #X obj 103 204 *~; #X obj 181 51 r revtime; #X obj 213 236 *~; #X obj 340 209 dbtorms; #X obj 340 237 pack 0 50; #X obj 340 261 line~; #X obj 294 37 inlet; #X msg 293 61 bang; #X obj 342 186 r drygain; #X connect 0 0 2 0; #X connect 0 0 9 0; #X connect 2 0 7 0; #X connect 3 0 4 0; #X connect 4 0 5 0; #X connect 5 0 6 0; #X connect 6 0 7 1; #X connect 7 0 1 0; #X connect 8 0 2 1; #X connect 9 0 1 0; #X connect 10 0 11 0; #X connect 11 0 12 0; #X connect 12 0 9 1; #X connect 13 0 14 0; #X connect 14 0 2 2; #X connect 15 0 10 0; #X restore 268 238 pd audio-transformation; #X obj 500 377 env~ 16384; #X obj 570 86 route normalized; #X msg 570 179 write -normalize \$1 array2; #X msg 570 138 bang; #X obj 570 159 savepanel; #X obj 570 204 soundfiler; #X obj 24 396 soundfiler; #X msg 24 374 read -resize -maxsize 1e+06 \$1 array1; #X msg 24 440 \; array2 resize \$1; #X obj 402 129 r q; #X obj 24 419 + 441000; #X connect 0 0 1 0; #X connect 1 0 33 0; #X connect 2 0 24 0; #X connect 4 0 18 0; #X connect 5 0 4 1; #X connect 6 0 5 0; #X connect 7 0 8 0; #X connect 8 0 22 0; #X connect 9 0 10 0; #X connect 9 0 15 0; #X connect 10 0 9 1; #X connect 11 0 9 1; #X connect 13 0 9 0; #X connect 15 0 14 0; #X connect 15 0 19 0; #X connect 15 0 25 1; #X connect 16 0 4 0; #X connect 18 0 3 0; #X connect 18 0 3 1; #X connect 18 0 26 0; #X connect 19 0 25 0; #X connect 20 0 21 0; #X connect 21 0 16 1; #X connect 22 0 23 0; #X connect 24 0 0 0; #X connect 24 1 15 0; #X connect 24 1 10 0; #X connect 24 1 17 0; #X connect 24 2 11 0; #X connect 24 2 17 0; #X connect 24 3 20 0; #X connect 24 4 27 0; #X connect 25 0 14 0; #X connect 25 0 16 0; #X connect 26 0 12 0; #X connect 27 0 29 0; #X connect 27 1 7 0; #X connect 28 0 31 0; #X connect 29 0 30 0; #X connect 30 0 28 0; #X connect 32 0 36 0; #X connect 33 0 32 0; #X connect 35 0 9 0; #X connect 36 0 34 0; #X restore 35 190 pd guts; #X msg 35 85 run the transformation; #X msg 35 127 hear the output buffer again; #X text 35 45 click below to:; #X msg 35 148 save the output buffer; #X floatatom 445 285 0 0 120; #N canvas 194 37 397 591 output 0; #X obj 63 194 t b; #X obj 63 146 f; #X obj 63 98 inlet; #X text 68 77 mute; #X obj 63 218 f; #X msg 129 233 0; #X msg 63 122 bang; #X obj 63 170 moses 1; #X obj 129 209 t b f; #X obj 92 423 outlet; #X msg 92 399 set \$1; #X obj 178 156 moses 1; #X obj 215 425 dbtorms; #X obj 215 450 pack 0 100; #X obj 178 132 r master-lvl; #X obj 92 366 r master-lvl; #X obj 79 274 s master-lvl; #X obj 215 474 s master-amp; #X obj 199 233 loadbang; #X msg 199 258 \; master-lvl 90; #X connect 0 0 4 0; #X connect 1 0 7 0; #X connect 2 0 6 0; #X connect 4 0 16 0; #X connect 5 0 16 0; #X connect 6 0 1 0; #X connect 7 0 0 0; #X connect 7 1 8 0; #X connect 8 0 5 0; #X connect 10 0 9 0; #X connect 11 1 4 1; #X connect 12 0 13 0; #X connect 13 0 17 0; #X connect 14 0 1 1; #X connect 14 0 11 0; #X connect 15 0 10 0; #X connect 15 0 12 0; #X connect 18 0 19 0; #X restore 445 264 pd output; #X msg 445 243 mute; #X obj 445 306 s master-lvl; #X text 486 242 <-- mute button; #X floatatom 35 211 0 0 0; #X text 13 251 100 maximum; #X text 13 233 output meter; #X text 482 284 <--set me; #X msg 35 64 read an input file; #X text 445 326 LINE OUT LEVEL in dB (100 norm); #X msg 35 169 save normalized to max amplitude; #X msg 35 106 start transformation when I change f or q; #X floatatom 445 82 0 0 120; #X floatatom 445 40 0 0 100; #X obj 445 61 s revtime; #X obj 445 103 s revgain; #X floatatom 446 184 0 0 120; #X text 494 84 <-- reverb gain; #X text 482 185 <-- dry gain; #X obj 446 205 s drygain; #X obj 446 142 loadbang; #X msg 446 163 100; #X text 486 39 <- reverb time 0-100; #X text 23 15 Reverberator. Read in a sample first.; #X connect 2 0 12 0; #X connect 3 0 2 0; #X connect 4 0 2 0; #X connect 6 0 2 0; #X connect 7 0 10 0; #X connect 8 0 7 0; #X connect 9 0 8 0; #X connect 16 0 2 0; #X connect 18 0 2 0; #X connect 19 0 2 0; #X connect 20 0 23 0; #X connect 21 0 22 0; #X connect 24 0 27 0; #X connect 28 0 29 0; #X connect 29 0 24 0; pd-0.46-7/doc/7.stuff/synth/0000775000175000017500000000000012160204055013575 5ustar mspmsppd-0.46-7/doc/7.stuff/synth/preset4.txt0000664000175000017500000000031012160204055015716 0ustar mspmsplist 2pc-in 0 list 2nd-in 0 list q-in 3.01 list fr-in 200 list fs-in 18 list fd-in 323 list fa-in 2 list fb-in 6 list fil-in 50 list as-in 88 list ad-in 72 list ar-in 207 list aa-in 6 list amp-in 100 pd-0.46-7/doc/7.stuff/synth/preset3.txt0000664000175000017500000000027512160204055015727 0ustar mspmsplist 2nd-in 1200 list q-in 10 list fr-in 200 list fs-in 46 list fd-in 360 list fa-in 2 list fb-in 30 list fil-in 73 list as-in 63 list ad-in 1631 list ar-in 207 list aa-in 6 list amp-in 95 pd-0.46-7/doc/7.stuff/synth/gadsr.pd0000664000175000017500000000652112160204055015226 0ustar mspmsp#N canvas 71 56 698 578 12; #X obj 9 412 inlet; #X obj 24 314 inlet; #X text 21 437 trigger; #X obj 154 314 inlet; #X obj 156 477 line~; #X obj 289 316 inlet; #X obj 426 321 inlet; #X obj 566 321 inlet; #X text 26 366 level; #X obj 156 512 outlet~; #X text 148 365 attack; #X text 284 366 decay; #X text 390 366 sustain; #X text 536 374 release; #X obj 460 480 snapshot~; #X obj 460 452 metro 200; #X msg 460 508 set \$1; #X floatatom 475 13 5 0 0; #X obj 15 286 f \$1; #X obj 460 426 loadbang; #X obj 13 233 loadbang; #X obj 273 58 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 346 63 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 346 85 0; #X obj 206 60 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 206 81 1; #X msg 273 83 -1; #X obj 143 288 f \$2; #X floatatom 143 342 4 0 0; #N canvas 110 169 840 732 control 0; #X obj 368 662 outlet; #X obj 37 46 inlet; #X obj 170 120 inlet; #X obj 256 121 inlet; #X text 74 12 trigger; #X text 167 82 level; #X text 392 640 to line~; #X obj 42 332 pack; #X obj 22 152 moses; #X text 76 168 from; #X text 78 180 here; #X obj 13 199 t b b; #X text 21 170 from; #X text 23 182 zero; #X msg 206 336 0; #X obj 36 302 f; #X text 245 84 attack time; #X obj 373 120 inlet; #X text 362 83 decay time; #X obj 494 119 inlet; #X text 478 85 sustain level; #X obj 617 117 inlet; #X text 610 86 release time; #X text 471 472 DECAY; #X obj 401 423 * 0.01; #X obj 415 329 del; #X obj 401 397 *; #X obj 420 358 f; #X obj 464 454 pack; #X obj 624 346 pack; #X obj 50 81 sel 0; #X msg 80 120 stop; #X obj 68 197 t b; #X connect 1 0 30 0; #X connect 2 0 15 1; #X connect 2 0 26 1; #X connect 3 0 7 1; #X connect 3 0 25 0; #X connect 7 0 0 0; #X connect 8 0 11 0; #X connect 8 1 32 0; #X connect 11 0 15 0; #X connect 11 1 14 0; #X connect 14 0 0 0; #X connect 15 0 7 0; #X connect 17 0 28 1; #X connect 19 0 27 1; #X connect 21 0 29 1; #X connect 24 0 28 0; #X connect 25 0 27 0; #X connect 26 0 24 0; #X connect 27 0 26 0; #X connect 28 0 0 0; #X connect 29 0 0 0; #X connect 30 0 31 0; #X connect 30 0 29 0; #X connect 30 1 8 0; #X connect 31 0 25 0; #X connect 32 0 15 0; #X restore 135 395 pd control; #X obj 280 288 f \$2; #X obj 410 286 f \$2; #X obj 543 286 f \$2; #X floatatom 280 345 4 0 0; #X floatatom 410 345 4 0 0; #X floatatom 543 346 4 0 0; #X obj 489 74 pack 0 20; #X msg 495 110 0; #X obj 489 47 t f b; #X text 104 541 gadsr - arguments: level \, attack time \, decay time \, sustain percentage \, release time; #X floatatom 15 341 4 0 0; #X connect 0 0 29 0; #X connect 1 0 40 0; #X connect 3 0 28 0; #X connect 4 0 9 0; #X connect 4 0 14 0; #X connect 5 0 33 0; #X connect 6 0 34 0; #X connect 7 0 35 0; #X connect 14 0 16 0; #X connect 15 0 14 0; #X connect 16 0 17 0; #X connect 17 0 38 0; #X connect 18 0 40 0; #X connect 19 0 15 0; #X connect 20 0 18 0; #X connect 20 0 27 0; #X connect 20 0 30 0; #X connect 20 0 31 0; #X connect 20 0 32 0; #X connect 21 0 26 0; #X connect 22 0 23 0; #X connect 23 0 29 0; #X connect 24 0 25 0; #X connect 25 0 29 0; #X connect 26 0 29 0; #X connect 27 0 28 0; #X connect 28 0 29 2; #X connect 29 0 4 0; #X connect 30 0 33 0; #X connect 31 0 34 0; #X connect 32 0 35 0; #X connect 33 0 29 3; #X connect 34 0 29 4; #X connect 35 0 29 5; #X connect 36 0 4 0; #X connect 37 0 29 0; #X connect 38 0 36 0; #X connect 38 1 37 0; #X connect 40 0 29 1; #X coords 0 0 1 1 200 40 1; pd-0.46-7/doc/7.stuff/synth/README.txt0000664000175000017500000000050112160204055015267 0ustar mspmspThis patch (1.poly.synth) is a polyphonic subtractive synthesizer with a dozen or so voice parameters you can control live or via presets. Four presets are defined. To test, recall a preset (you should see numbers pop up in all the parameter controls) start the metronome and turn up the output volume to around 100. pd-0.46-7/doc/7.stuff/synth/preset.pd0000664000175000017500000000241512160204055015426 0ustar mspmsp#N canvas 69 59 443 360 12; #X obj 210 286 textfile; #X obj 8 174 bng 15 250 50 0 empty empty store 16 7 0 10 -262144 -1 -1; #X obj 8 320 bng 15 250 50 0 empty empty recall 15 7 0 10 -262144 -1 -1; #X obj 408 330 tgl 10 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 104 59 t b b b; #X msg 219 121 clear; #X msg 114 149 -record-; #X obj 61 207 symbol \$1.txt; #X obj 363 115 1; #X obj 310 191 symbol \$1.txt; #X obj 312 165 loadbang; #X msg 310 216 read \$1 cr; #X msg 62 234 write \$1 cr; #X obj 75 299 until; #X msg 210 322 \; \$1 \$2; #X obj 112 175 s \$2-in; #X obj 224 187 r \$2-out; #X obj 77 265 t b b; #X msg 140 268 rewind; #X obj 308 295 print; #X obj 224 220 spigot; #X obj 311 126 1; #X obj 278 124 0; #X connect 0 0 14 0; #X connect 0 1 13 1; #X connect 1 0 4 0; #X connect 2 0 17 0; #X connect 4 0 7 0; #X connect 4 0 8 0; #X connect 4 0 22 0; #X connect 4 1 6 0; #X connect 4 2 5 0; #X connect 4 2 21 0; #X connect 5 0 0 0; #X connect 6 0 15 0; #X connect 7 0 12 0; #X connect 8 0 3 0; #X connect 9 0 11 0; #X connect 10 0 9 0; #X connect 11 0 0 0; #X connect 12 0 0 0; #X connect 13 0 0 0; #X connect 16 0 20 0; #X connect 17 0 13 0; #X connect 17 1 18 0; #X connect 18 0 0 0; #X connect 20 0 0 0; #X connect 21 0 20 1; #X connect 22 0 20 1; #X coords 0 0 1 1 90 35 1; pd-0.46-7/doc/7.stuff/synth/test-gadsr.pd0000664000175000017500000000006212160204055016175 0ustar mspmsp#N canvas 45 88 785 525 10; #X obj 208 171 gadsr; pd-0.46-7/doc/7.stuff/synth/preset1.txt0000664000175000017500000000027512160204055015725 0ustar mspmsplist 2nd-in 1200 list q-in 0.48 list fr-in 200 list fs-in 37 list fd-in 509 list fa-in 2 list fb-in 15 list fil-in 51 list as-in 81 list ad-in 11 list ar-in 207 list aa-in 6 list amp-in 94 pd-0.46-7/doc/7.stuff/synth/preset2.txt0000664000175000017500000000027712160204055015730 0ustar mspmsplist 2nd-in 1200 list q-in 0.87 list fr-in 200 list fs-in 37 list fd-in 509 list fa-in 2 list fb-in 39 list fil-in 51 list as-in 63 list ad-in 1631 list ar-in 207 list aa-in 6 list amp-in 90 pd-0.46-7/doc/7.stuff/synth/numset.pd0000664000175000017500000000123512160204055015436 0ustar mspmsp#N canvas 672 25 448 396 10; #X obj 11 240 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 0 0 10 -262144 -1 -1 0 256; #X obj 11 262 outlet; #X obj 78 267 s \$1-out; #X obj 189 49 r \$1-in; #X obj 191 130 r \$2-in; #X obj 191 177 route \$1 -record-; #X obj 191 205 f; #X obj 245 289 pack s 0; #X obj 248 203 b; #X obj 245 340 s \$2-out; #X msg 245 315 add list \$1 \$2; #X obj 248 228 symbol \$1-in; #X connect 0 0 1 0; #X connect 0 0 2 0; #X connect 0 0 7 1; #X connect 3 0 0 0; #X connect 4 0 5 0; #X connect 5 0 6 0; #X connect 5 1 8 0; #X connect 6 0 0 0; #X connect 7 0 10 0; #X connect 8 0 11 0; #X connect 10 0 9 0; #X connect 11 0 7 0; #X coords 0 0 1 1 80 24 1; pd-0.46-7/doc/7.stuff/synth/1.poly.synth.pd0000664000175000017500000002025512160204055016414 0ustar mspmsp#N canvas 232 162 657 719 12; #X floatatom 424 666 0 0 100 0 - - -; #N canvas 269 205 698 344 output 0; #X obj 388 156 t b; #X obj 388 105 f; #X obj 388 54 inlet; #X obj 388 181 f; #X msg 482 174 0; #X msg 388 79 bang; #X obj 388 130 moses 1; #X obj 482 149 t b f; #X obj 444 111 moses 1; #X obj 91 148 dbtorms; #X obj 444 86 r master-lvl; #X obj 91 48 r master-lvl; #X obj 388 207 s master-lvl; #X obj 28 169 inlet~; #X obj 213 195 inlet; #X obj 229 218 s master-lvl; #X msg 101 72 set \$1; #X obj 101 98 outlet; #X msg 213 241 \; pd dsp 1; #X obj 91 201 line~; #X obj 31 219 *~; #X obj 31 247 dac~; #X obj 91 173 pack 0 50; #X text 17 149 audio in; #X obj 28 194 hip~ 1; #X connect 0 0 3 0; #X connect 1 0 6 0; #X connect 2 0 5 0; #X connect 3 0 12 0; #X connect 4 0 12 0; #X connect 5 0 1 0; #X connect 6 0 0 0; #X connect 6 1 7 0; #X connect 7 0 4 0; #X connect 8 1 3 1; #X connect 9 0 22 0; #X connect 10 0 1 1; #X connect 10 0 8 0; #X connect 11 0 9 0; #X connect 11 0 16 0; #X connect 13 0 24 0; #X connect 14 0 15 0; #X connect 14 0 18 0; #X connect 16 0 17 0; #X connect 19 0 20 1; #X connect 20 0 21 0; #X connect 20 0 21 1; #X connect 22 0 19 0; #X connect 24 0 20 0; #X restore 386 690 pd output; #X msg 462 666 MUTE; #X obj 16 382 unpack; #X obj 16 299 notein; #X obj 16 327 pack; #X obj 329 213 numset amp x; #X obj 329 242 numset aa x; #X obj 329 329 numset ar x; #X obj 329 271 numset ad x; #X obj 329 300 numset as x; #N canvas 248 85 884 761 synth 0; #X obj 114 588 synthvoice; #X obj 114 561 synthvoice; #X obj 114 534 synthvoice; #X obj 114 507 synthvoice; #X obj 114 480 synthvoice; #X obj 114 453 synthvoice; #X obj 114 426 synthvoice; #X obj 114 399 synthvoice; #X obj 40 91 t b f; #X obj 22 185 f; #X obj 44 130 + 1; #X obj 44 158 mod 1e+06; #X obj 317 670 outlet~; #X obj 45 24 r syn-note; #X obj 454 25 r syn-noteon; #X text 445 652 todo: field to stamp note for later messages; #X obj 22 212 + 1e+06; #X obj 55 239 makenote; #X obj 109 309 moses 1e+06; #X obj 26 352 r all-off; #X msg 26 377 stop; #X obj 196 368 route 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16; #X obj 317 644 synthvoice; #X obj 317 617 synthvoice; #X obj 317 590 synthvoice; #X obj 317 563 synthvoice; #X obj 317 536 synthvoice; #X obj 317 509 synthvoice; #X obj 317 482 synthvoice; #X obj 317 455 synthvoice; #X obj 55 279 poly 16 1; #X obj 45 54 unpack 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0; #X obj 455 51 unpack 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0; #X obj 196 339 pack 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0; #X connect 0 0 29 0; #X connect 1 0 0 0; #X connect 2 0 1 0; #X connect 3 0 2 0; #X connect 4 0 3 0; #X connect 5 0 4 0; #X connect 6 0 5 0; #X connect 7 0 6 0; #X connect 8 0 9 0; #X connect 8 1 33 2; #X connect 9 0 10 0; #X connect 9 0 16 0; #X connect 10 0 11 0; #X connect 11 0 9 1; #X connect 13 0 31 0; #X connect 14 0 32 0; #X connect 16 0 17 0; #X connect 17 0 30 0; #X connect 17 1 30 1; #X connect 18 0 33 2; #X connect 19 0 20 0; #X connect 20 0 30 0; #X connect 21 0 7 1; #X connect 21 1 6 1; #X connect 21 2 5 1; #X connect 21 3 4 1; #X connect 21 4 3 1; #X connect 21 5 2 1; #X connect 21 6 1 1; #X connect 21 7 0 1; #X connect 21 8 29 1; #X connect 21 9 28 1; #X connect 21 10 27 1; #X connect 21 11 26 1; #X connect 21 12 25 1; #X connect 21 13 24 1; #X connect 21 14 23 1; #X connect 21 15 22 1; #X connect 22 0 12 0; #X connect 23 0 22 0; #X connect 24 0 23 0; #X connect 25 0 24 0; #X connect 26 0 25 0; #X connect 27 0 26 0; #X connect 28 0 27 0; #X connect 29 0 28 0; #X connect 30 0 33 0; #X connect 30 1 18 0; #X connect 30 2 33 1; #X connect 31 0 8 0; #X connect 31 1 17 1; #X connect 31 2 17 2; #X connect 31 3 33 3; #X connect 31 4 33 4; #X connect 31 5 33 5; #X connect 31 6 33 6; #X connect 31 7 33 7; #X connect 31 8 33 8; #X connect 31 9 33 9; #X connect 31 10 33 10; #X connect 31 11 33 11; #X connect 31 12 33 12; #X connect 31 13 33 13; #X connect 31 14 33 14; #X connect 31 15 33 15; #X connect 31 16 33 16; #X connect 32 0 30 0; #X connect 32 1 30 1; #X connect 32 2 33 3; #X connect 32 3 33 4; #X connect 32 4 33 5; #X connect 32 5 33 6; #X connect 32 6 33 7; #X connect 32 7 33 8; #X connect 32 8 33 9; #X connect 32 9 33 10; #X connect 32 10 33 11; #X connect 32 11 33 12; #X connect 32 12 33 13; #X connect 32 13 33 14; #X connect 32 14 33 15; #X connect 32 15 33 16; #X connect 33 0 21 0; #X restore 386 640 pd synth; #X obj 24 351 r syn-midinoteon; #X obj 16 649 s syn-noteon; #N canvas 0 0 690 415 tables 0; #X msg 107 49 bang; #X obj 107 78 t b b; #X obj 159 142 f; #X obj 197 142 + 1; #X msg 181 115 0; #X obj 107 107 until; #X obj 161 177 t f f; #X obj 109 210 mtof; #X obj 90 177 sel 129; #X obj 109 237 tabwrite mtof; #X text 48 15 patch to regenerate the mtof table; #N canvas 0 0 450 300 graph2 0; #X array mtof 130 float 1; #A 0 8.1758 8.66196 9.17702 9.72272 10.3009 10.9134 11.5623 12.2499 12.9783 13.75 14.5676 15.4339 16.3516 17.3239 18.354 19.4454 20.6017 21.8268 23.1247 24.4997 25.9565 27.5 29.1352 30.8677 32.7032 34.6478 36.7081 38.8909 41.2034 43.6535 46.2493 48.9994 51.9131 55 58.2705 61.7354 65.4064 69.2957 73.4162 77.7817 82.4069 87.3071 92.4986 97.9989 103.826 110 116.541 123.471 130.813 138.591 146.832 155.563 164.814 174.614 184.997 195.998 207.652 220 233.082 246.942 261.626 277.183 293.665 311.127 329.628 349.228 369.994 391.995 415.305 440 466.164 493.883 523.251 554.365 587.33 622.254 659.255 698.456 739.989 783.991 830.609 880 932.328 987.767 1046.5 1108.73 1174.66 1244.51 1318.51 1396.91 1479.98 1567.98 1661.22 1760 1864.66 1975.53 2093 2217.46 2349.32 2489.02 2637.02 2793.83 2959.96 3135.96 3322.44 3520 3729.31 3951.07 4186.01 4434.92 4698.64 4978.03 5274.04 5587.65 5919.91 6271.93 6644.88 7040 7458.62 7902.13 8372.02 8869.84 9397.27 9956.06 10548.1 11175.3 11839.8 12543.9 13289.8 14080; #X coords 0 12000 130 0 200 100 1; #X restore 381 116 graph; #X text 391 224 ------ 130 samples ------; #X text 590 209 0; #X text 592 109 12000; #X connect 0 0 1 0; #X connect 1 0 5 0; #X connect 1 1 4 0; #X connect 2 0 3 0; #X connect 2 0 6 0; #X connect 2 0 8 0; #X connect 3 0 2 1; #X connect 4 0 2 1; #X connect 5 0 2 0; #X connect 6 0 7 0; #X connect 6 1 9 1; #X connect 7 0 9 0; #X connect 8 0 5 1; #X restore 186 132 pd tables; #X obj 25 117 metro 500; #X floatatom 67 178 5 0 0 0 - - -; #X obj 25 203 makenote 64 250; #X obj 27 229 pack; #X obj 27 253 s syn-midinoteon; #X obj 25 98 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X obj 329 358 numset fil x; #X obj 329 387 numset fb x; #X obj 329 416 numset fa x; #X obj 329 445 numset fd x; #X obj 329 474 numset fs x; #X obj 329 503 numset fr x; #X obj 329 532 numset q x; #X floatatom 101 96 5 0 0 0 - - -; #X floatatom 155 176 5 0 0 0 - - -; #X floatatom 115 149 5 0 0 0 - - -; #X obj 25 178 + 24; #X obj 25 149 random 48; #X obj 329 15 preset preset1 x; #X obj 329 62 preset preset2 x; #X obj 329 108 preset preset3 x; #X obj 329 155 preset preset4 x; #X obj 330 561 numset 2nd x; #X obj 16 626 pack 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0; #X text 451 219 amplitude; #X text 440 246 amp attack time; #X text 445 279 amp decay time; #X text 448 305 amp sustain level (%); #X text 448 331 amp release time; #X text 454 362 filter sweep; #X text 445 392 filter base pitch; #X text 444 424 filter attack time; #X text 444 450 filter decay time; #X text 448 480 filter sustain; #X text 448 507 filter release time; #X text 453 535 q; #X text 450 566 2nd osc detune; #X text 444 596 2nd osc amp (%); #X text 508 666 OUTPUT LEVEL; #X text 41 14 polyphonic synth with; #X text 40 37 voice presets; #X text 21 74 random-note tester; #X obj 330 590 numset 2pc x; #X connect 0 0 1 1; #X connect 1 0 0 0; #X connect 2 0 1 2; #X connect 3 0 38 0; #X connect 3 1 38 1; #X connect 4 0 5 0; #X connect 4 1 5 1; #X connect 5 0 3 0; #X connect 6 0 38 2; #X connect 7 0 38 3; #X connect 8 0 38 6; #X connect 9 0 38 4; #X connect 10 0 38 5; #X connect 11 0 1 0; #X connect 12 0 3 0; #X connect 15 0 32 0; #X connect 16 0 31 1; #X connect 17 0 18 0; #X connect 17 1 18 1; #X connect 18 0 19 0; #X connect 20 0 15 0; #X connect 21 0 38 7; #X connect 22 0 38 8; #X connect 23 0 38 9; #X connect 24 0 38 10; #X connect 25 0 38 11; #X connect 26 0 38 12; #X connect 27 0 38 13; #X connect 28 0 15 1; #X connect 29 0 17 2; #X connect 30 0 32 1; #X connect 31 0 17 0; #X connect 32 0 31 0; #X connect 37 0 38 14; #X connect 38 0 13 0; #X connect 57 0 38 15; pd-0.46-7/doc/7.stuff/synth/synthvoice.pd0000664000175000017500000000317212160204055016320 0ustar mspmsp#N canvas 218 43 728 639 12; #X obj 61 616 outlet~; #X obj 363 475 *~; #X obj 166 328 *~; #X obj 166 351 *~; #X obj 40 325 mtof; #X obj 180 52 inlet; #X obj 61 565 inlet~; #X obj 61 592 +~; #X obj 473 266 gadsr; #X obj 166 265 gadsr; #X obj 106 115 dbtorms; #X obj 106 141 sqrt; #X obj 106 166 sqrt; #X obj 461 322 +~; #X obj 461 348 tabread4~ mtof; #X obj 405 464 vcf~; #X obj 42 416 phasor~; #X obj 106 349 + 0.3; #X obj 106 377 phasor~; #X obj 42 455 +~; #X obj 180 75 unpack 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0; #X text 173 19 on/off pitch amp a d s r filt filt-bias a d s r filt-q 2nd-interval 2nd-percentage; #X obj 106 281 +; #X obj 106 319 mtof; #X obj 120 414 *~ 1; #X obj 345 391 * 0.01; #X obj 133 241 * 0.01; #X connect 1 0 7 1; #X connect 2 0 3 0; #X connect 2 0 3 1; #X connect 3 0 1 0; #X connect 4 0 16 0; #X connect 5 0 20 0; #X connect 6 0 7 0; #X connect 7 0 0 0; #X connect 8 0 13 1; #X connect 9 0 2 0; #X connect 9 0 2 1; #X connect 10 0 11 0; #X connect 11 0 12 0; #X connect 12 0 9 1; #X connect 13 0 14 0; #X connect 14 0 15 1; #X connect 15 0 1 1; #X connect 16 0 19 0; #X connect 17 0 18 0; #X connect 18 0 24 0; #X connect 19 0 15 0; #X connect 20 0 9 0; #X connect 20 0 8 0; #X connect 20 1 4 0; #X connect 20 1 22 0; #X connect 20 2 10 0; #X connect 20 3 9 2; #X connect 20 4 9 3; #X connect 20 5 9 4; #X connect 20 6 9 5; #X connect 20 7 8 1; #X connect 20 8 13 0; #X connect 20 9 8 2; #X connect 20 10 8 3; #X connect 20 11 8 4; #X connect 20 12 8 5; #X connect 20 13 15 2; #X connect 20 14 26 0; #X connect 20 15 25 0; #X connect 22 0 23 0; #X connect 23 0 17 0; #X connect 24 0 19 1; #X connect 25 0 24 1; #X connect 26 0 22 1; pd-0.46-7/doc/7.stuff/tools/0000775000175000017500000000000012520221347013573 5ustar mspmsppd-0.46-7/doc/7.stuff/tools/load-meter.pd0000664000175000017500000000076412160204055016155 0ustar mspmsp#N canvas 161 261 299 317 12; #X floatatom 118 256 0 0 0 0 - - -; #X obj 118 168 cputime; #X obj 118 28 loadbang; #X obj 118 112 metro 1000; #X msg 118 56 1; #X floatatom 118 84 0 0 0 0 - - -; #X obj 118 140 t b b; #X obj 118 228 * 0.1; #X obj 118 197 int; #X text 163 84 <-- on/off; #X text 51 284 CPU load in percent; #X connect 1 0 8 0; #X connect 2 0 4 0; #X connect 3 0 6 0; #X connect 4 0 5 0; #X connect 5 0 3 0; #X connect 6 0 1 0; #X connect 6 1 1 1; #X connect 7 0 0 0; #X connect 8 0 7 0; pd-0.46-7/doc/7.stuff/tools/testtone16.pd0000664000175000017500000004607112160204055016141 0ustar mspmsp#N canvas 117 205 706 319 12; #X floatatom 86 283 3 0 0 0 - - -; #X obj 36 232 notein; #X obj 36 258 stripnote; #X floatatom 36 283 3 0 0 0 - - -; #X text 224 229 MIDI OUT; #X text 36 208 MIDI IN; #X floatatom 171 282 3 0 0 0 - - -; #X floatatom 132 282 3 0 0 0 - - -; #X obj 132 257 ctlin; #N canvas 0 0 484 446 midi 0; #X obj 96 65 inlet; #X obj 96 262 noteout; #X floatatom 96 92 0 0 0 0 - - -; #X obj 338 113 loadbang; #X obj 96 184 metro; #X obj 96 236 makenote; #X floatatom 189 166 0 0 0 0 - - -; #X obj 96 210 f; #X floatatom 145 166 0 0 0 0 - - -; #X floatatom 233 166 0 0 0 0 - - -; #X floatatom 276 166 0 0 0 0 - - -; #X msg 338 148 500; #X msg 370 148 60; #X msg 399 148 64; #X msg 427 148 250; #X text 144 145 rate; #X text 187 145 pitch; #X text 232 145 vel; #X text 268 146 length; #X obj 230 257 ctlout 1; #X floatatom 230 228 0 0 0 0 - - -; #X connect 0 0 2 0; #X connect 2 0 4 0; #X connect 3 0 11 0; #X connect 3 0 12 0; #X connect 3 0 13 0; #X connect 3 0 14 0; #X connect 4 0 7 0; #X connect 5 0 1 0; #X connect 5 1 1 1; #X connect 6 0 7 1; #X connect 7 0 5 0; #X connect 8 0 4 1; #X connect 9 0 5 1; #X connect 10 0 5 2; #X connect 11 0 8 0; #X connect 12 0 6 0; #X connect 13 0 9 0; #X connect 14 0 10 0; #X connect 20 0 19 0; #X restore 224 279 pd midi; #X floatatom 170 107 3 0 0 0 - tone-vu1 -; #X floatatom 197 107 3 0 0 0 - tone-vu2 -; #X obj 170 144 tgl 20 0 tone-ch1 tone-ch1 1 5 -8 0 12 -262144 -1 -1 1 1; #X obj 195 144 tgl 20 0 tone-ch2 tone-ch2 2 5 -8 0 12 -262144 -1 -1 1 1; #X obj 224 253 tgl 20 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 1; #N canvas 0 0 662 344 more 0; #X floatatom 42 209 0 0 0 0 - - -; #X obj 42 183 f; #X obj 79 183 + 1; #X obj 42 150 metro 1000; #X obj 42 123 tgl 20 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 1 ; #X msg 264 142 \; pd restart-audio; #X text 24 30 this window has various wierd debugging stuff...; #X text 218 97 ALSA gets twisted after a few; #X text 216 118 hours sometimes... use this to fix:; #X text 22 74 see if Pd's time; #X text 22 93 measurement works:; #X obj 516 159 adc~; #X obj 515 206 print~; #X obj 524 183 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X connect 1 0 2 0; #X connect 1 0 0 0; #X connect 2 0 1 1; #X connect 3 0 1 0; #X connect 4 0 3 0; #X connect 11 0 12 0; #X connect 13 0 12 0; #X restore 584 272 pd more; #X obj 228 144 tgl 20 0 tone-ch3 tone-ch3 3 5 -8 0 12 -262144 -1 -1 1 1; #X obj 253 144 tgl 20 0 tone-ch4 tone-ch4 4 5 -8 0 12 -262144 -1 -1 1 1; #X obj 286 144 tgl 20 0 tone-ch5 tone-ch5 5 5 -8 0 12 -262144 -1 -1 1 1; #X obj 311 144 tgl 20 0 tone-ch6 tone-ch6 6 5 -8 0 12 -262144 -1 -1 1 1; #X obj 647 132 bng 15 250 50 0 tone-all empty ALL 20 8 0 12 -262144 -1 -1; #X obj 647 153 bng 15 250 50 0 tone-none empty NONE 20 8 0 12 -262144 -1 -1; #X floatatom 227 107 3 0 0 0 - tone-vu3 -; #X floatatom 254 107 3 0 0 0 - tone-vu4 -; #X floatatom 285 107 3 0 0 0 - tone-vu5 -; #X floatatom 312 107 3 0 0 0 - tone-vu6 -; #X floatatom 345 107 3 0 0 0 - tone-vu7 -; #X floatatom 372 107 3 0 0 0 - tone-vu8 -; #X obj 345 144 tgl 20 0 tone-ch7 tone-ch7 7 5 -8 0 12 -262144 -1 -1 1 1; #X obj 370 144 tgl 20 0 tone-ch8 tone-ch8 8 5 -8 0 12 -262144 -1 -1 1 1; #N canvas 637 91 321 422 audio 0; #X obj 25 303 s~ tone-mon; #X obj 25 277 line~; #X obj 25 249 pack 0 50; #X obj 25 223 r tone-monitor; #X obj 28 140 * 5; #X obj 28 165 s tone-hip; #X obj 28 114 r tone-hipass; #N canvas 275 246 482 404 glue+loadbang 0; #X obj 8 20 loadbang; #X obj 175 18 r tone-all; #X obj 285 16 r tone-none; #X msg 8 48 \; pd dsp 1 \; tone-pitch 69 \; tone-radio 2 \; tone-radio-set set 2 \; tone-type 1 \; tone-type-set 1 \; tone-all 1 \; tone-hipass-set set 1 \;; #X msg 175 46 \; tone-ch1 1 \; tone-ch2 1 \; tone-ch3 1 \; tone-ch4 1 \; tone-ch5 1 \; tone-ch6 1 \; tone-ch7 1 \; tone-ch8 1 \; tone-ch9 1 \; tone-ch10 1 \; tone-ch11 1 \; tone-ch12 1 \; tone-ch13 1 \; tone-ch14 1 \; tone-ch15 1 \; tone-ch16 1; #X msg 285 47 \; tone-ch1 0 \; tone-ch2 0 \; tone-ch3 0 \; tone-ch4 0 \; tone-ch5 0 \; tone-ch6 0 \; tone-ch7 0 \; tone-ch8 0 \; tone-ch9 0 \; tone-ch10 0 \; tone-ch11 0 \; tone-ch12 0 \; tone-ch13 0 \; tone-ch14 0 \; tone-ch15 0 \; tone-ch16 0; #X connect 0 0 3 0; #X connect 1 0 4 0; #X connect 2 0 5 0; #X restore 22 332 pd glue+loadbang; #N canvas 731 146 468 559 tone-generator 0; #X obj 22 187 osc~; #X obj 22 81 mtof; #X floatatom 22 58 0 0 0 0 - - -; #X floatatom 22 103 0 0 0 0 - - -; #X obj 22 163 sig~; #X obj 22 33 r tone-pitch; #X obj 119 179 noise~; #X obj 65 249 +~; #X obj 282 140 - 1; #X obj 282 172 * -1; #X obj 191 228 line~; #X obj 281 229 line~; #X obj 22 211 *~; #X obj 119 210 *~; #X msg 191 199 \$1 20; #X msg 281 200 \$1 20; #X floatatom 273 109 0 0 0 0 - - -; #X obj 64 504 *~; #X obj 86 477 line~; #X obj 86 450 pack 0 50; #X floatatom 201 365 0 0 0 0 - - -; #X obj 86 423 dbtorms; #X obj 64 530 s~ tone-osc; #X obj 201 282 r tone-radio; #X obj 201 310 sel 0 1 2; #X msg 270 333 0; #X msg 201 335 80; #X msg 234 335 60; #X obj 273 86 r tone-type; #X obj 89 359 r tone-level; #X obj 178 453 s tone-level-set; #X msg 177 428 set \$1; #X obj 329 452 s tone-radio-set; #X obj 327 369 sel 80 60 0; #X msg 327 394 0; #X msg 360 394 1; #X msg 393 394 2; #X msg 329 426 set \$1; #X msg 423 394 2; #X obj 72 89 s tone-pitch-set; #X msg 72 66 set \$1; #X obj 177 29 r tone-hz; #X msg 75 117 set \$1; #X obj 75 140 s tone-hz-set; #X obj 177 55 ftom; #X connect 0 0 12 0; #X connect 1 0 3 0; #X connect 2 0 1 0; #X connect 2 0 40 0; #X connect 3 0 4 0; #X connect 3 0 42 0; #X connect 4 0 0 0; #X connect 5 0 2 0; #X connect 6 0 13 0; #X connect 7 0 17 0; #X connect 8 0 9 0; #X connect 9 0 15 0; #X connect 10 0 12 1; #X connect 11 0 13 1; #X connect 12 0 7 0; #X connect 13 0 7 1; #X connect 14 0 10 0; #X connect 15 0 11 0; #X connect 16 0 8 0; #X connect 16 0 14 0; #X connect 17 0 22 0; #X connect 18 0 17 1; #X connect 19 0 18 0; #X connect 20 0 21 0; #X connect 20 0 31 0; #X connect 21 0 19 0; #X connect 23 0 24 0; #X connect 24 0 26 0; #X connect 24 1 27 0; #X connect 24 2 25 0; #X connect 25 0 20 0; #X connect 26 0 20 0; #X connect 27 0 20 0; #X connect 28 0 16 0; #X connect 29 0 31 0; #X connect 29 0 21 0; #X connect 31 0 30 0; #X connect 33 0 34 0; #X connect 33 1 35 0; #X connect 33 2 36 0; #X connect 33 3 38 0; #X connect 34 0 37 0; #X connect 35 0 37 0; #X connect 36 0 37 0; #X connect 37 0 32 0; #X connect 38 0 37 0; #X connect 40 0 39 0; #X connect 41 0 44 0; #X connect 42 0 43 0; #X connect 44 0 2 0; #X restore 24 68 pd tone-generator; #N canvas 184 0 1014 892 assigns 0; #X obj 12 71 hip~ 5; #X obj 20 122 int; #X obj 20 96 env~ 8192; #X obj 12 18 adc~ 1; #X obj 22 171 r~ tone-mon; #X obj 31 306 line~; #X obj 12 196 *~; #X obj 31 279 pack 0 50; #X obj 31 253 r tone-ch1; #X obj 22 226 r~ tone-osc; #X obj 22 331 *~; #X obj 12 386 dac~ 1; #X obj 12 361 +~; #X obj 20 44 r tone-hip; #X obj 132 70 hip~ 5; #X obj 140 121 int; #X obj 140 95 env~ 8192; #X obj 142 170 r~ tone-mon; #X obj 151 305 line~; #X obj 132 195 *~; #X obj 151 278 pack 0 50; #X obj 142 225 r~ tone-osc; #X obj 142 330 *~; #X obj 132 360 +~; #X obj 140 43 r tone-hip; #X obj 132 17 adc~ 2; #X obj 132 385 dac~ 2; #X obj 151 252 r tone-ch2; #X obj 254 72 hip~ 5; #X obj 262 123 int; #X obj 262 97 env~ 8192; #X obj 264 172 r~ tone-mon; #X obj 273 307 line~; #X obj 254 197 *~; #X obj 273 280 pack 0 50; #X obj 264 227 r~ tone-osc; #X obj 264 332 *~; #X obj 254 362 +~; #X obj 262 45 r tone-hip; #X obj 370 68 hip~ 5; #X obj 378 119 int; #X obj 378 93 env~ 8192; #X obj 380 168 r~ tone-mon; #X obj 389 303 line~; #X obj 370 193 *~; #X obj 389 276 pack 0 50; #X obj 380 223 r~ tone-osc; #X obj 380 328 *~; #X obj 370 358 +~; #X obj 378 41 r tone-hip; #X obj 487 68 hip~ 5; #X obj 495 119 int; #X obj 495 93 env~ 8192; #X obj 497 168 r~ tone-mon; #X obj 506 303 line~; #X obj 487 193 *~; #X obj 506 276 pack 0 50; #X obj 497 223 r~ tone-osc; #X obj 497 328 *~; #X obj 487 358 +~; #X obj 495 41 r tone-hip; #X obj 607 67 hip~ 5; #X obj 615 118 int; #X obj 615 92 env~ 8192; #X obj 617 167 r~ tone-mon; #X obj 626 302 line~; #X obj 607 192 *~; #X obj 626 275 pack 0 50; #X obj 617 222 r~ tone-osc; #X obj 617 327 *~; #X obj 607 357 +~; #X obj 615 40 r tone-hip; #X obj 254 19 adc~ 3; #X obj 370 15 adc~ 4; #X obj 487 15 adc~ 5; #X obj 607 14 adc~ 6; #X obj 273 254 r tone-ch3; #X obj 389 249 r tone-ch4; #X obj 506 250 r tone-ch5; #X obj 626 249 r tone-ch6; #X obj 254 387 dac~ 3; #X obj 369 382 dac~ 4; #X obj 487 383 dac~ 5; #X obj 607 382 dac~ 6; #X obj 725 72 hip~ 5; #X obj 733 123 int; #X obj 733 97 env~ 8192; #X obj 735 172 r~ tone-mon; #X obj 744 307 line~; #X obj 725 197 *~; #X obj 744 280 pack 0 50; #X obj 735 227 r~ tone-osc; #X obj 735 332 *~; #X obj 725 362 +~; #X obj 733 45 r tone-hip; #X obj 845 71 hip~ 5; #X obj 853 122 int; #X obj 853 96 env~ 8192; #X obj 855 171 r~ tone-mon; #X obj 864 306 line~; #X obj 845 196 *~; #X obj 864 279 pack 0 50; #X obj 855 226 r~ tone-osc; #X obj 855 331 *~; #X obj 845 361 +~; #X obj 853 44 r tone-hip; #X obj 725 19 adc~ 7; #X obj 845 18 adc~ 8; #X obj 725 387 dac~ 7; #X obj 845 386 dac~ 8; #X obj 744 254 r tone-ch7; #X obj 864 253 r tone-ch8; #X obj 20 148 s tone-vu1; #X obj 140 147 s tone-vu2; #X obj 262 149 s tone-vu3; #X obj 378 145 s tone-vu4; #X obj 495 145 s tone-vu5; #X obj 615 144 s tone-vu6; #X obj 733 149 s tone-vu7; #X obj 853 148 s tone-vu8; #X obj 11 482 hip~ 5; #X obj 19 533 int; #X obj 19 507 env~ 8192; #X obj 21 582 r~ tone-mon; #X obj 30 717 line~; #X obj 11 607 *~; #X obj 30 690 pack 0 50; #X obj 21 637 r~ tone-osc; #X obj 21 742 *~; #X obj 11 772 +~; #X obj 19 455 r tone-hip; #X obj 131 481 hip~ 5; #X obj 139 532 int; #X obj 139 506 env~ 8192; #X obj 141 581 r~ tone-mon; #X obj 150 716 line~; #X obj 131 606 *~; #X obj 150 689 pack 0 50; #X obj 141 636 r~ tone-osc; #X obj 141 741 *~; #X obj 131 771 +~; #X obj 139 454 r tone-hip; #X obj 253 483 hip~ 5; #X obj 261 534 int; #X obj 261 508 env~ 8192; #X obj 263 583 r~ tone-mon; #X obj 272 718 line~; #X obj 253 608 *~; #X obj 272 691 pack 0 50; #X obj 263 638 r~ tone-osc; #X obj 263 743 *~; #X obj 253 773 +~; #X obj 261 456 r tone-hip; #X obj 369 479 hip~ 5; #X obj 377 530 int; #X obj 377 504 env~ 8192; #X obj 379 579 r~ tone-mon; #X obj 388 714 line~; #X obj 369 604 *~; #X obj 388 687 pack 0 50; #X obj 379 634 r~ tone-osc; #X obj 379 739 *~; #X obj 369 769 +~; #X obj 377 452 r tone-hip; #X obj 486 479 hip~ 5; #X obj 494 530 int; #X obj 494 504 env~ 8192; #X obj 496 579 r~ tone-mon; #X obj 505 714 line~; #X obj 486 604 *~; #X obj 505 687 pack 0 50; #X obj 496 634 r~ tone-osc; #X obj 496 739 *~; #X obj 486 769 +~; #X obj 494 452 r tone-hip; #X obj 606 478 hip~ 5; #X obj 614 529 int; #X obj 614 503 env~ 8192; #X obj 616 578 r~ tone-mon; #X obj 625 713 line~; #X obj 606 603 *~; #X obj 625 686 pack 0 50; #X obj 616 633 r~ tone-osc; #X obj 616 738 *~; #X obj 606 768 +~; #X obj 614 451 r tone-hip; #X obj 724 483 hip~ 5; #X obj 732 534 int; #X obj 732 508 env~ 8192; #X obj 734 583 r~ tone-mon; #X obj 743 718 line~; #X obj 724 608 *~; #X obj 743 691 pack 0 50; #X obj 734 638 r~ tone-osc; #X obj 734 743 *~; #X obj 724 773 +~; #X obj 732 456 r tone-hip; #X obj 844 482 hip~ 5; #X obj 852 533 int; #X obj 852 507 env~ 8192; #X obj 854 582 r~ tone-mon; #X obj 863 717 line~; #X obj 844 607 *~; #X obj 863 690 pack 0 50; #X obj 854 637 r~ tone-osc; #X obj 854 742 *~; #X obj 844 772 +~; #X obj 852 455 r tone-hip; #X obj 11 429 adc~ 9; #X obj 131 428 adc~ 10; #X obj 253 430 adc~ 11; #X obj 369 426 adc~ 12; #X obj 486 426 adc~ 13; #X obj 606 425 adc~ 14; #X obj 724 430 adc~ 15; #X obj 844 429 adc~ 16; #X obj 11 797 dac~ 9; #X obj 131 796 dac~ 10; #X obj 253 798 dac~ 11; #X obj 368 793 dac~ 12; #X obj 486 794 dac~ 13; #X obj 606 793 dac~ 14; #X obj 724 798 dac~ 15; #X obj 844 797 dac~ 16; #X obj 19 559 s tone-vu9; #X obj 139 558 s tone-vu10; #X obj 261 560 s tone-vu11; #X obj 377 556 s tone-vu12; #X obj 494 556 s tone-vu13; #X obj 614 555 s tone-vu14; #X obj 732 560 s tone-vu15; #X obj 852 559 s tone-vu16; #X obj 30 664 r tone-ch9; #X obj 150 663 r tone-ch10; #X obj 272 665 r tone-ch11; #X obj 388 660 r tone-ch12; #X obj 505 661 r tone-ch13; #X obj 625 660 r tone-ch14; #X obj 743 665 r tone-ch15; #X obj 863 664 r tone-ch16; #X connect 0 0 6 0; #X connect 0 0 2 0; #X connect 1 0 112 0; #X connect 2 0 1 0; #X connect 3 0 0 0; #X connect 4 0 6 1; #X connect 5 0 10 1; #X connect 6 0 12 0; #X connect 7 0 5 0; #X connect 8 0 7 0; #X connect 9 0 10 0; #X connect 10 0 12 1; #X connect 12 0 11 0; #X connect 13 0 0 1; #X connect 14 0 19 0; #X connect 14 0 16 0; #X connect 15 0 113 0; #X connect 16 0 15 0; #X connect 17 0 19 1; #X connect 18 0 22 1; #X connect 19 0 23 0; #X connect 20 0 18 0; #X connect 21 0 22 0; #X connect 22 0 23 1; #X connect 23 0 26 0; #X connect 24 0 14 1; #X connect 25 0 14 0; #X connect 27 0 20 0; #X connect 28 0 33 0; #X connect 28 0 30 0; #X connect 29 0 114 0; #X connect 30 0 29 0; #X connect 31 0 33 1; #X connect 32 0 36 1; #X connect 33 0 37 0; #X connect 34 0 32 0; #X connect 35 0 36 0; #X connect 36 0 37 1; #X connect 37 0 80 0; #X connect 38 0 28 1; #X connect 39 0 44 0; #X connect 39 0 41 0; #X connect 40 0 115 0; #X connect 41 0 40 0; #X connect 42 0 44 1; #X connect 43 0 47 1; #X connect 44 0 48 0; #X connect 45 0 43 0; #X connect 46 0 47 0; #X connect 47 0 48 1; #X connect 48 0 81 0; #X connect 49 0 39 1; #X connect 50 0 55 0; #X connect 50 0 52 0; #X connect 51 0 116 0; #X connect 52 0 51 0; #X connect 53 0 55 1; #X connect 54 0 58 1; #X connect 55 0 59 0; #X connect 56 0 54 0; #X connect 57 0 58 0; #X connect 58 0 59 1; #X connect 59 0 82 0; #X connect 60 0 50 1; #X connect 61 0 66 0; #X connect 61 0 63 0; #X connect 62 0 117 0; #X connect 63 0 62 0; #X connect 64 0 66 1; #X connect 65 0 69 1; #X connect 66 0 70 0; #X connect 67 0 65 0; #X connect 68 0 69 0; #X connect 69 0 70 1; #X connect 70 0 83 0; #X connect 71 0 61 1; #X connect 72 0 28 0; #X connect 73 0 39 0; #X connect 74 0 50 0; #X connect 75 0 61 0; #X connect 76 0 34 0; #X connect 77 0 45 0; #X connect 78 0 56 0; #X connect 79 0 67 0; #X connect 84 0 89 0; #X connect 84 0 86 0; #X connect 85 0 118 0; #X connect 86 0 85 0; #X connect 87 0 89 1; #X connect 88 0 92 1; #X connect 89 0 93 0; #X connect 90 0 88 0; #X connect 91 0 92 0; #X connect 92 0 93 1; #X connect 93 0 108 0; #X connect 94 0 84 1; #X connect 95 0 100 0; #X connect 95 0 97 0; #X connect 96 0 119 0; #X connect 97 0 96 0; #X connect 98 0 100 1; #X connect 99 0 103 1; #X connect 100 0 104 0; #X connect 101 0 99 0; #X connect 102 0 103 0; #X connect 103 0 104 1; #X connect 104 0 109 0; #X connect 105 0 95 1; #X connect 106 0 84 0; #X connect 107 0 95 0; #X connect 110 0 90 0; #X connect 111 0 101 0; #X connect 120 0 125 0; #X connect 120 0 122 0; #X connect 121 0 224 0; #X connect 122 0 121 0; #X connect 123 0 125 1; #X connect 124 0 128 1; #X connect 125 0 129 0; #X connect 126 0 124 0; #X connect 127 0 128 0; #X connect 128 0 129 1; #X connect 129 0 216 0; #X connect 130 0 120 1; #X connect 131 0 136 0; #X connect 131 0 133 0; #X connect 132 0 225 0; #X connect 133 0 132 0; #X connect 134 0 136 1; #X connect 135 0 139 1; #X connect 136 0 140 0; #X connect 137 0 135 0; #X connect 138 0 139 0; #X connect 139 0 140 1; #X connect 140 0 217 0; #X connect 141 0 131 1; #X connect 142 0 147 0; #X connect 142 0 144 0; #X connect 143 0 226 0; #X connect 144 0 143 0; #X connect 145 0 147 1; #X connect 146 0 150 1; #X connect 147 0 151 0; #X connect 148 0 146 0; #X connect 149 0 150 0; #X connect 150 0 151 1; #X connect 151 0 218 0; #X connect 152 0 142 1; #X connect 153 0 158 0; #X connect 153 0 155 0; #X connect 154 0 227 0; #X connect 155 0 154 0; #X connect 156 0 158 1; #X connect 157 0 161 1; #X connect 158 0 162 0; #X connect 159 0 157 0; #X connect 160 0 161 0; #X connect 161 0 162 1; #X connect 162 0 219 0; #X connect 163 0 153 1; #X connect 164 0 169 0; #X connect 164 0 166 0; #X connect 165 0 228 0; #X connect 166 0 165 0; #X connect 167 0 169 1; #X connect 168 0 172 1; #X connect 169 0 173 0; #X connect 170 0 168 0; #X connect 171 0 172 0; #X connect 172 0 173 1; #X connect 173 0 220 0; #X connect 174 0 164 1; #X connect 175 0 180 0; #X connect 175 0 177 0; #X connect 176 0 229 0; #X connect 177 0 176 0; #X connect 178 0 180 1; #X connect 179 0 183 1; #X connect 180 0 184 0; #X connect 181 0 179 0; #X connect 182 0 183 0; #X connect 183 0 184 1; #X connect 184 0 221 0; #X connect 185 0 175 1; #X connect 186 0 191 0; #X connect 186 0 188 0; #X connect 187 0 230 0; #X connect 188 0 187 0; #X connect 189 0 191 1; #X connect 190 0 194 1; #X connect 191 0 195 0; #X connect 192 0 190 0; #X connect 193 0 194 0; #X connect 194 0 195 1; #X connect 195 0 222 0; #X connect 196 0 186 1; #X connect 197 0 202 0; #X connect 197 0 199 0; #X connect 198 0 231 0; #X connect 199 0 198 0; #X connect 200 0 202 1; #X connect 201 0 205 1; #X connect 202 0 206 0; #X connect 203 0 201 0; #X connect 204 0 205 0; #X connect 205 0 206 1; #X connect 206 0 223 0; #X connect 207 0 197 1; #X connect 208 0 120 0; #X connect 209 0 131 0; #X connect 210 0 142 0; #X connect 211 0 153 0; #X connect 212 0 164 0; #X connect 213 0 175 0; #X connect 214 0 186 0; #X connect 215 0 197 0; #X connect 232 0 126 0; #X connect 233 0 137 0; #X connect 234 0 148 0; #X connect 235 0 159 0; #X connect 236 0 170 0; #X connect 237 0 181 0; #X connect 238 0 192 0; #X connect 239 0 203 0; #X restore 38 387 pd assigns; #X obj 178 87 loadbang; #X obj 178 111 1; #X connect 1 0 0 0; #X connect 2 0 1 0; #X connect 3 0 2 0; #X connect 4 0 5 0; #X connect 6 0 4 0; #X connect 10 0 11 0; #X connect 11 0 4 0; #X restore 584 249 pd audio; #X floatatom 408 108 3 0 0 0 - tone-vu9 -; #X floatatom 435 108 3 0 0 0 - tone-vu10 -; #X floatatom 466 108 3 0 0 0 - tone-vu11 -; #X floatatom 493 108 3 0 0 0 - tone-vu12 -; #X floatatom 524 108 3 0 0 0 - tone-vu13 -; #X floatatom 551 108 3 0 0 0 - tone-vu14 -; #X floatatom 584 108 3 0 0 0 - tone-vu15 -; #X floatatom 611 108 3 0 0 0 - tone-vu16 -; #X obj 408 144 tgl 20 0 tone-ch9 tone-ch9 9 5 -8 0 12 -262144 -1 -1 1 1; #X obj 433 144 tgl 20 0 tone-ch10 tone-ch10 10 5 -8 0 12 -262144 -1 -1 1 1; #X obj 466 144 tgl 20 0 tone-ch11 tone-ch11 11 5 -8 0 12 -262144 -1 -1 1 1; #X obj 491 144 tgl 20 0 tone-ch12 tone-ch12 12 5 -8 0 12 -262144 -1 -1 1 1; #X obj 524 144 tgl 20 0 tone-ch13 tone-ch13 13 5 -8 0 12 -262144 -1 -1 1 1; #X obj 549 144 tgl 20 0 tone-ch14 tone-ch14 14 5 -8 0 12 -262144 -1 -1 1 1; #X obj 583 144 tgl 20 0 tone-ch15 tone-ch15 15 5 -8 0 12 -262144 -1 -1 1 1; #X obj 608 144 tgl 20 0 tone-ch116 tone-ch16 16 5 -8 0 12 -262144 -1 -1 1 1; #X text 235 25 16 channel test tone patch; #X text 316 77 AUTIO INPUT (RMS dB); #X text 337 175 AUDIO OUTPUT ON/OFF; #X text 40 120 OFF; #X text 101 88 noise; #X text 100 105 tone; #X obj 84 90 vradio 15 1 0 2 tone-type tone-type-set empty 0 -6 0 8 -262144 -1 -1 1; #X obj 22 91 vradio 15 1 0 3 tone-radio tone-radio-set empty 0 -6 0 8 -262144 -1 -1 2; #X floatatom 22 144 3 0 100 1 - tone-level-set tone-level; #X floatatom 84 123 5 0 100 1 pitch tone-pitch-set tone-pitch; #X floatatom 84 145 5 0 20000 1 HZ tone-hz-set tone-hz; #X text 48 145 dB; #X text 28 67 TEST TONES; #X obj 265 201 tgl 15 0 tone-monitor set-tone-monitor monitor-inputs 23 8 0 12 -262144 -1 -1 0 1; #X obj 424 202 tgl 15 0 tone-hipass tone-hipass-set input-hipass 23 8 0 12 -262144 -1 -1 1 1; #X text 39 88 80; #X text 39 105 60; #X connect 1 0 2 0; #X connect 1 1 2 1; #X connect 2 0 3 0; #X connect 2 1 0 0; #X connect 8 0 7 0; #X connect 8 1 6 0; #X connect 14 0 9 0; pd-0.46-7/doc/7.stuff/tools/latency.pd0000664000175000017500000001661112222201037015555 0ustar mspmsp#N canvas 78 319 718 504 12; #X floatatom 239 98 4 0 0 0 - - adc-gain; #X text 317 17 latency measurement; #N canvas 31 48 928 842 guts 0; #X obj 292 35 adc~ 1 2 3 4 5 6 7 8; #X obj 318 102 == 1; #X obj 293 126 *~ 0; #X obj 355 128 *~ 0; #X obj 418 129 *~ 0; #X obj 480 131 *~ 0; #X obj 541 134 *~ 0; #X obj 603 136 *~ 0; #X obj 666 137 *~ 0; #X obj 728 139 *~ 0; #X obj 380 104 == 2; #X obj 443 105 == 3; #X obj 505 107 == 4; #X obj 566 110 == 5; #X obj 628 112 == 6; #X obj 691 113 == 7; #X obj 753 115 == 8; #X obj 46 34 loadbang; #X obj 59 153 r inchannel; #X msg 59 177 set \$1; #X obj 59 201 s inchannel-set; #N canvas 0 22 450 300 (subpatch) 0; #X array pulse 120 float 3; #A 0 0 0 0 0 0 0 0 0 0 0 -0 -6.19458e-05 -0.000494103 -0.00165937 -0.00390618 -0.00756153 -0.0129244 -0.0202596 -0.0297923 -0.0417031 -0.0561239 -0.0731343 -0.0927595 -0.114969 -0.139674 -0.166732 -0.195943 -0.227055 -0.259767 -0.293732 -0.328561 -0.363831 -0.39909 -0.433862 -0.467657 -0.499977 -0.530324 -0.558209 -0.583156 -0.604713 -0.622461 -0.636015 -0.645036 -0.649234 -0.648374 -0.642282 -0.630843 -0.614012 -0.591808 -0.564318 -0.531698 -0.494168 -0.452014 -0.405579 -0.355267 -0.301528 -0.244862 -0.185805 -0.124926 -0.0628189 -9.26574e-05 0.0626345 0.124745 0.185628 0.244691 0.301365 0.355113 0.405437 0.451883 0.494051 0.531595 0.56423 0.591735 0.613955 0.630802 0.642256 0.648364 0.649239 0.645055 0.636048 0.622507 0.604771 0.583224 0.558287 0.53041 0.500069 0.467754 0.433963 0.399193 0.363935 0.328665 0.293834 0.259866 0.22715 0.196032 0.166815 0.139751 0.115038 0.0928211 0.0731882 0.0561701 0.0417419 0.0298239 0.0202844 0.012943 0.00757468 0.00391473 0.00166424 0.000496283 6.24961e-05 0 0 0 0 0 0 0 0 0 0; #X coords 0 1 119 -1 200 140 1; #X restore 25 399 graph; #X obj 52 587 t b b; #X obj 123 648 f; #X obj 161 648 + 1; #X obj 52 616 until; #X obj 123 676 t f f; #X obj 46 780 tabwrite pulse; #X obj 50 563 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X msg 143 570 \; pulse const 0; #X msg 140 620 0; #X obj 44 676 sel 100; #X obj 157 780 + 10; #X obj 67 712 * 0.06283; #X obj 615 264 metro 1000; #X obj 615 218 r metro-on; #X obj 614 243 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1 1; #X obj 628 326 vline~; #X obj 627 357 tabread4~ pulse; #X obj 687 31 r inchannel; #X obj 291 186 hip~ 20; #X obj 411 516 *~ 1e+10; #X obj 411 543 clip~ 0 1; #X obj 411 567 *~ 1e+10; #X obj 412 603 lop~ 3; #X obj 413 627 clip~ 0 1; #X msg 355 574 clear; #X msg 629 295 0 \, 12000 10; #X obj 744 359 osc~ 220; #X obj 744 386 *~ 0.03; #X obj 649 526 +~; #X obj 650 581 dac~ 1 2 3 4 5 6 7 8; #X obj 431 268 bp~ 220 0.7; #X obj 693 622 env~ 65536; #X floatatom 693 649 4 0 0 0 - - -; #X floatatom 749 329 5 0 0 0 - - -; #X obj 704 414 +~; #X obj 430 292 rzero~ -1; #X obj 431 317 rzero~ -1; #X obj 431 343 *~ 0.15; #X obj 287 316 rzero~ 1; #X obj 288 341 rzero~ 1; #X obj 45 747 expr -0.5 * (1-cos($f1)) * sin($f1); #X obj 288 292 bp~ 2000 0.7; #X obj 413 465 *~ 20; #X obj 629 382 *~ 0.1; #X obj 332 220 + 100; #X obj 332 245 dbtorms; #X obj 290 246 *~ 1; #X obj 160 281 env~ 65536; #X floatatom 160 308 4 0 0 0 - - -; #X obj 431 370 bonk~; #X obj 431 395 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 412 489 -~ 0.1; #X obj 414 656 -~ 1; #X obj 414 683 *~ -1; #X obj 565 747 phasor~; #X msg 616 714 0; #X obj 664 703 del 800; #X obj 665 728 snapshot~; #X floatatom 665 779 6 0 0 0 - - -; #X obj 666 756 * 1000; #X obj 87 328 s adc-db; #X obj 733 646 s dac-db; #X obj 728 774 s latency; #X obj 354 196 r adc-gain; #X msg 47 61 \; inchannel 1 \; metro-on 1 \; pd dsp 1; #X obj 474 397 s discontinuity; #X obj 496 514 *~ 1e+10; #X obj 496 541 clip~ 0 1; #X obj 496 565 *~ 1e+10; #X obj 497 601 lop~ 3; #X obj 498 625 clip~ 0 1; #X obj 497 487 -~ 0.1; #X obj 497 463 *~ 20; #X obj 514 709 *~; #X connect 0 0 2 0; #X connect 0 1 3 0; #X connect 0 2 4 0; #X connect 0 3 5 0; #X connect 0 4 6 0; #X connect 0 5 7 0; #X connect 0 6 8 0; #X connect 0 7 9 0; #X connect 1 0 2 1; #X connect 2 0 40 0; #X connect 3 0 40 0; #X connect 4 0 40 0; #X connect 5 0 40 0; #X connect 6 0 40 0; #X connect 7 0 40 0; #X connect 8 0 40 0; #X connect 9 0 40 0; #X connect 10 0 3 1; #X connect 11 0 4 1; #X connect 12 0 5 1; #X connect 13 0 6 1; #X connect 14 0 7 1; #X connect 15 0 8 1; #X connect 16 0 9 1; #X connect 17 0 86 0; #X connect 18 0 19 0; #X connect 19 0 20 0; #X connect 22 0 25 0; #X connect 22 1 30 0; #X connect 22 1 29 0; #X connect 23 0 24 0; #X connect 23 0 26 0; #X connect 23 0 31 0; #X connect 24 0 23 1; #X connect 25 0 23 0; #X connect 26 0 33 0; #X connect 26 1 32 0; #X connect 28 0 22 0; #X connect 30 0 23 1; #X connect 31 0 25 1; #X connect 32 0 27 1; #X connect 33 0 62 0; #X connect 34 0 47 0; #X connect 34 0 46 0; #X connect 34 0 77 0; #X connect 34 0 78 0; #X connect 35 0 36 0; #X connect 36 0 34 0; #X connect 37 0 38 0; #X connect 38 0 65 0; #X connect 39 0 1 0; #X connect 39 0 10 0; #X connect 39 0 11 0; #X connect 39 0 12 0; #X connect 39 0 13 0; #X connect 39 0 14 0; #X connect 39 0 15 0; #X connect 39 0 16 0; #X connect 40 0 68 0; #X connect 41 0 42 0; #X connect 42 0 43 0; #X connect 43 0 44 0; #X connect 44 0 45 0; #X connect 45 0 74 0; #X connect 46 0 44 0; #X connect 47 0 37 0; #X connect 48 0 49 0; #X connect 49 0 56 1; #X connect 50 0 51 0; #X connect 50 0 51 1; #X connect 50 0 51 2; #X connect 50 0 51 3; #X connect 50 0 51 4; #X connect 50 0 51 5; #X connect 50 0 51 6; #X connect 50 0 51 7; #X connect 50 0 53 0; #X connect 52 0 57 0; #X connect 53 0 54 0; #X connect 53 0 83 0; #X connect 55 0 48 0; #X connect 56 0 50 0; #X connect 57 0 58 0; #X connect 58 0 59 0; #X connect 59 0 71 0; #X connect 60 0 61 0; #X connect 61 0 64 0; #X connect 62 0 27 0; #X connect 63 0 60 0; #X connect 64 0 73 0; #X connect 65 0 56 0; #X connect 65 0 94 0; #X connect 66 0 67 0; #X connect 67 0 68 1; #X connect 68 0 69 0; #X connect 68 0 63 0; #X connect 68 0 52 0; #X connect 69 0 70 0; #X connect 69 0 82 0; #X connect 71 0 72 0; #X connect 71 0 87 0; #X connect 73 0 41 0; #X connect 74 0 75 0; #X connect 75 0 95 0; #X connect 76 0 79 0; #X connect 77 0 76 1; #X connect 78 0 79 0; #X connect 79 0 81 0; #X connect 81 0 80 0; #X connect 81 0 84 0; #X connect 85 0 66 0; #X connect 88 0 89 0; #X connect 89 0 90 0; #X connect 90 0 91 0; #X connect 91 0 92 0; #X connect 92 0 95 1; #X connect 93 0 88 0; #X connect 94 0 93 0; #X connect 95 0 76 0; #X restore 595 387 pd guts; #X floatatom 242 50 4 1 8 0 inchannel inchannel-set inchannel; #X floatatom 626 267 6 0 0 0 - latency -; #X text 108 96 adjust gain here:; #X text 432 267 latency in milliseconds; #X text 571 245 THE ANSWER IS:; #X floatatom 528 143 4 0 0 0 - adc-db -; #X floatatom 527 92 4 0 0 0 - dac-db -; #X text 567 142 RMS amplitude in; #X text 564 93 RMS amplitude out; #X text 106 142 so that RMS amplitude in is between 60 and 70; #X text 108 121 (typically between -20 and 20); #X text 497 466 updated for Pd version 0.43; #X obj 228 259 bng 25 250 50 0 empty discontinuity empty 17 7 0 10 -262144 -1 -1; #X text 40 235 discontinuity: this flashes if there are audio errors ; #X text 67 343 To use this patch \, connect your audio output back to the audio input (any input and output channel from 1 to 8 \, but the input channel should agree wih the "inchannel" control at top). Then adjust gain so that "RMS amplitude in" is about 65 (anywhere from 60 to 70 will do.) The latency is measured once per second. If there are interruptions in the audio the button above should flash (whether or not the audio system reports the error).; pd-0.46-7/doc/7.stuff/tools/testtone.pd0000664000175000017500000003640712520221360015772 0ustar mspmsp#N canvas 273 107 607 373 12; #X floatatom 72 273 3 0 0 0 - - -, f 3; #X obj 27 221 notein; #X obj 27 247 stripnote; #X floatatom 27 272 3 0 0 0 - - -, f 3; #X text 219 234 MIDI OUT; #X text 27 197 MIDI IN; #X floatatom 150 272 3 0 0 0 - - -, f 3; #X floatatom 120 271 3 0 0 0 - - -, f 3; #X obj 120 246 ctlin; #N canvas 0 50 484 446 midi 0; #X obj 96 65 inlet; #X obj 96 262 noteout; #X floatatom 96 92 0 0 0 0 - - -; #X obj 338 113 loadbang; #X obj 96 184 metro; #X obj 96 236 makenote; #X floatatom 189 166 0 0 0 0 - - -; #X obj 96 210 f; #X floatatom 145 166 0 0 0 0 - - -; #X floatatom 233 166 0 0 0 0 - - -; #X floatatom 276 166 0 0 0 0 - - -; #X msg 338 148 500; #X msg 370 148 60; #X msg 399 148 64; #X msg 427 148 250; #X text 144 145 rate; #X text 187 145 pitch; #X text 232 145 vel; #X text 268 146 length; #X obj 230 257 ctlout 1; #X floatatom 230 228 0 0 0 0 - - -; #X connect 0 0 2 0; #X connect 2 0 4 0; #X connect 3 0 11 0; #X connect 3 0 12 0; #X connect 3 0 13 0; #X connect 3 0 14 0; #X connect 4 0 7 0; #X connect 5 0 1 0; #X connect 5 1 1 1; #X connect 6 0 7 1; #X connect 7 0 5 0; #X connect 8 0 4 1; #X connect 9 0 5 1; #X connect 10 0 5 2; #X connect 11 0 8 0; #X connect 12 0 6 0; #X connect 13 0 9 0; #X connect 14 0 10 0; #X connect 20 0 19 0; #X restore 219 284 pd midi; #X floatatom 178 85 3 0 0 0 - tone-vu1 -, f 3; #X floatatom 205 85 3 0 0 0 - tone-vu2 -, f 3; #X obj 177 132 tgl 20 0 tone-ch1 tone-ch1 1 5 -8 0 12 -262144 -1 -1 1 1; #X obj 202 132 tgl 20 0 tone-ch2 tone-ch2 2 5 -8 0 12 -262144 -1 -1 1 1; #X obj 219 258 tgl 20 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 1; #X text 40 120 OFF; #X obj 443 86 tgl 15 0 tone-hipass tone-hipass-set input-hipass 23 8 0 12 -262144 -1 -1 1 1; #X obj 243 132 tgl 20 0 tone-ch3 tone-ch3 3 5 -8 0 12 -262144 -1 -1 1 1; #X obj 268 132 tgl 20 0 tone-ch4 tone-ch4 4 5 -8 0 12 -262144 -1 -1 1 1; #X obj 309 132 tgl 20 0 tone-ch5 tone-ch5 5 5 -8 0 12 -262144 -1 -1 1 1; #X obj 334 132 tgl 20 0 tone-ch6 tone-ch6 6 5 -8 0 12 -262144 -1 -1 1 1; #X obj 428 125 bng 15 250 50 0 tone-all empty ALL 20 8 0 12 -262144 -1 -1; #X obj 428 146 bng 15 250 50 0 tone-none empty NONE 20 8 0 12 -262144 -1 -1; #X floatatom 244 85 3 0 0 0 - tone-vu3 -, f 3; #X floatatom 272 85 3 0 0 0 - tone-vu4 -, f 3; #X floatatom 310 85 3 0 0 0 - tone-vu5 -, f 3; #X floatatom 338 85 3 0 0 0 - tone-vu6 -, f 3; #X text 237 65 AUDIO INPUT (RMS dB); #X text 101 88 noise; #X text 100 105 tone; #X obj 84 90 vradio 15 1 0 2 tone-type tone-type-set empty 0 -6 0 8 -262144 -1 -1 1; #X obj 22 91 vradio 15 1 0 3 tone-radio tone-radio-set empty 0 -6 0 8 -262144 -1 -1 2; #X floatatom 376 85 3 0 0 0 - tone-vu7 -, f 3; #X floatatom 404 85 3 0 0 0 - tone-vu8 -, f 3; #X obj 375 132 tgl 20 0 tone-ch7 tone-ch7 7 5 -8 0 12 -262144 -1 -1 1 1; #X obj 400 132 tgl 20 0 tone-ch8 tone-ch8 8 5 -8 0 12 -262144 -1 -1 1 1; #N canvas 319 285 306 386 audio 0; #X obj 37 342 s~ tone-mon; #X obj 37 316 line~; #X obj 37 288 pack 0 50; #X obj 34 175 * 5; #X obj 34 200 s tone-hip; #X obj 34 144 r tone-hipass; #N canvas 860 185 459 296 glue+loadbang 0; #X obj 8 20 loadbang; #X obj 204 19 r tone-all; #X obj 314 17 r tone-none; #X msg 204 47 \; tone-ch1 1 \; tone-ch2 1 \; tone-ch3 1 \; tone-ch4 1 \; tone-ch5 1 \; tone-ch6 1 \; tone-ch7 1 \; tone-ch8 1; #X msg 314 48 \; tone-ch1 0 \; tone-ch2 0 \; tone-ch3 0 \; tone-ch4 0 \; tone-ch5 0 \; tone-ch6 0 \; tone-ch7 0 \; tone-ch8 0; #X msg 8 48 \; pd dsp 1 \; tone-pitch 69 \; tone-radio 2 \; tone-radio-set set 2 \; tone-type 1 \; tone-type-set 1 \; tone-all 1 \; tone-hipass 1 \; tone-hipass-set set 1 \;; #X connect 0 0 5 0; #X connect 1 0 3 0; #X connect 2 0 4 0; #X restore 25 97 pd glue+loadbang; #N canvas 207 133 468 559 tone-generator 0; #X obj 22 187 osc~; #X obj 22 81 mtof; #X floatatom 22 58 0 0 0 0 - - -; #X floatatom 22 103 0 0 0 0 - - -; #X obj 22 163 sig~; #X obj 22 33 r tone-pitch; #X obj 119 179 noise~; #X obj 65 249 +~; #X obj 282 140 - 1; #X obj 282 172 * -1; #X obj 191 228 line~; #X obj 281 229 line~; #X obj 22 211 *~; #X obj 119 210 *~; #X msg 191 199 \$1 20; #X msg 281 200 \$1 20; #X floatatom 273 109 0 0 0 0 - - -; #X obj 64 504 *~; #X obj 86 477 line~; #X obj 86 450 pack 0 50; #X floatatom 201 365 0 0 0 0 - - -; #X obj 86 423 dbtorms; #X obj 64 530 s~ tone-osc; #X obj 201 282 r tone-radio; #X obj 201 310 sel 0 1 2; #X msg 270 333 0; #X msg 201 335 80; #X msg 234 335 60; #X obj 273 86 r tone-type; #X obj 89 359 r tone-level; #X obj 178 453 s tone-level-set; #X msg 177 428 set \$1; #X obj 329 452 s tone-radio-set; #X obj 327 369 sel 80 60 0; #X msg 327 394 0; #X msg 360 394 1; #X msg 393 394 2; #X msg 329 426 set \$1; #X msg 423 394 2; #X obj 72 89 s tone-pitch-set; #X msg 72 66 set \$1; #X obj 177 29 r tone-hz; #X msg 75 117 set \$1; #X obj 75 140 s tone-hz-set; #X obj 177 55 ftom; #X connect 0 0 12 0; #X connect 1 0 3 0; #X connect 2 0 1 0; #X connect 2 0 40 0; #X connect 3 0 4 0; #X connect 3 0 42 0; #X connect 4 0 0 0; #X connect 5 0 2 0; #X connect 6 0 13 0; #X connect 7 0 17 0; #X connect 8 0 9 0; #X connect 9 0 15 0; #X connect 10 0 12 1; #X connect 11 0 13 1; #X connect 12 0 7 0; #X connect 13 0 7 1; #X connect 14 0 10 0; #X connect 15 0 11 0; #X connect 16 0 8 0; #X connect 16 0 14 0; #X connect 17 0 22 0; #X connect 18 0 17 1; #X connect 19 0 18 0; #X connect 20 0 21 0; #X connect 20 0 31 0; #X connect 21 0 19 0; #X connect 23 0 24 0; #X connect 24 0 26 0; #X connect 24 1 27 0; #X connect 24 2 25 0; #X connect 25 0 20 0; #X connect 26 0 20 0; #X connect 27 0 20 0; #X connect 28 0 16 0; #X connect 29 0 31 0; #X connect 29 0 21 0; #X connect 31 0 30 0; #X connect 33 0 34 0; #X connect 33 1 35 0; #X connect 33 2 36 0; #X connect 33 3 38 0; #X connect 34 0 37 0; #X connect 35 0 37 0; #X connect 36 0 37 0; #X connect 37 0 32 0; #X connect 38 0 37 0; #X connect 40 0 39 0; #X connect 41 0 44 0; #X connect 42 0 43 0; #X connect 44 0 2 0; #X restore 26 44 pd tone-generator; #N canvas 947 133 819 380 channel-select 0; #X obj 39 55 sel 0 1 2 3 4 5 6 7; #X obj 52 302 s inchlist; #X obj 39 30 r inch-sel; #X msg 40 84 set 1 2 3 4 5 6 7 8; #X msg 57 112 set 3 4 5 6 7 8 9 10; #X msg 76 140 set 5 6 7 8 9 10 11 12; #X msg 95 167 set 7 8 9 10 11 12 13 14; #X msg 113 194 set 9 10 11 12 13 14 15 16; #X msg 138 221 set 11 12 13 14 15 16 17 18; #X msg 157 248 set 17 18 19 20 21 22 23 24; #X msg 176 275 set 25 26 27 28 29 30 31 32; #X obj 414 55 sel 0 1 2 3 4 5 6 7; #X msg 415 84 set 1 2 3 4 5 6 7 8; #X msg 432 112 set 3 4 5 6 7 8 9 10; #X msg 451 140 set 5 6 7 8 9 10 11 12; #X msg 470 167 set 7 8 9 10 11 12 13 14; #X msg 488 194 set 9 10 11 12 13 14 15 16; #X msg 513 221 set 11 12 13 14 15 16 17 18; #X msg 532 248 set 17 18 19 20 21 22 23 24; #X msg 551 275 set 25 26 27 28 29 30 31 32; #X obj 414 30 r outch-sel; #X obj 427 302 s outchlist; #X connect 0 0 3 0; #X connect 0 1 4 0; #X connect 0 2 5 0; #X connect 0 3 6 0; #X connect 0 4 7 0; #X connect 0 5 8 0; #X connect 0 6 9 0; #X connect 0 7 10 0; #X connect 2 0 0 0; #X connect 3 0 1 0; #X connect 4 0 1 0; #X connect 5 0 1 0; #X connect 6 0 1 0; #X connect 7 0 1 0; #X connect 8 0 1 0; #X connect 9 0 1 0; #X connect 10 0 1 0; #X connect 11 0 12 0; #X connect 11 1 13 0; #X connect 11 2 14 0; #X connect 11 3 15 0; #X connect 11 4 16 0; #X connect 11 5 17 0; #X connect 11 6 18 0; #X connect 11 7 19 0; #X connect 12 0 21 0; #X connect 13 0 21 0; #X connect 14 0 21 0; #X connect 15 0 21 0; #X connect 16 0 21 0; #X connect 17 0 21 0; #X connect 18 0 21 0; #X connect 19 0 21 0; #X connect 20 0 11 0; #X restore 26 71 pd channel-select; #N canvas 675 374 967 515 adcs-and-dacs 0; #X obj 13 100 hip~ 5; #X obj 21 151 int; #X obj 21 125 env~ 8192; #X obj 23 200 r~ tone-mon; #X obj 32 335 line~; #X obj 13 225 *~; #X obj 32 308 pack 0 50; #X obj 32 282 r tone-ch1; #X obj 23 255 r~ tone-osc; #X obj 23 360 *~; #X obj 13 390 +~; #X obj 30 73 r tone-hip; #X obj 133 99 hip~ 5; #X obj 141 150 int; #X obj 141 124 env~ 8192; #X obj 143 199 r~ tone-mon; #X obj 152 334 line~; #X obj 133 224 *~; #X obj 152 307 pack 0 50; #X obj 143 254 r~ tone-osc; #X obj 143 359 *~; #X obj 133 389 +~; #X obj 150 72 r tone-hip; #X obj 152 281 r tone-ch2; #X obj 253 101 hip~ 5; #X obj 261 152 int; #X obj 261 126 env~ 8192; #X obj 263 201 r~ tone-mon; #X obj 272 336 line~; #X obj 253 226 *~; #X obj 272 309 pack 0 50; #X obj 263 256 r~ tone-osc; #X obj 263 361 *~; #X obj 253 391 +~; #X obj 270 74 r tone-hip; #X obj 371 97 hip~ 5; #X obj 379 148 int; #X obj 379 122 env~ 8192; #X obj 381 197 r~ tone-mon; #X obj 390 332 line~; #X obj 371 222 *~; #X obj 390 305 pack 0 50; #X obj 381 252 r~ tone-osc; #X obj 381 357 *~; #X obj 371 387 +~; #X obj 388 70 r tone-hip; #X obj 491 97 hip~ 5; #X obj 499 148 int; #X obj 499 122 env~ 8192; #X obj 501 197 r~ tone-mon; #X obj 510 332 line~; #X obj 491 222 *~; #X obj 510 305 pack 0 50; #X obj 501 252 r~ tone-osc; #X obj 501 357 *~; #X obj 491 387 +~; #X obj 508 70 r tone-hip; #X obj 610 96 hip~ 5; #X obj 618 147 int; #X obj 618 121 env~ 8192; #X obj 620 196 r~ tone-mon; #X obj 629 331 line~; #X obj 610 221 *~; #X obj 629 304 pack 0 50; #X obj 620 251 r~ tone-osc; #X obj 620 356 *~; #X obj 610 386 +~; #X obj 627 69 r tone-hip; #X obj 272 283 r tone-ch3; #X obj 390 278 r tone-ch4; #X obj 510 279 r tone-ch5; #X obj 629 278 r tone-ch6; #X obj 730 101 hip~ 5; #X obj 738 152 int; #X obj 738 126 env~ 8192; #X obj 740 201 r~ tone-mon; #X obj 749 336 line~; #X obj 730 226 *~; #X obj 749 309 pack 0 50; #X obj 740 256 r~ tone-osc; #X obj 740 361 *~; #X obj 730 391 +~; #X obj 747 74 r tone-hip; #X obj 850 100 hip~ 5; #X obj 858 151 int; #X obj 858 125 env~ 8192; #X obj 860 200 r~ tone-mon; #X obj 869 335 line~; #X obj 850 225 *~; #X obj 869 308 pack 0 50; #X obj 860 255 r~ tone-osc; #X obj 860 360 *~; #X obj 850 390 +~; #X obj 867 73 r tone-hip; #X obj 749 283 r tone-ch7; #X obj 869 282 r tone-ch8; #X obj 21 177 s tone-vu1; #X obj 141 176 s tone-vu2; #X obj 261 178 s tone-vu3; #X obj 379 174 s tone-vu4; #X obj 499 174 s tone-vu5; #X obj 618 173 s tone-vu6; #X obj 738 178 s tone-vu7; #X obj 858 177 s tone-vu8; #X obj 13 39 adc~ 1 2 3 4 5 6 7 8, f 105; #X obj 14 460 dac~ 1 2 3 4 5 6 7 8, f 105; #X obj 26 430 r outchlist; #X obj 32 12 r inchlist; #X connect 0 0 5 0; #X connect 0 0 2 0; #X connect 1 0 96 0; #X connect 2 0 1 0; #X connect 3 0 5 1; #X connect 4 0 9 1; #X connect 5 0 10 0; #X connect 6 0 4 0; #X connect 7 0 6 0; #X connect 8 0 9 0; #X connect 9 0 10 1; #X connect 10 0 105 0; #X connect 11 0 0 1; #X connect 12 0 17 0; #X connect 12 0 14 0; #X connect 13 0 97 0; #X connect 14 0 13 0; #X connect 15 0 17 1; #X connect 16 0 20 1; #X connect 17 0 21 0; #X connect 18 0 16 0; #X connect 19 0 20 0; #X connect 20 0 21 1; #X connect 21 0 105 1; #X connect 22 0 12 1; #X connect 23 0 18 0; #X connect 24 0 29 0; #X connect 24 0 26 0; #X connect 25 0 98 0; #X connect 26 0 25 0; #X connect 27 0 29 1; #X connect 28 0 32 1; #X connect 29 0 33 0; #X connect 30 0 28 0; #X connect 31 0 32 0; #X connect 32 0 33 1; #X connect 33 0 105 2; #X connect 34 0 24 1; #X connect 35 0 40 0; #X connect 35 0 37 0; #X connect 36 0 99 0; #X connect 37 0 36 0; #X connect 38 0 40 1; #X connect 39 0 43 1; #X connect 40 0 44 0; #X connect 41 0 39 0; #X connect 42 0 43 0; #X connect 43 0 44 1; #X connect 44 0 105 3; #X connect 45 0 35 1; #X connect 46 0 51 0; #X connect 46 0 48 0; #X connect 47 0 100 0; #X connect 48 0 47 0; #X connect 49 0 51 1; #X connect 50 0 54 1; #X connect 51 0 55 0; #X connect 52 0 50 0; #X connect 53 0 54 0; #X connect 54 0 55 1; #X connect 55 0 105 4; #X connect 56 0 46 1; #X connect 57 0 62 0; #X connect 57 0 59 0; #X connect 58 0 101 0; #X connect 59 0 58 0; #X connect 60 0 62 1; #X connect 61 0 65 1; #X connect 62 0 66 0; #X connect 63 0 61 0; #X connect 64 0 65 0; #X connect 65 0 66 1; #X connect 66 0 105 5; #X connect 67 0 57 1; #X connect 68 0 30 0; #X connect 69 0 41 0; #X connect 70 0 52 0; #X connect 71 0 63 0; #X connect 72 0 77 0; #X connect 72 0 74 0; #X connect 73 0 102 0; #X connect 74 0 73 0; #X connect 75 0 77 1; #X connect 76 0 80 1; #X connect 77 0 81 0; #X connect 78 0 76 0; #X connect 79 0 80 0; #X connect 80 0 81 1; #X connect 81 0 105 6; #X connect 82 0 72 1; #X connect 83 0 88 0; #X connect 83 0 85 0; #X connect 84 0 103 0; #X connect 85 0 84 0; #X connect 86 0 88 1; #X connect 87 0 91 1; #X connect 88 0 92 0; #X connect 89 0 87 0; #X connect 90 0 91 0; #X connect 91 0 92 1; #X connect 92 0 105 7; #X connect 93 0 83 1; #X connect 94 0 78 0; #X connect 95 0 89 0; #X connect 104 0 0 0; #X connect 104 1 12 0; #X connect 104 2 24 0; #X connect 104 3 35 0; #X connect 104 4 46 0; #X connect 104 5 57 0; #X connect 104 6 72 0; #X connect 104 7 83 0; #X connect 106 0 105 0; #X connect 107 0 104 0; #X restore 25 19 pd adcs-and-dacs; #X obj 36 235 r input-monitor-gain; #X obj 36 260 dbtorms; #X connect 1 0 0 0; #X connect 2 0 1 0; #X connect 3 0 4 0; #X connect 5 0 3 0; #X connect 10 0 11 0; #X connect 11 0 2 0; #X restore 373 252 pd audio; #X floatatom 22 144 3 0 100 1 - tone-level-set tone-level, f 3; #X floatatom 84 123 5 0 136 1 pitch tone-pitch-set tone-pitch, f 5 ; #X floatatom 84 145 6 0 20000 1 HZ tone-hz-set tone-hz, f 6; #X text 48 145 dB; #X text 34 67 TEST TONES; #X text 233 156 AUDIO OUTPUT ON/OFF; #X text 18 5 Welcome to Pd ("Pure Data"). You can use this window to test audio and MIDI connections. To see Pd's DOCUMENTATION \, select "getting started" in the Help menu.; #X text 18 323 Pd is Free software under the BSD license. See LICENSE.txt in the distribution for details.; #X obj 27 292 bng 20 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 120 293 bng 20 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X text 39 105 60; #X text 39 88 80; #X text 16 163 (100 max); #X obj 499 168 vradio 15 1 0 8 inch-sel empty empty 0 -8 0 10 -262144 -1 -1 0; #X obj 520 168 vradio 15 1 0 8 outch-sel empty empty 0 -8 0 10 -262144 -1 -1 0; #X text 541 165 1-8; #X text 542 180 3-10; #X text 542 195 5-12; #X text 543 212 7-14; #X text 542 227 9-16; #X text 543 242 11-18; #X text 543 257 17-24; #X floatatom 340 188 5 0 120 0 input-monitor-gain input-monitor-gain-set input-monitor-gain, f 5; #X text 507 122 channel assign:, f 7; #X text 496 289 in; #X text 519 290 out; #N canvas 178 52 578 350 tests 0; #X floatatom 42 209 0 0 0 0 - - -; #X obj 42 183 f; #X obj 79 183 + 1; #X obj 42 150 metro 1000; #X obj 42 123 tgl 20 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 1 ; #X text 24 30 this window has various wierd debugging stuff...; #X text 22 74 see if Pd's time; #X text 22 93 measurement works:; #X obj 227 127 adc~; #X obj 226 224 print~; #X obj 235 201 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 227 152 *~ 1; #X obj 302 138 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 302 158 sel 0 1; #X obj 301 183 1; #X obj 333 185 1000; #X text 226 94 print out literal values from ADC 1; #X text 323 136 optionally multiply by 1000; #X obj 53 264 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X floatatom 53 309 5 0 0 0 - - -, f 5; #X obj 53 284 samplerate~; #X text 163 287 get current sample rate; #X connect 1 0 2 0; #X connect 1 0 0 0; #X connect 2 0 1 1; #X connect 3 0 1 0; #X connect 4 0 3 0; #X connect 8 0 11 0; #X connect 10 0 9 0; #X connect 11 0 9 0; #X connect 12 0 13 0; #X connect 13 0 14 0; #X connect 13 1 15 0; #X connect 14 0 11 1; #X connect 15 0 11 1; #X connect 18 0 20 0; #X connect 20 0 19 0; #X restore 373 275 pd tests; #X text 543 274 25-32; #X connect 1 0 2 0; #X connect 1 1 2 1; #X connect 2 0 3 0; #X connect 2 1 0 0; #X connect 3 0 45 0; #X connect 7 0 46 0; #X connect 8 0 7 0; #X connect 8 1 6 0; #X connect 14 0 9 0; pd-0.46-7/doc/6.externs/0000775000175000017500000000000012374250720012777 5ustar mspmsppd-0.46-7/doc/6.externs/obj1.c0000664000175000017500000000243512160204055013773 0ustar mspmsp/* code for "obj1" pd class. This takes two messages: floating-point numbers, and "rats", and just prints something out for each message. */ #include "m_pd.h" /* the data structure for each copy of "obj1". In this case we on;y need pd's obligatory header (of type t_object). */ typedef struct obj1 { t_object x_ob; } t_obj1; /* this is called back when obj1 gets a "float" message (i.e., a number.) */ void obj1_float(t_obj1 *x, t_floatarg f) { post("obj1: %f", f); } /* this is called when obj1 gets the message, "rats". */ void obj1_rats(t_obj1 *x) { post("obj1: rats"); } /* this is a pointer to the class for "obj1", which is created in the "setup" routine below and used to create new ones in the "new" routine. */ t_class *obj1_class; /* this is called when a new "obj1" object is created. */ void *obj1_new(void) { t_obj1 *x = (t_obj1 *)pd_new(obj1_class); post("obj1_new"); return (void *)x; } /* this is called once at setup time, when this code is loaded into Pd. */ void obj1_setup(void) { post("obj1_setup"); obj1_class = class_new(gensym("obj1"), (t_newmethod)obj1_new, 0, sizeof(t_obj1), 0, 0); class_addmethod(obj1_class, (t_method)obj1_rats, gensym("rats"), 0); class_addfloat(obj1_class, obj1_float); } pd-0.46-7/doc/6.externs/test-obj5.pd0000664000175000017500000000020512160204055015126 0ustar mspmsp#N canvas 128 288 310 157 12; #X obj 15 74 obj5 1 2 3 cis boom bah; #X msg 15 30 rats 4 5 6 tara tara boum boum; #X connect 1 0 0 0; pd-0.46-7/doc/6.externs/test-dspobj~.pd0000664000175000017500000000036012160204055015750 0ustar mspmsp#N canvas 0 0 335 239 10; #X obj 90 124 dspobj~; #X obj 90 96 sig~ 0; #X msg 106 149 bang; #X obj 90 177 print~; #X floatatom 89 71; #X msg 202 37 \; pd dsp 1; #X connect 0 0 3 0; #X connect 1 0 0 0; #X connect 2 0 3 0; #X connect 4 0 1 0; pd-0.46-7/doc/6.externs/test-obj3.pd0000664000175000017500000000032512160204055015127 0ustar mspmsp#N canvas 128 288 310 157 12; #X obj 68 91 obj3; #X floatatom 67 61 3 0 0 0 - - -; #X floatatom 108 59 3 0 0 0 - - -; #X floatatom 70 118 3 0 0 0 - - -; #X connect 0 0 3 0; #X connect 1 0 0 0; #X connect 2 0 0 1; pd-0.46-7/doc/6.externs/obj5.c0000664000175000017500000000327612160204055014003 0ustar mspmsp/* code for the "obj5" pd class. This shows "gimme" arguments, which have variable arguments parsed by the routines (both "new" and "rats".) */ #include "m_pd.h" typedef struct obj5 { t_object x_ob; } t_obj5; /* the "rats" method is called with the selector (just "rats" again) and an array of the typed areguments, which are each either a number or a symbol. We just print them out. */ void obj5_rats(t_obj5 *x, t_symbol *selector, int argcount, t_atom *argvec) { int i; post("rats: selector %s", selector->s_name); for (i = 0; i < argcount; i++) { if (argvec[i].a_type == A_FLOAT) post("float: %f", argvec[i].a_w.w_float); else if (argvec[i].a_type == A_SYMBOL) post("symbol: %s", argvec[i].a_w.w_symbol->s_name); } } t_class *obj5_class; /* same for the "new" (creation) routine, except that we don't have "x" as an argument since we have to create "x" in this routine. */ void *obj5_new(t_symbol *selector, int argcount, t_atom *argvec) { t_obj5 *x = (t_obj5 *)pd_new(obj5_class); int i; post("new: selector %s", selector->s_name); for (i = 0; i < argcount; i++) { if (argvec[i].a_type == A_FLOAT) post("float: %f", argvec[i].a_w.w_float); else if (argvec[i].a_type == A_SYMBOL) post("symbol: %s", argvec[i].a_w.w_symbol->s_name); } return (void *)x; } void obj5_setup(void) { /* We specify "A_GIMME" as creation argument for both the creation routine and the method (callback) for the "rats" message. */ obj5_class = class_new(gensym("obj5"), (t_newmethod)obj5_new, 0, sizeof(t_obj5), 0, A_GIMME, 0); class_addmethod(obj5_class, (t_method)obj5_rats, gensym("rats"), A_GIMME, 0); } pd-0.46-7/doc/6.externs/obj3.c0000664000175000017500000000151112160204055013767 0ustar mspmsp/* code for the "obj3" pd class. This adds an outlet and a state variable. */ #include "m_pd.h" typedef struct obj3 { t_object x_ob; t_outlet *x_outlet; float x_value; } t_obj3; void obj3_float(t_obj3 *x, t_floatarg f) { outlet_float(x->x_outlet, f + x->x_value); } void obj3_ft1(t_obj3 *x, t_floatarg g) { x->x_value = g; } t_class *obj3_class; void *obj3_new(void) { t_obj3 *x = (t_obj3 *)pd_new(obj3_class); inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1")); x->x_outlet = outlet_new(&x->x_ob, gensym("float")); return (void *)x; } void obj3_setup(void) { obj3_class = class_new(gensym("obj3"), (t_newmethod)obj3_new, 0, sizeof(t_obj3), 0, 0); class_addmethod(obj3_class, (t_method)obj3_ft1, gensym("ft1"), A_FLOAT, 0); class_addfloat(obj3_class, obj3_float); } pd-0.46-7/doc/6.externs/dspobj~.c0000664000175000017500000000425012160204055014614 0ustar mspmsp#include "m_pd.h" #ifdef NT #pragma warning( disable : 4244 ) #pragma warning( disable : 4305 ) #endif /* ------------------------ dspobj~ ----------------------------- */ /* tilde object to take absolute value. */ static t_class *dspobj_class; typedef struct _dspobj { t_object x_obj; /* obligatory header */ t_float x_f; /* place to hold inlet's value if it's set by message */ } t_dspobj; /* this is the actual performance routine which acts on the samples. It's called with a single pointer "w" which is our location in the DSP call list. We return a new "w" which will point to the next item after us. Meanwhile, w[0] is just a pointer to dsp-perform itself (no use to us), w[1] and w[2] are the input and output vector locations, and w[3] is the number of points to calculate. */ static t_int *dspobj_perform(t_int *w) { t_float *in = (t_float *)(w[1]); t_float *out = (t_float *)(w[2]); int n = (int)(w[3]); while (n--) { float f = *(in++); *out++ = (f > 0 ? f : -f); } return (w+4); } /* called to start DSP. Here we call Pd back to add our perform routine to a linear callback list which Pd in turn calls to grind out the samples. */ static void dspobj_dsp(t_dspobj *x, t_signal **sp) { dsp_add(dspobj_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); } static void *dspobj_new(void) { t_dspobj *x = (t_dspobj *)pd_new(dspobj_class); outlet_new(&x->x_obj, gensym("signal")); x->x_f = 0; return (x); } /* this routine, which must have exactly this name (with the "~" replaced by "_tilde) is called when the code is first loaded, and tells Pd how to build the "class". */ void dspobj_tilde_setup(void) { dspobj_class = class_new(gensym("dspobj~"), (t_newmethod)dspobj_new, 0, sizeof(t_dspobj), 0, A_DEFFLOAT, 0); /* this is magic to declare that the leftmost, "main" inlet takes signals; other signal inlets are done differently... */ CLASS_MAINSIGNALIN(dspobj_class, t_dspobj, x_f); /* here we tell Pd about the "dsp" method, which is called back when DSP is turned on. */ class_addmethod(dspobj_class, (t_method)dspobj_dsp, gensym("dsp"), 0); } pd-0.46-7/doc/6.externs/obj4.c0000664000175000017500000000235512160204055013777 0ustar mspmsp/* code for the "obj4" pd class. This adds a creation argument, of type "float". */ #include "m_pd.h" typedef struct obj4 { t_object x_ob; t_outlet *x_outlet; float x_value; } t_obj4; void obj4_float(t_obj4 *x, t_floatarg f) { outlet_float(x->x_outlet, x->x_value + f); } void obj4_ft1(t_obj4 *x, t_floatarg g) { x->x_value = g; } t_class *obj4_class; /* as requested by the new invocation of "class_new" below, the new routine will be called with a "float" argument. */ void *obj4_new(t_floatarg f) { t_obj4 *x = (t_obj4 *)pd_new(obj4_class); inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1")); x->x_outlet = outlet_new(&x->x_ob, gensym("float")); /* just stick the argument in the object structure for later. */ x->x_value = f; return (void *)x; } void obj4_setup(void) { /* here we add "A_DEFFLOAT" to the (zero-terminated) list of arg types we declare for a new object. The value will be filled in as 0 if not given in the object box. */ obj4_class = class_new(gensym("obj4"), (t_newmethod)obj4_new, 0, sizeof(t_obj4), 0, A_DEFFLOAT, 0); class_addmethod(obj4_class, (t_method)obj4_ft1, gensym("ft1"), A_FLOAT, 0); class_addfloat(obj4_class, obj4_float); } pd-0.46-7/doc/6.externs/obj2.c0000664000175000017500000000164212160204055013773 0ustar mspmsp/* code for the "obj2" pd class. This one, in addition to the "obj1" code, has an inlet taking numbers. */ #include "m_pd.h" typedef struct obj2 { t_object x_ob; } t_obj2; void obj2_float(t_obj2 *x, t_floatarg f) { post("obj2: %f", f); } void obj2_rats(t_obj2 *x) { post("obj2: rats"); } void obj2_ft1(t_obj2 *x, t_floatarg g) { post("ft1: %f", g); } t_class *obj2_class; void *obj2_new(void) { t_obj2 *x = (t_obj2 *)pd_new(obj2_class); inlet_new(&x->x_ob, &x->x_ob.ob_pd, gensym("float"), gensym("ft1")); post("obj2_new"); return (void *)x; } void obj2_setup(void) { post("obj2_setup"); obj2_class = class_new(gensym("obj2"), (t_newmethod)obj2_new, 0, sizeof(t_obj2), 0, 0); class_addmethod(obj2_class, (t_method)obj2_rats, gensym("rats"), 0); class_addmethod(obj2_class, (t_method)obj2_ft1, gensym("ft1"), A_FLOAT, 0); class_addfloat(obj2_class, obj2_float); } pd-0.46-7/doc/6.externs/0.README.txt0000664000175000017500000000043112160204055014622 0ustar mspmspEXTERNAL OBJECTS in Pd. Here are the sources for three simple external objects in Pd. To compile, type "make pd_linux", "nmake pd_nt", "make pd_irix5" or "make pd_irix6". The objects "foo1" and "foo2" are intended as very simple control objects, and "dspobj" is a tilde object. pd-0.46-7/doc/6.externs/makefile0000664000175000017500000000421312374250720014477 0ustar mspmspcurrent: echo make pd_linux, pd_nt, pd_irix5, or pd_irix6 clean: ; rm -f *.pd_linux *.o # ----------------------- Windows----------------------- # note; you will certainly have to edit the definition of VC to agree with # whatever you've got installed on your machine: VC="D:\Program Files\Microsoft Visual Studio\Vc98" pd_nt: obj1.dll obj2.dll obj3.dll obj4.dll obj5.dll dspobj~.dll .SUFFIXES: .obj .dll PDNTCFLAGS = /W3 /WX /DNT /DPD /nologo PDNTINCLUDE = /I. /I\tcl\include /I..\..\src /I$(VC)\include PDNTLDIR = $(VC)\lib PDNTLIB = $(PDNTLDIR)\libc.lib \ $(PDNTLDIR)\oldnames.lib \ $(PDNTLDIR)\kernel32.lib \ ..\..\bin\pd.lib .c.dll: cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c link /dll /export:$*_setup $*.obj $(PDNTLIB) # override explicitly for tilde objects like this: dspobj~.dll: dspobj~.c; cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c link /dll /export:dspobj_tilde_setup $*.obj $(PDNTLIB) # ----------------------- LINUX i386 ----------------------- pd_linux: obj1.l_ia64 obj2.l_ia64 obj3.l_ia64 obj4.l_ia64 \ obj5.l_ia64 dspobj~.l_ia64 pd_linux32: obj1.l_i386 obj2.l_i386 obj3.l_i386 obj4.l_i386 \ obj5.l_i386 dspobj~.l_i386 .SUFFIXES: .l_i386 .l_ia64 LINUXCFLAGS = -DPD -O2 -funroll-loops -fomit-frame-pointer \ -Wall -W -Wshadow -Wstrict-prototypes -Werror \ -Wno-unused -Wno-parentheses -Wno-switch LINUXINCLUDE = -I../../src .c.l_i386: cc $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c ld -shared -o $*.l_i386 $*.o -lc -lm strip --strip-unneeded $*.l_i386 rm $*.o .c.l_ia64: cc $(LINUXCFLAGS) $(LINUXINCLUDE) -fPIC -o $*.o -c $*.c ld -shared -o $*.l_ia64 $*.o -lc -lm strip --strip-unneeded $*.l_ia64 rm $*.o # ----------------------- Mac OSX ----------------------- pd_darwin: obj1.pd_darwin obj2.pd_darwin \ obj3.pd_darwin obj4.pd_darwin obj5.pd_darwin dspobj~.pd_darwin .SUFFIXES: .pd_darwin DARWINCFLAGS = -DPD -O2 -Wall -W -Wshadow -Wstrict-prototypes \ -Wno-unused -Wno-parentheses -Wno-switch -arch i386 -arch x86_64 .c.pd_darwin: cc $(DARWINCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c cc -bundle -undefined suppress -arch i386 -arch x86_64 \ -flat_namespace -o $*.pd_darwin $*.o rm -f $*.o pd-0.46-7/doc/6.externs/test-obj2.pd0000664000175000017500000000024112160204055015123 0ustar mspmsp#N canvas 62 333 310 157 12; #X msg 109 51 rats; #X msg 157 52 7; #X msg 68 52 4; #X obj 68 90 obj2; #X connect 0 0 3 0; #X connect 1 0 3 1; #X connect 2 0 3 0; pd-0.46-7/doc/6.externs/test-obj4.pd0000664000175000017500000000024112160204055015125 0ustar mspmsp#N canvas 128 288 310 157 12; #X floatatom 67 61 3 0 0 0 - - -; #X floatatom 70 118 3 0 0 0 - - -; #X obj 68 91 obj4 34; #X connect 0 0 2 0; #X connect 2 0 1 0; pd-0.46-7/doc/6.externs/test-obj1.pd0000664000175000017500000000017312160204055015126 0ustar mspmsp#N canvas 68 38 317 151 12; #X msg 68 52 5; #X msg 100 52 rats; #X obj 67 90 obj1; #X connect 0 0 2 0; #X connect 1 0 2 0; pd-0.46-7/doc/5.reference/0000775000175000017500000000000012574135745013257 5ustar mspmsppd-0.46-7/doc/5.reference/setsize.txt0000664000175000017500000000033212160204055015462 0ustar mspmspdata; template help-setsize-template; float x; float y; array array1 help-setsize-array1-template; ; template help-setsize-array1-template; float y; ; ; help-setsize-template 31 23; 0; 10; 0; 10; 20; 10; 20; 70; 10; ; pd-0.46-7/doc/5.reference/snapshot~-help.pd0000664000175000017500000000237412160204055016553 0ustar mspmsp#N canvas 85 46 661 400 12; #X obj 19 316 snapshot~; #X floatatom 19 339 0 0 0 0 - - -; #X obj 74 14 snapshot~; #X msg 30 264 bang; #X text 112 342 This output updates each time bang is clicked above. ; #X text 154 14 - convert a signal to a number on demand; #X text 9 46 The snapshot~ object takes a signal and converts it to a control value whenever it receives a bang in its left outlet. This object is particularly useful for monitoring outputs.; #X msg 565 43 \; pd dsp 1; #X obj 565 20 loadbang; #X obj 19 239 osc~ 0.1; #X text 24 221 0.1 Hz cosine; #X text 397 373 updated for Pd version 0.37; #X msg 35 288 set 5; #X text 102 239 signal in to take snapshots of; #X text 73 263 bang -- take one snapshot; #X text 89 288 set -- set value (which is reset next DSP block.); #X msg 565 85 \; pd dsp 0; #X text 11 109 In the example below \, a snapshot~ object prints out the values of a low frequency cosine wave every time it is sent a bang message.; #X text 12 161 A 'set' message is provided for the (rare) situations where you might make a known change to the signal input \, and then read snapshot's value before any ensuing signal computation.; #X connect 0 0 1 0; #X connect 0 0 1 0; #X connect 3 0 0 0; #X connect 8 0 7 0; #X connect 9 0 0 0; #X connect 12 0 0 0; pd-0.46-7/doc/5.reference/noise~-help.pd0000664000175000017500000000075012160204055016025 0ustar mspmsp#N canvas 174 90 458 270 12; #X floatatom 77 178 4 0 0; #X obj 77 111 noise~; #X obj 167 149 print~; #X msg 167 123 bang; #X obj 282 89 loadbang; #X msg 282 114 \; pd dsp 1; #X obj 77 150 env~ 4096; #X text 67 204 RMS in dB; #X text 171 242 updated for Pd version 0.33; #X obj 20 11 noise~; #X text 84 11 - uniformly distributed white noise; #X text 38 49 the output range is -1 to 1...; #X connect 1 0 2 0; #X connect 1 0 6 0; #X connect 3 0 2 0; #X connect 4 0 5 0; #X connect 6 0 0 0; pd-0.46-7/doc/5.reference/append-help.pd0000664000175000017500000000377412425760510016001 0ustar mspmsp#N canvas 377 52 614 619 12; #X text 49 519 see also:; #N canvas 164 72 429 150 help-append-template1 0; #X obj 18 81 filledpolygon z z 0 0 0 20 0 20 30 0 30; #X obj 60 21 struct help-append-template1 float x float y float z; #X restore 373 539 pd help-append-template1; #X obj 50 543 get; #X obj 82 543 set; #X obj 182 543 getsize; #X obj 249 543 setsize; #X obj 252 568 element; #X obj 117 568 scalar; #N canvas 2 79 280 167 help-append-data 1; #X restore 373 517 pd help-append-data; #X obj 217 264 pointer; #X obj 21 10 append; #X text 75 9 -- add item to a list; #X msg 217 240 traverse pd-help-append-data \, bang; #X obj 39 304 append help-append-template1 x y z; #X floatatom 39 255 5 0 0 0 - - -, f 5; #X obj 39 275 t f f; #X msg 359 295 \; pd-help-append-data clear; #X text 27 28 "append" maintains a pointer to a scalar \, or else an empty pointer to the head of a list. You may set the pointer using the leftmost inlet. The creation arguments specify the template of a new scalar to append \, and the names of the fields (there should be at least one) you will wish to initialize. To append an object \, send a number to the leftmost inlet. "Append"'s pointer is updated to point to the new scalar \, and the new pointer is also output.; #X obj 115 543 pointer; #X text 39 235 click this first->; #X text 235 219 go to (and output) "head" of the list; #X obj 175 568 struct; #X text 358 574 updated for Pd version 0.47; #X obj 311 441 pointer; #X msg 311 417 traverse pd-help-append-data \, bang; #X floatatom 56 389 5 0 0 0 - - -, f 5; #X obj 55 463 append; #X msg 70 416 set help-append-template1 x; #X text 24 161 To insert to the beginning of a list \, you can append to the "head" of the list.; #X text 31 347 if there is no more than one field \, you can use a "set" message to set the template and field:; #X connect 9 0 13 3; #X connect 12 0 9 0; #X connect 14 0 15 0; #X connect 15 0 13 0; #X connect 15 1 13 1; #X connect 15 1 13 2; #X connect 23 0 26 1; #X connect 24 0 23 0; #X connect 25 0 26 0; #X connect 27 0 26 0; pd-0.46-7/doc/5.reference/switch~-help.pd0000664000175000017500000000367012160204055016215 0ustar mspmsp#N canvas 218 166 619 368 12; #X msg 382 133 \; metro 0; #X text 462 92 <-Click to start; #X text 455 137 <-Click to stop; #X text 47 13 switch and block - turn DSP on and off for subpatches and control block size; #N canvas 15 32 598 301 switched 1; #X obj 265 148 switch~; #X floatatom 265 121 1 0 0; #X floatatom 75 168 4 0 0; #X obj 75 104 noise~; #X obj 75 136 env~ 512; #X text 25 26 DSP in this subwindow is turned on and off by the switch~ object. Any subwindows of this window can also be switched off here. If a patch and a superpatch both have switches \, both must be "on" for DSP to run in the patch.; #X text 32 203 switch~ takes optional arguments the same as block~. If you supply arguments to switch \, the patch will be switched AND reblocked.; #X text 31 258 Only one switch~ or block~ may appear in any window. ; #X connect 1 0 0 0; #X connect 3 0 4 0; #X connect 4 0 2 0; #X restore 139 124 pd switched; #N canvas 13 421 564 200 blocked 1; #X obj 184 35 block~ 1024 4; #X text 14 76 This object specified that DSP in this subwindow is to be computed at a block size of 1024 \, and an overlap of 4 \, i.e. \, every 256 samples. You may not (yet) specify a block size smaller than your superpatch. This is useful for writing FFT based patches (see the "fft examples" tutorial series.); #X restore 141 158 pd blocked; #X msg 382 87 \; pd dsp 1; #X obj 382 61 loadbang; #X text 38 82 see the subpatches for explanation:; #X text 362 334 updated for Pd version 0.34; #X text 34 195 BUG! -- dac~ and adc~ work only with a blocksize of 64 If you want to reblock audio computation \, do so in a sub-patch and keep the adc~ and dac~ objects in a super-patch. Also \, you can't send~ or receive~ between windows with different block sizes or overlapping. Only the inlet~ and outlet~ objects know how to reblock signals. In this example \, you could put a dac~ in this \, outer window \, or in the switched subwindow \, but not the blocked one.; #X connect 7 0 6 0; pd-0.46-7/doc/5.reference/czero~-help.pd0000664000175000017500000000725112160204055016035 0ustar mspmsp#N canvas 79 19 533 567 12; #X obj 54 90 osc~ 100; #X msg 62 117 clear; #X obj 79 547 lop~; #X text 10 550 see also:; #X text 333 549 updated for Pd version-0.38; #X obj 86 497 rzero~; #X obj 37 517 cpole~; #X obj 37 497 rpole~; #X obj 135 497 rzero_rev~; #X obj 86 517 czero~; #X obj 135 517 czero_rev~; #X text 213 497 real; #X text 212 518 complex; #X text 34 481 1-pole; #X text 83 481 1-zero; #X text 133 481 1-zero \, reversed; #X text 59 466 summary of raw filters:; #X text 106 116 <-- clear internal state to zero; #N canvas 255 257 585 372 test 0; #X obj 152 296 env~ 16384; #X floatatom 152 320 5 0 0 0 - - -; #X floatatom 484 121 4 -1000 1000 0 - - -; #X obj 349 324 dac~; #X obj 349 288 *~; #X obj 375 115 cos~; #X floatatom 301 60 5 0 0 0 - - -; #X obj 329 112 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 301 110 *~; #X obj 301 83 phasor~; #X floatatom 382 66 5 0 0 0 - - -; #X obj 382 89 / 1000; #X obj 408 116 -~ 0.25; #X obj 408 138 cos~; #X obj 484 140 / 1000; #X obj 374 166 *~; #X obj 408 166 *~; #X obj 228 296 env~ 16384; #X floatatom 228 320 5 0 0 0 - - -; #X obj 381 284 dbtorms; #X floatatom 382 264 5 0 0 0 - - -; #X obj 245 220 czero~; #X floatatom 201 132 4 -1000 1000 0 - - -; #X obj 92 126 cos~; #X obj 112 85 phasor~; #X floatatom 115 60 5 0 0 0 - - -; #X obj 125 127 -~ 0.25; #X obj 125 149 cos~; #X obj 201 151 / 1000; #X obj 91 177 *~; #X obj 125 177 *~; #X text 214 27 Stuff to test it:; #X connect 0 0 1 0; #X connect 2 0 14 0; #X connect 4 0 3 0; #X connect 4 0 3 1; #X connect 5 0 15 0; #X connect 6 0 9 0; #X connect 7 0 8 1; #X connect 8 0 21 0; #X connect 9 0 8 0; #X connect 10 0 11 0; #X connect 11 0 5 0; #X connect 11 0 12 0; #X connect 12 0 13 0; #X connect 13 0 16 0; #X connect 14 0 16 1; #X connect 14 0 15 1; #X connect 15 0 21 2; #X connect 16 0 21 3; #X connect 17 0 18 0; #X connect 19 0 4 1; #X connect 20 0 19 0; #X connect 21 0 0 0; #X connect 21 0 4 0; #X connect 21 1 17 0; #X connect 22 0 28 0; #X connect 23 0 29 0; #X connect 24 0 26 0; #X connect 24 0 23 0; #X connect 25 0 24 0; #X connect 26 0 27 0; #X connect 27 0 30 0; #X connect 28 0 30 1; #X connect 28 0 29 1; #X connect 29 0 21 0; #X connect 30 0 21 1; #X restore 459 483 pd test; #X text 113 550 etc.: user-friendly filters; #X text 10 387 (Pd also provides a suite of user-friendly filters. This and other raw filters are provided for situations which the user-friendly ones can't handle. See Chapter 8 of http://crca.ucsd.edu/~msp/techniques for an introduction to the necessary theory.); #X text 118 91 <-- signal to filter (real part); #X text 117 173 <-- signal to filter (imaginary part); #X obj 84 172 sig~; #X obj 115 197 sig~; #X text 149 199 <-- filter coefficient (real part); #X obj 145 219 sig~; #X text 159 246 <-- creation arguments initialize filter; #X text 187 262 coefficient (real and imaginary part); #X text 150 144 <-- set internal state (real&imaginary parts); #X msg 64 143 set 0.6 0.8; #X obj 52 7 czero~; #X text 112 7 complex one-zero (non-recursive) filter \, raw; #X text 8 31 Czero~ filters a complex audio signal (first two inlets) via a one-zero filter \, whose coefficients are controlled by creation arguments or by another complex audio signal (remaining two inlets). ; #X text 179 221 <-- filter coefficient (imaginary part); #X text 14 279 The action of czero~ is:; #X text 73 300 y[n] = x[n] - a[n] * x[n-1]; #X text 11 320 where y[n] is the output \, x[n] the input \, and a[n] the filter coefficient (all complex numbers). The filter is always stable.; #X text 12 369 The transfer function is H(Z) = 1 - aZ^-1.; #X obj 53 244 czero~ 0.9 0.4; #X connect 0 0 39 0; #X connect 1 0 39 0; #X connect 23 0 39 1; #X connect 24 0 39 2; #X connect 26 0 39 3; #X connect 30 0 39 0; pd-0.46-7/doc/5.reference/text-object-help.txt0000664000175000017500000000005212222367057017164 0ustar mspmspthis is a message; this is another 1 ...; pd-0.46-7/doc/5.reference/text-help.pd0000664000175000017500000000026412160204055015476 0ustar mspmsp#N canvas 74 127 544 214 12; #X text 281 174 updated for Pd version 0.26; #X text 107 13 comments; #X text 38 73 This is Pd's help window for comments \, which don't do anything.; pd-0.46-7/doc/5.reference/readsf~-help.pd0000664000175000017500000000414012160204055016151 0ustar mspmsp#N canvas 113 157 888 480 12; #X msg 561 8 \; pd dsp 1; #X msg 39 240 1; #X msg 39 261 0; #X obj 516 359 print didit; #X obj 139 361 env~ 16384; #X floatatom 139 380 0 0 0 0 - - -; #X msg 40 283 print; #X obj 20 393 dac~; #X obj 233 360 env~ 16384; #X floatatom 233 379 0 0 0 0 - - -; #X obj 30 308 readsf~ 4 1e+06; #X obj 327 359 env~ 16384; #X floatatom 327 378 0 0 0 0 - - -; #X obj 421 359 env~ 16384; #X floatatom 421 379 0 0 0 0 - - -; #X msg 26 210 open ../sound/bell.aiff 0 200 4 2 b; #X obj 80 362 *~ 0.1; #X obj 21 363 *~ 0.1; #X text 40 7 READSF~ - read a soundfile; #X msg 26 189 open ../sound/bell.aiff; #X text 185 296 optional arguments: number of channels \; buffer size per channnel in bytes.; #X text 548 341 when the soundfile is done.; #X text 547 327 last outlet gives a "bang"; #X text 359 186 Open takes a filename \, an onset in sample frames \, and \, as an override \, you may also supply a header size to skip \, a number of channels \, bytes per channel \, and endianness.; #X text 36 24 The readsf~ object reads a soundfile into its signal outputs. You must open the soundfile in advance (a couple of seconds before you'll need it) using the "open" message. The object immediately starts reading from the file \, but output will only appear after you send a "1" to start playback. A "0" stops it.; #X text 33 121 The wave \, aiff \, and nextstep formats are parsed automatically \, although only 2- 3- and 4- byte samples are accepted (4 bytes implies floating point and is not available in aiff format.) ; #X text 647 450 Updated for version 0.37; #X obj 116 452 soundfiler; #X text 24 452 see also:; #X obj 216 452 readsf~; #X text 94 238 1 starts playback; #X text 97 261 0 stops it; #X connect 1 0 10 0; #X connect 2 0 10 0; #X connect 4 0 5 0; #X connect 6 0 10 0; #X connect 8 0 9 0; #X connect 10 0 4 0; #X connect 10 0 17 0; #X connect 10 1 8 0; #X connect 10 1 16 0; #X connect 10 2 11 0; #X connect 10 2 16 0; #X connect 10 3 13 0; #X connect 10 3 17 0; #X connect 10 4 3 0; #X connect 11 0 12 0; #X connect 13 0 14 0; #X connect 15 0 10 0; #X connect 16 0 7 1; #X connect 17 0 7 0; #X connect 19 0 10 0; pd-0.46-7/doc/5.reference/math-help.pd0000664000175000017500000000434212410567215015454 0ustar mspmsp#N canvas 86 76 548 648 12; #X floatatom 288 319 0 0 0 0 - - -; #X floatatom 231 405 0 0 0 0 - - -; #X floatatom 231 318 0 0 0 0 - - -; #X floatatom 293 574 0 0 0 0 - - -; #X floatatom 293 513 0 0 0 0 - - -; #X floatatom 197 574 0 0 0 0 - - -; #X floatatom 197 513 0 0 0 0 - - -; #X floatatom 129 574 0 0 0 0 - - -; #X floatatom 129 513 0 0 0 0 - - -; #X floatatom 122 382 0 0 0 0 - - -; #X floatatom 122 321 0 0 0 0 - - -; #X floatatom 42 574 0 0 0 0 - - -; #X floatatom 42 513 0 0 0 0 - - -; #X floatatom 223 242 0 0 0 0 - - -; #X floatatom 140 238 0 0 0 0 - - -; #X obj 71 208 sin; #X floatatom 71 123 0 0 0 0 - - -; #X floatatom 71 236 0 0 0 0 - - -; #X obj 71 175 * 6.28319; #X obj 71 149 / 360; #X obj 140 210 cos; #X obj 223 214 tan; #X obj 42 544 sqrt; #X obj 122 352 atan; #X obj 129 544 log; #X obj 197 544 exp; #X obj 293 544 abs; #X obj 231 346 float; #X obj 288 346 t b f; #X obj 231 375 atan2; #X text 29 269 The arc tangent takes two forms. The atan2 version takes an (x \, y) pair and gives you an output between -pi and pi.; #X floatatom 393 574 0 0 0 0 - - -; #X floatatom 393 513 0 0 0 0 - - -; #X obj 393 544 wrap; #X text 39 433 also \, square root \, natural logarithm and exponential \, and absolute value. The "wrap" object wraps the input to a value between 0 and 1 (including negative numbers. For instance \, -0.2 maps to 0.8.); #X text 16 87 Unlike the signal version cos~ \, control-rate trig functions take inputs in radians:; #X text 311 612 updated for Pd version 0.46; #X text 11 612 see also:; #X obj 99 611 cos~; #X text 19 37 Pd offers the mathematical functions sin \, cos \, tan \, atan \, atan2 \, sqrt \, log \, exp \, abs \, and wrap.; #X text 174 6 math function in Pd; #X connect 0 0 28 0; #X connect 2 0 27 0; #X connect 4 0 26 0; #X connect 6 0 25 0; #X connect 8 0 24 0; #X connect 10 0 23 0; #X connect 12 0 22 0; #X connect 15 0 17 0; #X connect 16 0 19 0; #X connect 18 0 15 0; #X connect 18 0 20 0; #X connect 18 0 21 0; #X connect 19 0 18 0; #X connect 20 0 14 0; #X connect 21 0 13 0; #X connect 22 0 11 0; #X connect 23 0 9 0; #X connect 24 0 7 0; #X connect 25 0 5 0; #X connect 26 0 3 0; #X connect 27 0 29 0; #X connect 28 0 27 0; #X connect 28 1 29 1; #X connect 29 0 1 0; #X connect 32 0 33 0; #X connect 33 0 31 0; pd-0.46-7/doc/5.reference/unpack-help.pd0000664000175000017500000000154312160204055015774 0ustar mspmsp#N canvas 234 84 730 277 12; #X floatatom 80 180 0 0 0; #X floatatom 205 180 0 0 0; #X floatatom 243 180 0 0 0; #X floatatom 46 180 0 0 0; #X obj 117 180 print foo; #X obj 133 243 pack; #X text 51 242 See also; #X obj 101 9 unpack; #X text 164 8 - split a message to atoms; #X text 196 139 <-- creation arguments specify the types of atoms expected ; #X msg 46 102 1 2; #X msg 85 102 3 4 shut; #X msg 164 102 5 6 pick 7 8; #X text 368 239 updated for Pd version 0.33; #X obj 46 139 unpack 0 0 s 0 0; #X text 25 36 unpack takes lists of atoms and distributes them to its outlets. The creation arguments specify float (any number or the symbol 'f') \, pointer (symbol 'p') or symbol (symbol 's').; #X connect 10 0 14 0; #X connect 11 0 14 0; #X connect 12 0 14 0; #X connect 14 0 3 0; #X connect 14 1 0 0; #X connect 14 2 4 0; #X connect 14 3 1 0; #X connect 14 4 2 0; pd-0.46-7/doc/5.reference/fft~-help.pd0000664000175000017500000000375512160204055015477 0ustar mspmsp#N canvas 22 7 886 436 12; #X text 85 158 frequency; #X floatatom 16 173 0 0 0 0 - - -; #X obj 16 120 * 44100; #X floatatom 16 94 0 0 0 0 - - -; #X text 88 92 frequency; #X text 91 111 in bins; #X text 85 175 in Hz.; #X obj 16 229 osc~; #X obj 36 16 fft~; #X obj 86 17 ifft~; #X text 146 15 - forward and inverse complex FFT; #X obj 36 42 rfft~; #X obj 86 43 rifft~; #X text 146 41 - forward and inverse real FFT; #X obj 16 254 rfft~; #X obj 16 148 / 64; #X obj 574 21 loadbang; #X msg 574 47 \; pd dsp 1; #X text 636 403 updated for Pd version 0.33; #X obj 16 322 rifft~; #X obj 102 310 print~ real; #X obj 115 285 print~ imaginary; #X obj 16 352 /~ 64; #X obj 16 407 print~ resynthesized; #X msg 30 380 bang; #X msg 101 248 bang; #X msg 100 199 0.25; #X msg 152 199 0; #X text 195 200 <-- bash phase; #X text 152 249 <-- print analysis; #X text 79 380 <-- print resynthesis; #X text 76 352 <-- renormalize; #X text 347 294 There is no normalization \, so that an FFT followed by an IFFT has a gain of N.; #X text 346 343 See the FFT examples to see how to use these in practice. ; #X text 347 205 The real FFT outputs N/2+1 real parts and N/2-1 imaginary parts. The other outputs are zero. At DC and at the Nyquist there is no imaginary part \, but the second through Nth output is as a real and imaginary pair \, which can be thought of as the cosine and sin component strengths.; #X text 346 112 The FFT objects do Fourier analyses and resyntheses of incoming real or complex signals. Complex signals are handled as pairs of signals (real and imaginary part.) The analysis size is one block (you can use the block~ or switch~ objects to control block size). ; #X connect 1 0 7 0; #X connect 2 0 15 0; #X connect 3 0 2 0; #X connect 7 0 14 0; #X connect 14 0 20 0; #X connect 14 0 19 0; #X connect 14 1 21 0; #X connect 14 1 19 1; #X connect 15 0 1 0; #X connect 16 0 17 0; #X connect 19 0 22 0; #X connect 22 0 23 0; #X connect 24 0 23 0; #X connect 25 0 20 0; #X connect 25 0 21 0; #X connect 26 0 7 1; #X connect 27 0 7 1; pd-0.46-7/doc/5.reference/rzero~-help.pd0000664000175000017500000000477712160204055016066 0ustar mspmsp#N canvas 211 109 664 557 12; #X floatatom 104 172 0 0 0 0 - - -; #X obj 54 85 osc~ 100; #X msg 69 117 clear; #X obj 92 520 lop~; #X text 9 520 see also:; #X text 402 521 updated for Pd version-0.38; #X obj 100 459 rzero~; #X obj 35 483 cpole~; #X obj 35 459 rpole~; #X obj 164 459 rzero_rev~; #X obj 100 483 czero~; #X obj 164 483 czero_rev~; #X text 262 459 real; #X text 261 484 complex; #X text 33 438 1-pole; #X text 98 439 1-zero; #X text 162 438 1-zero \, reversed; #X text 57 420 summary of raw filters:; #X msg 71 143 set 1; #X text 125 143 <-- set internal state; #X text 134 86 <-- signal to filter; #X text 137 172 <-- filter coefficient (may be a signal); #X text 132 195 <-- creation argument initializes filter coefficient ; #X text 124 116 <-- clear internal state to zero; #N canvas 393 91 326 287 test 0; #X obj 76 78 osc~; #X floatatom 76 55 5 0 0 0 - - -; #X obj 77 219 env~ 16384; #X floatatom 77 243 5 0 0 0 - - -; #X obj 104 107 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 76 105 *~; #X msg 97 137 set 1; #X floatatom 172 157 4 -100 100 0 - - -; #X obj 172 182 / 100; #X obj 214 256 dac~; #X obj 228 177 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 214 220 *~; #X obj 230 197 / 10; #X text 80 18 Stuff to test it:; #X obj 76 168 rzero~; #X connect 0 0 5 0; #X connect 1 0 0 0; #X connect 2 0 3 0; #X connect 4 0 5 1; #X connect 5 0 14 0; #X connect 6 0 14 0; #X connect 7 0 8 0; #X connect 8 0 14 1; #X connect 10 0 12 0; #X connect 11 0 9 0; #X connect 11 0 9 1; #X connect 12 0 11 1; #X connect 14 0 2 0; #X connect 14 0 11 0; #X restore 457 416 pd test; #X text 136 520 etc.: user-friendly filters; #X obj 52 7 rzero~; #X text 114 7 real one-zero (non-recursive) filter \, raw; #X text 8 35 Rzero~ filters an audio signal (left inlet) via a one-zero real filter \, whose coefficient is controlled by a creation argument or by an audio signal (right inlet).; #X obj 53 195 rzero~ 1; #X text 8 271 where y[n] is the output \, x[n] the input \, and a[n] the filter coefficient. The filter is always stable.; #X text 9 307 The transfer function is H(Z) = 1 - aZ^-1.; #X text 68 250 y[n] = x[n] - a[n] * x[n-1]; #X text 7 330 (Pd also provides a suite of user-friendly filters. This and other raw filters are provided for situations which the user-friendly ones can't handle. See Chapter 8 of http://crca.ucsd.edu/~msp/techniques for an introduction to the necessary theory.); #X text 14 230 The action of rzero~ is:; #X connect 0 0 29 1; #X connect 1 0 29 0; #X connect 2 0 29 0; #X connect 18 0 29 0; pd-0.46-7/doc/5.reference/midi-help.pd0000664000175000017500000000753512374250720015453 0ustar mspmsp#N canvas 267 68 876 553 12; #X floatatom 318 379 0 0 0 0 - - -; #X floatatom 282 468 0 0 0 0 - - -; #X floatatom 200 469 0 0 0 0 - - -; #X text 96 330 off; #X floatatom 52 383 0 0 0 0 - - -; #X floatatom 70 134 0 0 0 0 - - -; #X obj 34 108 notein; #X floatatom 34 134 0 0 0 0 - - -; #X obj 52 488 noteout; #X obj 52 462 makenote 64 250; #X obj 52 409 metro 500; #X msg 52 356 1; #X msg 84 356 0; #X text 52 333 on; #X msg 52 436 60; #X obj 200 496 pgmout; #X obj 282 494 bendout; #X floatatom 416 379 0 0 0 0 - - -; #X floatatom 197 136 0 0 0 0 - - -; #X floatatom 145 136 0 0 0 0 - - -; #X text 41 79 omni; #X floatatom 106 134 0 0 0 0 - - -; #X obj 145 109 notein 1; #X text 145 85 channel 1; #X text 194 17 MIDI I/O objects; #X text 85 54 notes; #X text 334 47 control change; #X text 264 69 everything; #X floatatom 309 137 0 0 0 0 - - -; #X floatatom 271 137 0 0 0 0 - - -; #X floatatom 347 136 0 0 0 0 - - -; #X obj 271 110 ctlin; #X floatatom 440 138 0 0 0 0 - - -; #X floatatom 396 138 0 0 0 0 - - -; #X obj 396 111 ctlin 7; #X text 364 71 specific controller number; #X text 410 88 omni; #X text 496 89 channel 1; #X floatatom 493 140 0 0 0 0 - - -; #X obj 493 114 ctlin 7 1; #X obj 61 221 pgmin; #X floatatom 97 248 0 0 0 0 - - -; #X floatatom 61 248 0 0 0 0 - - -; #X floatatom 197 250 0 0 0 0 - - -; #X floatatom 161 250 0 0 0 0 - - -; #X floatatom 307 253 0 0 0 0 - - -; #X floatatom 272 253 0 0 0 0 - - -; #X floatatom 382 255 0 0 0 0 - - -; #X floatatom 343 253 0 0 0 0 - - -; #X floatatom 420 256 0 0 0 0 - - -; #X obj 161 222 bendin; #X obj 272 226 touchin; #X obj 343 227 polytouchin; #X text 49 167 these can also take an optional channel number as argument but by default are omni:; #X text 32 197 program change; #X text 155 198 pitch bend; #X text 271 203 channel and poly aftertouch; #X floatatom 191 380 0 0 0 0 - - -; #X floatatom 224 380 0 0 0 0 - - -; #X floatatom 260 382 0 0 0 0 - - -; #X obj 191 407 ctlout; #X obj 318 406 ctlout 7; #X text 192 349 control out; #X text 314 353 control 7; #X text 409 354 control 7 \, channel 4; #X obj 416 406 ctlout 7 4; #X text 101 277 outputs work similarly. They all take an optional channel as creation argument \, and ctlin takes a control number and a channel. You get inlets to change them in any case. IF you specify no channel \, it's channel 1; #X floatatom 355 467 0 0 0 0 - - -; #X floatatom 440 466 0 0 0 0 - - -; #X obj 355 493 touchout; #X obj 440 492 polytouchout; #X floatatom 479 467 0 0 0 0 - - -; #X floatatom 520 467 0 0 0 0 - - -; #X obj 625 218 midiin; #X floatatom 625 249 0 0 0 0 - - -; #X floatatom 656 249 0 0 0 0 - - -; #X floatatom 695 249 0 0 0 0 - - -; #X floatatom 726 250 0 0 0 0 - - -; #X text 590 155 These two are always omni and; #X text 590 174 output the port number instead; #X text 594 192 of the channel:; #X obj 697 218 sysexin; #X obj 623 472 midiout; #X text 571 413 use this to output raw MIDI; #X text 566 433 (the second inlet is the port; #X text 569 451 number.); #X text 625 514 updated for Pd release 0.33; #X connect 0 0 61 0; #X connect 1 0 16 0; #X connect 2 0 15 0; #X connect 4 0 10 0; #X connect 6 0 7 0; #X connect 6 1 5 0; #X connect 6 2 21 0; #X connect 9 0 8 0; #X connect 9 1 8 1; #X connect 10 0 14 0; #X connect 11 0 4 0; #X connect 12 0 4 0; #X connect 14 0 9 0; #X connect 17 0 65 0; #X connect 22 0 19 0; #X connect 22 1 18 0; #X connect 31 0 29 0; #X connect 31 1 28 0; #X connect 31 2 30 0; #X connect 34 0 33 0; #X connect 34 1 32 0; #X connect 39 0 38 0; #X connect 40 0 42 0; #X connect 40 1 41 0; #X connect 50 0 44 0; #X connect 50 1 43 0; #X connect 51 0 46 0; #X connect 51 1 45 0; #X connect 52 0 48 0; #X connect 52 1 47 0; #X connect 52 2 49 0; #X connect 57 0 60 0; #X connect 58 0 60 1; #X connect 59 0 60 2; #X connect 67 0 69 0; #X connect 68 0 70 0; #X connect 71 0 70 1; #X connect 72 0 70 2; #X connect 73 0 74 0; #X connect 73 1 75 0; #X connect 81 0 76 0; #X connect 81 1 77 0; pd-0.46-7/doc/5.reference/tabreceive~-help.pd0000664000175000017500000000071612160204055017023 0ustar mspmsp#N canvas 295 230 646 239 12; #X obj 21 18 tabreceive~; #X text 129 18 - read a block of a signal from an array continuously ; #X msg 64 125 set my-table; #X obj 64 160 tabreceive~ my-table; #X text 380 202 updated for Pd version 0.43; #X text 21 77 By default a block is 64 samples but this can be reset using the block~ object.; #X text 239 160 creation argument: initializes table name; #X text 180 125 'set' message to change table name; #X connect 2 0 3 0; pd-0.46-7/doc/5.reference/tabread4-help.pd0000664000175000017500000000266012160204055016202 0ustar mspmsp#N canvas 61 69 685 536 12; #X text 89 188 index; #X obj 36 9 tabread; #X floatatom 52 189 0 0 0 0 - - -; #X floatatom 52 285 0 0 0 0 - - -; #N canvas 0 0 450 300 (subpatch) 0; #X array array99 10 float 3; #A 0 9 0 8 1 7 2 6 3 5 4; #X coords 0 10 10 0 250 200 1 0 0; #X restore 398 219 graph; #X text 90 286 output = array99[index]; #X text 196 243 creation argument; #X text 198 259 gives array name; #X msg 62 211 set array99; #X text 174 211 change array name; #X text 109 9 - read numbers from a table; #X msg 36 363 \; array99 xlabel -0.5 0 1 2 3 4 5 6 7 8 9 10 \; array99 ylabel -1 0 1 2 3 4 5 6 7 8 9 10; #X text 449 486 updated for Pd version 0.43; #X obj 37 337 loadbang; #X text 8 433 see also the "array" tutorial in section 2 of the Pd documentation \, and these objects:; #X obj 9 472 tabwrite~; #X obj 213 472 tabwrite; #X obj 278 472 tabsend~; #X obj 343 472 tabreceive~; #X obj 80 472 tabplay~; #X obj 52 251 tabread4 array99; #X obj 148 472 tabread; #X text 59 44 The tabread4 object reads values from an array ("table") according to an index \, applying four-point polynomial interpolation. Indices should range from 1 to (size-2) so that the 4-point interpolation is meaningful. You can shift-drag the number box to see the effect of interpolation.Indices outside of the range are replaced by the nearest index in range (from 1 to 8 in this example).; #X connect 2 0 20 0; #X connect 8 0 20 0; #X connect 13 0 11 0; #X connect 20 0 3 0; pd-0.46-7/doc/5.reference/phasor~-help.pd0000664000175000017500000000252212160204055016203 0ustar mspmsp#N canvas 5 31 889 373 12; #X graph graph1 0 1 100 -1 67 250 267 350; #X array array99 100 float; #X pop; #X obj 29 181 metro 500; #X obj 13 126 phasor~; #X floatatom 13 76 0 0 0; #X obj 57 12 phasor~; #X obj 29 156 r metro; #X obj 13 100 sig~ 890; #X text 78 75 <-- specify frequency; #X text 92 98 <-- convert it to audio signal; #X msg 409 75 \; metro 0; #X msg 405 18 \; pd dsp 1 \; metro 1; #X text 494 32 <-- Click to start; #X text 479 79 <-- Click to stop; #X text 129 14 - sawtooth generator; #X text 170 207 <-- graph the output; #X text 82 128 <-- right inlet resets phase; #X obj 425 227 phasor~ 440; #X floatatom 425 203 0 0 0; #X text 348 118 The phasor~ object outputs a sawtooth signal \, traditionally used for table lookup via cos~ or tabread4~. If no argument is supplied \, the input is taken to be an audio signal \; with a floating-point argument \, phasor~ takes floating-point messages to change frequency.; #X text 294 246 Invoked above with argument for non-signal input. Incoming messages override the initial value.; #X text 311 301 see also:; #X obj 396 301 osc~; #X obj 439 301 cos~; #X obj 481 301 tabread4~; #X text 627 345 updated for Pd version 0.33; #X obj 13 205 tabwrite~ array99; #X connect 1 0 25 0; #X connect 2 0 25 0; #X connect 3 0 6 0; #X connect 5 0 1 0; #X connect 5 0 1 0; #X connect 6 0 2 0; #X connect 17 0 16 0; pd-0.46-7/doc/5.reference/delay-help.pd0000664000175000017500000000455012374250720015621 0ustar mspmsp#N canvas 549 146 631 711 12; #X obj 123 11 delay; #X floatatom 128 418 0 0 0 0 - - -; #X text 168 12 - CALLBACK AFTER TIME DELAY; #X msg -5 184 stop; #X text 11 667 see also:; #X obj 133 666 timer; #X obj 85 666 metro; #X msg -5 208 2000; #X obj -4 472 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj -5 162 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 140 642 del; #X text 17 642 Also known as:; #X text 371 659 updated for Pd version 0.45; #X text 16 159 bang: start; #X text 55 182 stop: cancel the delay; #X text 54 208 number: set delay time and start; #X text 157 419 <-- number in inlet: set delay time but don't start ; #X text 182 446 <-- optional creation arguments:; #X obj -5 445 delay 1000 1 msec; #X msg -5 234 tempo 0.5 msec; #X text 231 465 - delay time (float); #X text 232 483 - tempo (float) and time unit (symbol) as in "tempo" message, f 31; #X obj 274 547 delay 1 60 permin; #X text 14 538 example: specify a delay of one beat at 60 beats per minute, f 31; #X obj 305 604 delay 1 1 persec; #X obj 305 580 delay 1 1 sec; #X obj 446 580 delay 1 44100 samp; #X obj 446 604 delay 44100 1 samp; #X obj 305 627 delay 0.01676 1 min; #X text 14 579 other possible ways to get a one-second delay (but the rightmost ones are sample-rate dependent), f 35; #X text 45 37 The delay object sends a bang to its outlet after a delay in milliseconds specified by its right inlet or its creation argument. Sending a bang to a delay which is already set will reschedule its output \, replacing any previous setting.; #X text 42 114 Delays are in millisconds by default \, but you can set the time units in the creation arguments or with a "tempo" message. , f 63; #X text 117 368 If the tempo is changed while the delay is in progress \, the change only applies to the remaining fraction of the delay. ; #X text 125 234 Set tempo. Units can be miliseconds (msec for short) \, seconds (sec) \, minutes (min) or samples (samp). In this example the unit is set to 1/2 millisecond so that '1000' gives a delay of 500 msec (1/2 second). Equivalently you can say "tempo 2 permsec" or even "120000 permin". A more traditionally musical way to specify a one-second delay would be "delay 1" with "tempo 60 permin" as in the second example below.; #X connect 1 0 18 1; #X connect 3 0 18 0; #X connect 7 0 18 0; #X connect 9 0 18 0; #X connect 18 0 8 0; #X connect 19 0 18 0; pd-0.46-7/doc/5.reference/setsize-help.pd0000664000175000017500000000475712425762153016227 0ustar mspmsp#N struct help-setsize-template float x float y array array1 help-setsize-array1-template ; #N struct help-setsize-array1-template float y; #N canvas 490 274 666 517 12; #X text 32 443 see also:; #N canvas 393 50 495 265 help-setsize-template 0; #X obj 27 174 filledpolygon 509 509 0 -10 -10 10 -10 10 10 -10 10; #X obj 27 76 plot array1 500 1 10 15 10; #X obj 24 16 struct help-setsize-template float x float y array array1 help-setsize-array1-template; #X restore 367 365 pd help-setsize-template; #N canvas 2 52 299 169 help-setsize-data 1; #X scalar help-setsize-template 31 23 \; 0 \; 10 \; 0 \; 10 \; 20 \; 10 \; 20 \; 70 \; 0 \; 0 \; 0 \; \;; #X restore 366 344 pd help-setsize-data; #N canvas 196 292 369 138 help-setsize-array1-template 0; #X obj 30 71 filledpolygon 0 0 0 -5 0 0 5 5 0 0 -5; #X obj 32 27 struct help-setsize-array1-template float y; #X restore 366 388 pd help-setsize-array1-template; #X obj 108 463 pointer; #X obj 243 463 setsize; #X obj 307 265 pointer; #X msg 307 241 traverse pd-help-setsize-data \, next; #X floatatom 24 238 5 0 0 0 - - -, f 5; #X text 327 319 arguments: template \, field name; #X obj 24 322 setsize help-setsize-template array1; #X text 114 292 inlet for pointer; #X obj 36 11 setsize; #X obj 175 463 element; #X text 30 205 number sets; #X text 29 219 size; #X text 99 12 -- resize an array; #X text 25 34 "setsize" takes a pointer to a scalar at left and a number at right. Its creation arguments specify the template of the pointer and the name of an array field. Sending a number then sets the number of elements of the array.; #X text 23 100 The smallest possible size is one. If the array is resized downward the extra data are lost. If resized upward \, the new elements are initialized to default values.; #X msg 565 422 bang; #X text 298 424 click to reload from file -->; #X text 309 222 click here first; #N canvas 458 61 439 176 readit 1; #X msg 66 65 \; pd-help-setsize-data read setsize.txt; #X obj 107 18 inlet; #X msg 62 123 \; pd-help-setsize-data write setsize.txt; #X connect 1 0 0 0; #X restore 565 448 pd readit; #X obj 29 463 struct; #X text 417 479 updated for Pd version 0.47; #X text 67 250 set template and field name; #X text 20 154 If you don't know the template name you may specify "-" \, in which case the object will figure out the template name itself \, at some possible cost in efficiancy and clarity.; #X msg 33 272 set help-setsize-template array1; #X connect 6 0 10 1; #X connect 7 0 6 0; #X connect 8 0 10 0; #X connect 19 0 22 0; #X connect 27 0 10 0; pd-0.46-7/doc/5.reference/wrap~-help.pd0000664000175000017500000000137712160204055015667 0ustar mspmsp#N canvas 182 132 703 319 12; #X obj 58 220 metro 500; #X obj 58 195 r metro; #X msg 575 106 \; metro 0; #X msg 574 48 \; pd dsp 1 \; metro 1; #X floatatom 42 121 0 0 0; #X floatatom 42 277 0 0 0; #X text 443 271 updated for Pd version 0.33; #X obj 574 21 loadbang; #X obj 42 244 snapshot~; #X obj 42 147 sig~; #X obj 36 16 wrap~; #X text 93 16 - remainder modulo 1; #X text 18 45 wrap~ gives the difference between the input and the largest integer not exceeding it (for positive numbers this is the fractional part).; #X obj 42 171 wrap~; #X text 127 123 <-- shift-drag here to get non-integers to try; #X connect 0 0 8 0; #X connect 1 0 0 0; #X connect 1 0 0 0; #X connect 4 0 9 0; #X connect 7 0 3 0; #X connect 8 0 5 0; #X connect 9 0 13 0; #X connect 13 0 8 0; pd-0.46-7/doc/5.reference/canvas-help.pd0000664000175000017500000000256312374250720016000 0ustar mspmsp#N canvas 102 88 575 525 12; #X obj 51 48 table; #X text 108 49 - Array of numbers; #X obj 44 312 table help-tab1 25; #X text 20 156 "Table" builds a subpatch with a graphical array inside. The creation arguments specify the name and an optional size in points. ; #X msg 77 368 \; help-tab1 read table.txt; #X msg 77 412 \; help-tab1 write /tmp/table.txt; #X text 77 346 You can also send messages to the array by name:; #X text 216 312 <- optional creation args: name \, size; #X text 19 214 Note that the data (and other properties) of the array aren't saved with the patch. You can resize \, save to and/or read from an external file as you would with "array" objects. See "arrays" in the 2.control examples under the "pure documentation" help menu item.; #N canvas 1 51 450 300 (subpatch) 0; #X restore 51 23 pd; #X text 108 24 - subpatch; #X text 342 494 updated for Pd version 0.46; #X text 17 462 see also:; #X obj 108 461 array; #N canvas 1 51 471 242 foo 0; #X obj 56 42 inlet; #X obj 50 139 outlet; #X text 120 36 this is the subpatch. Use "inlet" and "outlet" objects to creat inlets/outlets on the parent., f 34; #X restore 38 113 pd foo; #X text 118 115 <- optional argument to name the subpatch; #X text 27 75 "Pd" created a subpatch. Click on the object to open the subpatch. They may be nested as deeply as you like.; #X text 161 462 (newer and better replacement for "table").; pd-0.46-7/doc/5.reference/send-help.pd0000664000175000017500000000163212160204055015443 0ustar mspmsp#N canvas 257 45 511 351 12; #X text 278 321 updated for Pd version 0.32; #X obj 21 10 send; #X text 60 11 -- send messages without patch cords; #X obj 36 80 send help-send1; #X obj 152 81 send help-send1; #X obj 271 81 send help-send2; #X obj 38 110 receive help-send1; #X obj 171 110 receive help-send2; #X obj 305 110 receive help-send2; #X floatatom 36 55 5 0 0; #X floatatom 152 58 5 0 0; #X floatatom 272 57 5 0 0; #X floatatom 38 134 5 0 0; #X floatatom 171 136 5 0 0; #X floatatom 305 134 5 0 0; #X obj 161 320 s; #X text 62 321 abbreviation:; #X text 31 161 "Send" sends messages to "receive" objects. Sends and receives are named to tell them whom to connect to. They work across windows too. Also \, you can use message boxes as shown:; #X msg 84 233 \; help-send1 34 \; help-send2 67; #X connect 6 0 12 0; #X connect 7 0 13 0; #X connect 8 0 14 0; #X connect 9 0 3 0; #X connect 10 0 4 0; #X connect 11 0 5 0; pd-0.46-7/doc/5.reference/savepanel-help.pd0000664000175000017500000000072012160204055016465 0ustar mspmsp#N canvas 9 118 567 234 12; #X msg 102 92 bang; #X obj 102 145 print; #X text 295 199 updated for Pd version 0.24; #X text 28 192 see also:; #X text 16 35 When Savepanel gets a "bang" a "Save As" file browser appears on the screen \, If you choose a filename \, it appears on the outlet.; #X obj 102 120 savepanel; #X obj 115 191 openpanel; #X obj 19 7 savepanel; #X text 104 6 - query you for the name of a file to create; #X connect 0 0 5 0; #X connect 5 0 1 0; pd-0.46-7/doc/5.reference/netsend-help.pd0000664000175000017500000000611312375265406016170 0ustar mspmsp#N canvas 299 17 1043 631 12; #X obj 38 389 netsend; #X msg 38 285 connect localhost 3000; #X msg 47 367 send foo \$1; #X floatatom 47 340 0 0 0 0 - - -; #X msg 38 312 disconnect; #X msg 249 363 send foo \$1; #X msg 232 310 disconnect; #X msg 232 285 connect localhost 3001; #X floatatom 38 416 0 0 0 0 - - -; #X floatatom 232 415 0 0 0 0 - - -; #X text 197 9 Netsend -- send Pd messages over a network; #X text 713 311 Close the connection; #X obj 178 594 netreceive; #X text 87 594 see also:; #X obj 657 521 netsend 1; #X text 742 520 (UDP); #X text 75 513 An old (pre-0.45) calling convention is provided for compatibility: a single float argument \, "0" or "1" for TCP or UDP respectively:, f 69; #X obj 232 388 netsend -u; #X text 732 390 creation arguments:; #X text 800 409 optional -u flag for UDP; #X text 800 428 optional -b flag for binary; #X floatatom 249 336 0 0 0 0 - - -; #X text 670 337 Send messages to "foo" on remote machine; #X text 89 264 TCP \, ascii; #X text 307 261 UDP \, ascii; #X msg 424 311 disconnect; #X floatatom 424 416 0 0 0 0 - - -; #X floatatom 441 337 0 0 0 0 - - -; #X msg 441 364 send 1 2 3 \$1; #X msg 424 286 connect localhost 3002; #X msg 617 311 disconnect; #X floatatom 617 416 0 0 0 0 - - -; #X floatatom 634 337 0 0 0 0 - - -; #X text 666 259 UDP \, binary; #X msg 634 364 send 1 2 3 \$1; #X obj 617 389 netsend -u -b; #X text 473 259 TCP \, binary; #X text 806 273 Connect to "localhost" port number, f 22; #X obj 424 389 netsend -b; #X msg 617 286 connect localhost 3003; #X text 83 188 The Pd distribution includes "pdsend" and "pdreceive" standalone programs that work with netsend/netreceive in ASCII mode. , f 83; #X text 85 27 The Netsend object connects to another machine over the network for sending TCP ("stream") or UDP ("datagram") messages. An outlet reports whether the connection is open or not. A connection request should specify the name or IP address of the other host and the port number. There should be a "netreceive" on the remote host with a matching port number., f 83; #X text 84 114 By default the messages are ASCII text messages compatible with Pd (i.e. \, numbers and symbols terminated with a semicolon -- the "FUDI" protocol). The "-b" creation argument specifies binary messages instead \, which appear in Pd as lists of numbers from 0 to 255 (You could use this to send OSC messages \, for example.), f 83; #X obj 81 426 print backward; #X obj 477 422 print backward; #X text 61 455 First outlet is nonzero if connection is open \, zero otherwise., f 62; #X text 72 474 Second outlet (TCP only) outputs messages sent back from netreceive object., f 75; #X text 754 592 updated for Pd version 0.46; #X connect 0 0 8 0; #X connect 0 1 43 0; #X connect 1 0 0 0; #X connect 2 0 0 0; #X connect 3 0 2 0; #X connect 4 0 0 0; #X connect 5 0 17 0; #X connect 6 0 17 0; #X connect 7 0 17 0; #X connect 17 0 9 0; #X connect 21 0 5 0; #X connect 25 0 38 0; #X connect 27 0 28 0; #X connect 28 0 38 0; #X connect 29 0 38 0; #X connect 30 0 35 0; #X connect 32 0 34 0; #X connect 34 0 35 0; #X connect 35 0 31 0; #X connect 38 0 26 0; #X connect 38 1 44 0; #X connect 39 0 35 0; pd-0.46-7/doc/5.reference/toggle-help.pd0000664000175000017500000002043412374250720016003 0ustar mspmsp#N canvas 331 179 463 463 10; #X obj 1 1 cnv 8 100 60 empty empty toggle=tgl 20 20 1 18 -262144 -1109 0; #X text 21 296 (c) musil@iem.kug.ac.at; #X text 63 309 IEM KUG; #X text 115 41 click properties to; #X text 103 52 modify geometry \, colors \, etc.; #X obj 168 113 bng 15 250 50 0 empty empty empty 8 -8 0 10 -262144 -1 -1; #X obj 168 179 bng 15 250 50 0 empty empty empty 8 -8 0 10 -262144 -1 -1; #X obj 168 133 s foo6_rcv; #X obj 168 159 r foo6_snd; #X text 153 14 gui-toggle:; #X obj 26 270 bng 15 250 50 0 empty empty empty 8 -8 0 10 -262144 -1 -1; #X obj 10 117 bng 15 250 50 0 empty empty empty 8 -8 0 10 -262144 -1 -1; #X msg 26 39 33; #X obj 26 180 tgl 60 1 foo6_snd foo6_rcv big_toggle 63 20 2 13 -228992 -4033 -34 1 1; #X msg 42 79 1; #X msg 49 99 0; #X floatatom 26 249 4 0 0 0 - - -, f 4; #X msg 33 59 -0.001; #X msg 103 135 set 1; #X msg 108 157 set 0; #X obj 3 155 tgl 15 0 empty empty empty 8 -8 0 10 -262144 -1 -1 0 1 ; #X obj 65 249 tgl 15 0 empty empty empty 8 -8 0 10 -262144 -1 -1 1 1; #X msg 95 114 set -0.23; #X obj 189 93 tgl 15 0 empty empty empty 8 -8 0 10 -262144 -1 -1 0 1; #X obj 188 179 tgl 15 0 empty empty empty 8 -8 0 10 -262144 -1 -1 1 1; #X msg 93 93 0 3 4.55; #X msg 85 73 0.22 0 -5.44; #X msg 189 113 set \$1; #X text 96 222 UP- \, DOWN- \, LEFT- or RIGHT-key; #X text 95 233 for moving selected gui-objects; #N canvas 440 175 699 530 edit 0; #X msg 47 151 \; foo6_rcv color \$1 \$2 \$3; #X obj 47 126 pack 0 0 0; #X obj 47 98 f; #X msg 24 50 bang; #X floatatom 63 48 3 0 29 0 - - -, f 3; #X floatatom 79 68 3 0 29 0 - - -, f 3; #X floatatom 112 84 3 0 29 0 - - -, f 3; #X text 91 48 background; #X text 106 68 front-color; #X text 140 85 label-color; #X obj 49 223 f; #X msg 27 202 bang; #X floatatom 65 201 3 63 88 0 - - -, f 3; #X floatatom 100 223 3 0 37 0 - - -, f 3; #X obj 49 246 pack 0 0; #X text 127 223 y-label; #X text 93 201 x-label; #X msg 49 271 \; foo6_rcv label_pos \$1 \$2; #X floatatom 505 55 3 8 75 0 - - -, f 3; #X text 532 55 size; #X msg 505 76 \; foo6_rcv size \$1; #X obj 282 182 f; #X msg 260 161 bang; #X floatatom 298 160 3 -10 10 0 - - -, f 3; #X floatatom 333 182 3 -10 10 0 - - -, f 3; #X obj 282 205 pack 0 0; #X msg 282 230 \; foo6_rcv delta \$1 \$2; #X obj 296 301 f; #X msg 274 280 bang; #X floatatom 312 279 3 20 60 0 - - -, f 3; #X floatatom 347 301 3 150 200 0 - - -, f 3; #X obj 296 324 pack 0 0; #X msg 296 349 \; foo6_rcv pos \$1 \$2; #X text 326 160 x-delta; #X text 360 182 y-delta; #X text 340 279 x-position; #X text 374 301 y-position; #X obj 305 423 f; #X msg 283 402 bang; #X floatatom 321 401 3 -10 10 0 - - -, f 3; #X floatatom 356 423 3 -10 10 0 - - -, f 3; #X obj 305 446 pack 0 0; #X text 383 423 y-label; #X text 349 401 x-label; #X msg 305 471 \; foo6_rcv delta \$1 \$2; #X msg 499 140 \; foo6_rcv send foo6a_snd; #X msg 499 178 \; foo6_rcv send foo6_snd; #X msg 494 216 \; foo6_rcv receive foo6a_rcv; #X msg 494 254 \; foo6a_rcv receive foo6_rcv; #X msg 41 448 \; foo6_rcv label blabla; #X msg 41 484 \; foo6_rcv label big_toggle; #X obj 69 338 f; #X msg 47 317 bang; #X floatatom 85 316 3 0 2 0 - - -, f 3; #X floatatom 120 338 3 4 36 0 - - -, f 3; #X obj 69 361 pack 0 0; #X msg 69 386 \; foo6_rcv label_font \$1 \$2; #X text 113 316 font; #X text 149 338 height; #X floatatom 498 307 5 -200 200 0 - - -, f 5; #X text 542 307 nonzero-value; #X msg 498 331 \; foo6_rcv nonzero \$1; #X msg 503 412 \; foo6_rcv init 0; #X msg 510 479 \; foo6_rcv init 1; #X text 524 393 no init; #X text 500 461 init value on loadbang; #X msg 285 47 back; #X msg 285 67 front; #X msg 285 87 label; #X msg 247 47 bang; #N canvas 15 207 606 448 RGB_____________ 0; #X obj 97 56 inlet; #X obj 262 53 inlet; #X obj 339 55 inlet; #X obj 405 56 inlet; #X obj 97 270 bang; #X msg 77 295 0; #X msg 104 295 1; #X obj 146 268 bang; #X msg 132 295 0; #X msg 160 295 1; #X obj 196 269 bang; #X msg 187 295 0; #X msg 214 295 1; #X obj 265 313 spigot; #X obj 312 313 spigot; #X obj 359 313 spigot; #X obj 249 385 outlet; #X text 93 33 select; #X text 267 28 red; #X text 337 30 green; #X text 409 30 blue; #X obj 405 102 t b f; #X obj 339 160 +; #X obj 339 185 t b f; #X obj 339 216 +; #X obj 296 385 outlet; #X obj 343 385 outlet; #X obj 28 180 loadbang; #X obj 97 135 route back front label bang; #X obj 343 362 f; #X obj 296 361 f; #X obj 249 361 f; #X obj 262 79 * -65536; #X obj 339 80 * -256; #X obj 405 80 * -1; #X obj 339 247 - 1; #X obj 235 168 t b b b b; #X connect 0 0 28 0; #X connect 1 0 32 0; #X connect 2 0 33 0; #X connect 3 0 34 0; #X connect 4 0 5 0; #X connect 4 0 6 0; #X connect 5 0 14 1; #X connect 5 0 15 1; #X connect 6 0 13 1; #X connect 7 0 8 0; #X connect 7 0 9 0; #X connect 8 0 13 1; #X connect 8 0 15 1; #X connect 9 0 14 1; #X connect 10 0 11 0; #X connect 10 0 12 0; #X connect 11 0 13 1; #X connect 11 0 14 1; #X connect 12 0 15 1; #X connect 13 0 31 1; #X connect 14 0 30 1; #X connect 15 0 29 1; #X connect 21 0 22 0; #X connect 21 1 22 1; #X connect 22 0 23 0; #X connect 23 0 24 0; #X connect 23 1 24 1; #X connect 24 0 35 0; #X connect 27 0 6 0; #X connect 28 0 4 0; #X connect 28 1 7 0; #X connect 28 2 10 0; #X connect 28 3 36 0; #X connect 29 0 26 0; #X connect 30 0 25 0; #X connect 31 0 16 0; #X connect 32 0 24 0; #X connect 33 0 22 0; #X connect 34 0 21 0; #X connect 35 0 15 0; #X connect 35 0 14 0; #X connect 35 0 13 0; #X connect 36 0 31 0; #X connect 36 1 30 0; #X connect 36 2 29 0; #X connect 36 3 35 0; #X restore 285 108 pd RGB_____________; #X floatatom 327 77 3 0 255 0 - - -, f 3; #X floatatom 370 77 3 0 255 0 - - -, f 3; #X floatatom 413 78 3 0 255 0 - - -, f 3; #X text 34 22 preset-colors; #X text 296 19 RGB-colors; #X text 327 59 red; #X text 363 58 green; #X text 411 58 blue; #X connect 1 0 0 0; #X connect 2 0 1 0; #X connect 3 0 2 0; #X connect 4 0 2 1; #X connect 5 0 1 1; #X connect 6 0 1 2; #X connect 10 0 14 0; #X connect 11 0 10 0; #X connect 12 0 10 1; #X connect 13 0 14 1; #X connect 14 0 17 0; #X connect 18 0 20 0; #X connect 21 0 25 0; #X connect 22 0 21 0; #X connect 23 0 21 1; #X connect 24 0 25 1; #X connect 25 0 26 0; #X connect 27 0 31 0; #X connect 28 0 27 0; #X connect 29 0 27 1; #X connect 30 0 31 1; #X connect 31 0 32 0; #X connect 37 0 41 0; #X connect 38 0 37 0; #X connect 39 0 37 1; #X connect 40 0 41 1; #X connect 41 0 44 0; #X connect 51 0 55 0; #X connect 52 0 51 0; #X connect 53 0 51 1; #X connect 54 0 55 1; #X connect 55 0 56 0; #X connect 59 0 61 0; #X connect 66 0 70 0; #X connect 67 0 70 0; #X connect 68 0 70 0; #X connect 69 0 70 0; #X connect 70 0 1 0; #X connect 70 1 1 1; #X connect 70 2 1 2; #X connect 71 0 70 1; #X connect 72 0 70 2; #X connect 73 0 70 3; #X restore 278 136 pd edit; #X obj 222 276 tgl 15 0 bbb bbb empty 20 8 0 8 -262144 -1 -1 0 1; #X text 38 321 graz \, austria 2002; #X obj 127 255 x_all_guis aaa bbb ccc ddd eee fff ggg hhh iii; #X text 223 431 updated for Pd version 0.46; #N canvas 324 270 524 322 old-behavior 0; #X floatatom 26 40 5 0 0 0 - - -, f 5; #X floatatom 24 180 5 0 0 0 - - -, f 5; #X msg 96 192 \; pd compatibility 0.45; #X msg 275 193 \; pd compatibility 0.46; #X text 113 230 Old "compatible" behavior, f 16; #X text 282 230 Mew "correct" behavior; #X obj 26 69 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 16 ; #X msg 28 17 0; #X msg 65 19 50; #X floatatom 106 23 5 0 0 0 - - -, f 5; #X msg 102 41 nonzero \$1; #X text 63 74 Pressing the toggle \, if it is in "off" state \, resets it to its "value" which is normally one. Prior to Pd version 0.46 \, the value itself was changed if non-zero numbers were sent to the toggle. Now the value may still be changed explicitly with a "nonzero" message but doesn't change by toggling. You can get the old behavior globally by sending Pd a compatibility message as below:; #X connect 0 0 6 0; #X connect 6 0 1 0; #X connect 7 0 0 0; #X connect 8 0 0 0; #X connect 9 0 10 0; #X connect 10 0 6 0; #X restore 290 391 pd old-behavior; #X text 29 352 COMPATIBILIY NOTE: as of Pd 0.46 \, sending numbers through a toggle no longer resets the "value" field. You can get the old behavior back this way:; #X connect 5 0 7 0; #X connect 8 0 6 0; #X connect 8 0 24 0; #X connect 11 0 13 0; #X connect 12 0 13 0; #X connect 13 0 16 0; #X connect 13 0 21 0; #X connect 14 0 13 0; #X connect 15 0 13 0; #X connect 16 0 10 0; #X connect 17 0 13 0; #X connect 18 0 13 0; #X connect 19 0 13 0; #X connect 20 0 13 0; #X connect 22 0 13 0; #X connect 23 0 27 0; #X connect 25 0 13 0; #X connect 26 0 13 0; #X connect 27 0 7 0; pd-0.46-7/doc/5.reference/scalar-object-help.pd0000664000175000017500000000422412374250720017232 0ustar mspmsp#N canvas 558 349 688 433 12; #X text 34 388 see also:; #X text 485 171 (click for details:), f 11; #N canvas 930 175 716 699 define 0; #X text 324 399 creation arguments:; #X text 217 152 send a pointer to a named receive object; #X floatatom 145 299 5 0 0 0 - - -, f 5; #X text 46 408 click to open or edit array:; #X msg 31 116 read scalar-object-help.txt; #X text 258 117 read/write a file TBW; #X obj 145 251 r scalar-help-send; #X text 359 457 template; #X text 360 478 optional name (TBW); #X obj 145 275 get scalar-help-template1 x; #N canvas 464 264 450 300 scalar-help-template1 0; #X obj 62 55 struct scalar-help-template1 float x float y; #X obj 55 99 drawpolygon 3 3 0 0 0 30 30 30 30 0 0 0; #X msg 89 193 traverse pd-scalar-help-template1 \, bang; #X obj 89 218 pointer; #X msg 20 195 40 40; #X obj 53 252 append scalar-help-template1 x y; #X connect 2 0 3 0; #X connect 3 0 5 2; #X connect 4 0 5 0; #X restore 471 57 pd scalar-help-template1; #X floatatom 404 244 3 0 500 0 - - -, f 3; #X obj 506 244 r scalar-help-send; #X obj 405 282 set scalar-help-template1 x y; #X floatatom 458 244 3 0 500 0 - - -, f 3; #X text 32 20 "scalar define" defines and maintains a scalar.; #X text 471 29 here's the template:; #X obj 145 324 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X msg 40 152 send scalar-help-send; #X obj 27 435 scalar define -k scalar-help-template1; #A set scalar-help-template1 175 150 \;; #X text 360 435 optional -k flag to keep contents; #X connect 2 0 17 0; #X connect 4 0 19 0; #X connect 6 0 9 0; #X connect 9 0 2 0; #X connect 11 0 13 0; #X connect 12 0 13 2; #X connect 14 0 13 1; #X connect 18 0 19 0; #X restore 486 212 pd define; #X obj 163 388 text; #X text 201 210 - create \, store \, and/or edit one; #X text 96 260 (later); #X obj 19 8 scalar; #X text 77 7 - create a scalar datum; #X obj 90 212 scalar define; #X text 194 261 - more stuff; #X text 81 180 The first argument sets the function:; #X obj 114 387 array; #X obj 204 388 list; #X text 101 57 experimental - doesn't do much yet. This is included in 0.45 to check that its design will work coherently with the array and text objects.; #X text 444 398 updated for Pd version 0.45; pd-0.46-7/doc/5.reference/hradio-help.pd0000664000175000017500000001712412374250720015772 0ustar mspmsp#N canvas 25 53 394 569 10; #X obj 1 1 cnv 8 100 60 empty empty hradio 20 20 1 18 -262144 -1109 0; #X text 109 130 click properties to; #X text 97 141 modify geometry \, colors \, etc.; #X obj 60 254 bng 15 250 50 0 empty empty empty 8 -8 0 10 -262144 -1 -1; #X obj 21 54 bng 15 250 50 0 empty empty empty 8 -8 0 10 -262144 -1 -1; #X obj 59 206 s foo11_rcv; #X obj 60 232 r foo11_snd; #X floatatom 21 398 4 0 0 0 - - -, f 4; #X obj 21 420 bng 15 250 50 0 empty empty empty 8 -8 0 10 -262144 -1 -1; #X msg 157 73 set \$1; #X floatatom 157 52 4 0 9 0 - - -, f 4; #X floatatom 44 54 4 0 9 0 - - -, f 4; #X msg 84 50 7 0 -5.44; #X msg 88 72 3 3 4.55; #X obj 62 388 print; #X floatatom 84 280 4 0 0 0 - - -, f 4; #X msg 84 254 \$1; #X msg 59 185 set \$1; #X floatatom 59 164 4 0 9 0 - - -, f 4; #X text 59 318 UP- \, DOWN- \, LEFT- or RIGHT-key; #X text 58 329 for moving selected gui-objects; #N canvas 221 206 699 530 edit 0; #X obj 42 198 f; #X msg 20 177 bang; #X floatatom 58 176 3 63 156 0 - - -, f 3; #X floatatom 93 198 3 -20 37 0 - - -, f 3; #X obj 42 221 pack 0 0; #X text 120 198 y-label; #X text 86 176 x-label; #X floatatom 270 187 3 8 50 0 - - -, f 3; #X text 297 187 size; #X obj 286 293 f; #X msg 264 272 bang; #X floatatom 302 271 3 -10 10 0 - - -, f 3; #X floatatom 337 293 3 -10 10 0 - - -, f 3; #X obj 286 316 pack 0 0; #X obj 300 412 f; #X msg 278 391 bang; #X floatatom 316 390 3 20 60 0 - - -, f 3; #X floatatom 351 412 3 100 200 0 - - -, f 3; #X obj 300 435 pack 0 0; #X text 330 271 x-delta; #X text 364 293 y-delta; #X text 344 390 x-position; #X text 378 412 y-position; #X obj 62 313 f; #X msg 40 292 bang; #X floatatom 78 291 3 0 2 0 - - -, f 3; #X floatatom 113 313 3 4 36 0 - - -, f 3; #X obj 62 336 pack 0 0; #X text 106 291 font; #X text 142 313 height; #X text 504 293 no init; #X text 475 348 init value on loadbang; #X floatatom 482 228 5 2 20 0 - - -, f 5; #X msg 47 125 \; foo11_rcv color \$1 \$2 \$3; #X msg 42 246 \; foo11_rcv label_pos \$1 \$2; #X msg 62 361 \; foo11_rcv label_font \$1 \$2; #X msg 34 423 \; foo11_rcv label blabla; #X msg 300 460 \; foo11_rcv pos \$1 \$2; #X msg 286 341 \; foo11_rcv delta \$1 \$2; #X msg 270 216 \; foo11_rcv size \$1; #X msg 482 171 \; foo11a_rcv receive foo11_rcv; #X msg 483 133 \; foo11_rcv receive foo11a_rcv; #X msg 483 88 \; foo11_rcv send foo11_snd; #X msg 483 50 \; foo11_rcv send foo11a_snd; #X msg 483 312 \; foo11_rcv init 0; #X msg 485 366 \; foo11_rcv init 1; #X msg 490 436 \; foo11_rcv single_change; #X msg 490 470 \; foo11_rcv double_change; #X text 491 417 changing-behavior; #X msg 482 254 \; foo11_rcv number \$1; #X text 526 228 number of buttons; #X msg 34 459 \; foo11_rcv label radio_0_9; #X obj 47 104 pack 0 0 0; #X obj 47 76 f; #X msg 24 28 bang; #X floatatom 63 26 3 0 29 0 - - -, f 3; #X floatatom 79 46 3 0 29 0 - - -, f 3; #X floatatom 112 62 3 0 29 0 - - -, f 3; #X text 91 26 background; #X text 106 46 front-color; #X text 140 63 label-color; #X msg 285 25 back; #X msg 285 45 front; #X msg 285 65 label; #X msg 247 25 bang; #N canvas 15 207 606 448 RGB_____________ 0; #X obj 97 56 inlet; #X obj 262 53 inlet; #X obj 339 55 inlet; #X obj 405 56 inlet; #X obj 97 270 bang; #X msg 77 295 0; #X msg 104 295 1; #X obj 146 268 bang; #X msg 132 295 0; #X msg 160 295 1; #X obj 196 269 bang; #X msg 187 295 0; #X msg 214 295 1; #X obj 265 313 spigot; #X obj 312 313 spigot; #X obj 359 313 spigot; #X obj 249 385 outlet; #X text 93 33 select; #X text 267 28 red; #X text 337 30 green; #X text 409 30 blue; #X obj 405 102 t b f; #X obj 339 160 +; #X obj 339 185 t b f; #X obj 339 216 +; #X obj 296 385 outlet; #X obj 343 385 outlet; #X obj 28 180 loadbang; #X obj 97 135 route back front label bang; #X obj 343 362 f; #X obj 296 361 f; #X obj 249 361 f; #X obj 262 79 * -65536; #X obj 339 80 * -256; #X obj 405 80 * -1; #X obj 339 247 - 1; #X obj 235 168 t b b b b; #X connect 0 0 28 0; #X connect 1 0 32 0; #X connect 2 0 33 0; #X connect 3 0 34 0; #X connect 4 0 5 0; #X connect 4 0 6 0; #X connect 5 0 14 1; #X connect 5 0 15 1; #X connect 6 0 13 1; #X connect 7 0 8 0; #X connect 7 0 9 0; #X connect 8 0 13 1; #X connect 8 0 15 1; #X connect 9 0 14 1; #X connect 10 0 11 0; #X connect 10 0 12 0; #X connect 11 0 13 1; #X connect 11 0 14 1; #X connect 12 0 15 1; #X connect 13 0 31 1; #X connect 14 0 30 1; #X connect 15 0 29 1; #X connect 21 0 22 0; #X connect 21 1 22 1; #X connect 22 0 23 0; #X connect 23 0 24 0; #X connect 23 1 24 1; #X connect 24 0 35 0; #X connect 27 0 6 0; #X connect 28 0 4 0; #X connect 28 1 7 0; #X connect 28 2 10 0; #X connect 28 3 36 0; #X connect 29 0 26 0; #X connect 30 0 25 0; #X connect 31 0 16 0; #X connect 32 0 24 0; #X connect 33 0 22 0; #X connect 34 0 21 0; #X connect 35 0 15 0; #X connect 35 0 14 0; #X connect 35 0 13 0; #X connect 36 0 31 0; #X connect 36 1 30 0; #X connect 36 2 29 0; #X connect 36 3 35 0; #X restore 285 86 pd RGB_____________; #X floatatom 327 55 3 0 255 0 - - -, f 3; #X floatatom 370 55 3 0 255 0 - - -, f 3; #X floatatom 413 56 3 0 255 0 - - -, f 3; #X text 34 0 preset-colors; #X text 296 -3 RGB-colors; #X text 327 37 red; #X text 363 36 green; #X text 411 36 blue; #X connect 0 0 4 0; #X connect 1 0 0 0; #X connect 2 0 0 1; #X connect 3 0 4 1; #X connect 4 0 34 0; #X connect 7 0 39 0; #X connect 9 0 13 0; #X connect 10 0 9 0; #X connect 11 0 9 1; #X connect 12 0 13 1; #X connect 13 0 38 0; #X connect 14 0 18 0; #X connect 15 0 14 0; #X connect 16 0 14 1; #X connect 17 0 18 1; #X connect 18 0 37 0; #X connect 23 0 27 0; #X connect 24 0 23 0; #X connect 25 0 23 1; #X connect 26 0 27 1; #X connect 27 0 35 0; #X connect 32 0 49 0; #X connect 52 0 33 0; #X connect 53 0 52 0; #X connect 54 0 53 0; #X connect 55 0 53 1; #X connect 56 0 52 1; #X connect 57 0 52 2; #X connect 61 0 65 0; #X connect 62 0 65 0; #X connect 63 0 65 0; #X connect 64 0 65 0; #X connect 65 0 52 0; #X connect 65 1 52 1; #X connect 65 2 52 2; #X connect 66 0 65 1; #X connect 67 0 65 2; #X connect 68 0 65 3; #X restore 166 220 pd edit; #X text 144 11 gui-vertical dial:; #X text 133 437 IEM KUG; #X text 117 425 musil; #X text 157 425 @; #X text 170 426 iem.at; #X text 68 414 (c) Thomas Musil 2000 - 2005; #X text 116 447 Graz \, Austria; #X obj 21 106 hradio 25 1 0 10 foo11_snd foo11_rcv radio_0_9 32 12 0 10 -99865 -262144 -260818 3; #X text 46 355 float out; #X text 174 533 updated for Pd version 0.46; #N canvas 110 96 494 298 old-behavior 0; #X obj 66 151 hradio 15 1 0 8 empty empty empty 0 -8 0 10 -262144 -1 -1 0.5; #X floatatom 65 127 5 0 0 0 - - -, f 5; #X floatatom 65 173 5 0 0 0 - - -, f 5; #X msg 60 208 \; pd compatibility 0.45; #X msg 239 209 \; pd compatibility 0.46; #X text 77 246 Old "compatible" behavior, f 16; #X text 246 246 Mew "correct" behavior; #X text 38 21 Prior to Pd version 0.46 \, values sent to IEM controls were restricted to the control's own values before passing them through to the output. This behavior is changed in 0.46. You can toggle back and forth between the two behaviors using the messages boxes below. If you want to get the behavior in an up-to-date patch \, you can use "int" and "clip" objects to quantize and restrict the range o numbers. ; #X msg 111 126 0.5; #X msg 146 126 -12; #X connect 0 0 2 0; #X connect 1 0 0 0; #X connect 8 0 0 0; #X connect 9 0 0 0; #X restore 234 512 pd old-behavior; #X text 14 469 COMPATIBILIY NOTE: as of Pd 0.46 \, you can pass through numbers ouside the object's range. You can get the old behavior back this way:, f 48; #X connect 4 0 29 0; #X connect 6 0 3 0; #X connect 6 0 16 0; #X connect 7 0 8 0; #X connect 9 0 29 0; #X connect 10 0 9 0; #X connect 11 0 29 0; #X connect 12 0 29 0; #X connect 13 0 29 0; #X connect 16 0 15 0; #X connect 17 0 5 0; #X connect 18 0 17 0; #X connect 29 0 7 0; #X connect 29 0 14 0; pd-0.46-7/doc/5.reference/acoustics~-help.pd0000664000175000017500000000427212160204055016710 0ustar mspmsp#N canvas 35 42 813 458 12; #X obj 158 118 mtof~; #X obj 158 174 snapshot~; #X obj 698 132 metro 100; #X floatatom 158 205 0 0 0; #X obj 49 174 snapshot~; #X floatatom 49 55 0 0 0; #X floatatom 49 205 0 0 0; #X obj 49 118 ftom~; #X obj 264 174 snapshot~; #X floatatom 264 205 0 0 0; #X obj 264 118 dbtorms~; #X obj 697 58 loadbang; #X msg 709 88 \; pd dsp 1; #X obj 49 86 sig~; #X floatatom 158 55 0 0 0; #X obj 158 86 sig~; #X floatatom 264 54 0 0 0; #X obj 264 86 sig~; #X obj 492 172 snapshot~; #X floatatom 492 203 0 0 0; #X obj 383 172 snapshot~; #X floatatom 383 53 0 0 0; #X floatatom 383 203 0 0 0; #X obj 607 172 snapshot~; #X floatatom 607 203 0 0 0; #X obj 383 84 sig~; #X floatatom 492 53 0 0 0; #X obj 492 84 sig~; #X floatatom 607 53 0 0 0; #X obj 607 84 sig~; #X obj 383 115 rmstodb~; #X obj 492 115 dbtopow~; #X obj 607 115 powtodb~; #X obj 17 10 mtof~; #X text 70 11 (etc) - conversions for audio signals; #X text 60 400 see also:; #X obj 145 400 mtof; #X text 192 400 (etc.); #X text 547 416 updated for Pd version 0.33; #X text 43 241 These objects convert MIDI pitch to frequency and back \, and dB to and from RMS and power. THey take audio signals as input and output (and work sample by sample.) Since they call library math functions \, they may be much more expensive than other workaday tilde objects such as *~ and osc~ \, depending on your hardware and math library.; #X text 41 343 Boundary conditions are handled "reasonably". 100 db is assigned an RMS of 1 \, and dbtorms~ and dbtopow~ output true zero for 0 dB and less.; #X connect 0 0 1 0; #X connect 1 0 3 0; #X connect 2 0 1 0; #X connect 2 0 8 0; #X connect 2 0 4 0; #X connect 2 0 20 0; #X connect 2 0 18 0; #X connect 2 0 23 0; #X connect 4 0 6 0; #X connect 5 0 13 0; #X connect 7 0 4 0; #X connect 8 0 9 0; #X connect 10 0 8 0; #X connect 11 0 2 0; #X connect 11 0 12 0; #X connect 13 0 7 0; #X connect 14 0 15 0; #X connect 15 0 0 0; #X connect 16 0 17 0; #X connect 17 0 10 0; #X connect 18 0 19 0; #X connect 20 0 22 0; #X connect 21 0 25 0; #X connect 23 0 24 0; #X connect 25 0 30 0; #X connect 26 0 27 0; #X connect 27 0 31 0; #X connect 28 0 29 0; #X connect 29 0 32 0; #X connect 30 0 20 0; #X connect 31 0 18 0; #X connect 32 0 23 0; pd-0.46-7/doc/5.reference/symbol-help.pd0000664000175000017500000000172312374250720016027 0ustar mspmsp#N canvas 531 220 562 404 12; #X msg 30 107 bang; #X text 120 244 creation argument initializes the value; #X text 319 368 updated for Pd version 0.45; #X text 75 104 output the value; #X text 139 130 set and output the value; #X obj 29 241 symbol foo; #X obj 55 12 symbol; #X text 111 14 - STORE A SYMBOL (I.E. \, STRING); #X text 21 37 The symbol object stores a symbol \, pd's data type for handling fixed strings (often filenames or the names of other objects in pd).; #X msg 44 131 symbol bar; #X symbolatom 30 269 10 0 0 0 - - -, f 10; #X text 202 215 set the value; #X symbolatom 106 217 10 0 0 0 - - -, f 10; #X msg 50 161 zorglub; #X text 119 161 any other message is 'converted'; #X text 48 303 note: unlike "float" \, etc. \, there's no "s" message to forward to another object -- that would conflict with the function of converting arbitrary messages to symbols.; #X connect 0 0 5 0; #X connect 5 0 10 0; #X connect 9 0 5 0; #X connect 12 0 5 1; #X connect 13 0 5 0; pd-0.46-7/doc/5.reference/operators-help.pd0000664000175000017500000000200412160204055016522 0ustar mspmsp#N canvas 52 109 635 355 12; #X obj 29 172 +; #X floatatom 41 113 0 0 0; #X floatatom 29 197 0 0 0; #X floatatom 51 143 0 0 0; #X msg 29 82 bang; #X obj 44 6 +; #X text 27 307 see also:; #X obj 186 314 +~; #X text 79 5 (etc.) -- ARITHMETIC; #X text 72 88 Bang outputs sum; #X text 79 112 Numbers in left inlet add and output sum; #X text 93 142 Numbers in right inlet only change the inlet's value; #X obj 113 314 trigger; #X text 348 325 last updated for version 0.33; #X text 93 189 You can supply a creation argument to initialize the right inlet:; #X text 29 29 The floating point binary operators are + \, - \, * \, / \, pow \, max \, and min. Note that pow only works for nonnegative mantissas.; #X floatatom 101 225 0 0 0; #X floatatom 101 275 0 0 0; #X obj 101 250 pow -1; #X floatatom 179 225 0 0 0; #X floatatom 179 275 0 0 0; #X obj 179 250 min 20; #X connect 0 0 2 0; #X connect 1 0 0 0; #X connect 3 0 0 1; #X connect 4 0 0 0; #X connect 16 0 18 0; #X connect 18 0 17 0; #X connect 19 0 21 0; #X connect 21 0 20 0; pd-0.46-7/doc/5.reference/change-help.pd0000664000175000017500000000141112160204055015732 0ustar mspmsp#N canvas 376 130 540 355 12; #X msg 67 124 bang; #X floatatom 67 266 0 0 0; #X floatatom 79 154 0 0 0; #X floatatom 104 182 0 0 0; #X text 284 309 updated for Pd version 0.27; #X text 173 239 creation argument initializes first value; #X obj 66 15 change; #X text 114 16 - ELIMINATE REDUNDANCY IN A NUMBER STEAM; #X text 12 42 The change object outputs its input only when it changes. You can "set" the current value \, or bang to force output.; #X obj 67 240 change 6.5; #X msg 105 211 set \$1; #X text 136 183 set the value; #X text 112 123 output current value; #X text 110 154 if different from current value \, output and set; #X obj 67 293 print; #X connect 0 0 9 0; #X connect 1 0 14 0; #X connect 2 0 9 0; #X connect 3 0 10 0; #X connect 9 0 1 0; #X connect 10 0 9 0; pd-0.46-7/doc/5.reference/get-help.pd0000664000175000017500000000507212425762207015307 0ustar mspmsp#N struct help-get-template1 float x float y symbol s; #N canvas 546 108 630 629 12; #X text 24 576 see also:; #X obj 190 574 set; #X obj 225 574 append; #X obj 27 602 getsize; #X obj 95 602 setsize; #X obj 163 602 element; #X msg 58 117 next; #N canvas 292 338 631 204 help-get-template1 0; #X obj 41 87 filledpolygon 9 0 1 0 0 20 0 20 30 0 30; #X obj 60 21 struct help-get-template1 float x float y symbol s; #X restore 447 508 pd help-get-template1; #N canvas 2 131 276 156 help-get-data 1; #X scalar help-get-template1 46 23 dog \;; #X scalar help-get-template1 106 73 cat \;; #X restore 447 486 pd help-get-data; #X obj 21 10 get; #X text 61 8 -- get values from a scalar; #X msg 43 89 traverse pd-help-get-data \, next; #X floatatom 43 198 5 0 0 0 - - -, f 5; #X floatatom 166 198 5 0 0 0 - - -, f 5; #X obj 43 144 pointer; #X text 321 88 output first scalar in list; #X text 101 116 output next item; #X text 306 153 First argument selects template.; #X text 306 169 Remaining args are names of fields.; #X text 39 214 x output; #X text 164 215 y output; #X obj 123 574 pointer; #X obj 231 602 struct; #X obj 43 172 get help-get-template1 x y s; #X text 250 216 s output; #X symbolatom 254 198 6 0 0 0 - - -, f 6; #X obj 116 145 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X msg 461 248 traverse pd-help-get-data \, next, f 17; #X obj 461 304 pointer; #X msg 122 435 traverse pd-help-get-data \, next; #X obj 122 461 pointer; #X obj 122 544 get; #X msg 137 486 set help-get-template1 x; #X msg 136 511 set - y; #X obj 461 330 get - x; #X floatatom 461 355 5 0 0 0 - - -, f 5; #X text 390 593 updated for Pd version 0.47; #X text 22 378 If there are zero or one data fields specified \, you can use the "set" message to change the template and/or field name on the fly:, f 47; #X text 31 37 "Get" \, when sent a pointer to a scalar \, retrieves fields from it by name. The fields can be float or symbol., f 59; #X text 527 327 wild card template, f 9; #X text 14 252 If you have data whose template is variable (from a heterogeneous list \, for example) you can use the template "-" as a wild card. In Pd 0.47 and earlier \, there is no penalty for this \, but future versions may run faster with pre-specified templates than with "-" (by looking up the variable names in advance)., f 46 ; #X connect 6 0 14 0; #X connect 11 0 14 0; #X connect 14 0 23 0; #X connect 14 1 26 0; #X connect 23 0 12 0; #X connect 23 1 13 0; #X connect 23 2 25 0; #X connect 27 0 28 0; #X connect 28 0 34 0; #X connect 29 0 30 0; #X connect 30 0 31 0; #X connect 32 0 31 0; #X connect 33 0 31 0; #X connect 34 0 35 0; pd-0.46-7/doc/5.reference/tabread-help.pd0000664000175000017500000000251312160204055016113 0ustar mspmsp#N canvas 58 46 685 536 12; #X text 89 188 index; #X obj 36 9 tabread; #X obj 52 251 tabread array99; #X floatatom 52 189 0 0 0 0 - - -; #X floatatom 52 285 0 0 0 0 - - -; #N canvas 0 0 450 300 (subpatch) 0; #X array array99 10 float 3; #A 0 9 0 8 1 7 2 6 3 5 4; #X coords 0 10 10 0 250 200 1 0 0; #X restore 398 219 graph; #X text 90 286 output = array99[index]; #X text 196 243 creation argument; #X text 198 259 gives array name; #X msg 62 211 set array99; #X text 174 211 change array name; #X text 109 9 - read numbers from a table; #X msg 36 363 \; array99 xlabel -0.5 0 1 2 3 4 5 6 7 8 9 10 \; array99 ylabel -1 0 1 2 3 4 5 6 7 8 9 10; #X text 449 486 updated for Pd version 0.43; #X obj 37 337 loadbang; #X text 8 433 see also the "array" tutorial in section 2 of the Pd documentation \, and these objects:; #X obj 9 472 tabwrite~; #X obj 213 472 tabwrite; #X obj 278 472 tabsend~; #X obj 343 472 tabreceive~; #X obj 80 472 tabplay~; #X obj 148 472 tabread4; #X text 59 45 The tabread object reads values from an array ("table") according to an index. The index is rounded down to the next lower integer. Values in the table correspond to indices starting at 0 Indices outside of the range are replaced by the nearest index in range (from 0 to 9 in this example).; #X connect 2 0 4 0; #X connect 3 0 2 0; #X connect 9 0 2 0; #X connect 14 0 12 0; pd-0.46-7/doc/5.reference/value-help.pd0000664000175000017500000000176012374250720015637 0ustar mspmsp#N canvas 256 52 566 300 12; #X text 290 257 updated for Pd version 0.32; #X floatatom 36 55 5 0 0 0 - - -, f 5; #X text 50 249 abbreviation:; #X text 79 10 -- nonlocal shared value (named variable); #X floatatom 36 130 5 0 0 0 - - -, f 5; #X msg 46 78 bang; #X obj 21 10 value; #X obj 36 105 value help-value1; #X obj 167 250 v; #X floatatom 180 55 5 0 0 0 - - -, f 5; #X floatatom 180 130 5 0 0 0 - - -, f 5; #X msg 190 78 bang; #X obj 180 105 value help-value1; #X floatatom 328 55 5 0 0 0 - - -, f 5; #X floatatom 328 130 5 0 0 0 - - -, f 5; #X msg 338 78 bang; #X obj 328 105 value help-value2; #X text 31 171 "Value" stores a numeric value which is shared between all values with the same name (which need not be in the same Pd window.) ; #X text 382 54 numbers set the value; #X text 386 77 bang retrieves it; #X connect 1 0 7 0; #X connect 5 0 7 0; #X connect 7 0 4 0; #X connect 9 0 12 0; #X connect 11 0 12 0; #X connect 12 0 10 0; #X connect 13 0 16 0; #X connect 15 0 16 0; #X connect 16 0 14 0; pd-0.46-7/doc/5.reference/hdial-help.pd0000664000175000017500000001641312160204055015576 0ustar mspmsp#N canvas 106 314 612 281 10; #X obj 1 1 cnv 8 100 60 empty empty hdial=hdl 20 20 1 18 -262144 -1109 0; #X text 16 213 (c) musil@iem.kug.ac.at; #X text 58 226 IEM KUG; #X text 289 52 click properties to; #X text 277 63 modify geometry \, colors \, etc.; #X obj 356 172 bng 15 250 50 0 empty empty empty 8 -8 0 10 -262144 -1 -1; #X obj 21 54 bng 15 250 50 0 empty empty empty 8 -8 0 10 -262144 -1 -1; #X obj 355 124 s foo8_rcv; #X obj 356 150 r foo8_snd; #X obj 44 100 hdl 25 1 1 10 foo8_snd foo8_rcv hdial_0_9 156 -8 192 10 -99865 -262144 -260818 2; #X msg 44 142 \$1; #X floatatom 44 164 4 0 0; #X obj 44 186 bng 15 250 50 0 empty empty empty 8 -8 0 10 -262144 -1 -1; #X obj 89 161 tgl 12 0 empty empty empty 8 -8 0 10 -262144 -1 -1 0 1; #X obj 89 140 route 0 1 2 3 4 5 6 7 8 9; #X msg 176 64 set \$1; #X floatatom 176 43 4 0 9; #X floatatom 44 54 4 0 9; #X msg 91 41 7 0 -5.44; #X msg 95 63 3 3 4.55; #X obj 106 161 tgl 12 0 empty empty empty 8 -8 0 10 -262144 -1 -1 0 1; #X obj 123 161 tgl 12 0 empty empty empty 8 -8 0 10 -262144 -1 -1 1 1; #X obj 140 161 tgl 12 0 empty empty empty 8 -8 0 10 -262144 -1 -1 0 1; #X obj 157 161 tgl 12 0 empty empty empty 8 -8 0 10 -262144 -1 -1 0 1; #X obj 174 161 tgl 12 0 empty empty empty 8 -8 0 10 -262144 -1 -1 0 1; #X obj 191 161 tgl 12 0 empty empty empty 8 -8 0 10 -262144 -1 -1 0 1; #X obj 208 161 tgl 12 0 empty empty empty 8 -8 0 10 -262144 -1 -1 0 1; #X obj 225 161 tgl 12 0 empty empty empty 8 -8 0 10 -262144 -1 -1 0 1; #X obj 242 161 tgl 12 0 empty empty empty 8 -8 0 10 -262144 -1 -1 0 1; #X obj 82 178 print; #X floatatom 380 198 4 0 0; #X msg 380 172 \$1; #X msg 355 103 set \$1; #X floatatom 355 82 4 0 9; #X text 128 178 UP- \, DOWN- \, LEFT- or RIGHT-key; #X text 127 189 for moving selected gui-objects; #N canvas 226 227 699 530 edit 0; #X obj 42 198 f; #X msg 20 177 bang; #X floatatom 58 176 3 63 156; #X floatatom 93 198 3 -20 37; #X obj 42 221 pack 0 0; #X text 120 198 y-label; #X text 86 176 x-label; #X floatatom 270 187 3 8 50; #X text 297 187 size; #X obj 286 293 f; #X msg 264 272 bang; #X floatatom 302 271 3 -10 10; #X floatatom 337 293 3 -10 10; #X obj 286 316 pack 0 0; #X obj 300 412 f; #X msg 278 391 bang; #X floatatom 316 390 3 20 60; #X floatatom 351 412 3 100 200; #X obj 300 435 pack 0 0; #X text 330 271 x-delta; #X text 364 293 y-delta; #X text 344 390 x-position; #X text 378 412 y-position; #X obj 62 313 f; #X msg 40 292 bang; #X floatatom 78 291 3 0 2; #X floatatom 113 313 3 4 36; #X obj 62 336 pack 0 0; #X text 106 291 font; #X text 142 313 height; #X text 504 293 no init; #X text 475 348 init value on loadbang; #X floatatom 482 228 5 2 20; #X msg 47 125 \; foo8_rcv color \$1 \$2 \$3; #X msg 42 246 \; foo8_rcv label_pos \$1 \$2; #X msg 62 361 \; foo8_rcv label_font \$1 \$2; #X msg 34 423 \; foo8_rcv label blabla; #X msg 300 460 \; foo8_rcv pos \$1 \$2; #X msg 286 341 \; foo8_rcv delta \$1 \$2; #X msg 270 216 \; foo8_rcv size \$1; #X msg 482 171 \; foo8a_rcv receive foo8_rcv; #X msg 483 133 \; foo8_rcv receive foo8a_rcv; #X msg 483 88 \; foo8_rcv send foo8_snd; #X msg 483 50 \; foo8_rcv send foo8a_snd; #X msg 483 312 \; foo8_rcv init 0; #X msg 485 366 \; foo8_rcv init 1; #X msg 490 436 \; foo8_rcv single_change; #X msg 490 470 \; foo8_rcv double_change; #X text 491 417 changing-behavior; #X msg 482 254 \; foo8_rcv number \$1; #X text 526 228 number of buttons; #X obj 47 104 pack 0 0 0; #X obj 47 76 f; #X msg 24 28 bang; #X floatatom 63 26 3 0 29; #X floatatom 79 46 3 0 29; #X floatatom 112 62 3 0 29; #X text 91 26 background; #X text 106 46 front-color; #X text 140 63 label-color; #X msg 285 25 back; #X msg 285 45 front; #X msg 285 65 label; #X msg 247 25 bang; #N canvas 15 207 606 448 RGB_____________ 0; #X obj 97 56 inlet; #X obj 262 53 inlet; #X obj 339 55 inlet; #X obj 405 56 inlet; #X obj 97 270 bang; #X msg 77 295 0; #X msg 104 295 1; #X obj 146 268 bang; #X msg 132 295 0; #X msg 160 295 1; #X obj 196 269 bang; #X msg 187 295 0; #X msg 214 295 1; #X obj 265 313 spigot; #X obj 312 313 spigot; #X obj 359 313 spigot; #X obj 249 385 outlet; #X text 93 33 select; #X text 267 28 red; #X text 337 30 green; #X text 409 30 blue; #X obj 405 102 t b f; #X obj 339 160 +; #X obj 339 185 t b f; #X obj 339 216 +; #X obj 296 385 outlet; #X obj 343 385 outlet; #X obj 28 180 loadbang; #X obj 97 135 route back front label bang; #X obj 343 362 f; #X obj 296 361 f; #X obj 249 361 f; #X obj 262 79 * -65536; #X obj 339 80 * -256; #X obj 405 80 * -1; #X obj 339 247 - 1; #X obj 235 168 t b b b b; #X connect 0 0 28 0; #X connect 1 0 32 0; #X connect 2 0 33 0; #X connect 3 0 34 0; #X connect 4 0 5 0; #X connect 4 0 6 0; #X connect 5 0 14 1; #X connect 5 0 15 1; #X connect 6 0 13 1; #X connect 7 0 8 0; #X connect 7 0 9 0; #X connect 8 0 13 1; #X connect 8 0 15 1; #X connect 9 0 14 1; #X connect 10 0 11 0; #X connect 10 0 12 0; #X connect 11 0 13 1; #X connect 11 0 14 1; #X connect 12 0 15 1; #X connect 13 0 31 1; #X connect 14 0 30 1; #X connect 15 0 29 1; #X connect 21 0 22 0; #X connect 21 1 22 1; #X connect 22 0 23 0; #X connect 23 0 24 0; #X connect 23 1 24 1; #X connect 24 0 35 0; #X connect 27 0 6 0; #X connect 28 0 4 0; #X connect 28 1 7 0; #X connect 28 2 10 0; #X connect 28 3 36 0; #X connect 29 0 26 0; #X connect 30 0 25 0; #X connect 31 0 16 0; #X connect 32 0 24 0; #X connect 33 0 22 0; #X connect 34 0 21 0; #X connect 35 0 15 0; #X connect 35 0 14 0; #X connect 35 0 13 0; #X connect 36 0 31 0; #X connect 36 1 30 0; #X connect 36 2 29 0; #X connect 36 3 35 0; #X restore 285 86 pd RGB_____________; #X floatatom 327 55 3 0 255; #X floatatom 370 55 3 0 255; #X floatatom 413 56 3 0 255; #X text 34 0 preset-colors; #X text 296 -3 RGB-colors; #X text 327 37 red; #X text 363 36 green; #X text 411 36 blue; #X msg 34 459 \; foo8_rcv label hdial_0_9; #X connect 0 0 4 0; #X connect 1 0 0 0; #X connect 2 0 0 1; #X connect 3 0 4 1; #X connect 4 0 34 0; #X connect 7 0 39 0; #X connect 9 0 13 0; #X connect 10 0 9 0; #X connect 11 0 9 1; #X connect 12 0 13 1; #X connect 13 0 38 0; #X connect 14 0 18 0; #X connect 15 0 14 0; #X connect 16 0 14 1; #X connect 17 0 18 1; #X connect 18 0 37 0; #X connect 23 0 27 0; #X connect 24 0 23 0; #X connect 25 0 23 1; #X connect 26 0 27 1; #X connect 27 0 35 0; #X connect 32 0 49 0; #X connect 51 0 33 0; #X connect 52 0 51 0; #X connect 53 0 52 0; #X connect 54 0 52 1; #X connect 55 0 51 1; #X connect 56 0 51 2; #X connect 60 0 64 0; #X connect 61 0 64 0; #X connect 62 0 64 0; #X connect 63 0 64 0; #X connect 64 0 51 0; #X connect 64 1 51 1; #X connect 64 2 51 2; #X connect 65 0 64 1; #X connect 66 0 64 2; #X connect 67 0 64 3; #X restore 469 108 pd edit; #X obj 346 35 hdl 15 1 0 8 eee eee empty 20 8 192 8 -262144 -1 -1 0 ; #X obj 260 11 x_all_guis aaa bbb ccc ddd eee fff ggg hhh iii; #X text 183 11 gui-hdial:; #X text 33 238 graz \, austria 2002; #X text 251 232 updated for Pd version 0.35; #X connect 6 0 9 0; #X connect 8 0 5 0; #X connect 8 0 31 0; #X connect 9 0 10 0; #X connect 9 0 14 0; #X connect 9 0 29 0; #X connect 10 0 11 0; #X connect 11 0 12 0; #X connect 14 0 13 0; #X connect 14 1 20 0; #X connect 14 2 21 0; #X connect 14 3 22 0; #X connect 14 4 23 0; #X connect 14 5 24 0; #X connect 14 6 25 0; #X connect 14 7 26 0; #X connect 14 8 27 0; #X connect 14 9 28 0; #X connect 15 0 9 0; #X connect 16 0 15 0; #X connect 17 0 9 0; #X connect 18 0 9 0; #X connect 19 0 9 0; #X connect 31 0 30 0; #X connect 32 0 7 0; #X connect 33 0 32 0; pd-0.46-7/doc/5.reference/vd~-help.pd0000664000175000017500000000201012160204055015310 0ustar mspmsp#N canvas 109 10 654 410 12; #X floatatom 50 194 0 0 0; #X obj 50 287 outlet~; #X text 130 286 signal output (delayed signal); #X obj 24 16 vd~; #X text 60 9 reads a signal from a delay line at a variable delay time (4-point-interpolation); #X obj 50 222 sig~; #X text 99 219 signal input (delay time in ms); #X obj 50 254 vd~ del_example; #X text 193 252 creation argument: name of delay line; #X text 31 51 vd~ implements a 4-point interpolating delay tap from a corresponding delwrite~ object. The delay in milliseconds of the tap is specified by the incoming signal.; #X text 35 340 see also:; #X obj 123 343 delwrite~; #X obj 212 342 delread~; #X text 354 373 updated for Pd version 0.33; #X text 28 103 The delay time is always at least one sample and at most the length of the delay line (specified by hte delwrite~). In addition \, in case the delwrite~ runs later in the DSP loop than the vd~ \, the delay is constrained below by one vector length (64 samples.); #X connect 0 0 5 0; #X connect 5 0 7 0; #X connect 7 0 1 0; pd-0.46-7/doc/5.reference/tabwrite-help.pd0000664000175000017500000000144012160204055016330 0ustar mspmsp#N canvas 44 17 653 456 12; #X obj 31 27 tabwrite; #X floatatom 9 176 0 0 0; #X obj 9 282 tabwrite array99; #X text 113 28 write numbers to a table; #X graph graph1 0 0 10 10 355 389 605 189; #X array array99 10 float; #X pop; #X msg 9 53 \; readout 1 \; array99 resize 10 \; array99 bounds 0 0 10 10 \; array99 xlabel -0.5 0 1 2 3 4 5 6 7 8 9 10 \; array99 ylabel -1 0 1 2 3 4 5 6 7 8 9 10 \; array99 0 1 4 2 8 5 6 1 4 2 8; #X text 406 94 click here to initialize; #X floatatom 146 257 0 0 0; #X text 158 279 creation argument; #X text 160 297 is array name; #X text 46 174 set y value; #X text 44 239 right inlet selects x value; #X msg 25 204 set array99; #X text 133 203 change array name; #X text 389 423 updated for Pd version 0.33; #X connect 1 0 2 0; #X connect 7 0 2 1; #X connect 12 0 2 0; pd-0.46-7/doc/5.reference/print-help.pd0000664000175000017500000000127012160204055015644 0ustar mspmsp#N canvas 349 65 546 306 12; #X msg 102 52 walk the dog; #X msg 29 51 bang; #X msg 70 51 234; #X obj 29 96 print x1; #X obj 21 10 print; #X text 29 130 Print prints out the messages it receives on the "terminal window" that Pd is run from.; #X text 73 10 -- print messages to terminal window; #X text 27 167 Long symbol arguments are truncated to 78 characters and marked with "*" (but message selectors are printed in full.); #X obj 100 267 print -n; #X text 27 202 With the special "-n" argument the "print:" prefix is suppressed:; #X text 333 282 updated for Pd version 0.42; #X floatatom 101 244 5 0 0 0 - - -; #X connect 0 0 3 0; #X connect 1 0 3 0; #X connect 2 0 3 0; #X connect 11 0 8 0; pd-0.46-7/doc/5.reference/sigbinops-help.pd0000664000175000017500000000316312160204055016510 0ustar mspmsp#N canvas 18 67 1086 595 10; #X obj 8 251 +~; #X obj 115 249 -~; #X obj 222 249 *~; #X obj 327 251 /~; #X obj 38 17 +~; #X obj 73 17 -~; #X obj 106 16 *~; #X obj 140 16 /~; #X graph graph1 0 -1 100 1 678 446 1078 146; #X array array1 100 float; #X pop; #X obj 327 293 tabwrite~ array1; #X obj 8 293 tabwrite~ array1; #X obj 115 293 tabwrite~ array1; #X obj 222 293 tabwrite~ array1; #X text 266 14 -- operators on audio signals; #X obj 8 160 osc~ 440; #X obj 480 157 osc~ 675; #X msg 17 271 bang; #X obj 173 15 max~; #X obj 207 15 min~; #X text 487 458 modified for Pd version 0.27; #X obj 536 293 tabwrite~ array1; #X obj 431 293 tabwrite~ array1; #X obj 431 249 max~; #X obj 536 251 min~; #X msg 127 272 bang; #X msg 233 271 bang; #X msg 343 272 bang; #X msg 443 271 bang; #X msg 553 272 bang; #X text 52 332 The binary signal operators can be configured to combine two signals as above \, or \, if you give a numeric argument \, audio signals are combined with scalars:; #X obj 204 377 +~ 5; #X text 60 406 The right inlet takes audio signals or numbers depending on whether the argument is present or not.; #X msg 68 71 \; pd dsp 1; #X connect 0 0 10 0; #X connect 1 0 11 0; #X connect 2 0 12 0; #X connect 3 0 9 0; #X connect 14 0 0 0; #X connect 14 0 1 0; #X connect 14 0 3 0; #X connect 14 0 2 0; #X connect 14 0 22 0; #X connect 14 0 23 0; #X connect 15 0 3 1; #X connect 15 0 2 1; #X connect 15 0 1 1; #X connect 15 0 0 1; #X connect 15 0 22 1; #X connect 15 0 23 1; #X connect 16 0 10 0; #X connect 22 0 21 0; #X connect 23 0 20 0; #X connect 24 0 11 0; #X connect 25 0 12 0; #X connect 26 0 9 0; #X connect 27 0 21 0; #X connect 28 0 20 0; pd-0.46-7/doc/5.reference/tabsend~-help.pd0000664000175000017500000000071012160204055016324 0ustar mspmsp#N canvas 246 126 621 247 12; #X obj 31 27 tabsend~; #X text 113 26 writes one block of a signal continuously to an array ; #X msg 64 125 set my-table; #X text 380 202 updated for Pd version 0.43; #X text 21 77 By default a block is 64 samples but this can be reset using the block~ object.; #X text 225 161 creation argument: initializes table name; #X text 180 125 'set' message to change table name; #X obj 64 160 tabsend~ my-table; #X connect 2 0 7 0; pd-0.46-7/doc/5.reference/cputime-help.pd0000664000175000017500000000110412160204055016152 0ustar mspmsp#N canvas 302 232 550 286 12; #X msg 74 144 bang; #X msg 30 115 bang; #X floatatom 30 206 0 0 0; #X text 71 113 Click here to reset; #X text 27 232 Output is in milliseconds; #X obj 30 175 cputime; #X text 124 144 Click here to get elapsed CPU time; #X text 6 51 The cputime object measures elapsed CPU time \, as measured by your operating system. This appears to work on NT \, IRIX \, and Linux \, but not on W98.; #X obj 66 15 cputime; #X text 123 16 - measure CPU usage; #X text 297 261 updated for Pd version 0.33; #X connect 0 0 5 1; #X connect 1 0 5 0; #X connect 5 0 2 0; pd-0.46-7/doc/5.reference/plot-help.pd0000664000175000017500000000654412374250720015506 0ustar mspmsp#N struct help-plot-template float x float y array array1 help-plot-array1-template array array2 help-plot-array2-template array array3 help-plot-array3-template ; #N struct help-plot-array1-template float y; #N struct help-plot-array2-template float x float y; #N struct help-plot-array3-template float y float w; #N canvas 441 118 516 229 12; #N canvas 435 109 626 710 help-plot-template 0; #X text 29 34 creation arguments:; #X text 49 241 - RGB color (0=black \, 999=white \, 900=red \, 90=green \, 9=blue \, 555=grey \, etc.); #X text 47 271 - line width; #X text 47 290 - relative x and y location; #X text 48 310 - x spacing; #X obj 40 397 plot curve array2 70 3 100 0; #X obj 31 488 plot curve array3 9 1 120 50 20; #X obj 45 12 plot array1 500 1 10 15 20; #X text 30 327 This first example plots the red trace (500) \, width 1 \, at point (10 \, 15) \, with horizontal spacing 20 The black diamonds come from the template of the array1 element itself.; #X text 51 508 If a "w" variable is present in the template as for array3 \, it is added to the line width.; #X obj 23 672 filledpolygon 509 509 0 -10 -10 10 -10 10 10 -10 10; #X text 28 634 To see the data itself \, select "properties" for the scalar by right clicking on the purple square.; #X obj 25 567 struct help-plot-template float x float y array array1 help-plot-array1-template array array2 help-plot-array2-template array array3 help-plot-array3-template; #X text 34 546 here's the "struct" for all this:; #X text 46 220 - field to plot (the array); #X text 48 51 - optional "-n" flag to make invisible initially; #X text 47 70 - alternatively \, an optional "-v [variable]" flag to assign a variable to make this visible/invisible.; #X text 51 101 - Opional "-vs [constant or variable] to set visibility of scalars along the path of the plot.; #X text 47 199 - optional word "curve" to specify bezier; #X text 47 132 - optional "-x [variable]" flag to use different x variable ; #X text 48 153 - optional "-y [variable]" flag to use different y variable ; #X text 48 173 - optional "-w [variable]" flag to use different w variable ; #X text 63 419 This is the green spiral (color 70 \, line width 3 \, location (100 \, 0). Since the template for array2 contains an "x" variable \, plot ignores x spacing requests and takes x from the data itself.; #X restore 243 78 pd help-plot-template; #N canvas 196 292 273 120 help-plot-array1-template 0; #X obj 30 71 filledpolygon 0 0 0 -5 0 0 5 5 0 0 -5; #X obj 32 27 struct help-plot-array1-template float y; #X restore 242 101 pd help-plot-array1-template; #N canvas 161 163 273 120 help-plot-array2-template 0; #X obj 32 26 struct help-plot-array2-template float x float y; #X restore 243 123 pd help-plot-array2-template; #N canvas 2 52 411 207 help-plot-data 1; #X scalar help-plot-template 39 73 \; 0 \; 20 \; 0 \; 30 \; 0 \; \; 0 0 \; 0 10 \; 20 0 \; 0 -30 \; -40 0 \; 0 50 \; 60 0 \; \; 0 0 \; 10 10 \; 0 10 \; 0 1 \; 20 1 \; 20 10 \; 20 1 \; \;; #X restore 242 57 pd help-plot-data; #X text 23 139 see also:; #X obj 30 184 drawnumber; #X obj 35 22 plot; #X text 87 21 -- draw array elements of scalars; #X obj 29 206 drawpolygon; #N canvas 161 163 273 120 help-plot-array3-template 0; #X obj 43 32 struct help-plot-array3-template float y float w; #X restore 242 144 pd help-plot-array3-template; #X text 8 79 explanation is in here-->; #X text 264 203 updated for Pd version 0.35; #X obj 29 163 struct; pd-0.46-7/doc/5.reference/textfile.txt0000664000175000017500000000011712160204055015621 0ustar mspmsp2 4 6 8; cis boom bah; cis boom bah; cis boom bah; cis boom bah; cis boom bah; pd-0.46-7/doc/5.reference/struct-help.pd0000664000175000017500000000221612160204055016035 0ustar mspmsp#N canvas 343 45 557 321 12; #X text 88 11 -- declare the fields in a data structure.; #N canvas 345 476 638 171 help-template1 0; #X obj 60 21 struct struct-1 float x float y symbol dog array weasel struct-2; #X text 40 76 In this example \, the "struct-1" structure is defined in which "x" and "y" are "floats" \, i.e. \, numbers \, but "dog" is a symbol and "weasel" is an array of objects of structure "struct-2". ; #X restore 324 156 pd help-template1; #N canvas 10 274 588 157 help-template2 0; #X text 28 95 Here is one which specifies only the floating point "y" \; it's used for the elements of the array shown in the other template. ; #X obj 60 21 struct struct-2 float y; #X restore 324 183 pd help-template2; #X obj 36 215 drawpolygon; #X text 36 195 see also:; #X obj 141 215 drawnumber; #X obj 236 216 plot; #X text 281 290 updated for Pd version 0.35; #X obj 21 10 struct; #X text 16 49 There should be one "struct" object in each Pd window you are using as a data structure template. The arguments specify the types and names of the fields \; and for array fields \, a third argument specifies the template that the array elements should belong to.; pd-0.46-7/doc/5.reference/swap-help.pd0000664000175000017500000000256612160204055015473 0ustar mspmsp#N canvas 475 187 615 593 12; #X msg 72 167 bang; #X floatatom 72 292 0 0 0 0 - - -; #X floatatom 84 200 0 0 0 0 - - -; #X floatatom 139 237 0 0 0 0 - - -; #X obj 33 15 swap; #X text 81 16 - SWAP TWO NUMBERS \, RESPECTING RIGHT-TO-LEFT ORDER ; #X text 117 166 outputs 2 stored values; #X obj 72 266 swap 6.5; #X text 115 200 sets second value and outputs both; #X text 171 238 sets first value; #X text 157 266 creation argument initializes first value; #X floatatom 139 291 0 0 0 0 - - -; #X obj 139 331 print right; #X obj 72 367 print left; #X text 43 427 A common use of swap is to reverse the operands in arithmetic objects like this:; #X obj 72 491 swap; #X obj 72 519 -; #X floatatom 72 541 5 0 0 0 - - -; #X floatatom 103 469 3 0 0 0 - - -; #X floatatom 72 469 3 0 0 0 - - -; #X text 291 549 updated for Pd version 0.41; #X text 32 52 The swap object swaps the positions of two incoming numbers. The number coming in through the right inlet will be sent to the left outlet and the number coming in left will come out right. Only the left inlet is hot and triggers output on both outlets. Output order is right to left as in [trigger].; #X connect 0 0 7 0; #X connect 1 0 13 0; #X connect 2 0 7 0; #X connect 3 0 7 1; #X connect 7 0 1 0; #X connect 7 1 11 0; #X connect 11 0 12 0; #X connect 15 0 16 0; #X connect 15 1 16 1; #X connect 16 0 17 0; #X connect 18 0 15 1; #X connect 19 0 15 0; pd-0.46-7/doc/5.reference/declare-help.pd0000664000175000017500000000324512160204055016113 0ustar mspmsp#N canvas 103 177 618 583 12; #X declare; #X obj 48 10 declare; #X text 120 11 - set environment for loading patch; #X text 44 40 A declare object adds one or more directories to the search path \, and/or pre-loads one or more libraries ("extensions") to Pd in preparation for opening the patch from a file. Usage is "declare [-flag value] [-flag value] ..." where the flag can be:; #X text 31 182 -lib; #X text 31 198 -stdlib; #X text 31 146 -path; #X text 31 162 -stdpath; #X text 129 146 add to search path \, relative to the patch; #X text 129 182 load a library \, relative to the patch; #X text 129 199 load a library \, relative to Pd; #X text 40 231 (for any of these you may use a full pathname such as "/tmp/dir" or \, in Windows \, "C:/garbage" instead of a relative path). ; #X text 39 293 For instance \, if you put abstractions and/or other supporting files in a subdirectory "more" \, you can put an object \, "declare -path more" to make sure Pd sees them when the patch is loaded. Or \, if you have zexy installed in the directory extra/zexy (in the Pd installation") you can get it using "declare -stdpath extra/zexy". ; #X text 129 163 add to search path \, relative to Pd; #X text 367 557 updated for Pd version 0.41; #X text 42 395 WARNING: you might want to avoid putting "declare" statements inside abstractions \, as their effects will extend to the calling patch. As of version 0.41 \, "declare path" is ignored inside abstractions \, although \, probably unwisely \, "-stdpath" takes effect (on the calling patch as well as the abstraction.); #X text 42 494 BUG: The name "-stdpath" is confusing \, as it has a quite different effect from "-stdpath" on the pd command line.; pd-0.46-7/doc/5.reference/bag-help.pd0000664000175000017500000000203612160204055015242 0ustar mspmsp#N canvas 118 56 577 366 12; #X text 18 337 see also:; #X obj 148 337 makenote; #X msg 76 151 60 64; #X msg 127 151 60 0; #X msg 171 151 62 64; #X msg 218 151 62 0; #X obj 76 278 print; #X text 121 279 Output is in the printout window.; #X msg 218 197 clear; #X obj 66 15 bag; #X text 101 14 - COLLECTION OF NUMBERS; #X text 12 42 The bag object takes (value \, flag) pairs. If the flag is true (nonzero) \, the value is added to the collection \; if false \, it's removed. The collection may have many copies of the same value. You can output the collection (and empty it) with a "flush" message \, or just empty it with "clear." You can use this to mimic a sustain pedal \, for example.; #X msg 217 174 flush; #X obj 104 337 poly; #X obj 76 248 bag; #X text 267 151 <-- add or delete elements; #X text 271 174 <-- output them; #X text 273 198 <-- start over; #X text 328 337 updated for Pd version 0.33; #X connect 2 0 14 0; #X connect 3 0 14 0; #X connect 4 0 14 0; #X connect 5 0 14 0; #X connect 8 0 14 0; #X connect 12 0 14 0; #X connect 14 0 6 0; pd-0.46-7/doc/5.reference/qlist.txt0000664000175000017500000000011712160204055015131 0ustar mspmspthis text file is read by qlist.pd; 1000 that should explain everything; 1000; pd-0.46-7/doc/5.reference/textfile-help.pd0000664000175000017500000000415412160204055016340 0ustar mspmsp#N canvas 12 43 1181 529 12; #X msg 582 27 rewind; #X obj 577 416 print done; #X text 745 185 read a file; #X text 801 214 write one; #X text 97 472 see also:; #X obj 521 365 textfile; #X msg 584 188 read textfile.txt; #X obj 176 473 qlist; #X obj 145 20 textfile; #X text 236 20 read and write text files; #X text 34 92 The textfile object reads and writes text files to and from memory. You can read a file and output sequential lines as lists \, or collect lines and write them out. You can use this object to generate "models" for Gem \, for instance.; #X text 665 28 go to beginning; #X msg 582 54 bang; #X text 665 53 output one line as a list; #X msg 584 216 write /tmp/textfile.txt; #X msg 584 243 write /tmp/textfile2.txt cr; #X text 593 264 write a file \, terminating lines only with carriage return (omitting semicolons.) You can read files this way too \, in which case carriage returns are mapped to semicolons.; #X obj 521 438 print list; #X msg 583 312 read textfile.txt cr; #X msg 582 82 clear; #X text 737 83 empty the object; #X text 737 111 add a message; #X text 521 464 this outlet gets the lines in sequence.; #X text 35 246 You can also use this object simply for storing heterogeneous sequences of lists.; #X text 608 385 This outlet gets a bang when you hit the end of the sequence.; #X msg 582 162 set 2 4 6 8; #X text 740 163 clear and then add one message; #X msg 582 109 add cis boom bah; #X msg 582 136 add2 bang; #X text 734 136 add an unterminated message; #X text 31 160 To record textual messages and save them to a file \, first send "clear" to empty the qlist and "add" to add messages (terminated with semicolons.) The message \, "add2" adds a list of atoms without finishing with a semicolon in case you want to make variable-length messages.; #X msg 582 339 print; #X text 636 342 debugging printout; #X text 901 500 updated for Pd version 0.33; #X connect 0 0 5 0; #X connect 5 0 17 0; #X connect 5 1 1 0; #X connect 6 0 5 0; #X connect 12 0 5 0; #X connect 14 0 5 0; #X connect 15 0 5 0; #X connect 18 0 5 0; #X connect 19 0 5 0; #X connect 25 0 5 0; #X connect 27 0 5 0; #X connect 28 0 5 0; #X connect 31 0 5 0; pd-0.46-7/doc/5.reference/soundfiler-help.pd0000664000175000017500000000526112160204055016666 0ustar mspmsp#N canvas 59 252 1102 576 12; #N canvas 0 0 450 300 (subpatch) 0; #X array array1 77971 float 0; #X coords 0 1 77971 -1 300 100 1; #X restore 71 353 graph; #N canvas 0 0 450 300 (subpatch) 0; #X array array2 77971 float 0; #X coords 0 1 77971 -1 300 100 1; #X restore 71 459 graph; #X obj 11 313 soundfiler; #X msg 17 241 write -aiff /tmp/foo1 array2; #X msg 8 152 read ../sound/bell.aiff array2; #X msg 17 199 read -raw 128 2 2 b ../sound/bell.aiff array1 array2 ; #X text 26 10 SOUNDFILER - read and write soundfiles to arrays; #X text 548 3 When reading you can leave soundfiler to figure out which of the three known soundfile formats the file belongs to or override all header information using the "-raw" flag.; #X text 665 52 Flags for reading:; #X text 574 68 -skip ; #X floatatom 11 337 0 0 0 0 - - -; #X msg 15 175 read -resize ../sound/bell.aiff array2; #X msg 17 288 write -nextstep -bytes 4 /tmp/foo3 array1 array2; #X msg 16 265 write -wave -nframes 10000 /tmp/foo2 array2; #X text 287 150 read a file; #X text 362 173 ...optionally resize; #X text 225 217 ...or even overriding everything; #X text 283 240 write a file; #X text 352 309 write stereo; #X text 9 31 The soundfiler object reads and writes floating point arrays to binary soundfiles which may contain 2 or 3 byte fixed point or 4 byte floating point samples in wave \, aiff \, or next formats (no floating point aiff \, though.). The number of channels of the soundfile need not match the number of arrays given (extras are dropped and unsupplied channels are zeroed out.); #X text 575 123 -raw ; #X text 594 141 This causes all header information to be ignored. Endianness is "l" ("little") for Intel machines or "b" ("big") for Macintoshes and SGIs. You can give "n" (natural) to take the byte order your machine prefers.; #X text 575 86 -resize; #X text 575 104 -maxsize ; #X text 560 206 Flags for writing:; #X text 578 227 -wave \, -nextstep \, -aiff; #X text 579 246 -big \, -little (nextstep only!); #X text 578 268 -skip ; #X text 579 290 -nframes ; #X text 580 334 -normalize; #X text 579 312 -bytes <2 \, 3 \, or 4>; #X text 557 378 The number of channels is limited to 64; #X text 612 413 see also:; #X obj 606 436 tabwrite~; #X obj 607 460 tabread4~; #X obj 713 415 tabplay~; #X obj 711 464 writesf~; #X obj 712 441 readsf~; #X text 579 354 -rate ; #X text 751 539 updated for Pd version 0.37; #X connect 2 0 10 0; #X connect 3 0 2 0; #X connect 4 0 2 0; #X connect 5 0 2 0; #X connect 11 0 2 0; #X connect 12 0 2 0; #X connect 13 0 2 0; pd-0.46-7/doc/5.reference/log~-help.pd0000664000175000017500000000141612160204055015471 0ustar mspmsp#N canvas 299 273 531 296 10; #X obj 19 103 sig~; #X obj 50 167 loadbang; #X obj 50 191 metro 100; #X obj 50 215 snapshot~; #X floatatom 19 79 5 0 0 0 - - -; #X obj 60 103 sig~; #X floatatom 60 79 5 0 0 0 - - -; #X floatatom 50 240 7 0 0 0 - - -; #X text 316 257 updated for Pd version 0.42.; #X obj 21 14 log~; #X text 60 14 - logarithms; #X text 76 31 computes the logarithm of the left inlet \, to the base 'e' (about 2.718) \, or to another base specified by the inlet or a cration argument.; #X obj 20 132 log~ 2; #X text 83 131 <-- optional creation argument initializes right inlet (the base of the logarithm).; #X connect 0 0 12 0; #X connect 1 0 2 0; #X connect 2 0 3 0; #X connect 3 0 7 0; #X connect 4 0 0 0; #X connect 5 0 12 1; #X connect 6 0 5 0; #X connect 12 0 3 0; pd-0.46-7/doc/5.reference/table.txt0000664000175000017500000000006012160204055015061 0ustar mspmsp0 0.1 0.2 0.3 0.4 0.5 0.6 0.5 0.4 0.3 0.2 0.1 0 pd-0.46-7/doc/5.reference/tabplay~-help.pd0000664000175000017500000000427512160204055016352 0ustar mspmsp#N canvas 41 29 754 470 10; #X msg 639 93 \; pd dsp 0; #N canvas 0 0 450 300 (subpatch) 0; #X array array99 155948 float 0; #X coords 0 1 155948 -1 250 200 1; #X restore 428 169 graph; #X floatatom 11 354 0 0 0 0 - - -; #X msg 11 98 set array99; #X text 93 98 "set" message permits you to switch between arrays; #X text 128 228 creation argument initializes array name; #X text 5 392 see also the "array" tutorial in section 2 of the Pd documentation \, and these objects:; #X obj 6 438 tabwrite~; #X obj 144 438 tabread; #X obj 200 438 tabwrite; #X obj 262 438 tabsend~; #X obj 325 438 tabreceive~; #X obj 41 13 tabplay~; #X text 108 14 play a table as a sample (non-transposing); #X obj 11 228 tabplay~ array99; #X obj 452 82 soundfiler; #X msg 452 48 read -resize ../sound/bell.aiff array99 \; pd dsp 1 \; ; #X floatatom 452 104 0 0 0 0 - - -; #X obj 11 328 env~ 16384; #X obj 408 438 soundfiler; #X obj 75 438 tabread4~; #X obj 87 374 dac~ 1; #X obj 87 335 *~; #X obj 100 316 line~; #X msg 100 275 0.1 100; #X msg 116 296 0 100; #X text 162 276 on; #X text 157 295 off; #X text 148 313 envelope; #X text 148 324 generator; #X text 101 260 amplitude controls:; #X text 131 376 audio output; #X obj 87 354 hip~ 5; #X msg 31 162 0 44100; #X msg 32 141 44100; #X msg 31 121 bang; #X text 29 43 The tabplay~ object plays a sample \, or part of one \, with no transposition or interpolation. It is cheaper than tabread4~ and there are none of tabread4~'s interpolation artifacts.; #X text 509 25 click here to load table; #X text 85 119 "bang" or 0 plays whole sample; #X text 87 140 play starting at 44100th sample; #X text 98 160 play starting at beginning for 44100 samples; #X msg 30 182 44100 1000; #X text 108 181 play from 44100 through 45099 (1000 samples); #X text 502 443 updated for Pd version 0.43; #X msg 30 204 stop; #X text 69 203 stop playing (outputs zeros when stopped); #X connect 3 0 14 0; #X connect 14 0 18 0; #X connect 14 0 22 0; #X connect 15 0 17 0; #X connect 16 0 15 0; #X connect 18 0 2 0; #X connect 22 0 32 0; #X connect 23 0 22 1; #X connect 24 0 23 0; #X connect 25 0 23 0; #X connect 32 0 21 0; #X connect 33 0 14 0; #X connect 34 0 14 0; #X connect 35 0 14 0; #X connect 41 0 14 0; #X connect 44 0 14 0; pd-0.46-7/doc/5.reference/pointer-help.pd0000664000175000017500000000612612374250720016204 0ustar mspmsp#N struct template2 float x float y; #N struct template1 float x float y float z; #N canvas 459 64 698 764 12; #X text 19 635 see also:; #X obj 21 10 pointer; #X text 95 10 -- remember the location of a scalar in a list; #N canvas 164 72 425 146 help-pointer-template1 0; #X obj 18 81 filledpolygon z 0 1 0 0 20 0 20 30 0 30; #X obj 60 21 struct template1 float x float y float z; #X restore 326 449 pd help-pointer-template1; #N canvas 26 456 510 145 help-pointer-template2 0; #X obj 52 78 filledcurve 909 0 0 0 0 30 30 60 0 30 -30 0 0; #X obj 60 21 struct template2 float x float y; #X restore 326 472 pd help-pointer-template2; #X obj 22 655 get; #X obj 55 655 set; #X obj 90 655 append; #X obj 151 655 getsize; #X obj 219 656 setsize; #X obj 289 656 element; #N canvas 2 52 312 185 help-pointer-data 1; #X scalar template2 20 97 \;; #X scalar template1 80 17 90 \;; #X scalar template1 120 117 9 \;; #X restore 326 427 pd help-pointer-data; #X obj 53 423 pointer; #X msg 54 231 traverse pd-help-pointer-data; #X msg 67 255 bang; #X msg 69 281 next; #X obj 53 448 print out1; #X obj 166 434 print out2; #X text 15 489 Optional arguments to pointer allow you to select according to the class of the scalar being output:; #X msg 73 550 next; #X msg 59 527 traverse pd-help-pointer-data; #X obj 59 578 pointer help-pointer-template1 help-pointer-template2 ; #X obj 59 604 print template1; #X obj 197 604 print template2; #X obj 337 604 print other; #X obj 440 604 print bangout; #X text 333 232 sets to the "head" of the list; #X text 29 34 "Pointer" is a storage object like "float" \, except that the thing stored is the location of a scalar somewhere. You can send a pointer a value (perhaps from another "pointer" object). The right inlet takes pointers and simply stores them. A bang in the left outputs the pointer \, and a pointer in the left both sets and outputs the value.; #X text 29 132 The value of a pointer can either indicate a real scalar \, or else the "head" (before the first element) of the list. This allows you to point to an empty list \, and also \, to "append" a scalar to the beginning of the list.; #X text 29 191 Pointers are "safe": if you delete a scalar pointers to it are marked invalid.; #X text 165 454 bang at end; #X text 166 470 of list; #X text 52 468 output; #X obj 354 656 struct; #X msg 71 313 vnext 1; #X text 453 665 updated for Pd version 0.45; #X msg 71 377 send pointer-help; #X text 109 256 output current value; #X text 119 274 move forward one item and output pointer \; if we reach the end \, a "bang" goes to out2.; #X text 219 376 send pointer to a named object ->; #X obj 496 379 r pointer-help; #X obj 496 404 print pointer-help; #X text 149 314 output the next object (if arg is 0) or the next selected object (if arg is 1 -- but the window must be visible for the "selection" to make sense).; #X connect 12 0 16 0; #X connect 12 1 17 0; #X connect 13 0 12 0; #X connect 14 0 12 0; #X connect 15 0 12 0; #X connect 19 0 21 0; #X connect 20 0 21 0; #X connect 21 0 22 0; #X connect 21 1 23 0; #X connect 21 2 24 0; #X connect 21 3 25 0; #X connect 34 0 12 0; #X connect 36 0 12 0; #X connect 40 0 41 0; pd-0.46-7/doc/5.reference/rsqrt~-help.pd0000664000175000017500000000160612160204055016064 0ustar mspmsp#N canvas 183 264 685 375 12; #X obj 68 211 metro 500; #X obj 68 186 r metro; #X msg 575 106 \; metro 0; #X msg 574 48 \; pd dsp 1 \; metro 1; #X floatatom 52 112 0 0 0; #X floatatom 52 268 0 0 0; #X text 419 349 updated for Pd version 0.33; #X obj 574 21 loadbang; #X obj 52 235 snapshot~; #X floatatom 51 351 9 0 0; #X obj 51 295 t f f; #X obj 51 322 *; #X obj 52 138 sig~; #X obj 36 16 rsqrt~; #X text 105 14 - signal reciprocal square root; #X text 18 45 rsqrt~ takes the approximate reciprocal square root of the incoming signal \, using a fast \, approximate algorithm which is probably accurate to about 120 dB (20 bits).; #X obj 52 162 rsqrt~; #X connect 0 0 8 0; #X connect 1 0 0 0; #X connect 1 0 0 0; #X connect 4 0 12 0; #X connect 5 0 10 0; #X connect 7 0 3 0; #X connect 8 0 5 0; #X connect 10 0 11 0; #X connect 10 1 11 1; #X connect 11 0 9 0; #X connect 12 0 16 0; #X connect 16 0 8 0; pd-0.46-7/doc/5.reference/sig~-help.pd0000664000175000017500000000117412160204055015473 0ustar mspmsp#N canvas 132 175 547 284 12; #X obj 109 221 snapshot~; #X floatatom 110 246 0 0 0; #X obj 78 12 sig~; #X obj 24 133 sig~; #X floatatom 24 108 0 0 0; #X text 114 14 - convert numbers to audio signal; #X text 11 53 In this example \, the sig~ object converts numbers to an audio signal \, which the snapshot~ converts back again.; #X text 64 108 <-- Scroll to set value; #X obj 109 131 loadbang; #X msg 118 155 \; pd dsp 1; #X obj 109 195 metro 200; #X text 291 249 updated for Pd version 0.33; #X connect 0 0 1 0; #X connect 0 0 1 0; #X connect 3 0 0 0; #X connect 4 0 3 0; #X connect 8 0 9 0; #X connect 8 0 10 0; #X connect 10 0 0 0; pd-0.46-7/doc/5.reference/oscformat-help.pd0000664000175000017500000000540612375267415016533 0ustar mspmsp#N canvas 48 64 758 768 12; #X text 36 11 oscformat - convert lists to Open Sound Control (OSC) packets, f 61; #X msg 72 560 format b; #X msg 72 147 1 2 3; #X obj 72 268 oscformat cat horse pig; #X msg 94 203 set dog ferret; #X msg 92 230 set mouse banana; #X obj 180 302 oscparse; #X obj 72 301 print packet; #X msg 80 174 4 5 weasel 6 7 rat; #X obj 148 661 oscparse; #X obj 148 686 print parse-output; #X obj 42 662 print packet; #X msg 57 507 -1 1 2 mule 4 5; #X msg 69 605 format ifisf; #X obj 42 635 oscformat -f b wombat; #X msg 45 479 5 6 7 squirrel; #X msg 70 582 format fiiib; #X text 270 266 creation arguments are OSC address; #X text 138 137 OSC messages with numbers and symbols. Except as shown below the message will contain 'float' and 'string' data.; #X msg 342 379 disconnect; #X obj 334 406 netsend -u -b; #X msg 343 355 connect localhost 5000; #X obj 335 305 list prepend send; #X obj 335 330 list trim; #X obj 180 327 print reassembled; #X text 25 736 see also:; #X text 381 733 updated for Pd version 0.46; #X obj 267 736 list; #X obj 113 736 oscparse; #X obj 197 736 netsend; #X text 29 45 oscformat makes OSC packets suitable for sending over the network via netsend (in UDP binary mode). The OSC address (the strings between the slashes) are given by the creation arguments or by "set" messages. Incoming lists are output as OSC messages \, byte by byte., f 61; #X text 437 379 don't send; #X text 226 205 set message to change OSC address; #X text 232 632 the '-f' creation argument initializes the format; #X msg 73 535 format; #X text 142 535 no format; #X text 150 558 a 'blob'; #X text 180 593 mixtures; #X text 530 354 send as UDP; #X text 258 452 The format \, if any (initialized or set by a 'format' message) instructs oscformat to interpret incoming data as integer \, float \, string \, or 'blob'. Blobs are given as an atom count followed by that number of elements. (If an elements is a symbol \, its first byte is sent). If the count is negative \, the entire remaining message is included in the blob (but the OSC parser will report the actual number of elements). If the elements aren't exhausted at the end of the format string \, the default (float and symbol) conversions are made for the rest.; #X text 306 666 Note: there's no way using oscparse to distinguish between floats and integers \, nor to see blobs unambiguously., f 40; #X connect 1 0 14 0; #X connect 2 0 3 0; #X connect 3 0 7 0; #X connect 3 0 22 0; #X connect 3 0 6 0; #X connect 4 0 3 0; #X connect 5 0 3 0; #X connect 6 0 24 0; #X connect 8 0 3 0; #X connect 9 0 10 0; #X connect 12 0 14 0; #X connect 13 0 14 0; #X connect 14 0 11 0; #X connect 14 0 9 0; #X connect 15 0 14 0; #X connect 16 0 14 0; #X connect 19 0 20 0; #X connect 21 0 20 0; #X connect 22 0 23 0; #X connect 23 0 20 0; #X connect 34 0 14 0; pd-0.46-7/doc/5.reference/set-help.pd0000664000175000017500000000543112425757503015325 0ustar mspmsp#N struct help-set-template1 float x float y symbol s; #N canvas 155 52 618 738 12; #X text 39 640 see also:; #X obj 132 661 append; #X obj 190 661 getsize; #X obj 33 686 setsize; #X obj 158 685 element; #X msg 211 174 next; #X floatatom 20 192 5 0 0 0 - - -, f 5; #X floatatom 109 200 5 0 0 0 - - -, f 5; #X obj 197 199 pointer; #X text 274 132 output first scalar in list; #X text 257 174 output next item; #X text 266 218 First argument selects template.; #X text 267 233 Remaining args are names of fields.; #X obj 31 660 pointer; #X msg 197 150 traverse pd-help-set-data \, next; #N canvas 2 79 276 122 help-set-data 1; #X scalar help-set-template1 39 23 dog \;; #X scalar help-set-template1 99 73 cat \;; #X restore 414 639 pd help-set-data; #N canvas 41 424 514 219 help-set-template1 0; #X obj 41 87 filledpolygon 9 0 1 0 0 20 0 20 30 0 30; #X obj 39 34 struct help-set-template1 float x float y symbol s; #X obj 46 133 drawsymbol s 0 -15 0 s=; #X restore 414 661 pd help-set-template1; #X text 86 10 -- set values in a scalar; #X obj 20 223 set help-set-template1 x y; #X text 19 174 x value; #X text 107 181 y value; #X obj 99 660 get; #X obj 99 685 struct; #X obj 21 10 set; #X msg 276 359 next; #X obj 262 384 pointer; #X msg 262 335 traverse pd-help-set-data \, next; #X obj 40 414 set -symbol help-set-template1 s; #X symbolatom 40 393 10 0 0 0 - - -, f 10; #X msg 40 340 symbol monkey; #X msg 48 366 symbol fish; #X text 33 273 To set fields whose values are symbols \, give the set object the "-symbol" argument. (Unfortunately \, you can't mix symbols and numbers in the same "set" object.), f 56; #X text 14 34 "Set" takes a pointer to a scalar in its rightmost inlet \; the remaining inlets set numeric fields. Symbols are handled specially \, as shown below. Arrays are accessed using the "elemen" object \, and lists using "text" objects. Only the leftmost inlet is "hot".; #X text 341 688 updated for Pd version 0.47; #X text 39 443 You can use the template "-" as a wild card (this may be slower than if you use a specific template name). Also \, if there are zero or one fields specified \, you can send a "set" message to set a new template name and field name:; #X obj 85 578 set - x; #X obj 320 619 set; #X floatatom 85 551 5 0 0 0 - - -, f 5; #X msg 142 526 traverse pd-help-set-data \, next; #X obj 142 550 pointer; #X floatatom 320 560 5 0 0 0 - - -, f 5; #X msg 384 556 set help-set-template1 x; #X msg 383 583 set - x; #X connect 5 0 8 0; #X connect 6 0 18 0; #X connect 7 0 18 1; #X connect 8 0 18 2; #X connect 14 0 8 0; #X connect 24 0 25 0; #X connect 25 0 27 1; #X connect 26 0 25 0; #X connect 28 0 27 0; #X connect 29 0 28 0; #X connect 30 0 28 0; #X connect 37 0 35 0; #X connect 38 0 39 0; #X connect 39 0 36 1; #X connect 39 0 35 1; #X connect 40 0 36 0; #X connect 41 0 36 0; #X connect 42 0 36 0; pd-0.46-7/doc/5.reference/rzero_rev~-help.pd0000664000175000017500000000512612160204055016727 0ustar mspmsp#N canvas 717 52 526 510 12; #X floatatom 127 186 0 0 0 0 - - -; #X obj 49 98 osc~ 100; #X msg 64 130 clear; #X obj 77 483 lop~; #X text 8 483 see also:; #X text 331 482 updated for Pd version-0.38; #X obj 84 430 rzero~; #X obj 35 450 cpole~; #X obj 35 430 rpole~; #X obj 133 430 rzero_rev~; #X obj 84 450 czero~; #X obj 133 450 czero_rev~; #X text 211 430 real; #X text 210 451 complex; #X text 32 414 1-pole; #X text 81 414 1-zero; #X text 131 414 1-zero \, reversed; #X text 57 399 summary of raw filters:; #X msg 66 156 set 1; #X text 112 156 <-- set internal state; #X text 113 99 <-- signal to filter; #X text 155 189 <-- filter coefficient (may be a signal); #X text 143 210 <-- creation argument initializes filter coefficient ; #X text 108 129 <-- clear internal state to zero; #N canvas 393 91 326 287 test 0; #X obj 76 78 osc~; #X floatatom 76 55 5 0 0 0 - - -; #X obj 77 219 env~ 16384; #X floatatom 77 243 5 0 0 0 - - -; #X obj 104 107 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 76 105 *~; #X msg 97 137 set 1; #X floatatom 172 157 4 -100 100 0 - - -; #X obj 172 182 / 100; #X obj 214 256 dac~; #X obj 228 177 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 214 220 *~; #X obj 230 197 / 10; #X text 80 18 Stuff to test it:; #X obj 76 168 rzero_rev~; #X connect 0 0 5 0; #X connect 1 0 0 0; #X connect 2 0 3 0; #X connect 4 0 5 1; #X connect 5 0 14 0; #X connect 6 0 14 0; #X connect 7 0 8 0; #X connect 8 0 14 1; #X connect 10 0 12 0; #X connect 11 0 9 0; #X connect 11 0 9 1; #X connect 12 0 11 1; #X connect 14 0 2 0; #X connect 14 0 11 0; #X restore 457 416 pd test; #X text 111 483 etc.: user-friendly filters; #X text 8 270 where y[n] is the output \, x[n] the input \, and a[n] the filter coefficient. The filter is always stable.; #X obj 52 7 rzero_rev~; #X text 139 7 real one-zero (non-recursive) "reverse" filter \, raw ; #X obj 48 208 rzero_rev~ 1; #X text 7 35 Rzero_rev~ filters an audio signal (left inlet) via a one-zero real filter \, whose coefficient is controlled by a creation argument or by an audio signal (right inlet). The impulse response is that of "rzero" reversed in time.; #X text 14 230 The action of rpole_rev~ is:; #X text 71 251 y[n] = -a[n] * x[n] + x[n-1]; #X text 6 302 The transfer function is H(Z) = -a + Z^-1.; #X text 5 321 (Pd also provides a suite of user-friendly filters. This and other raw filters are provided for situations which the user-friendly ones can't handle. See Chapter 8 of http://crca.ucsd.edu/~msp/techniques for an introduction to the necessary theory.); #X connect 0 0 29 1; #X connect 1 0 29 0; #X connect 2 0 29 0; #X connect 18 0 29 0; pd-0.46-7/doc/5.reference/array-object-help.txt0000664000175000017500000000103512222367057017320 0ustar mspmsp0 0 0 0 0 0 0 0 0 0 0 0.00666678 0.060001 0.173336 0.540009 -0.0266671 -0.20667 -0.406674 -0.713345 -0.833347 -0.933349 -1.04668 -0.980017 -0.800014 -0.686678 -0.526676 -0.443341 -0.360006 -0.20667 -0.140002 -0.0733346 -0.00666678 0.060001 0.173336 0.313339 0.400007 0.433341 0.39334 0.293338 0.18667 0.0800014 0.0400007 0.060001 0.0733346 0.0933349 0.113335 0.126669 0.100002 0.0666678 0.0400007 0.0200003 0.0200003 -0.0400007 -0.0266671 -0.00666678 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 pd-0.46-7/doc/5.reference/tabosc4~-help.pd0000664000175000017500000000557612160204055016262 0ustar mspmsp#N canvas 307 35 742 511 12; #X floatatom 66 450 0 0 0 0 - - -; #N canvas 159 26 495 270 output 0; #X obj 414 196 t b; #X obj 414 134 f; #X obj 414 73 inlet; #X text 421 36 mute; #X obj 414 227 f; #X msg 521 218 0; #X msg 414 104 bang; #X obj 414 166 moses 1; #X obj 521 187 t b f; #X obj 486 143 moses 1; #X obj 102 181 dbtorms; #X obj 486 113 r master-lvl; #X obj 102 52 r master-lvl; #X obj 414 257 s master-lvl; #X obj 26 222 inlet~; #X obj 244 50 inlet; #X text 244 22 level; #X obj 244 122 s master-lvl; #X msg 118 80 set \$1; #X obj 118 109 outlet; #X msg 262 78 \; pd dsp 1; #X obj 102 238 line~; #X obj 26 259 *~; #X obj 26 295 dac~; #X obj 102 210 pack 0 50; #X text 24 195 audio; #X text 114 135 show level; #X connect 0 0 4 0; #X connect 1 0 7 0; #X connect 2 0 6 0; #X connect 4 0 13 0; #X connect 5 0 13 0; #X connect 6 0 1 0; #X connect 7 0 0 0; #X connect 7 1 8 0; #X connect 8 0 5 0; #X connect 9 1 4 1; #X connect 10 0 24 0; #X connect 11 0 1 1; #X connect 11 0 9 0; #X connect 12 0 10 0; #X connect 12 0 18 0; #X connect 14 0 22 0; #X connect 15 0 17 0; #X connect 15 0 20 0; #X connect 18 0 19 0; #X connect 21 0 22 1; #X connect 22 0 23 0; #X connect 22 0 23 1; #X connect 24 0 21 0; #X restore 32 476 pd output; #X msg 102 450 MUTE; #X text 148 449 <--- volume in dB; #X floatatom 32 296 4 0 0 0 - - -; #X obj 32 326 sig~ 100; #X obj 547 52 table table1; #X obj 547 80 table table2; #X msg 372 287 \; table1 sinesum 512 0.5 0.5 0.5 0.5 \; table2 cosinesum 512 0 1; #X text 433 474 Updated for Pd version 0.33; #X obj 20 11 tabosc4~; #X text 110 12 4-point interpolating oscillator; #X msg 52 372 set table1; #X obj 32 413 tabosc4~ table1; #X msg 156 372 set table2; #X text 372 343 click above \, start DSP \, and turn output; #X text 372 361 volume up to hear this; #X text 14 178 For good results use 512 points for up to about 15 partials \, or 32*npartials (rounded up to a power of 2) for more than 15; #X floatatom 275 391 4 0 0 0 - - -; #X text 12 233 Don't send new "sinesum" messages to tables while you're running -- instead \, use "set" messages to switch between tables. ; #X text 80 298 signal input for frequency (Hz.); #X text 46 349 message to switch tables; #X text 325 391 inlet to reset phase; #X text 166 414 creation argument initializes table; #X text 14 40 tabosc4~ is a traditional computer music style wavetable lookup oscillator using 4-point polynomial interpolation. The table should have a power of two points plus three "guard points" \, one at the beginning and two at the end \, which should be wraparound copies of the last point and the first two points \, respectively. The "sinesum" and "cosinesum" methods for arrays do this automatically for you if you just want to specify partial strengths.; #X connect 0 0 1 1; #X connect 1 0 0 0; #X connect 2 0 1 2; #X connect 4 0 5 0; #X connect 5 0 13 0; #X connect 12 0 13 0; #X connect 13 0 1 0; #X connect 14 0 13 0; #X connect 18 0 13 1; pd-0.46-7/doc/5.reference/lop~-help.pd0000664000175000017500000000231512160204055015501 0ustar mspmsp#N canvas 390 359 566 329 12; #X obj 70 228 env~; #X floatatom 70 248 0 0 0 0 - - -; #X floatatom 107 178 0 0 0 0 - - -; #X obj 12 226 env~; #X floatatom 12 245 0 0 0 0 - - -; #X floatatom 12 107 0 0 0 0 - - -; #X obj 83 6 lop~; #X text 9 68 The left inlet is the incoming audio signal. The right inlet is the cutoff frequency in Hz.; #X obj 12 130 osc~ 100; #X text 57 105 <-- scroll to change input frequency; #X text 8 35 lop~ is a one-pole low pass filter with a specified rolloff frequency.; #X text 114 7 - one-pole low pass filter; #X msg 70 154 clear; #X text 114 153 <-- reinitialize internal state; #X text 139 179 <-- set cutoff frequency; #X obj 70 206 lop~ 5; #X text 121 209 The filter is initialized to cut off frequencies above 5 Hz.; #X text 12 266 Compare the strength of the original signal on the left with that of the filtered signal on the right.; #X text 104 228 env~ gives the amplitude of the signal in dB.; #X text 8 305 see also:; #X obj 77 304 hip~; #X obj 112 304 bp~; #X obj 139 304 vcf~; #X text 364 306 updated for Pd version-0.38; #X connect 0 0 1 0; #X connect 2 0 15 1; #X connect 3 0 4 0; #X connect 5 0 8 0; #X connect 8 0 3 0; #X connect 8 0 15 0; #X connect 12 0 15 0; #X connect 15 0 0 0; pd-0.46-7/doc/5.reference/float-help.pd0000664000175000017500000000167112374250720015631 0ustar mspmsp#N canvas 532 221 610 305 12; #X msg 30 107 bang; #X obj 30 225 float 6.5; #X floatatom 30 251 0 0 0 0 - - -; #X floatatom 42 129 0 0 0 0 - - -; #X floatatom 88 195 0 0 0 0 - - -; #X obj 55 12 float; #X text 97 11 - STORE A (FLOATING POINT) NUMBER; #X text 12 36 The float object stores a number \, initialized by its creation argument \, which may be reset using its inlet and output by sending it the "bang" message. Sending a number sets a new value and outputs it.; #X text 123 197 sets the value; #X text 108 226 creation argument initializes the value; #X text 372 272 updated for Pd version 0.45; #X floatatom 456 182 5 0 0 0 - - -, f 5; #X text 75 104 output the value; #X text 72 128 set and output the value; #X text 176 156 send to a "receive" like this -->; #X obj 456 157 r float-help; #X msg 47 156 send float-help; #X connect 0 0 1 0; #X connect 1 0 2 0; #X connect 3 0 1 0; #X connect 4 0 1 1; #X connect 15 0 11 0; #X connect 16 0 1 0; pd-0.46-7/doc/5.reference/spigot-help.pd0000664000175000017500000000141712160204055016020 0ustar mspmsp#N canvas 59 19 612 342 12; #X obj 35 11 spigot; #X text 100 12 - pass or block messages; #X text 35 63 Spigot passes messages from its left inlet to its outlet \, as long as a nonzero number is sent to its right inlet. When its right inlet gets zero \, incoming messages are "blocked \, " i.e. \, ignored.; #X msg 25 157 0.5 1000; #X obj 25 300 print; #X msg 38 210 walk the cat; #X msg 31 182 bang; #X text 128 240 control: nonzero to pass messages \, zero to stop them ; #X obj 25 267 spigot 0; #X text 349 310 updated for Pd version 0.38; #X obj 92 244 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X text 125 267 optional arg sets the initial state (0 by default) ; #X connect 3 0 8 0; #X connect 5 0 8 0; #X connect 6 0 8 0; #X connect 8 0 4 0; #X connect 10 0 8 1; pd-0.46-7/doc/5.reference/tabread~-help.pd0000664000175000017500000000273012160204055016312 0ustar mspmsp#N canvas 320 156 845 474 12; #N canvas 0 0 450 300 (subpatch) 0; #X array array99 10 float 3; #A 0 -0.5 0.5 -0.4 0.4 -0.3 0.3 -0.2 0.2 -0.1 0.1; #X coords 0 1 10 -1 250 200 1; #X restore 562 167 graph; #X obj 16 362 snapshot~; #X obj 35 336 metro 200; #X obj 16 149 sig~; #X floatatom 16 123 6 0 10 0 - - -; #X obj 35 310 r readout; #X floatatom 16 388 0 0 0 0 - - -; #X msg 28 186 set array99; #X text 118 185 "set" message permits you to switch between arrays ; #X text 144 274 creation argument initializes array name; #X text 11 403 see also the "array" tutorial in section 2 of the Pd documentation \, and these objects:; #X text 563 16 click here to test; #X obj 91 445 tabwrite~; #X obj 236 445 tabread; #X obj 359 446 tabwrite; #X obj 424 446 tabsend~; #X obj 489 446 tabreceive~; #X obj 162 445 tabplay~; #X msg 582 40 \; readout 1 \; pd dsp 1 \;; #X text 24 230 signal input; #X obj 47 21 tabread~; #X text 127 21 non-interpolating table lookup; #X text 7 58 Tabread~ looks up values out of the named array. Incoming values are truncated to the next lower integer \, and values out of bounds get the nearest (first or last) point.; #X text 64 117 incoming signal is index. Indices should range from 0 to (size-1).; #X obj 16 274 tabread~ array99; #X obj 16 446 tabread4~; #X obj 294 445 tabread4; #X text 625 451 updated for Pd version 0.43; #X connect 1 0 6 0; #X connect 2 0 1 0; #X connect 3 0 24 0; #X connect 4 0 3 0; #X connect 5 0 2 0; #X connect 7 0 24 0; #X connect 24 0 1 0; pd-0.46-7/doc/5.reference/element-help.pd0000664000175000017500000000472712425761305016165 0ustar mspmsp#N struct help-element-template float x float y array array1 help-element-array1-template ; #N struct help-element-array1-template float y; #N canvas 36 82 671 548 12; #X text 31 474 see also:; #N canvas 393 50 503 273 help-element-template 0; #X obj 27 76 plot array1 500 1 10 15 20; #X obj 27 174 filledpolygon 509 509 0 -10 -10 10 -10 10 10 -10 10; #X obj 24 15 struct help-element-template float x float y array array1 help-element-array1-template; #X restore 421 450 pd help-element-template; #N canvas 2 79 292 163 help-element-data 1; #X scalar help-element-template 35 24 \; 0 \; 10 \; 0 \; 10 \; 20 \; 10 \; 20 \; 70 \; 10 \; \;; #X restore 457 429 pd help-element-data; #N canvas 196 292 373 142 help-element-array1-template 0; #X obj 30 71 filledpolygon 0 0 0 -5 0 0 5 5 0 0 -5; #X obj 32 27 struct help-element-array1-template float y; #X restore 361 472 pd help-element-array1-template; #X obj 22 11 element; #X text 91 10 -- get pointer to an element of an array; #X obj 105 494 pointer; #X obj 173 494 getsize; #X obj 241 494 setsize; #X text 31 37 "element" takes a pointer at right and a number at left. It looks up a field from the pointer \, which should be an array \, and outputs the element of the array specified by the number. There are no pointers to arrays themselves \, just to individual elements. The template and field mane are specified as creation arguments.; #X obj 336 300 pointer; #X msg 336 276 traverse pd-help-element-data \, next; #X floatatom 45 270 5 0 0 0 - - -, f 5; #X obj 45 357 element help-element-template array1; #X obj 45 404 get help-element-array1-template y; #X floatatom 45 431 5 0 0 0 - - -, f 5; #X text 358 353 arguments: template \, field name; #X text 337 323 pointer inlet; #X text 43 249 index; #X text 50 378 outlet is pointer to single element; #X text 96 429 here we just get the value of y.; #X text 34 142 Indices range from 0 to the number of elements minus one \; indices out of range are quietly replaced by the nearest endpoint. ; #X text 335 254 click here first; #X obj 28 494 struct; #X text 414 517 updated for Pd version 0.47; #X msg 55 321 set help-element-template array1; #X text 89 299 set template and field name; #X text 35 195 If you don't know the template name you may specify "-" \, in which case the object will figure out the template name itself \, at some possible cost in efficiancy and clarity.; #X connect 10 0 13 1; #X connect 11 0 10 0; #X connect 12 0 13 0; #X connect 13 0 14 0; #X connect 14 0 15 0; #X connect 25 0 13 0; pd-0.46-7/doc/5.reference/tabread4~-help.pd0000664000175000017500000000326312160204055016400 0ustar mspmsp#N canvas 323 179 845 474 12; #X obj 11 249 tabread4~ array99; #N canvas 0 0 450 300 (subpatch) 0; #X array array99 10 float 3; #A 0 -0.5 -0.5 -0.5 0.5 0.5 0.5 0 0 0 0; #X coords 0 1 10 -1 250 200 1; #X restore 561 167 graph; #X text 127 21 4-point-interpolating table lookup; #X obj 11 337 snapshot~; #X obj 30 311 metro 200; #X obj 11 124 sig~; #X floatatom 11 98 6 0 10 0 - - -; #X obj 30 285 r readout; #X floatatom 11 363 0 0 0 0 - - -; #X text 59 92 incoming signal is index. Indices should range from 1 to (size-2) so that the 4-point interpolation is meaningful. You can shift-drag the number box to see the effect of interpolation.; #X msg 23 161 set array99; #X text 113 160 "set" message permits you to switch between arrays ; #X text 139 249 creation argument initializes array name; #X text 11 403 see also the "array" tutorial in section 2 of the Pd documentation \, and these objects:; #X obj 47 21 tabread4~; #X text 563 16 click here to test; #X obj 12 442 tabwrite~; #X obj 157 442 tabread; #X obj 216 442 tabwrite; #X obj 281 442 tabsend~; #X obj 346 442 tabreceive~; #X text 7 58 Tabread4~ is used to build samplers and other table lookup algorithms. The interpolation scheme is 4-point polynomial.; #X obj 83 442 tabplay~; #X text 626 451 updated for Pd version 0.42; #X msg 582 40 \; readout 1 \; pd dsp 1 \;; #X floatatom 111 190 3 0 10 0 - - -; #X text 19 205 signal input; #X text 138 183 inlet sets onset into table. You can use this to improve the accuracy of indexing into the array. See B15.tabread4~-onset.pd for details.; #X connect 0 0 3 0; #X connect 3 0 8 0; #X connect 4 0 3 0; #X connect 5 0 0 0; #X connect 6 0 5 0; #X connect 7 0 4 0; #X connect 10 0 0 0; #X connect 25 0 0 1; pd-0.46-7/doc/5.reference/netreceive-help.pd0000664000175000017500000000464312374250720016657 0ustar mspmsp#N canvas 115 149 813 713 12; #X obj 100 359 netreceive 3000; #X floatatom 217 447 0 0 0 0 - - -; #X text 251 448 <--- number of open connections; #X text 85 12 Netreceive -- listen for incoming messages from network ; #X text 112 667 see also:; #X obj 198 669 netsend; #X obj 100 447 print tcp; #X obj 99 553 print udp; #X text 29 167 There are some possibilities for intercommunication with other programs... see the help for "netsend.", f 85; #X obj 593 606 netreceive 3003 1; #X text 607 582 (UDP port 3003); #X text 26 618 An old (pre-0.45) calling convention is provided for compatibility: port number and following "0" or "1" for TCP or UDP respectively:, f 67; #X text 564 666 updated for Pd version 0.45; #X obj 99 525 netreceive -u 3001; #X text 234 355 creation arguments:; #X text 302 374 optional -u flag for UDP; #X text 302 393 optional -b flag for binary; #X text 301 414 optional port number; #X obj 505 529 netreceive -u -b 3003; #X obj 291 550 netreceive -b 3002; #X obj 291 578 print tcp-binary; #X obj 504 557 print udp-binary; #X msg 100 283 listen 0; #X text 210 259 listen message to set or change port; #X text 206 284 (0 or negative number to close); #X msg 100 257 listen 3000; #X text 33 36 The Netreceive object opens a socket for TCP ("stream") or UDP ("datagram") network reception on a specified port. If using TCP \, an outlet gives you the number of Netsend objects (or other compatible clients) that have opened connections here., f 84; #X text 31 205 SECURITY NOTE: don't publish the port number of your netreceive unless you wouldn't mind other people being able to send you messages., f 85; #X text 31 93 By default the messages are ASCII text messages compatible with Pd (i.e. \, numbers and symbols terminated with a semicolon -- the "FUDI" protocol). The "-b" creation argument specifies binary messages instead \, which appear in Pd as lists of numbers from 0 to 255 (You could use this for OSC messages \, for example.), f 83; #X msg 121 332 send foo \$1; #X floatatom 121 309 0 0 0 0 - - -; #X msg 290 526 send foo \$1; #X floatatom 290 503 0 0 0 0 - - -; #X text 232 479 other examples:; #X text 158 309 "send" (for TCP connections only) sends back to connected netreceive objects, f 76; #X connect 0 0 6 0; #X connect 0 1 1 0; #X connect 13 0 7 0; #X connect 18 0 21 0; #X connect 19 0 20 0; #X connect 22 0 0 0; #X connect 25 0 0 0; #X connect 29 0 0 0; #X connect 30 0 29 0; #X connect 31 0 19 0; #X connect 32 0 31 0; pd-0.46-7/doc/5.reference/bang-help.pd0000664000175000017500000000060612160204055015421 0ustar mspmsp#N canvas 118 56 581 250 12; #X obj 49 182 print; #X text 107 183 Output is in the printout window.; #X obj 66 15 bang; #X text 112 14 - SEND "BANG" MESSAGE; #X msg 61 105 walk the cat; #X msg 49 79 45; #X obj 49 152 bang; #X text 336 233 updated for Pd version 0.27; #X text 23 42 Outputs a "bang" message whatever it receives.; #X connect 4 0 6 0; #X connect 5 0 6 0; #X connect 6 0 0 0; pd-0.46-7/doc/5.reference/poly-help.pd0000664000175000017500000000211612222367057015506 0ustar mspmsp#N canvas -1 49 655 444 12; #X text 406 383 updated for Pd version 0.25; #X text 42 383 see also:; #X obj 66 15 poly; #X text 101 14 - MIDI-STYLE POLYPHONIC VOICE ALLOCATOR; #X text 12 42 The poly object takes a stream of pitch/velocity pairs and outputs triples containing voice number \, pitch and velocity. You can pack the output and use the route object to route messages among a bank of voices depending on the first outlet. Poly can be configured to do voice stealing or not (the default.); #X obj 110 384 route; #X obj 154 384 makenote; #X obj 52 254 poly 4 1; #X text 134 253 <-- first argument \, number of voices \; second argument selects voice stealing; #X msg 52 168 60 64; #X msg 103 168 60 0; #X msg 147 168 62 64; #X msg 194 168 62 0; #X obj 52 280 pack 0 0 0; #X obj 52 306 print; #X text 97 305 Output is in the printout window.; #X msg 254 177 stop; #X msg 296 177 clear; #X connect 7 0 13 0; #X connect 7 1 13 1; #X connect 7 2 13 2; #X connect 9 0 7 0; #X connect 10 0 7 0; #X connect 11 0 7 0; #X connect 12 0 7 0; #X connect 13 0 14 0; #X connect 16 0 7 0; #X connect 17 0 7 0; pd-0.46-7/doc/5.reference/line~-help.pd0000664000175000017500000000223012160204055015632 0ustar mspmsp#N canvas 121 54 813 370 12; #X obj 33 301 snapshot~; #X obj 21 8 line~; #X obj 33 226 line~; #X floatatom 33 324 0 0 0 0 - - -; #X obj 43 274 metro 100; #X obj 43 249 r start; #X msg 550 21 \; pd dsp 1 \; start bang; #X msg 34 106 1 1000; #X text 89 105 a pair of numbers starts a ramp; #X msg 60 176 2; #X text 91 150 a single number jumps to value; #X msg 61 200 stop; #X text 104 199 "stop" message freezes line~ at its current value; #X msg 60 153 0; #X msg 43 128 0 5000; #X text 10 28 The line~ object generates linear ramps whose levels and timing are determined by messages you send it. The messages may be a single target value (causing the output to jump to the target) or a target and a time in milliseconds (to start a new ramp.); #X text 644 36 Click to start; #X text 639 94 Click to stop; #X text 185 300 see also:; #X obj 271 302 line; #X msg 550 75 \; pd dsp 0 \; start 0; #X text 75 7 - audio ramp generator; #X text 576 335 updated for version 0.33; #X obj 317 302 vline~; #X connect 0 0 3 0; #X connect 2 0 0 0; #X connect 4 0 0 0; #X connect 5 0 4 0; #X connect 7 0 2 0; #X connect 9 0 2 0; #X connect 11 0 2 0; #X connect 13 0 2 0; #X connect 14 0 2 0; pd-0.46-7/doc/5.reference/bng-help.pd0000664000175000017500000001507712160204055015270 0ustar mspmsp#N canvas 11 201 538 357 10; #X obj 1 1 cnv 8 100 60 empty empty bng 20 20 1 18 -262144 -1109 0 ; #X text 10 288 (c) musil@iem.kug.ac.at; #X text 52 301 IEM KUG; #X text 118 61 click properties to; #X text 106 72 modify geometry \, colors \, etc.; #X obj 64 257 print; #N canvas 598 330 290 225 once 0; #X msg 38 73 1; #X obj 38 47 t b b; #X obj 68 124 sel 0; #X obj 68 103 f 0; #X obj 38 24 inlet; #X obj 68 154 outlet; #X connect 0 0 3 1; #X connect 1 0 0 0; #X connect 1 1 3 0; #X connect 2 0 5 0; #X connect 3 0 2 0; #X connect 4 0 1 0; #X restore 64 234 pd once; #X obj 36 258 bng 15 250 50 0 empty empty empty 8 -8 0 10 -262144 -1 -1; #X obj 3 130 bng 15 250 50 0 empty empty empty 8 -8 0 10 -262144 -1 -1; #X obj 36 173 bng 50 950 50 1 foo5_snd foo5_rcv big-bang 63 2 192 12 -262131 -260818 -143491; #X msg 36 53 33; #X msg 50 75 -3.14; #X msg 73 117 11 22 33.33; #X msg 63 95 open xxx; #X msg 96 142 funny; #X text 101 11 gui-bang:; #X obj 202 135 s foo5_rcv; #X obj 202 155 r foo5_snd; #X obj 202 115 bng 15 250 50 0 empty empty empty 8 -8 0 10 -262144 -1 -1; #X obj 202 175 bng 15 250 50 0 empty empty empty 8 -8 0 10 -262144 -1 -1; #X msg 4 53 0; #X text 125 205 UP- \, DOWN- \, LEFT- or RIGHT-key; #X text 124 216 for moving selected gui-objects; #N canvas 425 170 699 530 edit 0; #X obj 39 197 f; #X msg 17 176 bang; #X floatatom 55 175 3 63 88; #X floatatom 90 197 3 0 37; #X obj 39 220 pack 0 0; #X text 117 197 y-label; #X text 83 175 x-label; #X floatatom 259 143 3 8 75; #X text 286 143 size; #X obj 279 236 f; #X msg 257 215 bang; #X floatatom 295 214 3 -10 10; #X floatatom 330 236 3 -10 10; #X obj 279 259 pack 0 0; #X obj 304 348 f; #X msg 282 327 bang; #X floatatom 320 326 3 20 90; #X floatatom 355 348 3 150 200; #X obj 304 371 pack 0 0; #X text 323 214 x-delta; #X text 357 236 y-delta; #X text 348 326 x-position; #X text 382 348 y-position; #X obj 59 312 f; #X msg 37 291 bang; #X floatatom 75 290 3 0 2; #X floatatom 110 312 3 4 36; #X obj 59 335 pack 0 0; #X text 103 290 font; #X text 139 312 height; #X msg 36 399 \; foo5_rcv label blabla; #X msg 59 360 \; foo5_rcv label_font \$1 \$2; #X msg 39 245 \; foo5_rcv label_pos \$1 \$2; #X msg 47 135 \; foo5_rcv color \$1 \$2 \$3; #X msg 259 172 \; foo5_rcv size \$1; #X msg 279 284 \; foo5_rcv delta \$1 \$2; #X msg 304 396 \; foo5_rcv pos \$1 \$2; #X msg 483 133 \; foo5_rcv receive foo5a_rcv; #X msg 482 171 \; foo5a_rcv receive foo5_rcv; #X msg 483 50 \; foo5_rcv send foo5a_snd; #X msg 483 88 \; foo5_rcv send foo5_snd; #X text 526 349 no init; #X msg 505 368 \; foo5_rcv init 0; #X msg 512 435 \; foo5_rcv init 1; #X obj 493 260 f; #X msg 471 239 bang; #X floatatom 509 238 4 10 100; #X floatatom 544 261 5 100 3000; #X obj 493 283 pack 0 0; #X msg 493 308 \; foo5_rcv flashtime \$1 \$2; #X text 548 237 interrupt-time; #X text 585 262 hold-time; #X msg 36 435 \; foo5_rcv label big-bang; #X text 502 417 init bang on loadbang; #X text 519 221 flash-time:; #X obj 47 114 pack 0 0 0; #X obj 47 86 f; #X msg 24 38 bang; #X floatatom 63 36 3 0 29; #X floatatom 79 56 3 0 29; #X floatatom 112 72 3 0 29; #X text 91 36 background; #X text 106 56 front-color; #X text 140 73 label-color; #X msg 285 35 back; #X msg 285 55 front; #X msg 285 75 label; #X msg 247 35 bang; #N canvas 15 207 606 448 RGB_____________ 0; #X obj 97 56 inlet; #X obj 262 53 inlet; #X obj 339 55 inlet; #X obj 405 56 inlet; #X obj 97 270 bang; #X msg 77 295 0; #X msg 104 295 1; #X obj 146 268 bang; #X msg 132 295 0; #X msg 160 295 1; #X obj 196 269 bang; #X msg 187 295 0; #X msg 214 295 1; #X obj 265 313 spigot; #X obj 312 313 spigot; #X obj 359 313 spigot; #X obj 249 385 outlet; #X text 93 33 select; #X text 267 28 red; #X text 337 30 green; #X text 409 30 blue; #X obj 405 102 t b f; #X obj 339 160 +; #X obj 339 185 t b f; #X obj 339 216 +; #X obj 296 385 outlet; #X obj 343 385 outlet; #X obj 28 180 loadbang; #X obj 97 135 route back front label bang; #X obj 343 362 f; #X obj 296 361 f; #X obj 249 361 f; #X obj 262 79 * -65536; #X obj 339 80 * -256; #X obj 405 80 * -1; #X obj 339 247 - 1; #X obj 235 168 t b b b b; #X connect 0 0 28 0; #X connect 1 0 32 0; #X connect 2 0 33 0; #X connect 3 0 34 0; #X connect 4 0 5 0; #X connect 4 0 6 0; #X connect 5 0 14 1; #X connect 5 0 15 1; #X connect 6 0 13 1; #X connect 7 0 8 0; #X connect 7 0 9 0; #X connect 8 0 13 1; #X connect 8 0 15 1; #X connect 9 0 14 1; #X connect 10 0 11 0; #X connect 10 0 12 0; #X connect 11 0 13 1; #X connect 11 0 14 1; #X connect 12 0 15 1; #X connect 13 0 31 1; #X connect 14 0 30 1; #X connect 15 0 29 1; #X connect 21 0 22 0; #X connect 21 1 22 1; #X connect 22 0 23 0; #X connect 23 0 24 0; #X connect 23 1 24 1; #X connect 24 0 35 0; #X connect 27 0 6 0; #X connect 28 0 4 0; #X connect 28 1 7 0; #X connect 28 2 10 0; #X connect 28 3 36 0; #X connect 29 0 26 0; #X connect 30 0 25 0; #X connect 31 0 16 0; #X connect 32 0 24 0; #X connect 33 0 22 0; #X connect 34 0 21 0; #X connect 35 0 15 0; #X connect 35 0 14 0; #X connect 35 0 13 0; #X connect 36 0 31 0; #X connect 36 1 30 0; #X connect 36 2 29 0; #X connect 36 3 35 0; #X restore 285 96 pd RGB_____________; #X floatatom 327 65 3 0 255; #X floatatom 370 65 3 0 255; #X floatatom 413 66 3 0 255; #X text 34 10 preset-colors; #X text 296 7 RGB-colors; #X text 327 47 red; #X text 363 46 green; #X text 411 46 blue; #X connect 0 0 4 0; #X connect 1 0 0 0; #X connect 2 0 0 1; #X connect 3 0 4 1; #X connect 4 0 32 0; #X connect 7 0 34 0; #X connect 9 0 13 0; #X connect 10 0 9 0; #X connect 11 0 9 1; #X connect 12 0 13 1; #X connect 13 0 35 0; #X connect 14 0 18 0; #X connect 15 0 14 0; #X connect 16 0 14 1; #X connect 17 0 18 1; #X connect 18 0 36 0; #X connect 23 0 27 0; #X connect 24 0 23 0; #X connect 25 0 23 1; #X connect 26 0 27 1; #X connect 27 0 31 0; #X connect 44 0 48 0; #X connect 45 0 44 0; #X connect 46 0 44 1; #X connect 47 0 48 1; #X connect 48 0 49 0; #X connect 55 0 33 0; #X connect 56 0 55 0; #X connect 57 0 56 0; #X connect 58 0 56 1; #X connect 59 0 55 1; #X connect 60 0 55 2; #X connect 64 0 68 0; #X connect 65 0 68 0; #X connect 66 0 68 0; #X connect 67 0 68 0; #X connect 68 0 55 0; #X connect 68 1 55 1; #X connect 68 2 55 2; #X connect 69 0 68 1; #X connect 70 0 68 2; #X connect 71 0 68 3; #X restore 297 144 pd edit; #X obj 248 34 bng 15 250 50 0 aaa aaa empty 20 8 192 8 -262144 -1 -1 ; #X text 185 312 updated for Pd version 0.35; #X text 27 313 graz \, austria 2002; #X obj 180 11 x_all_guis aaa bbb ccc ddd eee fff ggg hhh iii; #X connect 6 0 5 0; #X connect 8 0 9 0; #X connect 9 0 7 0; #X connect 9 0 6 0; #X connect 10 0 9 0; #X connect 11 0 9 0; #X connect 12 0 9 0; #X connect 13 0 9 0; #X connect 14 0 9 0; #X connect 17 0 19 0; #X connect 18 0 16 0; #X connect 20 0 9 0; pd-0.46-7/doc/5.reference/sqrt~-help.pd0000664000175000017500000000156012160204055015701 0ustar mspmsp#N canvas 182 132 778 399 12; #X obj 71 201 metro 500; #X obj 71 176 r metro; #X msg 575 106 \; metro 0; #X msg 574 48 \; pd dsp 1 \; metro 1; #X floatatom 55 102 0 0 0; #X floatatom 55 258 0 0 0; #X text 470 371 updated for Pd version 0.33; #X obj 574 21 loadbang; #X obj 36 16 sqrt~; #X text 88 18 - signal square root; #X obj 55 152 sqrt~; #X obj 55 225 snapshot~; #X floatatom 54 341 9 0 0; #X obj 54 285 t f f; #X obj 54 312 *; #X obj 55 128 sig~; #X text 18 45 sqrt~ takes the approximate square root of the incoming signal \, using a fast \, approximate algorithm which is probably accurate to about 120 dB (20 bits).; #X connect 0 0 11 0; #X connect 1 0 0 0; #X connect 1 0 0 0; #X connect 4 0 15 0; #X connect 5 0 13 0; #X connect 7 0 3 0; #X connect 10 0 11 0; #X connect 11 0 5 0; #X connect 13 0 14 0; #X connect 13 1 14 1; #X connect 14 0 12 0; #X connect 15 0 10 0; pd-0.46-7/doc/5.reference/threshold~-help.pd0000664000175000017500000000235612160204055016710 0ustar mspmsp#N canvas 114 43 685 360 12; #X msg 452 58 \; pd dsp 0; #X msg 452 24 \; pd dsp 1; #X obj 124 11 threshold~; #X text 200 12 - TRIGGER FROM AUDIO SIGNAL; #X obj 49 183 sig~; #X obj 49 261 threshold~ 10 100 0 100; #X text 303 255 Arguments:; #X text 384 255 1 trigger threshold; #X floatatom 49 156 5 0 0; #X obj 49 289 print trigger; #X obj 205 287 print rest; #X text 385 271 2 trigger debounce time; #X text 385 288 3 rest threshold; #X text 384 303 4 rest debounce time; #X text 486 342 updated for Pd version 0.32; #X msg 205 209 1; #X msg 235 210 0; #X text 12 39 threshold~ monitors its input signal and outputs bangs when the signal exceeds a specified "trigger" value \, and also when the signal recedes below a "rest" value. You can specify debounce times in milliseconds \, for the threshold~ to wait after the two event types before triggering again.; #X msg 131 151 set 0 2000 1 2000; #X msg 131 174 set 10 100 0 100; #X text 262 150 "set" to change the parameters; #X text 268 210 zero or nonszero in inlet to set the state to "high" or "low". There is no debounce period after this.; #X connect 4 0 5 0; #X connect 5 0 9 0; #X connect 5 1 10 0; #X connect 8 0 4 0; #X connect 15 0 5 1; #X connect 16 0 5 1; #X connect 18 0 5 0; #X connect 19 0 5 0; pd-0.46-7/doc/5.reference/makenote-help.pd0000664000175000017500000000163712160204055016322 0ustar mspmsp#N canvas 39 28 663 385 12; #X floatatom 180 207 0 0 0; #X floatatom 110 176 0 0 0; #X msg 48 127 60; #X obj 41 262 print x1; #X obj 180 262 print x2; #X floatatom 41 104 0 0 0; #X obj 29 14 makenote; #X text 113 14 - send note-on messages and schedule note-off for later; #X text 19 41 Makenote makes MIDI-style note-on/note-off pairs \, which you can use for MIDI output or to drive note-like processes within Pd.; #X msg 48 153 60.5; #X text 80 105 numbers at left are "pitches" which may be integers or not.; #X text 146 178 "velocity"; #X text 215 210 duration in milliseconds; #X obj 41 235 makenote 3.2 500; #X text 193 235 creation arguments initialize velocity and duration; #X text 38 316 see also; #X obj 117 316 stripnote; #X text 389 325 updated for Pd version 0.33; #X connect 0 0 13 2; #X connect 1 0 13 1; #X connect 2 0 13 0; #X connect 5 0 13 0; #X connect 9 0 13 0; #X connect 13 0 3 0; #X connect 13 1 4 0; pd-0.46-7/doc/5.reference/rpole~-help.pd0000664000175000017500000000501012160204055016023 0ustar mspmsp#N canvas 56 7 669 542 12; #X floatatom 118 172 0 0 0 0 - - -; #X obj 54 85 osc~ 100; #X msg 69 117 clear; #X obj 96 512 lop~; #X text 10 512 see also:; #X obj 52 7 rpole~; #X text 114 7 real one-pole (recursive) filter \, raw; #X text 8 35 Rpole~ filters an audio signal (left inlet) via a one-pole real filter \, whose coefficient is controlled by a creation argument or by an audio signal (right inlet).; #X obj 95 441 rzero~; #X obj 35 463 cpole~; #X obj 35 441 rpole~; #X obj 154 441 rzero_rev~; #X obj 95 463 czero~; #X obj 154 463 czero_rev~; #X text 253 441 real; #X text 252 464 complex; #X text 32 425 1-pole; #X text 92 425 1-zero; #X text 142 425 1-zero \, reversed; #X text 57 410 summary of raw filters:; #X msg 71 143 set 1; #X text 119 142 <-- set internal state; #X text 132 86 <-- signal to filter; #X text 150 173 <-- filter coefficient (may be a signal); #X text 150 195 <-- creation argument initializes filter coefficient ; #X text 10 310 The transfer function is H(Z) = 1/(1 - aZ^-1).; #X text 121 117 <-- clear internal state to zero; #X text 11 272 where y[n] is the output \, x[n] the input \, and a[n] the filter coefficient. The filter is unstable if/when |a[n]|>1.; #X obj 53 195 rpole~ 0.9; #X text 14 230 The action of rpole~ is:; #N canvas 393 91 326 287 test 0; #X obj 76 78 osc~; #X floatatom 76 55 5 0 0 0 - - -; #X obj 77 219 env~ 16384; #X floatatom 77 243 5 0 0 0 - - -; #X obj 76 168 rpole~; #X obj 104 107 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 76 105 *~; #X msg 97 137 set 1; #X floatatom 172 157 4 -100 100 0 - - -; #X obj 172 182 / 100; #X obj 214 256 dac~; #X obj 228 177 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 214 220 *~; #X obj 230 197 / 10; #X text 80 18 Stuff to test it:; #X connect 0 0 6 0; #X connect 1 0 0 0; #X connect 2 0 3 0; #X connect 4 0 2 0; #X connect 4 0 12 0; #X connect 5 0 6 1; #X connect 6 0 4 0; #X connect 7 0 4 0; #X connect 8 0 9 0; #X connect 9 0 4 1; #X connect 11 0 13 0; #X connect 12 0 10 0; #X connect 12 0 10 1; #X connect 13 0 12 1; #X restore 457 427 pd test; #X text 136 512 etc.: user-friendly filters; #X text 8 331 (Pd also provides a suite of user-friendly filters. This and other raw filters are provided for situations which the user-friendly ones can't handle. See Chapter 8 of http://crca.ucsd.edu/~msp/techniques for an introduction to the necessary theory.); #X text 73 252 y[n] = x[n] + a[n] * y[n-1]; #X text 413 511 updated for Pd version 0.42; #X connect 0 0 28 1; #X connect 1 0 28 0; #X connect 2 0 28 0; #X connect 20 0 28 0; pd-0.46-7/doc/5.reference/oscparse-help.pd0000664000175000017500000000427412376723272016356 0ustar mspmsp#N canvas 3 69 706 702 12; #X obj 171 576 oscparse; #X text 52 663 see also:; #X obj 140 663 oscformat; #X obj 224 663 netreceive; #X text 435 666 updated for Pd version 0.46; #X obj 171 599 print parse-output; #X obj 314 663 list; #X obj 419 521 netreceive -u -b; #X msg 419 466 listen 5000; #X msg 431 494 listen 0; #X text 520 493 stop listening; #X msg 57 471 1 2 3 foo 5; #X text 51 446 numbers and symbols; #X obj 57 496 oscformat dog cat; #X obj 222 496 oscformat -f b weasel; #X msg 222 471 -1 1 2 3 4 5; #X obj 57 576 print packet; #X text 234 445 a blob; #X text 416 442 packets from network; #X text 521 466 slisten on port 5000; #X text 558 521 UDP packets \, binary output, f 13; #X text 45 41 oscparse take incoming lists of numbers \, interpreting them as the bytes in an OSC message. The output is a list containing \, first \, the symbols making up the address of the OSC packet \, and following that \, numbers and symbols as present in the OSC message. OSC messages may contain 'float' \, 'int' \, 'string' \, or 'blob' elements. Blobs are arrays of bytes (numbers between 0 and 255) and are copied to the output preceded by the blob's byte count.; #X text 80 11 oscparse - parse Open Sound Control (OSC) packets into Pd messages, f 67; #X text 44 187 OSC is a complicated networking protocol (FUDI \, as used in netsend/netreceive is simpler and better but less widely used). oscparse and oscformat make no attempt to deal with timetags or aggregates of packets \, nor with streaming OSC. Also \, no attempt is made here to clearly distinguish between the OSC address (symbols) and the following data \, nor between blobs and lists of numbers - it is assumed that you know what types the message should contain. You can alternatively use the OSC objects from mrpeach which have more features than these. ; #X text 42 356 OSC messages may be combined in "bundles". If oscparse receives a bundle it simply parses all the messages in the bundle in the order they appear \, and ignores the bundle's time tag.; #X connect 0 0 5 0; #X connect 7 0 0 0; #X connect 8 0 7 0; #X connect 9 0 7 0; #X connect 11 0 13 0; #X connect 13 0 0 0; #X connect 13 0 16 0; #X connect 14 0 0 0; #X connect 14 0 16 0; #X connect 15 0 14 0; pd-0.46-7/doc/5.reference/hip~-help.pd0000664000175000017500000000300012222367057015472 0ustar mspmsp#N canvas 394 118 644 497 12; #X obj 76 238 env~; #X floatatom 76 261 0 0 0 0 - - -; #X floatatom 120 184 0 0 0 0 - - -; #X obj 76 211 hip~ 5; #X obj 18 238 env~; #X floatatom 18 260 0 0 0 0 - - -; #X text 121 240 env~ gives the amplitude of the signal envelop in dB. ; #X floatatom 18 112 0 0 0 0 - - -; #X obj 18 135 osc~ 100; #X text 69 112 <-- scroll to change input frequency; #X msg 76 159 clear; #X text 128 158 <-- reinitialize internal state; #X obj 83 6 hip~; #X text 128 5 - one-pole high pass filter; #X text 409 464 updated for Pd version 0.44; #X msg 127 439 \; pd compatibility 0.43; #X text 11 31 hip~ is a one-pole high pass filter with a specified cutoff frequency.; #X text 141 213 Creation argument initializes cutoff frequency.; #X text 172 183 <-- set cutoff frequency; #X text 13 68 Left (audio) inlet is the incoming audio signal.; #X text 12 87 Right (contol) inlet sets cutoff frequency.; #X text 21 293 COMPATIBILITY NOTE: in Pd versions before 0.44 \, the high-frequency output gain was incorrectly greater than one (usually only slightly so \, but noticeably if the cutoff frequency was more than 1/4 the Nyquist frequency). This problem was fixed INCORECTLY in pd 0.44-0 thoguh 0.44-2 \, and is now hopefully fixed since Pd 0.44-3. To get the old (0.43 and earlier) behavior \, set "compatibility" to 0.43 in Pd's command line or by a message:; #X connect 0 0 1 0; #X connect 2 0 3 1; #X connect 3 0 0 0; #X connect 4 0 5 0; #X connect 7 0 8 0; #X connect 8 0 4 0; #X connect 8 0 3 0; #X connect 10 0 3 0; pd-0.46-7/doc/5.reference/osc~-help.pd0000664000175000017500000000340412160204055015473 0ustar mspmsp#N canvas 85 32 811 508 12; #X obj 252 320 dac~ 1; #X obj 252 292 *~; #X floatatom 156 115 0 0 0; #X obj 276 264 line~; #X msg 276 208 0.1 100; #X msg 295 233 0 100; #X text 347 203 on; #X text 344 232 off; #X text 333 261 envelope; #X text 333 274 generator; #X text 260 183 amplitude controls:; #X text 250 344 audio output; #X text 424 426 see also:; #X obj 580 428 cos~; #X obj 629 428 tabread4~; #X obj 68 14 osc~; #X text 142 16 - cosine wave oscillator; #X obj 126 294 metro 500; #X obj 126 269 r metro; #X text 88 344 graph the output; #X obj 510 427 phasor~; #X msg 571 79 \; metro 0; #X msg 570 20 \; pd dsp 1 \; metro 1; #X floatatom 637 245 0 0 0; #X obj 637 275 sig~; #X text 522 266 convert to; #X text 512 282 audio signal; #X text 518 305 oscillator; #X text 479 243 frequency control; #X obj 637 306 osc~; #X text 3 120 change frequency; #X text 244 145 <-- creation argument sets initial frequency; #X text 231 123 v-- inlet resets phase; #X graph graph1 0 -1 100 1 94 388 294 488; #X array array99 100 float; #X pop; #X text 16 39 The osc~ object outputs a cosine wave. If no argument is supplied \, the input is taken to be an audio signal. With a floating-point argument \, osc~ takes floating-point messages to change frequency.; #X text 510 336 invoked without argument to; #X text 512 360 specify audio signal input; #X text 2 105 incoming numbers; #X obj 89 322 tabwrite~ array99; #X obj 156 144 osc~ 1000; #X text 546 480 updated for Pd version 0.33; #X text 655 39 <-Click to start; #X text 648 88 <-Click to stop; #X connect 1 0 0 0; #X connect 2 0 39 0; #X connect 3 0 1 1; #X connect 4 0 3 0; #X connect 5 0 3 0; #X connect 17 0 38 0; #X connect 18 0 17 0; #X connect 18 0 17 0; #X connect 23 0 24 0; #X connect 24 0 29 0; #X connect 39 0 1 0; #X connect 39 0 38 0; pd-0.46-7/doc/5.reference/cpole~-help.pd0000664000175000017500000000712412160204055016014 0ustar mspmsp#N canvas 619 313 610 611 12; #X obj 54 95 osc~ 100; #X msg 62 122 clear; #X text 12 374 The transfer function is H(Z) = 1/(1 - aZ^-1).; #X text 115 121 <-- clear internal state to zero; #N canvas 168 90 498 357 test 0; #X obj 76 78 osc~; #X floatatom 76 55 5 0 0 0 - - -; #X obj 18 287 env~ 16384; #X floatatom 18 311 5 0 0 0 - - -; #X obj 104 107 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 76 105 *~; #X msg 85 132 set 1; #X floatatom 350 112 4 -1000 1000 0 - - -; #X obj 215 315 dac~; #X obj 215 279 *~; #X text 80 18 Stuff to test it:; #X obj 241 106 cos~; #X obj 77 227 cpole~; #X obj 261 65 phasor~; #X floatatom 261 44 5 0 0 0 - - -; #X floatatom 132 55 5 0 0 0 - - -; #X obj 160 107 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 132 105 *~; #X obj 132 78 phasor~; #X floatatom 324 42 5 0 0 0 - - -; #X obj 324 65 / 1000; #X obj 274 107 -~ 0.25; #X obj 274 129 cos~; #X obj 350 131 / 1000; #X obj 240 157 *~; #X obj 274 157 *~; #X obj 94 287 env~ 16384; #X floatatom 94 311 5 0 0 0 - - -; #X obj 247 275 dbtorms; #X floatatom 248 255 5 0 0 0 - - -; #X connect 0 0 5 0; #X connect 1 0 0 0; #X connect 2 0 3 0; #X connect 4 0 5 1; #X connect 5 0 12 0; #X connect 6 0 12 0; #X connect 7 0 23 0; #X connect 9 0 8 0; #X connect 9 0 8 1; #X connect 11 0 24 0; #X connect 12 0 2 0; #X connect 12 0 9 0; #X connect 12 1 26 0; #X connect 13 0 21 0; #X connect 13 0 11 0; #X connect 14 0 13 0; #X connect 15 0 18 0; #X connect 16 0 17 1; #X connect 17 0 12 0; #X connect 18 0 17 0; #X connect 19 0 20 0; #X connect 20 0 13 1; #X connect 21 0 22 0; #X connect 22 0 25 0; #X connect 23 0 25 1; #X connect 23 0 24 1; #X connect 24 0 12 2; #X connect 25 0 12 3; #X connect 26 0 27 0; #X connect 28 0 9 1; #X connect 29 0 28 0; #X restore 459 488 pd test; #X text 10 392 (Pd also provides a suite of user-friendly filters. This and other raw filters are provided for situations which the user-friendly ones can't handle. See Chapter 8 of http://crca.ucsd.edu/~msp/techniques for an introduction to the necessary theory.); #X obj 52 7 cpole~; #X text 114 7 complex one-pole (recursive) filter \, raw; #X text 132 98 <-- signal to filter (real part); #X text 130 178 <-- signal to filter (imaginary part); #X obj 84 177 sig~; #X obj 115 202 sig~; #X text 162 204 <-- filter coefficient (real part); #X obj 145 224 sig~; #X obj 53 249 cpole~ 0.9 0.4; #X text 178 250 <-- creation arguments initialize filter; #X text 206 266 coefficient (real and imaginary part); #X text 14 283 The action of cpole~ is:; #X text 11 325 where y[n] is the output \, x[n] the input \, and a[n] the filter coefficient (all complex numbers). The filter is unstable if/when |a[n]|>1.; #X text 12 27 Cpole~ filters a complex audio signal (first two inlets) via a one-pole filter \, whose coefficients are controlled by creation arguments or by another complex audio signal (remaining two inlets). ; #X text 171 148 <-- set internal state (real&imaginary parts); #X msg 64 148 set 0.6 0.8; #X text 190 226 <-- filter coefficient (imaginary part); #X text 73 305 y[n] = x[n] + a[n] * y[n-1]; #X obj 97 563 lop~; #X text 16 563 see also:; #X obj 96 507 rzero~; #X obj 36 530 cpole~; #X obj 36 507 rpole~; #X obj 156 507 rzero_rev~; #X obj 96 530 czero~; #X obj 156 530 czero_rev~; #X text 255 507 real; #X text 254 531 complex; #X text 33 490 1-pole; #X text 93 490 1-zero; #X text 143 490 1-zero \, reversed; #X text 58 474 summary of raw filters:; #X text 140 563 etc.: user-friendly filters; #X text 343 583 updated for Pd version 0.43; #X connect 0 0 14 0; #X connect 1 0 14 0; #X connect 10 0 14 1; #X connect 11 0 14 2; #X connect 13 0 14 3; #X connect 21 0 14 0; pd-0.46-7/doc/5.reference/int-help.pd0000664000175000017500000000210712374250720015311 0ustar mspmsp#N canvas 312 78 599 357 12; #X msg 43 110 bang; #X floatatom 41 302 0 0 0 0 - - -; #X floatatom 55 134 0 0 0 0 - - -; #X floatatom 82 252 0 0 0 0 - - -; #X text 90 106 outputs the value; #X text 92 135 sets and outputs the value; #X text 93 274 creation argument initializes the value; #X obj 41 276 int 6; #X msg 55 157 9.6; #X text 88 157 non-integers get truncated; #X msg 53 182 -9.6; #X text 95 182 toward zero; #X text 116 254 set the value but no output; #X obj 60 11 int; #X text 108 12 - STORE AN INTEGER; #X text 19 42 The int object stores a number \, initialized by its creation argument \, which may be reset using its inlet and output by sending it the "bang" message. The output is truncated to an integer ala Max.; #X obj 500 209 r int-help; #X floatatom 500 234 5 0 0 0 - - -, f 5; #X text 171 209 send value to a "receive" like this -->; #X text 332 323 updated for Pd version 0.45; #X msg 54 211 send int-help; #X connect 0 0 7 0; #X connect 2 0 7 0; #X connect 3 0 7 1; #X connect 7 0 1 0; #X connect 8 0 7 0; #X connect 10 0 7 0; #X connect 16 0 17 0; #X connect 20 0 7 0; pd-0.46-7/doc/5.reference/otherbinops-help.pd0000664000175000017500000000417512160204055017053 0ustar mspmsp#N canvas 20 43 698 447 12; #X floatatom 524 338 0 0 0; #X floatatom 353 338 0 0 0; #X floatatom 298 338 0 0 0; #X floatatom 413 338 0 0 0; #X floatatom 467 338 0 0 0; #X obj 524 311 <; #X obj 298 262 r left; #X obj 540 267 r right; #X floatatom 71 335 0 0 0; #X floatatom 19 334 0 0 0; #X floatatom 119 335 0 0 0; #X floatatom 163 334 0 0 0; #X obj 16 45 &; #X obj 66 45 |; #X obj 118 45 &&; #X obj 169 45 ||; #X obj 19 307 &; #X obj 71 308 |; #X obj 119 308 &&; #X obj 163 307 ||; #X text 13 73 The Logical Operators; #X obj 19 266 r left; #X obj 218 266 r right; #X obj 12 118 >; #X obj 61 118 >=; #X obj 114 118 ==; #X obj 215 119 <=; #X obj 262 119 <; #X text 11 153 The Relational Operators; #X obj 298 312 >; #X obj 353 312 >=; #X obj 413 312 ==; #X obj 467 312 <=; #X text 16 190 relational output is logical- and negative numbers BAD in bitwise logical operators. These operators as defined by C programming language. (inputs and outputs are converted to and from floating point). ; #X floatatom 410 65 0 0 0; #X obj 410 92 s left; #X floatatom 481 66 0 0 0; #X obj 481 94 t b f; #X obj 481 122 s left; #X obj 541 122 s right; #X obj 166 118 !=; #X text 377 42 set left and right inputs here; #X floatatom 202 335 0 0 0; #X floatatom 246 334 0 0 0; #X obj 208 46 <<; #X obj 259 46 >>; #X obj 202 308 <<; #X obj 246 307 >>; #X text 421 383 last updated for version 0.32; #X connect 5 0 0 0; #X connect 6 0 29 0; #X connect 6 0 30 0; #X connect 6 0 31 0; #X connect 6 0 32 0; #X connect 6 0 5 0; #X connect 7 0 29 1; #X connect 7 0 30 1; #X connect 7 0 31 1; #X connect 7 0 32 1; #X connect 7 0 5 1; #X connect 16 0 9 0; #X connect 17 0 8 0; #X connect 18 0 10 0; #X connect 19 0 11 0; #X connect 21 0 16 0; #X connect 21 0 17 0; #X connect 21 0 18 0; #X connect 21 0 19 0; #X connect 21 0 46 0; #X connect 21 0 47 0; #X connect 22 0 19 1; #X connect 22 0 18 1; #X connect 22 0 17 1; #X connect 22 0 16 1; #X connect 22 0 47 1; #X connect 22 0 46 1; #X connect 29 0 2 0; #X connect 30 0 1 0; #X connect 31 0 3 0; #X connect 32 0 4 0; #X connect 34 0 35 0; #X connect 36 0 37 0; #X connect 37 0 38 0; #X connect 37 1 39 0; #X connect 46 0 42 0; #X connect 47 0 43 0; pd-0.46-7/doc/5.reference/pipe-help.pd0000664000175000017500000000302712160204055015447 0ustar mspmsp#N canvas 99 89 737 480 12; #X floatatom 52 127 0 0 0; #X floatatom 127 227 0 0 0; #X floatatom 52 284 0 0 0; #X floatatom 544 281 0 0 0; #X floatatom 535 392 0 0 0; #X obj 534 364 pipe 5 6 7 1000; #X obj 543 307 t f f f; #X obj 563 338 + 1; #X obj 597 337 + 2; #X floatatom 590 390 0 0 0; #X floatatom 658 391 0 0 0; #X text 32 433 see also:; #X text 129 13 pipe -- message "delay line"; #X obj 52 253 pipe 2000; #X text 91 125 numbers to store and output later; #X text 117 148 output all stored messages immediately; #X msg 63 152 flush; #X msg 65 180 clear; #X text 113 180 forget all stored messages; #X text 91 286 delayed output; #X obj 116 435 delay; #X obj 167 435 timer; #X text 51 42 The Pipe object stores a sequence of messages and outputs them after a specified delay time in miliseconds. You can change the delay time as you wish. The outputs are sorted automatically.; #X text 140 254 creation argument initializes delay time; #X text 163 228 set delay time; #X text 487 449 updated for Pd version 0.33; #X text 21 330 You can specify compound messages (lists) by adding arguments which set their type and initial value as in "pack." In this case the delay time comes last and is changed by the last inlet. You can also pack symbols and pointers but this feature is UNTESTED.; #X connect 0 0 13 0; #X connect 1 0 13 1; #X connect 3 0 6 0; #X connect 5 0 4 0; #X connect 5 1 9 0; #X connect 5 2 10 0; #X connect 6 0 5 0; #X connect 6 1 7 0; #X connect 6 2 8 0; #X connect 7 0 5 1; #X connect 8 0 5 2; #X connect 13 0 2 0; #X connect 16 0 13 0; pd-0.46-7/doc/5.reference/stripnote-help.pd0000664000175000017500000000106412160204055016540 0ustar mspmsp#N canvas 53 36 458 251 10; #X msg 39 100 23 0; #X obj 39 175 print x1; #X obj 96 175 print x2; #X obj 39 139 stripnote; #X msg 79 100 34.5 67.8; #X obj 65 214 makenote; #X text 83 12 - send note-on messages and schedule note-off for later; #X text 283 220 updated for Pd version 0.28; #X text 10 214 see also; #X obj 23 10 stripnote; #X text 17 44 Stripnote takes note-off (zero-velocity) messages out of a stream of MIDI-style note message and passes the others through unchanged.; #X connect 0 0 3 0; #X connect 3 0 1 0; #X connect 3 1 2 0; #X connect 4 0 3 0; pd-0.46-7/doc/5.reference/my_canvas-help.pd0000664000175000017500000001641112160204055016473 0ustar mspmsp#N canvas 0 22 500 292 10; #X obj 1 1 cnv 15 300 60 foo10_snd foo10_rcv my_canvas=cnv 63 37 0 17 -257472 -355 0; #X text 4 232 (c) musil@iem.kug.ac.at; #X text 46 245 IEM KUG; #N canvas 219 100 699 530 edit 0; #X obj 39 226 f; #X msg 17 205 bang; #X floatatom 55 204 3 63 88 0 - - -; #X floatatom 90 226 3 0 37 0 - - -; #X obj 39 249 pack 0 0; #X text 117 226 y-label; #X text 83 204 x-label; #X obj 297 281 f; #X msg 275 260 bang; #X floatatom 313 259 3 -10 10 0 - - -; #X floatatom 348 281 3 -10 10 0 - - -; #X obj 297 304 pack 0 0; #X obj 309 396 f; #X msg 287 375 bang; #X floatatom 325 374 3 20 60 0 - - -; #X floatatom 360 396 3 150 200 0 - - -; #X obj 309 419 pack 0 0; #X text 341 259 x-delta; #X text 375 281 y-delta; #X text 353 374 x-position; #X text 387 396 y-position; #X obj 59 341 f; #X msg 37 320 bang; #X floatatom 75 319 3 0 2 0 - - -; #X floatatom 110 341 3 4 36 0 - - -; #X obj 59 364 pack 0 0; #X text 103 319 font; #X text 139 341 height; #X floatatom 275 183 3 2 20 0 - - -; #X msg 52 137 \; foo10_rcv color \$1 \$2; #X msg 39 274 \; foo10_rcv label_pos \$1 \$2; #X msg 59 390 \; foo10_rcv label_font \$1 \$2; #X msg 36 430 \; foo10_rcv label blabla; #X msg 36 466 \; foo10_rcv label my_canvas; #X msg 309 444 \; foo10_rcv pos \$1 \$2; #X msg 297 329 \; foo10_rcv delta \$1 \$2; #X obj 505 234 f; #X msg 483 213 bang; #X floatatom 521 212 5 100 1000 0 - - -; #X floatatom 556 234 4 50 500 0 - - -; #X obj 505 257 pack 0 0; #X text 566 212 width; #X text 594 236 height; #X msg 505 282 \; foo10_rcv vis_size \$1 \$2; #X msg 275 211 \; foo10_rcv size \$1; #X text 305 183 selectable size; #X msg 483 156 \; foo10a_rcv receive foo10_rcv; #X msg 483 119 \; foo10_rcv receive foo10a_rcv; #X msg 482 29 \; foo10_rcv send foo10a_snd; #X msg 482 67 \; foo10_rcv send foo10_snd; #X msg 509 372 \; foo10_rcv get_pos; #X obj 510 407 r foo10_snd; #X obj 510 428 unpack 0 0; #X floatatom 510 453 4 0 0 0 - - -; #X floatatom 575 452 4 0 0 0 - - -; #X text 490 452 x=; #X text 557 452 y=; #X obj 52 79 f; #X msg 29 31 bang; #X floatatom 68 29 3 0 29 0 - - -; #X floatatom 103 47 3 0 29 0 - - -; #X text 96 29 background; #X text 131 48 label-color; #X msg 290 25 back; #X msg 290 49 label; #X msg 252 25 bang; #N canvas 15 207 606 448 RGB_____________ 0; #X obj 97 56 inlet; #X obj 262 53 inlet; #X obj 339 55 inlet; #X obj 405 56 inlet; #X obj 97 270 bang; #X msg 77 295 0; #X msg 104 295 1; #X obj 146 268 bang; #X msg 132 295 0; #X msg 160 295 1; #X obj 265 313 spigot; #X obj 312 313 spigot; #X obj 249 385 outlet; #X text 93 33 select; #X text 267 28 red; #X text 337 30 green; #X text 409 30 blue; #X obj 405 102 t b f; #X obj 339 160 +; #X obj 339 185 t b f; #X obj 339 216 +; #X obj 296 385 outlet; #X obj 28 180 loadbang; #X obj 296 361 f; #X obj 249 361 f; #X obj 262 79 * -65536; #X obj 339 80 * -256; #X obj 405 80 * -1; #X obj 339 247 - 1; #X obj 97 135 route back label bang; #X obj 235 168 t b b b; #X connect 0 0 29 0; #X connect 1 0 25 0; #X connect 2 0 26 0; #X connect 3 0 27 0; #X connect 4 0 5 0; #X connect 4 0 6 0; #X connect 5 0 11 1; #X connect 6 0 10 1; #X connect 7 0 8 0; #X connect 7 0 9 0; #X connect 8 0 10 1; #X connect 9 0 11 1; #X connect 10 0 24 1; #X connect 11 0 23 1; #X connect 17 0 18 0; #X connect 17 1 18 1; #X connect 18 0 19 0; #X connect 19 0 20 0; #X connect 19 1 20 1; #X connect 20 0 28 0; #X connect 22 0 6 0; #X connect 23 0 21 0; #X connect 24 0 12 0; #X connect 25 0 20 0; #X connect 26 0 18 0; #X connect 27 0 17 0; #X connect 28 0 11 0; #X connect 28 0 10 0; #X connect 29 0 4 0; #X connect 29 1 7 0; #X connect 29 2 30 0; #X connect 30 0 24 0; #X connect 30 1 23 0; #X connect 30 2 28 0; #X restore 290 86 pd RGB_____________; #X floatatom 332 55 3 0 255 0 - - -; #X floatatom 375 55 3 0 255 0 - - -; #X floatatom 418 56 3 0 255 0 - - -; #X text 39 3 preset-colors; #X text 301 0 RGB-colors; #X text 332 37 red; #X text 368 36 green; #X text 416 36 blue; #X obj 52 104 pack 0 0; #X connect 0 0 4 0; #X connect 1 0 0 0; #X connect 2 0 0 1; #X connect 3 0 4 1; #X connect 4 0 30 0; #X connect 7 0 11 0; #X connect 8 0 7 0; #X connect 9 0 7 1; #X connect 10 0 11 1; #X connect 11 0 35 0; #X connect 12 0 16 0; #X connect 13 0 12 0; #X connect 14 0 12 1; #X connect 15 0 16 1; #X connect 16 0 34 0; #X connect 21 0 25 0; #X connect 22 0 21 0; #X connect 23 0 21 1; #X connect 24 0 25 1; #X connect 25 0 31 0; #X connect 28 0 44 0; #X connect 36 0 40 0; #X connect 37 0 36 0; #X connect 38 0 36 1; #X connect 39 0 40 1; #X connect 40 0 43 0; #X connect 51 0 52 0; #X connect 52 0 53 0; #X connect 52 1 54 0; #X connect 57 0 75 0; #X connect 58 0 57 0; #X connect 59 0 57 1; #X connect 60 0 75 1; #X connect 63 0 66 0; #X connect 64 0 66 0; #X connect 65 0 66 0; #X connect 66 0 75 0; #X connect 66 1 75 1; #X connect 67 0 66 1; #X connect 68 0 66 2; #X connect 69 0 66 3; #X connect 75 0 29 0; #X restore 315 20 pd edit; #X floatatom 110 193 4 0 0 0 - - -; #X floatatom 147 193 4 0 0 0 - - -; #X text 121 209 x; #X text 158 209 y; #X obj 7 161 metro 100; #X obj 33 141 tgl 15 1 empty empty empty 20 8 0 10 -262144 -1 -1 1 1; #X obj 110 145 r from_K1; #X floatatom 188 194 4 0 0 0 - - -; #X floatatom 225 194 4 0 0 0 - - -; #X text 198 210 x; #X text 236 210 y; #X obj 188 146 r from_K2; #X msg 7 185 \; to_K get_pos; #N canvas 0 296 395 395 room 0; #X obj 1 1 cnv 1 400 400 empty empty type...ctrl+e 150 140 2 17 -33289 -24198 0; #X obj 15 16 cnv 1 1 360 empty empty move_K1_and_K2 115 160 2 17 -166441 -24198 0; #X obj 374 15 cnv 1 1 360 empty empty empty 20 12 2 20 -99865 -66577 0; #X obj 15 15 cnv 1 360 1 empty empty empty 20 12 2 20 -166441 -66577 0; #X obj 17 375 cnv 1 358 1 empty empty empty 20 12 2 20 -99865 -66577 0; #X obj 23 22 cnv 25 25 25 from_K1 to_K K1 1 13 2 14 -261681 -123526 0; #X obj 342 342 cnv 25 25 25 from_K2 to_K K2 1 13 2 14 -225280 -1109 0; #X restore 307 147 pd room; #X obj 110 169 unpack; #X obj 188 170 unpack; #X text 51 92 to modify geometry \, colors \, etc.; #X obj 2 115 cnv 1 470 1 empty empty empty 20 12 2 20 -261681 -66577 0; #X text 40 78 of the light-blue; #X text 166 78 my_canvas-object \,; #X text 5 64 click the properties-dialog on the top-left corner; #X obj 361 195 r foo10_rcv; #X obj 403 215 s ggg; #X text 21 257 graz \, austria 2002; #X obj 187 236 x_all_guis aaa bbb ccc ddd eee fff ggg hhh iii; #X text 313 46 For cnv's creation arguments:; #N canvas 881 440 467 369 canvas-creation-arguments 0; #X msg 7 12 canvas: cnv selectableSize xSize ySize sendName recieveName Label labelXOff labelYOff Font# fontSize bgColor lblColor 0; #X text 9 169 For example \, a canvas called thusly:; #X obj 9 248 cnv 15 200 100 myCanvas myCanvasR Canvas_Demo 20 12 2 14 -62784 -195568 0; #X text 9 226 will result in this:; #X text 8 59 Canvas can be called with 13 creation arguments. These are not "optional" - all parameters must be filled or the canvas will not instantiate correctly.; #X text 10 114 The function of the final "0" is unknown to me (it is found in the textual entry for a canvas object in a .pd file) but can be safely left off without ill effects.; #X msg 9 191 cnv 15 200 100 myCanvas myCanvasR Canvas_Demo 20 12 2 14 18 20; #X restore 314 63 pd canvas-creation-arguments; #X text 172 257 updated for Pd version 0.35; #X connect 8 0 16 0; #X connect 9 0 8 0; #X connect 10 0 18 0; #X connect 15 0 19 0; #X connect 18 0 4 0; #X connect 18 1 5 0; #X connect 19 0 11 0; #X connect 19 1 12 0; #X connect 25 0 26 0; pd-0.46-7/doc/5.reference/list-help.pd0000664000175000017500000003371312374250720015501 0ustar mspmsp#N canvas 1009 137 597 581 12; #X obj 29 11 list; #X text 76 12 - building and using variable-length messages; #N canvas 88 122 654 658 about-lists 0; #X obj 50 629 print message; #X msg 50 442 list x.wav 44100; #X msg 50 600 read \$1 \$2; #X msg 50 471 set x.wav 44100; #X msg 67 571 set \, add2 read \, adddollar 1 \, adddollar 2; #X msg 50 501 x.wav 44100; #X obj 67 545 loadbang; #X text 155 548 reset message as it was; #X text 207 442 good; #X text 196 473 bad; #X text 162 501 ugly; #X text 48 180 The distinction becomes visible \, and ugly \, when the leading item in a data-holding message is a symbol. In this case \, to disambiguate it from the other sort \, the printed form of the message has a selector \, "list" or "symbol" prepended to it. Underneath \, there is always a selector in fromt of data messages \, but it is implied if the first data item is a number.; #X msg 411 465 list 44100 x.wav; #X msg 424 490 44100 x.wav; #X obj 411 516 print number-first; #X text 405 437 these two are equivalent:; #X text 50 298 In the example below \, the top message sets \$1 to "x.wav" and \$2 to 44100 in the "read" message. The lower message box outputs the message "read x.wav 44100". The "set" message changes the content of the message box itself (click on the longer message box below to repair the damage.) The "ugly" message \, since it is neither "list" nor "set" \, gets interpreted in an arbitrary (and probably inappropriate!) way.; #X text 47 12 Messages in Pd are somewhat artificially divided into two classes. First are data-holding messages (bang \, float \, symbol \, list) which are the primary way of communicating between objects. Second is "everything else" (you could call them out-of-band messages or metamessages) that describe changes in configuration \, read and write files \, quit Pd \, etc. These are provided so that complex objects don't need to have 100 separate inlets for every possible functionality. It's not clear whether this was a good design choice \, but it's entrenched. ; #X connect 1 0 2 0; #X connect 2 0 0 0; #X connect 3 0 2 0; #X connect 4 0 2 0; #X connect 5 0 2 0; #X connect 6 0 4 0; #X connect 12 0 14 0; #X connect 13 0 14 0; #X restore 53 386 pd about-lists; #X obj 22 82 list append; #X obj 22 107 list prepend; #X obj 22 157 list trim; #X obj 22 132 list split; #X text 140 81 - append the second list to the first; #X text 141 108 - prepend the second list to the first; #X text 141 133 - split a list in two; #X text 141 160 - trim the "list" selector off; #N canvas 186 284 602 409 trim 0; #X msg 159 239 1 2 3; #X msg 159 190 list cis boom bah; #X msg 160 265 bang; #X msg 159 163 walk the dog; #X obj 134 341 list trim; #X obj 134 363 print trim; #X msg 160 287 1 x y; #X msg 159 313 x 1 y; #X text 29 19 trim - convert list to message \, using first item as selector; #X msg 159 213 55; #X text 27 55 The "list trim" object inputs lists (or makes lists out of incoming non-list messages) and outputs a message whose selector is the first item of the list \, and whose arguments \, if any \, are the remainder of the list. If the list has no items \, or if its first item is numeric \, the selector is "list" (which might print out as list \, float \, or bang.); #X connect 0 0 4 0; #X connect 1 0 4 0; #X connect 2 0 4 0; #X connect 3 0 4 0; #X connect 4 0 5 0; #X connect 6 0 4 0; #X connect 7 0 4 0; #X connect 9 0 4 0; #X restore 484 157 pd trim; #X text 483 55 details:; #X text 481 38 click for; #N canvas 100 190 608 420 append 0; #X obj 17 324 list append 1 2; #X floatatom 17 154 5 0 0 0 - - -, f 5; #X msg 17 129 1 2 3; #X msg 17 82 list cis boom bah; #X msg 17 179 bang; #X msg 176 294 bang; #X obj 17 353 print append; #X msg 17 39 walk the dog; #X msg 176 244 list x y z; #X msg 175 218 go dog go; #X msg 174 268 4 5 6 and 7; #X text 138 37 non-list message converted to list; #X text 182 77 list starting with symbol; #X text 181 96 (needs explicit "list" selector); #X text 69 152 number is one-element list; #X text 72 129 numeric list; #X text 67 181 bang is zero-element list; #X text 270 215 same for right inlet...; #X text 286 267 (note: only the first item; #X text 289 286 need be a number to make this; #X text 289 304 a list.); #X text 170 325 <- creation args initialize the list to append; #X text 20 6 Append - append (concatenate) the second list to the first ; #X connect 0 0 6 0; #X connect 1 0 0 0; #X connect 2 0 0 0; #X connect 3 0 0 0; #X connect 4 0 0 0; #X connect 5 0 0 1; #X connect 7 0 0 0; #X connect 8 0 0 1; #X connect 9 0 0 1; #X connect 10 0 0 1; #X restore 484 81 pd append; #N canvas 390 321 667 561 split 0; #X msg 103 328 1 2 3; #X msg 79 231 list cis boom bah; #X msg 99 263 bang; #X obj 79 421 list split 2; #X floatatom 182 396 3 0 5 0 - - -, f 3; #X obj 79 469 print split1; #X obj 198 470 print split2; #X msg 79 204 walk the dog; #X msg 102 306 1 2; #X msg 100 285 1; #X msg 103 349 1 2 3 4; #X msg 103 372 1 2 so are you; #X obj 320 470 print split3; #X text 76 488 first n; #X text 195 489 rest of list; #X text 317 489 shorter than n; #X text 218 394 new split point; #X text 49 25 Split - cut a list into smaller ones; #X text 210 419 <-- creation arg inits split point; #X text 201 202 non-list message converted to list; #X text 245 231 list with three symbols; #X text 139 288 list with one number; #X text 177 310 ... etc; #X text 241 370 <- if the first item is a number \, it's a list.; #X text 142 262 list with no items; #X text 48 61 The "list split" object takes lists and outputs the first "n" items (left outlet) and the remaining ones (middle outlet). The two outputs appear in the usual right-to-left order. In case there are fewer than "n" items in the list \, it is output (in its entirety) from the third outlet instead. The creation argument or the inlet sets the split point.; #X connect 0 0 3 0; #X connect 1 0 3 0; #X connect 2 0 3 0; #X connect 3 0 5 0; #X connect 3 1 6 0; #X connect 3 2 12 0; #X connect 4 0 3 1; #X connect 7 0 3 0; #X connect 8 0 3 0; #X connect 9 0 3 0; #X connect 10 0 3 0; #X connect 11 0 3 0; #X restore 484 131 pd split; #N canvas 0 50 640 478 prepend 0; #X floatatom 17 154 5 0 0 0 - - -, f 5; #X msg 17 129 1 2 3; #X msg 17 82 list cis boom bah; #X msg 17 179 bang; #X msg 176 294 bang; #X obj 17 353 print append; #X msg 17 39 walk the dog; #X msg 176 244 list x y z; #X msg 175 218 go dog go; #X msg 174 268 4 5 6 and 7; #X text 138 37 non-list message converted to list; #X text 182 77 list starting with symbol; #X text 181 96 (needs explicit "list" selector); #X text 69 152 number is one-element list; #X text 72 129 numeric list; #X text 67 181 bang is zero-element list; #X text 270 215 same for right inlet...; #X text 286 267 (note: only the first item; #X text 289 286 need be a number to make this; #X text 289 304 a list.); #X text 20 6 Prepend - prepend the second list to the first; #X text 171 326 <- creation args initialize the list to prepend; #X obj 17 324 list prepend 1 2; #X connect 0 0 22 0; #X connect 1 0 22 0; #X connect 2 0 22 0; #X connect 3 0 22 0; #X connect 4 0 22 1; #X connect 6 0 22 0; #X connect 7 0 22 1; #X connect 8 0 22 1; #X connect 9 0 22 1; #X connect 22 0 5 0; #X restore 484 106 pd prepend; #X text 32 299 In general \, inlets that take lists (two each for append/prepend \, and one each for split and trim) will convert non-list messages (such as "set 5") to lists (such as "list set 5" automatically. Here's more about lists in Pd:; #X text 33 415 And here are some examples showing how to use these objects to compose and/or use variable length messages:; #N canvas 381 50 719 646 example1 0; #X obj 43 173 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 252 176 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X text 247 154 clear; #X text 40 153 send; #X msg 91 175 250; #X msg 123 175 500; #X msg 156 175 750; #X msg 189 175 1000; #X obj 43 258 list append; #X obj 208 220 t l; #X obj 91 214 list prepend; #X obj 43 426 t l l; #X obj 94 426 print start; #X obj 149 257 print stored; #X obj 43 451 list split 1; #X obj 43 575 del; #X obj 43 607 print bang; #X obj 75 542 list append; #X msg 55 403 0 250 250 500; #X text 118 150 -- add --; #X text 57 20 example 1: simple rhythmic sequencer; #X text 49 53 The top part of this patch demonstrates building up a message from a variable number of elements provided sequentially. The "list prepend" object stores the list and \, each time a number arrives \, prepends the previous list to it.; #X text 416 237 "list prepend" to its own inlet.; #X text 253 220 "trigger list" is needed only to connect outlet of ; #X text 274 258 printout shows the growing message.; #X text 67 279 "list append" stores the growing message which is output by the "send" button above. "list prepend" would have been equivalent. ; #X text 185 403 <-- test message; #X text 59 354 The bottom part of the patch takes numbers off the beginning of the list \, one by one \, to use as delays.; #X text 210 426 printout shows the sequence as it starts.; #X text 189 543 The rest of the list is stored for next time.; #X obj 161 505 print done; #X text 170 450 Split off the first item. If there is none \, nothing comes out the first or second outlet \, but instead we get a "bang" from the third one.; #X text 84 575 After delay \, output a bang and recall the rest of the list.; #X connect 0 0 8 0; #X connect 1 0 10 1; #X connect 4 0 10 0; #X connect 5 0 10 0; #X connect 6 0 10 0; #X connect 7 0 10 0; #X connect 8 0 11 0; #X connect 9 0 10 1; #X connect 10 0 9 0; #X connect 10 0 8 1; #X connect 10 0 13 0; #X connect 11 0 14 0; #X connect 11 1 12 0; #X connect 14 0 15 0; #X connect 14 1 17 1; #X connect 14 2 30 0; #X connect 15 0 16 0; #X connect 15 0 17 0; #X connect 17 0 14 0; #X connect 18 0 11 0; #X restore 224 468 pd example1; #X text 67 467 simple sequencer; #N canvas 126 50 568 569 example2 0; #X obj 66 263 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 292 266 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X text 287 244 clear; #X text 63 243 send; #X obj 66 342 list append; #X obj 213 317 t l; #X obj 94 303 list prepend; #X obj 66 410 t l l; #X obj 121 410 print start; #X obj 171 340 print stored; #X obj 66 486 del; #X obj 105 486 list append; #X msg 94 264 250 57; #X msg 154 264 500 52; #X msg 215 264 750 55; #X obj 66 461 unpack; #X obj 66 435 list split 2; #X text 80 38 example 2: sequencer with pitch; #X text 147 242 -- add --; #X obj 185 438 print done; #X obj 115 517 print pitch; #X text 13 69 This example is a slight modification of example 1 showing how to build up lists with more than one item per iteration. We regard pairs of numbers as specifying a delay time and a pitch. Unlike the previous example \, the delay here is interpreted as teh delay until the next event \, not the delay since the previous one. This is done by taking the "pitch" output before the delay object (previously the "output" was taken from the delay object's output.); #X connect 0 0 4 0; #X connect 1 0 6 1; #X connect 4 0 7 0; #X connect 5 0 6 1; #X connect 6 0 5 0; #X connect 6 0 4 1; #X connect 6 0 9 0; #X connect 7 0 16 0; #X connect 7 1 8 0; #X connect 10 0 11 0; #X connect 11 0 16 0; #X connect 12 0 6 0; #X connect 13 0 6 0; #X connect 14 0 6 0; #X connect 15 0 10 0; #X connect 15 1 20 0; #X connect 16 0 15 0; #X connect 16 1 11 1; #X connect 16 2 19 0; #X restore 224 494 pd example2; #X text 58 496 another sequencer; #X text 117 523 serializer; #N canvas 116 50 673 426 example3 0; #X obj 19 287 list split 1; #X obj 19 378 print; #X obj 19 204 until; #X obj 19 242 list append; #X obj 45 171 t b l; #X obj 149 287 bang; #X msg 45 148 1 2 3 4 a b c; #X text 34 21 example 3: serializing a message without delays; #X text 17 55 The "until" object can be used as shown to iterate through all the items of a list.; #X text 178 147 <- click to test; #X text 101 171 First store list \, then start the loop; #X text 118 199 "until" bangs its output until told to stop by a "bang" to its right inlet.; #X text 137 241 Store the remaining list.; #X text 194 286 third outlet of "split" tells us to stop.; #X text 67 318 Second outlet of "split" becomes the new list for "list append" above.; #X text 75 377 First outlet is the output.; #X connect 0 0 1 0; #X connect 0 1 3 1; #X connect 0 2 5 0; #X connect 2 0 3 0; #X connect 3 0 0 0; #X connect 4 0 2 0; #X connect 4 1 3 1; #X connect 5 0 2 1; #X connect 6 0 4 0; #X restore 224 521 pd example3; #X obj 30 265 list; #X text 78 266 - short for "list append"; #X text 141 185 - output number of items in list; #N canvas 187 106 576 365 length 0; #X msg 126 183 1 2 3; #X msg 126 134 list cis boom bah; #X msg 127 209 bang; #X msg 126 107 walk the dog; #X msg 127 231 1 x y; #X msg 126 257 x 1 y; #X msg 126 157 55; #X obj 101 285 list length; #X floatatom 101 311 5 0 0 0 - - -, f 5; #X text 29 18 length - number of items in list; #X text 27 55 The "list length" object outputs the number of arguments in a list or other message.; #X connect 0 0 7 0; #X connect 1 0 7 0; #X connect 2 0 7 0; #X connect 3 0 7 0; #X connect 4 0 7 0; #X connect 5 0 7 0; #X connect 6 0 7 0; #X connect 7 0 8 0; #X restore 484 183 pd length; #X obj 22 182 list length; #X text 23 53 The list object's first argument sets its function:; #X obj 22 207 list fromsymbol; #X obj 22 232 list tosymbol; #X text 138 220 - convert symbols to/from numeric characters; #N canvas 613 90 552 344 from/to 0; #X symbolatom 71 226 10 0 0 0 - - -, f 10; #X obj 71 249 list fromsymbol; #X text 92 15 fromsymbol and tosymbol - symbols to and from lists of numeric character codes, f 41; #X msg 237 204 115 101 118 101 110 116 101 101 110; #X obj 236 232 list tosymbol; #X obj 71 273 print from-symbol; #X text 39 69 These allow you to do string manipulations (such as scanning a filename for '/' characters). THey convert a list of numbers (which might be ASCII or might be unicode if \, for example \, they represent a filename on a non-ASCII machine) to or from a symbol., f 63; #X symbolatom 236 258 10 0 0 0 - - -, f 10; #X msg 71 200 symbol seventeen; #X connect 0 0 1 0; #X connect 1 0 5 0; #X connect 3 0 4 0; #X connect 4 0 7 0; #X connect 8 0 0 0; #X restore 483 221 pd from/to; #X text 355 526 updated for Pd version 0.46.; pd-0.46-7/doc/5.reference/tabwrite~-help.pd0000664000175000017500000000266312374250720016545 0ustar mspmsp#N canvas 502 203 645 442 12; #X obj 12 12 tabwrite~; #X msg 47 210 bang; #X obj 28 318 tabwrite~ array99; #N canvas 0 50 450 300 (subpatch) 0; #X array array99 1000 float 0; #X coords 0 1 999 -1 200 100 1; #X restore 414 207 graph; #X text 190 318 creation argument initializes array name; #X msg 45 288 set array99; #X msg 555 13 \; pd dsp 1; #X msg 555 51 \; pd dsp 0; #X text 23 353 see also the "array" tutorial in section 2 of the Pd documentation \, and these objects:; #X obj 107 389 tabread; #X obj 174 389 tabwrite; #X obj 250 389 tabsend~; #X obj 327 389 tabreceive~; #X obj 22 389 tabread4~; #X msg 48 260 stop; #X text 153 261 stop recording; #X msg 47 236 start 500; #X text 147 236 start in middle of table; #X text 370 420 updated for Pd version 0.40.; #X text 104 12 - write a signal in an array; #X obj 27 187 phasor~ 200; #X text 148 209 start recording; #X text 149 286 set destination array; #X text 16 44 Tabwrite~ records an audio signal sequentially into an array. Sending it "bang" writes from beginning to end of the array. To avoid writing all the way to the end \, you can send a "stop message at an appropriate later time. The "start" message allows setting the array location at which the first sample is written. (Starting and stopping occur on block boundaries \, typically multiples of 64 samples \, in the input signal.); #X connect 1 0 2 0; #X connect 5 0 2 0; #X connect 14 0 2 0; #X connect 16 0 2 0; #X connect 20 0 2 0; pd-0.46-7/doc/5.reference/samphold~-help.pd0000664000175000017500000000306012160204055016514 0ustar mspmsp#N canvas 430 114 568 497 12; #X obj 24 451 snapshot~; #X floatatom 24 476 5 0 0 0 - - -; #X obj 33 425 metro 100; #X obj 19 7 samphold~; #X text 96 6 - sample and hold unit; #X obj 24 376 samphold~; #X text 14 32 The samphold~ object samples its left input whenever its right input decreases in value (as a phasor~ does each period \, for example.) Both inputs are audio signals.; #X obj 59 340 sig~; #X obj 116 376 sig~; #X floatatom 59 315 3 0 0 0 - - -; #X floatatom 116 355 3 0 0 0 - - -; #X msg 24 212 set 34; #X msg 37 281 reset; #X text 89 210 set output to a number; #X text 97 315 sample signal; #X text 159 353 control signal; #X msg 32 244 reset 10; #X text 111 242 reset previous value; #X text 100 292 to force the next sample; #X obj 33 403 loadbang; #X text 320 472 updated for version 0.39; #X text 111 256 for control inlet; #X text 99 278 reset to default 1e+20; #X text 14 82 The "set" message sets the output value (which continues to be updated as normal afterward.) The "reset" message causes samphold~ to act as if the specified value were the most recent value of the control input. Use this \, for example \, if you reset the incoming phasor but don't want the jump reflected in the output. Plain "reset" is equivalent to "reset infinity" which forces the next input to be sampled.; #X msg 122 422 \; pd dsp 1; #X connect 0 0 1 0; #X connect 2 0 0 0; #X connect 5 0 0 0; #X connect 7 0 5 0; #X connect 8 0 5 1; #X connect 9 0 7 0; #X connect 10 0 8 0; #X connect 11 0 5 0; #X connect 12 0 5 0; #X connect 16 0 5 0; #X connect 19 0 2 0; #X connect 19 0 24 0; pd-0.46-7/doc/5.reference/message-help.pd0000664000175000017500000000464212160204055016142 0ustar mspmsp#N canvas 70 162 648 546 12; #X msg 67 10 message boxes; #X text 34 33 Message boxes hold one or more message. Anytime the message box receives any message at all \, the messages in the box are all sent to their destinations.; #X obj 120 295 print; #X msg 120 235 60 64; #X msg 120 265 pitch \$1 \, velocity \$2; #X msg 49 378 123 \; my-receiver-name 858 \; another-receiver -45; #X text 34 81 Clicking on a message also sends it \, so you can use messsage boxes for push buttins. For instance \, click here while watching the printout window:; #X msg 122 139 walk the dog; #X obj 122 168 print; #X text 239 139 <--- message; #X text 223 165 <--- object (different border); #X text 14 197 You can separate multiple messages by commas. Also \, you can use "$1" \, "$2" \, etc. to make variable messages:; #X text 14 323 Finally \, if you separate messages by a semicolon instead of a comma \, the following message(s) are re-routed to named objects such as "receives":; #X obj 49 433 print; #X obj 253 378 receive my-receiver-name; #X floatatom 253 402 0 0 0 0 - - -; #X floatatom 252 449 0 0 0 0 - - -; #X obj 252 425 receive another-receiver; #X text 396 519 updated for Pd version 0.39; #X text 19 471 You can send messages to message boxes to change their content - open the subpatch below for details:; #N canvas 0 0 718 466 changing-messages 0; #X msg 55 380 dog bird monkey \; bird; #X msg 58 69 set dog; #X msg 75 143 add monkey; #X msg 77 188 add2 bird; #X msg 72 117 set; #X text 92 29 Messages to change contents of messages boxes:; #X msg 66 92 set 1 2 3 skidoo; #X text 236 120 "set" with no arguments clears it; #X text 240 75 "set" to set contents (numbers and/or symbols); #X text 180 146 "add" to add numbers and/or symbols \, plus a terminating semicolon; #X text 168 190 "add2" to add contents without the terminating semicolon ; #X msg 83 222 addcomma; #X msg 82 248 addsemi; #X msg 78 305 adddollsym 4-foo; #X msg 84 275 adddollar 3; #X text 174 225 add a comma; #X text 173 244 add a semicolon; #X text 199 275 add a dollar-sign argument; #X text 235 305 add a dollar-sign-plus-symbol argument; #X connect 1 0 0 0; #X connect 2 0 0 0; #X connect 3 0 0 0; #X connect 4 0 0 0; #X connect 6 0 0 0; #X connect 11 0 0 0; #X connect 12 0 0 0; #X connect 13 0 0 0; #X connect 14 0 0 0; #X restore 153 512 pd changing-messages; #X connect 3 0 4 0; #X connect 4 0 2 0; #X connect 5 0 13 0; #X connect 7 0 8 0; #X connect 14 0 15 0; #X connect 17 0 16 0; pd-0.46-7/doc/5.reference/cos~-help.pd0000664000175000017500000000175212160204055015477 0ustar mspmsp#N canvas 190 40 698 331 12; #X obj 112 12 cos~; #X obj 23 200 cos~; #X obj 23 249 snapshot~; #X obj 23 152 sig~; #X floatatom 23 275 7 0 0 0 - - -; #X obj 23 125 * 0.01; #X floatatom 23 98 0 0 0 0 - - -; #X obj 90 215 metro 500; #X obj 90 189 r metro; #X msg 469 157 \; metro 0; #X msg 450 103 \; pd dsp 1 \; metro 1; #X text 159 13 - COSINE WAVESHAPER; #X text 86 125 Divide by 100; #X text 71 153 convert to audio; #X text 78 100 <-- Scroll to set input value; #X text 97 275 <-- output of the cos~ object; #X text 83 305 see also:; #X obj 171 307 osc~; #X obj 215 307 tabread4~; #X text 537 118 <-Click to start; #X text 538 163 <-Click to stop; #X text 13 41 The cos~ object outputs the cosine of two pi times its signal input. So -1 \, 0 \, 1 and 2 give 1 out \, 0.5 gives -1 \, and so on.; #X text 411 298 updated for Pd version 0.41; #X connect 1 0 2 0; #X connect 2 0 4 0; #X connect 2 0 4 0; #X connect 3 0 1 0; #X connect 5 0 3 0; #X connect 6 0 5 0; #X connect 7 0 2 0; #X connect 8 0 7 0; pd-0.46-7/doc/5.reference/clip~-help.pd0000664000175000017500000000167312160204055015644 0ustar mspmsp#N canvas 182 132 778 399 12; #X obj 75 164 clip~ -0.5 0.5; #X obj 75 104 osc~ 1000; #X graph graph1 0 1 100 -1 78 280 278 380; #X array array99 100 float 0; #X pop; #X obj 91 213 metro 500; #X obj 91 188 r metro; #X text 239 235 <-- graph the output; #X obj 75 237 tabwrite~ array99; #X msg 519 69 \; metro 0; #X msg 515 12 \; pd dsp 1 \; metro 1; #X text 604 26 <-- Click to start; #X text 589 73 <-- Click to stop; #X obj 42 19 clip~; #X text 88 18 - restrict a signal to lie between two limits; #X text 243 136 inlets to reset clip range; #X floatatom 135 136 4 0 0; #X floatatom 196 137 4 0 0; #X text 210 164 creation arguments initialize clip range; #X text 4 55 The clip~ object passes its signal input to its output \, clipping it to lie between two limits.; #X text 470 371 updated for Pd version 0.33; #X connect 0 0 6 0; #X connect 1 0 0 0; #X connect 3 0 6 0; #X connect 4 0 3 0; #X connect 4 0 3 0; #X connect 14 0 0 1; #X connect 15 0 0 2; pd-0.46-7/doc/5.reference/bp~-help.pd0000664000175000017500000000261512374250720015322 0ustar mspmsp#N canvas 531 65 657 420 12; #X obj 124 11 bp~; #X text 159 11 - BANDPASS FILTER; #X floatatom 109 286 5 0 0 0 - - -, f 5; #X floatatom 147 192 0 0 0 0 - - -; #X floatatom 12 287 5 0 0 0 - - -, f 5; #X text 199 264 env~ gives the amplitude of the signal envelop in dB. ; #X floatatom 12 123 0 0 0 0 - - -; #X msg 544 67 \; pd dsp 0; #X obj 12 146 osc~ 100; #X text 57 121 <-- scroll to change input frequency; #X msg 101 169 clear; #X text 151 168 <-- reinitialize internal state; #X msg 544 28 \; pd dsp 1; #X text 13 73 The left inlet is the incoming audio signal \, the middle control input sets center frequency and the rigth input sets "Q".; #X text 179 193 <-- center frequency; #X obj 109 236 bp~ 100 10; #X text 208 240 Arguments initialize center frequency and Q.; #X text 12 311 Compare the amplitude of the original signal on the left with the amplitude of the filtered signal on the right.; #X floatatom 186 214 0 0 0 0 - - -; #X text 218 215 <-- Q; #X text 11 35 bp~ passes a sinusoid at the center frequency at unit gain (approximately). Other frequencies are attenuated.; #X text 21 367 see also:; #X obj 106 367 vcf~; #X obj 11 261 env~ 8192; #X obj 109 261 env~ 8192; #X text 398 371 updated for Pd version 0.46; #X connect 3 0 15 1; #X connect 6 0 8 0; #X connect 8 0 15 0; #X connect 8 0 23 0; #X connect 10 0 15 0; #X connect 15 0 24 0; #X connect 18 0 15 2; #X connect 23 0 4 0; #X connect 24 0 2 0; pd-0.46-7/doc/5.reference/until-help.pd0000664000175000017500000000160512160204055015645 0ustar mspmsp#N canvas 142 97 410 273 10; #X msg 65 116 bang; #X obj 66 15 until; #X text 114 16 - LOOP; #X text 24 36 The until object's left inlet starts a loop in which it outputs "bang" until its right inlet gets a bang which stops it. If you start "until" with a number \, it iterates at most that number of times \, as in the Max "uzi" object.; #X text 24 85 WARNING: if you bang an "until" which doesn't have a stopping mechanism \, Pd goes into an infinite loop!; #X obj 65 168 until; #X text 110 115 start; #X msg 73 137 3; #X text 109 138 start limited to 3 iterations; #X obj 65 196 f; #X obj 96 198 + 1; #X obj 140 198 sel 0; #X obj 65 240 print; #X obj 96 219 mod 10; #X text 225 247 updated for Pd version 0.28; #X connect 0 0 5 0; #X connect 5 0 9 0; #X connect 7 0 5 0; #X connect 9 0 10 0; #X connect 9 0 12 0; #X connect 10 0 13 0; #X connect 11 0 5 1; #X connect 13 0 9 1; #X connect 13 0 11 0; pd-0.46-7/doc/5.reference/delwrite~-help.pd0000664000175000017500000000116712160204055016532 0ustar mspmsp#N canvas 12 24 663 281 12; #X obj 24 16 delwrite~; #X obj 24 158 delwrite~ del_line_xxx 500; #X text 88 123 signal input; #X text 116 16 writes a signal in a delay line; #X text 271 156 1st argument: name of delay line; #X text 411 243 updated for Pd version 0.33; #X obj 24 124 sig~ 0; #X text 19 50 Delwrite~ allocates memory for a delay line and writes an audio signal into it. Delread~ objects by hte same name read from the delay line.; #X text 294 186 (= max. delay time); #X text 271 172 2nd argument: length of delay line in msec; #X text 24 203 see also:; #X obj 112 205 delread~; #X obj 193 205 vd~; #X connect 6 0 1 0; pd-0.46-7/doc/5.reference/drawpolygon-help.pd0000664000175000017500000000426112160204055017060 0ustar mspmsp#N struct help-drawpolygon-template float x float y float cat float dog float weasel; #N canvas 16 28 537 188 12; #X text 13 130 see also:; #X obj 95 149 drawnumber; #X obj 191 149 plot; #X obj 21 10 drawpolygon; #X obj 21 33 drawcurve; #X obj 126 11 filledpolygon; #X obj 127 33 filledcurve; #X text 225 10 -- draw shapes for data structures; #N canvas 177 100 580 549 help-drawpolygon-template 1; #X obj 19 24 drawpolygon 0 2 0 0 0 weasel; #X obj 18 300 filledpolygon 900 dog 3 10 0 20 cat 30 0; #X text 30 322 filledpolygon and filledcurve take the same arguments \, except that a new first argument is added to specify interior color. Here the interior color is red (900) \, the outline color is controlled by the "dog" field \, and the three points describe a triangle of altitude "cat". The fields x and y automatically govern the placement of the object as a whole.; #X text 37 164 - RGB color (0=black \, 999=white \, 900=red \, 90=green \, 9=blue \, 555=grey \, etc.); #X text 36 201 - line width; #X text 36 222 - two or more (x \, y) pairs giving coordinates.; #X text 25 485 This object defines the fields for this template. You can see teh fields' values by right-clicking on the object in the "data" window and selecting "properties."; #X obj 13 441 struct help-drawpolygon-template float x float y float cat float dog float weasel; #X text 26 44 drawpolygon and drawcurve take these arguments:; #X text 40 67 - optional "-n" flag to make invisible initially; #X text 38 88 - alternatively \, an optional "-v [variable]" flag to assign a variable to make this visible/invisible.; #X text 27 243 Any of these (except the flags) can be numbers or field names \, like "weasel" here. The example above draws a vertical black line of height "weasel".; #X text 38 127 - optional "-x" flag to inhibit selecting the object when the shape is clicked on in "edit" mode; #X restore 240 92 pd help-drawpolygon-template; #N canvas 11 270 384 178 help-drawpolygon-data 1; #X scalar help-drawpolygon-template 50 40 30 9 80 \;; #X scalar help-drawpolygon-template 150 40 -20 90 50 \;; #X coords 0 178 1 177 0 0 0; #X restore 240 118 pd help-drawpolygon-data; #X obj 34 149 struct; #X text 272 166 updated for Pd version 0.40.; pd-0.46-7/doc/5.reference/czero_rev~-help.pd0000664000175000017500000001013212160204055016701 0ustar mspmsp#N canvas 118 9 534 590 12; #X obj 57 106 osc~ 100; #X msg 65 133 clear; #X obj 82 563 lop~; #X text 13 566 see also:; #X text 336 565 updated for Pd version-0.38; #X obj 89 513 rzero~; #X obj 40 533 cpole~; #X obj 40 513 rpole~; #X obj 138 513 rzero_rev~; #X obj 89 533 czero~; #X obj 138 533 czero_rev~; #X text 216 513 real; #X text 215 534 complex; #X text 37 497 1-pole; #X text 86 497 1-zero; #X text 136 497 1-zero \, reversed; #X text 62 482 summary of raw filters:; #X text 109 132 <-- clear internal state to zero; #N canvas 255 257 585 372 test 0; #X obj 152 296 env~ 16384; #X floatatom 152 320 5 0 0 0 - - -; #X floatatom 499 76 4 -1000 1000 0 - - -; #X obj 349 324 dac~; #X obj 349 288 *~; #X obj 390 70 cos~; #X floatatom 298 8 5 0 0 0 - - -; #X obj 298 31 phasor~; #X floatatom 398 14 5 0 0 0 - - -; #X obj 397 39 / 1000; #X obj 423 71 -~ 0.25; #X obj 423 93 cos~; #X obj 499 95 / 1000; #X obj 389 121 *~; #X obj 423 121 *~; #X obj 228 296 env~ 16384; #X floatatom 228 320 5 0 0 0 - - -; #X obj 381 284 dbtorms; #X floatatom 382 264 5 0 0 0 - - -; #X obj 117 89 phasor~; #X floatatom 115 60 5 0 0 0 - - -; #X text 77 13 Stuff to test it:; #X obj 131 149 cpole~; #X obj 241 262 *~ -1; #X obj 21 261 env~ 16384; #X floatatom 21 285 5 0 0 0 - - -; #X obj 50 312 env~ 16384; #X floatatom 50 336 5 0 0 0 - - -; #X obj 138 181 cpole~; #X obj 146 216 czero_rev~; #X obj 154 264 czero_rev~; #X msg 204 103 clear; #X obj 262 50 cos~; #X obj 261 83 *~ 0.02; #X obj 193 50 sig~ 1.1; #X obj 448 296 *~; #X connect 0 0 1 0; #X connect 2 0 12 0; #X connect 4 0 3 0; #X connect 5 0 13 0; #X connect 6 0 7 0; #X connect 7 0 32 0; #X connect 8 0 9 0; #X connect 9 0 7 1; #X connect 10 0 11 0; #X connect 11 0 14 0; #X connect 12 0 14 1; #X connect 12 0 13 1; #X connect 13 0 22 2; #X connect 13 0 28 2; #X connect 13 0 29 2; #X connect 13 0 30 2; #X connect 14 0 22 3; #X connect 14 0 23 0; #X connect 14 0 29 3; #X connect 15 0 16 0; #X connect 17 0 4 1; #X connect 17 0 35 1; #X connect 18 0 17 0; #X connect 19 0 22 0; #X connect 19 0 24 0; #X connect 19 0 35 0; #X connect 20 0 19 0; #X connect 22 0 28 0; #X connect 22 1 28 1; #X connect 23 0 28 3; #X connect 23 0 30 3; #X connect 24 0 25 0; #X connect 26 0 27 0; #X connect 28 0 26 0; #X connect 28 0 29 0; #X connect 28 1 29 1; #X connect 29 0 30 0; #X connect 29 1 30 1; #X connect 30 0 0 0; #X connect 30 0 4 0; #X connect 30 1 15 0; #X connect 31 0 22 0; #X connect 31 0 28 0; #X connect 32 0 33 0; #X connect 33 0 5 0; #X connect 33 0 10 0; #X connect 34 0 33 0; #X connect 35 0 3 1; #X restore 462 499 pd test; #X text 116 566 etc.: user-friendly filters; #X text 13 403 (Pd also provides a suite of user-friendly filters. This and other raw filters are provided for situations which the user-friendly ones can't handle. See Chapter 8 of http://crca.ucsd.edu/~msp/techniques for an introduction to the necessary theory.); #X text 121 107 <-- signal to filter (real part); #X text 120 189 <-- signal to filter (imaginary part); #X obj 87 188 sig~; #X obj 118 213 sig~; #X text 152 215 <-- filter coefficient (real part); #X obj 148 235 sig~; #X text 162 262 <-- creation arguments initialize filter; #X text 190 278 coefficient (real and imaginary part); #X text 153 160 <-- set internal state (real&imaginary parts); #X msg 67 159 set 0.6 0.8; #X text 182 237 <-- filter coefficient (imaginary part); #X text 17 295 The action of czero~ is:; #X text 14 336 where y[n] is the output \, x[n] the input \, and a[n] the filter coefficient (all complex numbers). The filter is always stable.; #X obj 56 260 czero~ 0.9 0.4; #X obj 36 7 czero_rev~; #X text 114 9 complex one-zero (non-recursive) "reverse" filter \, raw; #X text 11 34 Czero_rev~ filters a complex audio signal (first two inlets) via a one-zero filter \, whose coefficients are controlled by creation arguments or by another complex audio signal (remaining two inlets). The impulse response is that of "rzero" reversed in time. ; #X text 77 316 y[n] = - a[n] * x[n] + x[n-1]; #X text 15 385 The transfer function is H(Z) = -a + Z^-1.; #X connect 0 0 34 0; #X connect 1 0 34 0; #X connect 23 0 34 1; #X connect 24 0 34 2; #X connect 26 0 34 3; #X connect 30 0 34 0; pd-0.46-7/doc/5.reference/route-help.pd0000664000175000017500000000526112160204055015652 0ustar mspmsp#N canvas 58 56 699 665 12; #X obj 183 213 print x1; #X obj 261 213 print x2; #X obj 339 213 print x3; #X obj 422 213 print x4; #X obj 183 185 route 23 54 1; #X msg 183 155 234 345 456; #X msg 308 155 23 34 45; #X msg 414 155 54 43; #X msg 485 155 1 foo bar; #X msg 254 247 impeach ringo starr; #X obj 191 275 route big apple; #X msg 435 248 apple pie; #X msg 191 247 1 2 3; #X msg 523 248 big apple pie; #X msg 578 155 walk the dog; #X text 45 33 Route checks the first element of a message against each of its arguments \, which may be numbers or symbols (but not a mixture of the two.); #X text 44 85 If a match is found \, the rest of the message appears on the corresponding outlet. If no match \, the message is repeated to the last "rejection" outlet. The number of outlets is the number of arguments plus one.; #X text 19 185 numeric arguments:; #X text 17 275 symbolic arguments:; #X obj 157 489 print z1; #X obj 233 489 print z2; #X msg 124 424 bang; #X msg 170 424 list; #X msg 213 424 5; #X msg 251 424 float 5; #X msg 320 424 list 5; #X msg 385 424 symbol pie; #X msg 560 424 pie; #X msg 483 424 list pie; #X msg 70 424 1 2 3; #X obj 157 461 route list float symbol bang; #X obj 310 489 print z3; #X obj 387 489 print z4; #X obj 461 489 print z5; #X obj 191 305 print y1; #X obj 269 305 print y2; #X obj 347 305 print y3; #X text 76 344 To avoid confusion between \, say \, the number 5 and the list contining only the number 5 \, both messages match "float" \, and ditto for symbols. An empty list matches "bang". In Pd these are all considered special cases of lists.; #X text 97 9 - route messages according to their first element; #X obj 43 8 route; #X text 482 627 updated for Pd version 0.43; #X obj 132 564 route 4; #X msg 84 539 1 2 3; #X floatatom 187 540 5 0 0 0 - - -; #X msg 132 539 4 5 6; #X obj 131 590 print w1; #X obj 200 591 print w2; #X text 278 549 With zero or one argument \, route sprouts an inlet to set the arument (which may be float or symbol).; #X connect 4 0 0 0; #X connect 4 1 1 0; #X connect 4 2 2 0; #X connect 4 3 3 0; #X connect 5 0 4 0; #X connect 6 0 4 0; #X connect 7 0 4 0; #X connect 8 0 4 0; #X connect 9 0 10 0; #X connect 10 0 34 0; #X connect 10 1 35 0; #X connect 10 2 36 0; #X connect 11 0 10 0; #X connect 12 0 10 0; #X connect 13 0 10 0; #X connect 14 0 4 0; #X connect 21 0 30 0; #X connect 22 0 30 0; #X connect 23 0 30 0; #X connect 24 0 30 0; #X connect 25 0 30 0; #X connect 26 0 30 0; #X connect 27 0 30 0; #X connect 28 0 30 0; #X connect 29 0 30 0; #X connect 30 0 19 0; #X connect 30 1 20 0; #X connect 30 2 31 0; #X connect 30 3 32 0; #X connect 30 4 33 0; #X connect 41 0 45 0; #X connect 41 1 46 0; #X connect 42 0 41 0; #X connect 43 0 41 1; #X connect 44 0 41 0; pd-0.46-7/doc/5.reference/receive-help.pd0000664000175000017500000000162712160204055016140 0ustar mspmsp#N canvas 257 45 511 351 12; #X text 278 321 updated for Pd version 0.32; #X floatatom 36 55 5 0 0; #X floatatom 152 58 5 0 0; #X floatatom 272 57 5 0 0; #X floatatom 38 134 5 0 0; #X floatatom 171 136 5 0 0; #X floatatom 305 134 5 0 0; #X text 62 321 abbreviation:; #X obj 36 80 send help-rcv1; #X obj 152 81 send help-rcv1; #X obj 271 81 send help-rcv2; #X obj 38 110 receive help-rcv1; #X obj 171 110 receive help-rcv2; #X obj 305 110 receive help-rcv2; #X text 31 161 "Receive" outputs messages sent via "send." Sends and receives are named to tell them whom to connect to. They work across windows too. Also \, you can use message boxes as shown:; #X msg 84 233 \; help-rcv1 34 \; help-rcv2 67; #X obj 161 320 r; #X obj 21 10 receive; #X text 79 10 -- receive messages without patch cords; #X connect 1 0 8 0; #X connect 2 0 9 0; #X connect 3 0 10 0; #X connect 11 0 4 0; #X connect 12 0 5 0; #X connect 13 0 6 0; pd-0.46-7/doc/5.reference/abs~-help.pd0000664000175000017500000000110512160204055015450 0ustar mspmsp#N canvas 286 197 499 284 10; #X obj 19 108 sig~; #X obj 71 133 loadbang; #X obj 71 157 metro 100; #X obj 71 181 snapshot~; #X floatatom 19 87 5 0 0 0 - - -; #X floatatom 71 206 7 0 0 0 - - -; #X text 316 257 updated for Pd version 0.42.; #X obj 20 132 abs~; #X obj 21 14 abs~; #X text 60 14 - absolute value; #X text 82 33 Passes nonnegative values unchanged \, but replaces negative ones with their (positive) inverses.; #X text 81 66 (turn DSP on to test):; #X connect 0 0 7 0; #X connect 1 0 2 0; #X connect 2 0 3 0; #X connect 3 0 5 0; #X connect 4 0 0 0; #X connect 7 0 3 0; pd-0.46-7/doc/5.reference/print~-help.pd0000664000175000017500000000120512160204055016040 0ustar mspmsp#N canvas 118 333 531 212 10; #X msg 74 143 2; #X msg 455 77 \; pd dsp 0; #X msg 454 40 \; pd dsp 1; #X obj 62 177 print~; #X msg 74 118 bang; #X obj 62 92 phasor~ 1000; #X text 122 119 bang prints one vector; #X obj 454 18 loadbang; #X text 109 142 print two or more successive vectors; #X obj 32 12 print~; #X text 85 12 - print out raw values of a signal; #X text 301 171 Updated for Pd version 0.33; #X text 19 44 The print~ object takes a signal input and prints one or more vectors out when you send it a bang or a number. By default a vector is 64 samples.; #X connect 0 0 3 0; #X connect 4 0 3 0; #X connect 5 0 3 0; #X connect 7 0 2 0; pd-0.46-7/doc/5.reference/acoustics-help.pd0000664000175000017500000000323312160204055016506 0ustar mspmsp#N canvas 0 466 571 483 12; #X obj 32 393 ftom; #X obj 8 10 mtof; #X obj 32 341 mtof; #X floatatom 32 313 0 0 0 0 - - -; #X floatatom 32 368 0 0 0 0 - - -; #X obj 64 10 ftom; #X floatatom 32 417 0 0 0 0 - - -; #X obj 120 11 dbtorms; #X obj 196 11 rmstodb; #X obj 275 11 dbtopow; #X obj 352 11 powtodb; #X floatatom 164 309 0 0 0 0 - - -; #X floatatom 164 364 0 0 0 0 - - -; #X floatatom 164 413 0 0 0 0 - - -; #X obj 164 337 dbtorms; #X obj 164 389 rmstodb; #X floatatom 278 310 0 0 0 0 - - -; #X floatatom 278 365 0 0 0 0 - - -; #X floatatom 278 414 0 0 0 0 - - -; #X obj 278 338 dbtopow; #X obj 278 390 powtodb; #X text 23 245 Finally \, dbtopow and powtodb convert decibels to and from power units \, equal to the square of the "RMS" amplitude.; #X text 304 448 updated for pd version 0.40.; #X text 21 53 The mtof object transposes a midi value into a frequency in Hertz \, so that "69" goes to "440". You can specify microtonal pitches as in "69.5" (a quarter tone higher than 69). Ftom does the reverse. A frequency of zero Hertz is given a MIDI value of -1500 (strictly speaking \, it is negative infinity.); #X text 22 149 The dbtorms and rmstodb objects convert from decibels to linear ("RMS") amplitude \, so that 100 dB corresponds to an "RMS" of 1 Zero amplitude (strictly speaking \, minus infinity dB) is clipped to zero dB \, and zero dB \, which should correspond to 1e-04 in "RMS" \, is instead rounded down to zero.; #X connect 0 0 6 0; #X connect 2 0 4 0; #X connect 3 0 2 0; #X connect 4 0 0 0; #X connect 11 0 14 0; #X connect 12 0 15 0; #X connect 14 0 12 0; #X connect 15 0 13 0; #X connect 16 0 19 0; #X connect 17 0 20 0; #X connect 19 0 17 0; #X connect 20 0 18 0; pd-0.46-7/doc/5.reference/numbox2-help.pd0000664000175000017500000001724012160204055016106 0ustar mspmsp#N canvas 290 235 617 416 10; #X obj 1 1 cnv 8 100 60 empty empty numbox=nbx 20 20 1 18 -262144 -1109 0; #X floatatom 38 300 9 0 0; #X msg 47 84 set \$1; #X floatatom 38 43 7 0 0; #X text 25 363 (c) musil@iem.kug.ac.at; #X text 67 376 IEM KUG; #X obj 38 324 bng 15 250 50 0 empty empty empty 8 -8 0 10 -262144 -1 -1; #X obj 18 47 bng 15 250 50 0 empty empty empty 8 -8 0 10 -262144 -1 -1; #X floatatom 47 63 7 0 0; #X floatatom 116 324 9 0 0; #X floatatom 106 42 7 0 0; #X floatatom 183 113 7 0 0; #X obj 111 249 ftom; #X floatatom 111 271 9 0 0; #X floatatom 147 244 9 0 0; #X floatatom 221 266 9 0 0; #X text 217 151 click properties to; #X floatatom 111 112 9 0 0; #X obj 111 134 mtof; #X text 202 65 (0.01 pixels); #X text 57 99 ------------------------------------------; #X text 57 286 --------------------------------------------; #X text 205 162 modify geometry \, colors \, etc.; #X msg 106 63 set \$1; #X text 188 44 shift-click & drag; #X text 194 54 for fine-tuning; #X text 195 203 UP- \, DOWN- \, LEFT- or RIGHT-key; #X text 193 214 for moving selected gui-objects; #N canvas 239 379 699 530 edit 0; #X obj 37 233 f; #X msg 15 212 bang; #X floatatom 53 211 3 6 88; #X floatatom 88 233 3 -20 37; #X obj 37 256 pack 0 0; #X text 115 233 y-label; #X text 81 211 x-label; #X obj 287 271 f; #X msg 265 250 bang; #X floatatom 303 249 3 -10 10; #X floatatom 338 271 3 -10 10; #X obj 287 294 pack 0 0; #X obj 299 381 f; #X msg 277 360 bang; #X floatatom 315 359 3 20 90; #X floatatom 350 381 3 150 200; #X obj 299 404 pack 0 0; #X text 331 249 x-delta; #X text 365 271 y-delta; #X text 343 359 x-position; #X text 377 381 y-position; #X obj 57 348 f; #X msg 35 327 bang; #X floatatom 73 326 3 0 2; #X floatatom 108 348 3 4 36; #X obj 57 371 pack 0 0; #X text 101 326 font; #X text 137 348 height; #X floatatom 476 188 1 0 1; #X text 523 401 no init; #X text 493 453 init value on loadbang; #X text 520 188 steady; #X obj 486 291 f; #X msg 464 270 bang; #X floatatom 502 269 4 55 440; #X floatatom 537 291 6 440 3520; #X obj 486 314 pack 0 0; #X text 269 469 linear / logarithmical; #X msg 47 158 \; goo4_rcv color \$1 \$2 \$3; #X msg 37 281 \; goo4_rcv label_pos \$1 \$2; #X msg 57 396 \; goo4_rcv label_font \$1 \$2; #X msg 40 442 \; goo4_rcv label blabla; #X msg 269 487 \; goo4_rcv lin; #X msg 363 486 \; goo4_rcv log; #X msg 299 429 \; goo4_rcv pos \$1 \$2; #X msg 287 319 \; goo4_rcv delta \$1 \$2; #X msg 475 21 \; goo4_rcv send goo4a_snd; #X msg 475 59 \; goo4_rcv send goo4_snd; #X msg 476 105 \; goo4_rcv receive goo4a_rcv; #X msg 476 143 \; goo4a_rcv receive goo4_rcv; #X msg 486 339 \; goo4_rcv range \$1 \$2; #X msg 502 420 \; goo4_rcv init 0; #X msg 503 471 \; goo4_rcv init 1; #X text 539 270 bottom-range-bound; #X text 586 292 top-range-bound; #X obj 286 160 f; #X msg 264 139 bang; #X floatatom 302 138 3 4 55; #X floatatom 337 160 3 15 73; #X obj 286 183 pack 0 0; #X msg 286 208 \; goo4_rcv size \$1 \$2; #X text 330 138 width; #X text 368 161 height; #X msg 41 478 \; goo4_rcv label log.freq.; #X msg 476 212 \; goo4_rcv steady \$1; #X obj 47 116 pack 0 0 0; #X obj 47 88 f; #X msg 24 40 bang; #X floatatom 63 38 3 0 29; #X floatatom 79 58 3 0 29; #X floatatom 112 74 3 0 29; #X text 91 38 background; #X text 106 58 front-color; #X text 140 75 label-color; #X msg 285 37 back; #X msg 285 57 front; #X msg 285 77 label; #X msg 247 37 bang; #N canvas 15 207 606 448 RGB_____________ 0; #X obj 97 56 inlet; #X obj 262 53 inlet; #X obj 339 55 inlet; #X obj 405 56 inlet; #X obj 97 270 bang; #X msg 77 295 0; #X msg 104 295 1; #X obj 146 268 bang; #X msg 132 295 0; #X msg 160 295 1; #X obj 196 269 bang; #X msg 187 295 0; #X msg 214 295 1; #X obj 265 313 spigot; #X obj 312 313 spigot; #X obj 359 313 spigot; #X obj 249 385 outlet; #X text 93 33 select; #X text 267 28 red; #X text 337 30 green; #X text 409 30 blue; #X obj 405 102 t b f; #X obj 339 160 +; #X obj 339 185 t b f; #X obj 339 216 +; #X obj 296 385 outlet; #X obj 343 385 outlet; #X obj 28 180 loadbang; #X obj 97 135 route back front label bang; #X obj 343 362 f; #X obj 296 361 f; #X obj 249 361 f; #X obj 262 79 * -65536; #X obj 339 80 * -256; #X obj 405 80 * -1; #X obj 339 247 - 1; #X obj 235 168 t b b b b; #X connect 0 0 28 0; #X connect 1 0 32 0; #X connect 2 0 33 0; #X connect 3 0 34 0; #X connect 4 0 5 0; #X connect 4 0 6 0; #X connect 5 0 14 1; #X connect 5 0 15 1; #X connect 6 0 13 1; #X connect 7 0 8 0; #X connect 7 0 9 0; #X connect 8 0 13 1; #X connect 8 0 15 1; #X connect 9 0 14 1; #X connect 10 0 11 0; #X connect 10 0 12 0; #X connect 11 0 13 1; #X connect 11 0 14 1; #X connect 12 0 15 1; #X connect 13 0 31 1; #X connect 14 0 30 1; #X connect 15 0 29 1; #X connect 21 0 22 0; #X connect 21 1 22 1; #X connect 22 0 23 0; #X connect 23 0 24 0; #X connect 23 1 24 1; #X connect 24 0 35 0; #X connect 27 0 6 0; #X connect 28 0 4 0; #X connect 28 1 7 0; #X connect 28 2 10 0; #X connect 28 3 36 0; #X connect 29 0 26 0; #X connect 30 0 25 0; #X connect 31 0 16 0; #X connect 32 0 24 0; #X connect 33 0 22 0; #X connect 34 0 21 0; #X connect 35 0 15 0; #X connect 35 0 14 0; #X connect 35 0 13 0; #X connect 36 0 31 0; #X connect 36 1 30 0; #X connect 36 2 29 0; #X connect 36 3 35 0; #X restore 285 98 pd RGB_____________; #X floatatom 327 67 3 0 255; #X floatatom 370 67 3 0 255; #X floatatom 413 68 3 0 255; #X text 34 12 preset-colors; #X text 296 9 RGB-colors; #X text 327 49 red; #X text 363 48 green; #X text 411 48 blue; #X connect 0 0 4 0; #X connect 1 0 0 0; #X connect 2 0 0 1; #X connect 3 0 4 1; #X connect 4 0 39 0; #X connect 7 0 11 0; #X connect 8 0 7 0; #X connect 9 0 7 1; #X connect 10 0 11 1; #X connect 11 0 45 0; #X connect 12 0 16 0; #X connect 13 0 12 0; #X connect 14 0 12 1; #X connect 15 0 16 1; #X connect 16 0 44 0; #X connect 21 0 25 0; #X connect 22 0 21 0; #X connect 23 0 21 1; #X connect 24 0 25 1; #X connect 25 0 40 0; #X connect 28 0 64 0; #X connect 32 0 36 0; #X connect 33 0 32 0; #X connect 34 0 32 1; #X connect 35 0 36 1; #X connect 36 0 50 0; #X connect 55 0 59 0; #X connect 56 0 55 0; #X connect 57 0 55 1; #X connect 58 0 59 1; #X connect 59 0 60 0; #X connect 65 0 38 0; #X connect 66 0 65 0; #X connect 67 0 66 0; #X connect 68 0 66 1; #X connect 69 0 65 1; #X connect 70 0 65 2; #X connect 74 0 78 0; #X connect 75 0 78 0; #X connect 76 0 78 0; #X connect 77 0 78 0; #X connect 78 0 65 0; #X connect 78 1 65 1; #X connect 78 2 65 2; #X connect 79 0 78 1; #X connect 80 0 78 2; #X connect 81 0 78 3; #X restore 327 48 pd edit; #X obj 61 345 print; #N canvas 276 200 290 224 once 0; #X obj 38 47 t b b f; #X msg 56 85 1; #X obj 31 108 f 0; #X obj 31 131 pack 0 0; #X obj 31 156 route 0; #X obj 38 24 inlet; #X obj 31 180 outlet; #X connect 0 0 1 0; #X connect 0 1 2 0; #X connect 0 2 3 1; #X connect 1 0 2 1; #X connect 2 0 3 0; #X connect 3 0 4 0; #X connect 4 0 6 0; #X connect 5 0 0 0; #X restore 61 322 pd once; #X obj 249 87 x_all_guis aaa bbb ccc ddd eee fff ggg hhh iii; #X text 218 387 updated for Pd version 0.35; #X text 42 388 graz \, austria 2002; #X text 192 13 gui-number-box:; #X obj 106 84 s foo13_rcv; #X obj 183 133 s goo14_rcv; #X obj 221 244 r goo14_snd; #X obj 116 302 r foo13_snd; #X obj 47 172 nbx 4 15 100 300 0 0 foo13_snd foo13_rcv empty 45 7 192 10 -225280 -1109 -1 100 256; #X obj 111 200 nbx 5 18 55 3520 1 0 goo14_snd goo14_rcv log.freq. 45 -10 192 14 -261681 -260818 -90881 55 72; #X obj 464 114 nbx 5 14 -1e+37 1e+37 0 0 hhh hhh empty 45 7 192 10 -262144 -1 -1 0 256; #X connect 1 0 6 0; #X connect 2 0 39 0; #X connect 3 0 39 0; #X connect 7 0 39 0; #X connect 8 0 2 0; #X connect 10 0 23 0; #X connect 11 0 36 0; #X connect 12 0 13 0; #X connect 17 0 18 0; #X connect 18 0 40 0; #X connect 23 0 35 0; #X connect 30 0 29 0; #X connect 37 0 15 0; #X connect 38 0 9 0; #X connect 39 0 30 0; #X connect 39 0 1 0; #X connect 40 0 12 0; #X connect 40 0 14 0; pd-0.46-7/doc/5.reference/timer-help.pd0000664000175000017500000000303112374250720015634 0ustar mspmsp#N canvas 58 53 601 508 12; #X msg 67 190 bang; #X msg 30 115 bang; #X obj 30 220 timer; #X obj 84 13 timer; #X text 129 14 - measure logical time; #X floatatom 30 251 0 0 0 0 - - -; #X text 12 48 The timer object measures elapsed logical time. Logical time moves forward as if all computation were instantaneous and as if all "delay" and "metro" objects were exact.; #X text 337 458 updated for Pd version 0.45; #X text 27 277 Output is in the specified time units \, milliseconds by default., f 63; #X text 105 191 Bang in inlet: output elapsed time; #X text 73 113 bang: reset elapsed time to zero, f 33; #X msg 29 154 tempo 2 msec; #X text 142 149 set tempo in units of milliseconds (msec for short) \, seconds (sec) \, minutes (min) or samples (samp)., f 52; #X text 46 453 see also:; #X obj 406 301 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 407 372 bng 25 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 266 396 delay; #X text 96 389 for details on tempo setting \, see:, f 20; #X obj 443 377 sel 1; #X floatatom 443 432 5 0 0 0 - - -, f 5; #X obj 406 321 t f f; #X obj 134 453 metro; #X obj 407 347 metro 1 90 permin; #X obj 443 407 timer 90 permin; #X text 97 309 for example \, this metronome outputs at intervals of one beat at 90 beats per minute \, as measured by a timer also set to that tempo:, f 37; #X connect 0 0 2 1; #X connect 1 0 2 0; #X connect 2 0 5 0; #X connect 14 0 20 0; #X connect 15 0 23 1; #X connect 18 0 23 0; #X connect 20 0 22 0; #X connect 20 1 18 0; #X connect 22 0 15 0; #X connect 23 0 19 0; pd-0.46-7/doc/5.reference/getsize-help.pd0000664000175000017500000000400112425762123016166 0ustar mspmsp#N struct help-getsize-template float x float y array array1 help-getsize-array1-template ; #N struct help-getsize-array1-template float y; #N canvas 465 131 639 497 12; #X text 27 408 see also:; #N canvas 393 50 495 265 help-getsize-template 0; #X obj 27 76 plot array1 500 1 10 15 20; #X obj 27 174 filledpolygon 509 509 0 -10 -10 10 -10 10 10 -10 10; #X obj 24 16 struct help-getsize-template float x float y array array1 help-getsize-array1-template; #X restore 337 400 pd help-getsize-template; #N canvas 2 52 305 197 help-getsize-data 1; #X scalar help-getsize-template 43 37 \; 0 \; 10 \; 0 \; 10 \; 20 \; 10 \; 20 \; 70 \; 10 \; \;; #X restore 336 379 pd help-getsize-data; #N canvas 196 292 369 138 help-getsize-array1-template 0; #X obj 30 71 filledpolygon 0 0 0 -5 0 0 5 5 0 0 -5; #X obj 32 27 struct help-getsize-array1-template float y; #X restore 336 423 pd help-getsize-array1-template; #X obj 101 428 pointer; #X obj 235 427 setsize; #X obj 24 255 pointer; #X msg 24 231 traverse pd-help-getsize-data \, next; #X floatatom 24 373 5 0 0 0 - - -, f 5; #X text 329 337 arguments: template \, field name; #X text 75 371 here we just get the value of y.; #X obj 24 344 getsize help-getsize-template array1; #X text 33 323 inlet for pointer; #X obj 35 21 getsize; #X text 98 22 -- get number of elements of an array; #X text 24 44 When sent a pointer \, "element" looks up a field \, which should be an array \, and outputs the number of elements of the array. The template and field name are specified as creation arguments. ; #X text 26 114 The smallest possible size is one.; #X obj 168 428 element; #X obj 24 428 struct; #X text 80 274 set template and field name; #X text 396 463 updated for Pd version 0.47; #X text 24 147 If you don't know the template name you may specify "-" \, in which case the object will figure out the template name itself \, at some possible cost in efficiancy and clarity.; #X msg 34 293 set help-getsize-template array1; #X connect 6 0 11 0; #X connect 7 0 6 0; #X connect 11 0 8 0; #X connect 22 0 11 0; pd-0.46-7/doc/5.reference/moses-help.pd0000664000175000017500000000113112160204055015632 0ustar mspmsp#N canvas 0 0 624 300 12; #X obj 72 196 moses 10; #X floatatom 72 164 4 0 0; #X floatatom 139 167 4 0 0; #X floatatom 72 229 4 0 0; #X floatatom 139 230 4 0 0; #X obj 63 24 moses; #X text 118 23 - part a stream of numbers; #X text 303 235 updated for Pd version 0.33; #X text 24 64 Moses takes numbers and outputs them at left if they're less than a control value \, and at right if they're greater or equal to it. The creation argument initializes the control value (10 in this example) and the right inlet changes it.; #X connect 0 0 3 0; #X connect 0 1 4 0; #X connect 1 0 0 0; #X connect 2 0 0 1; pd-0.46-7/doc/5.reference/realtime-help.pd0000664000175000017500000000102112160204055016304 0ustar mspmsp#N canvas 156 202 565 269 12; #X msg 73 146 bang; #X msg 30 115 bang; #X floatatom 30 206 0 0 0; #X text 71 113 Click here to reset; #X text 27 232 Output is in milliseconds; #X text 114 147 Click here to get elapsed CPU time; #X obj 66 15 realtime; #X text 12 47 The realtime object measures elapsed real time \, as measured by your operating system.; #X obj 30 176 realtime; #X text 134 15 - ask OS for elapsed real time; #X text 302 244 updated for Pd version 0.33; #X connect 0 0 8 1; #X connect 1 0 8 0; #X connect 8 0 2 0; pd-0.46-7/doc/5.reference/vcf~-help.pd0000664000175000017500000000321512374250720015474 0ustar mspmsp#N canvas 1 51 666 539 12; #X obj 265 266 sig~; #X text 22 259 test signal; #X text 108 407 amp in (db); #X text 100 210 test frequency; #X text 254 210 center frequency; #X text 382 250 q; #X floatatom 130 234 5 0 0 0 - - -, f 5; #X floatatom 265 237 5 0 0 0 - - -, f 5; #X obj 130 259 osc~; #X floatatom 361 269 5 0 0 0 - - -, f 5; #X obj 130 357 env~ 8192; #X obj 227 377 env~ 8192; #X floatatom 129 384 5 0 0 0 - - -, f 5; #X floatatom 227 406 5 0 0 0 - - -, f 5; #X obj 80 13 vcf~; #X text 135 13 -- voltage-controlled bandpass filter; #X text 34 461 see also:; #X obj 123 460 bp~; #X obj 228 330 vcf~ 1; #X text 298 322 optional argument to initialize q; #X obj 351 380 env~ 8192; #X floatatom 351 407 5 0 0 0 - - -, f 5; #X text 11 43 vcf~ is a resonant band-pass and low-pass filter that takes an audio signal to set center frequency \, which may thus change continuously in time. The "Q" or filter sharpness is still only set by messages. More expensive but more powerful than the bp~ bandpass filter.; #X msg 544 67 \; pd dsp 0; #X msg 544 28 \; pd dsp 1; #X text 419 509 updated for Pd version 0.46; #X text 9 129 vcf~ is implemented as a one-pole complex filter with outlets for the real and imaginary value. These may be used as bandpass and lowpass filter outputs \, or combined to allow other possibilities. ; #X text 224 445 (bandpass); #X text 356 450 (lowpass); #X text 224 428 real output; #X text 345 431 imaginary output; #X connect 0 0 18 1; #X connect 6 0 8 0; #X connect 7 0 0 0; #X connect 8 0 10 0; #X connect 8 0 18 0; #X connect 9 0 18 2; #X connect 10 0 12 0; #X connect 11 0 13 0; #X connect 18 0 11 0; #X connect 18 1 20 0; #X connect 20 0 21 0; pd-0.46-7/doc/5.reference/drawtext-help.pd0000664000175000017500000000434412572421652016372 0ustar mspmsp#N struct help-drawnumber-template float x float y float cat float dog symbol weasel; #N canvas 445 324 600 204 12; #X text 15 103 see also:; #X obj 18 7 drawnumber; #X obj 187 132 plot; #X obj 83 131 drawpolygon; #X text 240 0 -- draw numeric fields from data structures; #N canvas 11 52 375 224 help-drawnumber-data 1; #X scalar help-drawnumber-template 50 100 23 43 ethel \;; #X scalar help-drawnumber-template 150 50 3.14 -1.618 fred \;; #X restore 273 71 pd help-drawnumber-data; #N canvas 439 52 565 765 help-drawnumber-template 1; #X text 25 567 This object defines the fields for this template. Their values are initialized in the "works" subwindow. You can see them by right-clicking on the object in the "data" window and selecting "properties." ; #X text 42 211 - RGB color (0=black \, 999=white \, 900=red \, 90=green \, 9=blue \, 555=grey \, etc.); #X text 19 316 When not in "edit" mode \, you can click and drag vertically on the numbers to change their values. (In edit mode you can move \, cut \, copy \, and paste the objects.); #X text 21 365 Keyboard entry isn't supported yet.; #X obj 25 56 drawnumber cat 0 0 0 cat=; #X obj 260 57 drawnumber dog 0 -15 900 dog=; #X text 42 243 - an optional label ("cat=" for instance); #X text 27 85 drawnumber takes arguments specifying:; #X text 42 191 - an (x \, y) pair giving relative coordinates \;; #X text 42 171 - the number to draw; #X text 44 24 "0" in inlet makes invisible; #X obj 25 27 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X text 46 112 - optional "-n" flag to make invisible initially; #X text 44 133 - alternatively \, an optional "-v [variable]" flag to assign a variable to make this visible/invisible.; #X text 20 273 Any of these (except the two flags) can be numbers or field names \, like "dog" and "cat" here.; #X obj 27 646 struct help-drawnumber-template float x float y float cat float dog symbol weasel; #X obj 26 460 drawsymbol weasel 0 -30 0 weasel=; #X text 26 405 To draw a symbol \, use the drawsymbol object. Same arguments. No way to edit symbols though - they can only be changed through "set" objects..; #X connect 11 0 4 0; #X restore 273 44 pd help-drawnumber-template; #X obj 22 130 struct; #X text 275 159 updated for Pd version 0.39; #X obj 107 8 drawsymbol; pd-0.46-7/doc/5.reference/writesf~-help.pd0000664000175000017500000000345712160204055016402 0ustar mspmsp#N canvas 146 65 733 567 12; #X msg 592 11 \; pd dsp 1; #X msg 141 163 print; #X msg 53 83 bang; #X msg 140 115 start; #X msg 142 141 stop; #X obj 53 114 del 1000; #X text 41 9 writesf~ -- write audio signals to a soundfile; #X text 230 212 creation argument is number of channels; #X text 259 234 (1 to 64).; #X text 193 115 start streaming audio; #X text 188 141 stop streaming audio; #X obj 131 207 writesf~ 2; #X msg 131 31 open /tmp/foo.wav; #X obj 131 538 soundfiler; #X text 485 540 updated for Pd version 0.37; #X text 36 539 see also:; #X obj 145 185 osc~ 440; #X text 34 257 writesf~ creates a subthread whose task is to write audio streams to disk. You need not provide any disk access time between "open" and "start" \, but between "stop" and the next "open" you must give the object time to flush all the output to disk.; #X msg 131 86 open -bytes 4 /tmp/foo.wav; #X text 300 30 create a new 16-bit soundfile; #X text 377 59 create 24-bit soundfile; #X text 376 86 create 32-bit floating-point soundfile; #X msg 131 59 open -bytes 3 /tmp/foo.wav; #X text 33 339 The soundfile is 2- or 3-byte fixed point ("pcm") or 4-byte floating-point. The soundfile format is determined by the file extent ("foo.wav" \, "foo.aiff" \, or "foo.snd").; #X obj 233 540 readsf~; #X text 66 413 -wave \, -nextstep \, -aiff; #X text 67 434 -big \, -little (nextstep only!); #X text 67 455 -bytes <2 \, 3 \, or 4>; #X text 67 477 -rate ; #X text 32 395 The "open" message may take flag-style arguments as follows:; #X text 27 498 (setting sample rate will affect the soundfile header but the file will _not_ be resampled.); #X connect 1 0 11 0; #X connect 2 0 3 0; #X connect 2 0 5 0; #X connect 3 0 11 0; #X connect 4 0 11 0; #X connect 5 0 4 0; #X connect 12 0 11 0; #X connect 16 0 11 0; #X connect 18 0 11 0; #X connect 22 0 11 0; pd-0.46-7/doc/5.reference/pack-help.pd0000664000175000017500000000261012160204055015425 0ustar mspmsp#N canvas 14 8 809 354 12; #X floatatom 19 86 0 0 0; #X msg 29 115 bang; #X floatatom 49 138 0 0 0; #X floatatom 188 138 0 0 0; #X obj 19 254 print; #X msg 86 138 symbol cat; #X obj 82 9 pack; #X text 28 319 See also; #X obj 106 321 unpack; #X text 14 34 The pack object takes a series of inputs and outputs a concatenated list. The number of creation arguments determines the number of inlets.; #X text 60 85 <-- number in first inlet generates output; #X text 70 114 <-- bang generates output without resetting first value ; #X text 226 135 <-- numbers and symbols in the corresponding inlets change the values without causing output (see "trigger" for a way to change this behavior.); #X text 250 187 <-- as with any Pd object \, you can send a list whose atoms are automatically distributed to the corresponding inlets.; #X msg 175 190 1 2 dog; #X obj 167 321 trigger; #X obj 19 227 pack 100 0 s 0; #X text 121 9 - combine several atoms into one message; #X text 155 226 <-- creation arguments specify the number of inlets and their types: a number make a numeric outlet (and initializes the value). A symbol argument can start with "s" \, "f" \, or "p" to specify a "symbol" \, "float" (number) \, or pointer outlet.; #X text 538 331 updated for Pd version 0.34; #X connect 0 0 16 0; #X connect 1 0 16 0; #X connect 2 0 16 1; #X connect 3 0 16 3; #X connect 5 0 16 2; #X connect 14 0 16 0; #X connect 16 0 4 0; pd-0.46-7/doc/5.reference/openpanel-help.pd0000664000175000017500000000117512160204055016475 0ustar mspmsp#N canvas 70 117 585 333 12; #X obj 128 196 openpanel; #X msg 128 108 bang; #X obj 128 221 print; #X text 31 11 openpanel -- query you for a filename; #X text 48 278 see also:; #X obj 136 279 savepanel; #X text 28 44 When Openpanel gets a "bang" an "Open file" browser appears on the screen. If you select a file \, its name appears on the outlet. ; #X text 285 289 updated for Pd version 0.40.; #X text 178 109 Starts open panel in current directory; #X msg 144 136 symbol /tmp; #X msg 146 161 symbol C:/; #X text 252 137 Starts in a specified directory; #X connect 0 0 2 0; #X connect 1 0 0 0; #X connect 9 0 0 0; #X connect 10 0 0 0; pd-0.46-7/doc/5.reference/send~-help.pd0000664000175000017500000000232312160204055015637 0ustar mspmsp#N canvas 31 28 678 406 12; #X floatatom 344 238 0 0 0; #X obj 344 189 receive~ signal1; #X obj 17 215 send~ signal1; #X obj 17 192 sig~ 50; #X obj 344 213 snapshot~; #X obj 42 22 send~; #X obj 94 23 receive~; #X text 178 23 - one-to-many nonlocal signal connections; #X obj 507 133 loadbang; #X obj 507 194 metro 200; #X msg 517 155 \; pd dsp 1; #X floatatom 18 168 4 0 0; #X text 48 51 A send~ object copies its input to a local buffer which all receive~ objects of the same name read from. They may be in different windows or even different patches. Any number of receives may be associated with one send~ but it is an error to have two send~s of the same name.; #X obj 179 344 tabreceive~; #X text 405 368 updated for Pd version 0.33.; #X obj 148 187 sig~ 25; #X obj 148 215 send~ signal2; #X msg 355 139 set signal2; #X msg 356 161 set signal1; #X text 34 287 Send~/Receive~ only work for the default block size (64) \; for FFT applications see also:; #X text 35 262 Receive~ takes "set" messages to switch between send~s.; #X connect 1 0 4 0; #X connect 3 0 2 0; #X connect 4 0 0 0; #X connect 8 0 9 0; #X connect 8 0 10 0; #X connect 9 0 4 0; #X connect 11 0 3 0; #X connect 15 0 16 0; #X connect 17 0 1 0; #X connect 18 0 1 0; pd-0.46-7/doc/5.reference/adc~_dac~-help.pd0000664000175000017500000000132212574135745016462 0ustar mspmsp#N canvas 195 155 575 293 12; #X obj 8 11 adc~; #X obj 72 11 dac~; #X obj 63 121 adc~ 5; #X text 143 121 (input from channel 5 only); #X obj 61 145 dac~ 1 2 5 23; #X text 184 145 (output to channels 1 \, 2 \, 5 \, and 23); #X text 16 173 The actual number of channels Pd inputs and outputs are set on Pd's command line. You can open patches that want to use more channels \, and channel numbers out of rance will be dropped (dac~) or appear as zero (adc~).; #X text 308 254 updated for Pd version 0.33; #X text 122 9 - audio I/O; #X text 8 46 Adc~ and dac~ provide real-time audio input and output for Pd \, respectively \, whether analog or digital. By default they are stereo but you can specify channel numbers as in:; pd-0.46-7/doc/5.reference/gatom-help.pd0000664000175000017500000000257312160204055015626 0ustar mspmsp#N canvas 138 65 675 508 12; #X floatatom 107 9 0 0 0; #X text 155 10 atoms (number boxes); #X floatatom 38 85 0 0 0; #X floatatom 38 125 0 0 0; #X msg 51 260 set 45; #X floatatom 51 288 0 0 0; #X floatatom 51 317 0 0 0; #X text 84 40 Number boxes allow you to display numbers or to enter numbers using the mouse and keyboard. When a number arrives at the number box's inlet \, it is displayed and sent to the outlet. You can click on a number box and drag upward or downward to change the value continuously.; #X text 88 130 You can shift-click and drag to change the number by hundredths instead of units. Alt clicking toggles the value between 0 and the last nonzero value.; #X text 83 184 You can also type in values by clicking and typing a number followed by "enter."; #X text 30 220 the "set" message sets the number box's value but does not send it to the outlet.; #X text 423 482 updated for Pd version 0.34; #X text 39 339 You can set the width of the box by right-clicking and choosing "properties." By default the width is 5 characters. If you select a width of 0 \, the number box will grow as needed to hold the number--BUT BEWARE \, THIS IS EXPENSIVE IN CPU TIME. In a production patch \, you'll want to set a specific width.; #X floatatom 547 439 1 0 0; #X text 41 438 A width of one gives a clickable toggle switch ala Max: ; #X connect 2 0 3 0; #X connect 4 0 5 0; #X connect 5 0 6 0; pd-0.46-7/doc/5.reference/0_all_guis-INTRO.txt0000664000175000017500000001510212160204055016704 0ustar mspmspHOW TO MOVE A GUI-OBJECT: Of course by mouse, and: select a gui-object , then navigate the object by using the 4 direction-keys: UP , DOWN , LEFT or RIGHT. If you press the SHIFT-Key too , the object will move 10 times faster. PROPERTIES-DIALOG-WINDOW: "dimensions(pix): size:" = square-size of the gui-objects in pixels. "dimensions(pix)(pix): width: height:" = width & height of the rectangular gui-object in pixels. "selectable dimensions(pix): size:" = square-size of the selectable top-left corner of my_canvas in pixels. "flash-time(ms)(ms): hold:" = flash-hold-time in msec = duration of activity, if a bang-object was activated by any message-event or by a mouse-click. "flash-time(ms)(ms): intrrpt:" = flash-interrupt-time in msec = duration of inactivity , if an already activated bang is activated once more. "output-range: left: right:" = hslider-bounds for input- as well as output-values. "output-range: bottom: top:" = vslider-bounds for input- as well as output-values. "non-zero-value: value:" = toggle has 2 value-states: zero and this value. "visible_rectangle(pix)(pix): width: height:" = width & height of a visible, deactivated rectangle in pixels. "init" or "no init" = if "init"-mode is selected , the object gets a loadbang- behavior and puts out its in-patch-saved value. if "no init"-mode is selected, nothing will happen. "new&old" or "new-only" = the hdial- and vdial-object changes its state in 2 ways: "new&old"-mode: output sends previous state off, current state on; "new-only"-mode: output sends only current state on. "lin" or "log" = sliders and numberboxes can have linear or logarithmical scaling. "number:" = number of buttons of hdials and vdials. "log-height:" = is the graphical height of the numberbox in logarithmical mode. "steady on click" or "jump on click" = the 2 slider-objects react to mouse-click in 2 ways: "steady on click"-mode: slider-knob stays in position, mouse and knob will move parallel; "jump on click"-mode: slider-knob jumps immediately to new mouse-position, positions of mouse and knob will be identical. "send-symbol:" = an output-message can be received by a receive-object with the same send-symbol-name. "receive-symbol:" = a send-object with the same symbol-name can send an input-message to the gui-object. "label: name:" = visible name of a gui-object; it will be moved together with the gui-object. "label: x_off: y_off:" = coordinates of the label in relation to top-left corner of gui-object. "label: font: fontsize:" = font-properties of label. "colors:" = a click on radiobuttons "backgd:", "front:" or "label:" routes the button "compose color" and/or the preset-colors to background- front- and label-color. the 2 fields with "testlabel" and "o=||=o" will show you the 3 colors. "compose color" opens a tcl/tk color-dialog. "Cancel" quits the properties-dialog without sending down the last changings in dialogbox. "Apply" sends down the changings. "OK" sends down the changings and quits the dialogbox. THE DOLLAR-THING: If you want to send to, or to receive from gui-objects, you have to write into the property-entry your send- or receive-name. If you want an unique-name, write $0 or $0-blabla, if you want to communicate with this gui-object in an abstraction, write $1 or $1-blabla or $2 or $2-blabla in your property-entry. (send- , receive- or label- name) A new feature is: you can take the same send- and receive-name. If there is a send-name, the object will loose its output-rectangle, if there is a receive-name, the object will loose its input-rectangle; but the connective behavior is the same. GUI-MESSAGES: all gui-objects (bng, hsl, vsl, nbx, tgl, hdl, vdl, cnv and vu) understand input-messages which change their properties. except cnv has no input, so you have to send messages to its receive-label (edit properties). "size 15 128" = change width & height of sliders and vu in pixels. "size 15" = change square-size of rdb, bng and tgl in pixels. "vis_size 800 600" = change width & height of visual rectangle of my_canvas in pixels. "range 0.1 10.0" = change slider-boundaries for input- as well as output-values. "nonzero 127.0" = change the nonzero-value of toggle. "flashtime 50 600" = change flash-interrupt- and flash-hold-time of bng-object. "pos 150 170" = change the x-y-position of the top-left corner of a gui-object in pixels; "pos 0 0" is the top-left corner of your window; the positive directions of x- and y-axes are right and down. "delta 15 17" = move the gui-object in relation to its current position (in pixels). "color 0 22 22" = change background-, front- and label-color of object with one of 30 presets. "color 0 22" = change background- and label-color of vu and my_canvas with one of 30 presets. "color -16777216 (-1) -1" = change background-, (front-) and label-color of object with RGB-values. the RGB-value will be calculated: -65536*RED-value (0 .. 255) - 256*GREEN-value (0 .. 255) - BLUE-value (0 .. 255) - 1. "number 10" = change number of dial-buttons. "log_height 128" = graphical dimension for logarithmical behavior of numberbox. "steady 1" change slider-knob-behaviour on mouse-click. "single_change" change dial-behaviour to output only the new state. "double_change" change dial-behaviour to first release the previous button, then output the state of the new button. "send fromgui" = change send-name of gui-objects, except vu and cnv. "receive togui" = change receive-name of object. "label its_me" = change label-text of object. "label_pos 20 8" = change offset-coordinates of label-text. "label_font 0 10" = change font and fontsize of label-text. "init 1" = change initial loadbang-mode of gui-objects except vu and cnv. "set 64" = change only the inner state and display of gui-objects, except bng and cnv; no output will result. "lin" = change scale-mode of slider to linear. "log" = change scale-mode of slider to logarithmical. "get_pos" = if my_canvas has a receive-name and a send-name and you send the message "get_pos" to it, you receive the current x- and y-coordinates. pd-0.46-7/doc/5.reference/select-help.pd0000664000175000017500000000426512160204055015776 0ustar mspmsp#N canvas 47 29 618 662 12; #X floatatom 22 332 0 0 0; #X msg 156 120 6; #X msg 119 120 234; #X floatatom 119 150 0 0 0; #X msg 121 301 1; #X msg 89 301 54; #X obj 22 392 print x1; #X obj 100 391 print x2; #X msg 58 301 23; #X msg 22 302 234; #X msg 65 120 6; #X obj 28 180 select 6; #X msg 28 120 234; #X obj 28 210 print x1; #X obj 107 211 print x2; #X obj 177 391 print x3; #X obj 255 392 print x4; #X floatatom 28 150 0 0 0; #X obj 22 362 select 23 54 1; #X text 45 609 abbreviation:; #X obj 169 610 sel; #X text 20 37 In its simplest form shown below \, Select checks its input agains the constant "6". If they match \, the first outlet gives "bang" and otherwise the input is copied to the second outlet. If Select is used with a single argument \, a second inlet allows you to change the test value.; #X text 22 239 You can give several arguments. You get an outlet for each test value and finally an outlet for values which match none of them. In this case you don't get inlets to change the test values:; #X obj 32 566 print x1; #X obj 114 567 print x2; #X msg 34 451 symbol cort; #X msg 46 476 symbol zack; #X msg 178 476 symbol cort; #X msg 184 501 symbol zack; #X obj 34 539 select cort; #X msg 308 462 symbol cort; #X msg 415 462 symbol zack; #X obj 308 551 print x1; #X obj 385 551 print x2; #X obj 308 521 select cort zack; #X obj 462 551 print x3; #X msg 413 487 symbol bill; #X text 24 426 Select can also be used to sort symbols:; #X text 83 637 see also:; #X obj 175 639 route; #X obj 32 10 select; #X text 92 10 - compare numbers or symbols; #X text 370 629 updated for Pd version 0.33; #X connect 0 0 18 0; #X connect 1 0 3 0; #X connect 2 0 3 0; #X connect 3 0 11 1; #X connect 4 0 0 0; #X connect 5 0 0 0; #X connect 8 0 0 0; #X connect 9 0 0 0; #X connect 10 0 17 0; #X connect 11 0 13 0; #X connect 11 1 14 0; #X connect 12 0 17 0; #X connect 17 0 11 0; #X connect 18 0 6 0; #X connect 18 1 7 0; #X connect 18 2 15 0; #X connect 18 3 16 0; #X connect 25 0 29 0; #X connect 26 0 29 0; #X connect 27 0 29 1; #X connect 28 0 29 1; #X connect 29 0 23 0; #X connect 29 1 24 0; #X connect 30 0 34 0; #X connect 31 0 34 0; #X connect 34 0 32 0; #X connect 34 1 33 0; #X connect 34 2 35 0; #X connect 36 0 34 0; pd-0.46-7/doc/5.reference/line-help.pd0000664000175000017500000000324212160204055015440 0ustar mspmsp#N canvas 372 214 597 464 12; #X floatatom 22 416 8 0 0 0 - - -; #X msg 32 219 0 1000; #X msg 47 241 39; #X obj 66 15 line; #X text 106 14 - ramp generator; #X msg 23 196 1 1000; #X text 22 38 The line object takes (target \, time) pairs and slews to the specified target over the time given \, updating its output at a "grain rate" given by the creation argument. If you don't specify a time \, line jumps immediately to the target. Note that the inlet does not remember old values (unlike every other inlet in Pd) -- sending a float causes a jump in the output regardless of whatever time value was specified in some previous message. If the line object receives a message specifying some new target before reaching the previous one \, it takes off from its current value.; #X text 94 208 send a pair to ramp to a new value; #X text 97 243 send a single number to jump; #X text 106 443 see also:; #X obj 176 440 line~; #X msg 58 266 stop; #X text 103 268 "stop" message to stop output; #X obj 22 390 line 0 100; #X text 122 396 creation arguments:; #X text 271 388 1 initial value; #X msg 52 296 set 5; #X text 105 296 "set" to change value (and stop) without output; #X text 394 441 updated for Pd version 0.43; #X obj 222 440 vline~; #X floatatom 91 352 0 0 0 0 - - -; #X floatatom 91 328 0 0 0 0 - - -; #X text 126 328 first inlet sets next ramp time (cleared when ramp starts!); #X text 125 354 second inlet sets grain (not cleared \, acts as normal inlet); #X text 270 404 2 time grain in milliseconds (20 by default); #X connect 1 0 13 0; #X connect 2 0 13 0; #X connect 5 0 13 0; #X connect 11 0 13 0; #X connect 13 0 0 0; #X connect 16 0 13 0; #X connect 20 0 13 2; #X connect 21 0 13 1; pd-0.46-7/doc/5.reference/trigger-help.pd0000664000175000017500000000217612160204055016161 0ustar mspmsp#N canvas 58 142 685 355 12; #X msg 28 149 2.5; #X msg 126 151 bang; #X msg 68 150 23 64; #X obj 28 242 print x1; #X obj 112 242 print x2; #X obj 196 240 print x3; #X obj 43 26 trigger; #X obj 286 241 print x4; #X text 114 27 - sequence messages in right-to-left order; #X text 417 331 updated for Pd version 0.33; #X text 81 290 the above can be abbreviated as:; #X msg 172 152 symbol dog; #X text 39 59 The trigger object outputs its input from right to left \, converting to the types indicated by its creation arguments. There is also a "pointer" argument type (see the pointer object.); #X obj 381 293 t f b s l a; #X msg 466 167 dog my cats; #X obj 466 199 trigger bang anything; #X obj 374 242 print x5; #X obj 466 240 print y1; #X obj 552 242 print y2; #X obj 28 202 trigger float bang symbol list anything; #X text 464 122 "anythings" can only; #X text 461 142 be converted to bang:; #X connect 0 0 19 0; #X connect 1 0 19 0; #X connect 2 0 19 0; #X connect 11 0 19 0; #X connect 14 0 15 0; #X connect 15 0 17 0; #X connect 15 1 18 0; #X connect 19 0 3 0; #X connect 19 1 4 0; #X connect 19 2 5 0; #X connect 19 3 7 0; #X connect 19 4 16 0; pd-0.46-7/doc/5.reference/pd-help.pd0000664000175000017500000001203112222367057015123 0ustar mspmsp#N canvas 241 181 652 514 12; #N canvas 0 0 600 400 (subpatch) 0; #X restore 23 13 pd; #X text 57 14 - subpatch; #X obj 180 13 inlet; #X text 238 12 - control inlet; #X obj 410 12 inlet~; #X text 480 12 - audio inlet; #X obj 180 41 outlet; #X text 238 43 - control outlet; #X obj 410 40 outlet~; #X text 480 40 - audio outlet; #X text 15 77 Type "pd" into an object box to make a subpatch. When in run mode you can click on the object to open the subpatch. You can name the subpatch with an argument:; #N canvas 156 300 518 221 my-subpatch 0; #X text 49 96 this is a subpatch for the "pd" help window.; #X restore 111 134 pd my-subpatch; #X text 19 161 and you can put inlets and outlets by making "inlet" objects \, etc \, in the subpatch (open the patch below to see them.) ; #X obj 361 329 print~; #X obj 359 249 sig~ 12; #X floatatom 50 253 0 0 0 0 - - -; #X floatatom 50 305 0 0 0 0 - - -; #X text 388 306 (check that audio is on); #X text 20 232 messages in and out; #X text 329 226 audio in and out; #X text 10 444 see also:; #X obj 94 444 block~; #X obj 371 307 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #N canvas 868 141 634 613 up/downsampling 0; #X obj 29 395 print~; #X obj 47 369 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 152 397 print~; #X obj 170 371 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 276 395 print~; #X obj 294 369 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #N canvas 0 0 450 300 (subpatch) 0; #X array \$0-tab 64 float 3; #A 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0; #X coords 0 1 64 -1 200 140 1; #X restore 285 180 graph; #X obj 354 360 s \$0-tab; #X msg 353 333 const 0 \, 0 0 1; #X obj 176 243 print~; #X obj 176 218 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 24 191 tabreceive~ \$0-tab; #N canvas 162 294 571 346 test-subpatch-upsampled 0; #X obj 40 17 block~ 128 1 2; #X obj 43 144 inlet~ hold; #X obj 318 149 inlet~ lin; #X obj 183 200 print~; #X obj 201 174 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 43 204 print~; #X obj 61 178 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 317 209 print~; #X obj 334 183 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X text 42 49 Upsampling methods:; #X text 41 109 sample/hold; #X text 300 114 linear interpolation; #X obj 183 144 inlet~ pad; #X text 183 113 zero-padded; #X text 43 245 The default \, if no method is specified \, is sample/hold. ; #X connect 1 0 5 0; #X connect 2 0 7 0; #X connect 4 0 3 0; #X connect 6 0 5 0; #X connect 8 0 7 0; #X connect 12 0 3 0; #X restore 24 295 pd test-subpatch-upsampled; #N canvas 45 42 585 267 test-subpatch-downsampled 0; #X obj 367 153 outlet~ lin; #X text 206 173 sample/hold; #X text 364 177 linear interpolation; #X text 197 19 upsampling methods:; #X obj 40 17 block~ 32 1 0.5; #X text 18 169 interleaved zeros; #X obj 21 83 tabreceive~ \$0-tab; #X obj 23 146 outlet~ pad; #X obj 209 149 outlet~ hold; #X connect 6 0 0 0; #X connect 6 0 7 0; #X connect 6 0 8 0; #X restore 28 339 pd test-subpatch-downsampled; #X text 50 11 When a subpatch is reblocked to a higher or lower sample rate \, the inlet~ and outlet~ objects offer a choice of three upsampling methods. (The inlet~ upsamples when entering a subpatch with a higher sample rate \; the outlet~ upsamples when leaving a subpatch of _lower_ sample rate \, as demonstrated below.) There is no corresponding choice of downsampling method - downsampling is done simply by dropping the extra samples.; #X msg 127 541 \; pd compatibility 0.43; #X text 27 469 COMPATIBILITY NOTE: in Pd versions before 0.44 \, the default method was "pad". To get the old behavior \, either change the patch to specify "pad" \, or set "compatibility" to 0.43 in Pd's command line or by a message:; #X connect 1 0 0 0; #X connect 3 0 2 0; #X connect 5 0 4 0; #X connect 8 0 7 0; #X connect 10 0 9 0; #X connect 11 0 12 0; #X connect 11 0 12 2; #X connect 11 0 9 0; #X connect 11 0 12 1; #X connect 13 0 0 0; #X connect 13 1 2 0; #X connect 13 2 4 0; #X restore 20 370 pd up/downsampling; #N canvas 103 180 600 392 subpatch-with-inlets-and-outlets 0; #X obj 64 83 inlet; #X text 16 53 control inlet for receiving messages; #X floatatom 64 111 0 0 0 0 - - -; #X floatatom 67 212 0 0 0 0 - - -; #X obj 67 244 outlet; #X text 31 182 control outlet for sending message; #X obj 399 78 inlet~; #X obj 399 129 print~; #X msg 414 103 bang; #X obj 398 271 outlet~; #X obj 398 245 sig~ 34; #X text 392 32 same for; #X text 393 51 signals.; #X connect 0 0 2 0; #X connect 3 0 4 0; #X connect 6 0 7 0; #X connect 8 0 7 0; #X connect 10 0 9 0; #X restore 50 279 pd subpatch-with-inlets-and-outlets; #X text 193 368 <- here are some ugly details on; #X text 219 386 up/downsampling for inlet~ and outlet~; #X text 390 435 updated for Pd version 0.44; #X text 183 470 (documents new default upsampling behavior for reblocked inlet~ and outlet~.); #X connect 14 0 24 1; #X connect 15 0 24 0; #X connect 22 0 13 0; #X connect 24 0 16 0; #X connect 24 1 13 0; pd-0.46-7/doc/5.reference/vu-help.pd0000664000175000017500000001406512160204055015150 0ustar mspmsp#N canvas 171 210 549 418 10; #X obj 1 1 cnv 8 100 60 empty empty vu 20 20 1 18 -262144 -1109 0; #X text 19 363 (c) musil@iem.kug.ac.at; #X text 61 376 IEM KUG; #X floatatom 177 129 7 -110 20; #X text 202 41 click properties to; #X text 190 52 modify geometry \, colors \, etc.; #X text 49 13 gui-vu-meter-display:; #X obj 99 39 tgl 15 1 empty empty empty 8 -8 0 10 -262144 -1 -1 1 1 ; #X obj 12 179 vu 16 120 foo7_rcv vu-meter 60 0 64 10 -1 -355 1 0; #X floatatom 11 332 6 0 0; #X floatatom 22 310 6 0 0; #X text 75 309 dB; #X text 63 333 dB; #X text 71 128 dB; #X text 80 148 dB; #X text 103 146 peak-level; #X text 101 125 rms-level; #X text 96 308 peak-level; #X text 83 332 rms-level; #X text 108 99 of rms \, peak; #X obj 177 231 s foo7_rcv; #X obj 177 211 pack 0 0; #X floatatom 195 150 7 -110 20; #X obj 195 191 t b f; #X text 236 129 dB; #X text 255 151 dB; #X text 71 258 UP- \, DOWN- \, LEFT- or RIGHT-key; #X text 70 269 for moving selected gui-objects; #X floatatom 11 128 7 -110 20; #X floatatom 22 149 7 -110 20; #N canvas 236 62 699 530 edit 0; #X obj 37 222 f; #X msg 15 201 bang; #X floatatom 53 200 3 50 88; #X floatatom 88 222 3 0 37; #X obj 37 245 pack 0 0; #X text 115 222 y-label; #X text 81 200 x-label; #X obj 292 313 f; #X msg 270 292 bang; #X floatatom 308 291 3 -10 10; #X floatatom 343 313 3 -10 10; #X obj 292 336 pack 0 0; #X obj 304 435 f; #X msg 282 414 bang; #X floatatom 320 413 3 20 140; #X floatatom 355 435 3 150 200; #X obj 304 458 pack 0 0; #X text 336 291 x-delta; #X text 370 313 y-delta; #X text 348 413 x-position; #X text 382 435 y-position; #X obj 57 337 f; #X msg 35 316 bang; #X floatatom 73 315 3 0 2; #X floatatom 108 337 3 8 36; #X obj 57 360 pack 0 0; #X text 101 315 font; #X text 137 337 height; #X floatatom 471 106 1 0 1; #X msg 52 131 \; foo7_rcv color \$1 \$2; #X msg 37 270 \; foo7_rcv label_pos \$1 \$2; #X msg 57 386 \; foo7_rcv label_font \$1 \$2; #X msg 37 427 \; foo7_rcv label blabla; #X msg 292 361 \; foo7_rcv delta \$1 \$2; #X msg 304 483 \; foo7_rcv pos \$1 \$2; #X msg 469 23 \; foo7_rcv receive foo7a_rcv; #X msg 469 60 \; foo7a_rcv receive foo7_rcv; #X text 492 106 display scale; #X msg 471 132 \; foo7_rcv scale \$1; #X obj 279 193 f; #X msg 257 172 bang; #X floatatom 295 171 3 8 50; #X floatatom 330 193 3 110 200; #X obj 279 216 pack 0 0; #X text 323 171 width; #X text 357 193 height; #X msg 279 241 \; foo7_rcv size \$1 \$2; #X msg 37 463 \; foo7_rcv label vu-meter; #X obj 52 79 f; #X msg 29 31 bang; #X floatatom 68 29 3 0 29; #X floatatom 103 47 3 0 29; #X text 96 29 background; #X text 131 48 label-color; #X msg 290 25 back; #X msg 290 49 label; #X msg 252 25 bang; #N canvas 15 207 606 448 RGB_____________ 0; #X obj 97 56 inlet; #X obj 262 53 inlet; #X obj 339 55 inlet; #X obj 405 56 inlet; #X obj 97 270 bang; #X msg 77 295 0; #X msg 104 295 1; #X obj 146 268 bang; #X msg 132 295 0; #X msg 160 295 1; #X obj 265 313 spigot; #X obj 312 313 spigot; #X obj 249 385 outlet; #X text 93 33 select; #X text 267 28 red; #X text 337 30 green; #X text 409 30 blue; #X obj 405 102 t b f; #X obj 339 160 +; #X obj 339 185 t b f; #X obj 339 216 +; #X obj 296 385 outlet; #X obj 28 180 loadbang; #X obj 296 361 f; #X obj 249 361 f; #X obj 262 79 * -65536; #X obj 339 80 * -256; #X obj 405 80 * -1; #X obj 339 247 - 1; #X obj 97 135 route back label bang; #X obj 235 168 t b b b; #X connect 0 0 29 0; #X connect 1 0 25 0; #X connect 2 0 26 0; #X connect 3 0 27 0; #X connect 4 0 5 0; #X connect 4 0 6 0; #X connect 5 0 11 1; #X connect 6 0 10 1; #X connect 7 0 8 0; #X connect 7 0 9 0; #X connect 8 0 10 1; #X connect 9 0 11 1; #X connect 10 0 24 1; #X connect 11 0 23 1; #X connect 17 0 18 0; #X connect 17 1 18 1; #X connect 18 0 19 0; #X connect 19 0 20 0; #X connect 19 1 20 1; #X connect 20 0 28 0; #X connect 22 0 6 0; #X connect 23 0 21 0; #X connect 24 0 12 0; #X connect 25 0 20 0; #X connect 26 0 18 0; #X connect 27 0 17 0; #X connect 28 0 11 0; #X connect 28 0 10 0; #X connect 29 0 4 0; #X connect 29 1 7 0; #X connect 29 2 30 0; #X connect 30 0 24 0; #X connect 30 1 23 0; #X connect 30 2 28 0; #X restore 290 86 pd RGB_____________; #X floatatom 332 55 3 0 255; #X floatatom 375 55 3 0 255; #X floatatom 418 56 3 0 255; #X text 39 3 preset-colors; #X text 301 0 RGB-colors; #X text 332 37 red; #X text 368 36 green; #X text 416 36 blue; #X obj 52 104 pack 0 0; #X connect 0 0 4 0; #X connect 1 0 0 0; #X connect 2 0 0 1; #X connect 3 0 4 1; #X connect 4 0 30 0; #X connect 7 0 11 0; #X connect 8 0 7 0; #X connect 9 0 7 1; #X connect 10 0 11 1; #X connect 11 0 33 0; #X connect 12 0 16 0; #X connect 13 0 12 0; #X connect 14 0 12 1; #X connect 15 0 16 1; #X connect 16 0 34 0; #X connect 21 0 25 0; #X connect 22 0 21 0; #X connect 23 0 21 1; #X connect 24 0 25 1; #X connect 25 0 31 0; #X connect 28 0 38 0; #X connect 39 0 43 0; #X connect 40 0 39 0; #X connect 41 0 39 1; #X connect 42 0 43 1; #X connect 43 0 46 0; #X connect 48 0 66 0; #X connect 49 0 48 0; #X connect 50 0 48 1; #X connect 51 0 66 1; #X connect 54 0 57 0; #X connect 55 0 57 0; #X connect 56 0 57 0; #X connect 57 0 66 0; #X connect 57 1 66 1; #X connect 58 0 57 1; #X connect 59 0 57 2; #X connect 60 0 57 3; #X connect 66 0 29 0; #X restore 313 188 pd edit; #N canvas 147 336 290 278 source 0; #X obj 40 95 random 102; #X obj 40 171 - 101; #X obj 40 205 pack 0 0; #X obj 40 45 metro 300; #X obj 40 69 t b b; #X obj 133 95 random 20; #X obj 40 117 t f f; #X obj 91 147 +; #X obj 91 172 - 101; #X obj 40 21 inlet; #X obj 40 230 outlet; #X connect 0 0 6 0; #X connect 1 0 2 0; #X connect 2 0 10 0; #X connect 3 0 4 0; #X connect 4 0 0 0; #X connect 4 1 5 0; #X connect 5 0 7 1; #X connect 6 0 1 0; #X connect 6 1 7 0; #X connect 7 0 8 0; #X connect 8 0 2 1; #X connect 9 0 3 0; #X restore 99 62 pd source; #X obj 263 94 s fff; #X obj 186 302 x_all_guis aaa bbb ccc ddd eee fff ggg hhh iii; #X text 210 386 updated for Pd version 0.35; #X text 36 388 graz \, austria 2002; #X connect 3 0 21 0; #X connect 7 0 31 0; #X connect 8 0 9 0; #X connect 8 1 10 0; #X connect 21 0 20 0; #X connect 22 0 23 0; #X connect 23 0 21 0; #X connect 23 1 21 1; #X connect 28 0 8 0; #X connect 29 0 8 1; #X connect 31 0 8 0; #X connect 31 0 32 0; pd-0.46-7/doc/5.reference/key-help.pd0000664000175000017500000000154612160204055015306 0ustar mspmsp#N canvas 146 45 546 288 12; #X obj 21 10 key; #X obj 54 9 keyup; #X obj 105 9 keyname; #X text 173 8 -- grab keyboard; #X obj 38 67 key; #X floatatom 38 95 3 0 0 0 - - -; #X floatatom 77 93 3 0 0 0 - - -; #X obj 77 67 keyup; #X floatatom 128 93 3 0 0 0 - - -; #X obj 128 67 keyname; #X symbolatom 172 94 10 0 0 0 - - -; #X text 280 262 updated for Pd version 0.32.; #X text 26 133 Key and keyup report the (system dependent) numbers of "printing" keys of the keyboard. Keyname gives the symbolic name of the key \, with a 1 or 0 if it's up or down \, and works with non-printing keys like shift or "F1".; #X text 18 200 Caveat -- this only works if Pd actually gets the key events which can depend on the stacking order of windows and/or the pointer location \, depending on the system.; #X connect 4 0 5 0; #X connect 7 0 6 0; #X connect 9 0 8 0; #X connect 9 1 10 0; pd-0.46-7/doc/5.reference/vradio-help.pd0000664000175000017500000001743712374250720016017 0ustar mspmsp#N canvas 65 57 380 567 10; #X obj 1 1 cnv 8 100 60 empty empty vradio 20 20 1 18 -262144 -1109 0; #X text 109 130 click properties to; #X text 97 141 modify geometry \, colors \, etc.; #X obj 60 254 bng 15 250 50 0 empty empty empty 8 -8 0 10 -262144 -1 -1; #X obj 21 54 bng 15 250 50 0 empty empty empty 8 -8 0 10 -262144 -1 -1; #X obj 59 206 s foo11_rcv; #X obj 60 232 r foo11_snd; #X floatatom 21 398 4 0 0 0 - - -, f 4; #X obj 21 420 bng 15 250 50 0 empty empty empty 8 -8 0 10 -262144 -1 -1; #X msg 157 73 set \$1; #X floatatom 157 52 4 0 9 0 - - -, f 4; #X floatatom 44 54 4 0 9 0 - - -, f 4; #X msg 84 50 7 0 -5.44; #X msg 88 72 3 3 4.55; #X obj 62 388 print; #X floatatom 84 280 4 0 0 0 - - -, f 4; #X msg 84 254 \$1; #X msg 59 185 set \$1; #X floatatom 59 164 4 0 9 0 - - -, f 4; #X text 59 318 UP- \, DOWN- \, LEFT- or RIGHT-key; #X text 58 329 for moving selected gui-objects; #N canvas 221 206 699 530 edit 0; #X obj 42 198 f; #X msg 20 177 bang; #X floatatom 58 176 3 63 156 0 - - -, f 3; #X floatatom 93 198 3 -20 37 0 - - -, f 3; #X obj 42 221 pack 0 0; #X text 120 198 y-label; #X text 86 176 x-label; #X floatatom 270 187 3 8 50 0 - - -, f 3; #X text 297 187 size; #X obj 286 293 f; #X msg 264 272 bang; #X floatatom 302 271 3 -10 10 0 - - -, f 3; #X floatatom 337 293 3 -10 10 0 - - -, f 3; #X obj 286 316 pack 0 0; #X obj 300 412 f; #X msg 278 391 bang; #X floatatom 316 390 3 20 60 0 - - -, f 3; #X floatatom 351 412 3 100 200 0 - - -, f 3; #X obj 300 435 pack 0 0; #X text 330 271 x-delta; #X text 364 293 y-delta; #X text 344 390 x-position; #X text 378 412 y-position; #X obj 62 313 f; #X msg 40 292 bang; #X floatatom 78 291 3 0 2 0 - - -, f 3; #X floatatom 113 313 3 4 36 0 - - -, f 3; #X obj 62 336 pack 0 0; #X text 106 291 font; #X text 142 313 height; #X text 504 293 no init; #X text 475 348 init value on loadbang; #X floatatom 482 228 5 2 20 0 - - -, f 5; #X msg 47 125 \; foo11_rcv color \$1 \$2 \$3; #X msg 42 246 \; foo11_rcv label_pos \$1 \$2; #X msg 62 361 \; foo11_rcv label_font \$1 \$2; #X msg 34 423 \; foo11_rcv label blabla; #X msg 300 460 \; foo11_rcv pos \$1 \$2; #X msg 286 341 \; foo11_rcv delta \$1 \$2; #X msg 270 216 \; foo11_rcv size \$1; #X msg 482 171 \; foo11a_rcv receive foo11_rcv; #X msg 483 133 \; foo11_rcv receive foo11a_rcv; #X msg 483 88 \; foo11_rcv send foo11_snd; #X msg 483 50 \; foo11_rcv send foo11a_snd; #X msg 483 312 \; foo11_rcv init 0; #X msg 485 366 \; foo11_rcv init 1; #X msg 490 436 \; foo11_rcv single_change; #X msg 490 470 \; foo11_rcv double_change; #X text 491 417 changing-behavior; #X msg 482 254 \; foo11_rcv number \$1; #X text 526 228 number of buttons; #X msg 34 459 \; foo11_rcv label radio_0_9; #X obj 47 104 pack 0 0 0; #X obj 47 76 f; #X msg 24 28 bang; #X floatatom 63 26 3 0 29 0 - - -, f 3; #X floatatom 79 46 3 0 29 0 - - -, f 3; #X floatatom 112 62 3 0 29 0 - - -, f 3; #X text 91 26 background; #X text 106 46 front-color; #X text 140 63 label-color; #X msg 285 25 back; #X msg 285 45 front; #X msg 285 65 label; #X msg 247 25 bang; #N canvas 15 207 606 448 RGB_____________ 0; #X obj 97 56 inlet; #X obj 262 53 inlet; #X obj 339 55 inlet; #X obj 405 56 inlet; #X obj 97 270 bang; #X msg 77 295 0; #X msg 104 295 1; #X obj 146 268 bang; #X msg 132 295 0; #X msg 160 295 1; #X obj 196 269 bang; #X msg 187 295 0; #X msg 214 295 1; #X obj 265 313 spigot; #X obj 312 313 spigot; #X obj 359 313 spigot; #X obj 249 385 outlet; #X text 93 33 select; #X text 267 28 red; #X text 337 30 green; #X text 409 30 blue; #X obj 405 102 t b f; #X obj 339 160 +; #X obj 339 185 t b f; #X obj 339 216 +; #X obj 296 385 outlet; #X obj 343 385 outlet; #X obj 28 180 loadbang; #X obj 97 135 route back front label bang; #X obj 343 362 f; #X obj 296 361 f; #X obj 249 361 f; #X obj 262 79 * -65536; #X obj 339 80 * -256; #X obj 405 80 * -1; #X obj 339 247 - 1; #X obj 235 168 t b b b b; #X connect 0 0 28 0; #X connect 1 0 32 0; #X connect 2 0 33 0; #X connect 3 0 34 0; #X connect 4 0 5 0; #X connect 4 0 6 0; #X connect 5 0 14 1; #X connect 5 0 15 1; #X connect 6 0 13 1; #X connect 7 0 8 0; #X connect 7 0 9 0; #X connect 8 0 13 1; #X connect 8 0 15 1; #X connect 9 0 14 1; #X connect 10 0 11 0; #X connect 10 0 12 0; #X connect 11 0 13 1; #X connect 11 0 14 1; #X connect 12 0 15 1; #X connect 13 0 31 1; #X connect 14 0 30 1; #X connect 15 0 29 1; #X connect 21 0 22 0; #X connect 21 1 22 1; #X connect 22 0 23 0; #X connect 23 0 24 0; #X connect 23 1 24 1; #X connect 24 0 35 0; #X connect 27 0 6 0; #X connect 28 0 4 0; #X connect 28 1 7 0; #X connect 28 2 10 0; #X connect 28 3 36 0; #X connect 29 0 26 0; #X connect 30 0 25 0; #X connect 31 0 16 0; #X connect 32 0 24 0; #X connect 33 0 22 0; #X connect 34 0 21 0; #X connect 35 0 15 0; #X connect 35 0 14 0; #X connect 35 0 13 0; #X connect 36 0 31 0; #X connect 36 1 30 0; #X connect 36 2 29 0; #X connect 36 3 35 0; #X restore 285 86 pd RGB_____________; #X floatatom 327 55 3 0 255 0 - - -, f 3; #X floatatom 370 55 3 0 255 0 - - -, f 3; #X floatatom 413 56 3 0 255 0 - - -, f 3; #X text 34 0 preset-colors; #X text 296 -3 RGB-colors; #X text 327 37 red; #X text 363 36 green; #X text 411 36 blue; #X connect 0 0 4 0; #X connect 1 0 0 0; #X connect 2 0 0 1; #X connect 3 0 4 1; #X connect 4 0 34 0; #X connect 7 0 39 0; #X connect 9 0 13 0; #X connect 10 0 9 0; #X connect 11 0 9 1; #X connect 12 0 13 1; #X connect 13 0 38 0; #X connect 14 0 18 0; #X connect 15 0 14 0; #X connect 16 0 14 1; #X connect 17 0 18 1; #X connect 18 0 37 0; #X connect 23 0 27 0; #X connect 24 0 23 0; #X connect 25 0 23 1; #X connect 26 0 27 1; #X connect 27 0 35 0; #X connect 32 0 49 0; #X connect 52 0 33 0; #X connect 53 0 52 0; #X connect 54 0 53 0; #X connect 55 0 53 1; #X connect 56 0 52 1; #X connect 57 0 52 2; #X connect 61 0 65 0; #X connect 62 0 65 0; #X connect 63 0 65 0; #X connect 64 0 65 0; #X connect 65 0 52 0; #X connect 65 1 52 1; #X connect 65 2 52 2; #X connect 66 0 65 1; #X connect 67 0 65 2; #X connect 68 0 65 3; #X restore 166 220 pd edit; #X text 144 11 gui-vertical dial:; #X text 133 437 IEM KUG; #X text 117 425 musil; #X text 147 425 @; #X text 153 425 iem.at; #X text 68 414 (c) Thomas Musil 2000 - 2005; #X text 116 447 Graz \, Austria; #X obj 21 106 vradio 25 1 0 10 foo11_snd foo11_rcv radio_0_9 32 12 0 10 -99865 -262144 -260818 8; #X obj 229 46 vradio 8 1 0 8 hhh hhh empty 0 -6 0 8 -262144 -1 -1 0 ; #X obj 241 46 vradio 8 1 0 8 hhh hhh empty 0 -6 0 8 -262144 -1 -1 0 ; #X obj 253 46 vradio 8 1 0 8 hhh hhh empty 0 -6 0 8 -262144 -1 -1 0 ; #X text 46 355 float out; #X text 174 533 updated for Pd version 0.46; #N canvas 108 94 526 340 old-behavior 0; #X floatatom 29 39 5 0 0 0 - - -, f 5; #X floatatom 27 207 5 0 0 0 - - -, f 5; #X msg 18 229 \; pd compatibility 0.45; #X msg 197 230 \; pd compatibility 0.46; #X text 35 267 Old "compatible" behavior, f 16; #X text 204 267 Mew "correct" behavior; #X text 65 70 Prior to Pd version 0.46 \, values sent to IEM controls were restricted to the control's own values before passing them through to the output. This behavior is changed in 0.46. You can toggle back and forth between the two behaviors using the messages boxes below. If you want to get the behavior in an up-to-date patch \, you can use "int" and "clip" objects to quantize and restrict the range o numbers. ; #X msg 75 38 0.5; #X msg 110 38 -12; #X obj 28 65 vradio 15 1 0 8 empty empty empty 0 -8 0 10 -262144 -1 -1 0; #X connect 0 0 9 0; #X connect 7 0 9 0; #X connect 8 0 9 0; #X connect 9 0 1 0; #X restore 234 512 pd old-behavior; #X text 14 469 COMPATIBILIY NOTE: as of Pd 0.46 \, you can pass through numbers ouside the object's range. You can get the old behavior back this way:, f 48; #X connect 4 0 29 0; #X connect 6 0 3 0; #X connect 6 0 16 0; #X connect 7 0 8 0; #X connect 9 0 29 0; #X connect 10 0 9 0; #X connect 11 0 29 0; #X connect 12 0 29 0; #X connect 13 0 29 0; #X connect 16 0 15 0; #X connect 17 0 5 0; #X connect 18 0 17 0; #X connect 29 0 7 0; #X connect 29 0 14 0; pd-0.46-7/doc/5.reference/delread~-help.pd0000664000175000017500000000237312160204055016313 0ustar mspmsp#N canvas 24 20 796 472 12; #X text 351 276 1st argument: name of delay line; #X floatatom 116 253 0 0 0; #X text 151 255 float input (delay time in ms); #X text 127 310 signal output (delayed signal); #X text 21 52 You can use more than one delread~ objects for the same delay line.; #X text 20 81 If the specified delay time is longer than the size of the delay line or less than zero it is clipped to the length of the delay line.; #X obj 383 226 delwrite~ del_example 1000; #X floatatom 383 177 0 0 0; #X obj 116 375 snapshot~; #X floatatom 116 399 0 0 0; #X obj 24 246 loadbang; #X obj 24 313 metro 200; #X msg 32 273 \; pd dsp 1; #X obj 116 286 delread~ del_example 1000; #X obj 24 16 delread~; #X text 424 176 input to delay line; #X obj 383 201 sig~; #X text 433 443 updated for Pd version 0.33; #X text 89 16 - read a signal from a delay line; #X text 21 133 Note: if the delaywrite~ runs after the delread~ the minimum delay is actually one DSP period \, not zero.; #X text 351 292 2nd argument: (initial) delay time in ms; #X obj 126 444 delwrite~; #X obj 217 444 vd~; #X text 36 443 see also:; #X connect 1 0 13 0; #X connect 7 0 16 0; #X connect 8 0 9 0; #X connect 10 0 11 0; #X connect 10 0 12 0; #X connect 11 0 8 0; #X connect 13 0 8 0; #X connect 16 0 6 0; pd-0.46-7/doc/5.reference/pow~-help.pd0000664000175000017500000000201712160204055015513 0ustar mspmsp#N canvas 191 0 534 413 10; #X obj 21 14 pow~; #X obj 67 109 sig~; #X obj 98 173 loadbang; #X obj 98 197 metro 100; #X obj 98 221 snapshot~; #X floatatom 67 73 5 0 0 0 - - -; #X obj 108 109 sig~; #X floatatom 108 73 5 0 0 0 - - -; #X obj 68 138 pow~ 2; #X floatatom 98 246 7 0 0 0 - - -; #X obj 413 268 pow~ 2; #X text 20 271 An optional creation argument initializes right inlet: ; #X text 319 384 updated for Pd version 0.42.; #X text 23 303 WARNING: it's easy to generate "infinity" by accident \, and if you do \, the DSP chain may dramatically slow down if you're using an i386 or ia64 processor. Out-of-range floating point values are thousands of times slower to compute with than in-range ones.; #X text 68 12 - raise a signal to a numeric power (given by another signal). The left inlet must be a positive number. The right inlet my be positive \, zero \, or negative.; #X connect 1 0 8 0; #X connect 2 0 3 0; #X connect 3 0 4 0; #X connect 4 0 9 0; #X connect 5 0 1 0; #X connect 6 0 8 1; #X connect 7 0 6 0; #X connect 8 0 4 0; pd-0.46-7/doc/5.reference/makefilename-help.pd0000664000175000017500000000332212160204055017126 0ustar mspmsp#N canvas 87 80 611 646 12; #X floatatom 37 179 0 0 0 0 - - -; #X obj 37 281 print; #X obj 37 254 makefilename dog%d.aif; #X msg 34 326 symbol meat; #X msg 47 350 symbol hair; #X obj 34 405 print; #X obj 34 378 makefilename dog%s.aif; #X text 26 47 The Makefilename object generates symbols according to a format string \, for use as a series of filenames \, table names \, or whatnot. You can plug in a variable number or symbol by putting "%d" or "%s" in the string. If you put "%s" in the string be sure to send it a symbol and vice versa... there's no checking.; #X obj 49 17 makefilename; #X text 170 18 - format a "name" with a variable field; #X msg 52 205 set cat%d.wav; #X msg 52 229 set %d-zebra; #X text 359 625 updated for Pd version 0.37; #X text 71 179 <- numbers replace "%d" in string; #X text 177 207 <- "set" message replaces format; #X text 243 256 <- creation argument is format; #X text 138 152 SUBSTITUTING A NUMBER; #X text 126 301 SUBSTITUTING A SYMBOL; #X obj 49 619 print; #X obj 48 517 makefilename dog%%d.%s; #X msg 48 541 set \$1; #X obj 48 595 makefilename not-set-yet; #X floatatom 57 566 0 0 0 0 - - -; #X msg 48 465 symbol aif; #X msg 61 489 symbol wav; #X text 44 441 GANG THEM TO DO DOUBLE (OR N-TUPLE) SUBSTITUTION; #X text 258 519 "%s" is replaced by the symbol; #X text 259 502 here \, "%%" becomes "%" and; #X text 114 544 ... so this becomes "set dog%d.aif" \, for example. ; #X text 108 566 ... and then the number fills in "%d".; #X connect 0 0 2 0; #X connect 2 0 1 0; #X connect 3 0 6 0; #X connect 4 0 6 0; #X connect 6 0 5 0; #X connect 10 0 2 0; #X connect 11 0 2 0; #X connect 19 0 20 0; #X connect 20 0 21 0; #X connect 21 0 18 0; #X connect 22 0 21 0; #X connect 23 0 19 0; #X connect 24 0 19 0; pd-0.46-7/doc/5.reference/namecanvas-help.pd0000664000175000017500000000117612222367057016644 0ustar mspmsp#N canvas 248 104 751 339 12; #X obj 29 10 namecanvas; #X obj 29 98 namecanvas bonzo; #X text 521 311 updated for Pd version 0.44; #X text 121 10 - attach this canvas to a name; #X text 24 140 This is sometimes the only way to send a message to a canvas when making graph-on-parent abstractions \, but its use in making self-editing patches is dangerous since if you use it to edit the namecanvas itsef away you can cause Pd to crash. Instead \, you can just say:; #X msg 28 55 \; bonzo msg 280 50 hi there; #X msg 28 227 \; pd-namecanvas-help.pd msg 280 80 this is safer but only possible if you know the name of the canvas in advance.; pd-0.46-7/doc/5.reference/random-help.pd0000664000175000017500000000201612160204055015767 0ustar mspmsp#N canvas 0 0 630 421 12; #X msg 40 212 bang; #X obj 40 287 random 5; #X floatatom 83 261 0 0 0; #X floatatom 40 312 0 0 0; #X msg 50 236 seed 123; #X text 92 210 bang for output; #X text 132 236 message to set the seed; #X text 116 259 inlet to reset the range; #X text 119 286 argument to initialize the range; #X text 378 337 updated for Pd version 0.33; #X text 11 46 Random outputs pseudorandom integers from 0 to N-1 where N is the creation argument (5 in the example below.) You can specify a seed if you wish. Seeds are kept locally so that if two Randoms are seeded the same they will have the same output (or indeed you can seed the same one twice to repeat the output.); #X text 12 139 On the other hand \, if you don't supply a seed each instance of random gets its own seed. WARNING: nothing is known about the quality of teh pseudorandom number generator. It isn't any standard one!; #X obj 20 11 random; #X text 84 11 - pseudorandom integers; #X connect 0 0 1 0; #X connect 1 0 3 0; #X connect 2 0 1 1; #X connect 4 0 1 0; pd-0.46-7/doc/5.reference/x_all_guis.pd0000664000175000017500000000143312160204055015711 0ustar mspmsp#N canvas 209 342 290 271 10; #X obj 23 31 bng 15 250 50 532480 \$1 \$1 empty 20 8 192 8 -262144 -1 -1; #X obj 23 63 tgl 15 1.06496e+06 \$2 \$2 empty 20 8 192 8 -262144 -1 -1 0 1; #X obj 22 95 vsl 15 128 0 127 0 1.59744e+06 \$3 \$3 empty 20 8 192 8 -262144 -1 -1 0 1; #X obj 65 30 hsl 128 15 0 127 0 2.12992e+06 \$4 \$4 empty 20 8 192 8 -262144 -1 -1 0 1; #X obj 63 63 hdl 15 1 2.6624e+06 8 \$5 \$5 empty 20 8 192 8 -262144 -1 -1 0; #X obj 62 99 vu 15 120 \$6 empty 35 8 64 8 -66577 -1 1 49152; #X obj 115 99 cnv 15 100 60 \$7 \$7 \$7 20 12 917696 14 -233017 -66577 3.72736e+06; #X obj 41 308 inlet; #X obj 41 334 outlet; #X obj 227 30 vdl 15 1 4.79232e+06 8 \$9 \$9 empty 20 8 192 8 -262144 -1 -1 0; #X obj 116 176 nbx 5 14 -1e+37 1e+37 0 4.25984e+06 \$8 \$8 empty 45 7 192 10 -262144 -1 -1 0; pd-0.46-7/doc/5.reference/env~-help.pd0000664000175000017500000000230312160204055015474 0ustar mspmsp#N canvas 134 127 625 411 12; #X floatatom 11 332 0 0 0 0 - - -; #X obj 74 14 env~; #X text 120 16 - envelope follower; #X obj 11 209 osc~ 400; #X obj 11 236 *~; #X floatatom 103 211 3 -99 300 0 - - -; #X obj 103 235 dbtorms; #X text 9 46 The env~ object takes a signal and outputs its RMS amplitude in dB (with 1 normalized to 100 dB.) Output is bounded below by zero. ; #X text 141 209 <- set peak-to-peak amplitude here in dB.; #X text 57 333 <- the output is RMS amplitude which (for a sinusoid) is about 3 dB below peak-to-peak amplitude.; #X text 359 380 updated for Pd version 0.40.; #X obj 11 269 env~ 16384 8192; #X text 160 259 creation arguments:; #X text 158 277 1 window size in samples (1024 default); #X text 158 296 2 period in samples per analysis (window/2 default) ; #X text 9 102 The analysis is "Hanning" (raised cosine) windowed.; #X text 9 125 The optional creation arguments are the analysis window size in samples \, and the period (the number of samples between analyses). The latter should normally be a multiple of the DSP block size \, although this isn't enforced.; #X connect 3 0 4 0; #X connect 4 0 11 0; #X connect 5 0 6 0; #X connect 6 0 4 1; #X connect 11 0 0 0; #X connect 11 0 0 0; pd-0.46-7/doc/5.reference/graph-help.pd0000664000175000017500000000107312160204055015612 0ustar mspmsp#N canvas 28 3 693 300 12; #X graph graph1 0 -1 99 1 188 290 338 190; #X array array99 100 float; #X pop; #X text 174 19 GRAPHS; #X text 20 42 A graph in Pd is a rectangular subregion of the window in which you can store numeric arrays.; #X text 19 140 You can change the array values by redrawing it in the graph. See also "11.arrays" and passim in the "control examples".; #X text 406 266 last updated for release 0.33; #X text 18 85 If you create a new array Pd will usually make a new graph to put it in (you can change this using the "array" dialog that pops up.) ; pd-0.46-7/doc/5.reference/exp~-help.pd0000664000175000017500000000124312160204055015502 0ustar mspmsp#N canvas 35 5 531 296 10; #X obj 19 107 sig~; #X obj 50 167 loadbang; #X obj 50 191 metro 100; #X obj 50 215 snapshot~; #X floatatom 19 88 5 0 0 0 - - -; #X floatatom 50 240 7 0 0 0 - - -; #X text 314 271 updated for Pd version 0.42.; #X text 83 131 <-- optional creation argument initializes right inlet (the base of the logarithm).; #X obj 21 14 exp~; #X text 60 14 - exponential function; #X text 76 31 raises the Euler number 'e' (about 2.718) \, to the power of the input signal.; #X text 18 272 See also:; #X obj 92 271 pow~; #X obj 20 132 exp~; #X connect 0 0 13 0; #X connect 1 0 2 0; #X connect 2 0 3 0; #X connect 3 0 5 0; #X connect 4 0 0 0; #X connect 13 0 3 0; pd-0.46-7/doc/5.reference/biquad~-help.pd0000664000175000017500000000236212160204055016156 0ustar mspmsp#N canvas 327 119 689 397 12; #X obj 15 12 biquad~; #X msg 510 20 \; pd dsp 1; #X msg 504 66 \; pd dsp 0; #X obj 84 248 env~; #X floatatom 84 275 0 0 0 0 - - -; #X floatatom 15 110 0 0 0 0 - - -; #X obj 15 246 env~; #X floatatom 15 274 0 0 0 0 - - -; #X text 13 297 Compare the value of the straight signal on the left with the value of the filtered signal on the right.; #X obj 84 215 biquad~ 1.41407 -0.9998 1 -1.41421 1; #X msg 101 121 1.41407 -0.9998 1 -1.41421 1; #X text 76 31 calculates the following difference equation:; #X text 77 44 y(n) = ff1 * w(n) + ff2 * w(n-1) + ff3 * w(n-2); #X text 77 60 w(n) = x(n) + fb1 * w(n-1) + fb2 * w(n-2); #X text 18 76 Syntax: biquad~ fb1 fb2 ff1 ff2 ff3; #X text 259 239 this biquad~ is a notch filter for fn = Pi/4; #X text 265 258 (= SR/8 = 5512.5 Hz @44.1k); #X text 91 14 2-pole-2-zero-filter; #X text 113 99 list sets filter parameters; #X msg 119 161 set 0 0; #X msg 120 186 clear; #X obj 15 170 osc~ 5512.5; #X text 422 337 updated for Pd version-0.30; #X text 189 163 set internal state; #X text 187 185 ... or just clear it; #X connect 3 0 4 0; #X connect 5 0 21 0; #X connect 6 0 7 0; #X connect 9 0 3 0; #X connect 10 0 9 0; #X connect 19 0 9 0; #X connect 20 0 9 0; #X connect 21 0 6 0; #X connect 21 0 9 0; pd-0.46-7/doc/5.reference/throw~-help.pd0000664000175000017500000000200512160204055016046 0ustar mspmsp#N canvas 80 120 664 313 12; #X obj 97 159 throw~ signal1; #X floatatom 268 211 0 0 0; #X obj 90 193 sig~ 50; #X obj 268 181 snapshot~; #X obj 90 221 throw~ signal1; #X obj 97 88 sig~ 25; #X obj 268 135 catch~ signal1; #X obj 35 17 throw~; #X obj 97 17 catch~; #X text 163 16 - summing signal bus and non-local connection; #X obj 551 88 loadbang; #X msg 561 110 \; pd dsp 1; #X obj 551 151 metro 200; #X text 33 48 Any number of throw~ objects can add into one catch~ object (but two catch~ objects cannot share the same name.); #X floatatom 401 206 0 0 0; #X obj 402 182 snapshot~; #X obj 402 134 catch~ signal2; #X msg 113 111 set signal2; #X msg 114 135 set signal1; #X text 75 252 You can redirect throw~ via a "set" message.; #X text 410 283 updated for Pd version 0.33; #X connect 2 0 4 0; #X connect 3 0 1 0; #X connect 5 0 0 0; #X connect 6 0 3 0; #X connect 10 0 11 0; #X connect 10 0 12 0; #X connect 12 0 3 0; #X connect 12 0 15 0; #X connect 15 0 14 0; #X connect 16 0 15 0; #X connect 17 0 0 0; #X connect 18 0 0 0; pd-0.46-7/doc/5.reference/hslider-help.pd0000664000175000017500000002206112374250720016152 0ustar mspmsp#N canvas 333 147 509 514 10; #X obj 1 1 cnv 8 100 60 empty empty hslider=hsl 20 20 1 18 -262144 -1109 0; #X floatatom 38 127 9 0 0 0 - - -, f 9; #X msg 47 84 set \$1; #X floatatom 38 41 7 0 0 0 - - -, f 7; #X text 13 355 (c) musil@iem.kug.ac.at; #X text 55 368 IEM KUG; #X obj 38 149 bng 15 250 50 0 empty empty empty 8 -8 0 10 -262144 -1 -1; #X obj 18 41 bng 15 250 50 0 empty empty empty 8 -8 0 10 -262144 -1 -1; #X obj 41 107 hsl 101 15 25 75 0 1 foo1_snd foo1_rcv empty 8 -8 0 10 -225280 -1109 -1 6200 1; #X text 174 11 gui-horicontal-slider:; #X floatatom 47 62 7 0 0 0 - - -, f 7; #X floatatom 116 150 9 0 0 0 - - -, f 9; #X obj 110 308 r goo2_snd; #X obj 145 248 s goo2_rcv; #X floatatom 105 40 7 0 0 0 - - -, f 7; #X floatatom 145 206 7 0 0 0 - - -, f 7; #X obj 60 170 print; #N canvas 276 200 290 224 once 0; #X obj 38 47 t b b f; #X msg 56 85 1; #X obj 31 108 f 0; #X obj 31 131 pack 0 0; #X obj 31 156 route 0; #X obj 38 24 inlet; #X obj 31 180 outlet; #X connect 0 0 1 0; #X connect 0 1 2 0; #X connect 0 2 3 1; #X connect 1 0 2 1; #X connect 2 0 3 0; #X connect 3 0 4 0; #X connect 4 0 6 0; #X connect 5 0 0 0; #X restore 60 147 pd once; #X obj 40 265 hsl 73 15 55 3520 1 1 goo2_snd goo2_rcv log.freq. 8 -8 0 10 -42246 -260818 -90133 1600 1; #X obj 37 308 ftom; #X floatatom 37 330 9 0 0 0 - - -, f 9; #X floatatom 64 287 9 0 0 0 - - -, f 9; #X floatatom 110 329 9 0 0 0 - - -, f 9; #X text 175 176 click properties to; #X floatatom 37 203 8 0 0 0 - - -, f 8; #X obj 37 226 mtof; #X text 12 184 --------------------; #X text 163 187 modify geometry \, colors \, etc.; #X obj 105 82 s foo1_rcv; #X obj 116 130 r foo1_snd; #X msg 105 61 set \$1; #X msg 145 227 set \$1; #X text 197 120 (0.01 pixels); #X text 183 99 shift-click & drag; #X text 189 109 for fine-tuning; #X text 148 270 UP- \, DOWN- \, LEFT- or RIGHT-key; #X text 147 281 for moving selected gui-objects; #N canvas 207 113 716 530 edit 0; #X obj 32 220 f; #X msg 10 199 bang; #X floatatom 48 198 3 63 88 0 - - -, f 3; #X floatatom 83 220 3 0 37 0 - - -, f 3; #X obj 32 243 pack 0 0; #X text 110 220 y-label; #X text 76 198 x-label; #X obj 279 246 f; #X msg 257 225 bang; #X floatatom 295 224 3 -10 10 0 - - -, f 3; #X floatatom 330 246 3 -10 10 0 - - -, f 3; #X obj 279 269 pack 0 0; #X obj 292 358 f; #X msg 270 337 bang; #X floatatom 308 336 3 20 60 0 - - -, f 3; #X floatatom 343 358 3 150 200 0 - - -, f 3; #X obj 292 381 pack 0 0; #X text 323 224 x-delta; #X text 357 246 y-delta; #X text 336 336 x-position; #X text 370 358 y-position; #X obj 52 335 f; #X msg 30 314 bang; #X floatatom 68 313 3 0 2 0 - - -, f 3; #X floatatom 103 335 3 4 36 0 - - -, f 3; #X obj 52 358 pack 0 0; #X text 96 313 font; #X text 132 335 height; #X floatatom 476 188 1 0 1 0 - - -, f 1; #X text 523 401 no init; #X text 493 453 init value on loadbang; #X msg 47 154 \; goo2_rcv color \$1 \$2 \$3; #X msg 32 268 \; goo2_rcv label_pos \$1 \$2; #X msg 52 383 \; goo2_rcv label_font \$1 \$2; #X msg 34 427 \; goo2_rcv label blabla; #X msg 292 406 \; goo2_rcv pos \$1 \$2; #X msg 279 294 \; goo2_rcv delta \$1 \$2; #X msg 475 21 \; goo2_rcv send goo2a_snd; #X msg 475 59 \; goo2_rcv send goo2_snd; #X msg 476 105 \; goo2_rcv receive goo2a_rcv; #X msg 476 143 \; goo2a_rcv receive goo2_rcv; #X msg 502 420 \; goo2_rcv init 0; #X msg 503 471 \; goo2_rcv init 1; #X text 520 188 steady; #X obj 486 291 f; #X msg 464 270 bang; #X floatatom 502 269 3 55 440 0 - - -, f 3; #X floatatom 537 291 6 440 3520 0 - - -, f 6; #X obj 486 314 pack 0 0; #X text 530 269 left-range-bound; #X text 586 291 right-range-bound; #X msg 486 339 \; goo2_rcv range \$1 \$2; #X msg 363 465 \; goo2_rcv log; #X msg 269 466 \; goo2_rcv lin; #X text 269 448 linear / logarithmical; #X obj 275 133 f; #X msg 250 112 bang; #X floatatom 291 111 3 15 73 0 - - -, f 3; #X floatatom 326 133 3 8 50 0 - - -, f 3; #X obj 275 156 pack 0 0; #X text 319 111 width; #X text 357 134 height; #X msg 275 181 \; goo2_rcv size \$1 \$2; #X msg 34 463 \; goo2_rcv label log.freq.; #X msg 476 212 \; goo2_rcv steady \$1; #X obj 47 100 pack 0 0 0; #X obj 47 72 f; #X msg 24 24 bang; #X floatatom 63 22 3 0 29 0 - - -, f 3; #X floatatom 79 42 3 0 29 0 - - -, f 3; #X floatatom 112 58 3 0 29 0 - - -, f 3; #X text 91 22 background; #X text 106 42 front-color; #X text 140 59 label-color; #X msg 277 22 back; #X msg 277 42 front; #X msg 277 62 label; #X msg 239 22 bang; #N canvas 15 207 606 448 RGB_____________ 0; #X obj 97 56 inlet; #X obj 262 53 inlet; #X obj 339 55 inlet; #X obj 405 56 inlet; #X obj 97 270 bang; #X msg 77 295 0; #X msg 104 295 1; #X obj 146 268 bang; #X msg 132 295 0; #X msg 160 295 1; #X obj 196 269 bang; #X msg 187 295 0; #X msg 214 295 1; #X obj 265 313 spigot; #X obj 312 313 spigot; #X obj 359 313 spigot; #X obj 249 385 outlet; #X text 93 33 select; #X text 267 28 red; #X text 337 30 green; #X text 409 30 blue; #X obj 405 102 t b f; #X obj 339 160 +; #X obj 339 185 t b f; #X obj 339 216 +; #X obj 296 385 outlet; #X obj 343 385 outlet; #X obj 28 180 loadbang; #X obj 97 135 route back front label bang; #X obj 343 362 f; #X obj 296 361 f; #X obj 249 361 f; #X obj 262 79 * -65536; #X obj 339 80 * -256; #X obj 405 80 * -1; #X obj 339 247 - 1; #X obj 235 168 t b b b b; #X connect 0 0 28 0; #X connect 1 0 32 0; #X connect 2 0 33 0; #X connect 3 0 34 0; #X connect 4 0 5 0; #X connect 4 0 6 0; #X connect 5 0 14 1; #X connect 5 0 15 1; #X connect 6 0 13 1; #X connect 7 0 8 0; #X connect 7 0 9 0; #X connect 8 0 13 1; #X connect 8 0 15 1; #X connect 9 0 14 1; #X connect 10 0 11 0; #X connect 10 0 12 0; #X connect 11 0 13 1; #X connect 11 0 14 1; #X connect 12 0 15 1; #X connect 13 0 31 1; #X connect 14 0 30 1; #X connect 15 0 29 1; #X connect 21 0 22 0; #X connect 21 1 22 1; #X connect 22 0 23 0; #X connect 23 0 24 0; #X connect 23 1 24 1; #X connect 24 0 35 0; #X connect 27 0 6 0; #X connect 28 0 4 0; #X connect 28 1 7 0; #X connect 28 2 10 0; #X connect 28 3 36 0; #X connect 29 0 26 0; #X connect 30 0 25 0; #X connect 31 0 16 0; #X connect 32 0 24 0; #X connect 33 0 22 0; #X connect 34 0 21 0; #X connect 35 0 15 0; #X connect 35 0 14 0; #X connect 35 0 13 0; #X connect 36 0 31 0; #X connect 36 1 30 0; #X connect 36 2 29 0; #X connect 36 3 35 0; #X restore 277 82 pd RGB_____________; #X floatatom 319 52 3 0 255 0 - - -, f 3; #X floatatom 362 52 3 0 255 0 - - -, f 3; #X floatatom 405 53 3 0 255 0 - - -, f 3; #X text 34 -1 preset-colors; #X text 290 1 RGB-colors; #X text 319 34 red; #X text 355 33 green; #X text 403 33 blue; #X connect 0 0 4 0; #X connect 1 0 0 0; #X connect 2 0 0 1; #X connect 3 0 4 1; #X connect 4 0 32 0; #X connect 7 0 11 0; #X connect 8 0 7 0; #X connect 9 0 7 1; #X connect 10 0 11 1; #X connect 11 0 36 0; #X connect 12 0 16 0; #X connect 13 0 12 0; #X connect 14 0 12 1; #X connect 15 0 16 1; #X connect 16 0 35 0; #X connect 21 0 25 0; #X connect 22 0 21 0; #X connect 23 0 21 1; #X connect 24 0 25 1; #X connect 25 0 33 0; #X connect 28 0 64 0; #X connect 44 0 48 0; #X connect 45 0 44 0; #X connect 46 0 44 1; #X connect 47 0 48 1; #X connect 48 0 51 0; #X connect 55 0 59 0; #X connect 56 0 55 0; #X connect 57 0 55 1; #X connect 58 0 59 1; #X connect 59 0 62 0; #X connect 65 0 31 0; #X connect 66 0 65 0; #X connect 67 0 66 0; #X connect 68 0 66 1; #X connect 69 0 65 1; #X connect 70 0 65 2; #X connect 74 0 78 0; #X connect 75 0 78 0; #X connect 76 0 78 0; #X connect 77 0 78 0; #X connect 78 0 65 0; #X connect 78 1 65 1; #X connect 78 2 65 2; #X connect 79 0 78 1; #X connect 80 0 78 2; #X connect 81 0 78 3; #X restore 314 245 pd edit; #X obj 221 61 hsl 128 15 0 127 0 0 ddd ddd empty 20 8 0 8 -262144 -1 -1 0 1; #X text 30 380 graz \, austria 2002; #X obj 168 34 x_all_guis aaa bbb ccc ddd eee fff ggg hhh iii; #N canvas 108 94 494 298 old-behavior 0; #X floatatom 65 127 5 0 0 0 - - -, f 5; #X floatatom 65 173 5 0 0 0 - - -, f 5; #X msg 60 208 \; pd compatibility 0.45; #X msg 239 209 \; pd compatibility 0.46; #X text 77 246 Old "compatible" behavior, f 16; #X text 246 246 Mew "correct" behavior; #X text 38 21 Prior to Pd version 0.46 \, values sent to IEM controls were restricted to the control's own values before passing them through to the output. This behavior is changed in 0.46. You can toggle back and forth between the two behaviors using the messages boxes below. If you want to get the behavior in an up-to-date patch \, you can use "int" and "clip" objects to quantize and restrict the range o numbers. ; #X msg 111 126 0.5; #X msg 146 126 -12; #X obj 69 151 hsl 128 15 0 127 0 0 empty empty empty -2 -8 0 10 -262144 -1 -1 0 1; #X connect 0 0 9 0; #X connect 7 0 9 0; #X connect 8 0 9 0; #X connect 9 0 1 0; #X restore 260 446 pd old-behavior; #X text 40 403 COMPATIBILIY NOTE: as of Pd 0.46 \, you can pass through numbers ouside the object's range. You can get the old behavior back this way:, f 48; #X text 219 480 updated for Pd version 0.46; #X connect 1 0 6 0; #X connect 2 0 8 0; #X connect 3 0 8 0; #X connect 7 0 8 0; #X connect 8 0 1 0; #X connect 8 0 17 0; #X connect 10 0 2 0; #X connect 12 0 22 0; #X connect 14 0 30 0; #X connect 15 0 31 0; #X connect 17 0 16 0; #X connect 18 0 21 0; #X connect 18 0 19 0; #X connect 19 0 20 0; #X connect 24 0 25 0; #X connect 25 0 18 0; #X connect 29 0 11 0; #X connect 30 0 28 0; #X connect 31 0 13 0; pd-0.46-7/doc/5.reference/block~-help.pd0000664000175000017500000001100212160204055015772 0ustar mspmsp#N canvas 0 0 603 672 12; #X obj 48 10 block~; #X text 112 11 (and switch~) - block size and on/off control for DSP ; #X text 44 40 The block~ and switch~ objects set the block size \, overlap \, and up/down-sampling ratio for the window. (The overlap and resampling ratio are relative to the super-patch.); #X text 45 230 You may have at most one block~/switch~ object in any window.; #X text 45 176 A switch~ with no arguments does not reblock audio computation -- in other words \, block size and sample rate are as in the parent patch.; #X text 46 531 see also:; #X obj 134 531 fft~; #X text 44 567 ... and the control.blocksize and up.downsampling audio example patches.; #X text 194 459 <--- example usage in subpatch; #X text 43 92 Switch~ \, in addition \, allows you to switch DSP on and off for the window. All subwindows are also switched. (If a subwindow of a switched window is also switched \, both switches must be on for the subwindow's audio DSP to run. Pd's global DSP must also be on.) ; #N canvas 372 9 695 365 block-example 0; #X obj 258 238 bang~; #X obj 258 264 t b b; #X obj 258 290 timer; #X floatatom 258 319 5 0 0 0 - - -; #X obj 54 30 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X msg 78 53 set 4096 1 1; #X msg 78 108 set 4096 2 1; #X msg 78 79 set 8192 1 1; #X msg 81 138 set 4096 1 0.5; #X msg 81 165 set 4096 1 2; #X obj 52 192 switch~ 4096 1 1; #X obj 258 347 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X text 94 25 <--- switch this subpatch on and off; #X text 209 53 <--- block size 4096 \, no overlap \, no resampling ; #X text 206 81 <--- bigger block size; #X text 208 109 <--- double overlap; #X text 219 142 <--- downsampled by factor of 2; #X text 218 167 <--- upsampled by factor of 2; #X text 206 194 <--- creation arguments (if any) initialize blocking ; #X text 317 317 <--- measured time (msec) between blocks; #X text 245 209 (args are blocksize \, overlap \, up/downsampling) ; #X connect 0 0 1 0; #X connect 1 0 2 0; #X connect 1 1 2 1; #X connect 2 0 3 0; #X connect 3 0 11 0; #X connect 4 0 10 0; #X connect 5 0 10 0; #X connect 6 0 10 0; #X connect 7 0 10 0; #X connect 8 0 10 0; #X connect 9 0 10 0; #X restore 41 457 pd block-example; #N canvas 112 205 599 297 block-interations 0; #X text 32 61 Dac~ and adc~ don't work correctly if reblocked \, nor if a parent window is reblocked \, even if the window containing the dac~ or adc~ is reblocked back to the default block size and sample rate.; #X text 33 209 Patches using send~/receive~ or throw~/catch~ to intercommunicate must have the same blocking -- and if their parents are blocked bigger than they are \, there might be wierdness.; #X text 31 128 If using send~ or delwrite~ from a switched-off patch \, the output of corresponding receive~ and delread~ objects in other \, running patches will cycle old input (and sound like garbage). Throw~ may be switched with impunity \, but not catch~.; #X text 32 11 INTERACTIONS BETWEEN BLOCK~/SWITCH~ AND OTHER OBJECTS IN PD; #X restore 40 482 pd block-interations; #X text 44 269 Pd's default block size is 64 samples. The inlet~ and outlet~ objects reblock signals to adjust for differences between parent and subpatch \, but only power-of-two adjustments are possible. So for "normal" audio computations \, all blocaks should also be power-of-two in size. HOWEVER \, if you have no inlet~ or outlet~ you may specify any other block size. This is intended for later use in video processing. ; #X text 45 395 Switch~ takes a "bang" message that causes one block of DSP to be computed. This might be useful for pre-computing waveforms or window functions \, or also for video processing.; #X text 198 484 <-- BUG!! block~/switch~ and dac~/adc~ are incompatible ; #N canvas 0 0 581 315 block-interations 0; #X text 32 11 You can use the switch~ object to single-step dsp in a subpatch. This might be useful for block operations that don't want to be synced to the sample clock: loading a wondiw function in a table \, or copying one table to another:; #X obj 136 193 noise~; #X obj 136 225 tabwrite~ zzzz; #X obj 33 154 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #N canvas 0 0 450 300 (subpatch) 0; #X array zzzz 256 float 2; #X coords 0 1 256 -1 256 140 1; #X restore 300 116 graph; #X obj 33 228 switch~ 256; #X text 25 111 turn DSP on and click to; #X text 26 127 randomize the table at right:; #X connect 1 0 2 0; #X connect 3 0 2 0; #X connect 3 0 5 0; #X restore 40 505 pd block-interations; #X text 198 506 <-- wierd 'bang' feature lets you single-step DSP; #X text 337 604 updated for Pd version 0.43; pd-0.46-7/doc/5.reference/metro-help.pd0000664000175000017500000000312412374250720015645 0ustar mspmsp#N canvas 19 47 645 526 12; #X obj 32 291 metro 500; #X obj 70 9 metro; #X floatatom 101 268 4 0 0 0 - - -, f 4; #X msg 32 125 1; #X text 92 135 nonzero number or "bang" to start; #X msg 49 172 0; #X msg 38 148 bang; #X msg 49 194 stop; #X text 99 181 zero or "stop" to stop.; #X text 150 268 right inlet sets the rate in msec per tick.; #X text 377 471 Updated for Pd version 0.45; #X text 121 8 - metronome; #X text 23 35 The metro object sends a series of bangs at regular time intervals. The right inlet takes the value in milliseconds between each bang. The left inlet takes a 1 or 0 \, turning the metronome on or off.; #X obj 32 317 bng 25 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X text 116 292 <-- optional creation arguments:; #X text 165 311 - delay time (float); #X text 166 329 - tempo (float) and time unit (symbol) as in "tempo" message, f 31; #X msg 51 220 tempo 2 msec; #X text 165 219 set tempo in units of miliseconds (msec for short) \, seconds (sec) \, minutes (min) or samples (samp)., f 51; #X text 79 472 see also:; #X obj 173 470 timer; #X text 41 373 for example \, a metronome at intervals of one beat at 120 beats per minute:, f 37; #X obj 360 395 metro 1 120 permin; #X obj 360 373 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 360 420 bng 25 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 220 435 delay; #X text 50 428 for details on tempo setting \, see:, f 20; #X connect 0 0 13 0; #X connect 2 0 0 1; #X connect 3 0 0 0; #X connect 5 0 0 0; #X connect 6 0 0 0; #X connect 7 0 0 0; #X connect 17 0 0 0; #X connect 22 0 24 0; #X connect 23 0 22 0; pd-0.46-7/doc/5.reference/vslider-help.pd0000664000175000017500000002212212374250720016166 0ustar mspmsp#N canvas 348 256 557 492 10; #X obj 1 1 cnv 8 100 60 empty empty vslider=vsl 20 20 1 18 -262144 -1109 0; #X floatatom 38 300 9 0 0 0 - - -, f 9; #X msg 47 84 set \$1; #X floatatom 38 43 7 0 0 0 - - -, f 7; #X text 25 363 (c) musil@iem.kug.ac.at; #X text 67 376 IEM KUG; #X obj 38 324 bng 15 250 50 0 empty empty empty 8 -8 0 10 -262144 -1 -1; #X obj 18 47 bng 15 250 50 0 empty empty empty 8 -8 0 10 -262144 -1 -1; #X floatatom 47 63 7 0 0 0 - - -, f 7; #X floatatom 116 324 9 0 0 0 - - -, f 9; #X floatatom 106 42 7 0 0 0 - - -, f 7; #X floatatom 147 113 7 0 0 0 - - -, f 7; #X obj 75 249 ftom; #X floatatom 75 271 9 0 0 0 - - -, f 9; #X floatatom 111 244 9 0 0 0 - - -, f 9; #X floatatom 185 266 9 0 0 0 - - -, f 9; #X text 181 151 click properties to; #X floatatom 75 112 9 0 0 0 - - -, f 9; #X obj 75 134 mtof; #X text 166 12 gui-vertical-slider:; #X obj 38 162 vsl 15 101 100 300 0 1 foo3_snd foo3_rcv empty 8 -8 0 10 -225280 -1109 -1 2500 1; #X obj 75 168 vsl 15 73 55 3520 1 1 goo4_snd goo4_rcv log.freq. 11 -6 0 10 -261681 -260818 -90881 0 1; #X obj 185 244 r goo4_snd; #X obj 147 133 s goo4_rcv; #X text 202 65 (0.01 pixels); #X text 57 99 ------------------------------------------; #X text 57 286 --------------------------------------------; #X text 169 162 modify geometry \, colors \, etc.; #X obj 106 84 s foo3_rcv; #X obj 116 302 r foo3_snd; #X msg 106 63 set \$1; #X text 188 44 shift-click & drag; #X text 194 54 for fine-tuning; #X text 119 192 UP- \, DOWN- \, LEFT- or RIGHT-key; #X text 118 203 for moving selected gui-objects; #N canvas 239 379 699 530 edit 0; #X obj 37 233 f; #X msg 15 212 bang; #X floatatom 53 211 3 6 88 0 - - -, f 3; #X floatatom 88 233 3 -20 37 0 - - -, f 3; #X obj 37 256 pack 0 0; #X text 115 233 y-label; #X text 81 211 x-label; #X obj 287 271 f; #X msg 265 250 bang; #X floatatom 303 249 3 -10 10 0 - - -, f 3; #X floatatom 338 271 3 -10 10 0 - - -, f 3; #X obj 287 294 pack 0 0; #X obj 299 381 f; #X msg 277 360 bang; #X floatatom 315 359 3 20 90 0 - - -, f 3; #X floatatom 350 381 3 150 200 0 - - -, f 3; #X obj 299 404 pack 0 0; #X text 331 249 x-delta; #X text 365 271 y-delta; #X text 343 359 x-position; #X text 377 381 y-position; #X obj 57 348 f; #X msg 35 327 bang; #X floatatom 73 326 3 0 2 0 - - -, f 3; #X floatatom 108 348 3 4 36 0 - - -, f 3; #X obj 57 371 pack 0 0; #X text 101 326 font; #X text 137 348 height; #X floatatom 476 188 1 0 1 0 - - -, f 1; #X text 523 401 no init; #X text 493 453 init value on loadbang; #X text 520 188 steady; #X obj 486 291 f; #X msg 464 270 bang; #X floatatom 502 269 4 55 440 0 - - -, f 4; #X floatatom 537 291 6 440 3520 0 - - -, f 6; #X obj 486 314 pack 0 0; #X text 269 469 linear / logarithmical; #X msg 47 158 \; goo4_rcv color \$1 \$2 \$3; #X msg 37 281 \; goo4_rcv label_pos \$1 \$2; #X msg 57 396 \; goo4_rcv label_font \$1 \$2; #X msg 40 442 \; goo4_rcv label blabla; #X msg 269 487 \; goo4_rcv lin; #X msg 363 486 \; goo4_rcv log; #X msg 299 429 \; goo4_rcv pos \$1 \$2; #X msg 287 319 \; goo4_rcv delta \$1 \$2; #X msg 475 21 \; goo4_rcv send goo4a_snd; #X msg 475 59 \; goo4_rcv send goo4_snd; #X msg 476 105 \; goo4_rcv receive goo4a_rcv; #X msg 476 143 \; goo4a_rcv receive goo4_rcv; #X msg 486 339 \; goo4_rcv range \$1 \$2; #X msg 502 420 \; goo4_rcv init 0; #X msg 503 471 \; goo4_rcv init 1; #X text 539 270 bottom-range-bound; #X text 586 292 top-range-bound; #X obj 286 160 f; #X msg 264 139 bang; #X floatatom 302 138 3 4 55 0 - - -, f 3; #X floatatom 337 160 3 15 73 0 - - -, f 3; #X obj 286 183 pack 0 0; #X msg 286 208 \; goo4_rcv size \$1 \$2; #X text 330 138 width; #X text 368 161 height; #X msg 41 478 \; goo4_rcv label log.freq.; #X msg 476 212 \; goo4_rcv steady \$1; #X obj 47 116 pack 0 0 0; #X obj 47 88 f; #X msg 24 40 bang; #X floatatom 63 38 3 0 29 0 - - -, f 3; #X floatatom 79 58 3 0 29 0 - - -, f 3; #X floatatom 112 74 3 0 29 0 - - -, f 3; #X text 91 38 background; #X text 106 58 front-color; #X text 140 75 label-color; #X msg 285 37 back; #X msg 285 57 front; #X msg 285 77 label; #X msg 247 37 bang; #N canvas 15 207 606 448 RGB_____________ 0; #X obj 97 56 inlet; #X obj 262 53 inlet; #X obj 339 55 inlet; #X obj 405 56 inlet; #X obj 97 270 bang; #X msg 77 295 0; #X msg 104 295 1; #X obj 146 268 bang; #X msg 132 295 0; #X msg 160 295 1; #X obj 196 269 bang; #X msg 187 295 0; #X msg 214 295 1; #X obj 265 313 spigot; #X obj 312 313 spigot; #X obj 359 313 spigot; #X obj 249 385 outlet; #X text 93 33 select; #X text 267 28 red; #X text 337 30 green; #X text 409 30 blue; #X obj 405 102 t b f; #X obj 339 160 +; #X obj 339 185 t b f; #X obj 339 216 +; #X obj 296 385 outlet; #X obj 343 385 outlet; #X obj 28 180 loadbang; #X obj 97 135 route back front label bang; #X obj 343 362 f; #X obj 296 361 f; #X obj 249 361 f; #X obj 262 79 * -65536; #X obj 339 80 * -256; #X obj 405 80 * -1; #X obj 339 247 - 1; #X obj 235 168 t b b b b; #X connect 0 0 28 0; #X connect 1 0 32 0; #X connect 2 0 33 0; #X connect 3 0 34 0; #X connect 4 0 5 0; #X connect 4 0 6 0; #X connect 5 0 14 1; #X connect 5 0 15 1; #X connect 6 0 13 1; #X connect 7 0 8 0; #X connect 7 0 9 0; #X connect 8 0 13 1; #X connect 8 0 15 1; #X connect 9 0 14 1; #X connect 10 0 11 0; #X connect 10 0 12 0; #X connect 11 0 13 1; #X connect 11 0 14 1; #X connect 12 0 15 1; #X connect 13 0 31 1; #X connect 14 0 30 1; #X connect 15 0 29 1; #X connect 21 0 22 0; #X connect 21 1 22 1; #X connect 22 0 23 0; #X connect 23 0 24 0; #X connect 23 1 24 1; #X connect 24 0 35 0; #X connect 27 0 6 0; #X connect 28 0 4 0; #X connect 28 1 7 0; #X connect 28 2 10 0; #X connect 28 3 36 0; #X connect 29 0 26 0; #X connect 30 0 25 0; #X connect 31 0 16 0; #X connect 32 0 24 0; #X connect 33 0 22 0; #X connect 34 0 21 0; #X connect 35 0 15 0; #X connect 35 0 14 0; #X connect 35 0 13 0; #X connect 36 0 31 0; #X connect 36 1 30 0; #X connect 36 2 29 0; #X connect 36 3 35 0; #X restore 285 98 pd RGB_____________; #X floatatom 327 67 3 0 255 0 - - -, f 3; #X floatatom 370 67 3 0 255 0 - - -, f 3; #X floatatom 413 68 3 0 255 0 - - -, f 3; #X text 34 12 preset-colors; #X text 296 9 RGB-colors; #X text 327 49 red; #X text 363 48 green; #X text 411 48 blue; #X connect 0 0 4 0; #X connect 1 0 0 0; #X connect 2 0 0 1; #X connect 3 0 4 1; #X connect 4 0 39 0; #X connect 7 0 11 0; #X connect 8 0 7 0; #X connect 9 0 7 1; #X connect 10 0 11 1; #X connect 11 0 45 0; #X connect 12 0 16 0; #X connect 13 0 12 0; #X connect 14 0 12 1; #X connect 15 0 16 1; #X connect 16 0 44 0; #X connect 21 0 25 0; #X connect 22 0 21 0; #X connect 23 0 21 1; #X connect 24 0 25 1; #X connect 25 0 40 0; #X connect 28 0 64 0; #X connect 32 0 36 0; #X connect 33 0 32 0; #X connect 34 0 32 1; #X connect 35 0 36 1; #X connect 36 0 50 0; #X connect 55 0 59 0; #X connect 56 0 55 0; #X connect 57 0 55 1; #X connect 58 0 59 1; #X connect 59 0 60 0; #X connect 65 0 38 0; #X connect 66 0 65 0; #X connect 67 0 66 0; #X connect 68 0 66 1; #X connect 69 0 65 1; #X connect 70 0 65 2; #X connect 74 0 78 0; #X connect 75 0 78 0; #X connect 76 0 78 0; #X connect 77 0 78 0; #X connect 78 0 65 0; #X connect 78 1 65 1; #X connect 78 2 65 2; #X connect 79 0 78 1; #X connect 80 0 78 2; #X connect 81 0 78 3; #X restore 327 48 pd edit; #X obj 61 345 print; #N canvas 276 200 290 224 once 0; #X obj 38 47 t b b f; #X msg 56 85 1; #X obj 31 108 f 0; #X obj 31 131 pack 0 0; #X obj 31 156 route 0; #X obj 38 24 inlet; #X obj 31 180 outlet; #X connect 0 0 1 0; #X connect 0 1 2 0; #X connect 0 2 3 1; #X connect 1 0 2 1; #X connect 2 0 3 0; #X connect 3 0 4 0; #X connect 4 0 6 0; #X connect 5 0 0 0; #X restore 61 322 pd once; #X obj 377 110 vsl 15 128 0 127 0 0 ccc ccc empty 20 8 0 8 -262144 -1 -1 0 1; #X obj 210 83 x_all_guis aaa bbb ccc ddd eee fff ggg hhh iii; #X text 42 388 graz \, austria 2002; #X text 325 466 updated for Pd version 0.46; #N canvas 106 92 511 348 old-behavior 0; #X floatatom 51 37 5 0 0 0 - - -, f 5; #X floatatom 24 202 5 0 0 0 - - -, f 5; #X msg 24 234 \; pd compatibility 0.45; #X msg 203 235 \; pd compatibility 0.46; #X text 41 272 Old "compatible" behavior, f 16; #X text 210 272 Mew "correct" behavior; #X text 63 76 Prior to Pd version 0.46 \, values sent to IEM controls were restricted to the control's own values before passing them through to the output. This behavior is changed in 0.46. You can toggle back and forth between the two behaviors using the messages boxes below. If you want to get the behavior in an up-to-date patch \, you can use "int" and "clip" objects to quantize and restrict the range o numbers. ; #X msg 97 36 0.5; #X msg 132 36 -12; #X obj 23 58 vsl 15 128 0 127 0 0 empty empty empty 0 -9 0 10 -262144 -1 -1 0 1; #X connect 0 0 9 0; #X connect 7 0 9 0; #X connect 8 0 9 0; #X connect 9 0 1 0; #X restore 296 449 pd old-behavior; #X text 76 406 COMPATIBILIY NOTE: as of Pd 0.46 \, you can pass through numbers ouside the object's range. You can get the old behavior back this way:, f 48; #X connect 1 0 6 0; #X connect 2 0 20 0; #X connect 3 0 20 0; #X connect 7 0 20 0; #X connect 8 0 2 0; #X connect 10 0 30 0; #X connect 11 0 23 0; #X connect 12 0 13 0; #X connect 17 0 18 0; #X connect 18 0 21 0; #X connect 20 0 1 0; #X connect 20 0 37 0; #X connect 21 0 14 0; #X connect 21 0 12 0; #X connect 22 0 15 0; #X connect 29 0 9 0; #X connect 30 0 28 0; #X connect 37 0 36 0; pd-0.46-7/doc/5.reference/text-object-help.pd0000664000175000017500000005100512574135745016763 0ustar mspmsp#N struct text-help-struct float x float y text z; #N canvas 667 152 625 526 12; #X obj 131 474 list; #X obj 18 6 text; #X text 25 473 see also:; #N canvas 0 50 600 400 (subpatch) 0; #N canvas 0 50 450 250 (subpatch) 0; #X array table4 100 float 0; #X coords 0 1 99 -1 500 300 1; #X restore 50 50 graph; #X restore 171 474 array; #X obj 280 217 text define; #X text 81 173 The text object's first argument sets its function: , f 30; #N canvas 636 69 631 661 define 0; #X msg 39 141 clear; #X msg 37 167 read text-object-help.txt; #X msg 40 196 write text-object-help.txt; #X text 32 20 "text define" maintains a text object and can name it so that other objects can find it (and later should have some alternative \, anonymous way to be found).; #X text 61 376 click to open and edit text:; #X text 296 364 creation arguments:; #X text 324 382 optional -k flag to keep contents; #X text 326 399 optional name; #X text 77 263 (optionally you can read or write to/from a file interpreting carriage returns as separators \; this should allow reading some text file formats - like this:); #X text 274 165 read from a file; #X text 276 196 write to a file; #X text 277 139 clear; #X obj 48 228 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 38 491 t b p; #X obj 38 540 text get -s text t; #X msg 39 515 0; #X obj 38 590 print; #X obj 38 565 list trim; #X text 204 499 machinery for printing out first line of text when output as a pointer (by "bang" method above)., f 30; #X text 69 222 bang to output a pointer to a scalar (struct) containing the text, f 35; #X obj 38 400 text define -k text-help-1; #A set this is a message \; this is another 1 ... \;; #X msg 149 326 write -c /tmp/test-cr.txt; #X connect 0 0 20 0; #X connect 1 0 20 0; #X connect 2 0 20 0; #X connect 12 0 20 0; #X connect 13 0 15 0; #X connect 13 1 14 3; #X connect 14 0 17 0; #X connect 15 0 14 0; #X connect 17 0 16 0; #X connect 20 0 13 0; #X connect 21 0 20 0; #X restore 392 217 pd define; #X obj 280 240 text get; #N canvas 885 156 859 566 get 0; #X floatatom 47 115 5 0 5 0 - - -, f 5; #X msg 47 84 0; #X msg 123 84 2; #X msg 83 84 1; #X obj 47 275 print; #X obj 148 300 print type; #X msg 160 87 3; #X msg 200 89 4; #X text 242 298 "type" is 0 if terminated by a semicolon \, 1 if by a comma \, or 2 if the line number was out of range.; #X obj 72 533 text define -k text-help-get; #A set; #X obj 47 230 text get text-help-get, f 13; #X floatatom 50 407 5 0 0 0 - - -, f 5; #X msg 50 376 0; #X msg 126 376 2; #X msg 86 376 1; #X obj 50 478 print; #X msg 163 379 3; #X msg 203 381 4; #X obj 50 451 text get text-help-get 1; #X text 165 217 arguments: name of the text object or "-s struct-name" ; #X floatatom 462 410 5 0 0 0 - - -, f 5; #X msg 462 379 0; #X msg 538 379 2; #X msg 498 379 1; #X obj 462 461 print; #X msg 575 382 3; #X msg 615 384 4; #X text 259 450 read field number 1 (zero for first field), f 23; #X obj 461 434 text get text-help-get 1 3; #X text 127 345 examples showing field selection:; #X text 32 20 "text get" reads the nth line from the named text and outputs it \, or optionally reads one or more specific fields (atoms) from the line.; #X text 101 115 spedcify line number (0 for first line); #X floatatom 80 140 5 0 5 0 - - -, f 5; #X floatatom 114 163 5 0 5 0 - - -, f 5; #X text 162 162 specify number of fields (1 by default \, but ignored if whole line), f 66; #X text 680 434 read 3 fields starting at field 1, f 21; #X text 128 139 starting field number (-1 \, the default \, gives the whole line), f 61; #X text 162 237 next optional arg to set starting field number (first inlet -- none to specify whole line), f 63; #X text 166 274 next optional arg to set inlet 2 (number of fields \, defaults to one), f 68; #X msg 148 186 symbol text-help-get; #X text 321 186 find another text by name or pointer; #X connect 0 0 10 0; #X connect 1 0 0 0; #X connect 2 0 0 0; #X connect 3 0 0 0; #X connect 6 0 0 0; #X connect 7 0 0 0; #X connect 10 0 4 0; #X connect 10 1 5 0; #X connect 11 0 18 0; #X connect 12 0 11 0; #X connect 13 0 11 0; #X connect 14 0 11 0; #X connect 16 0 11 0; #X connect 17 0 11 0; #X connect 18 0 15 0; #X connect 20 0 28 0; #X connect 21 0 20 0; #X connect 22 0 20 0; #X connect 23 0 20 0; #X connect 25 0 20 0; #X connect 26 0 20 0; #X connect 28 0 24 0; #X connect 32 0 10 1; #X connect 33 0 10 2; #X connect 39 0 10 3; #X restore 392 240 pd get; #N canvas 226 212 807 554 text-and-data-structures 0; #X floatatom 65 196 5 0 0 0 - - -, f 5; #X msg 65 165 0; #X msg 140 165 2; #X msg 100 165 1; #X obj 65 387 print; #X obj 206 391 print type; #X obj 206 315 pointer; #X obj 65 347 text get -s text-help-struct z, f 18; #N canvas 807 416 450 300 text-help-struct 0; #X scalar text-help-struct 20 20 \; a b c d \;; #X obj 79 230 pointer; #X msg 79 172 traverse pd-text-help-struct \, bang, f 21; #X obj 22 257 append text-help-struct x y; #X msg 23 172 20 20; #X obj 13 56 struct text-help-struct float x float y text z; #X obj 13 83 filledpolygon 0 0 0 0 0 0 10 10 10 10 0 0 0; #X obj 15 120 drawtext z 16 -3 0; #X connect 1 0 3 2; #X connect 2 0 1 0; #X connect 4 0 3 0; #X restore 208 136 pd text-help-struct; #X obj 65 218 t f b; #X text 58 35 a simple example showing how to access text in data structures via pointers.; #N canvas 851 144 450 300 text-help-data 0; #X scalar text-help-struct 20 20 \; 1 2 3 \\\; a b c d \\\; \;; #X text 13 86 We have one datum (above) whose "z" field is text.; #X restore 209 108 pd text-help-data; #X msg 205 258 traverse pd-text-help-data \, next, f 18; #X text 88 466 bug - saving multi-line texts inside structures; #X obj 586 333 pointer; #X msg 585 276 traverse pd-text-help-data \, next, f 18; #X obj 445 365 text set -s text-help-struct z, f 18; #X obj 445 236 t l b; #X floatatom 492 337 5 0 0 0 - - -, f 5; #X msg 478 292 0; #X msg 553 292 2; #X msg 513 292 1; #X msg 443 158 1 2 3; #X msg 454 194 list a b c d; #X connect 0 0 9 0; #X connect 1 0 0 0; #X connect 2 0 0 0; #X connect 3 0 0 0; #X connect 6 0 7 3; #X connect 7 0 4 0; #X connect 7 1 5 0; #X connect 9 0 7 0; #X connect 9 1 12 0; #X connect 12 0 6 0; #X connect 14 0 16 3; #X connect 15 0 14 0; #X connect 17 0 16 0; #X connect 17 1 15 0; #X connect 18 0 16 1; #X connect 19 0 18 0; #X connect 20 0 18 0; #X connect 21 0 18 0; #X connect 22 0 17 0; #X connect 23 0 17 0; #X restore 83 434 pd text-and-data-structures; #X text 73 410 here's how to access texts inside data structures:; #X text 63 6 - manage a list of messages; #X obj 219 474 scalar; #X obj 280 287 text size; #N canvas 847 155 741 313 size 0; #X obj 71 55 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 68 257 text define -k text-help-size; #A set; #X obj 71 179 text size text-help-size; #X floatatom 71 204 5 0 0 0 - - -, f 5; #X floatatom 80 91 5 0 2 0 - - -, f 5; #X text 46 11 "text size" reports the number of lines in the text or the length of a specified line.; #X text 100 52 bang for number of lines; #X text 129 89 float for length of nth line (-1 if line number out of range); #X text 443 122 find another text by name or pointer, f 18; #X msg 260 126 symbol text-help-size; #X text 281 176 arguments: name of the text object or "-s struct-name" , f 30; #X connect 0 0 2 0; #X connect 2 0 3 0; #X connect 4 0 2 0; #X connect 9 0 2 1; #X restore 392 286 pd size; #X obj 280 264 text set; #N canvas 116 67 834 537 set 0; #X floatatom 107 197 5 0 0 0 - - -, f 5; #X msg 107 163 0; #X msg 180 165 2; #X msg 140 165 1; #X msg 62 111 list x y z w; #X msg 68 137 1 2 3; #X msg 53 84 12 23 34 45 56 56; #X obj 48 505 text define -k text-help-3; #A set 12 23 34 45 56 56 \; x y z w \; 1 2 3 \;; #X obj 55 293 text set text-help-3; #X msg 223 165 1e+06; #X floatatom 159 219 5 0 0 0 - - -, f 5; #X text 211 85 list to write into the text; #X text 165 197 line number - use a large number to append a line; #X text 240 295 arguments: name of the text object or "-s struct-name" ; #X text 240 320 next optional arg to set inlet 1 (line number), f 63; #X text 241 348 next optional arg to set inlet 2 (number of fields \, defaults to whole line), f 52; #X text 66 407 if inlet 2 is supplied to specify a starting field \, the line is not resized - instead \, as many items are replaced as were in the list at left. Otherwise \, the line is resized to the size of the list.; #X msg 212 260 symbol text-help-get; #X text 385 260 find another text by name or pointer; #X text 206 218 field number - if 0 or positive \, replace text starting at this field \, or if negative (or not supplied) \, replace whole line., f 62; #X text 288 506 <-- click here to see text; #X text 46 9 "text set" replaces the nth line with the incoming list. If the number n is greater than the number of lines in the text the new line is added.; #X connect 0 0 8 1; #X connect 1 0 0 0; #X connect 2 0 0 0; #X connect 3 0 0 0; #X connect 4 0 8 0; #X connect 5 0 8 0; #X connect 6 0 8 0; #X connect 9 0 0 0; #X connect 10 0 8 2; #X connect 17 0 8 3; #X restore 392 263 pd set; #X text 391 176 (click for details), f 11; #X text 60 216 create \, store \, and/or edit; #X text 91 239 read and output a line; #X text 100 263 replace or add a line; #X text 115 288 get number of lines; #X text 365 472 updated for Pd version 0.45; #X text 62 50 In Pd a "text" refers to a list of atoms that can include commas \, semicolons \, and dollar-sign constructs - anything that can go in a message box or a patch (as a saved file). You can use them to store a semicolon-separated list of lists \, or as messages to "execute" as in a sequencer or message box.; #X text 145 312 convert to list; #X obj 280 310 text tolist; #N canvas 842 231 590 379 tolist 0; #X obj 86 99 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X text 48 13 "text tolist" outputs the entire contents as a list. Semicolons \, commas \, and dollar signs are output as symbols (and so \, if symbols like " \, " are encountered \, they're escaped with backslashes).; #X text 108 96 bang to output list; #X obj 86 180 text tolist text-help-1; #X obj 173 218 list prepend set; #X obj 173 241 list trim; #X msg 173 291 this is a message \\\; this is another 1 ... \\\;; #X msg 187 265 set; #X obj 87 218 print; #X text 72 326 N.B.: text-help-1 is defined in 'pd define' subwindow. ; #X text 370 122 find another text by name or pointer, f 18; #X msg 267 124 symbol text-help-1, f 11; #X text 280 172 arguments: name of the text object or "-s struct-name" , f 30; #X connect 0 0 3 0; #X connect 3 0 4 0; #X connect 3 0 8 0; #X connect 4 0 5 0; #X connect 5 0 6 0; #X connect 7 0 6 0; #X connect 11 0 3 1; #X restore 392 310 pd tolist; #X obj 280 334 text fromlist; #N canvas 842 231 604 318 fromlist 0; #X obj 81 202 text fromlist text-help-fromlist; #X obj 114 263 text define text-help-fromlist; #X text 46 21 "text fromlist" converts a list such as "text tolist" would output and fills the text with it. Whatever the text had previously contained is discarded.; #X msg 81 115 list this is a message \\\; this is another 1 ... \\\; ; #X text 135 241 click here to see contents; #X msg 92 145 list 1 2 3; #X text 437 157 find another text by name or pointer, f 18; #X msg 334 159 symbol text-help-1, f 11; #X text 121 92 set contents of text; #X connect 3 0 0 0; #X connect 5 0 0 0; #X connect 7 0 0 1; #X restore 392 334 pd fromlist; #X text 131 336 convert from list; #X text 218 359 search; #X obj 280 358 text search; #N canvas 626 77 1011 913 search 0; #X floatatom 60 313 5 0 0 0 - - -, f 5; #X text 385 232 find another text by name or pointer, f 18; #X text 207 280 arguments: name of the text object or "-s struct-name" , f 30; #X text 46 11 "text search" outputs the line number of the line that best matches a search key. By default it seeks a line whose leading fields match the incoming list.; #X obj 52 873 text define -k text-help-search; #A set 1 2 3 dog \; 7 8 9 cat \; 4 5 3 dog \; 7 8 9 alligator \; random line that won't match numbers \;; #X obj 60 270 text search text-help-search, f 16; #X msg 182 244 symbol text-help-search; #X msg 60 77 1; #X msg 60 101 2; #X msg 60 125 4; #X msg 69 188 4 5; #X msg 69 211 4 13; #X msg 60 149 7; #X text 110 76 matches first line (number 0); #X text 102 99 doesn't match first field of any line so -1; #X text 113 210 fails on second field so no match; #X text 211 314 ... then optional search fields. Each is a field number (starting from 0) optionally preceeded by ">". ">=" \, "<" \, "<=" \, or "near".; #X text 98 150 if two lines match only the first is output (but see below for finding best matches).; #X msg 47 446 7 cat; #X msg 47 470 7 alligator; #X floatatom 47 574 5 0 0 0 - - -, f 5; #X msg 47 494 7 dog; #X obj 47 518 text search text-help-search 0 3, f 16; #X floatatom 503 600 5 0 0 0 - - -, f 5; #X obj 503 541 text search text-help-search 1, f 16; #X msg 504 508 8 9; #X msg 559 486 8 9 alligator; #X msg 504 482 8; #X msg 559 513 symbol line; #X text 43 392 in this example we ask to match both field 0 and field 3 exactly. In field 3 we're testing symbols for equality., f 39; #X text 401 382 If the search pattern (the incoming list) has more fields than we have specified search fields \, extra search patterns match succeeding fields starting from the last one give as an argument. So for example if there are no arguments we look for matches to any number of fields starting from the beginning of the line in the text. ; #X floatatom 49 834 5 0 0 0 - - -, f 5; #X obj 49 778 text search text-help-search > 0, f 16; #X text 45 613 Match a line for which the search key is greater than field zero of that line. The line getting closest to the key wins. , f 41; #X msg 49 671 2; #X msg 49 713 4; #X text 86 664 lines 1 \, 2 \, and 3 match \, but 2 wins because its first field (4) is closest to the search key 2, f 48; #X text 88 703 this matches lines 1 and 3 \, and each is equally good \, so line 1 wins., f 43; #X text 86 744 nobody's first field is greater than 10; #X msg 49 745 10; #X obj 507 809 text search text-help-search 2 near 0, f 18; #X floatatom 507 866 5 0 0 0 - - -, f 5; #X msg 507 685 3 3; #X msg 507 714 3 2.5 1; #X msg 507 775 3 3 1; #X text 506 628 Hear we ask for field 2 to equal 3 and fields starting at 0 to be 'near' the following arguments., f 33; #X text 547 684 field 2 is 3 and field 0 nearest 3; #X text 575 706 here lines 0 and 2 tie over 2.4 (1 and 4 are equally far from it) so line 0 whose second field is closer to 1 wins., f 40; #X text 560 766 Here line 2 wins because its field 0 is nearer to 3 \, notwithstanding that its field 1 is farther from 1; #X text 103 125 matches line number 2 (third line); #X text 114 188 matches two fields of line number 2; #X connect 5 0 0 0; #X connect 6 0 5 1; #X connect 7 0 5 0; #X connect 8 0 5 0; #X connect 9 0 5 0; #X connect 10 0 5 0; #X connect 11 0 5 0; #X connect 12 0 5 0; #X connect 18 0 22 0; #X connect 19 0 22 0; #X connect 21 0 22 0; #X connect 22 0 20 0; #X connect 24 0 23 0; #X connect 25 0 24 0; #X connect 26 0 24 0; #X connect 27 0 24 0; #X connect 28 0 24 0; #X connect 32 0 31 0; #X connect 34 0 32 0; #X connect 35 0 32 0; #X connect 39 0 32 0; #X connect 40 0 41 0; #X connect 42 0 40 0; #X connect 43 0 40 0; #X connect 44 0 40 0; #X restore 393 358 pd search; #X text 76 383 sequencer/message-sender; #X obj 280 381 text sequence; #N canvas 199 57 1155 839 sequence 0; #X msg 138 468 symbol text-help-search; #X text 101 443 specify another text by name or pointer; #X msg 37 225 bang; #X obj 37 693 print out1; #X obj 138 695 print out2; #X msg 46 415 args 1 2 fuzz; #X msg 37 167 line 0; #X obj 655 282 text sequence text-help-seq2 -g, f 17; #X obj 889 300 text define -k text-help-seq2; #A set test1 1 2 3 \; 1000 test2 6 7 8 \; test1 9 10 \, 21 22 23 \, walk the dog \; 500 1500 test1 \; test2 13 14 \;; #X msg 771 248 bang; #X msg 655 248 line 0; #X obj 334 748 print test1; #X obj 334 721 r test1; #X obj 431 720 r test2; #X obj 431 747 print test2; #X obj 749 329 print done; #X obj 46 391 loadbang; #X text 163 414 set values for \$1 \, \$2 \, etc; #X msg 37 198 step; #X text 81 198 output next line; #X text 97 160 set current line number (counting from 0), f 23; #X msg 820 248 auto; #X msg 868 248 stop; #X msg 37 263 auto; #X text 79 219 output all lines starting from current one to next waiting point, f 34; #X text 43 718 lists; #X text 133 718 bang if done; #X text 162 527 -g to specify global mode (each line begins with a symbolic destination), f 39; #X text 164 562 -w specifies that lines beginning with the symbol are waiting points, f 43; #X text 165 597 -w specifies that every line's leading n atoms are used as a waiting point, f 39; #X obj 37 497 text sequence text-help-seq, f 13; #X text 230 489 creation arguments:, f 30; #X text 164 508 name of the text object or "-s struct-name"; #X obj 58 764 text define -k text-help-seq; #A set 1 2 3 \; 4 5 symbol 7 \; 8 \$1 \$2 \; 9 \$3 \$1-\$2-\$3 \;; #X obj 653 328 print wait; #X msg 37 327 stop; #X text 84 328 stop the sequence; #X text 30 10 "text sequence" outputs lines from a text buffer \, either to an outlet \, or as messages to named destinations. The text is interpreted as a sequence of lists \, and possibly some interspersed waiting instructions (called "waits" here). You can ask for one line at a time ("step" message") \, or to proceed without delay to the next wait ("bang") \, or to automatically sequence through a series of waits (with each wait specifying a delay in milliseconds); #X text 78 255 automatically sequence \, interpreting waits as delay times (but note there aren't any waits in this example - see at right) , f 36; #X text 653 228 rewind; #X text 912 274 click to see the sequence:; #X msg 723 248 step; #X msg 761 448 bang; #X msg 629 448 line 0; #X obj 825 535 print done; #X msg 816 448 auto; #X msg 869 449 stop; #X obj 726 535 print wait; #X msg 704 448 step; #X obj 885 496 text define -k text-help-seq3; #A set 1 2 3 \; fred 1000 \; 4 5 6 \; blanch 7 8 \; fred 500 \; 9 10 \;; #X obj 629 482 text sequence text-help-seq3 -w fred, f 22; #X obj 629 535 print out1; #X text 624 365 Alternatively \, with the "-w" flag (with or without "-g" but most usefully without) \, you can specify a symbol that tags an entire line as a wait. Here the three outlets are for lists (regular lines) \, waits \, and a bang at end of sequence:; #X msg 760 718 bang; #X msg 628 718 line 0; #X msg 815 718 auto; #X msg 868 719 stop; #X msg 703 718 step; #X text 934 472 sequence:; #X text 962 746 sequence:; #X obj 884 766 text define -k text-help-seq4; #A set 0 1 2 3 \; 1000 4 5 6 \; 500 7 8 9 \; 500 10 11 12 \;; #X obj 628 752 text sequence text-help-seq4 -w 1, f 19; #X obj 824 802 print done; #X obj 725 802 print wait; #X obj 628 802 print out1; #X msg 37 356 tempo 1 msec; #X obj 390 376 delay; #X text 149 347 set tempo in msec \, sec \, min \, samples \, permin \, etc. -- see 'delay' help for details...., f 28; #X text 163 646 -t initializes tempo as with the "tempo" message above., f 36; #X msg 915 248 tempo 2 permsec; #X text 937 226 set 2x tempo; #X text 625 20 The -g flag (which must be given after specifying the text with a name or a "-s" argument) specifies that the text contains messages to send to global symbols. Lines beginning with symbols are sent to the corresponding receive (or other named object). Leading numbers are then interpreted as waits. If you use "bang" to sequence the text the waits will be output as lists for you to interpret as you wish. If you send an "auto" message \, waits that consist of a single number are interpreted as delay times in milliseconds (but waits with 2 or more arguments are treated as in "bang"). Here the two waits are "1000" and "500 1500".; #X text 623 576 If you want to use leading numbers in lists as waits without having to specify "-g" \, specify "-w 3" for example and up to 3 leading numbers (fewer if there's a symbol among the first 3 items) will be taken as a wait. Waits specified this way can only have numeric elements (while waits specified with a symbol tag as above could have symbols too if desired.) Here we use "-w 1" so the "auto" feature can simply sequence a list of numbers:; #X connect 0 0 30 1; #X connect 2 0 30 0; #X connect 5 0 30 0; #X connect 6 0 30 0; #X connect 7 0 34 0; #X connect 7 1 15 0; #X connect 9 0 7 0; #X connect 10 0 7 0; #X connect 12 0 11 0; #X connect 13 0 14 0; #X connect 16 0 5 0; #X connect 18 0 30 0; #X connect 21 0 7 0; #X connect 22 0 7 0; #X connect 23 0 30 0; #X connect 30 0 3 0; #X connect 30 1 4 0; #X connect 35 0 30 0; #X connect 41 0 7 0; #X connect 42 0 50 0; #X connect 43 0 50 0; #X connect 45 0 50 0; #X connect 46 0 50 0; #X connect 48 0 50 0; #X connect 50 0 51 0; #X connect 50 1 47 0; #X connect 50 2 44 0; #X connect 53 0 61 0; #X connect 54 0 61 0; #X connect 55 0 61 0; #X connect 56 0 61 0; #X connect 57 0 61 0; #X connect 61 0 64 0; #X connect 61 1 63 0; #X connect 61 2 62 0; #X connect 65 0 30 0; #X connect 69 0 7 0; #X restore 393 381 pd sequence; pd-0.46-7/doc/5.reference/bang~-help.pd0000664000175000017500000000115312160204055015615 0ustar mspmsp#N canvas 0 0 529 299 12; #X obj 112 128 bang~; #X obj 112 159 print; #X msg 210 223 \; pd dsp 1; #X msg 297 216 \; pd dsp 0; #X msg 210 144 bang; #X obj 19 20 bang~; #X obj 306 193 loadbang; #X obj 297 169 delay 100; #X text 211 122 click to test; #X text 71 21 - output bang after each DSP cycle; #X text 5 59 Bang~ outputs a bang after each DSP cycle (at the same logical time as the DSP cycle.) This is primarily useful for sampling the outputs of analysis algorithms.; #X text 251 266 updated for Pd version 0.33; #X connect 0 0 1 0; #X connect 4 0 2 0; #X connect 4 0 7 0; #X connect 6 0 3 0; #X connect 7 0 3 0; pd-0.46-7/doc/5.reference/framp~-help.pd0000664000175000017500000000226712160204055016022 0ustar mspmsp#N canvas 22 7 857 377 12; #X text 85 158 frequency; #X floatatom 16 173 0 0 0; #X obj 16 120 * 44100; #X floatatom 16 94 0 0 0; #X text 88 92 frequency; #X text 91 111 in bins; #X text 85 175 in Hz.; #X obj 17 238 rfft~; #X obj 16 148 / 64; #X obj 653 14 loadbang; #X msg 653 40 \; pd dsp 1; #X text 599 339 updated for Pd version 0.33; #X msg 103 260 bang; #X text 154 261 <-- print analysis; #X obj 36 16 framp~; #X text 119 15 - estimate frequency and amplitude of FFT components ; #X obj 16 270 framp~; #X obj 103 322 print~ frequency; #X obj 118 297 print~ amplitude; #X obj 16 204 osc~; #X text 324 98 Framp~ takes as input a rectangular-windowed FFT and outputs \, for each FFT channel \, the estimated amplitude and frequency of any component feedinf that channel. A sinusoidal component should appear in four components (or three in the special case of a sinusoid exactly tuned to a bin.) Frequency output is in bins \, i.e. \, units of SR/N.; #X connect 1 0 19 0; #X connect 2 0 8 0; #X connect 3 0 2 0; #X connect 7 0 16 0; #X connect 7 1 16 1; #X connect 8 0 1 0; #X connect 9 0 10 0; #X connect 12 0 17 0; #X connect 12 0 18 0; #X connect 16 0 17 0; #X connect 16 1 18 0; #X connect 19 0 7 0; pd-0.46-7/doc/5.reference/help-intro.pd0000664000175000017500000003204412467464462015672 0ustar mspmsp#N canvas 220 52 579 948 12; #X declare; #X obj 24 150 bang; #X text 124 150 - output a bang message; #X obj 24 174 float; #X text 124 174 - store and recall a number; #X obj 24 198 symbol; #X text 124 198 - store and recall a symbol; #X obj 24 222 int; #X text 124 222 - store and recall an integer; #X obj 24 246 send; #X text 124 246 - send a message to a named object; #X obj 24 270 receive; #X text 124 270 - catch "sent" messages; #X obj 24 294 select; #X text 124 294 - test for matching numbers or symbols; #X obj 24 318 route; #X text 124 318 - route messages according to first element; #X obj 24 342 pack; #X text 124 342 - make compound messages; #X obj 24 366 unpack; #X text 124 366 - get elements of compound messages; #X obj 24 390 trigger; #X text 124 390 - sequence and convert messagess; #X obj 24 414 spigot; #X text 124 414 - interruptible message connection; #X obj 24 438 moses; #X text 124 438 - part a numeric stream; #X obj 24 462 until; #X text 124 462 - looping mechanism; #X obj 24 486 print; #X text 124 486 - print out messages; #X obj 24 510 makefilename; #X text 145 511 - format a symbol with a variable field; #X obj 24 534 change; #X text 124 534 - remove repeated numbers from a stream; #X obj 24 559 swap; #X text 124 559 - swap two numbers; #X obj 24 583 value; #X text 124 583 - shared numeric value; #X obj 22 660 delay; #X text 122 660 - send a message after a time delay; #X obj 22 684 metro; #X text 122 684 - send a message periodically; #X obj 22 708 line; #X text 122 708 - send a series of linearly stepped numbers; #X obj 22 732 timer; #X text 122 732 - measure time intervals; #X obj 22 756 cputime; #X text 122 756 - measure CPU time; #X obj 22 780 realtime; #X text 122 780 - measure real time; #X obj 22 804 pipe; #X text 122 804 - dynamically growable delay line for numbers; #X text 212 860 - arithmetic; #X text 213 883 - relational tests; #X text 255 908 - bit twiddling; #X obj 23 936 mtof; #X obj 23 958 ftom; #X obj 64 936 powtodb; #X obj 132 935 rmstodb; #X obj 64 957 dbtopow; #X obj 132 957 dbtorms; #X text 214 949 - convert acoustical units; #X obj 22 981 mod; #X obj 53 981 div; #X obj 84 981 sin; #X obj 115 981 cos; #X obj 146 981 tan; #X obj 22 1003 atan; #X obj 62 1003 atan2; #X obj 111 1003 sqrt; #X obj 151 1003 log; #X obj 182 1003 exp; #X obj 213 1003 abs; #X text 253 993 - higher math; #X obj 22 1025 random; #X text 122 1025 - lower math; #X obj 22 1048 max; #X obj 54 1048 min; #X text 122 1048 - greater or lesser of 2 numbers; #X obj 22 1071 clip; #X text 122 1071 - force a number into a range; #X obj 23 1142 notein; #X obj 82 1142 ctlin; #X obj 133 1142 pgmin; #X obj 183 1142 bendin; #X obj 242 1142 touchin; #X obj 23 1165 polytouchin; #X obj 127 1165 midiin; #X obj 186 1165 sysexin; #X text 325 1154 - MIDI input; #X obj 22 1198 noteout; #X obj 90 1198 ctlout; #X obj 150 1198 pgmout; #X obj 209 1198 bendout; #X obj 22 1220 touchout; #X obj 100 1220 polytouchout; #X obj 213 1220 midiout; #X text 321 1208 - MIDI output; #X obj 22 1251 makenote; #X obj 22 1275 stripnote; #X text 114 1277 - strip "note off" messages; #X obj 25 1369 tabread; #X text 125 1369 - read a number from a table; #X obj 25 1392 tabread4; #X text 125 1392 - read a number from a table; #X obj 25 1415 tabwrite; #X text 125 1415 - write a number to a table; #X obj 25 1439 soundfiler; #X text 125 1439 - read and write tables to soundfiles; #X obj 25 1552 loadbang; #X text 125 1552 - bang on load; #X obj 25 1578 serial; #X text 125 1578 - serial device control for NT only; #X obj 25 1604 netsend; #X text 125 1604 - send messages over the internet; #X obj 25 1627 netreceive; #X text 125 1627 - receive them; #X obj 25 1658 qlist; #X text 125 1658 - message sequencer; #X text 125 1682 - file to message converter; #X obj 25 1740 openpanel; #X text 125 1740 - "Open" dialog; #X obj 25 1763 savepanel; #X text 125 1763 - "Save as" dialog; #X obj 25 1800 bag; #X text 125 1800 - set of numbers; #X obj 25 1830 poly; #X text 125 1830 - polyphonic voice allocation; #X obj 25 1860 key; #X obj 59 1860 keyup; #X text 125 1860 - numeric key values from keyboard; #X obj 25 1883 keyname; #X text 125 1883 - symbolic key name; #X text 154 1973 - arithmetic on audio signals; #X text 126 2003 - maximum or minimum of 2 inputs; #X obj 26 2031 clip~; #X text 126 2031 - constrict signal to lie between two bounds; #X obj 26 2061 q8_rsqrt~; #X text 126 2061 - cheap reciprocal square root (beware -- 8 bits!) ; #X obj 26 2083 q8_sqrt~; #X text 126 2083 - cheap square root (beware -- 8 bits!); #X obj 26 2134 wrap~; #X obj 26 2162 fft~; #X text 126 2162 - complex forward discrete Fourier transform; #X obj 26 2184 ifft~; #X text 126 2184 - complex inverse discrete Fourier transform; #X obj 26 2214 rfft~; #X text 126 2214 - real forward discrete Fourier transform; #X obj 26 2236 rifft~; #X text 126 2236 - real inverse discrete Fourier transform; #X obj 26 2290 framp~; #X text 126 2290 - output a ramp for each block; #X obj 26 2320 mtof~; #X obj 77 2320 ftom~; #X obj 127 2320 rmstodb~; #X obj 205 2320 dbtorms~; #X text 284 2320 - acoustic conversions; #X obj 26 2378 dac~; #X text 126 2378 - audio output; #X obj 26 2402 adc~; #X text 126 2402 - audio input; #X obj 26 2426 sig~; #X text 126 2426 - convert numbers to audio signals; #X obj 26 2450 line~; #X text 126 2450 - generate audio ramps; #X obj 26 2474 vline~; #X text 126 2474 - deluxe line~; #X obj 26 2522 snapshot~; #X text 126 2522 - sample a signal (convert it back to a number); #X obj 26 2546 vsnapshot~; #X text 126 2546 - deluxe snapshot~; #X obj 26 2570 bang~; #X text 126 2570 - send a bang message after each DSP block; #X obj 26 2594 samplerate~; #X text 126 2594 - get the sample rate; #X obj 26 2618 send~; #X text 126 2618 - nonlocal signal connection with fanout; #X obj 26 2642 receive~; #X text 126 2642 - get signal from send~; #X obj 26 2666 throw~; #X text 126 2666 - add to a summing bus; #X obj 26 2690 catch~; #X text 126 2690 - define and read a summing bus; #X obj 26 2714 block~; #X text 126 2714 - specify block size and overlap; #X obj 26 2738 switch~; #X text 126 2738 - switch DSP computation on and off; #X obj 26 2762 readsf~; #X text 126 2762 - soundfile playback from disk; #X obj 26 2786 writesf~; #X text 126 2786 - record sound to disk; #X obj 23 2848 phasor~; #X text 123 2848 - sawtooth oscillator; #X obj 23 2872 cos~; #X text 123 2872 - cosine; #X obj 23 2896 osc~; #X text 123 2896 - cosine oscillator; #X obj 23 2920 tabwrite~; #X text 123 2920 - write to a table; #X obj 23 2944 tabplay~; #X text 123 2944 - play back from a table (non-transposing); #X obj 23 2968 tabread~; #X text 123 2968 - non-interpolating table read; #X obj 23 2992 tabread4~; #X text 123 2992 - four-point interpolating table read; #X obj 23 3016 tabosc4~; #X text 123 3016 - wavetable oscillator; #X obj 23 3040 tabsend~; #X text 123 3040 - write one block continuously to a table; #X obj 23 3064 tabreceive~; #X text 123 3064 - read one block continuously from a table; #X text 18 3099 -------------------- AUDIO FILTERS ------------------------ ; #X obj 24 3129 vcf~; #X text 124 3129 - voltage controlled filter; #X obj 24 3153 noise~; #X text 124 3153 - white noise generator; #X obj 24 3177 env~; #X text 124 3177 - envelope follower; #X obj 24 3201 hip~; #X text 124 3201 - high pass filter; #X obj 24 3225 lop~; #X text 124 3225 - low pass filter; #X obj 24 3249 bp~; #X text 124 3249 - band pass filter; #X obj 24 3273 biquad~; #X text 124 3273 - raw filter; #X obj 24 3297 samphold~; #X text 124 3297 - sample and hold unit; #X obj 24 3321 print~; #X text 124 3321 - print out one or more "blocks"; #X obj 24 3345 rpole~; #X text 124 3345 - raw real-valued one-pole filter; #X obj 24 3369 rzero~; #X text 124 3369 - raw real-valued one-zero filter; #X obj 24 3393 rzero_rev~; #X text 127 3393 - time-reversed; #X obj 24 3417 cpole~; #X obj 83 3417 czero~; #X text 220 3417 - corresponding complex-valued filters; #X text 18 3455 -------------------- AUDIO DELAY ------------------------ ; #X obj 24 3479 delwrite~; #X text 124 3479 - write to a delay line; #X obj 24 3503 delread~; #X text 124 3503 - read from a delay line; #X obj 24 3527 vd~; #X text 124 3527 - read from a delay line at a variable delay time ; #N canvas 0 50 450 300 (subpatch) 0; #X restore 24 3587 pd; #X text 124 3587 - define a subwindow; #X obj 25 1463 table; #X obj 24 3611 inlet; #X text 124 3611 - add an inlet to a pd; #X obj 24 3635 outlet; #X text 124 3635 - add an outlet to a pd; #X obj 24 3659 inlet~; #X obj 84 3659 outlet~; #X obj 24 3728 struct; #X text 124 3728 - define a data structure; #X obj 24 3752 drawcurve; #X obj 112 3752 filledcurve; #X text 225 3752 - draw a curve; #X obj 24 3776 drawpolygon; #X obj 129 3776 filledpolygon; #X text 259 3776 - draw a polygon; #X obj 24 3800 plot; #X text 124 3800 - plot an array field; #X obj 24 3824 drawnumber; #X text 124 3824 - print a numeric value; #X obj 25 3888 pointer; #X text 125 3888 - point to an object belonging to a template; #X obj 25 3912 get; #X text 125 3912 - get numeric fields; #X obj 25 3936 set; #X text 125 3936 - change numeric fields; #X obj 25 3960 element; #X text 125 3960 - get an array element; #X obj 25 3984 getsize; #X text 125 3984 - get the size of an array; #X obj 25 4008 setsize; #X text 125 4008 - change the size of an array; #X obj 25 4032 append; #X text 125 4032 - add an element to a list; #X obj 25 4056 scalar; #X text 130 4401 (use tabwrite~ now); #X obj 30 4426 namecanvas; #X obj 142 3417 czero_rev~; #X obj 26 2498 threshold~; #X text 126 2498 - detect signal thresholds; #X text 21 1943 ---------------------- AUDIO MATH ----------------------- ; #X text 18 1520 --------------------- MISC ----------------------; #X text 20 831 ------------------------- MATH -----------------; #X text 20 630 ------------------------- TIME -------------------------- ; #X text 18 3558 ------------------------ SUBWINDOWS ------------------------ ; #X text 18 3698 ---------------------- DATA TEMPLATES ---------------------- ; #X text 18 3858 ---------------------- ACCESSING DATA ---------------------- ; #X text 17 2818 ------------ AUDIO OSCILLATORS AND TABLES ------------- ; #X obj 67 2003 min~; #X obj 26 2003 max~; #X obj 22 884 ==; #X obj 54 884 !=; #X obj 86 884 >; #X obj 118 884 <; #X obj 149 884 >=; #X obj 180 884 <=; #X text 26 4376 ------------------------ OBSOLETE -------------------------- ; #X obj 54 861 -; #X obj 87 861 *; #X obj 119 861 /; #X obj 152 861 pow; #X obj 22 861 +; #X obj 22 907 &; #X obj 54 907 &&; #X obj 86 907 |; #X obj 118 907 ||; #X obj 149 907 %; #X obj 26 1973 +~; #X obj 58 1973 -~; #X obj 89 1973 *~; #X obj 121 1973 /~; #X obj 25 1912 declare; #X text 125 1912 - set search path and/or load libraries; #X text 162 3660 - signal versions; #X obj 22 1094 wrap; #X text 121 1094 - wrap a number to range [0 \, 1); #X text 126 2132 - wraparound (fractional part); #X obj 25 2264 pow~; #X obj 69 2264 log~; #X obj 113 2264 exp~; #X text 207 2266 - math; #X obj 159 2265 abs~; #X text 24 120 --------------- GENERAL ----------------; #X obj 24 607 list; #X text 124 607 - manipulate lists; #X text 112 1249 - schedule delayed "note off" message for a note-on ; #X obj 25 1487 array; #X text 127 1462 - create a named table; #X text 26 2347 ------------- GENERAL AUDIO MANIPULATION -------------- ; #X text 125 1706 - general text handling; #X text 128 1489 - general array creation and manipulation; #X text 17 1343 ----------------- ARRAYS/TABLES ------------------- ; #X text 125 4055 - create a single scalar; #X text 129 4427 (potentially dangerous but no substitute exists yet) ; #X text 23 22 The following is a list of built-in objects in Pd. (Not included in this list are messages \, atoms \, graphs \, etc. which aren't typed into object boxes but come straight off the "add" menu.) Right-click (or control-click on a Macintosh) on any object to get its "help window".; #X msg 30 4399 scope~; #X msg 30 4451 template; #X text 129 4452 (use struct now); #X obj 25 1682 textfile; #X obj 25 1706 text; #X obj 180 907 <<; #X obj 211 907 >>; #X obj 26 2106 sqrt~; #X text 127 2108 - proper square root; #X text 17 1115 ------------------- MIDI and OSC------------------------ ; #X obj 22 1302 oscparse; #X obj 21 1326 oscformat; #X text 113 1303 - OSC messages to Pd lists; #X text 113 1326 - Pd lists to OSC messages; #X text 18 4087 -------- "EXTRA" (patches and externs in pd/extra) ---------; #X obj 26 4116 sigmund~; #X text 126 4116 - pitch tracker; #X obj 26 4141 bonk~; #X text 126 4141 - attack detector; #X obj 26 4166 choice; #X text 126 4166 - best match of list to templates; #X obj 26 4190 hilbert~; #X obj 104 4190 complex-mod~; #X text 218 4191 - phase quadrature / frequency shifting; #X text 195 4217 - C-style expressions (control and signal); #X obj 76 4216 expr~; #X obj 26 4215 expr; #X obj 129 4216 fexpr~; #X obj 26 4242 loop~; #X text 122 4245 - phasor~ with S/H on its frequency input; #X obj 26 4267 lrshift~; #X text 122 4270 - left and right shift (useful with FFT objects); #X obj 27 4293 pd~; #X text 124 4291 - run another copy of Pd (for multiprocessing); #X obj 27 4320 rev1~; #X obj 79 4320 rev2~; #X obj 128 4320 rev3~; #X text 188 4320 - reverberators; #X obj 60 4293 stdout; #X obj 27 4347 bob~; #X text 123 4349 - Moog resonant filter model; pd-0.46-7/doc/5.reference/qlist-help.pd0000664000175000017500000000614512160204055015652 0ustar mspmsp#N canvas 7 31 1178 587 12; #X obj 546 328 qlist; #X msg 592 110 rewind; #X msg 591 135 next; #X floatatom 546 382 0 0 0 0 - - -; #X msg 593 54 bang; #X obj 441 515 r this; #X obj 544 515 r that; #X obj 441 544 print this; #X obj 544 544 print that; #X obj 560 356 print done; #X msg 593 80 tempo 1; #X text 18 51 The qlist object reads text files containing time-tagged Pd messages. You can have them sequenced automatically (by sending a "bang" message \, possibly changing speed via "tempo" messages) or manually via the "rewind" and "next" messages.; #X text 15 136 To run the qlist automatically \, send it a "read" message (the filename is relative to the directory the patch is in) and later a "bang." Messages in the file are separated by semicolons. Optional leading numbers are delay times in milliseconds. If the tempo is diffrerent from 1 the messages are sent faster or slower accordingly. Messages should start with a symbol giving the destination object. In the file "qlist.q" used here \, the messages go to objects "this" and "that" which are receives below.; #X text 17 281 To run it manually \, send "rewind" followed by "next". All messages not preceeded by numbers are sent. As soon as a message starting with one or more numbers is encountered \, the numbers are output as a list. There are many ways you could design a sequencer around this.; #X text 668 48 sequence automatically; #X text 670 79 set relative tempo; #X text 668 105 go to beginning (and stop); #X text 668 132 single-step forward; #X text 713 273 read a file; #X text 777 300 write one; #X text 552 404 This outlet gets a list of leading numbers for the next message \, for you to use in designing your own sequencer.; #X msg 586 274 read qlist.txt; #X msg 586 300 write /tmp/qlist.txt; #X text 21 493 see also:; #X obj 97 493 textfile; #X text 22 362 You can also record textual messages and save them to a file. Send "clear" to empty the qlist and "add" to add messages (terminated with semicolons.) The message \, "add2" adds a list of atoms without finishing with a semicolon in case you want to make variable-length messages.; #X msg 589 190 clear; #X msg 589 216 add 500 this is another message; #X msg 590 242 add2 that; #X text 666 187 empty the qlist; #X text 882 217 add a message to a qlist; #X text 683 240 add a message to a qlist but don't terminate it; #X text 653 341 This outlet gets a bang when you hit the end of the sequence. In the file "qlist.txt" the end is delayed 1000 milliseconds after the last message.; #X text 379 470 These receives are invoked in the file "qlist.txt" in this directory.; #X obj 71 13 qlist; #X text 132 15 - text-based sequencer; #X text 668 158 single-step forward SUPRESSING MESSAGE-SENDING; #X msg 591 161 next 1; #X text 921 558 updated for Pd version 0.35; #X msg 593 29 print; #X text 667 28 print contents to Pd window; #X connect 0 0 3 0; #X connect 0 1 9 0; #X connect 1 0 0 0; #X connect 2 0 0 0; #X connect 4 0 0 0; #X connect 5 0 7 0; #X connect 6 0 8 0; #X connect 10 0 0 0; #X connect 21 0 0 0; #X connect 22 0 0 0; #X connect 26 0 0 0; #X connect 27 0 0 0; #X connect 28 0 0 0; #X connect 37 0 0 0; #X connect 39 0 0 0; pd-0.46-7/doc/5.reference/array-object-help.pd0000664000175000017500000004104612572421664017115 0ustar mspmsp#N struct array-help-struct float x float y array z float; #N struct float float y; #N struct array-help-struct2 float x float y array z element-struct2 ; #N struct element-struct2 float x float y float w; #N canvas 309 129 694 542 12; #X obj 208 496 list; #X text 34 496 see also:; #X text 485 171 (click for details:), f 11; #N canvas 844 217 900 716 define 0; #X text 295 562 creation arguments:; #X text 325 597 optional name; #X text 322 164 read from a file; #X text 324 195 write to a file; #X text 32 20 "array define" maintains an array and can name it so that other objects can find it (and later should have some alternative \, anonymous way to be found).; #X text 324 614 optional size (100 by default); #X msg 35 138 const 0; #X text 325 138 set to a constant (0 \, for instance); #X msg 45 167 read array-object-help.txt; #X msg 45 194 write array-object-help.txt; #X obj 36 596 array define array-help-1; #X msg 45 224 resize 100; #X text 71 255 ... other messages are also forwarded to the array like those above - xticks \, etc \, and also lists to set values.; #X obj 154 412 r array-help-send; #X text 221 313 send a pointer to a named receive object; #X floatatom 154 460 5 0 0 0 - - -, f 5; #X obj 364 407 r array-help-send; #X floatatom 364 481 5 0 0 0 - - -, f 5; #X text 46 570 click to open or edit array:; #X obj 364 431 t b p; #X obj 154 436 getsize float-array z; #X obj 364 456 array size -s float-array z; #X text 109 349 The pointer will be to a structure float-array and the array itself will be the field named 'z' \, so that you can access it as shown in these examples:; #X obj 38 659 array define -k array-help-2 10; #A 0 -0.320006 0 0 0 0.973333 0 0 0 0 0; #X msg 49 313 send array-help-send; #X text 323 580 optional -k flag to keep contents; #X connect 6 0 10 0; #X connect 8 0 10 0; #X connect 9 0 10 0; #X connect 11 0 10 0; #X connect 13 0 20 0; #X connect 16 0 19 0; #X connect 19 0 21 0; #X connect 19 1 21 1; #X connect 20 0 15 0; #X connect 21 0 17 0; #X connect 24 0 10 0; #X restore 486 212 pd define; #X obj 112 496 text; #X obj 90 236 array size; #N canvas 0 50 600 400 (subpatch) 0; #N canvas 0 50 450 250 (subpatch) 0; #X coords 0 1 99 -1 500 300 1; #X restore 50 50 graph; #X restore 18 6 array; #X text 193 210 - create \, store \, and/or edit one; #X text 193 237 - get or change size; #X text 194 261 - sum all or a range of elements; #N canvas 624 95 689 679 array-and-data-structures 0; #X obj 98 247 pointer; #N canvas 804 396 504 278 array-help-struct 0; #X scalar array-help-struct 20 20 \; 0 \; 0 \; -1 \; -6 \; -9 \; -10 \; -5 \; -2 \; 8 \; 12 \; 12 \; 12 \; 10 \; 8 \; 6 \; 1 \; \;; #X obj 88 204 pointer; #X msg 32 156 20 20; #X obj 31 231 append array-help-struct x y; #X msg 88 147 traverse pd-array-help-struct \, bang, f 21; #X obj 13 83 filledpolygon 0 0 0 0 0 0 10 20 10 20 0 0 0; #X obj 13 56 struct array-help-struct float x float y array z float ; #X obj 17 114 plot z 500 2 25 5 5; #X connect 1 0 3 2; #X connect 2 0 3 0; #X connect 4 0 1 0; #X restore 289 159 pd array-help-struct; #N canvas 1207 234 450 300 array-help-data 0; #X scalar array-help-struct 84 93 \; 0 \; 0 \; -1 \; -6 \; -9 \; -10 \; -5 \; -2 \; 5 \; -7 \; -41 \; -47 \; -45 \; -34 \; -17 \; 8 \; 5 \; 2 \; -2 \; -11 \; -16 \; -26 \; -43 \; 16 \; 24 \; 26 \; 21 \; 20 \; 19 \; 17 \; 16 \; 16 \; 16 \; 16 \; 12 \; \;; #X text 26 215 We have one datum... right-click to see contents.; #X restore 290 189 pd array-help-data; #X msg 98 190 traverse pd-array-help-data \, next, f 19; #X obj 61 139 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 61 161 t b b; #X obj 61 286 array sum -s array-help-struct z, f 19; #X floatatom 61 327 5 0 0 0 - - -, f 5; #X text 449 190 <- the array; #X text 460 161 <- the structure; #X text 56 21 The array objects can also reference arrays within structures via pointers. The "-s" flag takes two arguments \, specifying the data structure and the field within it that will contain the array. By default the array should be a simple floating point array (use hte template "float" for the array elements) but you can override that using "-f" as shown further down.; #X obj 115 549 pointer; #X obj 78 441 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X obj 78 463 t b b; #X floatatom 78 629 5 0 0 0 - - -, f 5; #X text 466 518 <- the array; #N canvas 1063 375 447 373 array-help-struct2 0; #X obj 95 252 pointer; #X msg 39 204 20 20; #X obj 13 94 filledpolygon 0 0 0 0 0 0 10 20 10 20 0 0 0; #X obj 13 56 struct array-help-struct2 float x float y array z element-struct2 ; #X msg 95 195 traverse pd-array-help-struct2 \, bang, f 22; #X obj 38 279 append array-help-struct2 x y; #X obj 16 120 plot z 500 2 25 5; #X connect 0 0 5 2; #X connect 1 0 5 0; #X connect 4 0 0 0; #X restore 306 461 pd array-help-struct2; #N canvas 1028 171 477 318 array-help-data2 0; #X scalar array-help-struct2 80 30 \; -54 200 10 \; 138 -10 3 \; -32 26 0 \; 109 141 8 \; 272 19 0 \; \;; #X text 31 267 A structure whose array has (x \, y \, w) triples - right-click to see contents., f 40; #X restore 307 517 pd array-help-data2; #X msg 115 492 traverse pd-array-help-data2 \, next, f 20; #X text 484 461 <- main structure, f 30; #X text 484 486 <- element structure, f 30; #N canvas 1103 205 413 178 element-struct2 0; #X obj 13 56 struct element-struct2 float x float y float w; #X restore 306 486 pd element-struct2; #X obj 78 588 array sum -s array-help-struct2 z -f element-struct2 w, f 33; #X text 58 366 Using an additional '-f' flag we can specify which field in the array we're referring to. In this example the array has (x \, y \, w) triples (struct element-struct2) and we're asking for the "w" field using the "-f" flag and its two arguments.; #X text 128 629 sum of all the 'w' values in the array; #X text 225 267 when "-s" is given this inlet takes a pointer in place of a name., f 35; #X connect 0 0 6 2; #X connect 3 0 0 0; #X connect 4 0 5 0; #X connect 5 0 6 0; #X connect 5 1 3 0; #X connect 6 0 7 0; #X connect 11 0 22 2; #X connect 12 0 13 0; #X connect 13 0 22 0; #X connect 13 1 18 0; #X connect 18 0 11 0; #X connect 22 0 14 0; #X restore 87 456 pd array-and-data-structures; #N canvas 771 174 751 261 size 0; #X floatatom 26 95 5 1 100 0 - - -, f 5; #X obj 25 200 print; #X text 45 19 "array size" outputs the size (if sent a bang) or sets the size (if sent a number).; #X obj 25 171 array size array-help-2; #X obj 35 122 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X text 226 169 creations arguments: either array name or "-s" and optional "-f" flags to refer to an array in a data structure; #X msg 249 137 symbol array-help-2; #X text 414 110 inlet to set name or pointer; #X text 74 94 number to set size; #X text 59 121 bang outputs size; #X msg 248 113 symbol array-help-1; #X connect 0 0 3 0; #X connect 3 0 1 0; #X connect 4 0 3 0; #X connect 6 0 3 1; #X connect 10 0 3 1; #X restore 486 236 pd size; #X obj 90 212 array define; #X text 84 432 accessing arrays inside data structures:; #X text 65 6 - accessing arrays; #X text 50 43 In Pd an array may be part of a "garray" (a graphical array of numbers) or appear as a slot in a data structure (in which case the elements may be arbitrary data \, not necessarily just numbers). The "array" object can define an array (so far just of numbers but maybe later arbitrary data structures) or access an array defined elsewhere to get or change its size \, set or read its elements \, and so on. ; #X text 93 183 The first argument sets its function:; #X obj 153 496 scalar; #X obj 90 260 array sum; #X obj 90 332 array quantile; #N canvas 791 201 776 362 sum 0; #X floatatom 74 135 5 0 10 0 - - -, f 5; #X obj 65 114 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X floatatom 65 268 5 0 0 0 - - -, f 5; #X floatatom 111 162 5 -1 10 0 - - -, f 5; #X text 45 19 "array sum" outputs the sum of all or a selected range of elements of the array.; #X obj 65 223 array sum array-help-2, f 12; #X text 183 262 - optional number to initialize onset - default 0; #X text 183 281 - optional number to initialize number of points - default -1, f 61; #X text 91 112 bang to output sum; #X text 184 226 creation arguments: either array name or "-s" and optional "-f" flags to refer to an array in a data structure; #X text 124 131 onset (first index to sum from) \, zero for start of array; #X text 159 157 number of points or -1 for end of array; #X text 65 328 (array-help-2 is defined in the "define" subwindow). ; #X msg 158 189 symbol array-help-2; #X text 322 188 set name or pointer; #X connect 0 0 5 0; #X connect 1 0 5 0; #X connect 3 0 5 1; #X connect 5 0 2 0; #X connect 13 0 5 2; #X restore 486 260 pd sum; #X obj 90 284 array get; #N canvas 342 597 805 335 get 0; #X floatatom 135 103 5 0 10 0 - - -, f 5; #X obj 118 78 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X floatatom 165 126 5 -1 10 0 - - -, f 5; #X obj 119 185 array get array-help-2, f 12; #X obj 119 226 print; #X text 45 19 "array get" outputs all or a selected range of elements of the array as a list.; #X text 276 238 - optional number to initialize onset - default 0; #X text 275 257 - optional number to initialize number of points - default -1, f 61; #X text 280 201 creation arguments: either array name or "-s" and optional "-f" flags to refer to an array in a data structure; #X text 212 128 number of points or -1 for end of array; #X text 140 78 bang for output; #X text 65 298 (array-help-2 is defined in the "define" subwindow). ; #X msg 212 155 symbol array-help-2; #X text 376 154 set name or pointer; #X text 181 102 onset (first index to output) \, zero for start of array; #X connect 0 0 3 0; #X connect 1 0 3 0; #X connect 2 0 3 1; #X connect 3 0 4 0; #X connect 12 0 3 2; #X restore 486 284 pd get; #X obj 90 308 array set; #N canvas 525 369 752 328 set 0; #X obj 119 203 array set array-help-2, f 12; #X msg 119 117 0.1 0.2 0.3 0.4 0.3 0.2 0.1; #X text 45 19 "array set" sets values of an array from an incoming list \, starting from a specified onset (0 by default). The size of the array is not changed -- values that would be written past the end of the array are dropped.; #X floatatom 165 143 5 0 0 0 - - -, f 5; #X text 215 141 onset (first index to write to); #X text 252 244 - optional number to initialize onset - default 0; #X text 256 207 creation arguments: either array name or "-s" and optional "-f" flags to refer to an array in a data structure; #X text 349 118 list of values to write to array; #X text 56 265 (array-help-2 is defined in the "define" subwindow). ; #X msg 212 170 symbol array-help-2; #X text 376 169 set name or pointer; #X connect 1 0 0 0; #X connect 3 0 0 1; #X connect 9 0 0 2; #X restore 486 308 pd set; #X text 194 285 - get contents as a list; #X text 194 309 - set contents from a list; #X text 212 333 - get a quantile; #X obj 90 356 array random; #N canvas 102 243 816 629 quantile+random 0; #X floatatom 75 177 5 0 100 0 - - -, f 5; #X obj 39 251 array quantile array-help-3, f 14; #N canvas 0 50 450 250 (subpatch) 0; #X array array-help-3 100 float 3; #A 0 0 0 0 0 0 0 0 0 0 0 0 0.00715053 0.00715053 0.0285789 0.0500072 0.0714356 0.100007 0.128578 0.164292 0.207148 0.478574 0.628573 0.678572 0.721429 0.717857 0.714286 0.707143 0.7 0.692857 0.685715 0.678572 0.18572 0.164292 0.157149 0.0142931 -0.00713521 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.014293 0.0214357 0.0357213 0.078578 0.142863 0.207148 0.335718 0.407146 0.435717 0.478574 0.514288 0.557144 0.592858 0.642858 0.7 0.692857 0.692857 0.692857 0.692857 0.7 0.696429 0.349997 0.335712 0.321426 0.278569 0.192856 0.149999 0.135714 0.114285 0.0999998 0.0714298 0.0642871 0.0571443 0.0285732 0 0 0 0 0; #X coords 0 1 99 0 200 140 1 0 0; #X restore 37 375 graph; #X floatatom 111 198 5 -1 100 0 - - -, f 5; #X msg 43 524 \; array-help-3 const 0; #X floatatom 39 131 5 -1 100 0 - - -, f 5; #X obj 39 152 / 100; #X floatatom 39 295 5 0 100 0 - - -, f 5; #X floatatom 368 599 5 0 100 0 - - -, f 5; #X obj 370 555 array random array-help-3, f 13; #X obj 370 435 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X floatatom 383 484 5 0 0 0 - - -, f 5; #X floatatom 420 507 5 0 0 0 - - -, f 5; #X text 303 358 "array random" makes a pseudo-random numbver from 0 to 1 and outputs its quantile (which will therefore have probabilities proportional to the table's values.); #X text 394 430 bang to generate a random value; #X msg 377 456 seed 56; #X text 445 456 set random seed; #X text 170 286 - optional number to initialize onset - default 0; #X text 169 305 - optional number to initialize number of points - default -1, f 61; #X text 494 569 same creation arguments; #X text 174 249 creation arguments: either array name or "-s" and optional "-f" flags to refer to an array in a data structure; #X text 120 174 onset (first index to sum from) \, zero for start of array; #X text 160 196 number of points or -1 for end of array; #X text 130 5 "array quantile" outputs the specified quantile of the array - so for instance \, the 0.5 quantile is the median of the array. This generalizes the "array random" function allowing you to use the same source of randomness on several arrays \, for example. Negative numbers in the array are silently replaced by zero. Quantiles outside the range 0-1 output the x values at the two extremes of the array (0 and 99 here).; #X text 428 481 onset; #X text 466 505 number of points; #X text 88 130 quantile (between 0 and 1); #X msg 149 218 symbol array-help-2; #X text 313 217 set name or pointer; #X msg 471 529 symbol array-help-2; #X text 635 528 set name or pointer; #X connect 0 0 1 1; #X connect 1 0 7 0; #X connect 3 0 1 2; #X connect 5 0 6 0; #X connect 6 0 1 0; #X connect 9 0 8 0; #X connect 10 0 9 0; #X connect 11 0 9 0; #X connect 12 0 9 1; #X connect 15 0 9 0; #X connect 27 0 1 3; #X connect 29 0 9 2; #X restore 485 346 pd quantile+random; #X text 195 356 - random - array as probabilities; #X text 444 471 updated for Pd version 0.45; #X obj 90 379 array max; #N canvas 727 168 744 595 min+max 0; #N canvas 0 50 450 250 (subpatch) 0; #X array array-help-4 100 float 3; #A 0 0.335714 0.37857 0.421427 0.442855 0.478569 0.521426 0.535711 0.55714 0.585711 0.599997 0.614282 0.63571 0.649996 0.664282 0.671424 0.699995 0.699995 0.714281 0.721424 0.707138 0.699995 0.692853 0.68571 0.671424 0.649996 0.628568 0.599997 0.571425 0.514283 0.471426 0.414284 0.385713 0.357142 0.328571 0.3 0.285714 0.271429 0.25 0.228572 0.214286 0.207143 0.200001 0.185715 0.17143 0.164287 0.157144 0.150001 0.135716 0.128573 0.12143 0.12143 0.114287 0.114287 0.114287 0.114287 0.114287 0.12143 0.125001 0.128573 0.128573 0.135716 0.139287 0.142858 0.150001 0.157144 0.157144 0.164287 0.17143 0.200001 0.214286 0.228572 0.235715 0.242857 0.257143 0.271429 0.285714 0.307142 0.321428 0.335714 0.357142 0.371427 0.385713 0.399999 0.407141 0.414284 0.421427 0.42857 0.435713 0.442855 0.457141 0.460712 0.464284 0.471426 0.478569 0.485712 0.499998 0.50714 0.514283 0.521426 0.528569; #X coords 0 1 99 0 200 140 1 0 0; #X restore 382 386 graph; #X floatatom 55 275 7 0 100 0 - - -, f 7; #X obj 57 136 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X floatatom 70 159 5 0 0 0 - - -, f 5; #X floatatom 107 182 5 0 0 0 - - -, f 5; #X text 179 264 - optional number to initialize onset - default 0; #X text 178 283 - optional number to initialize number of points - default -1, f 61; #X text 173 229 creation arguments: either array name or "-s" and optional "-f" flags to refer to an array in a data structure; #X text 115 156 onset; #X text 153 180 number of points; #X msg 158 204 symbol array-help-2; #X text 322 205 set name or pointer; #X obj 57 230 array max array-help-4, f 13; #X floatatom 123 275 5 0 100 0 - - -, f 5; #X text 79 133 bang to find maximum; #X text 130 5 "array max" and "array min" find the maximum and minimum values in the array \, respectively. The first outlet is the value and the second is the index (the x location where the value was found). The search may be restricted to a sub-domain of the array by specifying the "onset" and "number of points".; #X floatatom 52 497 7 0 100 0 - - -, f 7; #X obj 54 358 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X floatatom 67 381 5 0 0 0 - - -, f 5; #X floatatom 104 404 5 0 0 0 - - -, f 5; #X text 112 378 onset; #X floatatom 120 497 5 0 100 0 - - -, f 5; #X text 76 355 bang to find minimum; #X text 153 402 number of points; #X obj 54 452 array min array-help-4, f 13; #X text 54 298 value; #X text 118 299 index; #X connect 2 0 12 0; #X connect 3 0 12 0; #X connect 4 0 12 1; #X connect 10 0 12 2; #X connect 12 0 1 0; #X connect 12 1 13 0; #X connect 17 0 24 0; #X connect 18 0 24 0; #X connect 19 0 24 1; #X connect 24 0 16 0; #X connect 24 1 21 0; #X restore 480 392 pd min+max; #X obj 90 402 array min; #X text 194 403 - min - find lowest value; #X text 193 384 - max - find highest value; pd-0.46-7/doc/5.reference/vdial-help.pd0000664000175000017500000001645312160204055015620 0ustar mspmsp#N canvas 106 314 558 455 10; #X obj 1 1 cnv 8 100 60 empty empty vdial=vdl 20 20 1 18 -262144 -1109 0; #X text 13 390 (c) musil@iem.kug.ac.at; #X text 55 403 IEM KUG; #X text 132 122 click properties to; #X text 120 133 modify geometry \, colors \, etc.; #X obj 159 261 bng 15 250 50 0 empty empty empty 8 -8 0 10 -262144 -1 -1; #X obj 21 54 bng 15 250 50 0 empty empty empty 8 -8 0 10 -262144 -1 -1; #X msg 41 319 \$1; #X floatatom 41 341 4 0 0; #X obj 41 363 bng 15 250 50 0 empty empty empty 8 -8 0 10 -262144 -1 -1; #X obj 86 338 tgl 12 0 empty empty empty 8 -8 0 10 -262144 -1 -1 0 1; #X obj 86 317 route 0 1 2 3 4 5 6 7 8 9; #X msg 194 92 set \$1; #X floatatom 194 71 4 0 9; #X floatatom 44 54 4 0 9; #X msg 91 41 7 0 -5.44; #X msg 95 63 3 3 4.55; #X obj 103 338 tgl 12 0 empty empty empty 8 -8 0 10 -262144 -1 -1 0 1; #X obj 120 338 tgl 12 0 empty empty empty 8 -8 0 10 -262144 -1 -1 1 1; #X obj 137 338 tgl 12 0 empty empty empty 8 -8 0 10 -262144 -1 -1 0 1; #X obj 154 338 tgl 12 0 empty empty empty 8 -8 0 10 -262144 -1 -1 0 1; #X obj 171 338 tgl 12 0 empty empty empty 8 -8 0 10 -262144 -1 -1 0 1; #X obj 188 338 tgl 12 0 empty empty empty 8 -8 0 10 -262144 -1 -1 0 1; #X obj 205 338 tgl 12 0 empty empty empty 8 -8 0 10 -262144 -1 -1 0 1; #X obj 222 338 tgl 12 0 empty empty empty 8 -8 0 10 -262144 -1 -1 0 1; #X obj 239 338 tgl 12 0 empty empty empty 8 -8 0 10 -262144 -1 -1 0 1; #X obj 79 355 print; #X floatatom 183 287 4 0 0; #X msg 183 261 \$1; #X msg 158 192 set \$1; #X floatatom 158 171 4 0 9; #X text 125 355 UP- \, DOWN- \, LEFT- or RIGHT-key; #X text 124 366 for moving selected gui-objects; #N canvas 230 247 699 530 edit 0; #X obj 42 198 f; #X msg 20 177 bang; #X floatatom 58 176 3 63 156; #X floatatom 93 198 3 -20 37; #X obj 42 221 pack 0 0; #X text 120 198 y-label; #X text 86 176 x-label; #X floatatom 270 187 3 8 50; #X text 297 187 size; #X obj 286 293 f; #X msg 264 272 bang; #X floatatom 302 271 3 -10 10; #X floatatom 337 293 3 -10 10; #X obj 286 316 pack 0 0; #X obj 300 412 f; #X msg 278 391 bang; #X floatatom 316 390 3 20 60; #X floatatom 351 412 3 100 200; #X obj 300 435 pack 0 0; #X text 330 271 x-delta; #X text 364 293 y-delta; #X text 344 390 x-position; #X text 378 412 y-position; #X obj 62 313 f; #X msg 40 292 bang; #X floatatom 78 291 3 0 2; #X floatatom 113 313 3 4 36; #X obj 62 336 pack 0 0; #X text 106 291 font; #X text 142 313 height; #X text 504 293 no init; #X text 475 348 init value on loadbang; #X floatatom 482 228 5 2 20; #X text 491 417 changing-behavior; #X text 526 228 number of buttons; #X obj 47 104 pack 0 0 0; #X obj 47 76 f; #X msg 24 28 bang; #X floatatom 63 26 3 0 29; #X floatatom 79 46 3 0 29; #X floatatom 112 62 3 0 29; #X text 91 26 background; #X text 106 46 front-color; #X text 140 63 label-color; #X msg 285 25 back; #X msg 285 45 front; #X msg 285 65 label; #X msg 247 25 bang; #N canvas 15 207 606 448 RGB_____________ 0; #X obj 97 56 inlet; #X obj 262 53 inlet; #X obj 339 55 inlet; #X obj 405 56 inlet; #X obj 97 270 bang; #X msg 77 295 0; #X msg 104 295 1; #X obj 146 268 bang; #X msg 132 295 0; #X msg 160 295 1; #X obj 196 269 bang; #X msg 187 295 0; #X msg 214 295 1; #X obj 265 313 spigot; #X obj 312 313 spigot; #X obj 359 313 spigot; #X obj 249 385 outlet; #X text 93 33 select; #X text 267 28 red; #X text 337 30 green; #X text 409 30 blue; #X obj 405 102 t b f; #X obj 339 160 +; #X obj 339 185 t b f; #X obj 339 216 +; #X obj 296 385 outlet; #X obj 343 385 outlet; #X obj 28 180 loadbang; #X obj 97 135 route back front label bang; #X obj 343 362 f; #X obj 296 361 f; #X obj 249 361 f; #X obj 262 79 * -65536; #X obj 339 80 * -256; #X obj 405 80 * -1; #X obj 339 247 - 1; #X obj 235 168 t b b b b; #X connect 0 0 28 0; #X connect 1 0 32 0; #X connect 2 0 33 0; #X connect 3 0 34 0; #X connect 4 0 5 0; #X connect 4 0 6 0; #X connect 5 0 14 1; #X connect 5 0 15 1; #X connect 6 0 13 1; #X connect 7 0 8 0; #X connect 7 0 9 0; #X connect 8 0 13 1; #X connect 8 0 15 1; #X connect 9 0 14 1; #X connect 10 0 11 0; #X connect 10 0 12 0; #X connect 11 0 13 1; #X connect 11 0 14 1; #X connect 12 0 15 1; #X connect 13 0 31 1; #X connect 14 0 30 1; #X connect 15 0 29 1; #X connect 21 0 22 0; #X connect 21 1 22 1; #X connect 22 0 23 0; #X connect 23 0 24 0; #X connect 23 1 24 1; #X connect 24 0 35 0; #X connect 27 0 6 0; #X connect 28 0 4 0; #X connect 28 1 7 0; #X connect 28 2 10 0; #X connect 28 3 36 0; #X connect 29 0 26 0; #X connect 30 0 25 0; #X connect 31 0 16 0; #X connect 32 0 24 0; #X connect 33 0 22 0; #X connect 34 0 21 0; #X connect 35 0 15 0; #X connect 35 0 14 0; #X connect 35 0 13 0; #X connect 36 0 31 0; #X connect 36 1 30 0; #X connect 36 2 29 0; #X connect 36 3 35 0; #X restore 285 86 pd RGB_____________; #X floatatom 327 55 3 0 255; #X floatatom 370 55 3 0 255; #X floatatom 413 56 3 0 255; #X text 34 0 preset-colors; #X text 296 -3 RGB-colors; #X text 327 37 red; #X text 363 36 green; #X text 411 36 blue; #X msg 47 125 \; foo12_rcv color \$1 \$2 \$3; #X msg 42 246 \; foo12_rcv label_pos \$1 \$2; #X msg 62 361 \; foo12_rcv label_font \$1 \$2; #X msg 34 423 \; foo12_rcv label blabla; #X msg 34 459 \; foo12_rcv label vdial_0_9; #X msg 300 460 \; foo12_rcv pos \$1 \$2; #X msg 286 341 \; foo12_rcv delta \$1 \$2; #X msg 270 216 \; foo12_rcv size \$1; #X msg 483 50 \; foo12_rcv send foo12a_snd; #X msg 483 88 \; foo12_rcv send foo12_snd; #X msg 482 171 \; foo12a_rcv receive foo12_rcv; #X msg 483 133 \; foo12_rcv receive foo12a_rcv; #X msg 482 254 \; foo12_rcv number \$1; #X msg 483 312 \; foo12_rcv init 0; #X msg 485 366 \; foo12_rcv init 1; #X msg 490 436 \; foo12_rcv single_change; #X msg 490 470 \; foo12_rcv double_change; #X connect 0 0 4 0; #X connect 1 0 0 0; #X connect 2 0 0 1; #X connect 3 0 4 1; #X connect 4 0 58 0; #X connect 7 0 64 0; #X connect 9 0 13 0; #X connect 10 0 9 0; #X connect 11 0 9 1; #X connect 12 0 13 1; #X connect 13 0 63 0; #X connect 14 0 18 0; #X connect 15 0 14 0; #X connect 16 0 14 1; #X connect 17 0 18 1; #X connect 18 0 62 0; #X connect 23 0 27 0; #X connect 24 0 23 0; #X connect 25 0 23 1; #X connect 26 0 27 1; #X connect 27 0 59 0; #X connect 32 0 69 0; #X connect 35 0 57 0; #X connect 36 0 35 0; #X connect 37 0 36 0; #X connect 38 0 36 1; #X connect 39 0 35 1; #X connect 40 0 35 2; #X connect 44 0 48 0; #X connect 45 0 48 0; #X connect 46 0 48 0; #X connect 47 0 48 0; #X connect 48 0 35 0; #X connect 48 1 35 1; #X connect 48 2 35 2; #X connect 49 0 48 1; #X connect 50 0 48 2; #X connect 51 0 48 3; #X restore 267 222 pd edit; #X obj 221 11 x_all_guis aaa bbb ccc ddd eee fff ggg hhh iii; #X text 30 415 graz \, austria 2002; #X text 223 401 updated for Pd version 0.35; #X text 144 11 gui-vdial:; #X obj 79 110 vdl 25 1 0 8 foo12_snd foo12_rcv vdial_0_9 20 -8 192 10 -99865 -262144 -260818 0; #X obj 352 36 vdl 15 1 0 8 iii iii empty 20 8 192 8 -262144 -1 -1 0 ; #X obj 158 213 s foo12_rcv; #X obj 159 239 r foo12_snd; #X connect 6 0 38 0; #X connect 7 0 8 0; #X connect 8 0 9 0; #X connect 11 0 10 0; #X connect 11 1 17 0; #X connect 11 2 18 0; #X connect 11 3 19 0; #X connect 11 4 20 0; #X connect 11 5 21 0; #X connect 11 6 22 0; #X connect 11 7 23 0; #X connect 11 8 24 0; #X connect 11 9 25 0; #X connect 12 0 38 0; #X connect 13 0 12 0; #X connect 14 0 38 0; #X connect 15 0 38 0; #X connect 16 0 38 0; #X connect 28 0 27 0; #X connect 29 0 40 0; #X connect 30 0 29 0; #X connect 38 0 11 0; #X connect 38 0 26 0; #X connect 38 0 7 0; #X connect 41 0 5 0; #X connect 41 0 28 0; pd-0.46-7/doc/5.reference/vline~-help.pd0000664000175000017500000000313712160204055016027 0ustar mspmsp#N canvas 273 80 815 504 12; #X obj 55 458 snapshot~; #X floatatom 55 481 5 0 0 0 - - -; #X obj 65 431 metro 100; #X obj 65 406 r start; #X msg 550 21 \; pd dsp 1 \; start bang; #X msg 55 241 1 1000; #X msg 83 357 stop; #X msg 72 288 0; #X text 644 36 Click to start; #X text 639 94 Click to stop; #X text 207 457 see also:; #X obj 293 459 line; #X msg 550 75 \; pd dsp 0 \; start 0; #X text 561 465 updated for version 0.33; #X obj 339 459 line~; #X obj 21 7 vline~; #X text 85 7 - high-precision audio ramp generator; #X obj 55 383 vline~; #X text 15 44 The vline~ object \, like line~ \, generates linear ramps whose levels and timing are determined by messages you send it. The messages consist of a target value \, a time interval (zero if not supplied) \, and an initial delay (also zero if not supplied.) Ramps may start and stop between audio samples \, in which case the output is interpolated accordingly.; #X text 15 155 Any number of future ramps may be scheduled and vline~ will remember them and execute them in order. They must be specified in increasing order of initial delay however \, since a segment cancels all planned segments at any future time.; #X text 120 238 ramp up; #X msg 64 263 0 1000; #X text 127 266 ramp down; #X text 84 308 ramp up \, jump down \, ramp up again; #X msg 78 329 1 1000 \, 0 0 1000 \, 1 1000 1000; #X text 110 287 jump down; #X text 126 356 "stop" message freezes vline~ at its current value ; #X connect 0 0 1 0; #X connect 2 0 0 0; #X connect 3 0 2 0; #X connect 5 0 17 0; #X connect 6 0 17 0; #X connect 7 0 17 0; #X connect 17 0 0 0; #X connect 21 0 17 0; #X connect 24 0 17 0; pd-0.46-7/doc/4.data.structures/0000775000175000017500000000000012441377165014450 5ustar mspmsppd-0.46-7/doc/4.data.structures/osc-voice.pd0000664000175000017500000000332312160204055016646 0ustar mspmsp#N canvas 339 254 722 644 12; #X obj 261 279 element trace-template bazoo; #X obj 297 163 getsize trace-template bazoo; #X obj 429 466 line~; #X obj 342 6 inlet; #X obj 424 357 dbtorms; #X obj 260 437 mtof; #X obj 260 496 *~; #X obj 260 524 throw~ osc-sum; #X obj 185 163 f; #X obj 229 163 + 1; #X obj 262 240 moses; #X obj 261 319 get point-template y amp; #X obj 426 401 pack 0 30; #X obj 265 92 t b p; #X msg 203 138 0; #X obj 96 60 r osc-tick; #X msg 505 369 0; #X obj 507 341 r osc-stop; #X obj 519 161 get trace-template y; #X obj 261 357 +; #X msg 366 369 0; #X obj 260 466 osc~; #X obj 556 412 r osc-speed; #X obj 296 197 - 1; #X obj 125 318 >=; #X obj 125 342 sel 1; #X obj 342 32 route 1; #X obj 343 57 unpack 0 p; #X obj 136 384 f; #X text 162 385 track ID; #X obj 136 412 s osc-noteoff; #X text 394 3 on/off \, track-id \, pointer; #X text 61 434 when done \, send track id; #X text 59 449 back to poly object so it; #X text 58 466 can reuse us; #X connect 0 0 11 0; #X connect 1 0 23 0; #X connect 1 0 24 1; #X connect 2 0 6 1; #X connect 3 0 26 0; #X connect 4 0 12 0; #X connect 5 0 21 0; #X connect 6 0 7 0; #X connect 8 0 9 0; #X connect 8 0 10 0; #X connect 8 0 24 0; #X connect 9 0 8 1; #X connect 10 0 0 0; #X connect 10 1 20 0; #X connect 11 0 19 0; #X connect 11 1 4 0; #X connect 12 0 2 0; #X connect 13 0 14 0; #X connect 13 1 0 1; #X connect 13 1 1 0; #X connect 13 1 18 0; #X connect 14 0 8 1; #X connect 15 0 8 0; #X connect 16 0 12 0; #X connect 17 0 16 0; #X connect 18 0 19 1; #X connect 19 0 5 0; #X connect 20 0 12 0; #X connect 21 0 6 0; #X connect 22 0 12 1; #X connect 23 0 10 1; #X connect 24 0 25 0; #X connect 25 0 28 0; #X connect 26 0 27 0; #X connect 27 0 28 1; #X connect 27 1 13 0; #X connect 28 0 30 0; pd-0.46-7/doc/4.data.structures/output~.pd0000664000175000017500000000344212160204055016517 0ustar mspmsp#N canvas 0 0 757 616 12; #X obj 516 522 t b; #X obj 516 469 f; #X obj 516 547 f; #X msg 630 546 0; #X obj 516 499 moses 1; #X obj 630 518 t b f; #X obj 596 479 moses 1; #X obj 29 97 dbtorms; #X obj 85 170 inlet~; #X msg 278 300 \; pd dsp 1; #X obj 29 170 line~; #X obj 64 242 *~; #X obj 64 272 dac~; #X obj 29 127 pack 0 50; #X text 121 146 audio in; #X text 301 496 test if less than 1 -->; #X text 267 523 if true convert to bang -->; #X text 100 96 <-- convert from dB to linear units; #X floatatom 278 221 3 0 100 0 dB - -; #X obj 516 449 bng 15 250 50 0 empty empty mute -38 7 0 12 -262144 -1 -1; #X text 118 126 <-- make a ramp to avoid clicks or zipper noise; #X obj 148 170 inlet~; #X obj 154 241 *~; #X text 502 399 MUTE logic:; #X obj 278 193 r \$0-master-lvl; #X obj 516 573 s \$0-master-lvl; #X obj 293 247 s \$0-master-out; #X obj 29 71 r \$0-master-out; #X obj 596 450 r \$0-master-out; #X text 60 10 Level control abstraction \, used in many of the Pd example patches. The "level" and "mute" controls show up on the parent \, calling patch.; #X text 229 549 previous nonzero master-lvl -->; #X text 301 453 recall previous; #X text 301 471 value of master-lvl -->; #X text 16 310 automatically start DSP -->; #X obj 85 192 hip~ 3; #X obj 147 192 hip~ 3; #X connect 0 0 2 0; #X connect 1 0 4 0; #X connect 2 0 25 0; #X connect 3 0 25 0; #X connect 4 0 0 0; #X connect 4 1 5 0; #X connect 5 0 3 0; #X connect 6 1 2 1; #X connect 7 0 13 0; #X connect 8 0 34 0; #X connect 10 0 22 0; #X connect 10 0 11 0; #X connect 11 0 12 0; #X connect 13 0 10 0; #X connect 18 0 9 0; #X connect 18 0 26 0; #X connect 19 0 1 0; #X connect 21 0 35 0; #X connect 22 0 12 1; #X connect 24 0 18 0; #X connect 27 0 7 0; #X connect 28 0 1 1; #X connect 28 0 6 0; #X connect 34 0 11 1; #X connect 35 0 22 1; #X coords 0 0 1 1 65 55 1; pd-0.46-7/doc/4.data.structures/02.getting.data.pd0000664000175000017500000000604012160204055017547 0ustar mspmsp#N struct template2 float x float y float z float q float zz; #N canvas 138 2 630 580 12; #X text 345 543 updated for Pd version 0.32.; #N canvas 42 312 598 266 stuff 0; #X obj 353 159 pointer; #X obj 117 103 t b b b; #X msg 117 62 bang; #X obj 117 31 loadbang; #X text 163 62 click here to re-initialize; #X text 127 242 Explained later...; #X obj 28 208 append template2 x y z q; #X msg 353 101 \; pd-data2 clear; #X msg 353 137 traverse pd-data2 \, bang; #X msg 28 185 50 150 30 9 \, 200 100 -20 900 \, 100 100 -50 30; #X connect 0 0 6 4; #X connect 1 0 9 0; #X connect 1 1 8 0; #X connect 1 2 7 0; #X connect 2 0 1 0; #X connect 3 0 2 0; #X connect 8 0 0 0; #X connect 9 0 6 0; #X restore 506 310 pd stuff; #X text 506 242 subpatches:; #X obj 15 303 pointer; #X msg 27 271 next; #X text 75 301 <- object that outputs pointers to scalars; #N canvas 13 22 307 198 data2 1; #X scalar template2 50 150 30 9 0 \;; #X scalar template2 200 100 -20 900 0 \;; #X scalar template2 100 100 -50 30 0 \;; #X restore 506 265 pd data2; #N canvas 315 125 554 155 template2 1; #X text 13 79 The template for the two scalars \, as in the last patch ; #X obj 15 46 filledpolygon 244 q 5 0 0 20 z 40 0; #X obj 14 21 struct template2 float x float y float z float q; #X restore 506 288 pd template2; #X obj 15 355 get template2 x y z q; #X floatatom 15 384 5 0 0 0 - - -; #X floatatom 76 384 5 0 0 0 - - -; #X floatatom 137 384 5 0 0 0 - - -; #X floatatom 199 385 5 0 0 0 - - -; #X msg 15 246 traverse pd-data2; #X obj 59 330 print; #X text 111 331 <- this gets a bang when we reach the end; #X text 211 353 <- this takes incoming pointers; #X text 214 367 and outputs the values of x \, y \, z \, and q.; #X text 172 245 <- go to head of list (click first); #X text 68 273 <- output next item (click 4 times); #X text 14 5 The simplest thing you can do with a collection of scalars (a list) is to traverse it \, getting the numbers back out. This is done using two objects \, "pointer" which does the traversal \, and "get" which \, given a pointer to a scalar \, extracts numeric quantities from it.; #X text 14 85 You can send the "pointer" object a "traverse" message to point it to the head of the list. The argument "pd-data2" indicates the Pd window named "data2." The head of the list means \, not the first scalar in the list \, but the position before the first scalar \, which is a valid pointer in Pd but has no data or template.; #X text 14 180 The "next" message tells the "pointer" object to go to the next scalar in the list and output it. If there are no more \, "pointer" outputs a bang at right.; #X text 19 424 The "get" object takes a pointer \, checks that its template agrees with what "get" is expecting \, i.e. \, "template2" \, and if so outputs the values of x \, y \, z \, and q in the usual reverse order.; #X text 18 492 The pointer sent from "pointer" to "get" is an elementary Pd type on a level with "float" and "symbol".; #X connect 3 0 8 0; #X connect 3 1 14 0; #X connect 4 0 3 0; #X connect 8 0 9 0; #X connect 8 1 10 0; #X connect 8 2 11 0; #X connect 8 3 12 0; #X connect 13 0 3 0; pd-0.46-7/doc/4.data.structures/14.partialtracer.pd0000664000175000017500000036570212441432032020053 0ustar mspmsp#N struct peak-template float x float y float amp float ampreal float ampimag float used; #N struct trace-template float x float y float voiceno array bazoo point-template; #N struct point-template float y float amp; #N canvas 51 52 913 595 12; #X declare -path lib; #X floatatom 777 74 0 0 100 0 - - -; #N canvas 516 98 663 557 (subpatch) 0; #X obj 103 108 outlet; #X msg 101 80 set \$1; #X obj 103 57 r osc-amp; #X connect 1 0 0 0; #X connect 2 0 1 0; #X restore 777 52 pd; #X obj 777 100 s osc-amp; #X obj 121 511 pack 0 100; #X obj 122 533 line~; #X obj 121 489 dbtorms; #X obj 122 573 *~; #X floatatom 827 245 0 0 0 0 - - -; #X msg 668 269 0; #X floatatom 737 224 0 0 0 0 - - -; #X floatatom 838 290 0 0 0 0 - - -; #X floatatom 647 74 0 0 110 0 - - -; #N canvas 516 98 663 555 (subpatch) 0; #X obj 103 108 outlet; #X msg 101 80 set \$1; #X obj 103 57 r grain-amp; #X connect 1 0 0 0; #X connect 2 0 1 0; #X restore 647 51 pd; #N canvas 168 244 589 236 peak-template 0; #X obj 81 52 filledpolygon 3 3 3 0 0 0 amp 0 0; #X obj 74 10 struct peak-template float x float y float amp float ampreal float ampimag float used; #X restore 417 525 pd peak-template; #N canvas 0 50 600 386 peak-list 0; #X scalar peak-template 15.9467 330 -253.674 -0.0844134 0.146417 0 \;; #X scalar peak-template 8.09598 330 -245.031 -0.108977 0.0532605 0 \;; #X scalar peak-template 21.9063 330 -199.607 0.00667672 -0.0201446 0 \;; #X scalar peak-template 31.1714 330 -199.12 -0.0160738 -0.0132465 0 \;; #X scalar peak-template 37.8022 330 -186.266 0.0101767 -0.00762842 0 \;; #X scalar peak-template 45.3485 330 -173.243 0.00456202 0.00622276 0 \;; #X scalar peak-template 220.731 330 -164.961 0.00271995 0.00491236 0 \;; #X scalar peak-template 55.8179 330 -162.658 -0.00364487 -0.00362429 0 \;; #X scalar peak-template 214.238 330 -156.636 0.00401103 0.000744068 0 \;; #X scalar peak-template 230.388 330 -142.193 -0.00175354 -0.0015548 0 \;; #X scalar peak-template 205.698 330 -136.685 -0.000451969 -0.00184241 0 \;; #X scalar peak-template 236.853 330 -132.195 -0.00080052 -0.00138166 0 \;; #X scalar peak-template 70.1927 330 -129.01 0.000948858 -0.00104714 0 \;; #X scalar peak-template 60.6268 330 -128.771 -0.000107757 -0.00139601 0 \;; #X scalar peak-template 199.238 330 -125.184 -5.52664e-05 -0.00121886 0 \;; #X scalar peak-template 102.316 330 -124.61 -0.000913632 -0.000768002 0 \;; #X scalar peak-template 244.64 330 -122.316 0.000568954 -0.000933158 0 \;; #X scalar peak-template 183.608 330 -113.564 -0.000686299 0.000373102 0 \;; #X scalar peak-template 190.466 330 -112.684 -0.00070255 0.000277037 0 \;; #X scalar peak-template 84.4484 330 -116.207 0.000855315 -0.000125832 0 \;; #X scalar peak-template 110.15 330 -115.035 -0.000124898 -0.000817018 0 \;; #X scalar peak-template 174.384 330 -107.641 0.000516576 0.00034702 0 \;; #X scalar peak-template 80.1102 330 -113.14 0.000618533 0.000456135 0 \;; #X scalar peak-template 739.645 330 -113.263 -0.000612479 0.000470234 0 \;; #X scalar peak-template 141.831 330 -105.395 -0.000346356 0.000453872 0 \;; #X restore 298 457 pd peak-list; #N canvas 405 331 745 526 trace-list 1; #X scalar trace-template 0 0 0 \; 43.3302 66.0521 \; 44.6492 75.851 \; 44.6956 82.9816 \; 44.3137 85.9148 \; 43.4352 86.2268 \; 43.1128 85.6468 \; 43.0306 84.9578 \; 42.9591 84.0919 \; 42.7109 82.2432 \; 42.1735 78.3134 \; 40.6273 72.9205 \; 38.4355 66.4194 \; 36.987 66.0861 \; 36.0526 69.5062 \; 35.3811 70.993 \; 38.3488 67.3509 \; \;; #X scalar trace-template 0 0 1 \; 35.7851 60.3245 \; 28.7656 48.9997 \; \;; #X scalar trace-template 0 0 2 \; 67.1596 61.9347 \; 68.1884 69.7498 \; 68.1342 72.6229 \; 67.7473 73.3704 \; 66.8125 73.2892 \; 66.663 71.9773 \; 66.6789 70.454 \; 66.3016 68.1836 \; 66.3651 62.1891 \; \;; #X scalar trace-template 0 0 3 \; 66.5367 62.9806 \; \;; #X scalar trace-template 0 0 4 \; 60.9143 60.0013 \; 62.0291 63.7387 \; 63.1022 70.4535 \; 62.5499 72.8329 \; 61.8771 73.6051 \; 61.6928 72.9177 \; 61.6889 70.965 \; 60.6265 68.0588 \; \;; #X scalar trace-template 0 0 5 \; 60.0435 58.3026 \; 57.4756 71.1499 \; 56.6996 79.7329 \; \;; #X scalar trace-template 0 0 6 \; 50.4538 53.6763 \; \;; #X scalar trace-template 0 0 7 \; 64.792 52.6242 \; 65.105 64.364 \; 65.3278 66.1787 \; \;; #X scalar trace-template 0 0 8 \; 69.4266 52.4696 \; \;; #X scalar trace-template 0 0 9 \; 93.3934 53.7858 \; 93.3129 57.494 \; 93.3866 62.3986 \; 93.4731 62.6514 \; 93.6311 57.6541 \; \;; #X scalar trace-template 0 0 10 \; 98.0801 52.803 \; 98.0787 57.9338 \; 97.978 58.3166 \; 97.9167 59.7057 \; 97.8158 54.9004 \; 97.7138 56.6168 \; \;; #X scalar trace-template 0 0 11 \; 98.6797 52.4833 \; 98.7476 55.3555 \; 98.7456 58.0097 \; 98.6729 58.3025 \; 98.5137 55.6623 \; 98.3772 57.2168 \; 98.3283 56.7836 \; 98.4639 50.9759 \; \;; #X scalar trace-template 0 0 12 \; 93.5856 53.4024 \; \;; #X scalar trace-template 0 0 13 \; 94.0962 53.1939 \; 94.1801 51.7142 \; \;; #X scalar trace-template 0 0 14 \; 94.5618 52.1363 \; 94.6656 56.0829 \; 94.655 58.4145 \; 94.7741 54.2222 \; \;; #X scalar trace-template 0 0 15 \; 70.2788 51.815 \; \;; #X scalar trace-template 0 0 16 \; 92.4035 49.4034 \; 92.5834 50.7802 \; 92.6197 58.0994 \; 92.8153 56.7736 \; 92.69 53.7227 \; \;; #X scalar trace-template 0 0 17 \; 97.0111 52.4514 \; 97.1464 53.205 \; 97.1322 55.8306 \; 97.1939 58.9246 \; \;; #X scalar trace-template 0 0 18 \; 103.63 48.7534 \; \;; #X scalar trace-template 0 0 19 \; 106.708 52.5447 \; 106.667 50.9117 \; 106.615 54.0484 \; 106.573 56.6712 \; 106.572 53.7509 \; \;; #X scalar trace-template 0 0 20 \; 107.375 52.4933 \; 107.452 52.97 \; 107.479 53.8338 \; \;; #X scalar trace-template 0 0 21 \; 104.889 52.4301 \; 104.798 50.6847 \; 104.738 53.6064 \; 104.694 55.5078 \; \;; #X scalar trace-template 0 0 22 \; 93.1125 49.8142 \; \;; #X scalar trace-template 0 0 23 \; 106.168 52.0262 \; 106.168 51.845 \; 106.168 53.5205 \; 106.133 55.4745 \; \;; #X scalar trace-template 0 0 24 \; 103.564 53.0485 \; 103.522 52.3184 \; \;; #X scalar trace-template 5 0 3 \; 58.434 71.4234 \; \;; #X scalar trace-template 5 0 6 \; 68.7958 68.5415 \; \;; #X scalar trace-template 5 0 8 \; 72.1585 54.0198 \; 72.027 60.6226 \; 71.5842 61.862 \; 71.091 60.5141 \; 70.3611 60.3523 \; 70.9366 54.7085 \; 71.0735 52.2826 \; 71.3993 48.898 \; 70.4122 43.0506 \; 70.6467 35.4039 \; \;; #X scalar trace-template 5 0 12 \; 75.1361 54.1268 \; 74.826 58.9083 \; 74.8015 58.2652 \; \;; #X scalar trace-template 5 0 15 \; 93.8916 49.7957 \; \;; #X scalar trace-template 5 0 18 \; 104.549 52.3586 \; \;; #X scalar trace-template 5 0 22 \; 107.047 51.1394 \; 107.037 52.8323 \; 107.007 55.1471 \; \;; #X scalar trace-template 10 0 1 \; 55.8012 81.4728 \; 55.5341 82.4149 \; 55.0362 84.3325 \; 54.925 85.5837 \; 54.9055 86.3615 \; 54.6702 85.9042 \; 54.1036 83.7372 \; 53.7571 78.7488 \; 53.3201 72.8738 \; 54.8047 58.1952 \; \;; #X scalar trace-template 10 0 3 \; 98.2897 56.9831 \; 98.2967 56.5387 \; 98.12 61.6584 \; 98.0759 59.3161 \; 97.9283 57.2672 \; 97.9042 54.345 \; 97.9775 46.6193 \; 98.0437 30.8392 \; \;; #X scalar trace-template 10 0 6 \; 105.674 54.2495 \; 105.673 56.157 \; 105.679 54.3729 \; 105.672 45.7686 \; \;; #X scalar trace-template 10 0 13 \; 105.203 57.7523 \; 105.214 57.8342 \; 105.26 54.0331 \; \;; #X scalar trace-template 10 0 15 \; 105.27 55.7998 \; \;; #X scalar trace-template 10 0 18 \; 96.3372 53.1138 \; \;; #X scalar trace-template 10 0 24 \; 91.5376 52.4183 \; 91.6323 55.6354 \; \;; #X scalar trace-template 15 0 5 \; 73.8193 56.4623 \; 74.0778 57.8288 \; 73.8012 54.3914 \; 73.8703 48.2022 \; \;; #X scalar trace-template 15 0 7 \; 92.4832 57.2131 \; \;; #X scalar trace-template 15 0 15 \; 97.4895 56.1181 \; 97.4097 61.4156 \; 97.5703 59.4746 \; 97.639 61.3037 \; 97.5821 52.7503 \; 97.4317 49.262 \; 97.3345 37.6363 \; \;; #X scalar trace-template 15 0 18 \; 94.5248 54.9649 \; \;; #X scalar trace-template 15 0 20 \; 99.3492 54.9459 \; \;; #X scalar trace-template 20 0 7 \; 58.751 69.2183 \; \;; #X scalar trace-template 20 0 12 \; 68.7707 65.5664 \; 69.4343 58.9916 \; 69.2403 51.8567 \; 69.4641 51.8688 \; \;; #X scalar trace-template 20 0 14 \; 64.2458 66.3536 \; 64.7097 63.8999 \; \;; #X scalar trace-template 20 0 17 \; 98.2076 57.7703 \; \;; #X scalar trace-template 20 0 18 \; 72.1465 57.592 \; 72.7218 50.7256 \; 72.6739 45.1631 \; 72.827 47.7164 \; 72.347 45.3634 \; 73.2437 34.8942 \; 72.4919 36.8733 \; \;; #X scalar trace-template 20 0 20 \; 93.4187 56.559 \; \;; #X scalar trace-template 20 0 21 \; 96.7609 53.9646 \; 96.7573 57.3216 \; 96.901 56.4167 \; 96.8986 50.763 \; 96.7653 41.0124 \; 96.6051 27.4919 \; 96.6915 31.3267 \; \;; #X scalar trace-template 20 0 22 \; 96.6599 57.643 \; \;; #X scalar trace-template 20 0 23 \; 98.7288 54.3033 \; 98.819 52.9457 \; \;; #X scalar trace-template 20 0 24 \; 25.162 51.7721 \; \;; #X scalar trace-template 25 0 7 \; 97.3372 59.4565 \; 97.2453 55.0281 \; 97.1582 53.561 \; \;; #X scalar trace-template 25 0 9 \; 99.0862 52.1441 \; 98.9966 52.2653 \; 98.9366 43.5301 \; 98.7499 39.1149 \; \;; #X scalar trace-template 25 0 13 \; 88.7439 52.1357 \; 88.6063 48.607 \; 88.4629 45.3163 \; 88.5646 37.1753 \; \;; #X scalar trace-template 25 0 16 \; 76.6582 50.6773 \; 76.4757 47.9655 \; 76.0797 45.6933 \; 76.0124 41.2622 \; 76.111 34.2795 \; 76.485 38.5394 \; \;; #X scalar trace-template 25 0 17 \; 89.9143 50.7512 \; 89.8175 48.7246 \; 89.5803 46.0486 \; 89.5973 36.885 \; \;; #X scalar trace-template 25 0 19 \; 90.3997 50.241 \; 90.3685 46.0385 \; \;; #X scalar trace-template 25 0 20 \; 92.007 47.4144 \; \;; #X scalar trace-template 25 0 22 \; 95.9485 49.755 \; 96.1285 47.8386 \; 96.1404 43.5474 \; \;; #X scalar trace-template 25 0 24 \; 90.9179 47.4232 \; 90.9154 45.4841 \; 90.6842 43.4723 \; 90.7132 33.3246 \; \;; #X scalar trace-template 30 0 6 \; 96.4763 48.1872 \; \;; #X scalar trace-template 30 0 10 \; 89.3172 47.7196 \; \;; #X scalar trace-template 30 0 14 \; 82.8228 46.0375 \; 82.846 40.9498 \; 83.1092 38.7591 \; \;; #X scalar trace-template 30 0 20 \; 95.2468 44.5831 \; \;; #X scalar trace-template 30 0 23 \; 99.7228 45.2257 \; \;; #X scalar trace-template 35 0 5 \; 97.7405 56.7114 \; \;; #X scalar trace-template 35 0 6 \; 98.2853 50.0495 \; \;; #X scalar trace-template 35 0 10 \; 99.0794 45.8889 \; \;; #X scalar trace-template 35 0 19 \; 91.7936 43.9899 \; 91.9119 38.476 \; 91.7941 27.6638 \; \;; #X scalar trace-template 35 0 20 \; 96.3046 44.1244 \; \;; #X scalar trace-template 35 0 23 \; 84.3615 43.0986 \; 84.4914 38.6378 \; 84.5763 32.2108 \; \;; #X scalar trace-template 40 0 4 \; 64.8609 62.0142 \; 64.3096 52.2251 \; 62.8352 45.6144 \; 61.4115 49.4288 \; \;; #X scalar trace-template 40 0 5 \; 67.279 52.6475 \; 67.0166 51.557 \; 66.7609 42.7254 \; 66.2104 53.6697 \; \;; #X scalar trace-template 40 0 6 \; 79.7413 38.9881 \; 79.9646 31.0069 \; \;; #X scalar trace-template 40 0 7 \; 117.599 38.2206 \; 117.635 33.6855 \; \;; #X scalar trace-template 40 0 10 \; 117.527 36.493 \; 117.488 26.9096 \; \;; #X scalar trace-template 40 0 11 \; 83.4012 38.8664 \; 83.5996 31.6635 \; 83.5749 37.3988 \; \;; #X scalar trace-template 40 0 12 \; 117.755 36.44 \; 117.837 33.3774 \; \;; #X scalar trace-template 40 0 20 \; 95.2338 33.5163 \; \;; #X scalar trace-template 40 0 22 \; 107.704 35.4627 \; 107.784 31.1939 \; \;; #X scalar trace-template 45 0 2 \; 59.333 58.5199 \; \;; #X scalar trace-template 45 0 9 \; 4.76558 44.7982 \; \;; #X scalar trace-template 45 0 13 \; 97.1803 35.0264 \; \;; #X scalar trace-template 45 0 14 \; 117.68 34.5832 \; \;; #X scalar trace-template 45 0 17 \; 98.3911 24.5617 \; \;; #X scalar trace-template 45 0 20 \; 84.8597 30.5339 \; \;; #X scalar trace-template 45 0 24 \; 107.721 31.1631 \; \;; #X scalar trace-template 50 0 2 \; 51.6483 69.8412 \; \;; #X scalar trace-template 50 0 3 \; 63.9179 47.4607 \; 65.1468 51.9224 \; \;; #X scalar trace-template 50 0 6 \; 75.815 34.9297 \; \;; #X scalar trace-template 50 0 7 \; 67.5764 45.6307 \; 67.4924 51.162 \; \;; #X scalar trace-template 50 0 9 \; 82.1746 36.9205 \; \;; #X scalar trace-template 50 0 10 \; 74.7603 34.7385 \; \;; #X scalar trace-template 50 0 12 \; 114.054 32.9146 \; 114.149 57.9938 \; \;; #X scalar trace-template 50 0 13 \; 106.111 31.5629 \; \;; #X scalar trace-template 50 0 14 \; 119.166 39.5628 \; \;; #X scalar trace-template 50 0 15 \; 106.523 30.4059 \; 106.52 52.0421 \; 106.622 58.7555 \; 106.654 60.575 \; 106.665 57.6211 \; \;; #X scalar trace-template 50 0 17 \; 104.801 29.8914 \; 104.741 48.5498 \; \;; #X scalar trace-template 50 0 19 \; 119.205 37.0858 \; 119.193 51.4049 \; \;; #X scalar trace-template 50 0 20 \; 109.541 29.1446 \; 109.544 47.4596 \; \;; #X scalar trace-template 50 0 22 \; 119.001 26.3198 \; \;; #X scalar trace-template 50 0 23 \; 118.523 28.1975 \; \;; #X scalar trace-template 50 0 24 \; 92.9503 28.7476 \; \;; #X scalar trace-template 55 0 2 \; 113.879 55.3717 \; 113.876 63.208 \; 113.879 63.7127 \; 113.913 58.2536 \; 113.967 54.0574 \; \;; #X scalar trace-template 55 0 6 \; 105.25 56.3462 \; \;; #X scalar trace-template 55 0 8 \; 114.186 56.2486 \; 114.17 61.7646 \; \;; #X scalar trace-template 55 0 9 \; 115.369 51.8212 \; 115.396 58.0459 \; 115.404 58.493 \; \;; #X scalar trace-template 55 0 10 \; 105.314 55.0189 \; \;; #X scalar trace-template 55 0 11 \; 59.7326 50.1853 \; \;; #X scalar trace-template 55 0 13 \; 113.553 48.8139 \; \;; #X scalar trace-template 55 0 14 \; 114.65 48.9427 \; \;; #X scalar trace-template 55 0 16 \; 105.745 48.636 \; 105.679 57.4135 \; 105.528 61.5143 \; 105.528 62.5137 \; 105.518 58.751 \; 105.472 52.909 \; \;; #X scalar trace-template 55 0 18 \; 114.444 47.8306 \; \;; #X scalar trace-template 55 0 21 \; 116.679 45.6275 \; \;; #X scalar trace-template 55 0 22 \; 118.699 52.0081 \; \;; #X scalar trace-template 55 0 23 \; 118.669 51.6062 \; \;; #X scalar trace-template 55 0 24 \; 104.27 43.0815 \; \;; #X scalar trace-template 60 0 1 \; 108.535 61.6816 \; 108.532 63.3951 \; 108.509 58.7369 \; \;; #X scalar trace-template 60 0 3 \; 43.4621 60.557 \; \;; #X scalar trace-template 60 0 4 \; 111.754 62.3488 \; 111.753 62.0433 \; \;; #X scalar trace-template 60 0 5 \; 93.4812 61.1796 \; 93.4064 62.1943 \; 93.3087 61.1056 \; 93.2521 59.2244 \; 93.3045 53.8694 \; \;; #X scalar trace-template 60 0 6 \; 106.037 59.2202 \; 106.032 64.9245 \; 106.028 65.718 \; 105.99 61.6129 \; 105.946 54.7512 \; 105.902 53.4521 \; 105.764 61.2428 \; 105.791 63.1944 \; 105.735 64.2197 \; 105.685 67.6098 \; 105.628 69.7158 \; 105.762 63.5753 \; 105.802 57.0624 \; \;; #X scalar trace-template 60 0 7 \; 94.0043 59.8076 \; 94.0496 64.4823 \; 94.0766 67.4586 \; 94.0832 66.5082 \; 94.0858 60.4824 \; 94.0519 57.3767 \; 93.9501 59.9649 \; 93.8858 62.4423 \; 93.9548 61.1516 \; \;; #X scalar trace-template 60 0 10 \; 115.829 60.8003 \; 115.828 59.5409 \; \;; #X scalar trace-template 60 0 11 \; 99.9991 60.2356 \; 99.9902 60.3169 \; \;; #X scalar trace-template 60 0 12 \; 98.0686 60.0103 \; 98.0528 59.9308 \; 97.9925 57.6906 \; 97.8859 56.8807 \; 97.809 55.4109 \; 97.7985 57.8828 \; 97.8873 62.7719 \; 97.9727 67.3879 \; 98.0639 68.5004 \; 98.1988 66.872 \; 98.2398 63.897 \; 98.1126 58.0075 \; 98.0507 56.8621 \; 98.0248 54.25 \; 98.0529 52.1177 \; 98.0875 55.393 \; 98.1957 59.4561 \; 98.2548 62.1281 \; 98.3588 61.753 \; 98.2578 52.1227 \; \;; #X scalar trace-template 60 0 13 \; 77.0215 60.4598 \; \;; #X scalar trace-template 60 0 14 \; 99.5903 58.7265 \; 99.6018 60.2019 \; 99.634 59.678 \; 99.6371 57.6768 \; 99.5831 54.2244 \; 99.6482 56.5613 \; 99.658 62.8188 \; 99.6985 67.8082 \; 99.7882 68.3324 \; 99.9258 68.5941 \; 100.001 67.102 \; 100.071 59.6095 \; \;; #X scalar trace-template 60 0 17 \; 106.329 58.0421 \; \;; #X scalar trace-template 60 0 18 \; 118.448 58.3807 \; \;; #X scalar trace-template 60 0 19 \; 98.5344 58.6314 \; \;; #X scalar trace-template 60 0 20 \; 114.218 57.2896 \; 114.196 60.8147 \; 114.247 57.8065 \; \;; #X scalar trace-template 60 0 21 \; 74.1551 58.6946 \; \;; #X scalar trace-template 60 0 22 \; 108.876 57.4218 \; 108.884 59.8044 \; 108.887 56.5772 \; \;; #X scalar trace-template 60 0 23 \; 99.223 57.731 \; 99.2411 58.3133 \; 99.2309 59.3052 \; 99.2284 58.1737 \; 99.2168 53.516 \; \;; #X scalar trace-template 60 0 24 \; 108.273 57.9692 \; \;; #X scalar trace-template 65 0 3 \; 104.792 60.4364 \; 104.882 49.0181 \; 104.859 55.5088 \; \;; #X scalar trace-template 65 0 8 \; 92.8342 60.3298 \; 92.8528 60.5127 \; 92.5407 53.981 \; \;; #X scalar trace-template 65 0 13 \; 94.4643 58.0916 \; 94.6355 58.0613 \; 94.679 57.0481 \; 94.74 56.2747 \; 94.5523 55.6712 \; \;; #X scalar trace-template 65 0 17 \; 104.266 58.7875 \; 104.251 61.1319 \; 104.242 58.8205 \; 104.241 52.5004 \; \;; #X scalar trace-template 65 0 18 \; 117.546 59.4428 \; 117.55 56.2746 \; \;; #X scalar trace-template 65 0 19 \; 111.313 58.7874 \; 111.309 56.6006 \; \;; #X scalar trace-template 65 0 21 \; 114.438 58.3491 \; 114.446 57.5028 \; \;; #X scalar trace-template 65 0 24 \; 109.131 58.3358 \; \;; #X scalar trace-template 70 0 4 \; 104.779 58.7978 \; 104.683 55.9118 \; 104.658 50.6814 \; 104.71 51.4453 \; 104.659 56.6503 \; 104.631 62.6507 \; 104.543 61.3073 \; 104.488 61.5049 \; 104.41 63.3452 \; 104.469 57.9746 \; 104.532 44.7933 \; \;; #X scalar trace-template 70 0 9 \; 50.5129 58.1022 \; 52.0422 62.4943 \; \;; #X scalar trace-template 70 0 10 \; 104.938 57.3005 \; \;; #X scalar trace-template 70 0 11 \; 113.423 58.2578 \; 113.396 53.8867 \; \;; #X scalar trace-template 70 0 24 \; 103.921 58.4253 \; 103.965 56.4895 \; \;; #X scalar trace-template 75 0 1 \; 28.7656 65.6265 \; 30.4187 56.1352 \; 20.9307 55.7277 \; \;; #X scalar trace-template 75 0 10 \; 44.3816 62.7999 \; 47.1446 79.2267 \; \;; #X scalar trace-template 75 0 15 \; 66.028 56.9894 \; 65.9473 66.2473 \; 66.2148 73.5068 \; 66.3251 79.2535 \; 66.3195 82.2919 \; 66.223 82.904 \; 66.1099 82.4279 \; 66.0253 81.3052 \; 65.9722 78.2544 \; 66.2036 72.5636 \; 66.3236 66.8396 \; 66.0337 64.6209 \; 65.5822 67.3236 \; 65.2495 73.3914 \; 64.9661 78.6321 \; 64.8079 81.7467 \; 64.6581 81.0436 \; 64.178 76.2971 \; 64.0002 66.4944 \; 65.0725 59.3874 \; 65.2968 70.1558 \; 64.7961 79.8125 \; 64.2019 83.0497 \; 63.7437 83.4104 \; 63.4457 82.0825 \; 63.1555 79.6909 \; 62.9661 74.9721 \; 62.3735 67.2386 \; \;; #X scalar trace-template 75 0 18 \; 54.1281 59.7815 \; 53.8668 62.0644 \; \;; #X scalar trace-template 75 0 19 \; 59.5975 58.5012 \; 59.0246 64.932 \; 58.8337 75.1344 \; 58.8721 80.6605 \; 58.8335 82.3774 \; 58.797 81.5338 \; 58.9634 80.3942 \; 59.1204 80.149 \; 59.2536 80.8596 \; 59.3481 81.568 \; 59.2892 81.97 \; 59.0309 81.9452 \; 58.8996 82.1376 \; 58.7961 82.8746 \; 58.4282 83.9642 \; 58.118 84.3872 \; 57.4864 82.7859 \; 56.213 81.2494 \; 55.9459 80.4686 \; 56.4277 80.3121 \; 56.8306 80.2673 \; 57.3033 80.5597 \; 57.1452 81.0683 \; 56.6141 81.951 \; 56.4287 82.1288 \; 56.3809 81.5032 \; 56.0749 79.8672 \; 55.7657 75.9288 \; 54.7572 68.3138 \; 53.0913 58.55 \; \;; #X scalar trace-template 75 0 20 \; 97.5191 54.9218 \; 97.5905 54.0471 \; \;; #X scalar trace-template 75 0 21 \; 100.908 55.2177 \; 100.895 50.5504 \; \;; #X scalar trace-template 75 0 22 \; 60.661 57.6485 \; \;; #X scalar trace-template 80 0 0 \; 45.3064 79.4637 \; 46.0318 82.7263 \; 46.2638 86.5013 \; 46.6024 87.3288 \; 46.8569 86.6402 \; 46.917 85.573 \; 47.0133 84.9324 \; 47.2429 84.8494 \; 47.5238 85.098 \; 47.6638 85.1508 \; 47.4935 84.5333 \; 47.0848 83.4253 \; 46.5846 82.5027 \; 46.158 82.0857 \; 45.8538 82.0532 \; 45.7845 81.8161 \; 45.271 80.7153 \; 44.9272 79.1805 \; 44.6754 78.1312 \; 44.176 77.6596 \; 44.0203 77.6338 \; 44.5443 80.211 \; 44.7524 82.0784 \; 44.5238 83.859 \; 44.5432 84.6691 \; 44.4566 84.8053 \; 44.3101 83.2943 \; 43.4597 79.1389 \; 43.0261 71.7648 \; 42.9685 61.5879 \; \;; #X scalar trace-template 80 0 2 \; 95.3305 53.7638 \; 95.1563 63.5682 \; 95.058 69.933 \; 95.0398 72.6937 \; 95.0625 72.0074 \; 95.1761 69.3127 \; 95.2614 66.3402 \; 95.3102 60.6198 \; 95.2644 50.703 \; \;; #X scalar trace-template 80 0 3 \; 70.6684 54.5473 \; 70.8535 63.5517 \; 70.923 70.6645 \; 70.9625 74.8792 \; 70.9973 76.3398 \; 71.041 75.3628 \; 71.1063 71.4505 \; 71.4828 64.4961 \; 71.664 55.6991 \; 71.1539 56.093 \; \;; #X scalar trace-template 80 0 8 \; 74.5842 53.7224 \; 74.6798 60.9324 \; 74.7701 65.088 \; 74.8205 66.5031 \; 74.8536 66.2739 \; 74.9078 65.5817 \; 75.0981 63.6081 \; 75.36 58.2125 \; 75.5816 50.9285 \; 75.0917 48.3284 \; 74.6947 52.0563 \; 74.5236 54.0149 \; \;; #X scalar trace-template 80 0 9 \; 98.9494 52.6161 \; 98.855 59.6254 \; \;; #X scalar trace-template 80 0 11 \; 107.435 49.9268 \; \;; #X scalar trace-template 80 0 22 \; 97.0322 49.2979 \; 96.9545 55.426 \; 96.9874 62.7103 \; 97.0176 67.7851 \; 97.0907 68.579 \; 97.2424 67.1777 \; 97.3408 64.3775 \; 97.4824 57.7759 \; 97.4072 49.9733 \; 97.4188 43.1923 \; 97.4494 53.8367 \; 97.2663 60.9229 \; 97.399 62.1905 \; \;; #X scalar trace-template 80 0 24 \; 68.562 44.4703 \; \;; #X scalar trace-template 85 0 5 \; 62.6941 58.8803 \; \;; #X scalar trace-template 85 0 10 \; 96.1265 63.7529 \; 96.0421 66.677 \; 96.0624 72.5341 \; 96.1505 74.4534 \; 96.249 74.4393 \; 96.3181 71.6039 \; 96.323 64.0989 \; 96.2302 54.6293 \; \;; #X scalar trace-template 85 0 11 \; 96.211 61.8841 \; \;; #X scalar trace-template 85 0 16 \; 98.7364 57.2459 \; 98.7772 64 \; 98.835 69.2622 \; 98.9775 71.0388 \; 99.0667 71.2528 \; 99.1468 68.4925 \; 99.2247 61.5751 \; 99.2735 53.0332 \; 99.1813 42.7543 \; 99.3925 56.1553 \; \;; #X scalar trace-template 85 0 17 \; 97.2317 53.4618 \; \;; #X scalar trace-template 85 0 18 \; 99.8089 55.5397 \; \;; #X scalar trace-template 85 0 20 \; 77.7817 52.9002 \; 77.9789 62.443 \; 78.0495 61.979 \; 78.1565 60.837 \; \;; #X scalar trace-template 85 0 21 \; 118.685 53.5776 \; \;; #X scalar trace-template 85 0 23 \; 119.147 52.8507 \; \;; #X scalar trace-template 85 0 24 \; 105.139 50.5351 \; 105.163 59.2938 \; 105.221 64.0555 \; 105.163 62.8698 \; 105.09 64.5973 \; \;; #X scalar trace-template 90 0 1 \; 100.422 57.9845 \; 100.491 63.3379 \; 100.573 64.3463 \; 100.697 64.1111 \; 100.779 61.2922 \; 100.846 53.0746 \; \;; #X scalar trace-template 90 0 5 \; 106.282 57.177 \; 106.331 60.5044 \; 106.278 61.0081 \; 106.244 63.1701 \; \;; #X scalar trace-template 90 0 9 \; 78.228 58.4228 \; \;; #X scalar trace-template 90 0 11 \; 105.826 59.7742 \; \;; #X scalar trace-template 90 0 13 \; 104.477 56.8221 \; \;; #X scalar trace-template 90 0 17 \; 101.156 56.4595 \; 101.232 60.987 \; 101.363 61.7738 \; 101.491 62.3755 \; 101.566 60.2702 \; \;; #X scalar trace-template 90 0 18 \; 102.556 56.1643 \; 102.672 59.4596 \; \;; #X scalar trace-template 90 0 21 \; 103.279 55.5753 \; 103.338 60.8145 \; 103.452 60.2049 \; 103.626 62.2785 \; 103.69 60.1499 \; \;; #X scalar trace-template 90 0 23 \; 80.6156 56.2613 \; 80.6278 59.0661 \; \;; #X scalar trace-template 95 0 9 \; 104.017 60.4545 \; \;; #X scalar trace-template 95 0 11 \; 101.951 59.5806 \; 102.074 60.2808 \; 102.246 61.7509 \; 102.311 59.2503 \; \;; #X scalar trace-template 95 0 13 \; 92.7145 58.605 \; \;; #X scalar trace-template 100 0 9 \; 105.479 63.3839 \; 105.526 68.3622 \; \;; #X scalar trace-template 100 0 13 \; 104.926 61.7527 \; 104.953 67.5045 \; 105.01 66.9893 \; 105.106 61.8638 \; 105.242 56.0645 \; \;; #X scalar trace-template 100 0 18 \; 106.112 59.4222 \; 106.088 64.0517 \; 106.133 64.6438 \; 106.031 58.503 \; \;; #X scalar trace-template 100 0 23 \; 104.307 58.6226 \; 104.297 62.9229 \; \;; #X scalar trace-template 105 0 7 \; 102.933 61.6534 \; 103.043 60.5042 \; 103.149 53.9428 \; \;; #X scalar trace-template 105 0 20 \; 105.893 57.9727 \; \;; #X scalar trace-template 110 0 5 \; 63.6483 57.9829 \; \;; #X scalar trace-template 110 0 9 \; 106.686 58.7287 \; \;; #X scalar trace-template 110 0 20 \; 107.237 57.525 \; \;; #X scalar trace-template 110 0 23 \; 78.3567 56.9218 \; \;; #X scalar trace-template 110 0 24 \; 67.279 63.1581 \; \;; #X scalar trace-template 115 0 5 \; 105.632 62.3856 \; \;; #X scalar trace-template 115 0 9 \; 54.4145 54.0393 \; \;; #X scalar trace-template 115 0 11 \; 60.9096 61.9021 \; \;; #X scalar trace-template 115 0 17 \; 106.281 56.2507 \; \;; #X scalar trace-template 115 0 20 \; 98.3118 56.738 \; 98.3355 49.9897 \; 98.3369 51.8101 \; 98.3943 55.808 \; \;; #X scalar trace-template 115 0 21 \; 97.2826 56.4723 \; 97.1559 51.3868 \; 97.2517 49.4146 \; 97.1145 46.5651 \; 97.0374 68.5707 \; \;; #X scalar trace-template 115 0 23 \; 106.914 55.8768 \; 107.003 47.2128 \; \;; #X scalar trace-template 115 0 24 \; 97.8258 55.2253 \; 97.7615 56.9729 \; 97.7798 56.1292 \; 97.7046 57.0451 \; 97.7385 58.6266 \; 97.7286 63.1467 \; 97.6773 65.5081 \; \;; #X scalar trace-template 120 0 1 \; 68.2533 59.2205 \; \;; #X scalar trace-template 120 0 5 \; 105.729 54.4994 \; \;; #X scalar trace-template 120 0 7 \; 98.7789 54.5448 \; 98.6909 54.5418 \; 98.6698 56.6369 \; 98.6558 61.9572 \; 98.6089 66.107 \; 98.5499 65.5083 \; 98.5333 60.7304 \; \;; #X scalar trace-template 120 0 9 \; 96.7716 53.6612 \; 96.7862 48.729 \; 96.7225 52.0128 \; \;; #X scalar trace-template 120 0 11 \; 96.3578 56.2766 \; 96.4634 42.1048 \; \;; #X scalar trace-template 120 0 14 \; 105.161 53.9912 \; 105.056 36.4085 \; \;; #X scalar trace-template 120 0 17 \; 99.3979 53.8341 \; \;; #X scalar trace-template 120 0 18 \; 95.6152 47.3413 \; 95.7933 40.2091 \; 95.8117 52.2763 \; 96.0363 62.5129 \; 95.9603 64.1765 \; 95.86 64.5745 \; \;; #X scalar trace-template 125 0 1 \; 63.9916 57.0381 \; 64.2159 50.3829 \; \;; #X scalar trace-template 125 0 2 \; 70.6556 54.4364 \; 70.771 57.7957 \; 70.6885 60.2903 \; 70.5159 61.3918 \; 70.1955 61.5167 \; 69.6017 61.3411 \; 69.2061 59.7526 \; 67.6521 56.6884 \; 66.3772 59.0452 \; 66.317 57.2027 \; \;; #X scalar trace-template 125 0 4 \; 83.6247 47.5748 \; \;; #X scalar trace-template 125 0 5 \; 78.5751 46.396 \; \;; #X scalar trace-template 125 0 6 \; 72.0093 45.5065 \; \;; #X scalar trace-template 125 0 10 \; 93.513 42.6424 \; \;; #X scalar trace-template 125 0 13 \; 81.2407 43.4618 \; \;; #X scalar trace-template 125 0 17 \; 105.473 36.7186 \; 105.324 53.5137 \; 105.425 62.4231 \; 105.462 66.6387 \; 105.472 65.9009 \; 105.54 59.6241 \; \;; #X scalar trace-template 125 0 23 \; 94.6678 41.2581 \; \;; #X scalar trace-template 130 0 3 \; 67.279 55.2067 \; \;; #X scalar trace-template 130 0 4 \; 99.4797 55.7459 \; 99.5114 61.0345 \; 99.506 64.8965 \; 99.4235 61.3435 \; 99.3281 54.3145 \; \;; #X scalar trace-template 130 0 5 \; 104.792 50.2295 \; 104.851 59.5202 \; 104.852 64.0489 \; 104.834 62.4463 \; \;; #X scalar trace-template 130 0 6 \; 105.955 55.1657 \; 106.022 56.8532 \; 106.027 61.6359 \; 106.024 61.529 \; 106.104 54.688 \; \;; #X scalar trace-template 130 0 10 \; 100.073 46.225 \; 100.221 56.5845 \; 100.276 59.5332 \; \;; #X scalar trace-template 130 0 11 \; 105.903 54.6662 \; 105.73 54.6697 \; 105.772 60.0226 \; 105.787 62.842 \; 105.825 62.9742 \; 105.75 57.5191 \; \;; #X scalar trace-template 130 0 13 \; 104.191 45.1731 \; 104.305 56.2167 \; 104.29 62.1135 \; 104.225 59.7614 \; \;; #X scalar trace-template 130 0 14 \; 95.6491 49.0642 \; 95.4005 51.3254 \; 95.4859 58.3154 \; 95.5195 63.5584 \; 95.6858 63.111 \; 95.5254 52.9112 \; \;; #X scalar trace-template 130 0 23 \; 100.84 44.8828 \; 100.971 52.5872 \; \;; #X scalar trace-template 135 0 1 \; 96.9296 68.2025 \; 96.9229 70.7526 \; 96.911 71.2325 \; 96.8475 67.6464 \; 96.6719 57.2885 \; \;; #X scalar trace-template 135 0 3 \; 55.7407 61.8333 \; \;; #X scalar trace-template 135 0 9 \; 96.1424 61.1484 \; 96.3859 59.4198 \; \;; #X scalar trace-template 135 0 16 \; 105.169 58.025 \; 105.18 59.8246 \; 105.219 61.1852 \; 105.308 61.9676 \; 105.257 55.4418 \; 105.368 44.5374 \; \;; #X scalar trace-template 135 0 20 \; 103.749 51.8393 \; 103.689 58.5917 \; 103.567 59.2444 \; 103.509 59.6344 \; 103.507 54.4535 \; 103.665 48.2698 \; 103.569 21.2136 \; \;; #X scalar trace-template 140 0 3 \; 94.826 60.4828 \; 94.8546 62.6004 \; 94.671 62.0785 \; 94.4878 54.123 \; \;; #X scalar trace-template 140 0 8 \; 103.052 56.8622 \; \;; #X scalar trace-template 140 0 21 \; 94.6802 56.5378 \; \;; #X scalar trace-template 140 0 23 \; 104.556 55.3201 \; 104.64 58.9501 \; 104.721 59.9894 \; 104.677 29.848 \; 104.84 42.1598 \; \;; #X scalar trace-template 145 0 8 \; 97.574 67.4101 \; 97.583 67.5659 \; 97.4339 62.0541 \; 97.1835 51.5837 \; 97.2382 42.6143 \; 97.3407 41.9578 \; 97.2803 46.3782 \; 97.2462 54.9285 \; 97.2405 60.8982 \; 97.186 61.9162 \; 97.1356 58.9903 \; 97.0654 54.4072 \; \;; #X scalar trace-template 145 0 9 \; 104.963 59.2519 \; 104.96 55.6746 \; \;; #X scalar trace-template 145 0 10 \; 99.6143 60.2031 \; \;; #X scalar trace-template 145 0 21 \; 104.367 57.6511 \; 104.413 56.4335 \; 104.49 51.622 \; \;; #X scalar trace-template 145 0 22 \; 104.055 59.2627 \; 104.112 60.5614 \; 103.987 56.4863 \; \;; #X scalar trace-template 150 0 5 \; 97.0387 63.4862 \; 96.8883 56.7906 \; \;; #X scalar trace-template 150 0 10 \; 73.4964 58.6867 \; 73.132 57.006 \; 72.5959 52.2778 \; 72.3012 46.7949 \; 72.4469 43.2487 \; 72.8347 56.4173 \; 72.8036 65.6327 \; 72.4884 70.4341 \; 72.2612 71.256 \; 72.192 69.4709 \; 72.1761 65.3692 \; 72.1727 58.7169 \; \;; #X scalar trace-template 150 0 13 \; 102.91 56.0969 \; \;; #X scalar trace-template 150 0 18 \; 103.859 57.8932 \; 103.854 53.6061 \; \;; #X scalar trace-template 150 0 24 \; 103.24 55.3534 \; \;; #X scalar trace-template 155 0 4 \; 105.846 57.1241 \; 105.87 45.6745 \; 105.84 31.6255 \; \;; #X scalar trace-template 155 0 6 \; 104.1 54.8238 \; 104.292 41.62 \; \;; #X scalar trace-template 155 0 7 \; 104.659 52.0965 \; \;; #X scalar trace-template 155 0 9 \; 79.2186 53.3809 \; 79.0163 49.2866 \; 79.3079 43.6751 \; 79.3195 45.32 \; 79.2421 57.8438 \; 78.7816 61.5107 \; 78.5544 60.7085 \; 78.2576 61.3503 \; 78.1299 60.9071 \; 78.0477 58.0177 \; 77.9596 51.9549 \; \;; #X scalar trace-template 155 0 13 \; 89.5825 51.8688 \; \;; #X scalar trace-template 155 0 17 \; 76.7088 51.9108 \; 76.8432 46.4259 \; 77.8523 44.1406 \; 78.197 49.433 \; \;; #X scalar trace-template 155 0 24 \; 91.0294 50.8573 \; \;; #X scalar trace-template 160 0 1 \; 58.7854 73.5324 \; \;; #X scalar trace-template 160 0 3 \; 97.4373 50.5792 \; \;; #X scalar trace-template 160 0 5 \; 69.8033 52.0408 \; 69.0208 43.5237 \; 68.9326 56.827 \; 68.9851 66.3004 \; 69.1314 74.2815 \; 68.9457 79.5783 \; 68.5964 82.7769 \; 68.3265 83.2435 \; 68.1623 80.7762 \; 67.827 75.7023 \; 67.6299 67.8599 \; 67.7025 58.6257 \; \;; #X scalar trace-template 160 0 7 \; 97.8242 45.7325 \; 97.6397 42.3616 \; 97.7207 41.898 \; 97.6372 45.4791 \; \;; #X scalar trace-template 160 0 11 \; 81.072 47.1297 \; 80.2749 37.1673 \; 80.1904 41.7085 \; \;; #X scalar trace-template 160 0 12 \; 103.569 46.0626 \; 103.454 29.1254 \; 103.363 30.8575 \; 103.483 43.4293 \; 103.455 55.1119 \; 103.404 61.7872 \; 103.393 63.4632 \; 103.299 59.9118 \; 103.275 51.6698 \; \;; #X scalar trace-template 160 0 13 \; 82.7284 45.6134 \; \;; #X scalar trace-template 160 0 14 \; 75.8736 44.046 \; 75.4219 40.5243 \; 75.3126 45.842 \; 76.0672 54.4199 \; 75.9607 54.0018 \; 75.7005 54.6561 \; 75.2585 59.118 \; 75.3474 58.5097 \; 75.3939 56.9321 \; 75.3269 52.0046 \; \;; #X scalar trace-template 160 0 18 \; 89.0491 40.8756 \; \;; #X scalar trace-template 160 0 21 \; 83.1307 46.0906 \; 82.937 23.7351 \; 83.2355 39.4904 \; \;; #X scalar trace-template 160 0 22 \; 103.089 41.5226 \; \;; #X scalar trace-template 160 0 24 \; 87.6398 41.8453 \; \;; #X scalar trace-template 165 0 1 \; 67.279 60.564 \; \;; #X scalar trace-template 165 0 3 \; 78.8806 43.5405 \; \;; #X scalar trace-template 165 0 6 \; 77.1702 39.9933 \; \;; #X scalar trace-template 165 0 13 \; 96.8905 39.4582 \; 96.9248 36.8833 \; \;; #X scalar trace-template 165 0 16 \; 81.4454 34.6657 \; \;; #X scalar trace-template 165 0 18 \; 71.4971 44.8011 \; \;; #X scalar trace-template 165 0 22 \; 74.1322 29.2826 \; \;; #X scalar trace-template 165 0 23 \; 84.3907 32.3293 \; \;; #X scalar trace-template 165 0 24 \; 98.425 30.714 \; \;; #X scalar trace-template 170 0 1 \; 63.0613 51.8605 \; \;; #X scalar trace-template 170 0 3 \; 69.8808 52.7738 \; \;; #X scalar trace-template 170 0 4 \; 72.8347 42.8028 \; 73.3294 60.0839 \; \;; #X scalar trace-template 170 0 6 \; 83.6038 40.2629 \; 83.7488 60.8388 \; 83.6118 61.1732 \; 83.6416 59.2213 \; \;; #X scalar trace-template 170 0 16 \; 98.0969 33.0531 \; 98.0865 44.3888 \; 98.0603 54.4928 \; 98.052 60.8425 \; 98.0076 63.9834 \; 97.9835 63.2399 \; 97.919 58.6122 \; \;; #X scalar trace-template 170 0 18 \; 95.5827 32.4406 \; \;; #X scalar trace-template 170 0 20 \; 98.9543 31.4913 \; 98.8589 40.5702 \; \;; #X scalar trace-template 170 0 22 \; 94.2174 31.0072 \; \;; #X scalar trace-template 170 0 23 \; 85.8439 30.8784 \; 86.2516 42.0567 \; 86.3862 53.5239 \; 86.3392 62.3554 \; 86.2914 64.6131 \; 85.9585 62.4475 \; 85.826 55.4383 \; \;; #X scalar trace-template 170 0 24 \; 92.9538 29.4611 \; \;; #X scalar trace-template 175 0 1 \; 83.9354 58.8144 \; \;; #X scalar trace-template 175 0 2 \; 85.1639 47.1991 \; 84.9908 61.3567 \; 84.8308 66.4198 \; 84.6646 64.7867 \; 84.4705 58.0568 \; \;; #X scalar trace-template 175 0 3 \; 76.4174 52.7469 \; 77.4491 51.5702 \; \;; #X scalar trace-template 175 0 11 \; 97.1236 46.2216 \; \;; #X scalar trace-template 175 0 13 \; 105.835 40.7383 \; 105.978 49.2075 \; 106.031 56.7109 \; 105.999 58.0012 \; 105.973 56.2105 \; \;; #X scalar trace-template 175 0 17 \; 103.057 40.096 \; 102.913 49.0831 \; 102.808 55.3774 \; 102.73 55.7971 \; \;; #X scalar trace-template 175 0 18 \; 104.07 39.6159 \; 104.012 51.5969 \; 103.978 60.8304 \; \;; #X scalar trace-template 175 0 21 \; 103.626 37.5581 \; \;; #X scalar trace-template 175 0 22 \; 105.307 37.6238 \; \;; #X scalar trace-template 175 0 24 \; 96.3502 37.7664 \; 96.3927 47.8998 \; \;; #X scalar trace-template 180 0 1 \; 53.8911 67.3249 \; \;; #X scalar trace-template 180 0 4 \; 82.1272 66.4862 \; \;; #X scalar trace-template 180 0 7 \; 82.4572 61.6346 \; 82.2939 65.5493 \; 82.4371 61.8962 \; 82.4334 57.5816 \; 82.2831 53.503 \; \;; #X scalar trace-template 180 0 11 \; 81.3092 64.7334 \; 81.0542 63.1777 \; 80.5738 60.1169 \; 80.3458 57.9887 \; 80.2331 54.4228 \; \;; #X scalar trace-template 180 0 20 \; 30.9649 57.8221 \; \;; #X scalar trace-template 180 0 21 \; 79.6756 58.8891 \; 80.0306 55.445 \; \;; #X scalar trace-template 180 0 22 \; 87.6305 50.6796 \; 87.6824 61.3363 \; 87.7738 65.5553 \; 87.6706 63.9521 \; 87.5926 58.3977 \; 87.4044 49.0299 \; \;; #X scalar trace-template 185 0 1 \; 41.5517 64.6704 \; 30.5406 67.801 \; 31.2086 64.8856 \; 38.4538 57.4354 \; \;; #X scalar trace-template 185 0 3 \; 88.9938 55.8587 \; 89.0075 64.1778 \; 89.0137 67.1789 \; 89.0181 64.5468 \; 89.0589 58.319 \; \;; #X scalar trace-template 185 0 4 \; 103.928 62.9257 \; 103.913 62.6543 \; 103.909 62.2848 \; 103.918 58.3983 \; 104.071 54.312 \; \;; #X scalar trace-template 185 0 20 \; 74.6972 57.8181 \; \;; #X scalar trace-template 185 0 24 \; 104.478 54.7945 \; 104.424 57.2808 \; 104.365 59.383 \; 104.291 56.8206 \; 104.239 50.2427 \; \;; #X scalar trace-template 190 0 6 \; 90.1444 54.9002 \; 90.1774 60.3139 \; 90.1872 62.5949 \; 90.1773 59.8964 \; \;; #X scalar trace-template 190 0 18 \; 105.486 56.451 \; \;; #X scalar trace-template 190 0 20 \; 106.488 55.4928 \; \;; #X scalar trace-template 190 0 21 \; 102.894 52.3808 \; \;; #X scalar trace-template 195 0 17 \; 86.7483 58.3287 \; \;; #X scalar trace-template 195 0 18 \; 98.7084 57.0523 \; 98.7554 57.7563 \; 98.8544 55.7785 \; \;; #X scalar trace-template 195 0 20 \; 103.445 57.9885 \; \;; #X scalar trace-template 195 0 21 \; 91.1551 56.5026 \; 91.1378 55.5348 \; \;; #X scalar trace-template 200 0 2 \; 88.2358 53.3418 \; \;; #X scalar trace-template 200 0 13 \; 104.445 54.5809 \; 104.489 49.3027 \; \;; #X scalar trace-template 200 0 17 \; 99.0175 54.5166 \; \;; #X scalar trace-template 200 0 20 \; 99.4227 53.3752 \; \;; #X scalar trace-template 205 0 1 \; 17.8806 55.9034 \; \;; #X scalar trace-template 205 0 2 \; 111.325 51.4995 \; 111.249 57.7763 \; \;; #X scalar trace-template 205 0 7 \; 115.645 52.6935 \; 115.652 55.3135 \; 115.624 58.579 \; \;; #X scalar trace-template 205 0 8 \; 88.7186 53.0937 \; \;; #X scalar trace-template 205 0 11 \; 110.81 54.5493 \; \;; #X scalar trace-template 205 0 12 \; 111.534 48.8612 \; 111.503 60.7063 \; 111.473 64.4167 \; 111.44 64.4249 \; 111.429 65.1964 \; 111.435 64.716 \; 111.461 59.5964 \; \;; #X scalar trace-template 205 0 16 \; 107.192 51.3543 \; \;; #X scalar trace-template 205 0 17 \; 107.725 51.722 \; \;; #X scalar trace-template 205 0 20 \; 110.775 53.9938 \; 110.765 60.1593 \; 110.863 62.3883 \; 110.884 62.5401 \; 110.892 64.4451 \; 110.865 64.5475 \; 110.827 63.6657 \; 110.8 63.3741 \; 110.763 60.8118 \; 110.731 61.8331 \; 110.737 62.5076 \; 110.729 61.6645 \; 110.748 58.3789 \; \;; #X scalar trace-template 205 0 21 \; 115.855 50.5927 \; \;; #X scalar trace-template 205 0 23 \; 110.3 49.7937 \; 110.212 59.207 \; 110.234 64.4164 \; 110.251 69.1681 \; 110.258 71.0713 \; 110.247 67.8894 \; 110.231 62.9948 \; \;; #X scalar trace-template 210 0 1 \; 119.046 57.9889 \; 119.026 63.4287 \; 119.028 63.1849 \; 119.031 60.9702 \; \;; #X scalar trace-template 210 0 3 \; 115.101 56.6111 \; 115.102 63.0497 \; \;; #X scalar trace-template 210 0 4 \; 114.048 63.5805 \; 114.069 60.2282 \; 114.098 60.5725 \; 114.195 60.5632 \; 114.217 61.9178 \; 114.199 59.9502 \; \;; #X scalar trace-template 210 0 6 \; 118.711 56.2782 \; 118.641 58.5951 \; \;; #X scalar trace-template 210 0 8 \; 112.94 55.4876 \; 112.936 60.2285 \; \;; #X scalar trace-template 210 0 9 \; 114.28 55.6778 \; 114.319 59.0834 \; \;; #X scalar trace-template 210 0 10 \; 111.215 59.9421 \; 111.177 59.4391 \; 111.146 61.243 \; 111.13 61.8664 \; 111.136 63.1439 \; 111.173 63.9344 \; 111.245 61.7362 \; 111.21 56.2196 \; 111.239 57.173 \; 111.305 58.2531 \; 111.333 60.3108 \; 111.323 59.7934 \; 111.293 57.1695 \; \;; #X scalar trace-template 210 0 11 \; 113.501 58.3075 \; \;; #X scalar trace-template 210 0 13 \; 114.929 56.021 \; 114.919 59.4994 \; 114.929 61.7452 \; \;; #X scalar trace-template 210 0 14 \; 118.813 53.5036 \; 118.787 60.0132 \; 118.784 61.2655 \; \;; #X scalar trace-template 210 0 16 \; 114.025 58.6071 \; \;; #X scalar trace-template 210 0 17 \; 114.038 59.1291 \; \;; #X scalar trace-template 210 0 18 \; 115.32 54.0326 \; 115.315 60.519 \; 115.303 63.62 \; 115.288 63.4663 \; 115.299 60.4082 \; \;; #X scalar trace-template 210 0 21 \; 108.217 53.6661 \; \;; #X scalar trace-template 210 0 22 \; 113.466 58.9355 \; \;; #X scalar trace-template 210 0 24 \; 110.15 56.6294 \; \;; #X scalar trace-template 215 0 2 \; 109.638 61.7566 \; 109.669 67.3405 \; 109.728 64.2821 \; 109.71 64.7634 \; 109.767 62.9047 \; 109.769 60.0289 \; 109.773 58.7574 \; 109.704 61.8176 \; 109.71 66.4914 \; 109.749 66.836 \; \;; #X scalar trace-template 215 0 11 \; 110.72 61.4758 \; \;; #X scalar trace-template 215 0 15 \; 115.077 64.9949 \; 115.065 64.0915 \; 115.006 63.3023 \; 114.995 61.5753 \; 115.006 60.807 \; 115.021 62.7056 \; 115.019 62.0787 \; 115.037 61.6848 \; 115.031 60.1042 \; 115.005 59.2332 \; 114.99 58.5249 \; \;; #X scalar trace-template 215 0 16 \; 110.311 58.8075 \; \;; #X scalar trace-template 215 0 17 \; 115.52 58.2548 \; 115.565 62.0643 \; 115.547 61.0246 \; \;; #X scalar trace-template 215 0 21 \; 115.788 58.245 \; 115.788 59.9369 \; \;; #X scalar trace-template 215 0 22 \; 111.978 57.8804 \; \;; #X scalar trace-template 215 0 24 \; 109.705 61.3998 \; \;; #X scalar trace-template 220 0 3 \; 109.629 69.1354 \; 109.611 66.3531 \; 109.589 64.3165 \; 109.559 60.1706 \; 109.506 58.6773 \; 109.513 58.4946 \; 109.535 59.8422 \; 109.482 62.0589 \; 109.451 64.4827 \; 109.411 62.0315 \; \;; #X scalar trace-template 220 0 5 \; 108.539 61.2289 \; 108.534 62.8229 \; 108.479 60.3829 \; \;; #X scalar trace-template 220 0 6 \; 111.563 59.8638 \; \;; #X scalar trace-template 220 0 7 \; 109.983 60.9428 \; 109.952 64.8453 \; 109.97 66.9026 \; 109.981 66.6552 \; 109.931 61.7871 \; 109.935 53.9882 \; \;; #X scalar trace-template 220 0 8 \; 108.825 60.9774 \; 108.827 61.9332 \; 108.827 60.436 \; \;; #X scalar trace-template 220 0 9 \; 112.253 60.4079 \; 112.286 59.9168 \; 112.302 59.1805 \; \;; #X scalar trace-template 220 0 11 \; 119.185 59.4943 \; 119.195 63.38 \; 119.185 62.5575 \; \;; #X scalar trace-template 220 0 16 \; 114.465 60.2056 \; 114.416 61.0626 \; 114.411 61.535 \; 114.377 62.2623 \; 114.37 61.0554 \; 114.329 58.4786 \; \;; #X scalar trace-template 220 0 22 \; 114.795 58.1419 \; 114.804 61.6074 \; 114.806 64.8347 \; 114.777 62.5979 \; 114.734 60.6226 \; 114.709 58.6048 \; 114.684 56.1249 \; \;; #X scalar trace-template 220 0 24 \; 118.887 58.2542 \; \;; #X scalar trace-template 225 0 6 \; 112.113 62.6333 \; 112.133 65.0886 \; 112.108 62.0882 \; 112.135 58.622 \; \;; #X scalar trace-template 225 0 13 \; 115.073 56.0988 \; 115.103 59.9038 \; 115.111 60.8423 \; 115.136 58.9259 \; 115.158 60.0511 \; 115.167 58.4997 \; 115.197 58.9281 \; \;; #X scalar trace-template 225 0 14 \; 113.941 61.0123 \; 113.946 63.9524 \; 113.955 63.7432 \; 113.975 61.6876 \; 114.013 57.603 \; 114.05 56.9921 \; 114.096 57.6646 \; \;; #X scalar trace-template 225 0 19 \; 113.066 59.8583 \; 113.073 63.0846 \; 113.063 64.442 \; 113.053 64.0318 \; 113.063 63.1794 \; 113.081 62.5089 \; 113.097 60.0062 \; \;; #X scalar trace-template 225 0 21 \; 116.143 60.7241 \; 116.078 60.8979 \; 116.074 58.8135 \; \;; #X scalar trace-template 225 0 24 \; 111.789 60.2285 \; 111.802 64.6584 \; 111.822 66.3942 \; 111.796 64.1547 \; 111.793 58.9821 \; 111.859 58.7194 \; 111.897 60.9679 \; 111.904 58.9696 \; \;; #X scalar trace-template 230 0 0 \; 111.904 61.0514 \; \;; #X scalar trace-template 230 0 1 \; 113.628 62.2073 \; 113.657 61.3381 \; 113.714 57.7217 \; \;; #X scalar trace-template 230 0 17 \; 111.254 59.3837 \; \;; #X scalar trace-template 235 0 0 \; 110.065 58.8539 \; 110.035 62.7027 \; 110.079 58.5743 \; 110.031 58.9951 \; 110.009 62.3068 \; 109.978 66.9502 \; 110.01 65.4379 \; 109.973 64.1758 \; \;; #X scalar trace-template 235 0 5 \; 110.601 63.4055 \; 110.576 64.7381 \; 110.535 63.5107 \; 110.485 65.5188 \; \;; #X scalar trace-template 235 0 8 \; 112.141 65.3132 \; 112.216 60.6577 \; 112.263 56.6106 \; 112.299 56.9005 \; 112.32 58.5459 \; 112.323 58.8555 \; 112.328 58.3102 \; \;; #X scalar trace-template 235 0 9 \; 110.98 59.7334 \; 110.954 59.3772 \; 110.902 59.5167 \; \;; #X scalar trace-template 235 0 11 \; 115.443 60.8204 \; 115.442 61.3795 \; 115.447 61.2352 \; 115.454 57.5713 \; \;; #X scalar trace-template 235 0 17 \; 116.573 61.2182 \; 116.59 59.9929 \; 116.597 57.4185 \; \;; #X scalar trace-template 235 0 18 \; 118.598 60.1757 \; 118.605 57.1415 \; \;; #X scalar trace-template 240 0 4 \; 111.148 59.8725 \; 111.118 56.7723 \; \;; #X scalar trace-template 240 0 12 \; 114.505 55.5804 \; \;; #X scalar trace-template 240 0 21 \; 109.206 57.3355 \; 109.171 56.8109 \; 109.129 62.5785 \; 109.133 66.4944 \; 109.133 65.843 \; 109.139 61.1267 \; \;; #X scalar trace-template 240 0 23 \; 113.243 57.4388 \; 113.216 58.8721 \; 113.238 58.8026 \; 113.289 61.7848 \; 113.297 61.9071 \; 113.304 59.0348 \; \;; #X scalar trace-template 245 0 1 \; 110.365 57.4322 \; \;; #X scalar trace-template 245 0 6 \; 116.886 57.2863 \; 116.877 58.8456 \; \;; #X scalar trace-template 245 0 12 \; 114.203 56.4883 \; 114.193 59.3781 \; 114.23 60.3238 \; 114.234 61.4562 \; 114.285 60.0183 \; \;; #X scalar trace-template 245 0 18 \; 113.557 55.8053 \; 113.533 59.4318 \; 113.563 59.4649 \; \;; #X scalar trace-template 250 0 1 \; 110.445 64.0536 \; 110.445 67.8681 \; 110.411 70.3933 \; 110.379 68.4655 \; 110.313 63.0308 \; \;; #X scalar trace-template 250 0 4 \; 108.188 57.5731 \; 108.189 59.1263 \; \;; #X scalar trace-template 250 0 7 \; 114.512 57.0767 \; 114.521 61.2863 \; 114.5 62.9911 \; 114.423 58.6997 \; \;; #X scalar trace-template 250 0 9 \; 115.691 54.7675 \; 115.682 62.0605 \; 115.71 63.5017 \; 115.711 58.1871 \; \;; #X scalar trace-template 250 0 16 \; 113.344 56.9144 \; \;; #X scalar trace-template 250 0 17 \; 118.389 56.1649 \; 118.352 59.2933 \; 118.325 58.9929 \; \;; #X scalar trace-template 255 0 5 \; 118.53 59.7843 \; 118.545 61.4914 \; 118.549 60.1962 \; \;; #X scalar trace-template 255 0 6 \; 111.505 58.511 \; 111.5 63.1154 \; 111.5 62.817 \; 111.502 58.4828 \; \;; #X scalar trace-template 255 0 11 \; 116.53 59.4521 \; 116.525 59.4614 \; \;; #X scalar trace-template 255 0 16 \; 115.881 58.9615 \; 115.886 59.8338 \; \;; #X scalar trace-template 255 0 22 \; 114.357 56.6608 \; \;; #X scalar trace-template 260 0 4 \; 112.11 59.542 \; 112.104 60.3085 \; 112.079 56.1448 \; \;; #X scalar trace-template 260 0 13 \; 117.319 59.9772 \; \;; #X scalar trace-template 260 0 14 \; 119.079 59.4458 \; 119.048 60.4763 \; 119.03 56.9412 \; \;; #X scalar trace-template 260 0 18 \; 112.498 59.3368 \; 112.487 57.986 \; \;; #X scalar trace-template 260 0 19 \; 118.078 59.1041 \; 118.079 58.0394 \; \;; #X scalar trace-template 260 0 22 \; 116.08 59.6963 \; 116.082 58.787 \; \;; #X scalar trace-template 265 0 2 \; 109.889 67.2814 \; 109.891 63.6715 \; 109.887 51.8722 \; \;; #X scalar trace-template 265 0 11 \; 115.311 60.044 \; 115.327 56.0445 \; \;; #X scalar trace-template 265 0 13 \; 114.162 59.4405 \; \;; #X scalar trace-template 265 0 16 \; 114.525 57.7139 \; \;; #X scalar trace-template 265 0 17 \; 108.903 57.9206 \; \;; #X scalar trace-template 265 0 24 \; 113.727 57.8469 \; \;; #X scalar trace-template 270 0 3 \; 65.9686 65.8084 \; 66.3367 75.9846 \; 66.2735 78.8915 \; 65.8919 76.6756 \; 65.2994 73.5396 \; 64.9346 71.8191 \; 64.8234 70.8531 \; 65.1388 70.521 \; 65.7272 70.5762 \; 66.1835 70.6078 \; 66.4891 70.4807 \; 66.3697 70.2349 \; 65.9628 70.1615 \; 65.467 69.6348 \; 64.8712 67.3478 \; 64.2939 62.4146 \; 63.8362 53.1106 \; 63.4845 45.5518 \; 64.7161 51.871 \; 63.6534 56.1168 \; \;; #X scalar trace-template 270 0 5 \; 71.84 63.9345 \; 71.7913 77.3996 \; 71.7682 80.1257 \; 72.3407 76.842 \; \;; #X scalar trace-template 270 0 7 \; 67.5248 63.0406 \; \;; #X scalar trace-template 270 0 8 \; 53.8098 68.1673 \; 50.3304 74.3326 \; 47.8106 81.3903 \; 47.3139 83.8828 \; 46.5068 83.6372 \; 46.203 82.54 \; 45.9237 81.7084 \; 45.9361 81.2276 \; 46.3232 81.2229 \; 46.8654 81.5735 \; 47.3105 82.0669 \; 47.502 82.6299 \; 47.3722 83.254 \; 47.0065 83.9353 \; 46.4437 84.3165 \; 46.0045 83.5199 \; 45.7966 80.558 \; 47.6625 72.717 \; 47.0243 65.6857 \; 48.7035 62.6193 \; \;; #X scalar trace-template 270 0 9 \; 55.3584 69.4826 \; \;; #X scalar trace-template 270 0 12 \; 86.8658 58.8014 \; 86.912 69.1698 \; 86.7528 73.9734 \; 86.7273 73.1923 \; \;; #X scalar trace-template 270 0 13 \; 44.6287 49.1555 \; \;; #X scalar trace-template 270 0 15 \; 110.397 62.042 \; \;; #X scalar trace-template 270 0 16 \; 56.6758 66.0351 \; 57.3305 71.4322 \; 58.2789 77.4319 \; 58.4864 79.2017 \; 58.3734 78.1804 \; 57.9676 77.3786 \; 57.7343 76.8948 \; 57.9555 75.9782 \; 58.4443 74.941 \; 59.0144 74.0265 \; 59.3994 73.5609 \; 59.4371 73.6964 \; 59.1224 74.3365 \; 58.7575 75.159 \; 58.1458 74.515 \; 56.8487 71.8626 \; 55.5518 67.2782 \; 54.5964 60.0755 \; 55.529 52.5102 \; 55.6479 58.3431 \; 55.6832 60.8044 \; 54.9739 56.384 \; 55.7407 43.3155 \; 53.5182 36.9447 \; \;; #X scalar trace-template 270 0 17 \; 76.367 55.7239 \; 75.3837 73.318 \; \;; #X scalar trace-template 270 0 18 \; 85.8479 54.4204 \; 85.917 64.6292 \; 86.1501 68.6243 \; 86.4352 72.906 \; \;; #X scalar trace-template 270 0 19 \; 80.913 54.4039 \; 80.8744 63.2538 \; 80.5411 65.1817 \; 80.1955 68.144 \; 79.7511 69.9625 \; 79.4881 72.3306 \; 79.4548 74.0702 \; 79.715 72.4458 \; 80.0179 69.9682 \; \;; #X scalar trace-template 270 0 20 \; 84.8546 54.1655 \; 85.0033 64.0831 \; 84.898 69.3132 \; 85.0036 69.5424 \; 84.7346 67.5814 \; 84.8998 61.4702 \; 84.7841 58.7264 \; 84.6708 66.1913 \; 84.4924 68.2757 \; \;; #X scalar trace-template 270 0 21 \; 88.9782 53.9525 \; 88.8066 63.2468 \; 88.9378 58.0831 \; 88.9959 60.1172 \; 89.0436 63.3059 \; \;; #X scalar trace-template 270 0 22 \; 106.075 57.3922 \; 106.175 56.7511 \; \;; #X scalar trace-template 270 0 23 \; 88.3355 55.991 \; 87.9031 59.4032 \; 87.9726 63.6924 \; 87.8944 66.4185 \; \;; #X scalar trace-template 270 0 24 \; 77.7802 54.7733 \; 78.1053 63.2959 \; 77.716 70.3242 \; \;; #X scalar trace-template 275 0 0 \; 75.0451 73.7116 \; 75.0121 77.5542 \; 74.7802 82.0388 \; 74.5169 81.6509 \; 73.9392 78.558 \; 73.6926 76.8281 \; 73.9043 74.6795 \; 74.5242 75.4796 \; 75.0402 75.9337 \; 75.2989 76.2206 \; 75.2603 75.3861 \; 74.8493 74.2081 \; 74.4939 73.6658 \; 74.0272 69.1504 \; 73.4653 61.6327 \; 72.3234 49.0497 \; \;; #X scalar trace-template 275 0 1 \; 83.2187 62.5531 \; 82.8822 66.8277 \; 82.6493 69.5774 \; 82.6751 66.5763 \; \;; #X scalar trace-template 275 0 4 \; 88.6456 64.1159 \; 88.6222 63.8715 \; 88.4373 63.8516 \; 88.613 61.1168 \; 88.7909 64.8887 \; 88.7482 63.5686 \; 88.5291 60.5847 \; 88.5281 60.9204 \; 88.3346 58.9126 \; 88.5546 52.4593 \; \;; #X scalar trace-template 275 0 6 \; 83.9273 60.0344 \; \;; #X scalar trace-template 275 0 7 \; 76.7559 58.9207 \; \;; #X scalar trace-template 275 0 9 \; 90.1161 55.5294 \; 89.93 60.6368 \; 89.9133 62.0459 \; 90.1329 60.8106 \; 90.1941 63.7221 \; 90.1321 61.2938 \; 90.0018 57.5945 \; 90.0171 56.8389 \; \;; #X scalar trace-template 275 0 10 \; 105.671 55.7996 \; 105.685 59.0066 \; \;; #X scalar trace-template 275 0 11 \; 98.4533 55.4107 \; \;; #X scalar trace-template 275 0 13 \; 90.8799 54.7789 \; 90.9463 59.8699 \; 90.8862 62.8499 \; 90.4505 62.1378 \; \;; #X scalar trace-template 275 0 14 \; 91.4668 54.6648 \; \;; #X scalar trace-template 275 0 15 \; 20.6781 53.6597 \; 33.9453 58.3999 \; \;; #X scalar trace-template 280 0 2 \; 71.4711 82.6449 \; 71.3935 80.9503 \; 70.4116 76.1308 \; 69.8358 73.5168 \; 69.7831 73.5962 \; 70.2045 73.5824 \; 70.7012 73.567 \; 71.1429 73.2073 \; 71.4238 73.2852 \; 71.3872 72.923 \; 71.0362 72.0984 \; 70.708 71.3443 \; 70.692 66.6931 \; 69.3768 59.0069 \; 69.0003 46.2925 \; 70.536 43.4584 \; \;; #X scalar trace-template 280 0 6 \; 63.1915 65.5449 \; \;; #X scalar trace-template 280 0 7 \; 78.7255 65.929 \; 78.5699 65.5992 \; 78.4811 65.4891 \; \;; #X scalar trace-template 280 0 11 \; 77.3169 67.7731 \; 77.3407 73.0564 \; 77.2765 78.4436 \; 77.0359 80.3724 \; 76.8754 80.1772 \; 77.0518 77.4236 \; \;; #X scalar trace-template 280 0 14 \; 81.3124 63.0026 \; 81.5615 62.7425 \; 82.0572 69.6073 \; 81.8468 71.1511 \; 81.8037 71.3624 \; 82.0847 69.7455 \; \;; #X scalar trace-template 280 0 17 \; 89.4588 62.2316 \; 89.4408 64.327 \; 89.5149 61.3408 \; \;; #X scalar trace-template 280 0 22 \; 24.8204 59.8282 \; 29.3809 63.0958 \; 25.2902 59.6049 \; 16.7656 53.9698 \; 20.9359 51.4195 \; \;; #X scalar trace-template 285 0 6 \; 86.2507 75.3941 \; 86.3115 77.1975 \; 85.9838 67.4354 \; 86.0954 63.7488 \; 85.7499 67.3665 \; 85.6874 64.143 \; 85.5044 70.0089 \; 85.5389 73.1947 \; 85.5332 72.2809 \; 85.3309 68.7508 \; 85.1764 62.8604 \; \;; #X scalar trace-template 285 0 10 \; 84.4587 68.7666 \; 84.1132 69.2742 \; 83.7949 71.1896 \; 83.741 71.7189 \; 83.2926 68.0278 \; 83.1492 70.1776 \; 83.2333 72.9146 \; 83.4398 73.7301 \; 83.42 72.5027 \; 83.267 70.4536 \; 83.3528 64.4197 \; 83.6425 61.4444 \; 83.884 52.8312 \; 83.5122 42.0604 \; \;; #X scalar trace-template 285 0 15 \; 87.3927 65.4395 \; 87.4933 69.3678 \; 87.3374 71.4398 \; 87.2281 69.9882 \; 87.0983 65.4227 \; 86.9752 66.5857 \; 87.2238 66.4384 \; 87.3403 69.5367 \; 87.3364 69.1862 \; 87.0528 69.2754 \; 87.0426 66.0437 \; 87.3775 62.4298 \; 87.6385 57.9551 \; \;; #X scalar trace-template 285 0 24 \; 91.2876 59.9734 \; 90.8948 61.2393 \; \;; #X scalar trace-template 290 0 5 \; 106.116 55.1795 \; 106.079 60.0972 \; 106.083 55.1332 \; 106.06 54.8265 \; \;; #X scalar trace-template 290 0 12 \; 91.3807 59.6788 \; 91.451 61.0052 \; 91.3952 59.5706 \; 91.3477 56.0827 \; 91.3871 54.9769 \; \;; #X scalar trace-template 290 0 18 \; 105.698 59.6684 \; 105.563 58.6258 \; 105.545 55.9086 \; 105.508 55.8106 \; \;; #X scalar trace-template 290 0 23 \; 105.975 60.0982 \; 105.931 56.3563 \; 105.87 54.5686 \; \;; #X scalar trace-template 295 0 1 \; 85.646 72.4317 \; 85.6128 73.0186 \; 85.2783 67.1105 \; 85.1193 68.9657 \; 84.8442 66.5232 \; 85.0036 56.9935 \; 84.8872 62.6059 \; 84.7007 67.5506 \; 84.7055 68.8174 \; 84.5233 64.4014 \; 84.6818 56.0597 \; 84.7593 44.5969 \; \;; #X scalar trace-template 295 0 7 \; 86.3684 71.0242 \; \;; #X scalar trace-template 295 0 13 \; 80.2939 58.6706 \; \;; #X scalar trace-template 295 0 17 \; 92.6661 58.8559 \; 92.6005 55.8888 \; \;; #X scalar trace-template 295 0 21 \; 105.711 55.3819 \; \;; #X scalar trace-template 295 0 24 \; 93.8067 56.7854 \; \;; #X scalar trace-template 300 0 7 \; 74.643 68.193 \; \;; #X scalar trace-template 300 0 13 \; 77.8146 67.2281 \; 77.8315 70.5002 \; 77.7824 77.0494 \; 78.2746 78.0049 \; 78.5198 79.177 \; 78.4953 78.3465 \; 78.1017 76.4747 \; 77.593 75.1091 \; 77.2742 72.1158 \; 77.0455 63.9008 \; 77.2983 49.3089 \; \;; #X scalar trace-template 300 0 21 \; 82.7586 57.6481 \; 82.776 68.5881 \; 82.5275 70.57 \; \;; #X scalar trace-template 300 0 24 \; 87.8288 54.7669 \; 88.1147 60.3502 \; 87.9758 60.0941 \; \;; #X scalar trace-template 305 0 7 \; 83.9708 67.5223 \; \;; #X scalar trace-template 305 0 17 \; 86.4256 66.1859 \; 86.3199 67.4379 \; 86.1002 64.8715 \; \;; #X scalar trace-template 305 0 22 \; 89.5634 55.0015 \; 89.5044 55.4601 \; \;; #X scalar trace-template 305 0 23 \; 88.9755 55.1891 \; 88.9778 54.1275 \; 88.9778 59.5792 \; 89.0019 64.0404 \; 88.8786 63.9426 \; 88.6571 64.7298 \; 88.6237 62.788 \; 88.8031 56.8166 \; \;; #X scalar trace-template 310 0 5 \; 80.8241 68.5095 \; 80.9117 70.2604 \; 81.222 72.2413 \; 81.0717 72.3586 \; 80.5761 72.1063 \; 80.2165 72.0208 \; 79.9316 68.876 \; 79.5233 62.0462 \; 78.7345 52.5548 \; \;; #X scalar trace-template 310 0 7 \; 79.4144 65.2541 \; \;; #X scalar trace-template 310 0 11 \; 87.4727 59.4454 \; \;; #X scalar trace-template 310 0 14 \; 105.817 56.1494 \; 105.833 60.6558 \; 105.87 62.9625 \; 105.878 63.5852 \; 105.828 60.7864 \; 105.73 59.3848 \; 105.675 54.251 \; \;; #X scalar trace-template 310 0 18 \; 106.387 54.491 \; 106.426 58.0307 \; 106.464 60.194 \; 106.472 60.4796 \; \;; #X scalar trace-template 315 0 7 \; 86.7028 64.7523 \; 86.9115 57.9052 \; 86.7603 64.4256 \; 86.5063 66.7744 \; 86.5963 68.2344 \; 86.3281 64.5333 \; 86.3183 53.9856 \; \;; #X scalar trace-template 315 0 9 \; 105.224 59.0693 \; 105.261 61.5415 \; 105.273 62.1986 \; 105.221 59.9921 \; 105.154 58.7847 \; 105.105 54.3413 \; 105.045 42.7311 \; \;; #X scalar trace-template 315 0 11 \; 90.5756 59.7267 \; 90.5454 60.2136 \; 90.5263 57.802 \; 90.1035 58.9853 \; 90.07 57.9748 \; 90.2112 54.0475 \; \;; #X scalar trace-template 315 0 12 \; 104.592 56.5635 \; 104.627 59.1332 \; 104.644 59.4718 \; \;; #X scalar trace-template 315 0 19 \; 100.237 55.8602 \; 100.222 59.5315 \; 100.339 59.1349 \; \;; #X scalar trace-template 315 0 20 \; 103.95 55.7824 \; 103.97 58.7454 \; 104.008 59.6749 \; 103.998 57.7309 \; \;; #X scalar trace-template 315 0 21 \; 103.269 54.9448 \; 103.287 57.6945 \; 103.334 58.2133 \; \;; #X scalar trace-template 315 0 22 \; 101.068 54.6702 \; \;; #X scalar trace-template 315 0 24 \; 90.7356 56.6379 \; \;; #X scalar trace-template 320 0 17 \; 82.8591 61.1336 \; \;; #X scalar trace-template 320 0 22 \; 91.9623 58.3485 \; 91.928 56.0813 \; \;; #X scalar trace-template 320 0 24 \; 96.6513 56.8722 \; \;; #X scalar trace-template 325 0 4 \; 89.9368 56.2471 \; 89.669 60.3204 \; 89.6764 55.3495 \; \;; #X scalar trace-template 325 0 17 \; 99.5367 56.3944 \; \;; #X scalar trace-template 325 0 24 \; 102.633 56.1407 \; \;; #X scalar trace-template 330 0 12 \; 81.0845 66.0535 \; 81.2416 62.7177 \; 81.5531 62.3134 \; \;; #X scalar trace-template 330 0 17 \; 82.6044 67.4846 \; 82.6778 69.262 \; 82.2421 64.5732 \; 82.032 56.394 \; 82.5563 44.784 \; \;; #X scalar trace-template 330 0 18 \; 85.7432 65.5253 \; 85.9924 62.769 \; 85.6997 60.4339 \; \;; #X scalar trace-template 330 0 19 \; 88.2 65.6829 \; 88.2464 65.756 \; 88.0358 64.1864 \; \;; #X scalar trace-template 330 0 21 \; 87.573 61.644 \; 87.7796 64.4955 \; \;; #X scalar trace-template 330 0 22 \; 83.7216 62.3216 \; \;; #X scalar trace-template 330 0 24 \; 89.1766 55.5771 \; 89.4102 58.9538 \; 89.4509 58.0707 \; 89.5703 49.4026 \; 89.8847 38.0367 \; 89.9639 44.1111 \; 90.0483 49.3299 \; 90.1814 46.0072 \; 90.3714 37.4929 \; 90.4441 25.6514 \; \;; #X scalar trace-template 335 0 20 \; 78.5025 67.9036 \; 79.0676 67.0585 \; \;; #X scalar trace-template 335 0 22 \; 97.0107 56.0683 \; 97.3363 54.4821 \; 97.3009 49.7133 \; 97.1709 41.8519 \; 97.259 45.6074 \; \;; #X scalar trace-template 340 0 4 \; 74.7558 67.6013 \; 75.1131 61.0117 \; 75.6483 45.7892 \; \;; #X scalar trace-template 340 0 6 \; 82.6647 62.5293 \; \;; #X scalar trace-template 340 0 21 \; 90.8108 54.9334 \; 90.9077 48.7975 \; \;; #X scalar trace-template 345 0 6 \; 35.7851 59.4932 \; 31.7536 63.2974 \; 31.1215 65.4935 \; 28.6878 63.3004 \; 30.2833 60.9601 \; 38.311 64.1199 \; 38.9048 64.7289 \; 40.4917 57.7438 \; 38.4538 40.7919 \; 35.1935 46.8531 \; 37.0668 61.6493 \; 41.8484 64.578 \; 43.3946 73.6508 \; 42.7265 79.3467 \; 40.9228 81.5687 \; 39.4832 81.1123 \; 38.5234 80.2506 \; 38.202 79.9754 \; 38.1028 79.4859 \; 38.0069 79.3498 \; 38.0873 79.5262 \; 38.0258 79.4099 \; 37.9914 78.9947 \; 37.7747 78.3497 \; 37.5757 77.7038 \; 37.3938 77.3844 \; 37.2709 77.2654 \; 37.0865 77.0259 \; 37.0065 76.7741 \; 37.3956 76.5332 \; 37.8763 76.1895 \; 37.7784 75.3773 \; 38.0883 74.7868 \; 37.8282 73.7482 \; 37.0406 73.2887 \; 37.7628 74.3709 \; 38.2268 75.9839 \; 38.7929 77.519 \; 39.2504 78.7284 \; 39.6836 79.6803 \; 40.0322 80.609 \; 40.2782 81.2653 \; 40.4134 81.6036 \; 40.4804 81.8192 \; 40.535 81.9699 \; 40.5344 82.036 \; 40.7909 81.6955 \; 40.8477 79.4066 \; 40.5724 74.2557 \; 39.4263 67.0187 \; 40.3201 61.4596 \; 35.3883 53.9764 \; 31.9036 56.2244 \; \;; #X scalar trace-template 345 0 11 \; 87.8377 59.3892 \; 88.3514 47.2605 \; \;; #X scalar trace-template 345 0 12 \; 97.4188 42.0321 \; 97.4011 41.6583 \; \;; #X scalar trace-template 345 0 14 \; 110.493 46.6254 \; \;; #X scalar trace-template 345 0 18 \; 92.201 46.7388 \; \;; #X scalar trace-template 345 0 19 \; 91.2228 48.5465 \; 91.3755 42.6278 \; 91.2474 47.5923 \; 91.1825 51.1318 \; 91.1734 49.1408 \; 91.2814 40.2833 \; \;; #X scalar trace-template 345 0 20 \; 96.6013 46.0482 \; \;; #X scalar trace-template 345 0 23 \; 95.5346 45.4835 \; \;; #X scalar trace-template 350 0 7 \; 76.2159 28.6088 \; \;; #X scalar trace-template 350 0 9 \; 79.2708 54.4825 \; \;; #X scalar trace-template 350 0 14 \; 79.5789 53.953 \; \;; #X scalar trace-template 350 0 15 \; 118.621 50.2389 \; 118.623 56.7354 \; 118.623 56.3214 \; 118.623 52.6933 \; 118.596 42.2541 \; \;; #X scalar trace-template 350 0 18 \; 118.653 49.5421 \; 118.647 55.2675 \; \;; #X scalar trace-template 350 0 20 \; 118.812 41.8952 \; 118.839 51.9363 \; 118.858 45.9018 \; \;; #X scalar trace-template 350 0 21 \; 81.0433 41.0146 \; \;; #X scalar trace-template 350 0 23 \; 88.6085 43.4369 \; \;; #X scalar trace-template 355 0 0 \; 43.7806 72.7975 \; 44.0393 67.0753 \; 46.0688 63.188 \; 46.3916 65.948 \; \;; #X scalar trace-template 355 0 1 \; 118.812 53.1685 \; 118.81 51.6327 \; \;; #X scalar trace-template 355 0 4 \; 58.8163 43.6609 \; 58.536 49.0447 \; 58.9719 58.2416 \; \;; #X scalar trace-template 355 0 5 \; 118.217 51.0194 \; 118.214 46.8435 \; 118.203 48.852 \; 118.157 37.2743 \; \;; #X scalar trace-template 355 0 7 \; 117.195 50.1835 \; 117.188 50.3007 \; 117.186 47.2144 \; 117.182 38.4363 \; \;; #X scalar trace-template 355 0 9 \; 118.449 46.5845 \; 118.456 50.4383 \; 118.455 46.6179 \; \;; #X scalar trace-template 355 0 10 \; 118.189 51.7369 \; 118.183 50.3789 \; \;; #X scalar trace-template 355 0 11 \; 117.229 47.7081 \; \;; #X scalar trace-template 355 0 12 \; 116.9 45.3111 \; 116.922 48.6047 \; 116.927 46.1897 \; \;; #X scalar trace-template 355 0 13 \; 116.437 45.4545 \; \;; #X scalar trace-template 355 0 14 \; 103.569 44.4258 \; 103.578 48.4687 \; 103.579 47.877 \; 103.578 41.9992 \; 103.477 32.5325 \; 103.623 14.9483 \; \;; #X scalar trace-template 355 0 17 \; 62.1651 47.0133 \; 61.2075 47.0941 \; 61.2289 56.8588 \; \;; #X scalar trace-template 355 0 21 \; 74.0679 43.4681 \; \;; #X scalar trace-template 355 0 23 \; 89.4222 43.9958 \; 89.4563 48.8437 \; 89.6958 46.5906 \; \;; #X scalar trace-template 360 0 2 \; 118.871 51.1148 \; 118.879 46.6302 \; \;; #X scalar trace-template 360 0 11 \; 65.7114 53.2559 \; \;; #X scalar trace-template 360 0 13 \; 113.465 48.4965 \; 113.493 47.0391 \; 113.495 36.6357 \; \;; #X scalar trace-template 360 0 18 \; 92.1996 47.137 \; 92.2036 47.7415 \; 92.2006 43.4245 \; 92.1676 37.334 \; \;; #X scalar trace-template 360 0 21 \; 66.759 48.4603 \; \;; #X scalar trace-template 360 0 22 \; 97.7557 46.6582 \; 97.8155 48.7064 \; 97.893 44.4245 \; 97.8164 35.9603 \; 97.7443 17.8372 \; \;; #X scalar trace-template 365 0 1 \; 73.4931 47.4781 \; 72.8944 43.6083 \; 72.9651 33.3549 \; 73.0981 22.4101 \; 73.2833 32.6724 \; \;; #X scalar trace-template 365 0 10 \; 115.796 47.2363 \; 115.797 42.2171 \; \;; #X scalar trace-template 365 0 11 \; 115.194 46.379 \; \;; #X scalar trace-template 365 0 20 \; 95.328 47.0185 \; 95.3837 43.3352 \; 95.4206 31.8743 \; \;; #X scalar trace-template 365 0 21 \; 116.052 46.4809 \; \;; #X scalar trace-template 370 0 2 \; 19.2749 52.2256 \; 25.5508 55.2836 \; 29.8523 60.0216 \; 24.1448 56.15 \; 19.5336 53.3874 \; \;; #X scalar trace-template 370 0 3 \; 97.6632 42.787 \; \;; #X scalar trace-template 370 0 4 \; 95.6004 43.1966 \; 95.5311 35.313 \; \;; #X scalar trace-template 370 0 8 \; 73.6675 42.6621 \; 73.8262 32.2809 \; 74.2415 24.5126 \; 74.1419 35.5704 \; \;; #X scalar trace-template 370 0 9 \; 77.2834 41.0876 \; 77.0907 31.1442 \; \;; #X scalar trace-template 370 0 11 \; 115.744 39.5833 \; \;; #X scalar trace-template 370 0 12 \; 111.245 39.2466 \; \;; #X scalar trace-template 370 0 17 \; 102.806 40.9117 \; 102.852 28.5293 \; 102.907 14.7375 \; \;; #X scalar trace-template 370 0 21 \; 117.45 38.6995 \; \;; #X scalar trace-template 370 0 23 \; 105.997 37.223 \; \;; #X scalar trace-template 375 0 0 \; 66.3783 40.9443 \; 65.2771 33.124 \; 65.8151 28.9943 \; 65.2453 48.7031 \; 65.743 55.9395 \; 65.3801 60.6759 \; \;; #X scalar trace-template 375 0 3 \; 69.0853 30.3027 \; 68.467 28.8096 \; \;; #X scalar trace-template 375 0 5 \; 91.9387 36.7314 \; \;; #X scalar trace-template 375 0 7 \; 97.9237 36.1269 \; 98.2278 20.236 \; \;; #X scalar trace-template 375 0 10 \; 103.396 30.4241 \; 103.204 13.1761 \; \;; #X scalar trace-template 375 0 11 \; 75.4043 27.6907 \; \;; #X scalar trace-template 375 0 12 \; 77.8151 31.1187 \; \;; #X scalar trace-template 375 0 13 \; 84.3879 27.0474 \; \;; #X scalar trace-template 375 0 15 \; 94.3428 29.7513 \; \;; #X scalar trace-template 375 0 19 \; 94.4968 30.2066 \; \;; #X scalar trace-template 375 0 21 \; 79.6101 27.8398 \; 79.7246 21.2916 \; 80.1815 24.1713 \; \;; #X scalar trace-template 375 0 23 \; 86.293 24.6652 \; 86.4283 19.1084 \; \;; #X scalar trace-template 380 0 4 \; 61.2854 32.7182 \; 61.0562 33.7467 \; \;; #X scalar trace-template 380 0 5 \; 62.6765 29.4744 \; 63.6027 29.9359 \; \;; #X scalar trace-template 380 0 9 \; 97.3737 20.3509 \; \;; #X scalar trace-template 380 0 11 \; 96.9678 18.7081 \; \;; #X scalar trace-template 380 0 12 \; 71.0483 16.0877 \; \;; #X scalar trace-template 380 0 13 \; 98.9662 16.3931 \; \;; #X scalar trace-template 380 0 15 \; 99.6663 16.5622 \; 99.7906 25.8624 \; \;; #X scalar trace-template 380 0 18 \; 81.7021 15.6174 \; 81.4952 25.2012 \; \;; #X scalar trace-template 380 0 19 \; 105.412 13.9224 \; \;; #X scalar trace-template 380 0 20 \; 87.2154 16.6325 \; \;; #X scalar trace-template 380 0 24 \; 110.634 14.7738 \; 110.654 22.5543 \; \;; #X scalar trace-template 385 0 3 \; 67.1 33.6903 \; \;; #X scalar trace-template 385 0 7 \; 115.313 27.4945 \; \;; #X scalar trace-template 385 0 9 \; 107.303 26.0861 \; \;; #X scalar trace-template 385 0 10 \; 118.328 24.793 \; \;; #X scalar trace-template 385 0 11 \; 106.179 27.049 \; 106.278 46.4892 \; 106.345 50.0086 \; 106.33 52.2791 \; \;; #X scalar trace-template 385 0 12 \; 112.148 26.0024 \; \;; #X scalar trace-template 385 0 13 \; 118.136 23.8266 \; \;; #X scalar trace-template 385 0 14 \; 101.611 25.2761 \; \;; #X scalar trace-template 385 0 17 \; 101.785 25.2998 \; \;; #X scalar trace-template 385 0 19 \; 113.559 25.3039 \; 113.562 43.2953 \; \;; #X scalar trace-template 385 0 20 \; 100.005 22.0165 \; 100.238 51.3831 \; 100.226 56.3502 \; 100.311 54.9957 \; 100.322 50.8734 \; \;; #X scalar trace-template 385 0 22 \; 118.467 20.5896 \; \;; #X scalar trace-template 385 0 23 \; 113.591 26.4585 \; \;; #X scalar trace-template 390 0 1 \; 93.3693 50.0846 \; 93.3891 60.2179 \; 93.4491 59.7553 \; 93.42 60.9067 \; \;; #X scalar trace-template 390 0 3 \; 100.315 51.6171 \; \;; #X scalar trace-template 390 0 4 \; 111.721 44.8345 \; 111.722 52.0983 \; 111.724 51.5637 \; \;; #X scalar trace-template 390 0 5 \; 99.4296 43.7268 \; \;; #X scalar trace-template 390 0 7 \; 104.739 43.5809 \; 104.791 52.1069 \; 104.789 53.0115 \; \;; #X scalar trace-template 390 0 8 \; 106.823 44.7833 \; \;; #X scalar trace-template 390 0 9 \; 57.4734 43.0368 \; 54.999 52.9434 \; 51.8779 60.2172 \; \;; #X scalar trace-template 390 0 10 \; 103.964 49.2138 \; 103.959 53.7585 \; 103.916 57.878 \; 103.899 55.5874 \; \;; #X scalar trace-template 390 0 12 \; 119.191 43.0069 \; \;; #X scalar trace-template 390 0 13 \; 98.4925 43.4366 \; 98.4979 54.6725 \; 98.494 57.3374 \; 98.5186 59.47 \; 98.5202 58.342 \; 98.4551 53.2158 \; \;; #X scalar trace-template 390 0 14 \; 98.3805 42.2791 \; 98.4031 56.4782 \; 98.1451 55.7274 \; 98.115 57.0479 \; 98.0521 56.1766 \; \;; #X scalar trace-template 390 0 15 \; 104.016 47.8447 \; \;; #X scalar trace-template 390 0 16 \; 113.88 41.6872 \; \;; #X scalar trace-template 390 0 17 \; 114.954 41.3719 \; \;; #X scalar trace-template 390 0 18 \; 105.136 40.6514 \; \;; #X scalar trace-template 390 0 21 \; 103.236 45.0143 \; \;; #X scalar trace-template 390 0 22 \; 114.13 40.4122 \; \;; #X scalar trace-template 390 0 23 \; 117.03 39.5933 \; \;; #X scalar trace-template 390 0 24 \; 103.163 46.7184 \; \;; #X scalar trace-template 395 0 2 \; 33.1353 60.3554 \; \;; #X scalar trace-template 395 0 3 \; 93.5805 56.7892 \; 93.7856 54.7965 \; 93.9083 58.7549 \; 93.9607 62.5023 \; 93.7894 59.6069 \; 93.8556 53.863 \; \;; #X scalar trace-template 395 0 5 \; 63.2391 54.9406 \; 63.2873 62.0863 \; 64.0134 75.9389 \; 64.1655 77.5121 \; 65.1942 72.6254 \; 65.4817 72.9527 \; 66.0561 70.7274 \; 65.7887 68.6363 \; 65.8253 69.1864 \; 65.8876 68.9626 \; 65.8775 68.727 \; 65.765 68.3261 \; 65.8165 68.2814 \; 66.0022 68.8013 \; 65.8593 68.8224 \; 65.1658 68.0576 \; 64.8563 67.7534 \; 64.8865 66.5277 \; 65.3462 64.4466 \; 65.484 65.7133 \; 65.8589 69.2515 \; 66.4075 73.8187 \; 65.5859 70.3598 \; 65.1163 71.0524 \; 65.3866 69.8158 \; 66.1851 69.4536 \; 66.7235 68.1516 \; 66.9742 68.1973 \; 67.2794 68.0042 \; 67.6901 67.547 \; 68.076 67.9899 \; 68.2552 68.076 \; 68.3061 68.1516 \; 68.3209 68.0936 \; 68.2315 67.6663 \; 67.8039 65.0708 \; 67.3466 61.5109 \; \;; #X scalar trace-template 395 0 8 \; 59.7929 53.5529 \; 56.9433 58.4677 \; 54.6345 70.6083 \; 52.9808 74.4669 \; 51.6154 80.0792 \; 50.9218 82.0608 \; 50.3467 83.0251 \; 50.2382 83.8349 \; 50.1338 84.1139 \; 50.0007 84 \; 50.0633 83.897 \; 50.0111 83.6855 \; 49.8889 83.3392 \; 49.6842 82.881 \; 49.5634 82.2208 \; 49.4359 81.4713 \; 49.2318 80.8375 \; 49.0282 80.1351 \; 49.1767 79.328 \; 49.5796 78.3662 \; 49.792 77.7087 \; 49.9036 76.9973 \; 50.0958 76.7103 \; 49.6123 76.2172 \; 49.3632 76.4464 \; 49.9352 77.0797 \; 50.3958 77.867 \; 50.8846 78.6451 \; 51.2521 79.4906 \; 51.6328 80.088 \; 52.003 80.5506 \; 52.3018 80.8978 \; 52.4284 81.0977 \; 52.4885 81.2607 \; 52.5104 81.3666 \; 52.4499 81.1428 \; 52.3949 79.7438 \; 53.209 73.7855 \; 53.5057 65.1719 \; 54.7375 52.014 \; 54.2386 47.2216 \; \;; #X scalar trace-template 395 0 12 \; 100.153 57.0463 \; 100.071 55.5317 \; 100.006 54.2763 \; \;; #X scalar trace-template 395 0 15 \; 72.8203 53.806 \; 72.5635 55.0585 \; 72.8066 55.3802 \; 73.1468 58.2625 \; 72.9072 59.73 \; \;; #X scalar trace-template 395 0 16 \; 104.357 50.8812 \; 104.297 55.3325 \; 104.193 55.4977 \; \;; #X scalar trace-template 395 0 17 \; 109.702 52.6993 \; \;; #X scalar trace-template 395 0 18 \; 106.282 52.7796 \; \;; #X scalar trace-template 395 0 19 \; 71.1141 50.9943 \; 71.4208 51.9311 \; 71.4241 55.3353 \; 71.4039 59.7705 \; 71.4815 59.9607 \; 72.1706 60.9339 \; 71.9803 57.3388 \; 71.7828 55.2045 \; 71.738 54.5132 \; 71.7847 53.5202 \; 71.6964 52.1305 \; 71.6303 50.4562 \; 71.4254 56.7773 \; 71.0655 64.1456 \; 71.3079 70.1473 \; 71.1559 74.4095 \; 71.0092 76.7439 \; 71.0113 75.5618 \; 71.2194 73.0289 \; 71.095 72.5964 \; 70.6678 63.5153 \; \;; #X scalar trace-template 395 0 21 \; 118.331 51.7243 \; \;; #X scalar trace-template 395 0 22 \; 115.768 51.4252 \; \;; #X scalar trace-template 395 0 23 \; 112.423 51.0074 \; \;; #X scalar trace-template 395 0 24 \; 74.373 51.534 \; \;; #X scalar trace-template 400 0 2 \; 60.7909 58.8953 \; \;; #X scalar trace-template 400 0 17 \; 93.0794 56.7877 \; 93.0585 60.6526 \; 93.0661 64.8537 \; 93.0586 64.316 \; 93.0829 57.8017 \; 93.4734 51.9908 \; 93.4967 51.3335 \; 93.6351 51.2657 \; 93.6948 52.082 \; 93.689 52.5698 \; 93.6238 52.5727 \; 93.3867 50.8815 \; \;; #X scalar trace-template 400 0 18 \; 68.5645 55.8434 \; 68.1628 64.0191 \; 68.0025 70.957 \; 67.8113 74.1461 \; 67.7327 72.1855 \; 67.6405 66.935 \; 68.2277 57.7435 \; 69.0114 56.4171 \; 69.1769 55.4684 \; 69.1022 55.6504 \; 69.0435 55.5131 \; 69.0288 58.1368 \; 68.8294 67.4502 \; 69.0139 73.4645 \; 68.7206 73.2902 \; 68.377 69.2132 \; 67.8704 63.5782 \; 67.01 58.7076 \; \;; #X scalar trace-template 400 0 21 \; 99.2915 52.4865 \; 99.2783 53.6627 \; 99.1982 52.6905 \; \;; #X scalar trace-template 400 0 22 \; 99.6001 51.6552 \; 99.5883 51.8291 \; \;; #X scalar trace-template 400 0 23 \; 97.7982 50.7793 \; 97.7447 54.8176 \; 97.7469 57.1902 \; 97.8385 54.886 \; \;; #X scalar trace-template 400 0 24 \; 92.318 48.4004 \; 92.3201 53.9851 \; 92.3011 60.3238 \; 92.2804 61.4122 \; 91.9803 58.2215 \; 91.9808 48.9789 \; 92.0683 45.4198 \; 92.2134 47.11 \; 92.2924 49.5927 \; 92.3131 51.7382 \; 92.2196 51.6828 \; 92.3936 54.5223 \; 92.3862 55.7333 \; 92.3399 61.1094 \; \;; #X scalar trace-template 405 0 0 \; 64.6747 74.3114 \; \;; #X scalar trace-template 405 0 2 \; 31.706 69.0071 \; \;; #X scalar trace-template 405 0 4 \; 56.2558 71.4473 \; 58.058 71.4507 \; 57.9736 71.8686 \; 57.559 69.1831 \; 57.0099 70.1424 \; 56.9352 72.225 \; 56.7565 74.1905 \; 57.023 73.7814 \; 57.0353 73.3945 \; 56.9876 73.5521 \; 56.8695 73.9286 \; 56.7749 74.289 \; 56.685 74.145 \; 56.6709 73.5798 \; 56.4462 73.1142 \; 56.2825 72.4107 \; 56.5862 70.4527 \; 56.9145 68.9277 \; 56.7531 68.766 \; 56.9633 68.5499 \; 57.0206 68.0578 \; 56.3817 68.9635 \; 56.4395 69.6412 \; 57.1259 69.5199 \; 57.6043 69.5414 \; 58.0134 69.5198 \; 58.2535 69.3355 \; 58.7792 69.01 \; 59.0711 69.0329 \; 59.2884 69.1174 \; 59.4277 69.0332 \; 59.4741 68.7841 \; 59.334 68.1373 \; 59.1709 66.5248 \; 58.0222 61.3926 \; 57.1827 58.9038 \; \;; #X scalar trace-template 405 0 7 \; 94.7709 53.2042 \; 94.6756 58.4947 \; 94.7693 57.7545 \; 94.8286 56.0705 \; 94.8183 53.9364 \; 94.8701 52.2989 \; 95.0344 49.8333 \; 95.0838 48.2613 \; 95.0477 46.3652 \; 95.0083 43.1454 \; \;; #X scalar trace-template 405 0 9 \; 91.582 51.3465 \; 91.6108 56.8425 \; 91.6434 58.5355 \; \;; #X scalar trace-template 405 0 11 \; 97.1211 51.3276 \; 97.1747 52.692 \; \;; #X scalar trace-template 410 0 0 \; 70.2302 59.6623 \; \;; #X scalar trace-template 410 0 1 \; 95.3188 55.4147 \; 95.3418 56.1851 \; 95.5114 53.2473 \; 95.5304 46.8457 \; \;; #X scalar trace-template 410 0 2 \; 75.7073 53.7733 \; 75.6781 54.6239 \; 75.5982 50.493 \; 75.393 44.5731 \; \;; #X scalar trace-template 410 0 10 \; 95.9519 53.9215 \; 95.9693 53.7395 \; 96.161 49.8455 \; \;; #X scalar trace-template 410 0 12 \; 90.715 52.9653 \; \;; #X scalar trace-template 410 0 16 \; 96.5703 52.2934 \; 96.4942 51.287 \; \;; #X scalar trace-template 410 0 20 \; 78.0186 52.8112 \; 78.3004 51.5168 \; 78.5826 51.6835 \; 78.7019 45.1359 \; \;; #X scalar trace-template 410 0 22 \; 103.144 51.9664 \; 103.101 52.6842 \; 103.032 47.8254 \; \;; #X scalar trace-template 415 0 0 \; 63.9044 74.665 \; 62.7931 67.7733 \; 62.2322 66.4088 \; 61.9579 66.3871 \; 61.984 66.4297 \; 61.9671 66.1687 \; 62.0955 66.3099 \; 61.8897 66.0538 \; 61.9792 65.8605 \; 61.9292 64.5702 \; 61.8976 63.3387 \; 61.2528 61.7569 \; 60.9979 61.441 \; 61.0368 60.49 \; 61.5053 59.7703 \; 61.8281 60.7318 \; 61.8117 61.9132 \; 62.8703 66.1534 \; 61.8726 62.6533 \; 61.2582 65.0196 \; 61.514 65.1684 \; 62.1565 64.7884 \; 62.8631 65.3668 \; 63.1208 65.7356 \; 63.4585 65.8762 \; 63.8163 66.4072 \; 64.2257 67.3276 \; 64.405 67.8232 \; 64.4083 68.1037 \; 64.434 68.2996 \; 64.3093 67.9724 \; 64.1054 66.6662 \; 64.1368 62.693 \; 64.8006 55.6456 \; 64.8434 41.2511 \; 63.1434 44.0477 \; \;; #X scalar trace-template 415 0 11 \; 30.2537 66.5926 \; 28.7656 62.4366 \; 23.8669 58.4795 \; 28.9677 53.4282 \; \;; #X scalar trace-template 415 0 12 \; 94.0649 59.4979 \; 94.1159 56.3706 \; 94.1572 52.5386 \; 94.1933 53.5889 \; 94.3063 55.4104 \; 94.3906 54.0401 \; 94.4298 51.4517 \; 94.3554 48.3642 \; \;; #X scalar trace-template 415 0 14 \; 102.632 50.9021 \; \;; #X scalar trace-template 415 0 21 \; 77.1115 50.4848 \; 76.7415 49.5282 \; \;; #X scalar trace-template 420 0 9 \; 92.8438 57.3295 \; 92.84 52.2746 \; 92.8621 49.9578 \; 92.9702 53.9605 \; 93.0411 56.2904 \; 93.0246 56.6538 \; 92.93 55.4646 \; 92.9515 53.109 \; 93.0813 54.637 \; 93.019 62.4155 \; 93.3465 58.0651 \; 93.4106 59.3711 \; 93.4773 56.7961 \; 93.5072 48.188 \; \;; #X scalar trace-template 420 0 13 \; 81.6327 50.8855 \; 81.3443 49.0619 \; 81.0317 50.0767 \; 80.9332 50.9648 \; 81.0601 49.5628 \; 81.0262 47.3837 \; 80.9232 45.7369 \; 80.6749 49.6062 \; 80.4723 53.464 \; 80.3874 54.9019 \; \;; #X scalar trace-template 420 0 14 \; 91.1656 49.0433 \; 91.4823 42.143 \; 91.4663 44.9214 \; 91.4886 48.0358 \; 91.5338 48.4514 \; 91.5073 47.8788 \; 91.4127 47.7073 \; 91.1587 47.1028 \; 90.8319 50.7381 \; 90.8681 55.0399 \; 90.4341 58.1933 \; 90.3152 58.4281 \; \;; #X scalar trace-template 420 0 15 \; 90.2623 48.9218 \; \;; #X scalar trace-template 420 0 16 \; 74.6777 48.8598 \; 73.7681 49.4856 \; 73.8699 46.3965 \; 74.0214 44.1387 \; 74.2299 43.1116 \; 74.0042 41.3954 \; 74.0215 41.5129 \; 73.4355 48.1739 \; 73.5441 56.5877 \; 73.4131 62.8873 \; 72.8941 65.8422 \; 72.9414 68.4247 \; 73.1376 70.0577 \; 73.4732 68.2907 \; 73.7834 65.4445 \; 74.0083 61.6385 \; 73.9691 61.0821 \; \;; #X scalar trace-template 420 0 23 \; 89.4117 46.8768 \; \;; #X scalar trace-template 425 0 3 \; 68.9823 57.9746 \; \;; #X scalar trace-template 425 0 10 \; 92.9957 50.2935 \; \;; #X scalar trace-template 425 0 15 \; 84.3214 48.0136 \; 84.5921 47.2994 \; \;; #X scalar trace-template 425 0 21 \; 82.858 47.8268 \; 82.5141 46.2724 \; 82.3785 46.3624 \; 82.416 44.9319 \; 82.3566 44.0036 \; 82.3332 43.0712 \; 82.0267 48.3045 \; 81.8764 56.8812 \; 81.7218 59.0443 \; 81.5329 56.1969 \; 81.3016 55.8829 \; 81.1999 55.5795 \; 81.1217 57.307 \; 80.6739 53.7685 \; \;; #X scalar trace-template 425 0 22 \; 80.1919 45.6398 \; \;; #X scalar trace-template 425 0 23 \; 78.3105 48.0387 \; 78.0644 44.8867 \; 77.9689 46.5818 \; 77.8672 49.4984 \; 77.7538 51.4465 \; 77.6162 52.4088 \; 77.4481 53.8951 \; 77.2252 56.3992 \; 77.1069 58.7346 \; 76.931 60.4912 \; 76.7384 62.5741 \; 76.5581 62.9937 \; 76.2622 64.5483 \; 75.935 63.7163 \; 75.6269 59.1356 \; 75.3923 56.4981 \; 74.9826 58.9193 \; 73.7712 68.4809 \; 73.8504 74.5992 \; 74.4874 77.3407 \; 75.0526 79.2297 \; 75.3196 79.3612 \; 75.5409 77.2001 \; 75.8663 75.2055 \; 76.2175 75.5544 \; 76.296 75.122 \; 76.3493 74.6568 \; 76.3091 73.4835 \; 76.2362 70.9012 \; 76.133 65.5664 \; 75.914 56.8858 \; 76.5107 41.4361 \; 76.4929 31.4413 \; \;; #X scalar trace-template 430 0 1 \; 89.6982 48.3306 \; 89.8304 49.5892 \; 89.8508 48.3749 \; 89.8545 46.2613 \; 89.783 45.7989 \; \;; #X scalar trace-template 430 0 2 \; 90.5152 46.4056 \; 90.6456 48.1742 \; 90.721 49.2104 \; 90.7124 49.0332 \; 90.643 48.7764 \; 90.3896 46.7112 \; 90.0931 49.9058 \; 90.0371 56.28 \; 89.674 60.4066 \; 89.636 62.2296 \; 89.6582 60.8852 \; 89.7031 56.5344 \; 89.7206 47.3358 \; \;; #X scalar trace-template 430 0 3 \; 88.8817 49.8209 \; 88.9276 49.7833 \; 89.0176 50.717 \; 88.9951 50.2055 \; 88.868 49.5564 \; 88.6117 48.1454 \; 88.355 50.0224 \; 88.3899 56.5105 \; \;; #X scalar trace-template 430 0 10 \; 85.0674 44.0682 \; 84.8409 49.0018 \; 84.9078 47.4837 \; 84.9122 45.6971 \; 84.7996 44.9723 \; 84.3861 53.6424 \; 84.3118 57.9956 \; 84.3249 60.1426 \; 84.6287 57.0493 \; \;; #X scalar trace-template 430 0 20 \; 83.8084 44.4051 \; 83.6517 46.9925 \; 83.7594 47.9626 \; 83.6919 48.4217 \; 83.5918 48.8133 \; 83.3189 51.3186 \; 83.2008 57.7621 \; 83.0812 59.261 \; 83.3645 55.7677 \; \;; #X scalar trace-template 430 0 22 \; 89.0005 46.2853 \; \;; #X scalar trace-template 435 0 11 \; 79.3151 47.7248 \; 79.4472 49.908 \; 79.4711 49.6875 \; 79.4425 47.8128 \; 79.2476 47.7887 \; 79.0668 51.4491 \; 78.8211 54.1663 \; \;; #X scalar trace-template 435 0 15 \; 96.2643 42.6303 \; \;; #X scalar trace-template 435 0 22 \; 76.1611 41.8618 \; 76.2097 42.8969 \; 76.1801 45.8418 \; 75.9318 47.9776 \; 75.4468 50.0057 \; 75.2811 54.1875 \; 75.2103 57.0576 \; 75.0486 60.0142 \; 74.4892 62.5964 \; \;; #X scalar trace-template 440 0 15 \; 32.6287 39.6597 \; \;; #X scalar trace-template 445 0 15 \; 85.9842 41.3738 \; 85.9207 40.9137 \; \;; #X scalar trace-template 455 0 1 \; 92.595 54.1639 \; \;; #X scalar trace-template 455 0 7 \; 84.0752 53.5514 \; \;; #X scalar trace-template 455 0 12 \; 71.9754 51.2307 \; \;; #X scalar trace-template 455 0 15 \; 93.7039 47.8707 \; 93.8386 46.9087 \; \;; #X scalar trace-template 460 0 1 \; 89.182 51.8269 \; 89.096 58.0196 \; 88.8953 65.3887 \; \;; #X scalar trace-template 460 0 7 \; 91.6268 50.5045 \; 91.5268 58.0543 \; 91.2813 59.3876 \; \;; #X scalar trace-template 460 0 12 \; 87.4291 48.4764 \; 87.5024 56.7953 \; 87.7977 59.788 \; 87.9595 61.2738 \; \;; #X scalar trace-template 460 0 17 \; 86.5481 47.8126 \; 86.4709 54.5901 \; 86.9088 57.0885 \; 86.9194 60.3525 \; 86.842 60.2673 \; 86.777 58.6492 \; 86.7582 53.1978 \; \;; #X scalar trace-template 465 0 15 \; 92.9317 63.453 \; 92.8243 64.6915 \; 92.9027 59.8356 \; 92.7493 61.4731 \; 92.7019 47.4134 \; \;; #X scalar trace-template 470 0 3 \; 88.764 66.7744 \; 88.7466 66.6001 \; 88.6348 64.583 \; 88.5086 57.8875 \; 88.7181 48.9359 \; \;; #X scalar trace-template 470 0 11 \; 91.1604 61.7312 \; 91.1638 61.7693 \; 91.148 57.9649 \; 91.1924 53.185 \; \;; #X scalar trace-template 470 0 13 \; 84.0978 55.8659 \; 83.7601 56.1963 \; 83.6617 55.9256 \; 83.6511 56.5404 \; 83.7677 55.8827 \; 83.1522 52.2184 \; 82.9014 46.6945 \; \;; #X scalar trace-template 470 0 24 \; 82.9302 54.8452 \; \;; #X scalar trace-template 475 0 1 \; 92.622 63.9064 \; 92.567 60.6642 \; \;; #X scalar trace-template 475 0 7 \; 75.353 56.649 \; 75.099 61.5299 \; \;; #X scalar trace-template 475 0 10 \; 91.9828 57.9155 \; 91.9947 47.7828 \; \;; #X scalar trace-template 475 0 20 \; 90.6412 52.9618 \; \;; #X scalar trace-template 475 0 24 \; 85.8917 54.3305 \; 85.8293 54.1508 \; 85.7975 52.4587 \; 85.8241 46.3817 \; \;; #X scalar trace-template 480 0 12 \; 78.2175 55.2453 \; 77.7725 62.5141 \; 77.5856 61.401 \; 76.9609 58.7886 \; 76.9402 59.3096 \; 76.966 64.0213 \; 77.4012 66.4317 \; 77.4283 67.9767 \; 76.9703 69.6261 \; 77.1465 73.8677 \; 77.3718 76.2361 \; 77.5852 77.0536 \; 78.015 76.0112 \; 78.2914 76.4487 \; 78.3738 75.6721 \; 78.422 73.6719 \; 78.4871 70.6498 \; 78.5075 66.277 \; 78.3841 60.0376 \; 78.1288 50.984 \; 77.9376 37.6529 \; 78.5377 35.2225 \; 78.5455 42.6073 \; \;; #X scalar trace-template 480 0 14 \; 84.8631 53.4972 \; 84.8041 54.4078 \; 84.4768 55.6402 \; 84.1286 53.6739 \; \;; #X scalar trace-template 480 0 20 \; 79.7102 53.3586 \; 79.8567 51.0561 \; 80.2251 54.1447 \; 80.2232 55.6554 \; 80.0226 55.8852 \; 79.9023 55.5927 \; 80.1666 58.2372 \; 80.2217 66.7559 \; 80.2008 65.549 \; 80.3682 67.0433 \; 80.7067 64.8925 \; 80.5826 64.563 \; 80.4109 62.6492 \; 80.1467 67.5259 \; 80.2303 66.7688 \; 80.2977 65.2865 \; 80.2999 63.2846 \; 80.2312 59.8739 \; 80.1209 53.7782 \; 79.8288 46.6824 \; 79.4123 36.2735 \; \;; #X scalar trace-template 480 0 22 \; 93.9657 52.1516 \; \;; #X scalar trace-template 485 0 1 \; 77.9909 59.7677 \; \;; #X scalar trace-template 485 0 7 \; 81.9939 52.2885 \; 82.0761 57.8583 \; 81.6159 56.9224 \; 81.4866 54.084 \; 81.4843 52.8892 \; 81.335 56.2603 \; \;; #X scalar trace-template 485 0 10 \; 91.0006 50.2484 \; \;; #X scalar trace-template 485 0 22 \; 102 47.4016 \; \;; #X scalar trace-template 490 0 1 \; 70.0239 65.2117 \; \;; #X scalar trace-template 490 0 9 \; 87.6995 46.7176 \; \;; #X scalar trace-template 490 0 10 \; 105.88 48.1684 \; 105.892 48.6287 \; 105.918 46.7889 \; 106.009 46.8082 \; 106.023 49.7847 \; 105.932 50.4925 \; 105.91 52.8565 \; 105.824 54.8523 \; \;; #X scalar trace-template 490 0 11 \; 88.916 49.7698 \; \;; #X scalar trace-template 490 0 15 \; 99.7817 47.3329 \; \;; #X scalar trace-template 490 0 18 \; 105.271 47.3223 \; 105.215 46.8185 \; 105.183 46.3735 \; 105.097 47.0445 \; \;; #X scalar trace-template 490 0 22 \; 100.136 46.7691 \; \;; #X scalar trace-template 495 0 1 \; 70.9446 73.3419 \; 71.4077 65.2273 \; 70.6126 71.8945 \; 70.405 69.7798 \; 70.329 69.16 \; \;; #X scalar trace-template 495 0 2 \; 70.3504 70.5871 \; 69.9455 71.3615 \; 69.0971 69.2117 \; 69.0115 69.4547 \; 68.9236 71.9118 \; 69.5557 70.9135 \; 69.764 67.4427 \; 70.2561 68.0534 \; 70.4189 68.0555 \; 70.9783 68.6213 \; 71.2455 70.4278 \; 71.4002 71.2079 \; 71.4417 71.6407 \; 71.3923 72.0649 \; 71.3169 72.126 \; 71.0492 70.0548 \; 70.7152 64.0474 \; 70.8217 51.4644 \; 70.6168 42.3312 \; 70.042 46.7001 \; \;; #X scalar trace-template 495 0 3 \; 67.1862 65.7134 \; 67.1142 69.1866 \; 67.3455 72.7057 \; 67.67 72.787 \; \;; #X scalar trace-template 495 0 9 \; 72.6653 60.6826 \; 72.8663 63.4311 \; 72.8637 65.9985 \; 72.4164 67.6138 \; 72.4751 74.5938 \; 72.558 77.9604 \; 72.6588 76.9986 \; 72.7722 74.4262 \; 73.0808 72.2931 \; 73.4913 70.7694 \; 73.942 71.7161 \; 74.0454 71.7542 \; 74.0733 72.207 \; 74.0496 72.5273 \; 73.8649 71.6368 \; 73.7692 67.607 \; 73.517 59.0843 \; 74.064 46.3988 \; 73.6822 41.8651 \; 73.5244 46.3181 \; \;; #X scalar trace-template 495 0 11 \; 77.73 58.1138 \; 78.0508 61.773 \; \;; #X scalar trace-template 495 0 15 \; 78.6031 55.8516 \; 78.4894 59.0283 \; 78.3349 63.6968 \; 78.2628 68.351 \; 78.3544 71.8827 \; 78.3657 73.2444 \; 78.729 71.531 \; 79.1016 71.5445 \; 79.0154 69.6051 \; 79.7467 66.7767 \; \;; #X scalar trace-template 495 0 17 \; 82.3145 57.3985 \; 82.4493 53.5878 \; 82.4877 48.1427 \; 82.4708 55.0644 \; 82.0261 72.2768 \; 81.8789 74.7732 \; 81.9439 73.9254 \; 82.1614 69.6702 \; 82.1807 67.0401 \; 81.8554 66.4255 \; 81.8015 67.0175 \; 81.9041 66.1829 \; 81.9827 64.871 \; 82.0056 63.5091 \; 81.9382 60.5464 \; 81.8945 54.4222 \; 81.8665 44.1251 \; 81.9834 33.9453 \; 81.5731 33.2956 \; 81.4971 42.0351 \; \;; #X scalar trace-template 495 0 21 \; 84.4981 50.6119 \; \;; #X scalar trace-template 495 0 22 \; 106.211 46.1173 \; 106.225 48.2936 \; 106.335 49.0608 \; 106.346 48.9659 \; 106.289 49.04 \; 106.259 50.9816 \; \;; #X scalar trace-template 495 0 24 \; 105.378 44.6412 \; 105.425 47.1615 \; 105.435 49.5732 \; 105.415 47.7841 \; \;; #X scalar trace-template 500 0 14 \; 63.3088 62.274 \; 63.6483 65.0583 \; \;; #X scalar trace-template 500 0 19 \; 105.563 45.3989 \; 105.671 48.7325 \; 105.68 48.9501 \; \;; #X scalar trace-template 500 0 21 \; 104.694 46.5209 \; 104.72 48.263 \; 104.736 47.1111 \; \;; #X scalar trace-template 505 0 11 \; 71.0926 67.4764 \; \;; #X scalar trace-template 505 0 13 \; 106.136 46.731 \; \;; #X scalar trace-template 505 0 16 \; 106.654 45.5947 \; 106.645 48.4533 \; 106.631 49.7704 \; 106.605 51.1537 \; \;; #X scalar trace-template 510 0 11 \; 74.3291 66.0533 \; \;; #X scalar trace-template 510 0 13 \; 76.3235 62.2527 \; 75.5133 63.5007 \; \;; #X scalar trace-template 510 0 14 \; 83.6409 43.9421 \; \;; #X scalar trace-template 510 0 18 \; 85.8906 45.3991 \; 85.6534 52.8512 \; 85.3986 62.4321 \; 85.254 69.9902 \; 84.9991 73.3262 \; 85.0051 68.3535 \; 84.8347 64.5104 \; 84.663 65.2854 \; 84.7752 64.0055 \; 84.8571 61.4019 \; \;; #X scalar trace-template 515 0 3 \; 81.6857 71.7868 \; \;; #X scalar trace-template 515 0 7 \; 84.5009 54.3053 \; 84.4516 68.0483 \; 84.6717 72.4921 \; \;; #X scalar trace-template 515 0 11 \; 86.8069 47.5858 \; 86.2448 54.8238 \; 86.3258 62.9919 \; 86.4295 68.9578 \; 86.72 67.1108 \; 86.7705 65.6732 \; \;; #X scalar trace-template 515 0 14 \; 100.425 47.8601 \; 100.548 56.1214 \; \;; #X scalar trace-template 515 0 19 \; 106.959 47.5784 \; \;; #X scalar trace-template 515 0 21 \; 105.203 48.1733 \; \;; #X scalar trace-template 515 0 24 \; 100.026 46.3859 \; 100.073 54.1896 \; 100.098 57.916 \; 100.055 57.3471 \; 100.012 56.8406 \; \;; #X scalar trace-template 520 0 1 \; 83.4279 70.2744 \; 83.6114 73.3595 \; 83.7101 72.0643 \; 83.5791 68.0924 \; 83.4472 66.034 \; 83.2873 67.6479 \; 83.4004 66.1698 \; 83.4702 64.081 \; 83.4822 62.1829 \; 83.454 59.4481 \; 83.4136 53.7326 \; 83.4217 43.5176 \; \;; #X scalar trace-template 520 0 3 \; 76.7085 71.4206 \; \;; #X scalar trace-template 520 0 13 \; 79.9912 69.2915 \; 79.6259 67.4034 \; \;; #X scalar trace-template 520 0 19 \; 100.637 53.8453 \; 100.622 57.7114 \; 100.562 54.8402 \; \;; #X scalar trace-template 520 0 21 \; 101.023 52.4817 \; 101.106 53.3229 \; \;; #X scalar trace-template 525 0 3 \; 77.7221 70.6852 \; \;; #X scalar trace-template 525 0 14 \; 86.9404 58.5173 \; \;; #X scalar trace-template 525 0 16 \; 87.9751 56.2674 \; 87.5248 66.5733 \; 87.4391 66.3192 \; 87.3596 66.4014 \; 87.2017 66.861 \; 87.2958 63.8083 \; 87.3607 60.8036 \; \;; #X scalar trace-template 525 0 22 \; 89.0441 52.8794 \; 89.3 57.54 \; 89.3158 62.9757 \; 89.3845 67.2661 \; 89.4406 69.1805 \; 89.534 68.1255 \; 89.5595 64.5337 \; 89.5485 60.586 \; \;; #X scalar trace-template 530 0 3 \; 87.7132 64.8833 \; \;; #X scalar trace-template 530 0 7 \; 88.3988 60.5542 \; 88.3612 66.9592 \; 88.3383 70.575 \; 88.3552 70.4503 \; 88.4339 67.6466 \; 88.4838 63.9846 \; 88.5 61.0477 \; \;; #X scalar trace-template 530 0 10 \; 90.2287 56.1977 \; 90.2469 60.7629 \; 90.2873 65.0799 \; 90.4446 68.1948 \; 90.5644 70.4341 \; 90.6157 69.652 \; 90.6017 65.9494 \; 90.5647 60.3783 \; 90.5664 52.5491 \; 90.8006 44.2207 \; \;; #X scalar trace-template 530 0 13 \; 100.274 55.0555 \; 100.271 56.4482 \; \;; #X scalar trace-template 530 0 14 \; 91.1267 55.5667 \; 91.135 58.7424 \; 91.1908 61.3757 \; 91.2722 65.0242 \; 91.4573 66.9404 \; 91.5944 69.2178 \; 91.6211 68.708 \; 91.59 63.8532 \; 91.5047 55.8168 \; 91.7448 44.9222 \; \;; #X scalar trace-template 530 0 21 \; 100.766 54.8894 \; \;; #X scalar trace-template 535 0 3 \; 86.2748 68.7487 \; 86.0892 66.3964 \; 85.9702 64.484 \; 86.0875 61.9055 \; \;; #X scalar trace-template 535 0 19 \; 105.641 57.2293 \; \;; #X scalar trace-template 535 0 21 \; 92.8369 55.7683 \; \;; #X scalar trace-template 540 0 13 \; 82.834 63.5176 \; \;; #X scalar trace-template 540 0 19 \; 84.1493 61.0962 \; \;; #X scalar trace-template 540 0 21 \; 85.3574 61.1557 \; \;; #X scalar trace-template 540 0 24 \; 92.0731 58.0152 \; 92.1806 60.8348 \; 92.2726 64.0431 \; 92.4273 65.878 \; 92.494 67.6394 \; 92.5046 65.8391 \; 92.301 57.3752 \; \;; #X scalar trace-template 545 0 11 \; 99.7234 60.4762 \; \;; #X scalar trace-template 545 0 13 \; 100.227 59.4884 \; 100.354 58.6136 \; \;; #X scalar trace-template 545 0 15 \; 93.0233 58.7117 \; 93.0881 61.0373 \; 93.2213 62.7032 \; 93.247 65.2042 \; 93.2621 65.5166 \; 93.288 61.0725 \; 93.5621 52.8634 \; 93.4301 35.4121 \; 93.37 33.0415 \; 93.2809 42.0326 \; \;; #X scalar trace-template 545 0 19 \; 99.869 55.791 \; 99.7981 61.3428 \; 99.9133 59.9587 \; \;; #X scalar trace-template 545 0 21 \; 93.8378 56.6863 \; 93.8993 59.1934 \; 94.0057 60.61 \; 94.0263 62.0724 \; 93.9857 63.5183 \; 93.98 61.3231 \; 94.0599 52.991 \; 94.3197 35.5436 \; \;; #X scalar trace-template 550 0 11 \; 95.4198 57.4325 \; 95.5111 59.1349 \; 95.5037 60.787 \; 95.4865 60.7385 \; 95.4284 57.6801 \; 95.3903 50.4586 \; 95.2761 32.5969 \; \;; #X scalar trace-template 555 0 3 \; 99.3355 59.7816 \; 99.3368 60.9503 \; 99.2987 59.1855 \; \;; #X scalar trace-template 555 0 13 \; 97.5377 59.4125 \; 97.5268 60.5553 \; 97.4973 60.6902 \; 97.4799 58.8329 \; 97.4765 54.4491 \; 97.4924 45.9699 \; 97.5386 35.3714 \; \;; #X scalar trace-template 560 0 16 \; 94.7577 60.4812 \; 94.7537 60.6104 \; 94.7588 56.8823 \; 94.8588 46.6893 \; \;; #X scalar trace-template 560 0 18 \; 96.8956 60.7695 \; 96.8514 60.6364 \; 96.8366 58.4197 \; 96.8556 53.2549 \; 96.9277 44.9862 \; \;; #X scalar trace-template 560 0 19 \; 98.1532 59.7576 \; 98.1186 59.4233 \; 98.0625 56.5017 \; 98.0627 49.8139 \; 97.92 41.5941 \; \;; #X scalar trace-template 565 0 7 \; 96.1627 58.7818 \; 96.172 55.9452 \; 96.2063 49.9503 \; 96.2916 39.4985 \; \;; #X scalar trace-template 565 0 22 \; 98.6835 58.4552 \; 98.6755 52.936 \; \;; #X scalar trace-template 570 0 3 \; 92.5522 59.0208 \; 92.752 50.2557 \; 92.4956 34.9042 \; 92.4449 30.4699 \; 92.3075 44.6241 \; 92.4119 48.2365 \; \;; #X scalar trace-template 575 0 22 \; 58.9582 64.315 \; \;; #X scalar trace-template 575 0 24 \; 95.5221 52.3246 \; \;; #X scalar trace-template 580 0 1 \; 50.4538 73.0014 \; \;; #X scalar trace-template 580 0 5 \; 98.1016 40.2011 \; \;; #X scalar trace-template 580 0 10 \; 106.413 38.2315 \; \;; #X scalar trace-template 580 0 14 \; 79.7407 26.4828 \; 80.1904 33.9665 \; 79.5131 40.8717 \; \;; #X scalar trace-template 580 0 16 \; 108.009 32.949 \; \;; #X scalar trace-template 580 0 22 \; 92.6976 35.2008 \; 93.0049 30.9813 \; 93.0337 42.8019 \; \;; #X scalar trace-template 580 0 24 \; 117.242 31.1934 \; \;; #X scalar trace-template 585 0 1 \; 67.646 43.7599 \; \;; #X scalar trace-template 585 0 4 \; 61.1709 40.7605 \; 58.8878 42.2779 \; 57.7022 47.2662 \; \;; #X scalar trace-template 585 0 5 \; 66.8047 38.1124 \; 67.0533 48.2899 \; 67.2596 49.0547 \; \;; #X scalar trace-template 585 0 7 \; 72.1421 37.1332 \; 72.291 42.0397 \; \;; #X scalar trace-template 585 0 10 \; 90.7344 39.9425 \; \;; #X scalar trace-template 585 0 11 \; 91.5543 33.8808 \; 91.2736 45.7669 \; 91.1485 49.6021 \; \;; #X scalar trace-template 585 0 16 \; 90.5538 39.1953 \; 90.2007 45.3504 \; 90.3093 49.2628 \; \;; #X scalar trace-template 585 0 18 \; 89.3163 35.1765 \; 89.4363 44.5219 \; \;; #X scalar trace-template 585 0 19 \; 91.7633 33.8919 \; \;; #X scalar trace-template 585 0 20 \; 88.4827 31.8753 \; 88.2437 43.4446 \; \;; #X scalar trace-template 585 0 21 \; 89.1318 30.8594 \; \;; #X scalar trace-template 585 0 24 \; 84.8347 31.2284 \; \;; #X scalar trace-template 590 0 1 \; 23.7851 51.7882 \; 30.0712 54.8452 \; 26.7177 56.4246 \; \;; #X scalar trace-template 590 0 10 \; 56.2827 53.3406 \; \;; #X scalar trace-template 590 0 13 \; 48.219 46.4309 \; \;; #X scalar trace-template 590 0 19 \; 61.2844 44.5902 \; \;; #X scalar trace-template 590 0 21 \; 66.1304 46.2247 \; \;; #X scalar trace-template 590 0 23 \; 74.8963 41.6702 \; \;; #X scalar trace-template 590 0 24 \; 82.8369 41.3798 \; \;; #X scalar trace-template 595 0 0 \; 113.718 53.2705 \; 113.766 59.6186 \; 113.791 62.8436 \; 113.823 65.4335 \; 113.818 64.8404 \; 113.807 63.4175 \; 113.816 62.3084 \; 113.88 60.3213 \; 113.956 54.78 \; \; ; #X scalar trace-template 595 0 2 \; 111.791 51.0206 \; 111.729 57.9487 \; 111.719 59.6317 \; \;; #X scalar trace-template 595 0 7 \; 114 56.3057 \; 113.942 58.8198 \; 113.94 62.0429 \; \;; #X scalar trace-template 595 0 9 \; 114.039 55.5829 \; \;; #X scalar trace-template 595 0 10 \; 43.2138 53.0163 \; 41.2455 53.3823 \; \;; #X scalar trace-template 595 0 12 \; 114.334 60.7709 \; \;; #X scalar trace-template 595 0 13 \; 118.755 53.7915 \; 118.772 60.3108 \; 118.773 58.4647 \; 118.768 57.2781 \; \;; #X scalar trace-template 595 0 14 \; 114.326 58.6188 \; 114.326 60.9907 \; \;; #X scalar trace-template 595 0 15 \; 118.971 47.703 \; 118.985 59.3883 \; \;; #X scalar trace-template 595 0 17 \; 114.299 54.0219 \; 114.299 63.924 \; 114.285 65.2448 \; 114.277 68.3667 \; 114.274 66.6902 \; 114.246 63.1626 \; 114.247 59.1021 \; 114.276 58.6894 \; 114.29 55.3998 \; \;; #X scalar trace-template 595 0 18 \; 118.727 52.7678 \; \;; #X scalar trace-template 595 0 19 \; 114.84 47.1255 \; 114.845 57.2432 \; 114.831 61.3123 \; 114.783 60.8446 \; 114.738 59.7495 \; 114.715 58.8673 \; 114.685 61.7935 \; 114.715 58.5927 \; 114.758 51.7935 \; \;; #X scalar trace-template 595 0 20 \; 112.48 46.1863 \; 112.43 54.7496 \; 112.409 56.497 \; 112.362 57.9034 \; 112.327 60.2147 \; \;; #X scalar trace-template 595 0 21 \; 111.542 47.7409 \; 111.506 54.3546 \; 111.514 58.7659 \; 111.539 59.9999 \; \;; #X scalar trace-template 595 0 22 \; 91.5021 45.8306 \; \;; #X scalar trace-template 595 0 23 \; 110.761 45.0076 \; \;; #X scalar trace-template 595 0 24 \; 117.806 45.8392 \; \;; #X scalar trace-template 600 0 3 \; 115.25 64.117 \; 115.229 66.3067 \; 115.192 64.1362 \; 115.154 64.6548 \; 115.136 63.1913 \; 115.177 57.3522 \; \;; #X scalar trace-template 600 0 4 \; 115.36 61.6598 \; 115.387 62.7049 \; 115.404 61.4628 \; 115.399 57.5387 \; 115.502 56.921 \; 115.499 56.2516 \; 115.509 54.9687 \; \;; #X scalar trace-template 600 0 5 \; 115.066 58.0553 \; 115.094 52.7694 \; \;; #X scalar trace-template 600 0 8 \; 113.641 56.7066 \; 113.582 60.5143 \; \;; #X scalar trace-template 600 0 9 \; 118.524 55.9165 \; 118.548 58.2441 \; \;; #X scalar trace-template 600 0 11 \; 118.793 56.1446 \; \;; #X scalar trace-template 600 0 12 \; 118.404 54.9832 \; 118.373 57.6831 \; 118.344 59.4771 \; 118.358 59.3103 \; 118.375 59.9651 \; 118.361 59.8269 \; 118.358 59.0866 \; 118.404 56.5229 \; \;; #X scalar trace-template 600 0 16 \; 119.014 55.8091 \; 119.004 59.3385 \; 119.008 59.1503 \; \;; #X scalar trace-template 600 0 18 \; 111.893 55.4258 \; \;; #X scalar trace-template 600 0 22 \; 116.022 53.9379 \; 116.047 56.9 \; \;; #X scalar trace-template 600 0 23 \; 113.451 53.0101 \; \;; #X scalar trace-template 600 0 24 \; 112.594 53.4201 \; 112.63 58.2363 \; 112.635 60.6503 \; 112.586 59.6184 \; 112.596 59.9405 \; 112.661 62.1033 \; 112.652 58.9526 \; 112.657 52.3765 \; \;; #X scalar trace-template 605 0 1 \; 114.105 59.574 \; 114.124 64.9554 \; 114.097 65.2225 \; 114.063 60.676 \; \;; #X scalar trace-template 605 0 10 \; 114.596 58.9467 \; 114.587 63.53 \; 114.586 64.4699 \; 114.616 62.7023 \; \;; #X scalar trace-template 605 0 11 \; 112.961 58.7863 \; 113.032 59.9266 \; 113.048 62.0863 \; 113.03 63.4869 \; 113 62.7615 \; 112.934 56.1129 \; \;; #X scalar trace-template 605 0 14 \; 115.036 58.2567 \; 115.002 59.9302 \; 114.997 59.4012 \; 114.964 59.5241 \; 114.988 57.2328 \; 115.038 56.8664 \; \;; #X scalar trace-template 605 0 15 \; 113.546 61.0847 \; 113.531 63.0184 \; 113.501 64.2579 \; 113.468 62.134 \; 113.458 55.8551 \; \;; #X scalar trace-template 605 0 18 \; 118.662 56.4865 \; \;; #X scalar trace-template 605 0 23 \; 111.282 56.1602 \; 111.284 58.2454 \; 111.286 58.4216 \; \;; #X scalar trace-template 610 0 2 \; 115.279 58.4135 \; 115.264 57.2103 \; \;; #X scalar trace-template 610 0 5 \; 112.165 59.3814 \; 112.195 60.7489 \; 112.251 60.4649 \; \;; #X scalar trace-template 610 0 6 \; 112.895 59.6331 \; 112.902 58.9485 \; \;; #X scalar trace-template 610 0 7 \; 117.161 58.8926 \; 117.185 61.7071 \; 117.189 59.588 \; 117.208 55.5277 \; \;; #X scalar trace-template 610 0 8 \; 111.1 58.5477 \; \;; #X scalar trace-template 610 0 9 \; 116.354 58.3927 \; 116.351 58.9609 \; \;; #X scalar trace-template 610 0 18 \; 113.205 57.8933 \; 113.197 59.672 \; 113.159 60.8365 \; 113.166 59.8285 \; 113.168 58.3424 \; 113.169 53.1693 \; \;; #X scalar trace-template 610 0 22 \; 113.374 56.893 \; \;; #X scalar trace-template 615 0 8 \; 114.348 54.5214 \; 114.34 62.6583 \; 114.374 60.6628 \; 114.372 55.6316 \; \;; #X scalar trace-template 615 0 13 \; 112.075 60.4804 \; 112.044 59.0623 \; 111.963 55.4253 \; \;; #X scalar trace-template 615 0 16 \; 112.737 59.5668 \; 112.735 61.7468 \; \;; #X scalar trace-template 615 0 21 \; 116.94 57.7011 \; 116.945 59.9821 \; 116.969 60.0125 \; 116.977 55.963 \; \;; #X scalar trace-template 615 0 22 \; 115.658 59.1929 \; \;; #X scalar trace-template 620 0 2 \; 114.137 61.5322 \; \;; #X scalar trace-template 620 0 6 \; 118.595 60.542 \; 118.616 60.2602 \; 118.62 57.0168 \; \;; #X scalar trace-template 620 0 9 \; 115.909 59.4103 \; 115.888 57.3518 \; 115.97 51.8603 \; \;; #X scalar trace-template 620 0 20 \; 118.717 57.736 \; \;; #X scalar trace-template 620 0 22 \; 118.957 56.3953 \; 119.001 58.3801 \; 119.002 55.3597 \; \;; #X scalar trace-template 620 0 23 \; 111.472 56.0261 \; 111.57 53.7604 \; 111.54 57.7347 \; 111.545 51.1921 \; \;; #X scalar trace-template 625 0 1 \; 117.935 58.697 \; 117.935 57.5603 \; 117.933 50.4738 \; \;; #X scalar trace-template 625 0 2 \; 115.103 57.1327 \; \;; #X scalar trace-template 625 0 5 \; 118.455 54.1507 \; 118.475 57.8249 \; \;; #X scalar trace-template 625 0 10 \; 115.337 56.8999 \; \;; #X scalar trace-template 625 0 16 \; 111.891 57.3586 \; 111.904 59.3167 \; 111.899 56.0872 \; \;; #X scalar trace-template 625 0 20 \; 111.507 57.9965 \; \;; #X scalar trace-template 630 0 2 \; 113.026 57.283 \; 113.09 53.9905 \; \;; #X scalar trace-template 630 0 3 \; 42.4282 53.9733 \; 44.6587 65.9304 \; 44.7895 77.695 \; 42.4643 81.9832 \; 40.836 83.2193 \; 39.8599 82.6942 \; 39.5713 82.3959 \; 39.5654 82.2658 \; 39.6933 81.6769 \; \;; #X scalar trace-template 630 0 7 \; 111.166 55.1646 \; 111.132 56.4644 \; 111.061 52.1002 \; \;; #X scalar trace-template 630 0 10 \; 118.087 54.7511 \; \;; #X scalar trace-template 630 0 13 \; 110.951 54.7755 \; 110.989 56.5427 \; \;; #X scalar trace-template 630 0 15 \; 118.706 52.2999 \; \;; #X scalar trace-template 630 0 20 \; 119.199 55.0985 \; \;; #X scalar trace-template 635 0 4 \; 58.4266 71.0592 \; 59.0486 70.6632 \; 59.0168 73.4254 \; 58.9273 73.1853 \; 58.1736 74.0071 \; 58.3129 72.2041 \; 58.3643 70.189 \; 56.9261 66.5358 \; \;; #X scalar trace-template 635 0 5 \; 57.4861 71.4524 \; 55.1139 72.7167 \; 52.0038 84.0201 \; 51.9024 85.0374 \; 51.8134 85.7674 \; 51.547 85.8245 \; 51.477 85.583 \; 51.4291 84.5581 \; \;; #X scalar trace-template 635 0 6 \; 65.9162 68.9938 \; \;; #X scalar trace-template 635 0 8 \; 65.3277 69.1431 \; 64.7843 70.5406 \; 64.2028 71.6783 \; 63.733 71.4284 \; 63.2432 70.7821 \; 63.1979 70.0653 \; 63.1048 69.7311 \; 63.0327 66.3733 \; \;; #X scalar trace-template 635 0 9 \; 35.7725 59.4376 \; \;; #X scalar trace-template 635 0 10 \; 69.9342 59.7387 \; 68.5482 72.5399 \; 67.8286 72.7588 \; 67.6787 73.4941 \; 67.161 72.6799 \; 67.0163 69.9039 \; 66.7503 66.0932 \; 66.3716 62.0886 \; \;; #X scalar trace-template 635 0 11 \; 92.9541 57.5759 \; 93.3157 64.5774 \; 93.2577 61.7797 \; 93.2324 57.1403 \; 93.1224 48.6124 \; \;; #X scalar trace-template 635 0 14 \; 113.879 52.0058 \; \;; #X scalar trace-template 635 0 15 \; 74.133 52.6457 \; 74.1908 59.5778 \; 73.893 61.4234 \; 75.0422 52.9199 \; \;; #X scalar trace-template 635 0 20 \; 118.307 52.9318 \; \;; #X scalar trace-template 635 0 21 \; 114.684 50.6263 \; \;; #X scalar trace-template 635 0 22 \; 92.3117 52.1461 \; 92.3343 53.7606 \; 92.3124 53.0089 \; \;; #X scalar trace-template 640 0 0 \; 69.0097 71.5218 \; \;; #X scalar trace-template 640 0 1 \; 70.9727 61.9286 \; 71.0953 61.8597 \; \;; #X scalar trace-template 640 0 2 \; 96.3922 59.4868 \; 96.4194 64.3998 \; 96.5028 64.7287 \; 96.6644 62.8341 \; 96.6311 56.6521 \; 96.5995 48.3874 \; \;; #X scalar trace-template 640 0 6 \; 93.4478 62.0942 \; 93.4638 55.7609 \; 93.4917 60.749 \; 93.5761 52.7505 \; 93.4639 48.124 \; 93.6571 45.0203 \; 93.7326 37.8548 \; \;; #X scalar trace-template 640 0 9 \; 97.0131 58.7974 \; 97.0936 63.091 \; 97.0854 61.4434 \; 97.0195 57.5923 \; 96.8883 60.8413 \; 96.9412 59.1049 \; 96.9206 54.9872 \; \;; #X scalar trace-template 640 0 12 \; 95.7121 58.1855 \; 95.7866 62.1503 \; 95.802 60.6281 \; 95.9891 57.3853 \; 96.2532 55.7833 \; 96.3873 55.2429 \; 96.4037 52.212 \; \;; #X scalar trace-template 640 0 13 \; 94.2517 62.278 \; 94.1561 59.1415 \; 93.9766 57.232 \; 93.8438 54.297 \; \;; #X scalar trace-template 640 0 14 \; 94.3441 59.5835 \; 94.4502 57.4434 \; 94.3668 58.1533 \; 94.5866 52.8031 \; \;; #X scalar trace-template 640 0 16 \; 95.0593 58.0663 \; 95.0532 60.0025 \; 95.1226 58.5712 \; 95.0483 50.1275 \; 94.9303 48.1923 \; \;; #X scalar trace-template 640 0 17 \; 97.7604 55.4184 \; 97.7452 59.611 \; 97.753 59.373 \; 97.8523 54.6533 \; 97.843 49.4806 \; \;; #X scalar trace-template 640 0 18 \; 92.8946 58.4034 \; 92.6925 54.4934 \; 92.7018 51.7524 \; 92.8118 51.2981 \; 92.7069 48.3812 \; 92.6705 43.2537 \; \;; #X scalar trace-template 640 0 19 \; 94.9616 59.297 \; \;; #X scalar trace-template 640 0 20 \; 91.6198 52.5509 \; \;; #X scalar trace-template 640 0 21 \; 76.7735 51.5719 \; 76.928 52.9243 \; 77.1241 51.2043 \; 77.3901 51.3419 \; 77.3609 50.3932 \; 77.3166 48.0167 \; 77.0858 43.0034 \; \;; #X scalar trace-template 640 0 23 \; 118.519 49.7004 \; \;; #X scalar trace-template 640 0 24 \; 79.0453 50.9433 \; \;; #X scalar trace-template 645 0 0 \; 53.4769 82.0777 \; \;; #X scalar trace-template 645 0 7 \; 65.4662 65.6075 \; \;; #X scalar trace-template 645 0 19 \; 93.532 61.6672 \; \;; #X scalar trace-template 645 0 20 \; 72.4406 60.6394 \; 73.1711 63.8493 \; 73.1219 63.4485 \; 73.005 60.9634 \; 72.9752 58.2399 \; 73.1187 54.2194 \; \;; #X scalar trace-template 645 0 23 \; 98.3726 54.6578 \; 98.4334 56.3528 \; 98.4641 55.9416 \; 98.4242 52.0511 \; \;; #X scalar trace-template 645 0 24 \; 23.7851 54.8485 \; \;; #X scalar trace-template 650 0 0 \; 97.3061 58.5622 \; 97.2776 59.1141 \; 97.492 54.2353 \; 97.5989 51.8676 \; 97.6619 47.3976 \; \;; #X scalar trace-template 650 0 1 \; 95.4167 56.8196 \; 95.3126 55.3792 \; 95.3283 46.7388 \; 95.1306 46.7253 \; 95.147 41.728 \; \;; #X scalar trace-template 650 0 7 \; 89.5699 53.2536 \; \;; #X scalar trace-template 650 0 19 \; 88.6175 52.5698 \; \;; #X scalar trace-template 650 0 22 \; 79.2767 52.119 \; 79.3102 49.5639 \; \;; #X scalar trace-template 650 0 24 \; 98.8685 51.0232 \; \;; #X scalar trace-template 655 0 7 \; 70.258 62.8691 \; 70.374 60.7793 \; 70.0017 59.3662 \; 69.5226 57.7477 \; \;; #X scalar trace-template 655 0 15 \; 95.7851 55.4228 \; 95.6031 52.903 \; 95.7044 50.4609 \; 95.6995 45.5615 \; \;; #X scalar trace-template 655 0 19 \; 94.3768 51.2544 \; 94.1946 47.8939 \; 94.328 44.6819 \; 94.3675 37.5612 \; \;; #X scalar trace-template 655 0 24 \; 98.1845 50.7136 \; 98.0865 53.434 \; 98.1691 51.3942 \; 98.141 44.0651 \; \;; #X scalar trace-template 660 0 11 \; 98.6655 52.1347 \; 98.7443 47.6732 \; 98.701 40.7718 \; \;; #X scalar trace-template 660 0 13 \; 89.1909 46.575 \; \;; #X scalar trace-template 660 0 14 \; 91.9512 47.5126 \; 91.8357 44.1274 \; \;; #X scalar trace-template 660 0 22 \; 74.884 44.8679 \; \;; #X scalar trace-template 665 0 13 \; 83.71 44.657 \; 83.6094 41.5368 \; \;; #X scalar trace-template 665 0 16 \; 85.0166 43.8889 \; 84.8868 38.345 \; \;; #X scalar trace-template 665 0 17 \; 92.0268 44.2326 \; \;; #X scalar trace-template 665 0 22 \; 92.8821 43.3524 \; 92.8403 35.8802 \; \;; #X scalar trace-template 665 0 23 \; 80.9979 42.8421 \; 80.2868 38.7355 \; \;; #X scalar trace-template 670 0 2 \; 74.5494 42.9236 \; \;; #X scalar trace-template 670 0 14 \; 79.3738 37.7132 \; \;; #X scalar trace-template 670 0 17 \; 117.855 37.7543 \; \;; #X scalar trace-template 670 0 18 \; 89.2631 35.1317 \; \;; #X coords 0 131.5 1 131.25 0 0 0; #X restore 298 436 pd trace-list; #N canvas 375 90 563 188 trace-template 0; #X text 121 93 This template describes a pitch/amplitude trace. The array "bazoo" holds the actual points. In this template \, y is always 0 and x is the starting location in pixels. There are 5 pixels per point.; #X obj 125 36 struct trace-template float x float y float voiceno array bazoo point-template; #X obj 121 72 plot bazoo 0 1 0 0 5; #X restore 417 546 pd trace-template; #N canvas 96 258 494 158 point-template 0; #X text 127 56 This template describes a single point on a pitch trace (cf. trace-template w describes the trace itself.); #X text 127 89 "y" is the field that is shown on the graph \; it's - 4 * pitch. You also get an "amp" field in dB \, which you can't see as a plot (yet).; #X obj 212 14 struct point-template float y float amp; #X restore 417 567 pd point-template; #X msg 746 506 bang; #X obj 8 425 pack 0 100; #X obj 8 449 line~; #X obj 8 404 dbtorms; #X floatatom 545 73 0 0 110 0 - - -; #N canvas 193 52 730 722 output 0; #X obj 295 76 t b f; #X obj 286 100 +; #X obj 515 207 f; #X obj 532 165 f; #X obj 359 210 f; #X obj 83 179 t b; #X obj 82 127 f; #X obj 71 58 inlet; #X text 78 37 mute; #X obj 83 201 f; #X msg 235 153 0; #X msg 74 84 bang; #X obj 83 155 moses 1; #X obj 231 69 t b f; #X obj 222 93 +; #X obj 181 27 r loop-amp; #X obj 395 26 r osc-amp; #X obj 83 236 s loop-amp; #X obj 359 235 s osc-amp; #X obj 186 148 f; #X obj 374 168 f; #X obj 225 120 t b b; #X obj 552 23 r grain-amp; #X obj 516 232 s grain-amp; #X connect 0 0 1 0; #X connect 0 1 1 1; #X connect 1 0 6 1; #X connect 2 0 23 0; #X connect 3 0 2 1; #X connect 4 0 18 0; #X connect 5 0 9 0; #X connect 5 0 4 0; #X connect 5 0 2 0; #X connect 6 0 12 0; #X connect 7 0 11 0; #X connect 9 0 17 0; #X connect 10 0 17 0; #X connect 10 0 18 0; #X connect 10 0 23 0; #X connect 11 0 6 0; #X connect 12 0 5 0; #X connect 12 1 21 0; #X connect 13 0 14 0; #X connect 13 1 14 1; #X connect 14 0 1 0; #X connect 15 0 14 0; #X connect 15 0 19 1; #X connect 16 0 13 0; #X connect 16 0 20 1; #X connect 19 0 9 1; #X connect 20 0 4 1; #X connect 21 0 10 0; #X connect 21 1 19 0; #X connect 21 1 20 0; #X connect 21 1 3 0; #X connect 22 0 3 1; #X connect 22 0 0 0; #X restore 820 69 pd output; #N canvas 516 98 663 559 (subpatch) 0; #X obj 103 108 outlet; #X msg 101 80 set \$1; #X obj 103 57 r loop-amp; #X connect 1 0 0 0; #X connect 2 0 1 0; #X restore 545 50 pd; #X obj 8 493 *~; #X obj 9 544 hip~ 5; #X obj 9 571 dac~; #X obj 754 529 adc~; #X obj 545 94 s loop-amp; #X msg 820 48 mute; #X text 33 110 click here first; #X text 741 489 live sample; #X text 677 25 AMPLITUDES; #N canvas 357 94 1152 664 make-trace 0; #X obj 781 133 pointer; #X obj 757 603 setsize trace-template bazoo; #X obj 757 490 random 200; #X obj 757 512 + 100; #X obj 870 511 pointer; #X obj 218 532 pointer; #X floatatom 356 524 0 0 0 0 - - -; #X floatatom 296 550 0 0 0 0 - - -; #X msg 205 509 bang; #X floatatom 108 461 0 0 0 0 - - -; #X floatatom 40 509 0 0 0 0 - - -; #X floatatom 153 590 0 0 0 0 - - -; #X floatatom 516 556 0 0 0 0 - - -; #X floatatom 356 489 0 0 0 0 - - -; #X floatatom 667 511 0 0 0 0 - - -; #X obj 419 435 pointer; #X msg 438 408 next; #X floatatom 532 512 0 0 0 0 - - -; #X obj 516 539 getsize trace-template bazoo; #X obj 127 563 get point-template y; #X obj 40 533 set point-template y; #X obj 101 486 element trace-template bazoo; #X obj 296 580 setsize trace-template bazoo; #X obj 356 507 set trace-template x; #X obj 356 542 set trace-template y; #X msg 757 468 bang; #X obj 757 534 append trace-template x; #X obj 519 489 get trace-template x y; #X obj 757 557 t b p; #X msg 757 580 5; #X obj 781 155 s last-in-list; #X msg 780 37 bang; #X obj 780 60 t b b; #X obj 710 134 f 0; #X obj 710 156 s nframe; #X obj 824 235 r nframe; #X obj 807 258 f; #X obj 807 282 + 1; #X obj 807 304 s nframe; #X obj 780 15 r clear-all; #X msg 781 111 traverse pd-trace-list \, bang; #X msg 419 382 traverse pd-trace-list \, next; #X msg 870 489 traverse pd-trace-list \, bang; #X obj 72 45 add-trace 0; #X obj 807 202 r done-analysis; #X msg 833 56 \; pd-trace-list clear \; add-trace-clear bang; #X obj 72 65 add-trace 1; #X obj 72 85 add-trace 2; #X obj 72 105 add-trace 3; #X obj 72 125 add-trace 4; #X obj 72 145 add-trace 5; #X obj 72 165 add-trace 6; #X obj 72 185 add-trace 7; #X obj 72 205 add-trace 8; #X obj 72 225 add-trace 9; #X obj 174 45 add-trace 10; #X obj 174 65 add-trace 11; #X obj 174 85 add-trace 12; #X obj 174 105 add-trace 13; #X obj 174 125 add-trace 14; #X obj 174 145 add-trace 15; #X obj 174 165 add-trace 16; #X obj 174 185 add-trace 17; #X obj 174 205 add-trace 18; #X obj 174 225 add-trace 19; #X obj 283 44 add-trace 20; #X obj 283 64 add-trace 21; #X obj 283 84 add-trace 22; #X obj 283 104 add-trace 23; #X obj 283 124 add-trace 24; #X obj 283 144 add-trace 25; #X obj 283 164 add-trace 26; #X obj 283 184 add-trace 27; #X obj 283 204 add-trace 28; #X obj 283 224 add-trace 29; #X obj 395 44 add-trace 30; #X obj 395 64 add-trace 31; #X obj 395 84 add-trace 32; #X obj 395 104 add-trace 33; #X obj 395 124 add-trace 34; #X obj 395 144 add-trace 35; #X obj 395 164 add-trace 36; #X obj 395 184 add-trace 37; #X obj 395 204 add-trace 38; #X obj 395 224 add-trace 39; #X obj 505 44 add-trace 40; #X obj 505 64 add-trace 41; #X obj 505 84 add-trace 42; #X obj 505 104 add-trace 43; #X obj 505 124 add-trace 44; #X obj 505 144 add-trace 45; #X obj 505 164 add-trace 46; #X obj 505 184 add-trace 47; #X obj 505 204 add-trace 48; #X obj 505 224 add-trace 49; #X connect 0 0 30 0; #X connect 2 0 3 0; #X connect 3 0 26 0; #X connect 4 0 26 1; #X connect 5 0 19 0; #X connect 6 0 24 0; #X connect 7 0 22 0; #X connect 8 0 5 0; #X connect 9 0 21 0; #X connect 10 0 20 0; #X connect 13 0 23 0; #X connect 15 0 22 1; #X connect 15 0 23 1; #X connect 15 0 24 1; #X connect 15 0 21 1; #X connect 15 0 27 0; #X connect 15 0 18 0; #X connect 16 0 15 0; #X connect 18 0 12 0; #X connect 19 0 11 0; #X connect 21 0 5 0; #X connect 21 0 20 1; #X connect 25 0 2 0; #X connect 26 0 28 0; #X connect 27 0 17 0; #X connect 27 1 14 0; #X connect 28 0 29 0; #X connect 28 1 1 1; #X connect 29 0 1 0; #X connect 31 0 32 0; #X connect 32 0 40 0; #X connect 32 0 33 0; #X connect 32 1 45 0; #X connect 33 0 34 0; #X connect 35 0 36 1; #X connect 36 0 37 0; #X connect 37 0 38 0; #X connect 39 0 31 0; #X connect 40 0 0 0; #X connect 41 0 15 0; #X connect 42 0 4 0; #X connect 44 0 36 0; #X restore 417 503 pd make-trace; #X floatatom 74 236 0 0 0 0 location location-set location; #X obj 106 417 r loop-amp; #X obj 737 288 f; #X obj 777 288 +; #X msg 695 330 0; #X msg 694 247 1; #X msg 737 337 \; location \$1 \; snapshot bang; #X floatatom 655 305 0 0 0 0 - - -; #X obj 628 231 t b b; #X obj 838 270 r incr; #X obj 8 383 r grain-amp; #X obj 121 467 r osc-amp; #X obj 143 553 catch~ osc-sum; #N canvas 0 50 887 632 osc-bank 0; #X msg 203 132 0; #X obj 508 403 pointer; #X obj 415 229 pointer; #X msg 341 373 next; #X msg 332 169 1; #X msg 373 168 0; #X obj 415 326 <; #X obj 415 252 t p p; #X obj 203 213 until; #X obj 413 55 r start-resynth; #X obj 314 229 f; #X obj 314 252 sel 0 1; #X obj 446 326 r synth-index; #X obj 414 349 sel 0 1; #X obj 72 91 r step-resynth; #X obj 203 159 f; #X obj 204 183 s synth-index; #X obj 244 160 + 5; #X obj 72 113 t b b b; #X obj 73 187 s osc-tick; #X msg 413 166 traverse pd-trace-list \, next; #N canvas 0 55 1009 518 oscs 0; #X obj 18 66 route 1 2 3 4 5 6 7 8 9 10; #X obj 272 65 route 11 12 13 14 15 16 17 18 19 20; #X obj 17 26 inlet; #X obj 594 66 route 21 22 23 24 25 26 27 28 29 30; #X obj 154 293 route 31 32 33 34 35 36 37 38 39 40; #X obj 465 294 route 41 42 43 44 45 46 47 48 49 50; #X obj 18 260 osc-voice; #X obj 60 222 osc-voice; #X obj 206 89 osc-voice; #X obj 185 107 osc-voice; #X obj 164 127 osc-voice; #X obj 143 146 osc-voice; #X obj 122 166 osc-voice; #X obj 102 184 osc-voice; #X obj 81 203 osc-voice; #X obj 39 242 osc-voice; #X obj 506 91 osc-voice; #X obj 485 109 osc-voice; #X obj 464 129 osc-voice; #X obj 443 148 osc-voice; #X obj 422 168 osc-voice; #X obj 402 186 osc-voice; #X obj 381 205 osc-voice; #X obj 360 224 osc-voice; #X obj 339 244 osc-voice; #X obj 318 262 osc-voice; #X obj 828 92 osc-voice; #X obj 807 110 osc-voice; #X obj 786 130 osc-voice; #X obj 765 149 osc-voice; #X obj 744 169 osc-voice; #X obj 724 187 osc-voice; #X obj 703 206 osc-voice; #X obj 682 225 osc-voice; #X obj 661 245 osc-voice; #X obj 640 263 osc-voice; #X obj 388 319 osc-voice; #X obj 367 337 osc-voice; #X obj 346 357 osc-voice; #X obj 325 376 osc-voice; #X obj 304 396 osc-voice; #X obj 284 414 osc-voice; #X obj 263 433 osc-voice; #X obj 242 452 osc-voice; #X obj 221 472 osc-voice; #X obj 200 490 osc-voice; #X obj 699 320 osc-voice; #X obj 678 338 osc-voice; #X obj 657 358 osc-voice; #X obj 636 377 osc-voice; #X obj 615 397 osc-voice; #X obj 595 415 osc-voice; #X obj 574 434 osc-voice; #X obj 553 453 osc-voice; #X obj 532 473 osc-voice; #X obj 511 491 osc-voice; #X connect 0 0 6 0; #X connect 0 1 15 0; #X connect 0 2 7 0; #X connect 0 3 14 0; #X connect 0 4 13 0; #X connect 0 5 12 0; #X connect 0 6 11 0; #X connect 0 7 10 0; #X connect 0 8 9 0; #X connect 0 9 8 0; #X connect 0 10 1 0; #X connect 1 0 25 0; #X connect 1 1 24 0; #X connect 1 2 23 0; #X connect 1 3 22 0; #X connect 1 4 21 0; #X connect 1 5 20 0; #X connect 1 6 19 0; #X connect 1 7 18 0; #X connect 1 8 17 0; #X connect 1 9 16 0; #X connect 1 10 3 0; #X connect 2 0 0 0; #X connect 3 0 35 0; #X connect 3 1 34 0; #X connect 3 2 33 0; #X connect 3 3 32 0; #X connect 3 4 31 0; #X connect 3 5 30 0; #X connect 3 6 29 0; #X connect 3 7 28 0; #X connect 3 8 27 0; #X connect 3 9 26 0; #X connect 3 10 4 0; #X connect 4 0 45 0; #X connect 4 1 44 0; #X connect 4 2 43 0; #X connect 4 3 42 0; #X connect 4 4 41 0; #X connect 4 5 40 0; #X connect 4 6 39 0; #X connect 4 7 38 0; #X connect 4 8 37 0; #X connect 4 9 36 0; #X connect 4 10 5 0; #X connect 5 0 55 0; #X connect 5 1 54 0; #X connect 5 2 53 0; #X connect 5 3 52 0; #X connect 5 4 51 0; #X connect 5 5 50 0; #X connect 5 6 49 0; #X connect 5 7 48 0; #X connect 5 8 47 0; #X connect 5 9 46 0; #X restore 380 563 pd oscs; #X obj 412 92 t b b b; #X msg 475 92 \; pd-trace-list sort; #X obj 332 199 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 415 276 get trace-template x; #X obj 415 302 f; #X obj 437 376 t b b b; #X obj 380 504 poly 50; #X obj 379 437 f; #X obj 420 426 + 1; #X obj 420 450 mod 1e+06; #X obj 379 476 pack 0 1; #X obj 380 534 pack f f f p; #X text 297 425 make an ID; #X text 298 439 for the; #X text 300 454 track; #X obj 161 455 r osc-noteoff; #X text 159 409 voice sends us; #X text 158 424 a note-off when; #X text 161 436 done; #X text 457 555 message is: voice number \, on/off \, track ID \, pointer ; #X obj 160 482 pack 0 0; #X connect 0 0 15 0; #X connect 1 0 33 3; #X connect 2 0 7 0; #X connect 2 1 5 0; #X connect 2 1 8 1; #X connect 3 0 2 0; #X connect 4 0 24 0; #X connect 5 0 24 0; #X connect 6 0 13 0; #X connect 7 0 25 0; #X connect 7 1 1 1; #X connect 8 0 10 0; #X connect 9 0 22 0; #X connect 10 0 11 0; #X connect 11 0 8 1; #X connect 11 1 26 0; #X connect 12 0 6 1; #X connect 13 0 8 1; #X connect 13 1 27 0; #X connect 14 0 18 0; #X connect 15 0 16 0; #X connect 15 0 17 0; #X connect 17 0 15 1; #X connect 18 0 19 0; #X connect 18 1 8 0; #X connect 18 2 15 0; #X connect 20 0 2 0; #X connect 22 0 20 0; #X connect 22 1 4 0; #X connect 22 1 0 0; #X connect 22 2 23 0; #X connect 24 0 10 1; #X connect 25 0 26 0; #X connect 26 0 6 0; #X connect 27 0 3 0; #X connect 27 1 29 0; #X connect 27 2 1 0; #X connect 28 0 33 0; #X connect 28 1 33 2; #X connect 28 2 33 1; #X connect 29 0 30 0; #X connect 29 0 32 0; #X connect 30 0 31 0; #X connect 31 0 29 1; #X connect 32 0 28 0; #X connect 33 0 21 0; #X connect 37 0 42 0; #X connect 42 0 28 0; #X restore 417 458 pd osc-bank; #X obj 647 98 s grain-amp; #N canvas 207 50 820 345 save-list 0; #X floatatom 759 255 0 0 0 0 - - -; #X floatatom 677 254 0 0 0 0 - - -; #X floatatom 599 251 0 0 0 0 - - -; #X floatatom 517 250 0 0 0 0 - - -; #X obj 448 201 pointer; #X obj 307 121 pointer; #X msg 328 47 bang; #X obj 134 193 rmstodb; #X obj 10 201 * 0.1; #X obj 134 216 * -3; #X floatatom 445 247 0 0 0 0 - - -; #X obj 304 24 r start-analysis; #X obj 305 71 t b b; #X msg 469 180 next; #X obj 443 222 get peak-template x y amp ampreal ampimag; #X obj 9 241 append peak-template x y amp ampreal ampimag; #X obj 126 137 r found-peak; #X obj 126 161 unpack 0 0 0 0 0; #X msg 81 201 330; #X msg 374 58 \; pd-peak-list clear; #X msg 305 100 traverse pd-peak-list \, bang; #X msg 450 161 traverse pd-peak-list \, next; #X connect 4 0 14 0; #X connect 5 0 15 5; #X connect 6 0 12 0; #X connect 7 0 9 0; #X connect 8 0 15 0; #X connect 9 0 15 2; #X connect 11 0 12 0; #X connect 12 0 20 0; #X connect 12 1 19 0; #X connect 13 0 4 0; #X connect 14 0 10 0; #X connect 14 1 3 0; #X connect 14 2 2 0; #X connect 14 3 1 0; #X connect 14 4 0 0; #X connect 16 0 17 0; #X connect 17 1 8 0; #X connect 17 2 18 0; #X connect 17 2 7 0; #X connect 17 3 15 3; #X connect 17 4 15 4; #X connect 18 0 15 1; #X connect 20 0 5 0; #X connect 21 0 4 0; #X restore 417 481 pd save-list; #X msg 139 349 \; start-resynth bang; #X msg 301 350 \; step-resynth bang; #X msg 461 352 \; osc-stop bang; #X text 780 116 resynth; #X text 643 115 analyzed grains; #X text 545 113 original; #X text 597 146 ... and here third to analyze; #X text 310 107 read a sample; #N canvas 189 52 500 453 test-signal 0; #X obj 174 293 tabread4~ sample; #X obj 174 268 line~; #X obj 123 146 f; #X obj 330 46 r insamprate; #X obj 177 350 *~; #X obj 213 351 dbtorms; #X obj 213 328 inlet; #X obj 175 415 outlet~; #X obj 190 33 r insamplength; #X msg 174 247 0 \, \$1 \$2; #X obj 174 221 pack 0 0; #X obj 272 190 /; #X obj 389 99 * 0.001; #X obj 175 388 hip~ 5; #X obj 43 5 loadbang; #X text 315 13 sample playback; #X msg 43 25 1; #X obj 43 69 metro 1000; #X floatatom 43 48 0 0 0 0 - - -; #X obj 331 75 t b b f; #X obj 209 84 t b f; #X connect 0 0 4 0; #X connect 1 0 0 0; #X connect 2 0 10 0; #X connect 3 0 19 0; #X connect 4 0 13 0; #X connect 5 0 4 1; #X connect 6 0 5 0; #X connect 8 0 20 0; #X connect 9 0 1 0; #X connect 10 0 9 0; #X connect 11 0 10 1; #X connect 11 0 17 1; #X connect 12 0 11 1; #X connect 13 0 7 0; #X connect 14 0 16 0; #X connect 16 0 18 0; #X connect 17 0 2 0; #X connect 18 0 17 0; #X connect 19 0 16 0; #X connect 19 1 11 0; #X connect 19 2 12 0; #X connect 20 0 16 0; #X connect 20 1 11 0; #X connect 20 1 2 1; #X restore 106 440 pd test-signal; #N canvas 132 255 634 331 insample 0; #N canvas 0 50 450 300 (subpatch) 0; #X array sample 62079 float 0; #X coords 0 1 62078 -1 400 150 1; #X restore 259 18 graph; #X obj 25 70 r read-sample; #X obj 25 95 unpack s f; #X obj 69 121 s insamprate; #X obj 25 171 soundfiler; #X msg 25 147 read -resize \$1 sample; #X obj 25 201 s insamplength; #X msg 464 197 \; sample resize 220500 \; insamplength 220500; #X obj 42 272 declare -path lib; #X connect 1 0 2 0; #X connect 2 0 5 0; #X connect 2 1 3 0; #X connect 4 0 6 0; #X connect 5 0 4 0; #X restore 296 509 pd insample; #X obj 744 553 tabwrite~ sample; #X text 152 0 SINUSOID TRACKING; #X obj 752 268 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 301 306 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X msg 207 130 \; read-sample ../doc/sound/bell.aiff 44100; #N canvas 143 192 728 480 sigmund 0; #X obj 2 227 spigot; #X obj 165 94 f; #X obj 165 128 pack; #X obj 268 67 r window-size; #X obj 354 92 r location; #X obj 354 116 *; #X obj 449 47 r sample-rate; #X obj 449 71 * 0.001; #X obj 166 31 r snapshot; #X obj 73 228 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 ; #X obj 24 331 s done-analysis; #X obj 355 334 s start-analysis; #X obj 147 333 s found-peak; #X obj 26 303 spigot; #X obj 145 306 spigot; #X obj 356 305 spigot; #X obj 390 278 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1; #X obj 165 64 t b b b; #X msg 165 160 list sample \$1 \$2 44100 0; #X obj 53 163 print; #X obj 391 230 loadbang; #X msg 392 251 1; #X obj 257 306 spigot; #X obj 259 333 s track-out; #X obj 556 288 spigot; #X obj 627 289 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; #X obj 555 314 print t; #X obj 1 253 print p; #X obj 165 186 sigmund~ -t -npts 1024 -npeak 40 -maxfreq 8000 peaks tracks; #X floatatom 507 135 5 1 50 0 - - -, f 5; #X msg 507 155 npeak \$1; #X obj 506 109 r nvoice; #X connect 0 0 27 0; #X connect 1 0 2 0; #X connect 2 0 18 0; #X connect 3 0 1 1; #X connect 4 0 5 0; #X connect 5 0 2 1; #X connect 6 0 7 0; #X connect 7 0 5 1; #X connect 8 0 17 0; #X connect 9 0 0 1; #X connect 13 0 10 0; #X connect 14 0 12 0; #X connect 15 0 11 0; #X connect 16 0 15 1; #X connect 16 0 14 1; #X connect 16 0 13 1; #X connect 16 0 22 1; #X connect 17 0 13 0; #X connect 17 1 1 0; #X connect 17 2 15 0; #X connect 18 0 28 0; #X connect 20 0 21 0; #X connect 21 0 16 0; #X connect 22 0 23 0; #X connect 24 0 26 0; #X connect 25 0 24 1; #X connect 28 0 0 0; #X connect 28 0 14 0; #X connect 28 1 22 0; #X connect 28 1 24 0; #X connect 29 0 30 0; #X connect 30 0 28 0; #X connect 31 0 29 0; #X restore 417 436 pd sigmund; #X msg 206 167 \; read-sample ../doc/sound/voice.wav 44100; #X msg 206 206 \; read-sample ../doc/sound/voice2.wav 44100; #X obj 737 311 moses 1350; #X text 142 246 to resynthesize \, "start" once and "step" ad lib. To stop \, stop stepping and hit osc-stop. Note resynth amplitude control above.; #X msg 24 127 \; pd dsp 1 \; window-size 2048 \; sample-rate 44100 \; incr 10; #X obj 737 245 metro 50; #X obj 301 326 metro 10; #N canvas 0 50 1028 393 misc 0; #X floatatom 56 120 0 0 0 0 - - -; #X obj 56 141 s loud; #X msg 49 84 \; clear-all bang; #X msg 51 52 \; snapshot bang; #X obj 233 60 osc~ 110; #X obj 287 115 line~; #X obj 233 112 *~; #X obj 231 150 +~ 0.2; #X obj 230 178 cos~; #X obj 269 212 line~; #X obj 227 211 *~; #X obj 234 295 tabwrite~ sample; #X obj 426 31 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X msg 345 75 0 \, 2 500; #X msg 438 75 0 \, 1 100; #X obj 538 121 del 500; #X msg 426 164 0.05 500; #X msg 532 171 0 2000; #X obj 723 119 r location; #X msg 723 140 set \$1; #X obj 722 163 s location-set; #X msg 719 224 set \$1; #X obj 719 203 r osc-speed; #X obj 719 247 s osc-speed-set; #X msg 718 318 set \$1; #X obj 718 297 r nvoice; #X obj 718 341 s nvoice-set; #X obj 725 33 loadbang; #X msg 725 60 \; osc-speed 10 \; nvoice 25; #X connect 0 0 1 0; #X connect 4 0 6 0; #X connect 5 0 6 1; #X connect 6 0 7 0; #X connect 7 0 8 0; #X connect 8 0 10 0; #X connect 9 0 10 1; #X connect 10 0 11 0; #X connect 12 0 13 0; #X connect 12 0 11 0; #X connect 12 0 14 0; #X connect 12 0 15 0; #X connect 13 0 5 0; #X connect 14 0 9 0; #X connect 15 0 17 0; #X connect 15 0 16 0; #X connect 16 0 5 0; #X connect 17 0 9 0; #X connect 18 0 19 0; #X connect 19 0 20 0; #X connect 21 0 23 0; #X connect 22 0 21 0; #X connect 24 0 26 0; #X connect 25 0 24 0; #X connect 27 0 28 0; #X restore 296 488 pd misc; #X floatatom 412 296 0 0 0 0 osc-speed osc-speed-set osc-speed; #X floatatom 75 261 0 1 50 0 nvoice nvoice-set nvoice; #X obj 375 326 r osc-speed; #X text 24 293 analysis; #X text 26 308 parameters; #X text 13 24 This patch derives sinusoidal "tracks" from a sampled sound using sigmund~ and the data structure facilities. The number of tracks may range from 1 to 50 You can edit the tracks (but note that the resynthezier is limited to 50-voice polyphony.); #X obj 628 170 bng 25 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1; #X msg 618 353 \; location 0 \; clear-all bang; #N canvas 2 261 838 506 grain 0; #X floatatom 305 194 0 0 0 0 - - -; #X obj 454 160 r sample-rate; #X obj 454 180 t b f; #X obj 304 169 r window-size; #X obj 264 38 r sample-rate; #X obj 238 16 r window-size; #X obj 264 58 t b f; #X obj 238 83 /; #X obj 168 103 bang~; #X obj 169 175 line~; #X obj 238 104 * 1000; #X text 298 104 window size (msec); #X obj 429 140 r location; #X obj 429 205 *; #X obj 429 228 * 0.001; #X text 498 228 location (samples); #X obj 169 129 f; #X msg 169 152 0 \, 1 \$1; #X obj 113 201 *~; #X obj 113 224 -~; #X obj 114 278 *~; #X obj 114 301 outlet~; #X floatatom 429 252 0 0 0 0 - - -; #X obj 66 31 block~ 2048 1; #X obj 168 255 tabread4~ sample; #X obj 169 211 *~ 0; #X obj 168 232 +~ 0; #X connect 1 0 2 0; #X connect 2 0 13 0; #X connect 2 1 13 1; #X connect 3 0 0 0; #X connect 3 0 25 1; #X connect 4 0 6 0; #X connect 5 0 7 0; #X connect 6 0 7 0; #X connect 6 1 7 1; #X connect 7 0 10 0; #X connect 8 0 16 0; #X connect 9 0 18 0; #X connect 9 0 18 1; #X connect 9 0 19 1; #X connect 9 0 25 0; #X connect 10 0 16 1; #X connect 12 0 13 0; #X connect 13 0 14 0; #X connect 14 0 22 0; #X connect 14 0 26 1; #X connect 16 0 17 0; #X connect 17 0 9 0; #X connect 18 0 19 0; #X connect 19 0 20 0; #X connect 20 0 21 0; #X connect 24 0 20 1; #X connect 25 0 26 0; #X connect 26 0 24 0; #X restore 22 470 pd grain; #X connect 0 0 2 0; #X connect 1 0 0 0; #X connect 3 0 4 0; #X connect 4 0 6 0; #X connect 5 0 3 0; #X connect 6 0 26 0; #X connect 7 0 72 1; #X connect 8 0 37 1; #X connect 9 0 72 0; #X connect 10 0 38 1; #X connect 11 0 49 0; #X connect 12 0 11 0; #X connect 18 0 61 0; #X connect 19 0 20 0; #X connect 20 0 25 0; #X connect 21 0 19 0; #X connect 22 0 29 0; #X connect 24 0 22 0; #X connect 25 0 26 0; #X connect 26 0 27 0; #X connect 26 0 27 1; #X connect 28 0 61 0; #X connect 30 0 23 0; #X connect 36 0 59 0; #X connect 37 0 38 0; #X connect 37 0 42 0; #X connect 37 0 69 0; #X connect 38 0 37 1; #X connect 39 0 9 0; #X connect 40 0 9 0; #X connect 43 0 40 0; #X connect 43 1 8 0; #X connect 43 1 82 0; #X connect 44 0 10 0; #X connect 45 0 21 0; #X connect 46 0 5 0; #X connect 47 0 6 1; #X connect 59 0 26 0; #X connect 63 0 37 0; #X connect 64 0 73 0; #X connect 69 0 41 0; #X connect 69 1 39 0; #X connect 72 0 37 0; #X connect 73 0 52 0; #X connect 77 0 73 1; #X connect 81 0 43 0; #X connect 83 0 25 1; pd-0.46-7/doc/4.data.structures/05.array.pd0000664000175000017500000001016412222367057016334 0ustar mspmsp#N struct template5 float x float y float z float q array bazoo template5-element ; #N struct template5-element float y; #N canvas 17 49 709 456 12; #X obj 235 323 pointer; #X floatatom 232 183 0 0 0 0 - - -; #X msg 235 300 bang; #X floatatom 15 200 0 0 0 0 - - -; #X floatatom 17 350 0 0 0 0 - - -; #X floatatom 235 369 0 0 0 0 - - -; #X floatatom 451 276 0 0 0 0 - - -; #X obj 451 229 pointer; #X obj 318 163 pointer; #X msg 449 194 bang; #N canvas 29 563 348 217 data5 1; #X scalar template5 50 80 30 9 \; 0 \; 0 \; 0 \; 0 \; 0 \; 3 \; 0 \; 0 \; 0 \; 7 \; -30 \; 0 \; 0 \; 0 \; 0 \; 0 \; 0 \; 0 \; 0 \; 0 \; 0 \; 0 \; 0 \; 0 \; 0 \; 0 \; 0 \; 0 \; 0 \; 0 \; 0 \; 0 \; 0 \; 0 \; 0 \; 0 \; 0 \; 0 \; 0 \; 0 \; 0 \; 0 \; 0 \; 0 \; 0 \; 43 \; 0 \; 0 \; 0 \; 0 \; \;; #X restore 508 314 pd data5; #N canvas 384 566 646 260 template5 1; #X obj 8 91 filledpolygon 244 q 3 0 0 20 z 40 0; #X text 6 44 this declares an array named "bazoo" whose elements are described by "template5-element." Array declarations take three arguments while "float" declarations take only two.; #X text 6 136 Here we ask to plot the array \, color 700 \, line width 3 \, starting location (30 \, 10) relative to the scalar \, points spaced 4 apart.; #X text 7 186 You can also do (x \, y) plots and/or make the line thickness variable---see the help window for "plot".; #X obj 6 8 struct template5 float x float y float z float q array bazoo template5-element; #X obj 8 113 plot bazoo 700 3 30 40 4; #X restore 508 337 pd template5; #N canvas 65 248 568 128 template5-element 0; #X text 12 36 This says that array elements will have a single floating-point number named "y". The variable name "y" is automatically assumed to control screen height \; if you don't have at least that variable you can't plot the array..; #X obj 35 11 struct template5-element float y; #X restore 508 360 pd template5-element; #N canvas 512 81 589 429 stuff 0; #X obj 354 163 pointer; #X obj 136 102 t b b b; #X msg 136 61 bang; #X text 176 60 click here to re-initialize; #X obj 134 163 append template5 x y z q; #X msg 354 100 \; pd-data5 clear; #X msg 354 140 traverse pd-data5 \, bang; #X msg 283 280 50; #X obj 284 307 setsize template5 bazoo; #X obj 134 191 t b b p; #X floatatom 68 327 0 0 0 0 - - -; #X floatatom 14 332 0 0 0 0 - - -; #X obj 14 376 set template5-element y; #X obj 68 350 element template5 bazoo; #X obj 20 303 unpack; #X msg 12 258 3 5 \, 7 9 \, -30 10 \, 43 45; #X msg 134 140 50 80 30 9; #X connect 0 0 4 4; #X connect 1 0 16 0; #X connect 1 1 6 0; #X connect 1 2 5 0; #X connect 2 0 1 0; #X connect 4 0 9 0; #X connect 6 0 0 0; #X connect 7 0 8 0; #X connect 9 0 15 0; #X connect 9 1 7 0; #X connect 9 2 8 1; #X connect 9 2 13 1; #X connect 10 0 13 0; #X connect 11 0 12 0; #X connect 13 0 12 1; #X connect 14 0 11 0; #X connect 14 1 10 0; #X connect 15 0 14 0; #X connect 16 0 4 0; #X restore 508 383 pd stuff; #X msg 318 140 traverse pd-data5 \, next; #X obj 451 252 getsize template5 bazoo; #X obj 232 229 setsize template5 bazoo; #X obj 17 373 set template5-element y; #X obj 235 346 get template5-element y; #X obj 15 223 element template5 bazoo; #X text 38 15 Scalars may contain arrays \, and moreover the elements of an array can be of any scalar type (and can have sub-arrays recursively.) The type of the element of an array is fixed in the template. In this case \, "template5" contains the definition of the top-level scalar and "template5-element" is the template of each array element (see the template subpatch.); #X text 328 121 click to get pointer; #X text 449 173 get size; #X text 221 158 set size; #X text 16 133 select an individual; #X text 16 153 element \, which is a; #X text 14 169 scalar with template; #X text 104 189 template5; #X text 12 413 work as before \, but on; #X text 12 433 array elements...; #X text 433 424 Updated for Pd version 0.35; #X text 17 395 normal "set" amd "get"; #X connect 0 0 18 0; #X connect 1 0 16 0; #X connect 2 0 0 0; #X connect 3 0 19 0; #X connect 4 0 17 0; #X connect 7 0 15 0; #X connect 8 0 16 1; #X connect 8 0 19 1; #X connect 8 0 7 0; #X connect 9 0 7 0; #X connect 14 0 8 0; #X connect 15 0 6 0; #X connect 18 0 5 0; #X connect 19 0 0 0; #X connect 19 0 17 1; pd-0.46-7/doc/4.data.structures/10.onoff.pd0000664000175000017500000000420112160204055016301 0ustar mspmsp#N struct template10 float x float y float a float b float c float w; #N canvas 322 90 571 381 12; #X text 315 344 updated for Pd version 0.39; #N canvas 36 348 577 459 template10 1; #X obj 63 327 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 63 349 t b b; #X obj 242 408 pointer; #X msg 92 377 traverse pd-data10 \, bang; #X obj 33 203 drawpolygon 0 1 20 20 20 -20 -20 -20 -20 20 20 20; #X obj 33 111 drawcurve -v b 900 2 a(0:100)(0:100) 0 a(0:100)(0:71) a(0:100)(0:71) 0 a(0:100)(0:100) a(0:100)(0:-71) a(0:100)(0:71) a(0:100)(0:-100) 0 a(0:100)(0:-71) a(0:100)(0:-71) 0 a(0:100)(0:-100) a(0:100)(0:71) a(0:100)(0:-71) a(0:100)(0:100) 0; #X obj 33 274 drawnumber b -10 -30 0; #X text 71 86 "circle" of radius a \, visible when b != 0; #X obj 63 433 append template10 x y a b; #X msg 61 409 50 50 10 1; #X obj 24 19 struct template10 float x float y float a float b; #X text 23 50 Template demonstrating turning a drawing instruction on and off.; #X obj 33 231 loadbang; #X obj 33 254 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1 ; #X text 63 252 <- show/hide this drawing instruction; #X connect 0 0 1 0; #X connect 1 0 9 0; #X connect 1 1 3 0; #X connect 2 0 8 4; #X connect 3 0 2 0; #X connect 9 0 8 0; #X connect 12 0 13 0; #X connect 13 0 6 0; #X restore 22 236 pd template10; #N canvas 210 14 324 294 data10 1; #X scalar template10 92 193 15 1 40 0 \;; #X scalar template10 180 161 15 0 40 0 \;; #X coords 0 294 1 293 0 0 0; #X restore 23 269 pd data10; #X text 25 13 Drawing instructions can be dynamically turned on and off \, either globally for all data of a given template \, or locally according to a data field. In this example the "drawcurve" instruction's arguments contain the leading flag "-v b" meaning that its visibility is turned on and off by the field b.; #X text 25 111 To turn a drawing instruction on and off globally \, send a number to its inlet. By default drawing instructions are initially visible \, unless given the "-n" flag.; #X text 21 169 Arrays have the additional possibility of turning on and off drawing instructions for their individual points as scalars. Use "-vs z" to make the variable z control this.; pd-0.46-7/doc/4.data.structures/04.append.pd0000664000175000017500000000273212160204055016453 0ustar mspmsp#N canvas 308 71 688 415 12; #X obj 421 332 pointer; #X obj 108 277 t b b b; #X msg 120 241 bang; #X text 161 240 click here to re-initialize; #X msg 11 313 50 250 30 9 \, 200 200 -20 900 \, 100 200 -50 30; #X text 56 27 The objects below put three items in the data window. First the window is cleared. Then a "pointer" object is instructed to point to the beginning of the data window ("traverse pd-data") \, and to output its value ("bang") to the "append" object. This object is then given numeric values to create three items.; #X obj 11 336 append template4 x y z q; #X msg 421 269 \; pd-data4 clear; #N canvas 0 0 315 341 data4 1; #X restore 430 219 pd data4; #N canvas 15 278 519 148 template4 0; #X obj 17 44 filledpolygon 244 q 5 0 0 20 z 40 0; #X text 13 79 The template for the two scalars \, as in the last patch ; #X obj 17 19 struct template4 float x float y float z float q; #X restore 428 243 pd template4; #X msg 421 309 traverse pd-data4 \, bang; #X text 57 165 The outlet of "append" is a pointer to the newly created scalar. You can pass that on to other append objects if you want to build heterogenous lists.; #X text 363 375 Updated for Pd version 0.32; #X text 57 121 The "append" object is given the argument "template4" to specify what kind of data structure to append. The other arguments are the names of variables we'll set.; #X connect 0 0 6 4; #X connect 1 0 4 0; #X connect 1 1 10 0; #X connect 1 2 7 0; #X connect 2 0 1 0; #X connect 4 0 6 0; #X connect 10 0 0 0; pd-0.46-7/doc/4.data.structures/data-start.pd0000664000175000017500000000206112160204055017021 0ustar mspmsp#N canvas 404 0 597 385 12; #X obj 248 142 inlet; #X obj 295 250 *; #X obj 165 262 del; #X obj 130 141 r reset-stop; #X obj 195 339 outlet; #X obj 375 172 outlet; #X obj 310 145 get \$1 x y; #X obj 195 312 pointer; #X text 46 101 outlets: pointer (delayed) \, y-value.; #X obj 248 167 t b p; #X obj 165 288 t b b; #X obj 335 224 r time-of-last-evt; #X obj 295 223 -; #X obj 310 167 t f f; #X obj 97 339 s next-evt; #X obj 335 201 s time-of-last-evt; #X obj 329 251 r delay-multiplier; #X text 49 10 This is an abstraction used by the sequencer example. ; #X text 46 45 Here we carry out the actual sequencing. Argument is template of the scalar. Note the sends and receives which must agree with the rest of the patch.; #X connect 0 0 9 0; #X connect 1 0 2 1; #X connect 2 0 10 0; #X connect 3 0 2 0; #X connect 6 0 13 0; #X connect 6 1 5 0; #X connect 7 0 4 0; #X connect 9 0 2 0; #X connect 9 1 7 1; #X connect 9 1 6 0; #X connect 10 0 14 0; #X connect 10 1 7 0; #X connect 11 0 12 1; #X connect 12 0 1 0; #X connect 13 0 15 0; #X connect 13 1 12 0; #X connect 16 0 1 1; pd-0.46-7/doc/4.data.structures/08.selection.pd0000664000175000017500000000567512441401272017210 0ustar mspmsp#N struct template8 float x float y float w float h float q; #N canvas 628 474 586 452 12; #X floatatom 53 347 0 0 0 0 - - -; #X floatatom 53 299 0 0 0 0 - - -; #X floatatom 53 251 0 0 0 0 - - -; #X floatatom 53 203 0 0 0 0 - - -; #X floatatom 342 283 0 0 0 0 - - -; #X floatatom 301 283 0 0 0 0 - - -; #X floatatom 258 283 0 0 0 0 - - -; #X floatatom 215 283 0 0 0 0 - - -; #X floatatom 374 283 0 0 0 0 - - -; #X floatatom 53 394 0 0 0 0 - - -; #N canvas 17 52 388 446 data8 1; #X scalar template8 29 182 0 16 917 \;; #X scalar template8 290 272 0 32 66 \;; #X scalar template8 186 29 46 71 78 \;; #X scalar template8 21 318 49 42 220 \;; #X scalar template8 112 201 28 72 634 \;; #X scalar template8 250 125 46 11 48 \;; #X scalar template8 26 62 70 11 903 \;; #X scalar template8 260 36 10 4 169 \;; #X scalar template8 230 175 25 27 710 \;; #X scalar template8 282 266 50 25 612 \;; #X scalar template8 55 183 62 51 421 \;; #X scalar template8 177 241 39 66 866 \;; #X scalar template8 145 96 27 27 125 \;; #X scalar template8 116 85 66 32 319 \;; #X scalar template8 135 61 50 25 454 \;; #X scalar template8 275 117 21 45 583 \;; #X scalar template8 270 230 25 38 548 \;; #X scalar template8 217 249 24 73 214 \;; #X scalar template8 214 312 50 78 652 \;; #X scalar template8 288 91 72 19 325 \;; #X restore 410 359 pd data8; #N canvas 280 471 688 314 template8 0; #X obj 25 177 filledpolygon q 0 1 0 0 w 0 w h 0 h; #X obj 26 200 drawnumber q 0 0 0; #X obj 24 19 struct template8 float x float y float w float h float q; #X obj 24 74 route select; #X obj 24 103 outlet; #X obj 32 46 print struct-template8; #X text 151 72 "struct" outputs messages notifying you when objects of this structure are selected or deselected. Here we only catch selection. ; #X connect 2 0 3 0; #X connect 2 0 5 0; #X connect 3 0 4 0; #X restore 215 208 pd template8; #X text 46 5 This patch demonstrates catching the selection so you can make control panels to edit parameters. The "struct" object outputs a pointer to any selected object of type struct8.; #X obj 53 227 set template8 x; #X obj 53 275 set template8 y; #X obj 53 323 set template8 w; #X obj 53 370 set template8 h; #X obj 53 417 set template8 q; #X obj 215 259 get template8 x y w h q; #X text 46 68 To try it \, unlock the subpatch (data8) and select something. The 5 paramters should show up under the "get" object in this window \, and you should be able to change them with the "set" object.; #X text 332 405 updated for Pd version 0.39; #X text 47 136 The blue "selection" rectangle ought to notice when the object that got selected gets moved or resized \, but this isn't done yet (as of Pd version 0.39).; #X connect 0 0 16 0; #X connect 1 0 15 0; #X connect 2 0 14 0; #X connect 3 0 13 0; #X connect 9 0 17 0; #X connect 11 0 13 1; #X connect 11 0 14 1; #X connect 11 0 15 1; #X connect 11 0 16 1; #X connect 11 0 17 1; #X connect 11 0 18 0; #X connect 18 0 7 0; #X connect 18 1 6 0; #X connect 18 2 5 0; #X connect 18 3 4 0; #X connect 18 4 8 0; pd-0.46-7/doc/4.data.structures/03.setting.data.pd0000664000175000017500000001077412374245151017606 0ustar mspmsp#N struct template3 float x float y float w float h float q; #N canvas 387 65 585 485 12; #X floatatom 60 371 0 0 0 0 - - -; #X floatatom 60 323 0 0 0 0 - - -; #X floatatom 60 275 0 0 0 0 - - -; #X floatatom 60 227 0 0 0 0 - - -; #X floatatom 324 322 0 0 0 0 - - -; #X floatatom 283 322 0 0 0 0 - - -; #X floatatom 240 322 0 0 0 0 - - -; #X obj 197 274 pointer; #X msg 205 249 next; #X floatatom 197 322 0 0 0 0 - - -; #N canvas 2 70 381 425 data3 1; #X scalar template3 18 85 43 18 741 \;; #X scalar template3 111 169 75 25 72 \;; #X scalar template3 111 92 4 15 163 \;; #X scalar template3 59 61 13 34 563 \;; #X scalar template3 148 86 37 20 566 \;; #X scalar template3 173 281 76 48 763 \;; #X scalar template3 250 187 18 36 543 \;; #X scalar template3 124 270 78 21 107 \;; #X scalar template3 264 243 1 33 178 \;; #X scalar template3 26 88 56 60 132 \;; #X scalar template3 2 262 66 2 808 \;; #X scalar template3 270 106 74 51 23 \;; #X scalar template3 214 286 8 43 180 \;; #X scalar template3 57 205 51 58 939 \;; #X scalar template3 216 162 36 43 505 \;; #X scalar template3 166 146 68 9 614 \;; #X scalar template3 144 251 56 28 886 \;; #X scalar template3 228 62 62 1 786 \;; #X scalar template3 168 229 28 23 654 \;; #X scalar template3 223 308 73 50 727 \;; #X restore 269 425 pd data3; #N canvas 97 433 512 247 template3 0; #X obj 25 68 filledpolygon q 0 1 0 0 w 0 w h 0 h; #X text 22 39 five numeric ("float") fields; #X text 25 88 drawing a rectangle \, interior color q \, border black and one unit thick \, through the points (0 \, 0) \, (w \, 0) \, (w \, h) \, and (0 \, h). Note that the three points containing variables become hot spots for mouse dragging.; #X obj 24 19 struct template3 float x float y float w float h float q; #X text 26 184 Draw the value of q as an Arabic numeral \, at (0 \, 0) \, in black.; #X obj 26 163 drawnumber q 0 -15 0; #X restore 269 446 pd template3; #N canvas 395 94 628 377 stuff 0; #X obj 352 180 pointer; #X obj 352 204 t b b p; #X obj 222 333 append template3 x y w h q; #X obj 288 9 loadbang; #X obj 288 62 t b b b; #X msg 331 138 traverse pd-data3; #X msg 477 136 \; pd-data3 clear; #X msg 240 110 0; #X obj 187 136 f; #X obj 220 136 + 1; #X obj 189 112 until; #X obj 201 159 sel 20; #X obj 251 159 t b; #X msg 290 32 bang; #X obj 25 237 random 300; #X obj 100 237 random 300; #X obj 323 236 random 1000; #X obj 177 237 random 80; #X obj 252 237 random 80; #X obj 354 11 inlet; #X obj 101 263 + 30; #X connect 0 0 1 0; #X connect 1 0 14 0; #X connect 1 1 15 0; #X connect 1 1 16 0; #X connect 1 1 17 0; #X connect 1 1 18 0; #X connect 1 2 2 5; #X connect 3 0 13 0; #X connect 4 0 10 0; #X connect 4 1 5 0; #X connect 4 1 7 0; #X connect 4 2 6 0; #X connect 5 0 0 0; #X connect 7 0 8 1; #X connect 8 0 11 0; #X connect 8 0 9 0; #X connect 9 0 8 1; #X connect 10 0 8 0; #X connect 11 0 10 1; #X connect 11 1 12 0; #X connect 12 0 0 0; #X connect 13 0 4 0; #X connect 14 0 2 0; #X connect 15 0 20 0; #X connect 16 0 2 4; #X connect 17 0 2 2; #X connect 18 0 2 3; #X connect 19 0 13 0; #X connect 20 0 2 1; #X restore 269 404 pd stuff; #X msg 269 379 remake; #X obj 197 298 get template3 x y w h q; #X floatatom 356 322 0 0 0 0 - - -; #X obj 60 251 set template3 x; #X obj 60 299 set template3 y; #X obj 60 347 set template3 w; #X obj 60 394 set template3 h; #X floatatom 60 418 0 0 0 0 - - -; #X obj 60 441 set template3 q; #X msg 197 226 traverse pd-data3; #X text 46 5 The "set" object allows you to change numeric values. In this example \, the template specifies five fields describing the (x \, y) location \, width \, height \, and color. A new feature is that the color is also getting printed out under the rectangles. This is done using the "drawnumber" object in the template.; #X text 323 378 <- click to randomize; #X text 45 99 Getting parameter values is as in the previous patch \; however \, as you traverse the list with "next" messages the new pointers are also sent to the five "set" objects. These have as arguments the template name and the name of the field they will set. You can drag on the five number boxes (after selecting an object with "traverse" and "next" messages) to change its location \, shape \, and color. ; #X connect 0 0 19 0; #X connect 1 0 18 0; #X connect 2 0 17 0; #X connect 3 0 16 0; #X connect 7 0 14 0; #X connect 7 0 16 1; #X connect 7 0 17 1; #X connect 7 0 18 1; #X connect 7 0 19 1; #X connect 7 0 21 1; #X connect 8 0 7 0; #X connect 13 0 12 0; #X connect 14 0 9 0; #X connect 14 1 6 0; #X connect 14 2 5 0; #X connect 14 3 4 0; #X connect 14 4 15 0; #X connect 20 0 21 0; #X connect 22 0 7 0; pd-0.46-7/doc/4.data.structures/11.array.controls.pd0000664000175000017500000000364412160204055020165 0ustar mspmsp#N struct template11 float x float y array a template11a; #N struct template11a float x float amp float w1 float w2; #N canvas 14 266 568 347 12; #X text 300 287 updated for Pd version 0.39; #N canvas 587 7 540 455 template11 1; #X obj 41 303 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; #X obj 41 325 t b b; #X obj 222 384 pointer; #X msg 72 353 traverse pd-data11 \, bang; #X obj 43 409 append template11 x y; #X msg 41 385 50 50; #X obj 23 19 struct template11 float x float y array a template11a ; #X obj 31 254 filledpolygon 0 0 0 0 0 3 0 3 30 0 30 0 0; #X obj 31 134 plot -w w1 a 0 2 5 0; #X obj 33 190 plot -w w2 a 0 2 5 15; #X obj 40 83 plot -y amp(0:100)(0:100) a 500 2 5 30; #X text 41 61 Graph (x \, amp) pairs (using "amp" as the "y" field"): ; #X text 33 108 Graph "w1" as width ("y" is zero); #X text 30 168 also "w2" \, at (5 \, 15) to disambiguate the one at (5 \, 0); #X text 28 231 Mark the scalar itself; #X connect 0 0 1 0; #X connect 1 0 5 0; #X connect 1 1 3 0; #X connect 2 0 4 2; #X connect 3 0 2 0; #X connect 5 0 4 0; #X restore 40 233 pd template11; #N canvas 25 458 313 196 data11 1; #X scalar template11 41 87 \; 2 0 0 0 \; 18 51 7 0 \; 98 41 0 5 \; 109 0 0 0 \; \;; #X coords 0 196 1 195 0 0 0; #X restore 51 299 pd data11; #N canvas 336 497 561 109 template11a 0; #X obj 23 19 struct template11a float x float amp float w1 float w2 ; #X restore 47 271 pd template11a; #X text 25 13 You can control which variable is used as "x" \, "y" \, and "width" when plotting an array. In this example a single array "a" is plotted three times \, to show the values of the "amp" \, "w1" and "w2" fields. This is convenient when you want to have several variables in each point of the array and need several traces of the same array to visualize it all.; #X text 24 127 In this example the array points have no "y" field at all \, so if no variable is supplied to use instead of "y" \, the array is flat along its "x" axis.; pd-0.46-7/doc/4.data.structures/00.intro.txt0000664000175000017500000000713312160204055016547 0ustar mspmspPd release 0.23 and onward include objects for managing lists of data. The objects allow you to describe data structures and how they are viewed ("template objects") and to traverse lists ("traversal objects.") The rest of this file gives a highly condensed summary of what's there; the patches, starting with "1.scalars.pd", act as a tutorial. 1. TEMPLATE OBJECTS. templates describe data structures. You can add an item to a data structure using "field" or ask for a shape to be drawn using a "display command." 1.1. "template" -- data structure. usage, "template ..." where the fields are either "float ", "symbol ", "list " (don't try that yet); or "array . 1.2. DISPLAY COMMANDS. These are objects which ask Pd to draw a shape corresponding to some fields of the datum. 1.2.1. POLYGONS and CURVES. polygons: polygon ... filled polygons: fpolygon ... curves: curve ... filled curves: fcurve ... Each argument can either be a number or a symbol. If a symbol, it's the name of a field (which must be a "float) which specifies the vaiue. So for instance in the "1.scalar.pd" example, in the template "template1", the object "fpolygon 244 q 5 0 0 20 z 40 0" draws a filled polygon whose interior color is 244 (red 2, green 4, blue 4) but whose outline color depends on the value of the field "q". Its coordinates describe a triangle whose altitude is given by "z." 1.2.2 PLOT. The "plot" objects plots an array field as shown in 5_array.pd. 2. TRAVERSAL. In this release of Pd, you can only traverse lists all of whose elements belong to the same template; this restriction will be relaxed in a future release. You "traverse" a list either to build it, to get its elements, or to change their values. 2.1. POINTER. The "pointer" object can be used to refer to an element of a list. Its methods are: 2.1.1. traverse . Point to the "head" of a list. The symbol should match the name of a Pd window holding the list. The pointer is output, but you can't set or get the fields of the "head" pointer; you can only get the "next" element or "append" to the list. 2.1.2. next. Goes to the next element of the list. Either the pointer is output on the left side, or else a "bang" at right tells you that no more objects are forthcoming. 2.1.3. bang. outputs the current pointer. 2.2. APPEND. Adds an element of the specified template to the list. You specify what fields you want to supply and the last inlet takes a pointer to the element you want to "append" after. 2.3. GET. get