diff --git a/include/system/nxrecorder.h b/include/system/nxrecorder.h index 4a2d127a3..4b2c2ac96 100644 --- a/include/system/nxrecorder.h +++ b/include/system/nxrecorder.h @@ -38,6 +38,14 @@ * Public Type Declarations ****************************************************************************/ +struct nxrecorder_enc_ops_s +{ + int format; + CODE int (*pre_write)(int fd, uint32_t samplerate, + uint8_t chans, uint8_t bps); + CODE int (*write_data)(int fd, struct ap_buffer_s *apb); +}; + /* This structure describes the internal state of the NxRecorder */ struct nxrecorder_s @@ -54,6 +62,8 @@ struct nxrecorder_s #ifdef CONFIG_AUDIO_MULTI_SESSION FAR void *session; /* Session assignment from device */ #endif + + FAR const struct nxrecorder_enc_ops_s *ops; }; typedef int (*nxrecorder_func)(FAR struct nxrecorder_s *precorder, @@ -229,6 +239,41 @@ int nxrecorder_pause(FAR struct nxrecorder_s *precorder); int nxrecorder_resume(FAR struct nxrecorder_s *precorder); #endif +/**************************************************************************** + * Name: nxrecorder_write_amr + * + * Performs pre-process when record amr file. + * + * Input Parameters: + * fd - recording file descriptor + * samplerate - sample rate + * chans - channels num + * bps - bit width + * + * Returned Value: + * OK if file writed successfully. + * + ****************************************************************************/ + +int nxrecorder_write_amr(int fd, uint32_t samplerate, + uint8_t chans, uint8_t bps); + +/**************************************************************************** + * Name: nxrecorder_write_common + * + * Performs common function to write apb buffer to FILE + * + * Input Parameters: + * fd - recording file descriptor + * apb - apb buffer + * + * Returned Value: + * OK if apb buffer write successfully. + * + ****************************************************************************/ + +int nxrecorder_write_common(int fd, FAR struct ap_buffer_s *apb); + #undef EXTERN #ifdef __cplusplus } diff --git a/system/nxrecorder/CMakeLists.txt b/system/nxrecorder/CMakeLists.txt index 365f778af..5f43d4e75 100644 --- a/system/nxrecorder/CMakeLists.txt +++ b/system/nxrecorder/CMakeLists.txt @@ -24,4 +24,8 @@ if(CONFIG_SYSTEM_NXRECORDER) ${CONFIG_NXRECORDER_MAINTHREAD_STACKSIZE}) endif() target_sources(apps PRIVATE nxrecorder.c) + + set(CSRCS nxrecorder.c nxrecorder_common.c nxrecorder_amr.c) + + target_sources(apps PRIVATE ${CSRCS}) endif() diff --git a/system/nxrecorder/Makefile b/system/nxrecorder/Makefile index f7eb66542..2a2f6d09f 100644 --- a/system/nxrecorder/Makefile +++ b/system/nxrecorder/Makefile @@ -22,8 +22,9 @@ include $(APPDIR)/Make.defs # NxRecorder Library -CSRCS = nxrecorder.c - +CSRCS = nxrecorder.c +CSRCS += nxrecorder_amr.c +CSRCS += nxrecorder_common.c ifneq ($(CONFIG_NXRECORDER_COMMAND_LINE),) PROGNAME = nxrecorder diff --git a/system/nxrecorder/nxrecorder.c b/system/nxrecorder/nxrecorder.c index de6051857..674baf1a6 100644 --- a/system/nxrecorder/nxrecorder.c +++ b/system/nxrecorder/nxrecorder.c @@ -108,14 +108,29 @@ static const struct nxrecorder_ext_fmt_s g_known_ext[] = { "midi", AUDIO_FMT_MIDI, NULL }, #endif #ifdef CONFIG_AUDIO_FORMAT_OGG_VORBIS - { "ogg", AUDIO_FMT_OGG_VORBIS, NULL } + { "ogg", AUDIO_FMT_OGG_VORBIS, NULL }, #endif + { "amr", AUDIO_FMT_AMR, NULL } }; static const int g_known_ext_count = sizeof(g_known_ext) / sizeof(struct nxrecorder_ext_fmt_s); #endif +static const struct nxrecorder_enc_ops_s g_enc_ops[] = +{ + { + AUDIO_FMT_AMR, + nxrecorder_write_amr, + nxrecorder_write_common, + }, + { + AUDIO_FMT_PCM, + NULL, + nxrecorder_write_common, + } +}; + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -353,7 +368,7 @@ static int nxrecorder_writebuffer(FAR struct nxrecorder_s *precorder, /* Write data to the file. */ - ret = write(precorder->fd, apb->samp, apb->nbytes); + ret = precorder->ops->write_data(precorder->fd, apb); if (ret < 0) { return ret; @@ -1019,6 +1034,7 @@ int nxrecorder_recordinternal(FAR struct nxrecorder_s *precorder, int min_channels; int ret; int subfmt = AUDIO_FMT_UNDEF; + int index; DEBUGASSERT(precorder != NULL); DEBUGASSERT(pfilename != NULL); @@ -1070,6 +1086,30 @@ int nxrecorder_recordinternal(FAR struct nxrecorder_s *precorder, goto err_out_nodev; } + for (index = 0; index < sizeof(g_enc_ops) / sizeof(g_enc_ops[0]); index++) + { + if (g_enc_ops[index].format == filefmt) + { + precorder->ops = &g_enc_ops[index]; + break; + } + } + + if (!precorder->ops) + { + goto err_out; + } + + if (precorder->ops->pre_write) + { + ret = precorder->ops->pre_write(precorder->fd, + samprate, nchannels, bpsamp); + if (ret < 0) + { + goto err_out; + } + } + /* Try to reserve the device */ #ifdef CONFIG_AUDIO_MULTI_SESSION diff --git a/system/nxrecorder/nxrecorder_amr.c b/system/nxrecorder/nxrecorder_amr.c new file mode 100644 index 000000000..646be196f --- /dev/null +++ b/system/nxrecorder/nxrecorder_amr.c @@ -0,0 +1,67 @@ +/**************************************************************************** + * apps/system/nxrecorder/nxrecorder_amr.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "system/nxrecorder.h" + +/**************************************************************************** + * Private Type Declarations + ****************************************************************************/ + +static const uint8_t AMR_NB[6] = "#!AMR\n"; +static const uint8_t AMR_WB[9] = "#!AMR-WB\n"; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxrecorder_record_amr + * + * nxrecorder_record_amr() add amr file header + * + ****************************************************************************/ + +int nxrecorder_write_amr(int fd, uint32_t samplerate, + uint8_t chans, uint8_t bps) +{ + const uint8_t *data; + int size; + + if (samplerate != 8000 && samplerate != 16000) + { + return -EINVAL; + } + + data = samplerate == 16000 ? &AMR_WB[0] : &AMR_NB[0]; + size = samplerate == 16000 ? sizeof(AMR_WB) : sizeof(AMR_NB); + + return write(fd, data, size); +} diff --git a/system/nxrecorder/nxrecorder_common.c b/system/nxrecorder/nxrecorder_common.c new file mode 100644 index 000000000..04d3ce941 --- /dev/null +++ b/system/nxrecorder/nxrecorder_common.c @@ -0,0 +1,67 @@ +/**************************************************************************** + * apps/system/nxrecorder/nxrecorder_common.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "system/nxrecorder.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxrecorder_write_common + * + * Performs common function to write data to apb buffer + * + * Input Parameters: + * fd - recording file descriptor + * apb - ap buffer + * + * Returned Value: + * OK if apb buffer write successfully. + * + ****************************************************************************/ + +int nxrecorder_write_common(int fd, FAR struct ap_buffer_s *apb) +{ + int ret = 0; + + ret = write(fd, apb->samp, apb->nbytes); + if (ret < 0) + { + auderr("ERROR: precorder write failed: %d\n", ret); + } + + return ret; +}