Changeset 0e4c5f0 in mainline for uspace/drv/audio/hdaudio/pcm_iface.c


Ignore:
Timestamp:
2015-03-18T18:34:40Z (9 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ac235711
Parents:
795e2bf
Message:

hdaudio capture support. wavplay fixes to recording code.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/audio/hdaudio/pcm_iface.c

    r795e2bf r0e4c5f0  
    100100static unsigned hda_query_cap(ddf_fun_t *fun, audio_cap_t cap)
    101101{
     102        hda_t *hda = fun_to_hda(fun);
     103
    102104        ddf_msg(LVL_NOTE, "hda_query_cap(%d)", cap);
    103105        switch (cap) {
    104106        case AUDIO_CAP_PLAYBACK:
    105107        case AUDIO_CAP_INTERRUPT:
     108                /* XXX Only if we have an output converter */
    106109                return 1;
     110        case AUDIO_CAP_CAPTURE:
     111                /* Yes if we have an input converter */
     112                return hda->ctl->codec->in_aw >= 0;
    107113        case AUDIO_CAP_BUFFER_POS:
    108         case AUDIO_CAP_CAPTURE:
    109114                return 0;
    110115        case AUDIO_CAP_MAX_BUFFER:
     
    148153{
    149154        hda_t *hda = fun_to_hda(fun);
     155        int rc;
    150156
    151157        hda_lock(hda);
    152158
    153159        ddf_msg(LVL_NOTE, "hda_get_buffer(): hda=%p", hda);
     160        if (hda->pcm_buffers != NULL) {
     161                hda_unlock(hda);
     162                return EBUSY;
     163        }
     164
     165        ddf_msg(LVL_NOTE, "hda_get_buffer() - allocate stream buffers");
     166        rc = hda_stream_buffers_alloc(hda, &hda->pcm_buffers);
     167        if (rc != EOK) {
     168                assert(rc == ENOMEM);
     169                hda_unlock(hda);
     170                return ENOMEM;
     171        }
     172
     173        ddf_msg(LVL_NOTE, "hda_get_buffer() - fill info");
     174        /* XXX This is only one buffer */
     175        *buffer = hda->pcm_buffers->buf[0];
     176        *size = hda->pcm_buffers->bufsize * hda->pcm_buffers->nbuffers;
     177
     178        ddf_msg(LVL_NOTE, "hda_get_buffer() returing EOK, buffer=%p, size=%zu",
     179            *buffer, *size);
     180
     181        hda_unlock(hda);
     182        return EOK;
     183}
     184
     185static int hda_get_buffer_position(ddf_fun_t *fun, size_t *pos)
     186{
     187        ddf_msg(LVL_NOTE, "hda_get_buffer_position()");
     188        return ENOTSUP;
     189}
     190
     191static int hda_set_event_session(ddf_fun_t *fun, async_sess_t *sess)
     192{
     193        hda_t *hda = fun_to_hda(fun);
     194
     195        ddf_msg(LVL_NOTE, "hda_set_event_session()");
     196        hda_lock(hda);
     197        hda->ev_sess = sess;
     198        hda_unlock(hda);
     199
     200        return EOK;
     201}
     202
     203static async_sess_t *hda_get_event_session(ddf_fun_t *fun)
     204{
     205        hda_t *hda = fun_to_hda(fun);
     206        async_sess_t *sess;
     207
     208        ddf_msg(LVL_NOTE, "hda_get_event_session()");
     209
     210        hda_lock(hda);
     211        sess = hda->ev_sess;
     212        hda_unlock(hda);
     213
     214        return sess;
     215}
     216
     217static int hda_release_buffer(ddf_fun_t *fun)
     218{
     219        hda_t *hda = fun_to_hda(fun);
     220
     221        hda_lock(hda);
     222
     223        ddf_msg(LVL_NOTE, "hda_release_buffer()");
     224        if (hda->pcm_buffers == NULL) {
     225                hda_unlock(hda);
     226                return EINVAL;
     227        }
     228
     229        hda_stream_buffers_free(hda->pcm_buffers);
     230
     231        hda_unlock(hda);
     232        return EOK;
     233}
     234
     235static int hda_start_playback(ddf_fun_t *fun, unsigned frames,
     236    unsigned channels, unsigned rate, pcm_sample_format_t format)
     237{
     238        hda_t *hda = fun_to_hda(fun);
     239        int rc;
     240
     241        ddf_msg(LVL_NOTE, "hda_start_playback()");
     242        hda_lock(hda);
     243
    154244        if (hda->pcm_stream != NULL) {
    155245                hda_unlock(hda);
     
    162252        fmt = (fmt_base_44khz << fmt_base) | (fmt_bits_16 << fmt_bits_l) | 1;
    163253
    164         ddf_msg(LVL_NOTE, "hda_get_buffer() - create stream");
    165         hda->pcm_stream = hda_stream_create(hda, sdir_output, fmt);
     254        ddf_msg(LVL_NOTE, "hda_start_playback() - create output stream");
     255        hda->pcm_stream = hda_stream_create(hda, sdir_output, hda->pcm_buffers,
     256            fmt);
    166257        if (hda->pcm_stream == NULL) {
    167258                hda_unlock(hda);
    168259                return EIO;
    169260        }
    170 
    171         ddf_msg(LVL_NOTE, "hda_get_buffer() - fill info");
    172         /* XXX This is only one buffer */
    173         *buffer = hda->pcm_stream->buf[0];
    174         *size = hda->pcm_stream->bufsize * hda->pcm_stream->nbuffers;
    175 
    176         ddf_msg(LVL_NOTE, "hda_get_buffer() retturing EOK, buffer=%p, size=%zu",
    177             *buffer, *size);
    178 
    179         hda_unlock(hda);
    180         return EOK;
    181 }
    182 
    183 static int hda_get_buffer_position(ddf_fun_t *fun, size_t *pos)
    184 {
    185         ddf_msg(LVL_NOTE, "hda_get_buffer_position()");
    186         return ENOTSUP;
    187 }
    188 
    189 static int hda_set_event_session(ddf_fun_t *fun, async_sess_t *sess)
    190 {
    191         hda_t *hda = fun_to_hda(fun);
    192 
    193         ddf_msg(LVL_NOTE, "hda_set_event_session()");
    194         hda_lock(hda);
    195         hda->ev_sess = sess;
    196         hda_unlock(hda);
    197 
    198         return EOK;
    199 }
    200 
    201 static async_sess_t *hda_get_event_session(ddf_fun_t *fun)
    202 {
    203         hda_t *hda = fun_to_hda(fun);
    204         async_sess_t *sess;
    205 
    206         ddf_msg(LVL_NOTE, "hda_get_event_session()");
    207 
    208         hda_lock(hda);
    209         sess = hda->ev_sess;
    210         hda_unlock(hda);
    211 
    212         return sess;
    213 }
    214 
    215 static int hda_release_buffer(ddf_fun_t *fun)
    216 {
    217         hda_t *hda = fun_to_hda(fun);
    218 
    219         hda_lock(hda);
    220 
    221         ddf_msg(LVL_NOTE, "hda_release_buffer()");
    222         if (hda->pcm_stream == NULL) {
    223                 hda_unlock(hda);
    224                 return EINVAL;
    225         }
    226 
    227         hda_stream_destroy(hda->pcm_stream);
    228         hda->pcm_stream = NULL;
    229 
    230         hda_unlock(hda);
    231         return EOK;
    232 }
    233 
    234 static int hda_start_playback(ddf_fun_t *fun, unsigned frames,
    235     unsigned channels, unsigned rate, pcm_sample_format_t format)
    236 {
    237         hda_t *hda = fun_to_hda(fun);
    238         int rc;
    239 
    240         ddf_msg(LVL_NOTE, "hda_start_playback()");
    241         hda_lock(hda);
    242261
    243262        rc = hda_out_converter_setup(hda->ctl->codec, hda->pcm_stream);
    244263        if (rc != EOK) {
     264                hda_stream_destroy(hda->pcm_stream);
     265                hda->pcm_stream = NULL;
    245266                hda_unlock(hda);
    246267                return rc;
    247268        }
    248269
     270        hda->playing = true;
    249271        hda_stream_start(hda->pcm_stream);
    250         hda->playing = true;
    251272        hda_unlock(hda);
    252273        return EOK;
     
    262283        hda_stream_reset(hda->pcm_stream);
    263284        hda->playing = false;
     285        hda_stream_destroy(hda->pcm_stream);
     286        hda->pcm_stream = NULL;
     287
    264288        hda_unlock(hda);
    265289
     
    271295    unsigned rate, pcm_sample_format_t format)
    272296{
     297        hda_t *hda = fun_to_hda(fun);
     298        int rc;
     299
    273300        ddf_msg(LVL_NOTE, "hda_start_capture()");
    274         return ENOTSUP;
     301        hda_lock(hda);
     302
     303        if (hda->pcm_stream != NULL) {
     304                hda_unlock(hda);
     305                return EBUSY;
     306        }
     307
     308        /* XXX Choose appropriate parameters */
     309        uint32_t fmt;
     310        /* 48 kHz, 16-bits, 1 channel */
     311        fmt = (fmt_base_44khz << fmt_base) | (fmt_bits_16 << fmt_bits_l) | 1;
     312
     313        ddf_msg(LVL_NOTE, "hda_start_capture() - create input stream");
     314        hda->pcm_stream = hda_stream_create(hda, sdir_input, hda->pcm_buffers,
     315            fmt);
     316        if (hda->pcm_stream == NULL) {
     317                hda_unlock(hda);
     318                return EIO;
     319        }
     320
     321        rc = hda_in_converter_setup(hda->ctl->codec, hda->pcm_stream);
     322        if (rc != EOK) {
     323                hda_stream_destroy(hda->pcm_stream);
     324                hda->pcm_stream = NULL;
     325                hda_unlock(hda);
     326                return rc;
     327        }
     328
     329        hda->capturing = true;
     330        hda_stream_start(hda->pcm_stream);
     331        hda_unlock(hda);
     332        return EOK;
    275333}
    276334
    277335static int hda_stop_capture(ddf_fun_t *fun, bool immediate)
    278336{
     337        hda_t *hda = fun_to_hda(fun);
     338
    279339        ddf_msg(LVL_NOTE, "hda_stop_capture()");
    280         return ENOTSUP;
     340        hda_lock(hda);
     341        hda_stream_stop(hda->pcm_stream);
     342        hda_stream_reset(hda->pcm_stream);
     343        hda->capturing = false;
     344        hda_stream_destroy(hda->pcm_stream);
     345        hda->pcm_stream = NULL;
     346        hda_unlock(hda);
     347
     348        hda_pcm_event(hda, PCM_EVENT_CAPTURE_TERMINATED);
     349        return EOK;
    281350}
    282351
Note: See TracChangeset for help on using the changeset viewer.