mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	try to use file sample type for cache entries and play-file playback
allow paplay to use STDIN add new module: module-match git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@244 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
		
							parent
							
								
									f014d466cd
								
							
						
					
					
						commit
						450ad85b35
					
				
					 9 changed files with 292 additions and 22 deletions
				
			
		
							
								
								
									
										2
									
								
								doc/todo
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								doc/todo
									
										
									
									
									
								
							| 
						 | 
					@ -11,10 +11,8 @@
 | 
				
			||||||
- pacat sample type args
 | 
					- pacat sample type args
 | 
				
			||||||
- filter capture data in client through alignment
 | 
					- filter capture data in client through alignment
 | 
				
			||||||
- add redirection module
 | 
					- add redirection module
 | 
				
			||||||
- add matching module
 | 
					 | 
				
			||||||
- add radio module
 | 
					- add radio module
 | 
				
			||||||
- make autoload list use idxset
 | 
					- make autoload list use idxset
 | 
				
			||||||
- improve file load to note force sample typ to PA_SAMPLE_FLOAT32
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
** later ***
 | 
					** later ***
 | 
				
			||||||
- xmlrpc/http
 | 
					- xmlrpc/http
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -105,7 +105,8 @@ modlib_LTLIBRARIES= \
 | 
				
			||||||
		module-sine.la \
 | 
							module-sine.la \
 | 
				
			||||||
		module-combine.la \
 | 
							module-combine.la \
 | 
				
			||||||
		module-esound-compat-spawnfd.la \
 | 
							module-esound-compat-spawnfd.la \
 | 
				
			||||||
		module-esound-compat-spawnpid.la
 | 
							module-esound-compat-spawnpid.la \
 | 
				
			||||||
 | 
							module-match.la
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lib_LTLIBRARIES= \
 | 
					lib_LTLIBRARIES= \
 | 
				
			||||||
		libpolyp-@PA_MAJORMINOR@.la \
 | 
							libpolyp-@PA_MAJORMINOR@.la \
 | 
				
			||||||
| 
						 | 
					@ -305,6 +306,10 @@ module_combine_la_SOURCES = module-combine.c
 | 
				
			||||||
module_combine_la_LDFLAGS = -module -avoid-version
 | 
					module_combine_la_LDFLAGS = -module -avoid-version
 | 
				
			||||||
module_combine_la_LIBADD = $(AM_LIBADD)
 | 
					module_combine_la_LIBADD = $(AM_LIBADD)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module_match_la_SOURCES = module-match.c
 | 
				
			||||||
 | 
					module_match_la_LDFLAGS = -module -avoid-version
 | 
				
			||||||
 | 
					module_match_la_LIBADD = $(AM_LIBADD)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module_esound_compat_spawnfd_la_SOURCES = module-esound-compat-spawnfd.c
 | 
					module_esound_compat_spawnfd_la_SOURCES = module-esound-compat-spawnfd.c
 | 
				
			||||||
module_esound_compat_spawnfd_la_LDFLAGS = -module -avoid-version
 | 
					module_esound_compat_spawnfd_la_LDFLAGS = -module -avoid-version
 | 
				
			||||||
module_esound_compat_spawnfd_la_LIBADD = $(AM_LIBADD)
 | 
					module_esound_compat_spawnfd_la_LIBADD = $(AM_LIBADD)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										217
									
								
								polyp/module-match.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										217
									
								
								polyp/module-match.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,217 @@
 | 
				
			||||||
 | 
					/* $Id$ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***
 | 
				
			||||||
 | 
					  This file is part of polypaudio.
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					  polypaudio 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.
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					  polypaudio 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 polypaudio; if not, write to the Free Software
 | 
				
			||||||
 | 
					  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 | 
				
			||||||
 | 
					  USA.
 | 
				
			||||||
 | 
					***/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef HAVE_CONFIG_H
 | 
				
			||||||
 | 
					#include <config.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					#include <assert.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					#include <regex.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "module.h"
 | 
				
			||||||
 | 
					#include "util.h"
 | 
				
			||||||
 | 
					#include "modargs.h"
 | 
				
			||||||
 | 
					#include "log.h"
 | 
				
			||||||
 | 
					#include "subscribe.h"
 | 
				
			||||||
 | 
					#include "xmalloc.h"
 | 
				
			||||||
 | 
					#include "sink-input.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PA_MODULE_AUTHOR("Lennart Poettering")
 | 
				
			||||||
 | 
					PA_MODULE_DESCRIPTION("Sink input matching module")
 | 
				
			||||||
 | 
					PA_MODULE_USAGE("table=<filename>")
 | 
				
			||||||
 | 
					PA_MODULE_VERSION(PACKAGE_VERSION)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define WHITESPACE "\n\r \t"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char* const valid_modargs[] = {
 | 
				
			||||||
 | 
					    "table",
 | 
				
			||||||
 | 
					    NULL,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct rule {
 | 
				
			||||||
 | 
					    regex_t regex;
 | 
				
			||||||
 | 
					    pa_volume_t volume;
 | 
				
			||||||
 | 
					    struct rule *next;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct userdata {
 | 
				
			||||||
 | 
					    struct rule *rules;
 | 
				
			||||||
 | 
					    struct pa_subscription *subscription;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int load_rules(struct userdata *u, const char *filename) {
 | 
				
			||||||
 | 
					    FILE *f;
 | 
				
			||||||
 | 
					    int n = 0;
 | 
				
			||||||
 | 
					    int ret = -1;
 | 
				
			||||||
 | 
					    struct rule *end = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!(f = fopen(filename, "r"))) {
 | 
				
			||||||
 | 
					        pa_log(__FILE__": failed to open file '%s': %s\n", filename, strerror(errno));
 | 
				
			||||||
 | 
					        goto finish;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while (!feof(f)) {
 | 
				
			||||||
 | 
					        char *d, *v, *e = NULL;
 | 
				
			||||||
 | 
					        pa_volume_t volume;
 | 
				
			||||||
 | 
					        regex_t regex;
 | 
				
			||||||
 | 
					        char ln[256];
 | 
				
			||||||
 | 
					        struct rule *rule;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if (!fgets(ln, sizeof(ln), f))
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        n++;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        pa_strip_nl(ln);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (ln[0] == '#' || !*ln )
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        d = ln+strcspn(ln, WHITESPACE);
 | 
				
			||||||
 | 
					        v = d+strspn(d, WHITESPACE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if (!*v) {
 | 
				
			||||||
 | 
					            pa_log(__FILE__ ": [%s:%u] failed to parse line - too few words\n", filename, n);
 | 
				
			||||||
 | 
					            goto finish;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        *d = 0;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        volume = (pa_volume_t) strtol(v, &e, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!e || *e) {
 | 
				
			||||||
 | 
					            pa_log(__FILE__": [%s:%u] failed to parse volume\n", filename, n);
 | 
				
			||||||
 | 
					            goto finish;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (regcomp(®ex, ln, REG_EXTENDED|REG_NOSUB) != 0) {
 | 
				
			||||||
 | 
					            pa_log(__FILE__": [%s:%u] invalid regular expression\n", filename, n);
 | 
				
			||||||
 | 
					            goto finish;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        rule = pa_xmalloc(sizeof(struct rule));
 | 
				
			||||||
 | 
					        rule->regex = regex;
 | 
				
			||||||
 | 
					        rule->volume = volume;
 | 
				
			||||||
 | 
					        rule->next = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (end)
 | 
				
			||||||
 | 
					            end->next = rule;
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            u->rules = rule;
 | 
				
			||||||
 | 
					        end = rule;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        *d = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ret = 0;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					finish:
 | 
				
			||||||
 | 
					    if (f)
 | 
				
			||||||
 | 
					        fclose(f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void callback(struct pa_core *c, enum pa_subscription_event_type t, uint32_t index, void *userdata) {
 | 
				
			||||||
 | 
					    struct userdata *u =  userdata;
 | 
				
			||||||
 | 
					    struct pa_sink_input *si;
 | 
				
			||||||
 | 
					    struct rule *r;
 | 
				
			||||||
 | 
					    assert(c && u);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (t != (PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW))
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!(si = pa_idxset_get_by_index(c->sink_inputs, index))) {
 | 
				
			||||||
 | 
					        pa_log(__FILE__": WARNING: failed to get sink input\n");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!si->name)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    for (r = u->rules; r; r = r->next) {
 | 
				
			||||||
 | 
					        if (!regexec(&r->regex, si->name, 0, NULL, 0)) {
 | 
				
			||||||
 | 
					            pa_log(__FILE__": changing volume of sink input '%s' to 0x%03x\n", si->name, r->volume);
 | 
				
			||||||
 | 
					            pa_sink_input_set_volume(si, r->volume);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int pa__init(struct pa_core *c, struct pa_module*m) {
 | 
				
			||||||
 | 
					    struct pa_modargs *ma = NULL;
 | 
				
			||||||
 | 
					    int ret = -1;
 | 
				
			||||||
 | 
					    const char *table_file;
 | 
				
			||||||
 | 
					    struct userdata *u;
 | 
				
			||||||
 | 
					    assert(c && m);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!(ma = pa_modargs_new(m->argument, valid_modargs)) ||
 | 
				
			||||||
 | 
					        !(table_file = pa_modargs_get_value(ma, "table", NULL))) {
 | 
				
			||||||
 | 
					        pa_log(__FILE__": Failed to parse module arguments\n");
 | 
				
			||||||
 | 
					        goto finish;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    u = pa_xmalloc(sizeof(struct userdata));
 | 
				
			||||||
 | 
					    u->rules = NULL;
 | 
				
			||||||
 | 
					    u->subscription = NULL;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (load_rules(u, table_file) < 0)
 | 
				
			||||||
 | 
					        goto finish;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    u->subscription = pa_subscription_new(c, PA_SUBSCRIPTION_MASK_SINK_INPUT, callback, u);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					finish:
 | 
				
			||||||
 | 
					    if (ma)
 | 
				
			||||||
 | 
					        pa_modargs_free(ma);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void pa__done(struct pa_core *c, struct pa_module*m) {
 | 
				
			||||||
 | 
					    struct userdata* u;
 | 
				
			||||||
 | 
					    struct rule *r, *n;
 | 
				
			||||||
 | 
					    assert(c && m);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!(u = m->userdata))
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (u->subscription)
 | 
				
			||||||
 | 
					        pa_subscription_free(u->subscription);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    for (r = u->rules; r; r = n) {
 | 
				
			||||||
 | 
					        n = r->next;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        regfree(&r->regex);
 | 
				
			||||||
 | 
					        pa_xfree(r);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pa_xfree(u);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -192,7 +192,7 @@ static void exit_signal_callback(struct pa_mainloop_api*m, struct pa_signal_even
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void help(const char *argv0) {
 | 
					static void help(const char *argv0) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    printf("%s [options] FILE\n\n"
 | 
					    printf("%s [options] [FILE]\n\n"
 | 
				
			||||||
           "  -h, --help                            Show this help\n"
 | 
					           "  -h, --help                            Show this help\n"
 | 
				
			||||||
           "      --version                         Show version\n\n"
 | 
					           "      --version                         Show version\n\n"
 | 
				
			||||||
           "  -v, --verbose                         Enable verbose operations\n\n"
 | 
					           "  -v, --verbose                         Enable verbose operations\n\n"
 | 
				
			||||||
| 
						 | 
					@ -213,7 +213,7 @@ enum {
 | 
				
			||||||
int main(int argc, char *argv[]) {
 | 
					int main(int argc, char *argv[]) {
 | 
				
			||||||
    struct pa_mainloop* m = NULL;
 | 
					    struct pa_mainloop* m = NULL;
 | 
				
			||||||
    int ret = 1, r, c;
 | 
					    int ret = 1, r, c;
 | 
				
			||||||
    char *bn, *server = NULL;
 | 
					    char *bn, *server = NULL, *filename;
 | 
				
			||||||
    SF_INFO sfinfo;
 | 
					    SF_INFO sfinfo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static const struct option long_options[] = {
 | 
					    static const struct option long_options[] = {
 | 
				
			||||||
| 
						 | 
					@ -281,21 +281,25 @@ int main(int argc, char *argv[]) {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (optind >= argc) {
 | 
					
 | 
				
			||||||
        fprintf(stderr, "Missing file name.\n");
 | 
					    filename = optind < argc ? argv[optind] : "STDIN";
 | 
				
			||||||
        goto quit;
 | 
					    
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if (!client_name)
 | 
					    if (!client_name)
 | 
				
			||||||
        client_name = strdup(bn);
 | 
					        client_name = strdup(bn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!stream_name)
 | 
					    if (!stream_name)
 | 
				
			||||||
        stream_name = strdup(argv[optind]);
 | 
					        stream_name = strdup(filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    memset(&sfinfo, 0, sizeof(sfinfo));
 | 
					    memset(&sfinfo, 0, sizeof(sfinfo));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!(sndfile = sf_open(argv[optind], SFM_READ, &sfinfo))) {
 | 
					    if (optind < argc)
 | 
				
			||||||
        fprintf(stderr, "Faile to open file '%s'\n", argv[optind]);
 | 
					        sndfile = sf_open(filename, SFM_READ, &sfinfo);
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        sndfile = sf_open_fd(STDIN_FILENO, SFM_READ, &sfinfo, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!sndfile) {
 | 
				
			||||||
 | 
					        fprintf(stderr, "Failed to open file '%s'\n", filename);
 | 
				
			||||||
        goto quit;
 | 
					        goto quit;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
              
 | 
					              
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,6 +37,7 @@
 | 
				
			||||||
#include "subscribe.h"
 | 
					#include "subscribe.h"
 | 
				
			||||||
#include "namereg.h"
 | 
					#include "namereg.h"
 | 
				
			||||||
#include "sound-file.h"
 | 
					#include "sound-file.h"
 | 
				
			||||||
 | 
					#include "util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define UNLOAD_POLL_TIME 2
 | 
					#define UNLOAD_POLL_TIME 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -199,6 +200,7 @@ void pa_scache_free(struct pa_core *c) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int pa_scache_play_item(struct pa_core *c, const char *name, struct pa_sink *sink, uint32_t volume) {
 | 
					int pa_scache_play_item(struct pa_core *c, const char *name, struct pa_sink *sink, uint32_t volume) {
 | 
				
			||||||
    struct pa_scache_entry *e;
 | 
					    struct pa_scache_entry *e;
 | 
				
			||||||
 | 
					    char *t;
 | 
				
			||||||
    assert(c && name && sink);
 | 
					    assert(c && name && sink);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!(e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE, 1)))
 | 
					    if (!(e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE, 1)))
 | 
				
			||||||
| 
						 | 
					@ -214,8 +216,13 @@ int pa_scache_play_item(struct pa_core *c, const char *name, struct pa_sink *sin
 | 
				
			||||||
    if (!e->memchunk.memblock)
 | 
					    if (!e->memchunk.memblock)
 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (pa_play_memchunk(sink, name, &e->sample_spec, &e->memchunk, pa_volume_multiply(volume, e->volume)) < 0)
 | 
					    t = pa_sprintf_malloc("sample:%s", name);
 | 
				
			||||||
 | 
					    if (pa_play_memchunk(sink, t, &e->sample_spec, &e->memchunk, pa_volume_multiply(volume, e->volume)) < 0) {
 | 
				
			||||||
 | 
					        free(t);
 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    free(t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (e->lazy)
 | 
					    if (e->lazy)
 | 
				
			||||||
        time(&e->last_used_time);
 | 
					        time(&e->last_used_time);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -41,6 +41,7 @@ struct userdata {
 | 
				
			||||||
    SNDFILE *sndfile;
 | 
					    SNDFILE *sndfile;
 | 
				
			||||||
    struct pa_sink_input *sink_input;
 | 
					    struct pa_sink_input *sink_input;
 | 
				
			||||||
    struct pa_memchunk memchunk;
 | 
					    struct pa_memchunk memchunk;
 | 
				
			||||||
 | 
					    sf_count_t (*readf_function)(SNDFILE *sndfile, void *ptr, sf_count_t frames);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void free_userdata(struct userdata *u) {
 | 
					static void free_userdata(struct userdata *u) {
 | 
				
			||||||
| 
						 | 
					@ -78,7 +79,7 @@ static int sink_input_peek(struct pa_sink_input *i, struct pa_memchunk *chunk) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        u->memchunk.memblock = pa_memblock_new(BUF_SIZE, i->sink->core->memblock_stat);
 | 
					        u->memchunk.memblock = pa_memblock_new(BUF_SIZE, i->sink->core->memblock_stat);
 | 
				
			||||||
        u->memchunk.index = 0;
 | 
					        u->memchunk.index = 0;
 | 
				
			||||||
        samples = sf_readf_float(u->sndfile, u->memchunk.memblock->data, samples);
 | 
					        samples = u->readf_function(u->sndfile, u->memchunk.memblock->data, samples);
 | 
				
			||||||
        u->memchunk.length = samples*fs;
 | 
					        u->memchunk.length = samples*fs;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if (!u->memchunk.length) {
 | 
					        if (!u->memchunk.length) {
 | 
				
			||||||
| 
						 | 
					@ -136,7 +137,21 @@ int pa_play_file(struct pa_sink *sink, const char *fname, pa_volume_t volume) {
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ss.format = PA_SAMPLE_FLOAT32;
 | 
					    switch (sfinfo.format & 0xFF) {
 | 
				
			||||||
 | 
					        case SF_FORMAT_PCM_16:
 | 
				
			||||||
 | 
					        case SF_FORMAT_PCM_U8:
 | 
				
			||||||
 | 
					        case SF_FORMAT_ULAW:
 | 
				
			||||||
 | 
					        case SF_FORMAT_ALAW:
 | 
				
			||||||
 | 
					            ss.format = PA_SAMPLE_S16NE;
 | 
				
			||||||
 | 
					            u->readf_function = (sf_count_t (*)(SNDFILE *sndfile, void *ptr, sf_count_t frames)) sf_readf_short;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case SF_FORMAT_FLOAT:
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            ss.format = PA_SAMPLE_FLOAT32NE;
 | 
				
			||||||
 | 
					            u->readf_function = (sf_count_t (*)(SNDFILE *sndfile, void *ptr, sf_count_t frames)) sf_readf_float;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
    ss.rate = sfinfo.samplerate;
 | 
					    ss.rate = sfinfo.samplerate;
 | 
				
			||||||
    ss.channels = sfinfo.channels;
 | 
					    ss.channels = sfinfo.channels;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,19 +39,34 @@ int pa_sound_file_load(const char *fname, struct pa_sample_spec *ss, struct pa_m
 | 
				
			||||||
    SF_INFO sfinfo;
 | 
					    SF_INFO sfinfo;
 | 
				
			||||||
    int ret = -1;
 | 
					    int ret = -1;
 | 
				
			||||||
    size_t l;
 | 
					    size_t l;
 | 
				
			||||||
 | 
					    sf_count_t (*readf_function)(SNDFILE *sndfile, void *ptr, sf_count_t frames);
 | 
				
			||||||
    assert(fname && ss && chunk);
 | 
					    assert(fname && ss && chunk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    memset(&sfinfo, 0, sizeof(sfinfo));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    chunk->memblock = NULL;
 | 
					    chunk->memblock = NULL;
 | 
				
			||||||
    chunk->index = chunk->length = 0;
 | 
					    chunk->index = chunk->length = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memset(&sfinfo, 0, sizeof(sfinfo));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!(sf = sf_open(fname, SFM_READ, &sfinfo))) {
 | 
					    if (!(sf = sf_open(fname, SFM_READ, &sfinfo))) {
 | 
				
			||||||
        pa_log(__FILE__": Failed to open file %s\n", fname);
 | 
					        pa_log(__FILE__": Failed to open file %s\n", fname);
 | 
				
			||||||
        goto finish;
 | 
					        goto finish;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ss->format = PA_SAMPLE_FLOAT32;
 | 
					    switch (sfinfo.format & 0xFF) {
 | 
				
			||||||
 | 
					        case SF_FORMAT_PCM_16:
 | 
				
			||||||
 | 
					        case SF_FORMAT_PCM_U8:
 | 
				
			||||||
 | 
					        case SF_FORMAT_ULAW:
 | 
				
			||||||
 | 
					        case SF_FORMAT_ALAW:
 | 
				
			||||||
 | 
					            ss->format = PA_SAMPLE_S16NE;
 | 
				
			||||||
 | 
					            readf_function = (sf_count_t (*)(SNDFILE *sndfile, void *ptr, sf_count_t frames)) sf_readf_short;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case SF_FORMAT_FLOAT:
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            ss->format = PA_SAMPLE_FLOAT32NE;
 | 
				
			||||||
 | 
					            readf_function = (sf_count_t (*)(SNDFILE *sndfile, void *ptr, sf_count_t frames)) sf_readf_float;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ss->rate = sfinfo.samplerate;
 | 
					    ss->rate = sfinfo.samplerate;
 | 
				
			||||||
    ss->channels = sfinfo.channels;
 | 
					    ss->channels = sfinfo.channels;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -70,7 +85,7 @@ int pa_sound_file_load(const char *fname, struct pa_sample_spec *ss, struct pa_m
 | 
				
			||||||
    chunk->index = 0;
 | 
					    chunk->index = 0;
 | 
				
			||||||
    chunk->length = l;
 | 
					    chunk->length = l;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (sf_readf_float(sf, chunk->memblock->data, sfinfo.frames) != sfinfo.frames) {
 | 
					    if (readf_function(sf, chunk->memblock->data, sfinfo.frames) != sfinfo.frames) {
 | 
				
			||||||
        pa_log(__FILE__": Premature file end\n");
 | 
					        pa_log(__FILE__": Premature file end\n");
 | 
				
			||||||
        goto finish;
 | 
					        goto finish;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -518,3 +518,10 @@ int pa_lock_file(int fd, int b) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char* pa_strip_nl(char *s) {
 | 
				
			||||||
 | 
					    assert(s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    s[strcspn(s, "\r\n")] = 0;
 | 
				
			||||||
 | 
					    return s;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -62,6 +62,8 @@ int pa_parse_boolean(const char *s);
 | 
				
			||||||
char *pa_split(const char *c, const char*delimiters, const char **state);
 | 
					char *pa_split(const char *c, const char*delimiters, const char **state);
 | 
				
			||||||
char *pa_split_spaces(const char *c, const char **state);
 | 
					char *pa_split_spaces(const char *c, const char **state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char *pa_strip_nl(char *s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const char *pa_strsignal(int sig);
 | 
					const char *pa_strsignal(int sig);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int pa_parse_resample_method(const char *string);
 | 
					int pa_parse_resample_method(const char *string);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue