Changeset a8e87da in mainline
- Timestamp:
- 2013-04-10T18:49:43Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- b1dfe13
- Parents:
- 76e863c
- Location:
- uspace/app/wavplay
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/wavplay/dplay.c
r76e863c ra8e87da 52 52 #define DEFAULT_FRAGMENTS 2 53 53 54 /** Playback helper structure */ 54 55 typedef struct { 55 56 struct { … … 66 67 } playback_t; 67 68 69 /** 70 * Initialize playback helper structure. 71 * @param pb Pointer to helper structure to initialize 72 * @param sess Pointer to audio device IPC session 73 * @return 74 */ 68 75 static void playback_initialize(playback_t *pb, audio_pcm_sess_t *sess) 69 76 { … … 80 87 } 81 88 82 89 /** 90 * Fragment playback callback function. 91 * @param iid IPC call id. 92 * @param icall Pointer to the call structure 93 * @param arg Argument, pointer to the playback helper function 94 */ 83 95 static void device_event_callback(ipc_callid_t iid, ipc_call_t *icall, void* arg) 84 96 { … … 125 137 } 126 138 139 /** 140 * Start event based playback. 141 * @param pb Playback helper structure. 142 */ 127 143 static void play_fragment(playback_t *pb) 128 144 { … … 166 182 } 167 183 184 /** 185 * Count occupied space in a cyclic buffer. 186 * @param pb Playback helper structure. 187 * @param pos read pointer position. 188 * @return Occupied space size. 189 */ 168 190 static size_t buffer_occupied(const playback_t *pb, size_t pos) 169 191 { … … 176 198 } 177 199 200 /** 201 * Count available space in a cyclic buffer. 202 * @param pb Playback helper structure. 203 * @param pos read pointer position. 204 * @return Free space size. 205 */ 178 206 static size_t buffer_avail(const playback_t *pb, size_t pos) 179 207 { … … 185 213 } 186 214 215 /** 216 * Size of the space between write pointer and the end of a cyclic buffer 217 * @param pb Playback helper structure. 218 */ 187 219 static size_t buffer_remain(const playback_t *pb) 188 220 { … … 191 223 } 192 224 225 /** 226 * Move write pointer forward. Wrap around the end. 227 * @param pb Playback helper structure. 228 * @param bytes NUmber of bytes to advance. 229 */ 193 230 static void buffer_advance(playback_t *pb, size_t bytes) 194 231 { … … 202 239 printf("%.2lu:%.6lu "f, time.tv_sec % 100, time.tv_usec, __VA_ARGS__) 203 240 204 241 /** 242 * Start playback using buffer position api. 243 * @param pb Playback helper function. 244 */ 205 245 static void play(playback_t *pb) 206 246 { … … 217 257 do { 218 258 size_t available = buffer_avail(pb, pos); 219 /* Writing might need wrap around the end */ 259 /* Writing might need wrap around the end, 260 * read directly to device buffer */ 220 261 size_t bytes = fread(pb->buffer.write_ptr, sizeof(uint8_t), 221 262 min(available, buffer_remain(pb)), pb->source); … … 225 266 pb->buffer.write_ptr - pb->buffer.base); 226 267 available -= bytes; 268 269 /* continue if we wrapped around the end */ 227 270 if (available) { 228 271 bytes = fread(pb->buffer.write_ptr, … … 254 297 pcm_format_size_to_usec(to_play, &pb->f); 255 298 299 /* Compute delay time */ 256 300 const useconds_t real_delay = (usecs > work_time) 257 301 ? usecs - work_time : 0; … … 260 304 if (real_delay) 261 305 async_usleep(real_delay); 306 /* update buffer position */ 262 307 const int ret = audio_pcm_get_buffer_pos(pb->device, &pos); 263 308 if (ret != EOK) { … … 265 310 } 266 311 getuptime(&time); 312 313 /* we did not use all the space we had, 314 * that is the end */ 267 315 if (available) 268 316 break; … … 272 320 } 273 321 322 /** 323 * Play audio file usign direct device access. 324 * @param device The device. 325 * @param file The file. 326 * @return Error code. 327 */ 274 328 int dplay(const char *device, const char *file) 275 329 { -
uspace/app/wavplay/main.c
r76e863c ra8e87da 51 51 #define STREAM_BUFFER_SIZE (64 * 1024) 52 52 53 /** 54 * Play audio file using a new stream on provided context. 55 * @param ctx Provided context. 56 * @param filename File to play. 57 * @return Error code. 58 */ 53 59 static int hplay_ctx(hound_context_t *ctx, const char *filename) 54 60 { … … 59 65 return EINVAL; 60 66 } 67 68 /* Read and parse WAV header */ 61 69 wave_header_t header; 62 70 size_t read = fread(&header, sizeof(header), 1, source); … … 76 84 } 77 85 86 /* Allocate buffer and create new context */ 87 char * buffer = malloc(READ_SIZE); 88 if (!buffer) { 89 fclose(source); 90 return ENOMEM; 91 } 78 92 hound_stream_t *stream = hound_stream_create(ctx, 79 93 HOUND_STREAM_DRAIN_ON_EXIT, format, STREAM_BUFFER_SIZE); 80 94 81 char * buffer = malloc(READ_SIZE); 82 if (!buffer) { 83 fclose(source); 84 return ENOMEM; 85 } 95 /* Read and play */ 86 96 while ((read = fread(buffer, sizeof(char), READ_SIZE, source)) > 0) { 87 97 ret = hound_stream_write(stream, buffer, read); … … 92 102 } 93 103 } 104 105 /* Cleanup */ 94 106 free(buffer); 95 107 fclose(source); … … 97 109 } 98 110 111 /** 112 * Play audio file via hound server. 113 * @param filename File to play. 114 * @return Error code 115 */ 99 116 static int hplay(const char *filename) 100 117 { … … 105 122 return EINVAL; 106 123 } 124 125 /* Read and parse WAV header */ 107 126 wave_header_t header; 108 127 size_t read = fread(&header, sizeof(header), 1, source); … … 121 140 return EINVAL; 122 141 } 142 143 /* Connect new playback context */ 123 144 hound_context_t *hound = hound_context_create_playback(filename, 124 145 format, STREAM_BUFFER_SIZE); … … 137 158 return ret; 138 159 } 160 161 /* Read and play */ 139 162 static char buffer[READ_SIZE]; 140 163 while ((read = fread(buffer, sizeof(char), READ_SIZE, source)) > 0) { … … 146 169 } 147 170 } 171 172 /* Cleanup */ 148 173 hound_context_destroy(hound); 149 174 fclose(source); … … 151 176 } 152 177 178 /** 179 * Helper structure for playback in separate fibrils 180 */ 153 181 typedef struct { 154 182 hound_context_t *ctx; … … 157 185 } fib_play_t; 158 186 187 /** 188 * Fibril playback wrapper. 189 * @param arg Argument, pointer to playback helper structure. 190 * @return Error code. 191 */ 159 192 static int play_wrapper(void *arg) 160 193 { … … 167 200 } 168 201 202 /** 203 * Array of supported commandline options 204 */ 169 205 static const struct option opts[] = { 170 206 {"device", required_argument, 0, 'd'}, … … 175 211 }; 176 212 213 /** 214 * Print usage help. 215 * @param name Name of the program. 216 */ 177 217 static void print_help(const char* name) 178 218 { … … 195 235 optind = 0; 196 236 int ret = 0; 237 238 /* Parse command line options */ 197 239 while (ret != -1) { 198 240 ret = getopt_long(argc, argv, "d:prh", opts, &idx); … … 227 269 } 228 270 271 /* Init parallel playback variables */ 229 272 hound_context_t *hound_ctx = NULL; 230 273 atomic_t playcount; 231 274 atomic_set(&playcount, 0); 275 276 /* Init parallel playback context if necessary */ 232 277 if (parallel) { 233 278 hound_ctx = hound_context_create_playback("wavplay", … … 247 292 } 248 293 294 /* play or record all files */ 249 295 for (int i = optind; i < argc; ++i) { 250 296 const char *file = argv[i]; … … 261 307 } 262 308 } 309 263 310 if (direct) { 264 311 dplay(device, file); 265 312 } else { 266 313 if (parallel) { 314 /* Start new fibril for parallel playback */ 267 315 fib_play_t *data = malloc(sizeof(fib_play_t)); 268 316 if (!data) { … … 283 331 } 284 332 333 /* Wait for all fibrils to finish */ 285 334 while (atomic_get(&playcount) > 0) 286 335 async_usleep(1000000); 287 336 337 /* Destroy parallel playback context, if initialized */ 288 338 if (hound_ctx) 289 339 hound_context_destroy(hound_ctx);
Note:
See TracChangeset
for help on using the changeset viewer.