1 /* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 2 * Use of this source code is governed by a BSD-style license that can be 3 * found in the LICENSE file. 4 */ 5 6 #include <pthread.h> 7 #include <sys/param.h> 8 #include <syslog.h> 9 10 #include "cras_audio_area.h" 11 #include "cras_config.h" 12 #include "cras_iodev.h" 13 #include "cras_iodev_list.h" 14 #include "cras_rstream.h" 15 #include "cras_types.h" 16 #include "utlist.h" 17 18 #define EMPTY_BUFFER_SIZE (16 * 1024) 19 #define EMPTY_FRAME_SIZE 4 20 #define EMPTY_FRAMES (EMPTY_BUFFER_SIZE / EMPTY_FRAME_SIZE) 21 22 static size_t empty_supported_rates[] = { 23 44100, 48000, 0 24 }; 25 26 static size_t empty_supported_channel_counts[] = { 27 1, 2, 0 28 }; 29 30 static snd_pcm_format_t empty_supported_formats[] = { 31 SND_PCM_FORMAT_S16_LE, 32 SND_PCM_FORMAT_S24_LE, 33 SND_PCM_FORMAT_S32_LE, 34 SND_PCM_FORMAT_S24_3LE, 35 0 36 }; 37 38 struct empty_iodev { 39 struct cras_iodev base; 40 int open; 41 uint8_t *audio_buffer; 42 unsigned int buffer_level; 43 struct timespec last_buffer_access; 44 }; 45 46 /* Current level of the audio buffer. This is made up based on what has been 47 * read/written and how long it has been since then. Simulates audio hardware 48 * running at the given sample rate. 49 */ 50 static unsigned int current_level(const struct cras_iodev *iodev) 51 { 52 struct empty_iodev *empty_iodev = (struct empty_iodev *)iodev; 53 unsigned int frames, frames_since_last; 54 55 frames = empty_iodev->buffer_level; 56 frames_since_last = cras_frames_since_time( 57 &empty_iodev->last_buffer_access, 58 iodev->format->frame_rate); 59 60 if (iodev->direction == CRAS_STREAM_INPUT) 61 return (frames + frames_since_last) % EMPTY_FRAMES; 62 63 /* output */ 64 if (frames <= frames_since_last) 65 return 0; 66 return frames - frames_since_last; 67 } 68 69 /* 70 * iodev callbacks. 71 */ 72 73 static int frames_queued(const struct cras_iodev *iodev, 74 struct timespec *tstamp) 75 { 76 clock_gettime(CLOCK_MONOTONIC_RAW, tstamp); 77 return current_level(iodev); 78 } 79 80 static int delay_frames(const struct cras_iodev *iodev) 81 { 82 return 0; 83 } 84 85 static int close_dev(struct cras_iodev *iodev) 86 { 87 struct empty_iodev *empty_iodev = (struct empty_iodev *)iodev; 88 89 empty_iodev->open = 0; 90 free(empty_iodev->audio_buffer); 91 empty_iodev->audio_buffer = NULL; 92 cras_iodev_free_audio_area(iodev); 93 return 0; 94 } 95 96 static int open_dev(struct cras_iodev *iodev) 97 { 98 struct empty_iodev *empty_iodev = (struct empty_iodev *)iodev; 99 100 if (iodev->format == NULL) 101 return -EINVAL; 102 103 cras_iodev_init_audio_area(iodev, iodev->format->num_channels); 104 empty_iodev->open = 1; 105 empty_iodev->audio_buffer = calloc(1, EMPTY_BUFFER_SIZE); 106 empty_iodev->buffer_level = 0; 107 108 clock_gettime(CLOCK_MONOTONIC_RAW, &empty_iodev->last_buffer_access); 109 110 return 0; 111 } 112 113 static int get_buffer(struct cras_iodev *iodev, 114 struct cras_audio_area **area, 115 unsigned *frames) 116 { 117 struct empty_iodev *empty_iodev = (struct empty_iodev *)iodev; 118 unsigned int avail, current; 119 120 if (iodev->direction == CRAS_STREAM_OUTPUT) { 121 avail = EMPTY_FRAMES - current_level(iodev); 122 *frames = MIN(*frames, avail); 123 } else { 124 current = current_level(iodev); 125 *frames = MIN(*frames, current); 126 } 127 128 iodev->area->frames = *frames; 129 cras_audio_area_config_buf_pointers(iodev->area, iodev->format, 130 empty_iodev->audio_buffer); 131 *area = iodev->area; 132 return 0; 133 } 134 135 static int put_buffer(struct cras_iodev *iodev, unsigned frames) 136 { 137 struct empty_iodev *empty_iodev = (struct empty_iodev *)iodev; 138 139 empty_iodev->buffer_level = current_level(iodev); 140 141 clock_gettime(CLOCK_MONOTONIC_RAW, &empty_iodev->last_buffer_access); 142 143 if (iodev->direction == CRAS_STREAM_OUTPUT) { 144 empty_iodev->buffer_level += frames; 145 empty_iodev->buffer_level %= EMPTY_FRAMES; 146 } else { 147 /* Input */ 148 if (empty_iodev->buffer_level > frames) 149 empty_iodev->buffer_level -= frames; 150 else 151 empty_iodev->buffer_level = 0; 152 } 153 154 return 0; 155 } 156 157 static int flush_buffer(struct cras_iodev *iodev) 158 { 159 struct empty_iodev *empty_iodev = (struct empty_iodev *)iodev; 160 161 empty_iodev->buffer_level = current_level(iodev); 162 if (iodev->direction == CRAS_STREAM_INPUT) { 163 empty_iodev->buffer_level = 0; 164 clock_gettime(CLOCK_MONOTONIC_RAW, 165 &empty_iodev->last_buffer_access); 166 } 167 return 0; 168 } 169 170 static void update_active_node(struct cras_iodev *iodev, unsigned node_idx, 171 unsigned dev_enabled) 172 { 173 } 174 175 /* 176 * Exported Interface. 177 */ 178 179 struct cras_iodev *empty_iodev_create(enum CRAS_STREAM_DIRECTION direction) 180 { 181 struct empty_iodev *empty_iodev; 182 struct cras_iodev *iodev; 183 struct cras_ionode *node; 184 185 if (direction != CRAS_STREAM_INPUT && direction != CRAS_STREAM_OUTPUT) 186 return NULL; 187 188 empty_iodev = calloc(1, sizeof(*empty_iodev)); 189 if (empty_iodev == NULL) 190 return NULL; 191 iodev = &empty_iodev->base; 192 iodev->direction = direction; 193 194 iodev->supported_rates = empty_supported_rates; 195 iodev->supported_channel_counts = empty_supported_channel_counts; 196 iodev->supported_formats = empty_supported_formats; 197 iodev->buffer_size = EMPTY_FRAMES; 198 199 iodev->open_dev = open_dev; 200 iodev->close_dev = close_dev; 201 iodev->frames_queued = frames_queued; 202 iodev->delay_frames = delay_frames; 203 iodev->get_buffer = get_buffer; 204 iodev->put_buffer = put_buffer; 205 iodev->flush_buffer = flush_buffer; 206 iodev->update_active_node = update_active_node; 207 iodev->no_stream = cras_iodev_default_no_stream_playback; 208 209 /* Create a dummy ionode */ 210 node = (struct cras_ionode *)calloc(1, sizeof(*node)); 211 node->dev = iodev; 212 node->type = CRAS_NODE_TYPE_UNKNOWN; 213 node->volume = 100; 214 strcpy(node->name, "(default)"); 215 cras_iodev_add_node(iodev, node); 216 cras_iodev_set_active_node(iodev, node); 217 218 /* Finally add it to the appropriate iodev list. */ 219 if (direction == CRAS_STREAM_INPUT) { 220 snprintf(iodev->info.name, 221 ARRAY_SIZE(iodev->info.name), 222 "Silent record device."); 223 iodev->info.name[ARRAY_SIZE(iodev->info.name) - 1] = '\0'; 224 iodev->info.idx = SILENT_RECORD_DEVICE; 225 } else { 226 snprintf(iodev->info.name, 227 ARRAY_SIZE(iodev->info.name), 228 "Silent playback device."); 229 iodev->info.name[ARRAY_SIZE(iodev->info.name) - 1] = '\0'; 230 iodev->info.idx = SILENT_PLAYBACK_DEVICE; 231 } 232 233 return iodev; 234 } 235 236 void empty_iodev_destroy(struct cras_iodev *iodev) 237 { 238 struct empty_iodev *empty_iodev = (struct empty_iodev *)iodev; 239 240 if (iodev->direction == CRAS_STREAM_INPUT) 241 cras_iodev_list_rm_input(iodev); 242 else 243 cras_iodev_list_rm_output(iodev); 244 free(iodev->active_node); 245 cras_iodev_free_resources(iodev); 246 free(empty_iodev); 247 } 248