From 427f5b66ce0abe19daed9291b1693f6e8aae6552 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 9 Jun 2019 13:43:51 +0200 Subject: [PATCH] patch 8.1.1502: cannot play any sound Problem: Cannot play any sound. Solution: Use libcanberra if available. Add sound functions. --- .travis.yml | 1 + Filelist | 3 + runtime/doc/eval.txt | 50 ++++++++++ src/Makefile | 10 ++ src/auto/configure | 195 ++++++++++++++----------------------- src/config.h.in | 1 + src/configure.ac | 35 +++++-- src/evalfunc.c | 9 ++ src/feature.h | 7 ++ src/proto.h | 1 + src/proto/sound.pro | 7 ++ src/sound.c | 193 ++++++++++++++++++++++++++++++++++++ src/testdir/Make_all.mak | 2 + src/testdir/silent.wav | Bin 0 -> 65580 bytes src/testdir/test_sound.vim | 45 +++++++++ src/version.c | 12 +++ 16 files changed, 440 insertions(+), 131 deletions(-) create mode 100644 src/proto/sound.pro create mode 100644 src/sound.c create mode 100644 src/testdir/silent.wav create mode 100644 src/testdir/test_sound.vim diff --git a/.travis.yml b/.travis.yml index 51d357836..53331e6ec 100644 --- a/.travis.yml +++ b/.travis.yml @@ -77,6 +77,7 @@ addons: - clang - lcov - gettext + - libcanberra-dev - libperl-dev - python-dev - python3-dev diff --git a/Filelist b/Filelist index d6a90e2c9..7bf4fd675 100644 --- a/Filelist +++ b/Filelist @@ -88,6 +88,7 @@ SRC_ALL = \ src/search.c \ src/sha256.c \ src/sign.c \ + src/sound.c \ src/spell.c \ src/spell.h \ src/spellfile.c \ @@ -150,6 +151,7 @@ SRC_ALL = \ src/testdir/samples/test000 \ src/testdir/if_ver*.vim \ src/testdir/color_ramp.vim \ + src/testdir/silent.wav \ src/proto.h \ src/protodef.h \ src/proto/arabic.pro \ @@ -209,6 +211,7 @@ SRC_ALL = \ src/proto/search.pro \ src/proto/sha256.pro \ src/proto/sign.pro \ + src/proto/sound.pro \ src/proto/spell.pro \ src/proto/spellfile.pro \ src/proto/syntax.pro \ diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 85230a60a..d1f6824b6 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -2622,6 +2622,12 @@ sin({expr}) Float sine of {expr} sinh({expr}) Float hyperbolic sine of {expr} sort({list} [, {func} [, {dict}]]) List sort {list}, using {func} to compare +sound_playevent({name} [, {callback}]) + Number play an event sound +sound_playfile({name} [, {callback}]) + Number play a sound file +sound_stop({id}) none stop playing sound {id} +sound_stopall() none stop playing all sounds soundfold({word}) String sound-fold {word} spellbadword() String badly spelled word at cursor spellsuggest({word} [, {max} [, {capital}]]) @@ -8837,6 +8843,49 @@ sort({list} [, {func} [, {dict}]]) *sort()* *E702* return a:i1 - a:i2 endfunc < + *sound_playevent()* +sound_playevent({name} [, {callback}]) + Play a sound identified by {name}. Which event names are + supported depends on the system. Often the XDG sound names + are used. On Ubuntu they may be found in + /usr/share/sounds/freedesktop/stereo. Example: > + call sound_playevent('bell') + +< When {callback} is specified it is invoked when the sound is + finished. The first argument is the sound ID, the second + argument is the status: + 0 sound was played to the end + 1 sound was interruped + 2 error occured after sound started + Example: > + func Callback(id, status) + echomsg "sound " .. a:id .. " finished with " .. a:status + endfunc + call sound_playevent('bell', 'Callback') + +< Returns the sound ID, which can be passed to `sound_stop()`. + Returns zero if the sound could not be played. + {only available when compiled with the +sound feature} + + *sound_playfile()* +sound_playfile({name} [, {callback}]) + Like `sound_playevent()` but play sound file {name}. {name} + must be a full path. On Ubuntu you may find files to play + with this command: > + :!find /usr/share/sounds -type f | grep -v index.theme + +< {only available when compiled with the +sound feature} + + +sound_stop({id}) *sound_stop()* + Stop playing sound {id}. {id} must be previously returned by + `sound_playevent()` or `sound_playfile()`. + {only available when compiled with the +sound feature} + +sound_stopall() *sound_stopall()* + Stop playing all sounds. + {only available when compiled with the +sound feature} + *soundfold()* soundfold({word}) Return the sound-folded equivalent of {word}. Uses the first @@ -10756,6 +10805,7 @@ scrollbind Compiled with 'scrollbind' support. (always true) showcmd Compiled with 'showcmd' support. signs Compiled with |:sign| support. smartindent Compiled with 'smartindent' support. +sound Compiled with sound support, e.g. `sound_playevent()` spell Compiled with spell checking support |spell|. startuptime Compiled with |--startuptime| support. statusline Compiled with support for 'statusline', 'rulerformat' diff --git a/src/Makefile b/src/Makefile index 65398d018..eef91ece2 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1628,6 +1628,7 @@ BASIC_SRC = \ search.c \ sha256.c \ sign.c \ + sound.c \ spell.c \ spellfile.c \ syntax.c \ @@ -1743,6 +1744,7 @@ OBJ_COMMON = \ objects/search.o \ objects/sha256.o \ objects/sign.o \ + objects/sound.o \ objects/spell.o \ objects/spellfile.o \ objects/syntax.o \ @@ -1883,6 +1885,7 @@ PRO_AUTO = \ search.pro \ sha256.pro \ sign.pro \ + sound.pro \ spell.pro \ spellfile.pro \ syntax.pro \ @@ -3235,6 +3238,9 @@ objects/sha256.o: sha256.c objects/sign.o: sign.c $(CCC) -o $@ sign.c +objects/sound.o: sound.c + $(CCC) -o $@ sound.c + objects/spell.o: spell.c $(CCC) -o $@ spell.c @@ -3650,6 +3656,10 @@ objects/sign.o: sign.c vim.h protodef.h auto/config.h feature.h os_unix.h \ auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ proto.h globals.h +objects/sound.o: spell.c vim.h protodef.h auto/config.h feature.h os_unix.h \ + auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ + proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ + proto.h globals.h objects/spell.o: spell.c vim.h protodef.h auto/config.h feature.h os_unix.h \ auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ diff --git a/src/auto/configure b/src/auto/configure index 1f5ee2add..d5b4f6053 100755 --- a/src/auto/configure +++ b/src/auto/configure @@ -9303,28 +9303,8 @@ fi - -if test -z "$SKIP_GTK2"; then - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking --disable-gtktest argument" >&5 -$as_echo_n "checking --disable-gtktest argument... " >&6; } - # Check whether --enable-gtktest was given. -if test "${enable_gtktest+set}" = set; then : - enableval=$enable_gtktest; -else - enable_gtktest=yes -fi - - if test "x$enable_gtktest" = "xyes" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: gtk test enabled" >&5 -$as_echo "gtk test enabled" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: gtk test disabled" >&5 -$as_echo "gtk test disabled" >&6; } - fi - - if test "X$PKG_CONFIG" = "X"; then - if test -n "$ac_tool_prefix"; then +if test "X$PKG_CONFIG" = "X"; then + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -9422,6 +9402,26 @@ else PKG_CONFIG="$ac_cv_path_PKG_CONFIG" fi +fi + + +if test -z "$SKIP_GTK2"; then + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking --disable-gtktest argument" >&5 +$as_echo_n "checking --disable-gtktest argument... " >&6; } + # Check whether --enable-gtktest was given. +if test "${enable_gtktest+set}" = set; then : + enableval=$enable_gtktest; +else + enable_gtktest=yes +fi + + if test "x$enable_gtktest" = "xyes" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: gtk test enabled" >&5 +$as_echo "gtk test enabled" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: gtk test disabled" >&5 +$as_echo "gtk test disabled" >&6; } fi if test "x$PKG_CONFIG" != "xno"; then @@ -9677,107 +9677,6 @@ $as_echo "gtk test enabled" >&6; } $as_echo "gtk test disabled" >&6; } fi - if test "X$PKG_CONFIG" = "X"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. -set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_PKG_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $PKG_CONFIG in - [\\/]* | ?:[\\/]*) - ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -PKG_CONFIG=$ac_cv_path_PKG_CONFIG -if test -n "$PKG_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 -$as_echo "$PKG_CONFIG" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_path_PKG_CONFIG"; then - ac_pt_PKG_CONFIG=$PKG_CONFIG - # Extract the first word of "pkg-config", so it can be a program name with args. -set dummy pkg-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $ac_pt_PKG_CONFIG in - [\\/]* | ?:[\\/]*) - ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG -if test -n "$ac_pt_PKG_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 -$as_echo "$ac_pt_PKG_CONFIG" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_pt_PKG_CONFIG" = x; then - PKG_CONFIG="no" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - PKG_CONFIG=$ac_pt_PKG_CONFIG - fi -else - PKG_CONFIG="$ac_cv_path_PKG_CONFIG" -fi - - fi - if test "x$PKG_CONFIG" != "xno"; then if test "X$GTK_CONFIG" != "Xno" -o "X$PKG_CONFIG" != "Xno"; then @@ -13026,6 +12925,56 @@ rm -rf conftest* fi + +if test "x$PKG_CONFIG" != "xno"; then + canberra_lib=`$PKG_CONFIG --libs libcanberrax 2>/dev/null` + canberra_cflags=`$PKG_CONFIG --cflags libcanberrax 2>/dev/null` + { $as_echo "$as_me:${as_lineno-$LINENO}: result: canberra_lib: $canberra_lib" >&5 +$as_echo "canberra_lib: $canberra_lib" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: canberra_cflags: $canberra_cflags" >&5 +$as_echo "canberra_cflags: $canberra_cflags" >&6; } +fi +if test "x$canberra_lib" = "x"; then + canberra_lib=-lcanberra + canberra_cflags=-D_REENTRANT +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: canberra_lib: $canberra_lib" >&5 +$as_echo "canberra_lib: $canberra_lib" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: canberra_cflags: $canberra_cflags" >&5 +$as_echo "canberra_cflags: $canberra_cflags" >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libcanberra" >&5 +$as_echo_n "checking for libcanberra... " >&6; } +ac_save_CFLAGS="$CFLAGS" +ac_save_LIBS="$LIBS" +CFLAGS="$CFLAGS $canberra_cflags" +LIBS="$LIBS $canberra_lib" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +# include + +int +main () +{ + + ca_context *hello; + ca_context_create(&hello); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; }; $as_echo "#define HAVE_CANBERRA 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; }; CFLAGS="$ac_save_CFLAGS"; LIBS="$ac_save_LIBS" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for st_blksize" >&5 $as_echo_n "checking for st_blksize... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext diff --git a/src/config.h.in b/src/config.h.in index 23e301c90..c1ced6fe9 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -207,6 +207,7 @@ #undef HAVE_STRNICMP #undef HAVE_STRPBRK #undef HAVE_STRTOL +#undef HAVE_CANBERRA #undef HAVE_ST_BLKSIZE #undef HAVE_SYSCONF #undef HAVE_SYSCTL diff --git a/src/configure.ac b/src/configure.ac index 773844a0d..7e821e63b 100644 --- a/src/configure.ac +++ b/src/configure.ac @@ -2702,6 +2702,10 @@ AC_DEFUN([GNOME_INIT],[ GNOME_INIT_HOOK([],fail) ]) +if test "X$PKG_CONFIG" = "X"; then + AC_PATH_TOOL(PKG_CONFIG, pkg-config, no) +fi + dnl --------------------------------------------------------------------------- dnl Check for GTK2. If it fails, then continue on for Motif as before... @@ -2717,10 +2721,6 @@ if test -z "$SKIP_GTK2"; then AC_MSG_RESULT(gtk test disabled) fi - if test "X$PKG_CONFIG" = "X"; then - AC_PATH_TOOL(PKG_CONFIG, pkg-config, no) - fi - if test "x$PKG_CONFIG" != "xno"; then dnl First try finding version 2.2.0 or later. The 2.0.x series has dnl problems (bold fonts, --remote doesn't work). @@ -2769,10 +2769,6 @@ if test -z "$SKIP_GTK3"; then AC_MSG_RESULT(gtk test disabled) fi - if test "X$PKG_CONFIG" = "X"; then - AC_PATH_TOOL(PKG_CONFIG, pkg-config, no) - fi - if test "x$PKG_CONFIG" != "xno"; then AM_PATH_GTK(3.0.0, [GUI_LIB_LOC="$GTK_LIBDIR" @@ -3755,6 +3751,29 @@ dnl define _LARGE_FILES, _FILE_OFFSET_BITS and _LARGEFILE_SOURCE when dnl appropriate, so that off_t is 64 bits when needed. AC_SYS_LARGEFILE + +if test "x$PKG_CONFIG" != "xno"; then + canberra_lib=`$PKG_CONFIG --libs libcanberra 2>/dev/null` + canberra_cflags=`$PKG_CONFIG --cflags libcanberra 2>/dev/null` +fi +if test "x$canberra_lib" = "x"; then + canberra_lib=-lcanberra + canberra_cflags=-D_REENTRANT +fi +AC_MSG_CHECKING(for libcanberra) +ac_save_CFLAGS="$CFLAGS" +ac_save_LIBS="$LIBS" +CFLAGS="$CFLAGS $canberra_cflags" +LIBS="$LIBS $canberra_lib" +AC_TRY_LINK([ +# include + ], [ + ca_context *hello; + ca_context_create(&hello);], + AC_MSG_RESULT(yes); AC_DEFINE(HAVE_CANBERRA), + AC_MSG_RESULT(no); CFLAGS="$ac_save_CFLAGS"; LIBS="$ac_save_LIBS") + + dnl fstatfs() can take 2 to 4 arguments, try to use st_blksize if possible AC_MSG_CHECKING(for st_blksize) AC_TRY_COMPILE( diff --git a/src/evalfunc.c b/src/evalfunc.c index bc6056785..42973797d 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -925,6 +925,12 @@ static struct fst {"sinh", 1, 1, f_sinh}, #endif {"sort", 1, 3, f_sort}, +#ifdef FEAT_SOUND + {"sound_playevent", 1, 2, f_sound_playevent}, + {"sound_playfile", 1, 2, f_sound_playfile}, + {"sound_stop", 1, 1, f_sound_stop}, + {"sound_stopall", 0, 0, f_sound_stopall}, +#endif {"soundfold", 1, 1, f_soundfold}, {"spellbadword", 0, 1, f_spellbadword}, {"spellsuggest", 1, 3, f_spellsuggest}, @@ -6782,6 +6788,9 @@ f_has(typval_T *argvars, typval_T *rettv) #ifdef FEAT_NETBEANS_INTG "netbeans_intg", #endif +#ifdef FEAT_SOUND + "sound", +#endif #ifdef FEAT_SPELL "spell", #endif diff --git a/src/feature.h b/src/feature.h index c613c4bc9..c5d7d777e 100644 --- a/src/feature.h +++ b/src/feature.h @@ -660,6 +660,13 @@ # define FEAT_TERM_POPUP_MENU #endif +/* + * sound - currently only with libcanberra + */ +#if !defined(FEAT_SOUND) && defined(FEAT_BIG) && defined(HAVE_CANBERRA) +# define FEAT_SOUND +#endif + /* There are two ways to use XPM. */ #if (defined(HAVE_XM_XPMP_H) && defined(FEAT_GUI_MOTIF)) \ || defined(HAVE_X11_XPM_H) diff --git a/src/proto.h b/src/proto.h index e606f08f5..264cbb9e4 100644 --- a/src/proto.h +++ b/src/proto.h @@ -183,6 +183,7 @@ void qsort(void *base, size_t elm_count, size_t elm_size, int (*cmp)(const void # ifdef FEAT_SIGNS # include "sign.pro" # endif +# include "sound.pro" # include "spell.pro" # include "spellfile.pro" # include "syntax.pro" diff --git a/src/proto/sound.pro b/src/proto/sound.pro new file mode 100644 index 000000000..43e472775 --- /dev/null +++ b/src/proto/sound.pro @@ -0,0 +1,7 @@ +/* sound.c */ +void f_sound_playevent(typval_T *argvars, typval_T *rettv); +void f_sound_playfile(typval_T *argvars, typval_T *rettv); +void f_sound_stop(typval_T *argvars, typval_T *rettv); +void f_sound_stopall(typval_T *argvars, typval_T *rettv); +void sound_free(void); +/* vim: set ft=c : */ diff --git a/src/sound.c b/src/sound.c new file mode 100644 index 000000000..ac6c377be --- /dev/null +++ b/src/sound.c @@ -0,0 +1,193 @@ +/* vi:set ts=8 sts=4 sw=4 noet: + * + * VIM - Vi IMproved by Bram Moolenaar + * + * Do ":help uganda" in Vim to read copying and usage conditions. + * Do ":help credits" in Vim to see a list of people who contributed. + * See README.txt for an overview of the Vim source code. + */ + +/* + * sound.c: functions related making noise + */ + +#include "vim.h" + +#if (defined(FEAT_SOUND) && defined(HAVE_CANBERRA)) || defined(PROTO) + +#include + +static long sound_id = 0; +static ca_context *context = NULL; + +typedef struct soundcb_S soundcb_T; + +struct soundcb_S { + callback_T snd_callback; + soundcb_T *snd_next; +}; + +static soundcb_T *first_callback = NULL; + + static soundcb_T * +get_sound_callback(typval_T *arg) +{ + callback_T callback; + soundcb_T *soundcb; + + if (arg->v_type == VAR_UNKNOWN) + return NULL; + callback = get_callback(arg); + if (callback.cb_name == NULL) + return NULL; + + soundcb = ALLOC_ONE(soundcb_T); + if (soundcb == NULL) + free_callback(&callback); + else + { + soundcb->snd_next = first_callback; + first_callback = soundcb; + set_callback(&soundcb->snd_callback, &callback); + } + return soundcb; +} + +/* + * Delete "soundcb" from the list of pending callbacks. + */ + static void +delete_sound_callback(soundcb_T *soundcb) +{ + soundcb_T *p; + soundcb_T *prev = NULL; + + for (p = first_callback; p != NULL; prev = p, p = p->snd_next) + if (p == soundcb) + { + if (prev == NULL) + first_callback = p->snd_next; + else + prev->snd_next = p->snd_next; + free_callback(&p->snd_callback); + vim_free(p); + break; + } +} + + static void +sound_callback( + ca_context *c UNUSED, + uint32_t id, + int error_code, + void *userdata) +{ + soundcb_T *soundcb = (soundcb_T *)userdata; + typval_T argv[3]; + typval_T rettv; + int dummy; + + argv[0].v_type = VAR_NUMBER; + argv[0].vval.v_number = id; + argv[1].v_type = VAR_NUMBER; + argv[1].vval.v_number = error_code == CA_SUCCESS ? 0 + : error_code == CA_ERROR_CANCELED + || error_code == CA_ERROR_DESTROYED + ? 1 : 2; + argv[2].v_type = VAR_UNKNOWN; + + call_callback(&soundcb->snd_callback, -1, + &rettv, 2, argv, NULL, 0L, 0L, &dummy, TRUE, NULL); + clear_tv(&rettv); + + delete_sound_callback(soundcb); + redraw_after_callback(TRUE); +} + + static void +sound_play_common(typval_T *argvars, typval_T *rettv, int playfile) +{ + if (context == NULL) + ca_context_create(&context); + if (context != NULL) + { + soundcb_T *soundcb = get_sound_callback(&argvars[1]); + int res = CA_ERROR_INVALID; + + ++sound_id; + if (soundcb == NULL) + { + res = ca_context_play(context, sound_id, + playfile ? CA_PROP_MEDIA_FILENAME : CA_PROP_EVENT_ID, + tv_get_string(&argvars[0]), + CA_PROP_CANBERRA_CACHE_CONTROL, "volatile", + NULL); + } + else + { + static ca_proplist *proplist = NULL; + + ca_proplist_create(&proplist); + if (proplist != NULL) + { + if (playfile) + ca_proplist_sets(proplist, CA_PROP_MEDIA_FILENAME, + (char *)tv_get_string(&argvars[0])); + else + ca_proplist_sets(proplist, CA_PROP_EVENT_ID, + (char *)tv_get_string(&argvars[0])); + ca_proplist_sets(proplist, CA_PROP_CANBERRA_CACHE_CONTROL, + "volatile"); + res = ca_context_play_full(context, sound_id, proplist, + sound_callback, soundcb); + if (res != CA_SUCCESS) + delete_sound_callback(soundcb); + + ca_proplist_destroy(proplist); + } + } + rettv->vval.v_number = res == CA_SUCCESS ? sound_id : 0; + } +} + + void +f_sound_playevent(typval_T *argvars, typval_T *rettv) +{ + sound_play_common(argvars, rettv, FALSE); +} + + void +f_sound_playfile(typval_T *argvars, typval_T *rettv) +{ + sound_play_common(argvars, rettv, TRUE); +} + + void +f_sound_stop(typval_T *argvars, typval_T *rettv UNUSED) +{ + if (context != NULL) + ca_context_cancel(context, tv_get_number(&argvars[0])); +} + + void +f_sound_stopall(typval_T *argvars UNUSED, typval_T *rettv UNUSED) +{ + if (context != NULL) + { + ca_context_destroy(context); + context = NULL; + } +} + +#if defined(EXITFREE) || defined(PROTO) + void +sound_free(void) +{ + if (context != NULL) + ca_context_destroy(context); + while (first_callback != NULL) + delete_sound_callback(first_callback); +} +#endif + +#endif // FEAT_SOUND && HAVE_CANBERRA diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak index 34644d6b9..08f6c5bca 100644 --- a/src/testdir/Make_all.mak +++ b/src/testdir/Make_all.mak @@ -228,6 +228,7 @@ NEW_TESTS = \ test_signs \ test_smartindent \ test_sort \ + test_sound \ test_source \ test_source_utf8 \ test_spell \ @@ -399,6 +400,7 @@ NEW_TESTS_RES = \ test_signals.res \ test_signs.res \ test_smartindent.res \ + test_sound.res \ test_source.res \ test_spell.res \ test_startup.res \ diff --git a/src/testdir/silent.wav b/src/testdir/silent.wav new file mode 100644 index 0000000000000000000000000000000000000000..4631a7e8ed007b62af0a63111b9e4adc60a9eebe GIT binary patch literal 65580 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 0) + + " play until the end + let id2 = sound_playfile(fname, 'PlayCallback') + call assert_true(id2 > 0) + sleep 500m + call assert_equal(id2, g:id) + call assert_equal(0, g:result) + + let id2 = sound_playfile(fname, 'PlayCallback') + call assert_true(id2 > 0) + sleep 20m + call sound_stopall() + call assert_equal(id2, g:id) + call assert_equal(1, g:result) +endfunc diff --git a/src/version.c b/src/version.c index 3dcf0c631..5a69befa7 100644 --- a/src/version.c +++ b/src/version.c @@ -580,6 +580,16 @@ static char *(features[]) = #else "-smartindent", #endif +#ifdef FEAT_SOUND + "+sound", +#else + "-sound", +#endif +#ifdef FEAT_SPELL + "+spell", +#else + "-spell", +#endif #ifdef STARTUPTIME "+startuptime", #else @@ -767,6 +777,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1502, /**/ 1501, /**/ -- 2.50.1