Changeset a8e87da in mainline


Ignore:
Timestamp:
2013-04-10T18:49:43Z (11 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
b1dfe13
Parents:
76e863c
Message:

wavplay: comments

Location:
uspace/app/wavplay
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/wavplay/dplay.c

    r76e863c ra8e87da  
    5252#define DEFAULT_FRAGMENTS 2
    5353
     54/** Playback helper structure */
    5455typedef struct {
    5556        struct {
     
    6667} playback_t;
    6768
     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 */
    6875static void playback_initialize(playback_t *pb, audio_pcm_sess_t *sess)
    6976{
     
    8087}
    8188
    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 */
    8395static void device_event_callback(ipc_callid_t iid, ipc_call_t *icall, void* arg)
    8496{
     
    125137}
    126138
     139/**
     140 * Start event based playback.
     141 * @param pb Playback helper structure.
     142 */
    127143static void play_fragment(playback_t *pb)
    128144{
     
    166182}
    167183
     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 */
    168190static size_t buffer_occupied(const playback_t *pb, size_t pos)
    169191{
     
    176198}
    177199
     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 */
    178206static size_t buffer_avail(const playback_t *pb, size_t pos)
    179207{
     
    185213}
    186214
     215/**
     216 * Size of the space between write pointer and the end of a cyclic buffer
     217 * @param pb Playback helper structure.
     218 */
    187219static size_t buffer_remain(const playback_t *pb)
    188220{
     
    191223}
    192224
     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 */
    193230static void buffer_advance(playback_t *pb, size_t bytes)
    194231{
     
    202239        printf("%.2lu:%.6lu   "f, time.tv_sec % 100, time.tv_usec, __VA_ARGS__)
    203240
    204 
     241/**
     242 * Start playback using buffer position api.
     243 * @param pb Playback helper function.
     244 */
    205245static void play(playback_t *pb)
    206246{
     
    217257        do {
    218258                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 */
    220261                size_t bytes = fread(pb->buffer.write_ptr, sizeof(uint8_t),
    221262                    min(available, buffer_remain(pb)), pb->source);
     
    225266                    pb->buffer.write_ptr - pb->buffer.base);
    226267                available -= bytes;
     268
     269                /* continue if we wrapped around the end */
    227270                if (available) {
    228271                        bytes = fread(pb->buffer.write_ptr,
     
    254297                    pcm_format_size_to_usec(to_play, &pb->f);
    255298
     299                /* Compute delay time */
    256300                const useconds_t real_delay = (usecs > work_time)
    257301                    ? usecs - work_time : 0;
     
    260304                if (real_delay)
    261305                        async_usleep(real_delay);
     306                /* update buffer position */
    262307                const int ret = audio_pcm_get_buffer_pos(pb->device, &pos);
    263308                if (ret != EOK) {
     
    265310                }
    266311                getuptime(&time);
     312
     313                /* we did not use all the space we had,
     314                 * that is the end */
    267315                if (available)
    268316                        break;
     
    272320}
    273321
     322/**
     323 * Play audio file usign direct device access.
     324 * @param device The device.
     325 * @param file The file.
     326 * @return Error code.
     327 */
    274328int dplay(const char *device, const char *file)
    275329{
  • uspace/app/wavplay/main.c

    r76e863c ra8e87da  
    5151#define STREAM_BUFFER_SIZE   (64 * 1024)
    5252
     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 */
    5359static int hplay_ctx(hound_context_t *ctx, const char *filename)
    5460{
     
    5965                return EINVAL;
    6066        }
     67
     68        /* Read and parse WAV header */
    6169        wave_header_t header;
    6270        size_t read = fread(&header, sizeof(header), 1, source);
     
    7684        }
    7785
     86        /* Allocate buffer and create new context */
     87        char * buffer = malloc(READ_SIZE);
     88        if (!buffer) {
     89                fclose(source);
     90                return ENOMEM;
     91        }
    7892        hound_stream_t *stream = hound_stream_create(ctx,
    7993            HOUND_STREAM_DRAIN_ON_EXIT, format, STREAM_BUFFER_SIZE);
    8094
    81         char * buffer = malloc(READ_SIZE);
    82         if (!buffer) {
    83                 fclose(source);
    84                 return ENOMEM;
    85         }
     95        /* Read and play */
    8696        while ((read = fread(buffer, sizeof(char), READ_SIZE, source)) > 0) {
    8797                ret = hound_stream_write(stream, buffer, read);
     
    92102                }
    93103        }
     104
     105        /* Cleanup */
    94106        free(buffer);
    95107        fclose(source);
     
    97109}
    98110
     111/**
     112 * Play audio file via hound server.
     113 * @param filename File to play.
     114 * @return Error code
     115 */
    99116static int hplay(const char *filename)
    100117{
     
    105122                return EINVAL;
    106123        }
     124
     125        /* Read and parse WAV header */
    107126        wave_header_t header;
    108127        size_t read = fread(&header, sizeof(header), 1, source);
     
    121140                return EINVAL;
    122141        }
     142
     143        /* Connect new playback context */
    123144        hound_context_t *hound = hound_context_create_playback(filename,
    124145            format, STREAM_BUFFER_SIZE);
     
    137158                return ret;
    138159        }
     160
     161        /* Read and play */
    139162        static char buffer[READ_SIZE];
    140163        while ((read = fread(buffer, sizeof(char), READ_SIZE, source)) > 0) {
     
    146169                }
    147170        }
     171
     172        /* Cleanup */
    148173        hound_context_destroy(hound);
    149174        fclose(source);
     
    151176}
    152177
     178/**
     179 * Helper structure for playback in separate fibrils
     180 */
    153181typedef struct {
    154182        hound_context_t *ctx;
     
    157185} fib_play_t;
    158186
     187/**
     188 * Fibril playback wrapper.
     189 * @param arg Argument, pointer to playback helper structure.
     190 * @return Error code.
     191 */
    159192static int play_wrapper(void *arg)
    160193{
     
    167200}
    168201
     202/**
     203 * Array of supported commandline options
     204 */
    169205static const struct option opts[] = {
    170206        {"device", required_argument, 0, 'd'},
     
    175211};
    176212
     213/**
     214 * Print usage help.
     215 * @param name Name of the program.
     216 */
    177217static void print_help(const char* name)
    178218{
     
    195235        optind = 0;
    196236        int ret = 0;
     237
     238        /* Parse command line options */
    197239        while (ret != -1) {
    198240                ret = getopt_long(argc, argv, "d:prh", opts, &idx);
     
    227269        }
    228270
     271        /* Init parallel playback variables */
    229272        hound_context_t *hound_ctx = NULL;
    230273        atomic_t playcount;
    231274        atomic_set(&playcount, 0);
     275
     276        /* Init parallel playback context if necessary */
    232277        if (parallel) {
    233278                hound_ctx = hound_context_create_playback("wavplay",
     
    247292        }
    248293
     294        /* play or record all files */
    249295        for (int i = optind; i < argc; ++i) {
    250296                const char *file = argv[i];
     
    261307                        }
    262308                }
     309
    263310                if (direct) {
    264311                        dplay(device, file);
    265312                } else {
    266313                        if (parallel) {
     314                                /* Start new fibril for parallel playback */
    267315                                fib_play_t *data = malloc(sizeof(fib_play_t));
    268316                                if (!data) {
     
    283331        }
    284332
     333        /* Wait for all fibrils to finish */
    285334        while (atomic_get(&playcount) > 0)
    286335                async_usleep(1000000);
    287336
     337        /* Destroy parallel playback context, if initialized */
    288338        if (hound_ctx)
    289339                hound_context_destroy(hound_ctx);
Note: See TracChangeset for help on using the changeset viewer.