mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	make module-oss-* use modargs
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@63 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
		
							parent
							
								
									216591d95e
								
							
						
					
					
						commit
						d4e0d51c15
					
				
					 7 changed files with 135 additions and 70 deletions
				
			
		| 
						 | 
				
			
			@ -42,7 +42,7 @@ int main(int argc, char *argv[]) {
 | 
			
		|||
    c = pa_core_new(pa_mainloop_get_api(mainloop));
 | 
			
		||||
    assert(c);
 | 
			
		||||
    
 | 
			
		||||
    pa_module_load(c, "module-oss-mmap", "/dev/dsp");
 | 
			
		||||
    pa_module_load(c, "module-oss-mmap", "device=/dev/dsp playback=1 record=1");
 | 
			
		||||
/*    pa_module_load(c, "module-oss-mmap", "/dev/dsp1");*/
 | 
			
		||||
/*    pa_module_load(c, "module-pipe-sink", NULL);*/
 | 
			
		||||
    pa_module_load(c, "module-simple-protocol-tcp", NULL);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,6 +18,7 @@
 | 
			
		|||
#include "oss-util.h"
 | 
			
		||||
#include "sample-util.h"
 | 
			
		||||
#include "util.h"
 | 
			
		||||
#include "modargs.h"
 | 
			
		||||
 | 
			
		||||
struct userdata {
 | 
			
		||||
    struct pa_sink *sink;
 | 
			
		||||
| 
						 | 
				
			
			@ -38,8 +39,18 @@ struct userdata {
 | 
			
		|||
    unsigned out_current, in_current;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void module_done(struct pa_core *c, struct pa_module*m);
 | 
			
		||||
static const char* const valid_modargs[] = {
 | 
			
		||||
    "sink_name",
 | 
			
		||||
    "source_name",
 | 
			
		||||
    "device",
 | 
			
		||||
    "record",
 | 
			
		||||
    "playback",
 | 
			
		||||
    NULL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_SINK_NAME "oss_output"
 | 
			
		||||
#define DEFAULT_SOURCE_NAME "oss_input"
 | 
			
		||||
#define DEFAULT_DEVICE "/dev/dsp"
 | 
			
		||||
 | 
			
		||||
static void out_fill_memblocks(struct userdata *u, unsigned n) {
 | 
			
		||||
    assert(u && u->out_memblocks);
 | 
			
		||||
| 
						 | 
				
			
			@ -163,10 +174,12 @@ static uint32_t sink_get_latency_cb(struct pa_sink *s) {
 | 
			
		|||
int pa_module_init(struct pa_core *c, struct pa_module*m) {
 | 
			
		||||
    struct audio_buf_info info;
 | 
			
		||||
    struct userdata *u = NULL;
 | 
			
		||||
    char *p;
 | 
			
		||||
    const char *p;
 | 
			
		||||
    int frag_size;
 | 
			
		||||
    int mode, caps, caps_read = 0;
 | 
			
		||||
    int mode, caps;
 | 
			
		||||
    int enable_bits = 0, zero = 0;
 | 
			
		||||
    int playback = 1, record = 1;
 | 
			
		||||
    struct pa_modargs *ma = NULL;
 | 
			
		||||
    assert(c && m);
 | 
			
		||||
 | 
			
		||||
    m->userdata = u = malloc(sizeof(struct userdata));
 | 
			
		||||
| 
						 | 
				
			
			@ -175,38 +188,25 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) {
 | 
			
		|||
    u->fd = -1;
 | 
			
		||||
    u->core = c;
 | 
			
		||||
 | 
			
		||||
    p = m->argument ? m->argument : "/dev/dsp";
 | 
			
		||||
    if ((u->fd = open(p, (mode = O_RDWR)|O_NDELAY)) >= 0) {
 | 
			
		||||
        ioctl(u->fd, SNDCTL_DSP_SETDUPLEX, 0);
 | 
			
		||||
        
 | 
			
		||||
        if (ioctl(u->fd, SNDCTL_DSP_GETCAPS, &caps) < 0) {
 | 
			
		||||
            fprintf(stderr, "SNDCTL_DSP_GETCAPS: %s\n", strerror(errno));
 | 
			
		||||
            goto fail;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!(caps & DSP_CAP_DUPLEX)) {
 | 
			
		||||
            close(u->fd);
 | 
			
		||||
            u->fd = -1;
 | 
			
		||||
        } else
 | 
			
		||||
            caps_read = 1;
 | 
			
		||||
    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
 | 
			
		||||
        fprintf(stderr, __FILE__": failed to parse module arguments.\n");
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    if (u->fd < 0) {
 | 
			
		||||
        if ((u->fd = open(p, (mode = O_WRONLY)|O_NDELAY)) < 0) {
 | 
			
		||||
            if ((u->fd = open(p, (mode = O_RDONLY)|O_NDELAY)) < 0) {
 | 
			
		||||
                fprintf(stderr, "open('%s'): %s\n", p, strerror(errno));
 | 
			
		||||
                goto fail;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    if (pa_modargs_get_value_u32(ma, "record", &record) < 0 || pa_modargs_get_value_u32(ma, "playback", &playback) < 0) {
 | 
			
		||||
        fprintf(stderr, __FILE__": record= and playback= expect numeric arguments.\n");
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!caps_read) {
 | 
			
		||||
        if (ioctl(u->fd, SNDCTL_DSP_GETCAPS, &caps) < 0) {
 | 
			
		||||
            fprintf(stderr, "SNDCTL_DSP_GETCAPS: %s\n", strerror(errno));
 | 
			
		||||
            goto fail;
 | 
			
		||||
        }
 | 
			
		||||
    mode = (playback&&record) ? O_RDWR : (playback ? O_WRONLY : (record ? O_RDONLY : 0));
 | 
			
		||||
    if (mode == 0) {
 | 
			
		||||
        fprintf(stderr, __FILE__": neither playback nor record enabled for device.\n");
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((u->fd = pa_oss_open(p = pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), &mode, &caps)) < 0)
 | 
			
		||||
        goto fail;
 | 
			
		||||
 | 
			
		||||
    if (!(caps & DSP_CAP_MMAP) || !(caps & DSP_CAP_REALTIME) || !(caps & DSP_CAP_TRIGGER)) {
 | 
			
		||||
        fprintf(stderr, "OSS device not mmap capable.\n");
 | 
			
		||||
        goto fail;
 | 
			
		||||
| 
						 | 
				
			
			@ -242,7 +242,7 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) {
 | 
			
		|||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
        
 | 
			
		||||
            u->source = pa_source_new(c, "oss_input", 0, &u->sample_spec);
 | 
			
		||||
            u->source = pa_source_new(c, pa_modargs_get_value(ma, "source_name", DEFAULT_SOURCE_NAME), 0, &u->sample_spec);
 | 
			
		||||
            assert(u->source);
 | 
			
		||||
            u->source->userdata = u;
 | 
			
		||||
            pa_source_set_owner(u->source, m);
 | 
			
		||||
| 
						 | 
				
			
			@ -276,7 +276,7 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) {
 | 
			
		|||
        } else {
 | 
			
		||||
            pa_silence_memory(u->out_mmap, u->out_mmap_length, &u->sample_spec);
 | 
			
		||||
            
 | 
			
		||||
            u->sink = pa_sink_new(c, "oss_output", 0, &u->sample_spec);
 | 
			
		||||
            u->sink = pa_sink_new(c, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &u->sample_spec);
 | 
			
		||||
            assert(u->sink);
 | 
			
		||||
            u->sink->get_latency = sink_get_latency_cb;
 | 
			
		||||
            u->sink->userdata = u;
 | 
			
		||||
| 
						 | 
				
			
			@ -309,7 +309,7 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) {
 | 
			
		|||
    return 0;
 | 
			
		||||
 | 
			
		||||
fail:
 | 
			
		||||
    module_done(c, m);
 | 
			
		||||
    pa_module_done(c, m);
 | 
			
		||||
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,6 +17,7 @@
 | 
			
		|||
#include "oss-util.h"
 | 
			
		||||
#include "sample-util.h"
 | 
			
		||||
#include "util.h"
 | 
			
		||||
#include "modargs.h"
 | 
			
		||||
 | 
			
		||||
struct userdata {
 | 
			
		||||
    struct pa_sink *sink;
 | 
			
		||||
| 
						 | 
				
			
			@ -31,6 +32,19 @@ struct userdata {
 | 
			
		|||
    int fd;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const char* const valid_modargs[] = {
 | 
			
		||||
    "sink_name",
 | 
			
		||||
    "source_name",
 | 
			
		||||
    "device",
 | 
			
		||||
    "record",
 | 
			
		||||
    "playback",
 | 
			
		||||
    NULL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_SINK_NAME "oss_output"
 | 
			
		||||
#define DEFAULT_SOURCE_NAME "oss_input"
 | 
			
		||||
#define DEFAULT_DEVICE "/dev/dsp"
 | 
			
		||||
 | 
			
		||||
static void do_write(struct userdata *u) {
 | 
			
		||||
    struct pa_memchunk *memchunk;
 | 
			
		||||
    ssize_t r;
 | 
			
		||||
| 
						 | 
				
			
			@ -115,39 +129,34 @@ static uint32_t sink_get_latency_cb(struct pa_sink *s) {
 | 
			
		|||
int pa_module_init(struct pa_core *c, struct pa_module*m) {
 | 
			
		||||
    struct audio_buf_info info;
 | 
			
		||||
    struct userdata *u = NULL;
 | 
			
		||||
    char *p;
 | 
			
		||||
    const char *p;
 | 
			
		||||
    int fd = -1;
 | 
			
		||||
    int frag_size, in_frag_size, out_frag_size;
 | 
			
		||||
    int mode;
 | 
			
		||||
    uint32_t record = 1, playback = 1;
 | 
			
		||||
    struct pa_sample_spec ss;
 | 
			
		||||
    struct pa_modargs *ma = NULL;
 | 
			
		||||
    assert(c && m);
 | 
			
		||||
 | 
			
		||||
    p = m->argument ? m->argument : "/dev/dsp";
 | 
			
		||||
    if ((fd = open(p, (mode = O_RDWR)|O_NDELAY)) >= 0) {
 | 
			
		||||
        int caps;
 | 
			
		||||
 | 
			
		||||
        ioctl(fd, SNDCTL_DSP_SETDUPLEX, 0);
 | 
			
		||||
        
 | 
			
		||||
        if (ioctl(fd, SNDCTL_DSP_GETCAPS, &caps) < 0) {
 | 
			
		||||
            fprintf(stderr, "SNDCTL_DSP_GETCAPS: %s\n", strerror(errno));
 | 
			
		||||
            goto fail;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!(caps & DSP_CAP_DUPLEX)) {
 | 
			
		||||
            close(fd);
 | 
			
		||||
            fd = -1;
 | 
			
		||||
        }
 | 
			
		||||
    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
 | 
			
		||||
        fprintf(stderr, __FILE__": failed to parse module arguments.\n");
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    if (fd < 0) {
 | 
			
		||||
        if ((fd = open(p, (mode = O_WRONLY)|O_NDELAY)) < 0) {
 | 
			
		||||
            if ((fd = open(p, (mode = O_RDONLY)|O_NDELAY)) < 0) {
 | 
			
		||||
                fprintf(stderr, "open('%s'): %s\n", p, strerror(errno));
 | 
			
		||||
                goto fail;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    if (pa_modargs_get_value_u32(ma, "record", &record) < 0 || pa_modargs_get_value_u32(ma, "playback", &playback) < 0) {
 | 
			
		||||
        fprintf(stderr, __FILE__": record= and playback= expect numeric argument.\n");
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    mode = (playback&&record) ? O_RDWR : (playback ? O_WRONLY : (record ? O_RDONLY : 0));
 | 
			
		||||
    if (mode == 0) {
 | 
			
		||||
        fprintf(stderr, __FILE__": neither playback nor record enabled for device.\n");
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((fd = pa_oss_open(p = pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), &mode, NULL)) < 0)
 | 
			
		||||
        goto fail;
 | 
			
		||||
 | 
			
		||||
    fprintf(stderr, "module-oss: device opened in %s mode.\n", mode == O_WRONLY ? "O_WRONLY" : (mode == O_RDONLY ? "O_RDONLY" : "O_RDWR"));
 | 
			
		||||
    
 | 
			
		||||
    frag_size = ((int) 12 << 16) | 10; /* nfrags = 12; frag_size = 2^10 */
 | 
			
		||||
| 
						 | 
				
			
			@ -182,7 +191,7 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) {
 | 
			
		|||
    u->core = c;
 | 
			
		||||
 | 
			
		||||
    if (mode != O_WRONLY) {
 | 
			
		||||
        u->source = pa_source_new(c, "oss_input", 0, &ss);
 | 
			
		||||
        u->source = pa_source_new(c, pa_modargs_get_value(ma, "source_name", DEFAULT_SOURCE_NAME), 0, &ss);
 | 
			
		||||
        assert(u->source);
 | 
			
		||||
        u->source->userdata = u;
 | 
			
		||||
        pa_source_set_owner(u->source, m);
 | 
			
		||||
| 
						 | 
				
			
			@ -191,7 +200,7 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) {
 | 
			
		|||
        u->source = NULL;
 | 
			
		||||
 | 
			
		||||
    if (mode != O_RDONLY) {
 | 
			
		||||
        u->sink = pa_sink_new(c, "oss_output", 0, &ss);
 | 
			
		||||
        u->sink = pa_sink_new(c, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &ss);
 | 
			
		||||
        assert(u->sink);
 | 
			
		||||
        u->sink->get_latency = sink_get_latency_cb;
 | 
			
		||||
        u->sink->userdata = u;
 | 
			
		||||
| 
						 | 
				
			
			@ -226,6 +235,9 @@ fail:
 | 
			
		|||
    if (fd >= 0)
 | 
			
		||||
        close(fd);
 | 
			
		||||
 | 
			
		||||
    if (ma)
 | 
			
		||||
        pa_modargs_free(ma);
 | 
			
		||||
    
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,7 +34,7 @@ static const char* const valid_modargs[] = {
 | 
			
		|||
    "rate",
 | 
			
		||||
    "channels",
 | 
			
		||||
    "format",
 | 
			
		||||
    "sink",
 | 
			
		||||
    "sink_name",
 | 
			
		||||
    NULL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -131,7 +131,7 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) {
 | 
			
		|||
    assert(u->filename);
 | 
			
		||||
    u->core = c;
 | 
			
		||||
    
 | 
			
		||||
    if (!(u->sink = pa_sink_new(c, pa_modargs_get_value(ma, "sink", DEFAULT_SINK_NAME), 0, &ss))) {
 | 
			
		||||
    if (!(u->sink = pa_sink_new(c, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &ss))) {
 | 
			
		||||
        fprintf(stderr, __FILE__": failed to create sink.\n");
 | 
			
		||||
        goto fail;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,9 +4,63 @@
 | 
			
		|||
#include <stdio.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
 | 
			
		||||
#include "oss-util.h"
 | 
			
		||||
 | 
			
		||||
int pa_oss_open(const char *device, int *mode, int* pcaps) {
 | 
			
		||||
    int fd = -1;
 | 
			
		||||
    assert(device && mode && (*mode == O_RDWR || *mode == O_RDONLY || *mode == O_WRONLY));
 | 
			
		||||
 | 
			
		||||
    if (*mode == O_RDWR) {
 | 
			
		||||
        if ((fd = open(device, O_RDWR|O_NDELAY)) >= 0) {
 | 
			
		||||
            int dcaps, *tcaps;
 | 
			
		||||
            ioctl(fd, SNDCTL_DSP_SETDUPLEX, 0);
 | 
			
		||||
 | 
			
		||||
            tcaps = pcaps ? pcaps : &dcaps;
 | 
			
		||||
            
 | 
			
		||||
            if (ioctl(fd, SNDCTL_DSP_GETCAPS, tcaps) < 0) {
 | 
			
		||||
                fprintf(stderr, __FILE__": SNDCTL_DSP_GETCAPS: %s\n", strerror(errno));
 | 
			
		||||
                goto fail;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (*tcaps & DSP_CAP_DUPLEX)
 | 
			
		||||
                return fd;
 | 
			
		||||
 | 
			
		||||
            close(fd);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if ((fd = open(device, (*mode = O_WRONLY)|O_NDELAY)) < 0) {
 | 
			
		||||
            if ((fd = open(device, (*mode = O_RDONLY)|O_NDELAY)) < 0) {
 | 
			
		||||
                fprintf(stderr, __FILE__": open('%s'): %s\n", device, strerror(errno));
 | 
			
		||||
                goto fail;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        if ((fd = open(device, *mode|O_NDELAY)) < 0) {
 | 
			
		||||
            fprintf(stderr, __FILE__": open('%s'): %s\n", device, strerror(errno));
 | 
			
		||||
            goto fail;
 | 
			
		||||
        }
 | 
			
		||||
    } 
 | 
			
		||||
 | 
			
		||||
    if (pcaps) {
 | 
			
		||||
        if (ioctl(fd, SNDCTL_DSP_GETCAPS, pcaps) < 0) {
 | 
			
		||||
            fprintf(stderr, "SNDCTL_DSP_GETCAPS: %s\n", strerror(errno));
 | 
			
		||||
            goto fail;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return fd;
 | 
			
		||||
 | 
			
		||||
fail:
 | 
			
		||||
    if (fd >= 0)
 | 
			
		||||
        close(fd);
 | 
			
		||||
    return fd;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int pa_oss_auto_format(int fd, struct pa_sample_spec *ss) {
 | 
			
		||||
    int format, channels, speed;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,7 @@
 | 
			
		|||
 | 
			
		||||
#include "sample.h"
 | 
			
		||||
 | 
			
		||||
int pa_oss_open(const char *device, int *mode, int* pcaps);
 | 
			
		||||
int pa_oss_auto_format(int fd, struct pa_sample_spec *ss);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										14
									
								
								src/todo
									
										
									
									
									
								
							
							
						
						
									
										14
									
								
								src/todo
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,13 +1,7 @@
 | 
			
		|||
- native library/protocol:
 | 
			
		||||
       more functions (esp. latency)
 | 
			
		||||
 | 
			
		||||
- make all modules use modargs.c:
 | 
			
		||||
   module-oss.c
 | 
			
		||||
   module-oss-mmap.c
 | 
			
		||||
- cmdline
 | 
			
		||||
- daemonizing
 | 
			
		||||
 | 
			
		||||
- move more stuff from module-oss[-dma] to liboss-util
 | 
			
		||||
- cmdline & daemonizing
 | 
			
		||||
 | 
			
		||||
- prefix modules/libraries with pa_
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -17,7 +11,10 @@
 | 
			
		|||
- svn-id and license in every file
 | 
			
		||||
- documentation
 | 
			
		||||
 | 
			
		||||
- eliminate global variables
 | 
			
		||||
- eliminate global variables:
 | 
			
		||||
            pa_default_sample_spec
 | 
			
		||||
            pa_memblock_count
 | 
			
		||||
            pa_memblock_total
 | 
			
		||||
 | 
			
		||||
-- post 0.1
 | 
			
		||||
- future cancellation
 | 
			
		||||
| 
						 | 
				
			
			@ -27,6 +24,7 @@
 | 
			
		|||
- slp/rendezvous
 | 
			
		||||
- doxygen
 | 
			
		||||
- make mcalign merge chunks
 | 
			
		||||
- modinfo
 | 
			
		||||
 | 
			
		||||
drivers:
 | 
			
		||||
- libao
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue