From: Lawrence S. <ljs...@us...> - 2013-06-05 21:11:48
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via 2301649311ec1eeb4efad496d11d8829c80b7985 (commit) from 447092cd714bf88c3e7c65c258f1734171f4df1c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2301649311ec1eeb4efad496d11d8829c80b7985 Author: Lawrence Sebald <ljs...@us...> Date: Wed Jun 5 17:11:24 2013 -0400 Fix a major bug in the mic driver and change how it works internally. ----------------------------------------------------------------------- Summary of changes: doc/CHANGELOG | 7 +- kernel/arch/dreamcast/hardware/maple/sip.c | 132 ++++---------------------- kernel/arch/dreamcast/include/dc/maple/sip.h | 62 +++++-------- 3 files changed, 47 insertions(+), 154 deletions(-) diff --git a/doc/CHANGELOG b/doc/CHANGELOG index e09d43f..7b90de7 100644 --- a/doc/CHANGELOG +++ b/doc/CHANGELOG @@ -3,7 +3,12 @@ applicable platform is listed. If someone besides me found the bug or suggested the fix, I'll put their name in [ ]. KallistiOS version 2.0.1 ----------------------------------------------- -- *** Clean up generated stubs files on a make clean [Lawrence Sebald = LS] +- *** Cleaned up generated stubs files on a make clean [Lawrence Sebald = LS] +- DC Added a function to detect if the program is being run on a retail + Dreamcast or a Set5.xx device [LS] +- DC Fixed an issue with the SIP driver that would cause programs to freeze + if a microphone was connected at program startup [LS] +- DC Rearranged the SIP driver to get rid of the internal buffer [LS] KallistiOS version 2.0.0 ----------------------------------------------- - DC Broadband Adapter driver fixes [Dan Potter == DP] diff --git a/kernel/arch/dreamcast/hardware/maple/sip.c b/kernel/arch/dreamcast/hardware/maple/sip.c index 93862af..29d812c 100644 --- a/kernel/arch/dreamcast/hardware/maple/sip.c +++ b/kernel/arch/dreamcast/hardware/maple/sip.c @@ -1,7 +1,7 @@ /* KallistiOS ##version## sip.c - Copyright (C) 2005, 2008 Lawrence Sebald + Copyright (C) 2005, 2008, 2013 Lawrence Sebald */ #include <assert.h> @@ -52,6 +52,7 @@ static void sip_stop_sampling_cb(maple_frame_t *frame) { /* Clear the is_sampling flag. */ sip = (sip_state_t *)frame->dev->status; sip->is_sampling = 0; + sip->callback = NULL; /* Wake up! */ genwait_wake_all(frame); @@ -112,7 +113,7 @@ int sip_set_frequency(maple_device_t *dev, unsigned int freq) { return MAPLE_EOK; } -int sip_start_sampling(maple_device_t *dev, int block) { +int sip_start_sampling(maple_device_t *dev, sip_sample_cb cb, int block) { sip_state_t *sip; uint32 *send_buf; @@ -120,14 +121,16 @@ int sip_start_sampling(maple_device_t *dev, int block) { sip = (sip_state_t *)dev->status; - /* Make sure we aren't yet sampling */ - if(sip->is_sampling) + /* Make sure we aren't yet sampling and that the callback is sane. */ + if(sip->is_sampling || !cb) return MAPLE_EFAIL; /* Lock the frame */ if(maple_frame_lock(&dev->frame) < 0) return MAPLE_EAGAIN; + sip->callback = cb; + /* Reset the frame */ maple_frame_init(&dev->frame); send_buf = (uint32 *)dev->frame.recv_buf; @@ -204,76 +207,10 @@ int sip_stop_sampling(maple_device_t *dev, int block) { return MAPLE_EOK; } -uint8 *sip_get_samples(maple_device_t *dev, size_t *sz) { - sip_state_t *sip; - uint8 *rv; - uint32 old; - - assert(dev != NULL); - assert(sz != NULL); - - /* Disable interrupts so that nothing changes underneath us. */ - old = irq_disable(); - - sip = (sip_state_t *)dev->status; - - /* Make sure that we're not currently sampling. */ - if(sip->is_sampling) { - irq_restore(old); - *sz = (size_t) - 1; - return NULL; - } - - /* Grab the values to return. */ - *sz = sip->buf_pos; - rv = sip->samples_buf; - - /* Allocate us a new buffer. */ - sip->buf_pos = 0; - sip->samples_buf = (uint8 *)malloc(11025 * 2 * 10); - - if(sip->samples_buf == NULL) { - sip->buf_len = 0; - dev->status_valid = 0; - } - else { - sip->buf_len = 11025 * 2 * 10; - dev->status_valid = 1; - } - - irq_restore(old); - return rv; -} - -int sip_clear_samples(maple_device_t *dev) { - sip_state_t *sip; - uint32 old; - - assert(dev != NULL); - - /* Disable IRQs so that nothing changes under us */ - old = irq_disable(); - - sip = (sip_state_t *)dev->status; - - if(sip->is_sampling) { - irq_restore(old); - return MAPLE_EFAIL; - } - - sip->buf_pos = 0; - - irq_restore(old); - - return MAPLE_EOK; -} - static void sip_reply(maple_frame_t *frm) { maple_response_t *resp; uint32 *respbuf; - size_t sz; sip_state_t *sip; - void *tmp; /* Unlock the frame now (it's ok, we're in an IRQ) */ maple_frame_unlock(frm); @@ -293,24 +230,9 @@ static void sip_reply(maple_frame_t *frm) { sip = (sip_state_t *)frm->dev->status; frm->dev->status_valid = 1; - if(sip->is_sampling) { - sz = resp->data_len * 4 - 8; - - /* Resize the buffer, if it is needed. */ - if(sz + sip->buf_pos > sip->buf_len) { - /* Attempt to double the buffer size. */ - tmp = realloc(sip->samples_buf, sip->buf_len << 1); - - if(!tmp) { - return; - } - - sip->samples_buf = tmp; - sip->buf_len <<= 1; - } - - memcpy(sip->samples_buf + sip->buf_pos, resp->data + 8, sz); - sip->buf_pos += sz; + if(sip->is_sampling && sip->callback) { + /* Call the user's callback. */ + sip->callback(frm->dev, resp->data + 8, (resp->data_len << 2) - 8); } } } @@ -322,7 +244,7 @@ static int sip_poll(maple_device_t *dev) { sip = (sip_state_t *)dev->status; /* Test to make sure that the particular mic is enabled */ - if(!sip->is_sampling) { + if(!sip->is_sampling || !sip->callback) { dev->status_valid = 1; return 0; } @@ -354,32 +276,12 @@ static void sip_periodic(maple_driver_t *drv) { static int sip_attach(maple_driver_t *drv, maple_device_t *dev) { sip_state_t *sip; - /* Allocate the sample buffer for 10 seconds worth of samples (11.025kHz, - 16-bit signed samples). */ - sip = (sip_state_t *)dev->status; - sip->samples_buf = (uint8 *)malloc(11025 * 2 * 10); - - if(sip->samples_buf == NULL) { - return -1; - } - else { - sip->is_sampling = 0; - sip->amp_gain = SIP_DEFAULT_GAIN; - sip->buf_pos = 0; - sip->buf_len = 11025 * 2 * 10; - dev->status_valid = 1; - return 0; - } -} - -static void sip_detach(maple_driver_t *drv, maple_device_t *dev) { - sip_state_t *sip; - sip = (sip_state_t *)dev->status; - - if(sip->samples_buf) { - free(sip->samples_buf); - } + sip->is_sampling = 0; + sip->amp_gain = SIP_DEFAULT_GAIN; + sip->callback = NULL; + dev->status_valid = 1; + return 0; } /* Device Driver Struct */ @@ -393,7 +295,7 @@ periodic: attach: sip_attach, detach: - sip_detach + NULL }; /* Add the SIP to the driver chain */ diff --git a/kernel/arch/dreamcast/include/dc/maple/sip.h b/kernel/arch/dreamcast/include/dc/maple/sip.h index e58bbf6..51aabae 100644 --- a/kernel/arch/dreamcast/include/dc/maple/sip.h +++ b/kernel/arch/dreamcast/include/dc/maple/sip.h @@ -1,7 +1,7 @@ /* KallistiOS ##version## dc/maple/sip.h - Copyright (C) 2005, 2008, 2010 Lawrence Sebald + Copyright (C) 2005, 2008, 2010, 2013 Lawrence Sebald */ @@ -28,6 +28,23 @@ __BEGIN_DECLS #include <sys/types.h> #include <dc/maple.h> +/** \brief Type for a microphone sample callback. + + This is the signature that is required for a function to accept samples + from the microphone as it is sampling. This function will be called about + once per frame, and in an interrupt context (so it should be pretty quick + to execute). Basically, all you should do in one of these is copy the + samples out to your own buffer -- do not do any processing on the samples + in your callback other than to copy them out! + + \param dev The device the samples are coming from. + \param samples Pointer to the sample buffer. + \param len The number of bytes in the sample buffer. + + \headerfile dc/maple/sip.h +*/ +typedef void (*sip_sample_cb)(maple_device_t *dev, uint8 *samples, size_t len); + /** \brief SIP status structure. This structure contains information about the status of the microphone @@ -51,14 +68,8 @@ typedef struct sip_state { /** \brief Is the mic currently sampling? */ int is_sampling; - /** \brief How long is the samples buffer? */ - size_t buf_len; - - /** \brief What is the last place written to in the buffer? */ - off_t buf_pos; - - /** \brief Buffer for storing samples in (automatically allocated). */ - uint8 *samples_buf; + /** \brief Sampling callback. */ + sip_sample_cb callback; } sip_state_t; /** \brief Get recorded samples from the microphone device. @@ -156,15 +167,17 @@ int sip_set_frequency(maple_device_t *dev, unsigned int freq); This function informs a microphone it should start recording samples. \param dev The device to start sampling on. + \param cb A callback to call when samples are ready. \param block Set to 1 to wait for the SIP to start sampling. Otherwise check the is_sampling member of the status for dev to know when it has started. \retval MAPLE_EOK On success. \retval MAPLE_EAGAIN If the command couldn't be sent, try again later. - \retval MAPLE_EFAIL If the microphone is already sampling. + \retval MAPLE_EFAIL If the microphone is already sampling or the + callback function is NULL. \retval MAPLE_ETIMEOUT If the command timed out while blocking. */ -int sip_start_sampling(maple_device_t *dev, int block); +int sip_start_sampling(maple_device_t *dev, sip_sample_cb cb, int block); /** \brief Stop sampling on a microphone. @@ -181,33 +194,6 @@ int sip_start_sampling(maple_device_t *dev, int block); */ int sip_stop_sampling(maple_device_t *dev, int block); -/** \brief Retrieve the sample buffer from the microphone. - - This function retrieves the sample buffer from the microphone and allocates - a new buffer for the microphone to record into. This function cannot be - called while the microphone is sampling. The caller is responsible for the - buffer returned, and must free the buffer when it is done with it. - - \param dev The device to fetch samples for. - \param sz On return, the size of the sample buffer in bytes. - This must not be NULL. - \return The sample buffer on success, NULL on failure. -*/ -uint8 *sip_get_samples(maple_device_t *dev, size_t *sz); - -/** \brief Clear the sample buffer of a microphone. - - This function clears out any old samples on the microphone buffer so that - recording will start from the beginning of the buffer again. This does not - resize the buffer in any way. This function will not work if called while - the microphone is sampling. - - \param dev The device to clear the buffer on. - \retval MAPLE_EOK On success. - \retval MAPLE_EFAIL If the device is currently sampling. -*/ -int sip_clear_samples(maple_device_t *dev); - /* \cond */ /* Init / Shutdown */ int sip_init(); hooks/post-receive -- A pseudo Operating System for the Dreamcast. |