diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2013-05-03 21:08:42 +0400 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2013-05-03 21:08:42 +0400 |
commit | 1058def8e7827e56ce4a70afb4aeacb5dc44148f (patch) | |
tree | 4495d23e7b54ab5700e3839081e797c1eafe0db9 /kernel/framework/include/audio_core.h | |
download | oss4-upstream.tar.gz |
Imported Upstream version 4.2-build2006upstream/4.2-build2006upstream
Diffstat (limited to 'kernel/framework/include/audio_core.h')
-rw-r--r-- | kernel/framework/include/audio_core.h | 427 |
1 files changed, 427 insertions, 0 deletions
diff --git a/kernel/framework/include/audio_core.h b/kernel/framework/include/audio_core.h new file mode 100644 index 0000000..59aa3bc --- /dev/null +++ b/kernel/framework/include/audio_core.h @@ -0,0 +1,427 @@ +#ifndef AUDIO_CORE_H +#define AUDIO_CORE_H +/* + * Purpose: Internal definitions for the OS audio core + * + * IMPORTANT NOTICE! + * + * This file contains internal structures used by Open Sound Systems. + * They will change without any notice between OSS versions. Care must be taken + * to make sure any software using this header gets properly re-compiled before + * use. + * + * 4Front Technologies (or anybody else) takes no responsibility of damages + * caused by use of this file. + */ + +/* + * + * This file is part of Open Sound System. + * + * Copyright (C) 4Front Technologies 1996-2008. + * + * This this source file is released under GPL v2 license (no other versions). + * See the COPYING file included in the main directory of this source + * distribution for the license terms and conditions. + * + */ + +/* + * Max number of audio channels currently supported by the sample format converter. + */ +#define OSS_MAX_CONVERT_CHANNELS 64 + +/* + * Size of the temporary buffer used for audio conversions. + * + * TMP_CONVERT_MAX defines how many bytes can be fed to the converter in + * one call. + * + * TMP_CONVERT_BUF_SIZE defines how many bytes of buffer will be allocated. + * This is larger than TMP_CONVERT_MAX because amount of data may get expanded + * during the conversion (for example if the output sampling rate or #channels + * is larger than in the input side). + */ +#define TMP_CONVERT_MAX (16*1024) +#define TMP_CONVERT_BUF_SIZE (8*TMP_CONVERT_MAX) + +/* + * open_flags (for opening audio devices) + */ +#define OF_MMAP 0x00000001 /* Opening application is known to use mmap() */ +#define OF_BLOCK 0x00000002 /* Disable O_NONBLOCK */ +#define OF_NOCONV 0x00000010 /* Disable all fmt/src conversions */ +#define OF_DEVAUDIO 0x00000020 /* Solaris /dev/audio emulator */ +#define OF_SMALLFRAGS 0x00000040 /* Use smaller fragments than requested */ +#define OF_SMALLBUF 0x00000080 /* Allocate small (4k) buffer this time */ +#define OF_MEDIUMBUF 0x00000100 /* Allocate moderate (16k) buffer */ + +#define CONVERTABLE_FORMATS \ + (AFMT_U8|AFMT_S8|AFMT_MU_LAW|AFMT_S16_LE|AFMT_S16_BE|\ + AFMT_S24_LE|AFMT_S24_BE|AFMT_S32_LE|AFMT_S32_BE|AFMT_S24_PACKED) + +#ifndef _KERNEL +typedef struct _audiodrv_t audiodrv_t; +#endif + +typedef struct +{ + char *name; + int fmt; + unsigned char neutral_byte; + char bits; + char is_linear; + char endianess; +#define ENDIAN_NONE 0 +#define ENDIAN_LITTLE 1 +#define ENDIAN_BIG 2 +#ifdef OSS_BIG_ENDIAN +# define ENDIAN_NATIVE ENDIAN_BIG +#else +# define ENDIAN_NATIVE ENDIAN_LITTLE +#endif + + char is_signed; + char alignment; +#define ALIGN_MSB 0 +#define ALIGN_LSB 1 + int no_convert; +} +audio_format_info_t, *audio_format_info_p; + +typedef struct +{ + int fmt, rate, channels; + int convert; +} +sample_parms; + +typedef struct _adev_t adev_t, *adev_p; +typedef struct _dmap_t *dmap_p; +typedef int (*cnv_func_t) (adev_p adev, dmap_p dmap, unsigned char **srcp, int *srcl, + unsigned char **tgtp, sample_parms * source, + sample_parms * target); + +struct _dmap_t +{ +/* + * Static fields (not to be cleared during open) + */ +#ifdef _KERNEL + oss_mutex_t mutex; +#endif + oss_device_t *osdev; + oss_device_t *master_osdev; /* The osdev pointer of the master (for virtual drivers) */ + adev_t *adev; + unsigned char *dmabuf; + oss_native_word dmabuf_phys; + oss_dma_handle_t dmabuf_dma_handle; + int buffsize; + int buffer_protected; /* Buffer is shared - don't modify/clear */ + unsigned char *tmpbuf1, *tmpbuf2; + void *driver_use_ptr; + long driver_use_value; + /* Interrupt callback stuff */ + void (*audio_callback) (int dev, int parm); + int callback_parm; + +#ifdef OS_DMA_PARMS + OS_DMA_PARMS +#endif +/* + * Dynamic fields (will be zeroed during open) + * Don't add anything before flags. + */ + void *srcstate[OSS_MAX_CONVERT_CHANNELS]; + oss_native_word flags; +#define DMAP_NOTIMEOUT 0x00000001 +#define DMAP_POST 0x00000002 +#define DMAP_PREPARED 0x00000004 +#define DMAP_FRAGFIXED 0x00000008 /* Fragment size fixed */ +#define DMAP_STARTED 0x00000010 +#define DMAP_COOKED 0x00000020 +#define DMAP_SMALLBUF 0x00000040 /* Allocate small buffers */ +#define DMAP_MEDIUMBUF 0x00000040 /* Allocate 16k buffers */ + int dma_mode; /* PCM_ENABLE_INPUT, PCM_ENABLE_OUTPUT or 0 */ + + /* + * Queue parameters. + */ + int nfrags; + int fragment_size; + int bytes_in_use; + int data_rate; /* Bytes/second */ + int frame_size; /* Device frame size */ + int user_frame_size; /* Application frame size */ + int fragsize_rq; + int low_water, low_water_rq; + volatile oss_uint64_t byte_counter; + volatile oss_uint64_t user_counter; + int interrupt_count; + int fragment_counter; + int expand_factor; + + int mapping_flags; +#define DMA_MAP_MAPPED 0x00000001 + char neutral_byte; + + int error; + int play_underruns, rec_overruns; + int underrun_flag; + int num_errors; +#define MAX_AUDIO_ERRORS 5 + int errors[MAX_AUDIO_ERRORS]; + int error_parms[MAX_AUDIO_ERRORS]; + + unsigned char *leftover_buf; + int leftover_bytes; + int tmpbuf_len, tmpbuf_ptr; + cnv_func_t convert_func; + unsigned int convert_mode; + struct audio_buffer *(*user_import) (adev_t * adev, + dmap_t * dmap, + sample_parms * parms, + unsigned char *cbuf, int len); + int (*user_export) (adev_t * adev, + dmap_t * dmap, sample_parms * parms, + struct audio_buffer * buf, unsigned char *cbuf, + int maxbytes); + struct audio_buffer *(*device_read) (adev_t * adev, + dmap_t * dmap, + sample_parms * parms, + unsigned char *cbuf, int len); + int (*device_write) (adev_t * adev, + dmap_t * dmap, + void *frombuf, void *tobuf, + int maxspace, int *fromlen, int *tolen); +}; +extern int dmap_get_qlen (dmap_t * dmap); +extern int dmap_get_qhead (dmap_t * dmap); +extern int dmap_get_qtail (dmap_t * dmap); + +struct _adev_t +{ + char name[64]; + char handle[32]; + int engine_num; /* Audio engine number */ + int audio_devfile; /* Audio device file number */ + int enabled; + int unloaded; + struct _adev_t *next_in, *next_out; /* Links to the next "shadow" devices */ + long long flags; + int open_flags; + int src_quality; + int caps; + int magic; /* Secret low level driver ID */ + int latency; /* In usecs, -1=unknown */ + + + /* + * Sampling parameters + */ + + sample_parms user_parms, hw_parms; + int iformat_mask, oformat_mask; /* Bitmasks for supported audio formats */ + int min_rate, max_rate; /* Sampling rate limits */ + int min_channels, max_channels; + char *inch_names, *outch_names; + int xformat_mask; /* Format mask for current open mode */ + int binding; + void *devc; /* Driver specific info */ + audiodrv_t *d; + void *portc, *portc_play, *portc_record; /* Driver specific info */ + dmap_t *dmap_in, *dmap_out; + int mixer_dev; + int open_mode; + int go; + int enable_bits; + int parent_dev; /* 0 -> no parent, 1 to n -> parent=parent_dev+1 */ + int max_block; /* Maximum fragment size to be accepted */ + int min_block; /* Minimum fragment size */ + int min_fragments; /* Minimum number of fragments */ + int max_fragments; /* Maximum number of fragments */ + int max_intrate; /* Another form of min_block */ + int dmabuf_alloc_flags; + oss_uint64_t dmabuf_maxaddr; + int fixed_rate; + int vmix_flags; /* special flags sent to virtual mixer */ +#define VMIX_MULTIFRAG 0x00000001 /* More than 2 fragments required (causes longer latencies) */ +#define VMIX_DISABLED 0x00000002 /* Not compatible with vmix */ +#define VMIX_NOINPUT 0x00000004 /* Disable input capability */ +#define VMIX_NOMAINVOL 0x00000008 /* No main volume sliders/meters please */ + pid_t pid; + char cmd[16]; + oss_device_t *osdev; + oss_device_t *master_osdev; /* The osdev pointer of the master (for virtual drivers) */ + int setfragment_warned; + int getispace_error_count; + int redirect_in, redirect_out; + int dmask; /* Open dmaps */ +#define DMASK_OUT 0x01 +#define DMASK_IN 0x02 + int nonblock; + int forced_nonblock; + int ossd_registered; + int sync_flags; +#define SYNC_MASTER 0x01 +#define SYNC_SLAVE 0x02 + int sync_group; + int sync_mode; + adev_t *sync_next; /* Next device in sync group */ + + int rate_source; + unsigned int nrates, rates[OSS_MAX_SAMPLE_RATES + 1]; + +#ifdef _KERNEL + oss_mutex_t mutex; + oss_wait_queue_t *out_wq, *in_wq; +#endif + + int card_number; + int port_number; + int real_dev; + +/* + * By default OSS will let applications to use sampling rates and formats + * that are not supported by the hardware. Instead OSS performs the necessary + * format conversions in software. Applications that don't tolerate this kind + * of conversions usually disable them by using features of the OSS API + * (SNDCTL_DSP_COOKEDMODE). If this option is set to 0 then the format + * conversions will be disabled for all applications and devices unless the + * application explicitly enables them. + * + * cooked_enable is a global variable (int) defined in oss_core_options.c. The current + * value of this global variable will be copied to adev->cooked_enable when + * an audio engine is opened. + */ + int cooked_enable; + int timeout_count; + + void (*outputintr) (int dev, int intr_flags); + void (*inputintr) (int dev, int intr_flags); + + int policy; + void *os_id; /* The device ID (dip) given by the system. */ + oss_longname_t song_name; + oss_label_t label; + oss_devnode_t devnode; + void *vmix_mixer; /* Pointer to the vmix_mixer_t structure for this device */ + void *prev_vmix_mixer; /* Reserved for vmix_core */ +}; + +#define UNIT_EXPAND 1024 + +/* + * The audio_devfiles and audio_engines tables contain pointers to + * the (same) adev_t structures. The difference is that + * audio_engines contains an entry for all audio devices/engines in the system + * (including hidden and shadow devices). The 'dev' parameter of most audio + * core routines and audio driver methods are indexes to this array. + * + * The audio_devfiles array is a "parallel" structure that contains only + * the audio engines that have a device file in /dev/oss (and usually also + * an legacy /dev/dsp# device file). This audio_devfiles array doesn't contain + * "hidden" audio engines. + * + * Each audio operations structure in audio_devfiles will also be in + * audio_engines but the indexes are different. Both arrays contain pointer to + * the same structure in memory (not a copy). + * + * For example the 6th audio device file (usually but not always /dev/dsp5) is + * audio_devfiles[5]. However it may be (say) audio_engines[11] if there are + * hidden devices created before it. + * + * /dev/dsp5 -> audio_devfile[5] == audio_engines[11] + * + * The next field of the adev_t structure contains a pointer + * to the next "identical" device. Most OSS implementations will + * try to open one of the subsequent devices in the next chain if + * the original device was busy. "Identical" means that the device suports + * multiple identical (hw mixing) engines or the vmix driver is used to + * add software mixing capability to the device. + */ + +extern adev_t **audio_engines; +extern int num_audio_engines; +extern adev_t **audio_devfiles; +extern int num_audio_devfiles; + +#if 0 +typedef struct +{ + int ndevs; + unsigned short devices[MAX_AUDIO_DEVFILES]; +} +oss_devlist_t; + +extern oss_devlist_t dspoutlist, dspoutlist2, dspinlist, dspinoutlist; +#endif + +int oss_install_audiodev (int vers, + oss_device_t * osdev, + oss_device_t * master_osdev, + char *name, + const audiodrv_t * driver, + int driver_size, + unsigned long long flags, + unsigned int format_mask, void *devc, int parent); + +int oss_install_audiodev_with_devname (int vers, + oss_device_t * osdev, + oss_device_t * master_osdev, + char *name, + const audiodrv_t * driver, + int driver_size, + int flags, + unsigned int format_mask, void *devc, int parent, + const char *devfile_name); +extern void install_vdsp (oss_device_t * osdev); +extern int *load_mixer_volumes (char *name, int *levels, int present); + +#ifdef _KERNEL +int oss_audio_read (int dev, struct fileinfo *file, uio_t * buf, int count); +int oss_audio_write (int dev, struct fileinfo *file, uio_t * buf, int count); +int oss_audio_open_engine (int dev, int dev_class, struct fileinfo *file, + int recursive, int open_flags, int *newdev); +int oss_audio_open_devfile (int dev, int dev_class, struct fileinfo *file, + int recursive, int open_flags, int *newdev); +int oss_open_vdsp (int dev, int dev_type, struct fileinfo *file, + int recursive, int open_flags, int *newdev); +void oss_audio_release (int dev, struct fileinfo *file); +int oss_audio_ioctl (int dev, struct fileinfo *file, + unsigned int cmd, ioctl_arg arg); +int oss_audio_set_format (int dev, int fmt, int format_mask); +int oss_audio_set_channels (int dev, int ch); +int oss_audio_set_rate (int dev, int val); +void audio_uninit_device (int dev); +int oss_audio_mmap (int dev, int direction); +#endif + +/* From audiofmt.c */ +int setup_format_conversions (adev_p adev, dmap_p dmap, sample_parms * source, + sample_parms * target, + sample_parms * user, + sample_parms * device, int format_mask); +audio_format_info_p oss_find_format (unsigned int fmt); + + +#define oss_audio_outputintr(dev, flags) audio_engines[dev]->outputintr(dev, flags) +#define oss_audio_inputintr(dev, flags) audio_engines[dev]->inputintr(dev, flags) +void oss_audio_reset (int dev); +void oss_audio_start_syncgroup (unsigned int syncgroup); +typedef int (*oss_audio_startup_func) (void *devc); +extern void oss_audio_register_client (oss_audio_startup_func func, + void *devc, oss_device_t * osdev); + +extern int oss_encode_enum (oss_mixer_enuminfo * ei, const char *s, + int version); +extern char *audio_show_latency (int dev); +extern void oss_audio_inc_byte_counter (dmap_t * dmap, int increment); +extern void oss_add_audio_devlist (int list, int devfile); + +#ifndef SMALL_DMABUF_SIZE +#define SMALL_DMABUF_SIZE (4*1024) +#endif + +#define MEDIUM_DMABUF_SIZE (16*1024) +#endif |