Changeset 3e6a975a in mainline for uspace/app/wavplay/dplay.c
- Timestamp:
- 2013-03-16T14:18:26Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 1bd99785
- Parents:
- 7ed6ee2
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/wavplay/dplay.c
r7ed6ee2 r3e6a975a 58 58 void *base; 59 59 size_t size; 60 void* position;60 void* write_ptr; 61 61 } buffer; 62 62 pcm_format_t f; … … 74 74 pb->buffer.base = NULL; 75 75 pb->buffer.size = 0; 76 pb->buffer. position= NULL;76 pb->buffer.write_ptr = NULL; 77 77 pb->playing = false; 78 78 pb->source = NULL; … … 111 111 112 112 } 113 const size_t bytes = fread(pb->buffer. position, sizeof(uint8_t),114 fragment_size, pb->source);113 const size_t bytes = fread(pb->buffer.write_ptr, 114 sizeof(uint8_t), fragment_size, pb->source); 115 115 printf("Copied from position %p size %zu/%zu\n", 116 pb->buffer. position, bytes, fragment_size);116 pb->buffer.write_ptr, bytes, fragment_size); 117 117 if (bytes == 0) { 118 118 audio_pcm_last_playback_fragment(pb->device); 119 119 } 120 bzero(pb->buffer.position + bytes, fragment_size - bytes); 121 pb->buffer.position += fragment_size; 122 123 if (pb->buffer.position >= (pb->buffer.base + pb->buffer.size)) 124 pb->buffer.position -= pb->buffer.size; 120 /* any constant is silence */ 121 bzero(pb->buffer.write_ptr + bytes, fragment_size - bytes); 122 pb->buffer.write_ptr += fragment_size; 123 124 if (pb->buffer.write_ptr >= (pb->buffer.base + pb->buffer.size)) 125 pb->buffer.write_ptr -= pb->buffer.size; 125 126 } 126 127 } … … 146 147 printf("Initial: Copied from position %p size %zu/%zu\n", 147 148 pb->buffer.base, bytes, fragment_size); 148 pb->buffer. position= pb->buffer.base + fragment_size;149 pb->buffer.write_ptr = pb->buffer.base + fragment_size; 149 150 fibril_mutex_lock(&pb->mutex); 150 const unsigned frames = pcm_format_size_to_frames(fragment_size, &pb->f); 151 const unsigned frames = 152 pcm_format_size_to_frames(fragment_size, &pb->f); 151 153 ret = audio_pcm_start_playback_fragment(pb->device, frames, 152 154 pb->f.channels, pb->f.sampling_rate, pb->f.sample_format); … … 166 168 } 167 169 170 static size_t buffer_occupied(const playback_t *pb, size_t pos) 171 { 172 assert(pb); 173 void *read_ptr = pb->buffer.base + pos; 174 if (read_ptr > pb->buffer.write_ptr) 175 return pb->buffer.write_ptr + pb->buffer.size - read_ptr; 176 return pb->buffer.write_ptr - read_ptr; 177 178 } 179 180 static size_t buffer_avail(const playback_t *pb, size_t pos) 181 { 182 assert(pb); 183 void *read_ptr = pb->buffer.base + pos; 184 if (read_ptr <= pb->buffer.write_ptr) 185 return read_ptr + pb->buffer.size - pb->buffer.write_ptr - 1; 186 return (read_ptr - pb->buffer.write_ptr) - 1; 187 } 188 189 static size_t buffer_remain(const playback_t *pb) 190 { 191 assert(pb); 192 return (pb->buffer.base + pb->buffer.size) - pb->buffer.write_ptr; 193 } 194 195 static void buffer_advance(playback_t *pb, size_t bytes) 196 { 197 assert(pb); 198 pb->buffer.write_ptr += bytes; 199 while (pb->buffer.write_ptr >= (pb->buffer.base + pb->buffer.size)) 200 pb->buffer.write_ptr -= pb->buffer.size; 201 } 202 203 168 204 static void play(playback_t *pb) 169 205 { 170 206 assert(pb); 171 207 assert(pb->device); 172 pb->buffer. position= pb->buffer.base;208 pb->buffer.write_ptr = pb->buffer.base; 173 209 printf("Playing: %dHz, %s, %d channel(s).\n", pb->f.sampling_rate, 174 210 pcm_sample_format_str(pb->f.sample_format), pb->f.channels); 175 static useconds_t work_time = 8000; /* 8 ms */ 176 size_t bytes = fread(pb->buffer.position, sizeof(uint8_t), 177 pb->buffer.size, pb->source); 178 if (bytes == 0) 179 return; 180 audio_pcm_start_playback(pb->device, 181 pb->f.channels, pb->f.sampling_rate, pb->f.sample_format); 211 useconds_t work_time = 50000; /* 10 ms */ 212 bool started = false; 213 size_t pos = 0; 182 214 do { 183 size_t pos = 0; 184 audio_pcm_get_buffer_pos(pb->device, &pos); 185 size_t to_play = bytes - pos; 186 useconds_t usecs = (bytes > pos) ? 187 pcm_format_size_to_usec(to_play, &pb->f) : 0; 188 189 pb->buffer.position += bytes; 190 191 printf("%u usecs to play %zu bytes from pos %zu.\n", 192 usecs, to_play, pos); 193 if (usecs > work_time) { 194 async_usleep(usecs - work_time); 195 audio_pcm_get_buffer_pos(pb->device, &pos); 196 // printf("Woke up at position %zu/%zu.\n", 197 // pos, pb->buffer.size); 198 } 199 200 /* Remove any overflow */ 201 while (pb->buffer.position >= pb->buffer.base + pb->buffer.size) 202 pb->buffer.position -= pb->buffer.size; 203 204 if (bytes < pb->buffer.size) { 205 const size_t remain = pb->buffer.size - 206 (pb->buffer.position - pb->buffer.base); 207 /* This was the last part, 208 * zero 200 bytes or until the end of buffer. */ 209 bzero(pb->buffer.position, min(1024, remain)); 210 if ((pb->buffer.base + pos) > pb->buffer.position) { 211 printf("Overflow: %zu vs. %zu!\n", 212 pos, pb->buffer.position - pb->buffer.base); 213 } else { 214 udelay(pcm_format_size_to_usec( 215 pb->buffer.position - pb->buffer.base - pos, 216 &pb->f)); 217 audio_pcm_get_buffer_pos(pb->device, &pos); 215 size_t available = buffer_avail(pb, pos); 216 /* Writing might need wrap around the end */ 217 size_t bytes = fread(pb->buffer.write_ptr, sizeof(uint8_t), 218 min(available, buffer_remain(pb)), pb->source); 219 buffer_advance(pb, bytes); 220 printf("POS %zu: %zu bytes free in buffer, read %zu, wp %zu\n", 221 pos, available, bytes, pb->buffer.write_ptr - pb->buffer.base); 222 available -= bytes; 223 if (available) { 224 bytes = fread(pb->buffer.write_ptr, 225 sizeof(uint8_t), min(available, buffer_remain(pb)), 226 pb->source); 227 buffer_advance(pb, bytes); 228 printf("POS %zu: %zu bytes still free in buffer, read %zu, wp %zu\n", 229 pos, available, bytes, pb->buffer.write_ptr - pb->buffer.base); 230 available -= bytes; 231 } 232 233 if (!started) { 234 const int ret = audio_pcm_start_playback(pb->device, 235 pb->f.channels, pb->f.sampling_rate, 236 pb->f.sample_format); 237 if (ret != EOK) { 238 printf("Failed to start playback\n"); 239 return; 218 240 } 219 printf("Stopped at %zu(%zu)/%zu\n", 220 pos, pb->buffer.position - pb->buffer.base, 221 pb->buffer.size); 241 started = true; 242 } 243 const size_t to_play = buffer_occupied(pb, pos); 244 const useconds_t usecs = 245 pcm_format_size_to_usec(to_play, &pb->f); 246 247 const useconds_t real_delay = (usecs > work_time) 248 ? usecs - work_time : 0; 249 printf("POS %zu: %u usecs (%u) to play %zu bytes.\n", 250 pos, usecs, real_delay, to_play); 251 if (real_delay) 252 async_usleep(real_delay); 253 const int ret = audio_pcm_get_buffer_pos(pb->device, &pos); 254 if (ret != EOK) { 255 printf("Failed to update position indicator\n"); 256 } 257 if (available) 222 258 break; 223 } 224 /* copy first half */ 225 bytes = fread(pb->buffer.position, sizeof(uint8_t), 226 pb->buffer.size / 2, pb->source); 227 if (bytes == 0) 228 break; 229 audio_pcm_get_buffer_pos(pb->device, &pos); 230 printf("Half buffer copied at pos %zu ", pos); 231 /* Wait until the rest of the buffer is ready */ 232 udelay(pcm_format_size_to_usec(pb->buffer.size - pos, &pb->f)); 233 /* copy the other part of the buffer */ 234 if (bytes == (pb->buffer.size / 2)) { 235 bytes += fread(pb->buffer.position + bytes, 236 sizeof(uint8_t), pb->buffer.size / 2, pb->source); 237 audio_pcm_get_buffer_pos(pb->device, &pos); 238 printf("the other half copied at pos %zu\n", pos); 239 } 259 240 260 } while (1); 241 261 audio_pcm_stop_playback(pb->device); … … 277 297 } 278 298 printf("Buffer: %p %zu.\n", pb.buffer.base, pb.buffer.size); 279 uintptr_t ptr = 0; 280 as_get_physical_mapping(pb.buffer.base, &ptr); 281 printf("buffer mapped at %x.\n", ptr); 299 300 { 301 uintptr_t ptr = 0; 302 as_get_physical_mapping(pb.buffer.base, &ptr); 303 printf("buffer mapped at %x.\n", ptr); 304 } 282 305 283 306 pb.source = fopen(file, "rb"); 284 307 if (pb.source == NULL) { 285 308 ret = ENOENT; 286 printf("Failed to open %s.\n", file);309 printf("Failed to open file: %s.\n", file); 287 310 goto cleanup; 288 311 } 312 289 313 wave_header_t header; 290 314 fread(&header, sizeof(header), 1, pb.source); … … 294 318 if (ret != EOK) { 295 319 printf("Error parsing wav header: %s.\n", error); 296 fclose(pb.source);297 320 goto cleanup; 298 321 }
Note:
See TracChangeset
for help on using the changeset viewer.