![]() |
|
|||
0001 /* SPDX-License-Identifier: GPL-2.0-only */ 0002 /* 0003 * Line 6 Linux USB driver 0004 * 0005 * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) 0006 */ 0007 0008 /* 0009 PCM interface to POD series devices. 0010 */ 0011 0012 #ifndef PCM_H 0013 #define PCM_H 0014 0015 #include <sound/pcm.h> 0016 0017 #include "driver.h" 0018 0019 /* 0020 number of USB frames per URB 0021 The Line 6 Windows driver always transmits two frames per packet, but 0022 the Linux driver performs significantly better (i.e., lower latency) 0023 with only one frame per packet. 0024 */ 0025 #define LINE6_ISO_PACKETS 1 0026 0027 /* in a "full speed" device (such as the PODxt Pro) this means 1ms, 0028 * for "high speed" it's 1/8ms 0029 */ 0030 #define LINE6_ISO_INTERVAL 1 0031 0032 #define LINE6_IMPULSE_DEFAULT_PERIOD 100 0033 0034 /* 0035 Get substream from Line 6 PCM data structure 0036 */ 0037 #define get_substream(line6pcm, stream) \ 0038 (line6pcm->pcm->streams[stream].substream) 0039 0040 /* 0041 PCM mode bits. 0042 0043 There are several features of the Line 6 USB driver which require PCM 0044 data to be exchanged with the device: 0045 *) PCM playback and capture via ALSA 0046 *) software monitoring (for devices without hardware monitoring) 0047 *) optional impulse response measurement 0048 However, from the device's point of view, there is just a single 0049 capture and playback stream, which must be shared between these 0050 subsystems. It is therefore necessary to maintain the state of the 0051 subsystems with respect to PCM usage. 0052 0053 We define two bit flags, "opened" and "running", for each playback 0054 or capture stream. Both can contain the bit flag corresponding to 0055 LINE6_STREAM_* type, 0056 LINE6_STREAM_PCM = ALSA PCM playback or capture 0057 LINE6_STREAM_MONITOR = software monitoring 0058 IMPULSE = optional impulse response measurement 0059 The opened flag indicates whether the buffer is allocated while 0060 the running flag indicates whether the stream is running. 0061 0062 For monitor or impulse operations, the driver needs to call 0063 line6_pcm_acquire() or line6_pcm_release() with the appropriate 0064 LINE6_STREAM_* flag. 0065 */ 0066 0067 /* stream types */ 0068 enum { 0069 LINE6_STREAM_PCM, 0070 LINE6_STREAM_MONITOR, 0071 LINE6_STREAM_IMPULSE, 0072 LINE6_STREAM_CAPTURE_HELPER, 0073 }; 0074 0075 /* misc bit flags for PCM operation */ 0076 enum { 0077 LINE6_FLAG_PAUSE_PLAYBACK, 0078 LINE6_FLAG_PREPARED, 0079 }; 0080 0081 struct line6_pcm_properties { 0082 struct snd_pcm_hardware playback_hw, capture_hw; 0083 struct snd_pcm_hw_constraint_ratdens rates; 0084 int bytes_per_channel; 0085 }; 0086 0087 struct line6_pcm_stream { 0088 /* allocated URBs */ 0089 struct urb **urbs; 0090 0091 /* Temporary buffer; 0092 * Since the packet size is not known in advance, this buffer is 0093 * large enough to store maximum size packets. 0094 */ 0095 unsigned char *buffer; 0096 0097 /* Free frame position in the buffer. */ 0098 snd_pcm_uframes_t pos; 0099 0100 /* Count processed bytes; 0101 * This is modulo period size (to determine when a period is finished). 0102 */ 0103 unsigned bytes; 0104 0105 /* Counter to create desired sample rate */ 0106 unsigned count; 0107 0108 /* period size in bytes */ 0109 unsigned period; 0110 0111 /* Processed frame position in the buffer; 0112 * The contents of the ring buffer have been consumed by the USB 0113 * subsystem (i.e., sent to the USB device) up to this position. 0114 */ 0115 snd_pcm_uframes_t pos_done; 0116 0117 /* Bit mask of active URBs */ 0118 unsigned long active_urbs; 0119 0120 /* Bit mask of URBs currently being unlinked */ 0121 unsigned long unlink_urbs; 0122 0123 /* Spin lock to protect updates of the buffer positions (not contents) 0124 */ 0125 spinlock_t lock; 0126 0127 /* Bit flags for operational stream types */ 0128 unsigned long opened; 0129 0130 /* Bit flags for running stream types */ 0131 unsigned long running; 0132 0133 int last_frame; 0134 }; 0135 0136 struct snd_line6_pcm { 0137 /* Pointer back to the Line 6 driver data structure */ 0138 struct usb_line6 *line6; 0139 0140 /* Properties. */ 0141 struct line6_pcm_properties *properties; 0142 0143 /* ALSA pcm stream */ 0144 struct snd_pcm *pcm; 0145 0146 /* protection to state changes of in/out streams */ 0147 struct mutex state_mutex; 0148 0149 /* Capture and playback streams */ 0150 struct line6_pcm_stream in; 0151 struct line6_pcm_stream out; 0152 0153 /* Previously captured frame (for software monitoring) */ 0154 unsigned char *prev_fbuf; 0155 0156 /* Size of previously captured frame (for software monitoring/sync) */ 0157 int prev_fsize; 0158 0159 /* Maximum size of USB packet */ 0160 int max_packet_size_in; 0161 int max_packet_size_out; 0162 0163 /* PCM playback volume (left and right) */ 0164 int volume_playback[2]; 0165 0166 /* PCM monitor volume */ 0167 int volume_monitor; 0168 0169 /* Volume of impulse response test signal (if zero, test is disabled) */ 0170 int impulse_volume; 0171 0172 /* Period of impulse response test signal */ 0173 int impulse_period; 0174 0175 /* Counter for impulse response test signal */ 0176 int impulse_count; 0177 0178 /* Several status bits (see LINE6_FLAG_*) */ 0179 unsigned long flags; 0180 }; 0181 0182 extern int line6_init_pcm(struct usb_line6 *line6, 0183 struct line6_pcm_properties *properties); 0184 extern int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd); 0185 extern int snd_line6_prepare(struct snd_pcm_substream *substream); 0186 extern int snd_line6_hw_params(struct snd_pcm_substream *substream, 0187 struct snd_pcm_hw_params *hw_params); 0188 extern int snd_line6_hw_free(struct snd_pcm_substream *substream); 0189 extern snd_pcm_uframes_t snd_line6_pointer(struct snd_pcm_substream *substream); 0190 extern void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm); 0191 extern int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int type, 0192 bool start); 0193 extern void line6_pcm_release(struct snd_line6_pcm *line6pcm, int type); 0194 0195 #endif
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.1.0 LXR engine. The LXR team |
![]() ![]() |