Changeset 018ab50 in mainline


Ignore:
Timestamp:
2012-08-20T11:28:46Z (12 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
fb6c98f
Parents:
20840922
Message:

audio: Move event callback into separate API calls.

Location:
uspace
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/drec/drec.c

    r20840922 r018ab50  
    173173
    174174        ret = audio_pcm_get_buffer(rec.device, &rec.buffer.base,
    175             &rec.buffer.size, device_event_callback, &rec);
     175            &rec.buffer.size);
    176176        if (ret != EOK) {
    177177                printf("Failed to get PCM buffer: %s.\n", str_error(ret));
    178178                goto close_session;
     179        }
     180        ret = audio_pcm_register_event_callback(rec.device,
     181            device_event_callback, &rec);
     182        if (ret != EOK) {
     183                printf("Failed to register for events: %s.\n", str_error(ret));
     184                goto cleanup;
    179185        }
    180186        printf("Buffer: %p %zu.\n", rec.buffer.base, rec.buffer.size);
     
    209215        munmap(rec.buffer.base, rec.buffer.size);
    210216        audio_pcm_release_buffer(rec.device);
     217        audio_pcm_unregister_event_callback(rec.device);
    211218close_session:
    212219        async_hangup(session);
  • uspace/app/wavplay/dplay.c

    r20840922 r018ab50  
    123123
    124124
    125 static void play(playback_t *pb, unsigned channels,  unsigned sampling_rate,
     125static void play(playback_t *pb, unsigned channels, unsigned sampling_rate,
    126126    pcm_sample_format_t format)
    127127{
     
    129129        assert(pb->device);
    130130        pb->buffer.position = pb->buffer.base;
     131        printf("Registering event callback\n");
     132        int ret = audio_pcm_register_event_callback(pb->device,
     133            device_event_callback, pb);
     134        if (ret != EOK) {
     135                printf("Failed to register event callback.\n");
     136                return;
     137        }
    131138        printf("Playing: %dHz, %s, %d channel(s).\n",
    132139            sampling_rate, pcm_sample_format_str(format), channels);
     
    139146        const unsigned frames = pb->buffer.size /
    140147            (BUFFER_PARTS * channels * pcm_sample_format_size(format));
    141         int ret = audio_pcm_start_playback(pb->device,
    142             frames, channels, sampling_rate, format);
     148        ret = audio_pcm_start_playback(pb->device, frames, channels,
     149            sampling_rate, format);
    143150        if (ret != EOK) {
    144151                fibril_mutex_unlock(&pb->mutex);
     
    152159        fibril_mutex_unlock(&pb->mutex);
    153160        printf("\n");
     161        audio_pcm_unregister_event_callback(pb->device);
    154162}
    155163
     
    177185        playback_initialize(&pb, session);
    178186
    179         ret = audio_pcm_get_buffer(pb.device, &pb.buffer.base,
    180             &pb.buffer.size, device_event_callback, &pb);
     187        ret = audio_pcm_get_buffer(pb.device, &pb.buffer.base, &pb.buffer.size);
    181188        if (ret != EOK) {
    182189                printf("Failed to get PCM buffer: %s.\n", str_error(ret));
  • uspace/drv/audio/sb16/dsp.c

    r20840922 r018ab50  
    5555
    5656#define DSP_RESET_RESPONSE 0xaa
    57 #define DSP_RATE_LIMIT 45000
     57
     58/* These are only for SB16 (DSP4.00+) */
     59#define DSP_RATE_UPPER_LIMIT 44100
     60#define DSP_RATE_LOWER_LIMIT 5000
    5861
    5962#define AUTO_DMA_MODE
     
    294297                ret = ELIMIT;
    295298        }
    296         if (*rate > DSP_RATE_LIMIT) {
    297                 *rate = DSP_RATE_LIMIT;
    298                 ret = ELIMIT;
    299         }
    300299        //TODO 8bit DMA supports 8bit formats
    301300        if (*format != PCM_SAMPLE_SINT16_LE && *format != PCM_SAMPLE_UINT16_LE) {
     
    304303                ret = ELIMIT;
    305304        }
     305        if (*rate > DSP_RATE_UPPER_LIMIT) {
     306                *rate = DSP_RATE_UPPER_LIMIT;
     307                ret = ELIMIT;
     308        }
     309        if (*rate < DSP_RATE_LOWER_LIMIT) {
     310                *rate = DSP_RATE_LOWER_LIMIT;
     311                ret = ELIMIT;
     312        }
    306313        return ret;
    307314}
     
    333340{
    334341        assert(dsp);
    335         assert(session);
    336342        if (dsp->event_session)
    337343                return EBUSY;
    338344        dsp->event_session = session;
    339         ddf_log_debug("Set event session.");
    340         return EOK;
     345        ddf_log_debug("Set event session to %p.", session);
     346        return EOK;
     347}
     348
     349async_sess_t * sb_dsp_get_event_session(sb_dsp_t *dsp)
     350{
     351        assert(dsp);
     352        ddf_log_debug("Get event session: %p.", dsp->event_session);
     353        return dsp->event_session;
    341354}
    342355
  • uspace/drv/audio/sb16/dsp.h

    r20840922 r018ab50  
    8080int sb_dsp_get_buffer(sb_dsp_t *dsp, void **buffer, size_t *size);
    8181int sb_dsp_set_event_session(sb_dsp_t *dsp, async_sess_t *session);
     82async_sess_t * sb_dsp_get_event_session(sb_dsp_t *dsp);
    8283int sb_dsp_release_buffer(sb_dsp_t *dsp);
    8384int sb_dsp_start_playback(sb_dsp_t *dsp, unsigned frames,
  • uspace/drv/audio/sb16/pcm_iface.c

    r20840922 r018ab50  
    8787}
    8888
     89static async_sess_t * sb_get_event_session(ddf_fun_t *fun)
     90{
     91        assert(fun);
     92        assert(fun->driver_data);
     93        sb_dsp_t *dsp = fun->driver_data;
     94        return sb_dsp_get_event_session(dsp);
     95}
     96
    8997static int sb_release_buffer(ddf_fun_t *fun)
    9098{
     
    139147        .release_buffer = sb_release_buffer,
    140148        .set_event_session = sb_set_event_session,
     149        .get_event_session = sb_get_event_session,
    141150        .get_buffer_pos = sb_get_buffer_position,
    142151
  • uspace/lib/drv/generic/remote_audio_pcm.c

    r20840922 r018ab50  
    4646        IPC_M_AUDIO_PCM_GET_INFO_STR,
    4747        IPC_M_AUDIO_PCM_QUERY_CAPS,
     48        IPC_M_AUDIO_PCM_REGISTER_EVENTS,
     49        IPC_M_AUDIO_PCM_UNREGISTER_EVENTS,
    4850        IPC_M_AUDIO_PCM_TEST_FORMAT,
    4951        IPC_M_AUDIO_PCM_GET_BUFFER,
     
    235237
    236238/**
     239 * Register callback for device generated events.
     240 *
     241 * @param sess Audio device session.
     242 * @param event_rec Event callback function.
     243 * @param arg Event callback custom parameter.
     244 *
     245 * @return Error code.
     246 */
     247int audio_pcm_register_event_callback(audio_pcm_sess_t *sess,
     248    async_client_conn_t event_callback, void *arg)
     249{
     250        if (!event_callback)
     251                return EINVAL;
     252
     253        async_exch_t *exch = async_exchange_begin(sess);
     254        int ret = async_req_1_0(exch, DEV_IFACE_ID(AUDIO_PCM_BUFFER_IFACE),
     255            IPC_M_AUDIO_PCM_REGISTER_EVENTS);
     256        if (ret == EOK) {
     257                ret = async_connect_to_me(exch, 0, 0, 0, event_callback, arg);
     258        }
     259        async_exchange_end(exch);
     260        return ret;
     261}
     262
     263/**
     264 * Unregister callback for device generated events.
     265 *
     266 * @param sess Audio device session.
     267 *
     268 * @return Error code.
     269 */
     270int audio_pcm_unregister_event_callback(audio_pcm_sess_t *sess)
     271{
     272        async_exch_t *exch = async_exchange_begin(sess);
     273        const int ret = async_req_1_0(exch,
     274            DEV_IFACE_ID(AUDIO_PCM_BUFFER_IFACE),
     275            IPC_M_AUDIO_PCM_UNREGISTER_EVENTS);
     276        async_exchange_end(exch);
     277        return ret;
     278}
     279
     280/**
    237281 * Get device accessible playback/capture buffer.
    238282 *
     
    240284 * @param buffer Place to store pointer to the buffer.
    241285 * @param size Place to store buffer size (bytes).
    242  * @param event_rec Event callback function.
    243  * @param arg Event callback custom parameter.
    244  *
    245  * @return Error code.
    246  */
    247 int audio_pcm_get_buffer(audio_pcm_sess_t *sess, void **buffer, size_t *size,
    248     async_client_conn_t event_rec, void* arg)
     286 *
     287 * @return Error code.
     288 */
     289int audio_pcm_get_buffer(audio_pcm_sess_t *sess, void **buffer, size_t *size)
    249290{
    250291        if (!buffer || !size)
     
    254295
    255296        sysarg_t buffer_size = *size;
    256         const int ret = async_req_2_1(exch,
    257             DEV_IFACE_ID(AUDIO_PCM_BUFFER_IFACE), IPC_M_AUDIO_PCM_GET_BUFFER,
    258             (sysarg_t)buffer_size, &buffer_size);
     297        int ret = async_req_2_1(exch, DEV_IFACE_ID(AUDIO_PCM_BUFFER_IFACE),
     298            IPC_M_AUDIO_PCM_GET_BUFFER, (sysarg_t)buffer_size, &buffer_size);
    259299        if (ret == EOK) {
    260300                void *dst = NULL;
    261                 int ret = async_share_in_start_0_0(exch, buffer_size, &dst);
     301                ret = async_share_in_start_0_0(exch, buffer_size, &dst);
    262302                if (ret != EOK) {
    263303                        async_exchange_end(exch);
    264304                        return ret;
    265305                }
    266                 ret = async_connect_to_me(exch, 0, 0, 0, event_rec, arg);
    267                 if (ret != EOK) {
    268                         async_exchange_end(exch);
    269                         return ret;
    270                 }
    271 
    272306                *buffer = dst;
    273307                *size = buffer_size;
     
    391425static void remote_audio_pcm_get_info_str(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    392426static void remote_audio_pcm_query_caps(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     427static void remote_audio_pcm_events_register(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     428static void remote_audio_pcm_events_unregister(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    393429static void remote_audio_pcm_get_buffer_pos(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    394430static void remote_audio_pcm_test_format(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     
    404440        [IPC_M_AUDIO_PCM_GET_INFO_STR] = remote_audio_pcm_get_info_str,
    405441        [IPC_M_AUDIO_PCM_QUERY_CAPS] = remote_audio_pcm_query_caps,
     442        [IPC_M_AUDIO_PCM_REGISTER_EVENTS] = remote_audio_pcm_events_register,
     443        [IPC_M_AUDIO_PCM_UNREGISTER_EVENTS] = remote_audio_pcm_events_unregister,
    406444        [IPC_M_AUDIO_PCM_GET_BUFFER_POS] = remote_audio_pcm_get_buffer_pos,
    407445        [IPC_M_AUDIO_PCM_TEST_FORMAT] = remote_audio_pcm_test_format,
     
    461499        }
    462500}
     501
     502static void remote_audio_pcm_events_register(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)
     503{
     504        const audio_pcm_iface_t *pcm_iface = iface;
     505        if (!pcm_iface->get_event_session ||
     506            !pcm_iface->set_event_session) {
     507                async_answer_0(callid, ENOTSUP);
     508                return;
     509        }
     510
     511        async_answer_0(callid, EOK);
     512
     513        ipc_call_t callback_call;
     514        ipc_callid_t callback_id = async_get_call(&callback_call);
     515        async_sess_t *sess =
     516            async_callback_receive_start(EXCHANGE_ATOMIC, &callback_call);
     517        if (sess == NULL) {
     518                ddf_msg(LVL_DEBUG, "Failed to create event callback");
     519                pcm_iface->release_buffer(fun);
     520                async_answer_0(callback_id, EAGAIN);
     521                return;
     522        }
     523        const int ret = pcm_iface->set_event_session(fun, sess);
     524        if (ret != EOK) {
     525                ddf_msg(LVL_DEBUG, "Failed to set event callback.");
     526                pcm_iface->release_buffer(fun);
     527                async_hangup(sess);
     528                async_answer_0(callback_id, ret);
     529                return;
     530        }
     531        ddf_msg(LVL_DEBUG2, "Event session setup OK.");
     532        async_answer_0(callback_id, EOK);
     533}
     534
     535static void remote_audio_pcm_events_unregister(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)
     536{
     537        const audio_pcm_iface_t *pcm_iface = iface;
     538        if (!pcm_iface->get_event_session ||
     539            !pcm_iface->set_event_session) {
     540                async_answer_0(callid, ENOTSUP);
     541                return;
     542        }
     543        async_sess_t *sess = pcm_iface->get_event_session(fun);
     544        if (sess) {
     545                async_hangup(sess);
     546                pcm_iface->set_event_session(fun, NULL);
     547        }
     548        async_answer_0(callid, EOK);
     549}
     550
    463551void remote_audio_pcm_get_buffer_pos(ddf_fun_t *fun, void *iface, ipc_callid_t callid, ipc_call_t *call)
    464552{
     
    487575
    488576        if (!pcm_iface->get_buffer ||
    489             !pcm_iface->release_buffer ||
    490             !pcm_iface->set_event_session) {
     577            !pcm_iface->release_buffer) {
    491578                async_answer_0(callid, ENOTSUP);
    492579                return;
     
    528615        }
    529616
    530         ddf_msg(LVL_DEBUG2, "Buffer shared with size %zu, creating callback.",
    531             share_size);
    532         {
    533                 ipc_call_t call;
    534                 ipc_callid_t callid = async_get_call(&call);
    535                 async_sess_t *sess =
    536                     async_callback_receive_start(EXCHANGE_ATOMIC, &call);
    537                 if (sess == NULL) {
    538                         ddf_msg(LVL_DEBUG, "Failed to create event callback");
    539                         pcm_iface->release_buffer(fun);
    540                         async_answer_0(callid, EAGAIN);
    541                         return;
    542                 }
    543                 ret = pcm_iface->set_event_session(fun, sess);
    544                 if (ret != EOK) {
    545                         ddf_msg(LVL_DEBUG, "Failed to set event callback.");
    546                         pcm_iface->release_buffer(fun);
    547                         async_answer_0(callid, ret);
    548                         return;
    549                 }
    550                 ddf_msg(LVL_DEBUG2, "Buffer and event session setup OK.");
    551                 async_answer_0(callid, EOK);
    552         }
     617        ddf_msg(LVL_DEBUG2, "Buffer shared with size %zu.", share_size);
    553618}
    554619
  • uspace/lib/drv/include/audio_pcm_iface.h

    r20840922 r018ab50  
    7171    pcm_sample_format_t *);
    7272int audio_pcm_query_cap(audio_pcm_sess_t *, audio_cap_t, unsigned *);
     73int audio_pcm_register_event_callback(audio_pcm_sess_t *,
     74    async_client_conn_t, void *);
     75int audio_pcm_unregister_event_callback(audio_pcm_sess_t *);
     76
     77int audio_pcm_get_buffer(audio_pcm_sess_t *, void **, size_t *);
    7378int audio_pcm_get_buffer_pos(audio_pcm_sess_t *, size_t *);
    74 
    75 int audio_pcm_get_buffer(audio_pcm_sess_t *, void **, size_t *,
    76     async_client_conn_t, void *);
    7779int audio_pcm_release_buffer(audio_pcm_sess_t *);
    7880
     
    9597        int (*release_buffer)(ddf_fun_t *);
    9698        int (*set_event_session)(ddf_fun_t *, async_sess_t *);
     99        async_sess_t * (*get_event_session)(ddf_fun_t *);
    97100        int (*start_playback)(ddf_fun_t *, unsigned,
    98101            unsigned, unsigned, pcm_sample_format_t);
  • uspace/srv/audio/hound/audio_device.c

    r20840922 r018ab50  
    103103                        return ret;
    104104                }
     105                audio_pcm_register_event_callback(dev->sess,
     106                    device_event_callback, dev);
    105107
    106108                /* Fill the buffer first */
     
    176178                        return ret;
    177179                }
     180                audio_pcm_unregister_event_callback(dev->sess);
    178181        }
    179182
     
    246249
    247250        return audio_pcm_get_buffer(dev->sess, &dev->buffer.base,
    248             &dev->buffer.size, device_event_callback, dev);
     251            &dev->buffer.size);
    249252}
    250253
Note: See TracChangeset for help on using the changeset viewer.