forked from len0rd/rockbox
Added FS#2939 Encoder Codec Interface + Codecs by Antonius Hellmann with additional FM Recording support and my modifications
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10789 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
65c2c58b3a
commit
4fc717a4c1
36 changed files with 4803 additions and 860 deletions
|
@ -40,6 +40,7 @@
|
||||||
#include "mpeg.h"
|
#include "mpeg.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "mp3_playback.h"
|
#include "mp3_playback.h"
|
||||||
|
#include "playback.h"
|
||||||
#include "backlight.h"
|
#include "backlight.h"
|
||||||
#include "ata.h"
|
#include "ata.h"
|
||||||
#include "talk.h"
|
#include "talk.h"
|
||||||
|
@ -208,11 +209,28 @@ struct codec_api ci = {
|
||||||
profile_func_exit,
|
profile_func_exit,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_RECORDING) && !defined(SIMULATOR)
|
||||||
|
false,
|
||||||
|
enc_get_inputs,
|
||||||
|
enc_set_parameters,
|
||||||
|
enc_alloc_chunk,
|
||||||
|
enc_free_chunk,
|
||||||
|
enc_wavbuf_near_empty,
|
||||||
|
enc_get_wav_data,
|
||||||
|
&enc_set_header_callback,
|
||||||
|
#endif
|
||||||
|
|
||||||
/* new stuff at the end, sort into place next time
|
/* new stuff at the end, sort into place next time
|
||||||
the API gets incompatible */
|
the API gets incompatible */
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void codec_get_full_path(char *path, const char *codec_fn)
|
||||||
|
{
|
||||||
|
/* Create full codec path */
|
||||||
|
snprintf(path, MAX_PATH-1, ROCKBOX_DIR CODECS_DIR "/%s", codec_fn);
|
||||||
|
}
|
||||||
|
|
||||||
int codec_load_ram(char* codecptr, int size, void* ptr2, int bufwrap,
|
int codec_load_ram(char* codecptr, int size, void* ptr2, int bufwrap,
|
||||||
struct codec_api *api)
|
struct codec_api *api)
|
||||||
{
|
{
|
||||||
|
@ -277,15 +295,18 @@ int codec_load_ram(char* codecptr, int size, void* ptr2, int bufwrap,
|
||||||
int codec_load_file(const char *plugin, struct codec_api *api)
|
int codec_load_file(const char *plugin, struct codec_api *api)
|
||||||
{
|
{
|
||||||
char msgbuf[80];
|
char msgbuf[80];
|
||||||
|
char path[MAX_PATH];
|
||||||
int fd;
|
int fd;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
codec_get_full_path(path, plugin);
|
||||||
|
|
||||||
/* zero out codec buffer to ensure a properly zeroed bss area */
|
/* zero out codec buffer to ensure a properly zeroed bss area */
|
||||||
memset(codecbuf, 0, CODEC_SIZE);
|
memset(codecbuf, 0, CODEC_SIZE);
|
||||||
|
|
||||||
fd = open(plugin, O_RDONLY);
|
fd = open(path, O_RDONLY);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
snprintf(msgbuf, sizeof(msgbuf)-1, "Couldn't load codec: %s", plugin);
|
snprintf(msgbuf, sizeof(msgbuf)-1, "Couldn't load codec: %s", path);
|
||||||
logf("Codec load error:%d", fd);
|
logf("Codec load error:%d", fd);
|
||||||
gui_syncsplash(HZ*2, true, msgbuf);
|
gui_syncsplash(HZ*2, true, msgbuf);
|
||||||
return fd;
|
return fd;
|
||||||
|
|
|
@ -46,6 +46,9 @@
|
||||||
#include "profile.h"
|
#include "profile.h"
|
||||||
#endif
|
#endif
|
||||||
#if (CONFIG_CODEC == SWCODEC)
|
#if (CONFIG_CODEC == SWCODEC)
|
||||||
|
#if !defined(SIMULATOR)
|
||||||
|
#include "pcm_record.h"
|
||||||
|
#endif
|
||||||
#include "dsp.h"
|
#include "dsp.h"
|
||||||
#include "playback.h"
|
#include "playback.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -84,7 +87,7 @@
|
||||||
#define CODEC_MAGIC 0x52434F44 /* RCOD */
|
#define CODEC_MAGIC 0x52434F44 /* RCOD */
|
||||||
|
|
||||||
/* increase this every time the api struct changes */
|
/* increase this every time the api struct changes */
|
||||||
#define CODEC_API_VERSION 8
|
#define CODEC_API_VERSION 9
|
||||||
|
|
||||||
/* update this to latest version if a change to the api struct breaks
|
/* update this to latest version if a change to the api struct breaks
|
||||||
backwards compatibility (and please take the opportunity to sort in any
|
backwards compatibility (and please take the opportunity to sort in any
|
||||||
|
@ -285,6 +288,21 @@ struct codec_api {
|
||||||
void (*profile_func_exit)(void *this_fn, void *call_site);
|
void (*profile_func_exit)(void *this_fn, void *call_site);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_RECORDING) && !defined(SIMULATOR)
|
||||||
|
bool enc_codec_loaded;
|
||||||
|
void (*enc_get_inputs)(int *buffer_size,
|
||||||
|
int *channels, int *quality);
|
||||||
|
void (*enc_set_parameters)(int chunk_size, int num_chunks,
|
||||||
|
int samp_per_chunk, char *head_ptr, int head_size,
|
||||||
|
int enc_id);
|
||||||
|
unsigned int* (*enc_alloc_chunk)(void);
|
||||||
|
void (*enc_free_chunk)(void);
|
||||||
|
int (*enc_wavbuf_near_empty)(void);
|
||||||
|
char* (*enc_get_wav_data)(int size);
|
||||||
|
void (**enc_set_header_callback)(void *head_buffer,
|
||||||
|
int head_size, int num_samples, bool is_file_header);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* new stuff at the end, sort into place next time
|
/* new stuff at the end, sort into place next time
|
||||||
the API gets incompatible */
|
the API gets incompatible */
|
||||||
|
|
||||||
|
@ -317,6 +335,10 @@ extern unsigned char plugin_end_addr[];
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* create full codec path from filenames in audio_formats[]
|
||||||
|
assumes buffer size is MAX_PATH */
|
||||||
|
void codec_get_full_path(char *path, const char *codec_fn);
|
||||||
|
|
||||||
/* defined by the codec loader (codec.c) */
|
/* defined by the codec loader (codec.c) */
|
||||||
int codec_load_ram(char* codecptr, int size, void* ptr2, int bufwrap,
|
int codec_load_ram(char* codecptr, int size, void* ptr2, int bufwrap,
|
||||||
struct codec_api *api);
|
struct codec_api *api);
|
||||||
|
|
|
@ -58,6 +58,9 @@ $(OBJDIR)/wavpack.elf : $(OBJDIR)/wavpack.o $(BUILDDIR)/libwavpack.a
|
||||||
$(OBJDIR)/alac.elf : $(OBJDIR)/alac.o $(BUILDDIR)/libalac.a $(BUILDDIR)/libm4a.a
|
$(OBJDIR)/alac.elf : $(OBJDIR)/alac.o $(BUILDDIR)/libalac.a $(BUILDDIR)/libm4a.a
|
||||||
$(OBJDIR)/aac.elf : $(OBJDIR)/aac.o $(BUILDDIR)/libfaad.a $(BUILDDIR)/libm4a.a
|
$(OBJDIR)/aac.elf : $(OBJDIR)/aac.o $(BUILDDIR)/libfaad.a $(BUILDDIR)/libm4a.a
|
||||||
$(OBJDIR)/shorten.elf : $(OBJDIR)/shorten.o $(BUILDDIR)/libffmpegFLAC.a
|
$(OBJDIR)/shorten.elf : $(OBJDIR)/shorten.o $(BUILDDIR)/libffmpegFLAC.a
|
||||||
|
$(OBJDIR)/mp3_enc.elf: $(OBJDIR)/mp3_enc.o
|
||||||
|
$(OBJDIR)/wav_enc.elf: $(OBJDIR)/wav_enc.o
|
||||||
|
$(OBJDIR)/wavpack_enc.elf: $(OBJDIR)/wavpack_enc.o $(BUILDDIR)/libwavpack.a
|
||||||
|
|
||||||
$(OBJDIR)/%.elf :
|
$(OBJDIR)/%.elf :
|
||||||
@echo "LD $(notdir $@)"
|
@echo "LD $(notdir $@)"
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#if CONFIG_CODEC == SWCODEC
|
#if CONFIG_CODEC == SWCODEC
|
||||||
|
/* decoders */
|
||||||
vorbis.c
|
vorbis.c
|
||||||
mpa.c
|
mpa.c
|
||||||
flac.c
|
flac.c
|
||||||
|
@ -13,4 +14,11 @@ aac.c
|
||||||
shorten.c
|
shorten.c
|
||||||
aiff.c
|
aiff.c
|
||||||
sid.c
|
sid.c
|
||||||
|
#if defined(HAVE_RECORDING) && !defined(SIMULATOR)
|
||||||
|
/* encoders */
|
||||||
|
mp3_enc.c
|
||||||
|
wav_enc.c
|
||||||
|
wavpack_enc.c
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
2860
apps/codecs/mp3_enc.c
Normal file
2860
apps/codecs/mp3_enc.c
Normal file
File diff suppressed because it is too large
Load diff
172
apps/codecs/wav_enc.c
Normal file
172
apps/codecs/wav_enc.c
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* __________ __ ___.
|
||||||
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||||
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||||
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||||
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||||
|
* \/ \/ \/ \/ \/
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Antonius Hellmann
|
||||||
|
*
|
||||||
|
* All files in this archive are subject to the GNU General Public License.
|
||||||
|
* See the file COPYING in the source tree root for full license agreement.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef SIMULATOR
|
||||||
|
|
||||||
|
#include "codeclib.h"
|
||||||
|
|
||||||
|
CODEC_HEADER
|
||||||
|
|
||||||
|
static struct codec_api *ci;
|
||||||
|
static int enc_channels;
|
||||||
|
|
||||||
|
#define CHUNK_SIZE 8192
|
||||||
|
|
||||||
|
static unsigned char wav_header[44] =
|
||||||
|
{'R','I','F','F',0,0,0,0,'W','A','V','E','f','m','t',' ',16,
|
||||||
|
0,0,0,1,0,2,0,0x44,0xac,0,0,0x10,0xb1,2,0,4,0,16,0,'d','a','t','a',0,0,0,0};
|
||||||
|
|
||||||
|
static unsigned char wav_header_mono[44] =
|
||||||
|
{'R','I','F','F',0,0,0,0,'W','A','V','E','f','m','t',' ',16,
|
||||||
|
0,0,0,1,0,1,0,0x44,0xac,0,0,0x88,0x58,1,0,2,0,16,0,'d','a','t','a',0,0,0,0};
|
||||||
|
|
||||||
|
/* update file header info callback function (called by main application) */
|
||||||
|
void enc_set_header(void *head_buffer, /* ptr to the file header data */
|
||||||
|
int head_size, /* size of this header data */
|
||||||
|
int num_pcm_samples, /* amount of processed pcm samples */
|
||||||
|
bool is_file_header)
|
||||||
|
{
|
||||||
|
int num_file_bytes = num_pcm_samples * 2 * enc_channels;
|
||||||
|
|
||||||
|
if(is_file_header)
|
||||||
|
{
|
||||||
|
/* update file header before file closing */
|
||||||
|
if((int)sizeof(wav_header) < head_size)
|
||||||
|
{
|
||||||
|
/* update wave header size entries: special to WAV format */
|
||||||
|
*(long*)(head_buffer+ 4) = htole32(num_file_bytes + 36);
|
||||||
|
*(long*)(head_buffer+40) = htole32(num_file_bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* main codec entry point */
|
||||||
|
enum codec_status codec_start(struct codec_api* api)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
long lr;
|
||||||
|
unsigned long t;
|
||||||
|
unsigned long *src;
|
||||||
|
unsigned long *dst;
|
||||||
|
int chunk_size, num_chunks, samp_per_chunk;
|
||||||
|
int enc_buffer_size;
|
||||||
|
int enc_quality;
|
||||||
|
bool cpu_boosted = true; /* start boosted */
|
||||||
|
|
||||||
|
ci = api; // copy to global api pointer
|
||||||
|
|
||||||
|
if(ci->enc_get_inputs == NULL ||
|
||||||
|
ci->enc_set_parameters == NULL ||
|
||||||
|
ci->enc_alloc_chunk == NULL ||
|
||||||
|
ci->enc_free_chunk == NULL ||
|
||||||
|
ci->enc_wavbuf_near_empty == NULL ||
|
||||||
|
ci->enc_get_wav_data == NULL ||
|
||||||
|
ci->enc_set_header_callback == NULL )
|
||||||
|
return CODEC_ERROR;
|
||||||
|
|
||||||
|
ci->cpu_boost(true);
|
||||||
|
|
||||||
|
*ci->enc_set_header_callback = enc_set_header;
|
||||||
|
ci->enc_get_inputs(&enc_buffer_size, &enc_channels, &enc_quality);
|
||||||
|
|
||||||
|
/* configure the buffer system */
|
||||||
|
chunk_size = sizeof(long) + CHUNK_SIZE * enc_channels / 2;
|
||||||
|
num_chunks = enc_buffer_size / chunk_size;
|
||||||
|
samp_per_chunk = CHUNK_SIZE / 4;
|
||||||
|
|
||||||
|
/* inform the main program about buffer dimensions and other params */
|
||||||
|
ci->enc_set_parameters(chunk_size, num_chunks, samp_per_chunk,
|
||||||
|
(enc_channels == 2) ? wav_header : wav_header_mono,
|
||||||
|
sizeof(wav_header), AFMT_PCM_WAV);
|
||||||
|
|
||||||
|
/* main application waits for this flag during encoder loading */
|
||||||
|
ci->enc_codec_loaded = true;
|
||||||
|
|
||||||
|
/* main encoding loop */
|
||||||
|
while(!ci->stop_codec)
|
||||||
|
{
|
||||||
|
while((src = (unsigned long*)ci->enc_get_wav_data(CHUNK_SIZE)) != NULL)
|
||||||
|
{
|
||||||
|
if(ci->stop_codec)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(ci->enc_wavbuf_near_empty() == 0)
|
||||||
|
{
|
||||||
|
if(!cpu_boosted)
|
||||||
|
{
|
||||||
|
ci->cpu_boost(true);
|
||||||
|
cpu_boosted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dst = (unsigned long*)ci->enc_alloc_chunk();
|
||||||
|
*dst++ = CHUNK_SIZE * enc_channels / 2; /* set size info */
|
||||||
|
|
||||||
|
if(enc_channels == 2)
|
||||||
|
{
|
||||||
|
/* swap byte order & copy to destination */
|
||||||
|
for (i=0; i<CHUNK_SIZE/4; i++)
|
||||||
|
{
|
||||||
|
t = *src++;
|
||||||
|
*dst++ = ((t >> 8) & 0xff00ff) | ((t << 8) & 0xff00ff00);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* mix left/right, swap byte order & copy to destination */
|
||||||
|
for (i=0; i<CHUNK_SIZE/8; i++)
|
||||||
|
{
|
||||||
|
lr = (long)*src++;
|
||||||
|
lr = (((lr<<16)>>16) + (lr>>16)) >> 1; /* left+right */
|
||||||
|
t = (lr << 16);
|
||||||
|
lr = (long)*src++;
|
||||||
|
lr = (((lr<<16)>>16) + (lr>>16)) >> 1; /* left+right */
|
||||||
|
t |= lr & 0xffff;
|
||||||
|
*dst++ = ((t >> 8) & 0xff00ff) | ((t << 8) & 0xff00ff00);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ci->enc_free_chunk();
|
||||||
|
ci->yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ci->enc_wavbuf_near_empty())
|
||||||
|
{
|
||||||
|
if(cpu_boosted)
|
||||||
|
{
|
||||||
|
ci->cpu_boost(false);
|
||||||
|
cpu_boosted = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ci->yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cpu_boosted) /* set initial boost state */
|
||||||
|
ci->cpu_boost(false);
|
||||||
|
|
||||||
|
/* reset parameters to initial state */
|
||||||
|
ci->enc_set_parameters(0, 0, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
/* main application waits for this flag during encoder removing */
|
||||||
|
ci->enc_codec_loaded = false;
|
||||||
|
|
||||||
|
return CODEC_OK;
|
||||||
|
}
|
||||||
|
#endif
|
230
apps/codecs/wavpack_enc.c
Normal file
230
apps/codecs/wavpack_enc.c
Normal file
|
@ -0,0 +1,230 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* __________ __ ___.
|
||||||
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||||
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||||
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||||
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||||
|
* \/ \/ \/ \/ \/
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Antonius Hellmann
|
||||||
|
*
|
||||||
|
* All files in this archive are subject to the GNU General Public License.
|
||||||
|
* See the file COPYING in the source tree root for full license agreement.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef SIMULATOR
|
||||||
|
|
||||||
|
#include "codeclib.h"
|
||||||
|
#include "libwavpack/wavpack.h"
|
||||||
|
|
||||||
|
CODEC_HEADER
|
||||||
|
|
||||||
|
typedef unsigned long uint32;
|
||||||
|
typedef unsigned short uint16;
|
||||||
|
typedef unsigned char uint8;
|
||||||
|
|
||||||
|
static unsigned char wav_header_ster [46] =
|
||||||
|
{33,22,'R','I','F','F',0,0,0,0,'W','A','V','E','f','m','t',' ',16,
|
||||||
|
0,0,0,1,0,2,0,0x44,0xac,0,0,0x10,0xb1,2,0,4,0,16,0,'d','a','t','a',0,0,0,0};
|
||||||
|
|
||||||
|
static unsigned char wav_header_mono [46] =
|
||||||
|
{33,22,'R','I','F','F',0,0,0,0,'W','A','V','E','f','m','t',' ',16,
|
||||||
|
0,0,0,1,0,1,0,0x44,0xac,0,0,0x88,0x58,1,0,2,0,16,0,'d','a','t','a',0,0,0,0};
|
||||||
|
|
||||||
|
static struct codec_api *ci;
|
||||||
|
static int enc_channels;
|
||||||
|
|
||||||
|
#define CHUNK_SIZE 20000
|
||||||
|
|
||||||
|
static long input_buffer[CHUNK_SIZE/2] IBSS_ATTR;
|
||||||
|
|
||||||
|
void *memset(void *s, int c, size_t n)
|
||||||
|
{
|
||||||
|
return(ci->memset(s,c,n));
|
||||||
|
}
|
||||||
|
|
||||||
|
void *memcpy(void *dest, const void *src, size_t n)
|
||||||
|
{
|
||||||
|
return(ci->memcpy(dest,src,n));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* update file header info callback function */
|
||||||
|
void enc_set_header(void *head_buffer, /* ptr to the file header data */
|
||||||
|
int head_size, /* size of this header data */
|
||||||
|
int num_pcm_sampl, /* amount of processed pcm samples */
|
||||||
|
bool is_file_header) /* update file/chunk header */
|
||||||
|
{
|
||||||
|
if(is_file_header)
|
||||||
|
{
|
||||||
|
/* update file header before file closing */
|
||||||
|
if(sizeof(WavpackHeader) + sizeof(wav_header_mono) < (unsigned)head_size)
|
||||||
|
{
|
||||||
|
char* riff_header = (char*)head_buffer + sizeof(WavpackHeader);
|
||||||
|
char* wv_header = (char*)head_buffer + sizeof(wav_header_mono);
|
||||||
|
int num_file_bytes = num_pcm_sampl * 2 * enc_channels;
|
||||||
|
unsigned long ckSize;
|
||||||
|
|
||||||
|
/* RIFF header and WVPK header have to be swapped */
|
||||||
|
/* copy wavpack header to file start position */
|
||||||
|
ci->memcpy(head_buffer, wv_header, sizeof(WavpackHeader));
|
||||||
|
wv_header = head_buffer; /* recalc wavpack header position */
|
||||||
|
|
||||||
|
if(enc_channels == 2)
|
||||||
|
ci->memcpy(riff_header, wav_header_ster, sizeof(wav_header_ster));
|
||||||
|
else
|
||||||
|
ci->memcpy(riff_header, wav_header_mono, sizeof(wav_header_mono));
|
||||||
|
|
||||||
|
/* update the Wavpack header first chunk size & total frame count */
|
||||||
|
ckSize = htole32(((WavpackHeader*)wv_header)->ckSize)
|
||||||
|
+ sizeof(wav_header_mono);
|
||||||
|
((WavpackHeader*)wv_header)->total_samples = htole32(num_pcm_sampl);
|
||||||
|
((WavpackHeader*)wv_header)->ckSize = htole32(ckSize);
|
||||||
|
|
||||||
|
/* update the RIFF WAV header size entries */
|
||||||
|
*(long*)(riff_header+ 6) = htole32(num_file_bytes + 36);
|
||||||
|
*(long*)(riff_header+42) = htole32(num_file_bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* update timestamp (block_index) */
|
||||||
|
((WavpackHeader*)head_buffer)->block_index = htole32(num_pcm_sampl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enum codec_status codec_start(struct codec_api* api)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
long t;
|
||||||
|
uint32 *src;
|
||||||
|
uint32 *dst;
|
||||||
|
int chunk_size, num_chunks, samp_per_chunk;
|
||||||
|
int enc_buffer_size;
|
||||||
|
int enc_quality;
|
||||||
|
WavpackConfig config;
|
||||||
|
WavpackContext *wpc;
|
||||||
|
bool cpu_boosted = true; /* start boosted */
|
||||||
|
|
||||||
|
ci = api; // copy to global api pointer
|
||||||
|
|
||||||
|
if(ci->enc_get_inputs == NULL ||
|
||||||
|
ci->enc_set_parameters == NULL ||
|
||||||
|
ci->enc_alloc_chunk == NULL ||
|
||||||
|
ci->enc_free_chunk == NULL ||
|
||||||
|
ci->enc_wavbuf_near_empty == NULL ||
|
||||||
|
ci->enc_get_wav_data == NULL ||
|
||||||
|
ci->enc_set_header_callback == NULL )
|
||||||
|
return CODEC_ERROR;
|
||||||
|
|
||||||
|
ci->cpu_boost(true);
|
||||||
|
|
||||||
|
*ci->enc_set_header_callback = enc_set_header;
|
||||||
|
ci->enc_get_inputs(&enc_buffer_size, &enc_channels, &enc_quality);
|
||||||
|
|
||||||
|
/* configure the buffer system */
|
||||||
|
chunk_size = sizeof(long) + CHUNK_SIZE * enc_channels / 2;
|
||||||
|
num_chunks = enc_buffer_size / chunk_size;
|
||||||
|
samp_per_chunk = CHUNK_SIZE / 4;
|
||||||
|
|
||||||
|
/* inform the main program about buffer dimensions and other params */
|
||||||
|
/* add wav_header_mono as place holder to file start position */
|
||||||
|
/* wav header and wvpk header have to be reordered later */
|
||||||
|
ci->enc_set_parameters(chunk_size, num_chunks, samp_per_chunk,
|
||||||
|
wav_header_mono, sizeof(wav_header_mono),
|
||||||
|
AFMT_WAVPACK);
|
||||||
|
|
||||||
|
wpc = WavpackOpenFileOutput ();
|
||||||
|
|
||||||
|
memset (&config, 0, sizeof (config));
|
||||||
|
config.bits_per_sample = 16;
|
||||||
|
config.bytes_per_sample = 2;
|
||||||
|
config.sample_rate = 44100;
|
||||||
|
config.num_channels = enc_channels;
|
||||||
|
|
||||||
|
if (!WavpackSetConfiguration (wpc, &config, 1))
|
||||||
|
return CODEC_ERROR;
|
||||||
|
|
||||||
|
/* main application waits for this flag during encoder loading */
|
||||||
|
ci->enc_codec_loaded = true;
|
||||||
|
|
||||||
|
/* main encoding loop */
|
||||||
|
while(!ci->stop_codec)
|
||||||
|
{
|
||||||
|
while((src = (uint32*)ci->enc_get_wav_data(CHUNK_SIZE)) != NULL)
|
||||||
|
{
|
||||||
|
if(ci->stop_codec)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(ci->enc_wavbuf_near_empty() == 0)
|
||||||
|
{
|
||||||
|
if(!cpu_boosted)
|
||||||
|
{
|
||||||
|
ci->cpu_boost(true);
|
||||||
|
cpu_boosted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dst = (uint32*)ci->enc_alloc_chunk() + 1;
|
||||||
|
|
||||||
|
WavpackStartBlock (wpc, (uint8*)dst, (uint8*)dst + CHUNK_SIZE);
|
||||||
|
|
||||||
|
if(enc_channels == 2)
|
||||||
|
{
|
||||||
|
for (i=0; i<CHUNK_SIZE/4; i++)
|
||||||
|
{
|
||||||
|
t = (long)*src++;
|
||||||
|
|
||||||
|
input_buffer[2*i + 0] = t >> 16;
|
||||||
|
input_buffer[2*i + 1] = (short)t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i=0; i<CHUNK_SIZE/4; i++)
|
||||||
|
{
|
||||||
|
t = (long)*src++;
|
||||||
|
t = (((t<<16)>>16) + (t>>16)) >> 1; /* left+right */
|
||||||
|
|
||||||
|
input_buffer[i] = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!WavpackPackSamples (wpc, input_buffer, CHUNK_SIZE/4))
|
||||||
|
return CODEC_ERROR;
|
||||||
|
|
||||||
|
/* finish the chunk and store chunk size info */
|
||||||
|
dst[-1] = WavpackFinishBlock (wpc);
|
||||||
|
|
||||||
|
ci->enc_free_chunk();
|
||||||
|
ci->yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ci->enc_wavbuf_near_empty())
|
||||||
|
{
|
||||||
|
if(cpu_boosted)
|
||||||
|
{
|
||||||
|
ci->cpu_boost(false);
|
||||||
|
cpu_boosted = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ci->yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cpu_boosted) /* set initial boost state */
|
||||||
|
ci->cpu_boost(false);
|
||||||
|
|
||||||
|
/* reset parameters to initial state */
|
||||||
|
ci->enc_set_parameters(0, 0, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
/* main application waits for this flag during encoder removing */
|
||||||
|
ci->enc_codec_loaded = false;
|
||||||
|
|
||||||
|
return CODEC_OK;
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -445,9 +445,8 @@ int ft_enter(struct tree_context* c)
|
||||||
{
|
{
|
||||||
set_file(buf, global_settings.fmr_file, MAX_FILENAME);
|
set_file(buf, global_settings.fmr_file, MAX_FILENAME);
|
||||||
radio_load_presets(global_settings.fmr_file);
|
radio_load_presets(global_settings.fmr_file);
|
||||||
if(get_radio_status() != FMRADIO_PLAYING &&
|
if(!in_radio_screen())
|
||||||
get_radio_status() != FMRADIO_PAUSED)
|
radio_screen();
|
||||||
radio_screen();
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Preset outside default folder, we can choose such only
|
* Preset outside default folder, we can choose such only
|
||||||
|
|
|
@ -9661,6 +9661,22 @@
|
||||||
*: "Full Path"
|
*: "Full Path"
|
||||||
</voice>
|
</voice>
|
||||||
</phrase>
|
</phrase>
|
||||||
|
<<<<<<< english.lang
|
||||||
|
<phrase>
|
||||||
|
id: VOICE_KBIT_PER_SEC
|
||||||
|
desc: spoken only, for file extension
|
||||||
|
user:
|
||||||
|
<source>
|
||||||
|
*: ""
|
||||||
|
</source>
|
||||||
|
<dest>
|
||||||
|
*: ""
|
||||||
|
</dest>
|
||||||
|
<voice>
|
||||||
|
*: "kilobits per second"
|
||||||
|
</voice>
|
||||||
|
</phrase>
|
||||||
|
=======
|
||||||
<phrase>
|
<phrase>
|
||||||
id: LANG_RECORD_AGC_PRESET
|
id: LANG_RECORD_AGC_PRESET
|
||||||
desc: automatic gain control in record settings
|
desc: automatic gain control in record settings
|
||||||
|
@ -9778,3 +9794,4 @@
|
||||||
*: "AGC maximum gain"
|
*: "AGC maximum gain"
|
||||||
</voice>
|
</voice>
|
||||||
</phrase>
|
</phrase>
|
||||||
|
>>>>>>> 1.267
|
||||||
|
|
|
@ -285,9 +285,31 @@ static bool custom_theme_browse(void)
|
||||||
|
|
||||||
#ifdef HAVE_RECORDING
|
#ifdef HAVE_RECORDING
|
||||||
|
|
||||||
|
static bool rec_menu_recording_screen(void)
|
||||||
|
{
|
||||||
|
return recording_screen(false);
|
||||||
|
}
|
||||||
|
|
||||||
static bool recording_settings(void)
|
static bool recording_settings(void)
|
||||||
{
|
{
|
||||||
return recording_menu(false);
|
bool ret;
|
||||||
|
#ifdef HAVE_FMRADIO_IN
|
||||||
|
int rec_source = global_settings.rec_source;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ret = recording_menu(false);
|
||||||
|
|
||||||
|
#ifdef HAVE_FMRADIO_IN
|
||||||
|
if (rec_source != global_settings.rec_source)
|
||||||
|
{
|
||||||
|
if (rec_source == AUDIO_SRC_FMRADIO)
|
||||||
|
radio_stop();
|
||||||
|
/* If AUDIO_SRC_FMRADIO was selected from something else,
|
||||||
|
the recording screen will start the radio */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rec_menu(void)
|
bool rec_menu(void)
|
||||||
|
@ -297,7 +319,7 @@ bool rec_menu(void)
|
||||||
|
|
||||||
/* recording menu */
|
/* recording menu */
|
||||||
static const struct menu_item items[] = {
|
static const struct menu_item items[] = {
|
||||||
{ ID2P(LANG_RECORDING_MENU), recording_screen },
|
{ ID2P(LANG_RECORDING_MENU), rec_menu_recording_screen },
|
||||||
{ ID2P(LANG_RECORDING_SETTINGS), recording_settings},
|
{ ID2P(LANG_RECORDING_SETTINGS), recording_settings},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
217
apps/playback.c
217
apps/playback.c
|
@ -74,29 +74,18 @@
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
#include "metadata.h"
|
#include "metadata.h"
|
||||||
#include "talk.h"
|
|
||||||
#ifdef CONFIG_TUNER
|
|
||||||
#include "radio.h"
|
|
||||||
#endif
|
|
||||||
#include "splash.h"
|
#include "splash.h"
|
||||||
|
#include "talk.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_RECORDING
|
||||||
|
#include "recording.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
static volatile bool audio_codec_loaded;
|
static volatile bool audio_codec_loaded;
|
||||||
static volatile bool voice_codec_loaded;
|
static volatile bool voice_codec_loaded;
|
||||||
static volatile bool playing;
|
static volatile bool playing;
|
||||||
static volatile bool paused;
|
static volatile bool paused;
|
||||||
|
|
||||||
#define CODEC_VORBIS "/.rockbox/codecs/vorbis.codec"
|
|
||||||
#define CODEC_MPA_L3 "/.rockbox/codecs/mpa.codec"
|
|
||||||
#define CODEC_FLAC "/.rockbox/codecs/flac.codec"
|
|
||||||
#define CODEC_WAV "/.rockbox/codecs/wav.codec"
|
|
||||||
#define CODEC_A52 "/.rockbox/codecs/a52.codec"
|
|
||||||
#define CODEC_MPC "/.rockbox/codecs/mpc.codec"
|
|
||||||
#define CODEC_WAVPACK "/.rockbox/codecs/wavpack.codec"
|
|
||||||
#define CODEC_ALAC "/.rockbox/codecs/alac.codec"
|
|
||||||
#define CODEC_AAC "/.rockbox/codecs/aac.codec"
|
|
||||||
#define CODEC_SHN "/.rockbox/codecs/shorten.codec"
|
|
||||||
#define CODEC_AIFF "/.rockbox/codecs/aiff.codec"
|
|
||||||
#define CODEC_SID "/.rockbox/codecs/sid.codec"
|
|
||||||
|
|
||||||
/* default point to start buffer refill */
|
/* default point to start buffer refill */
|
||||||
#define AUDIO_DEFAULT_WATERMARK (1024*512)
|
#define AUDIO_DEFAULT_WATERMARK (1024*512)
|
||||||
|
@ -133,6 +122,11 @@ enum {
|
||||||
|
|
||||||
Q_CODEC_LOAD,
|
Q_CODEC_LOAD,
|
||||||
Q_CODEC_LOAD_DISK,
|
Q_CODEC_LOAD_DISK,
|
||||||
|
|
||||||
|
#if defined(HAVE_RECORDING) && !defined(SIMULATOR)
|
||||||
|
Q_ENCODER_LOAD_DISK,
|
||||||
|
Q_ENCODER_RECORD,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/* As defined in plugins/lib/xxx2wav.h */
|
/* As defined in plugins/lib/xxx2wav.h */
|
||||||
|
@ -382,7 +376,7 @@ static bool voice_pcmbuf_insert_split_callback(
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
} /* voice_pcmbuf_insert_split_callback */
|
||||||
|
|
||||||
static bool codec_pcmbuf_insert_split_callback(
|
static bool codec_pcmbuf_insert_split_callback(
|
||||||
const void *ch1, const void *ch2, size_t length)
|
const void *ch1, const void *ch2, size_t length)
|
||||||
|
@ -444,7 +438,7 @@ static bool codec_pcmbuf_insert_split_callback(
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
} /* codec_pcmbuf_insert_split_callback */
|
||||||
|
|
||||||
static bool voice_pcmbuf_insert_callback(const char *buf, size_t length)
|
static bool voice_pcmbuf_insert_callback(const char *buf, size_t length)
|
||||||
{
|
{
|
||||||
|
@ -649,7 +643,7 @@ static size_t codec_filebuf_callback(void *ptr, size_t size)
|
||||||
|
|
||||||
/* Return the actual amount of data copied to the buffer */
|
/* Return the actual amount of data copied to the buffer */
|
||||||
return copy_n;
|
return copy_n;
|
||||||
}
|
} /* codec_filebuf_callback */
|
||||||
|
|
||||||
static void* voice_request_buffer_callback(size_t *realsize, size_t reqsize)
|
static void* voice_request_buffer_callback(size_t *realsize, size_t reqsize)
|
||||||
{
|
{
|
||||||
|
@ -664,7 +658,9 @@ static void* voice_request_buffer_callback(size_t *realsize, size_t reqsize)
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
if (voice_is_playing)
|
if (voice_is_playing)
|
||||||
|
{
|
||||||
queue_wait_w_tmo(&voice_codec_queue, &ev, 0);
|
queue_wait_w_tmo(&voice_codec_queue, &ev, 0);
|
||||||
|
}
|
||||||
else if (playing)
|
else if (playing)
|
||||||
{
|
{
|
||||||
queue_wait_w_tmo(&voice_codec_queue, &ev, 0);
|
queue_wait_w_tmo(&voice_codec_queue, &ev, 0);
|
||||||
|
@ -679,7 +675,11 @@ static void* voice_request_buffer_callback(size_t *realsize, size_t reqsize)
|
||||||
if (playing)
|
if (playing)
|
||||||
swap_codec();
|
swap_codec();
|
||||||
break;
|
break;
|
||||||
|
#if defined(HAVE_RECORDING) && !defined(SIMULATOR)
|
||||||
|
case Q_ENCODER_RECORD:
|
||||||
|
swap_codec();
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
case Q_VOICE_STOP:
|
case Q_VOICE_STOP:
|
||||||
if (voice_is_playing)
|
if (voice_is_playing)
|
||||||
{
|
{
|
||||||
|
@ -743,7 +743,7 @@ voice_play_clip:
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return voicebuf;
|
return voicebuf;
|
||||||
}
|
} /* voice_request_buffer_callback */
|
||||||
|
|
||||||
static void* codec_request_buffer_callback(size_t *realsize, size_t reqsize)
|
static void* codec_request_buffer_callback(size_t *realsize, size_t reqsize)
|
||||||
{
|
{
|
||||||
|
@ -794,7 +794,7 @@ static void* codec_request_buffer_callback(size_t *realsize, size_t reqsize)
|
||||||
*realsize = copy_n;
|
*realsize = copy_n;
|
||||||
|
|
||||||
return (char *)&filebuf[buf_ridx];
|
return (char *)&filebuf[buf_ridx];
|
||||||
}
|
} /* codec_request_buffer_callback */
|
||||||
|
|
||||||
static int get_codec_base_type(int type)
|
static int get_codec_base_type(int type)
|
||||||
{
|
{
|
||||||
|
@ -1531,52 +1531,24 @@ static void codec_discard_codec_callback(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *get_codec_path(int codectype)
|
static const char * get_codec_filename(int enc_spec)
|
||||||
{
|
{
|
||||||
switch (codectype) {
|
const char *fname;
|
||||||
case AFMT_OGG_VORBIS:
|
int type = enc_spec & CODEC_TYPE_MASK;
|
||||||
logf("Codec: Vorbis");
|
int afmt = enc_spec & CODEC_AFMT_MASK;
|
||||||
return CODEC_VORBIS;
|
|
||||||
case AFMT_MPA_L1:
|
if ((unsigned)afmt >= AFMT_NUM_CODECS)
|
||||||
case AFMT_MPA_L2:
|
type = AFMT_UNKNOWN | (type & CODEC_TYPE_MASK);
|
||||||
case AFMT_MPA_L3:
|
|
||||||
logf("Codec: MPA L1/L2/L3");
|
fname = (type == CODEC_TYPE_DECODER) ?
|
||||||
return CODEC_MPA_L3;
|
audio_formats[afmt].codec_fn : audio_formats[afmt].codec_enc_fn;
|
||||||
case AFMT_PCM_WAV:
|
|
||||||
logf("Codec: PCM WAV");
|
logf("%s: %d - %s",
|
||||||
return CODEC_WAV;
|
(type == CODEC_TYPE_ENCODER) ? "Encoder" : "Decoder",
|
||||||
case AFMT_FLAC:
|
afmt, fname ? fname : "<unknown>");
|
||||||
logf("Codec: FLAC");
|
|
||||||
return CODEC_FLAC;
|
return fname;
|
||||||
case AFMT_A52:
|
} /* get_codec_filename */
|
||||||
logf("Codec: A52");
|
|
||||||
return CODEC_A52;
|
|
||||||
case AFMT_MPC:
|
|
||||||
logf("Codec: Musepack");
|
|
||||||
return CODEC_MPC;
|
|
||||||
case AFMT_WAVPACK:
|
|
||||||
logf("Codec: WAVPACK");
|
|
||||||
return CODEC_WAVPACK;
|
|
||||||
case AFMT_ALAC:
|
|
||||||
logf("Codec: ALAC");
|
|
||||||
return CODEC_ALAC;
|
|
||||||
case AFMT_AAC:
|
|
||||||
logf("Codec: AAC");
|
|
||||||
return CODEC_AAC;
|
|
||||||
case AFMT_SHN:
|
|
||||||
logf("Codec: SHN");
|
|
||||||
return CODEC_SHN;
|
|
||||||
case AFMT_AIFF:
|
|
||||||
logf("Codec: PCM AIFF");
|
|
||||||
return CODEC_AIFF;
|
|
||||||
case AFMT_SID:
|
|
||||||
logf("Codec: SID");
|
|
||||||
return CODEC_SID;
|
|
||||||
default:
|
|
||||||
logf("Codec: Unsupported");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool loadcodec(bool start_play)
|
static bool loadcodec(bool start_play)
|
||||||
{
|
{
|
||||||
|
@ -1585,9 +1557,10 @@ static bool loadcodec(bool start_play)
|
||||||
int rc;
|
int rc;
|
||||||
size_t copy_n;
|
size_t copy_n;
|
||||||
int prev_track;
|
int prev_track;
|
||||||
|
char codec_path[MAX_PATH]; /* Full path to codec */
|
||||||
|
|
||||||
const char *codec_path = get_codec_path(tracks[track_widx].id3.codectype);
|
const char * codec_fn = get_codec_filename(tracks[track_widx].id3.codectype);
|
||||||
if (codec_path == NULL)
|
if (codec_fn == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
tracks[track_widx].has_codec = false;
|
tracks[track_widx].has_codec = false;
|
||||||
|
@ -1603,7 +1576,7 @@ static bool loadcodec(bool start_play)
|
||||||
ci.taginfo_ready = &cur_ti->taginfo_ready;
|
ci.taginfo_ready = &cur_ti->taginfo_ready;
|
||||||
ci.curpos = 0;
|
ci.curpos = 0;
|
||||||
playing = true;
|
playing = true;
|
||||||
queue_post(&codec_queue, Q_CODEC_LOAD_DISK, (void *)codec_path);
|
queue_post(&codec_queue, Q_CODEC_LOAD_DISK, (void *)codec_fn);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1625,6 +1598,8 @@ static bool loadcodec(bool start_play)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
codec_get_full_path(codec_path, codec_fn);
|
||||||
|
|
||||||
fd = open(codec_path, O_RDONLY);
|
fd = open(codec_path, O_RDONLY);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
|
@ -1973,11 +1948,8 @@ static void audio_stop_playback(void)
|
||||||
(playlist_end && ci.stop_codec)?NULL:audio_current_track());
|
(playlist_end && ci.stop_codec)?NULL:audio_current_track());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (voice_is_playing)
|
while (voice_is_playing && !queue_empty(&voice_codec_queue))
|
||||||
{
|
yield();
|
||||||
while (voice_is_playing && !queue_empty(&voice_codec_queue))
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
|
|
||||||
filebufused = 0;
|
filebufused = 0;
|
||||||
playing = false;
|
playing = false;
|
||||||
|
@ -1998,10 +1970,8 @@ static void audio_stop_playback(void)
|
||||||
|
|
||||||
static void audio_play_start(size_t offset)
|
static void audio_play_start(size_t offset)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_TUNER
|
#if defined(HAVE_RECORDING) || defined(CONFIG_TUNER)
|
||||||
/* check if radio is playing */
|
rec_set_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
|
||||||
if (get_radio_status() != FMRADIO_OFF)
|
|
||||||
radio_stop();
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Wait for any previously playing audio to flush - TODO: Not necessary? */
|
/* Wait for any previously playing audio to flush - TODO: Not necessary? */
|
||||||
|
@ -2483,6 +2453,20 @@ static void codec_thread(void)
|
||||||
mutex_unlock(&mutex_codecthread);
|
mutex_unlock(&mutex_codecthread);
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
|
#if defined(HAVE_RECORDING) && !defined(SIMULATOR)
|
||||||
|
case Q_ENCODER_LOAD_DISK:
|
||||||
|
logf("Encoder load disk");
|
||||||
|
audio_codec_loaded = false;
|
||||||
|
if (voice_codec_loaded && current_codec == CODEC_IDX_VOICE)
|
||||||
|
queue_post(&voice_codec_queue, Q_ENCODER_RECORD, NULL);
|
||||||
|
mutex_lock(&mutex_codecthread);
|
||||||
|
current_codec = CODEC_IDX_AUDIO;
|
||||||
|
ci.stop_codec = false;
|
||||||
|
status = codec_load_file((const char *)ev.data, &ci);
|
||||||
|
mutex_unlock(&mutex_codecthread);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef SIMULATOR
|
#ifndef SIMULATOR
|
||||||
case SYS_USB_CONNECTED:
|
case SYS_USB_CONNECTED:
|
||||||
queue_clear(&codec_queue);
|
queue_clear(&codec_queue);
|
||||||
|
@ -2511,8 +2495,6 @@ static void codec_thread(void)
|
||||||
case Q_CODEC_LOAD:
|
case Q_CODEC_LOAD:
|
||||||
if (playing)
|
if (playing)
|
||||||
{
|
{
|
||||||
const char *codec_path;
|
|
||||||
|
|
||||||
if (ci.new_track || status != CODEC_OK)
|
if (ci.new_track || status != CODEC_OK)
|
||||||
{
|
{
|
||||||
if (!ci.new_track)
|
if (!ci.new_track)
|
||||||
|
@ -2523,7 +2505,8 @@ static void codec_thread(void)
|
||||||
|
|
||||||
if (!load_next_track())
|
if (!load_next_track())
|
||||||
{
|
{
|
||||||
queue_post(&codec_queue, Q_AUDIO_STOP, 0);
|
// queue_post(&codec_queue, Q_AUDIO_STOP, 0);
|
||||||
|
queue_post(&audio_queue, Q_AUDIO_STOP, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2545,12 +2528,12 @@ static void codec_thread(void)
|
||||||
queue_post(&codec_queue, Q_CODEC_LOAD, 0);
|
queue_post(&codec_queue, Q_CODEC_LOAD, 0);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
codec_path = get_codec_path(cur_ti->id3.codectype);
|
const char *codec_fn = get_codec_filename(cur_ti->id3.codectype);
|
||||||
queue_post(&codec_queue,
|
queue_post(&codec_queue, Q_CODEC_LOAD_DISK,
|
||||||
Q_CODEC_LOAD_DISK, (void *)codec_path);
|
(void *)codec_fn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} /* end switch */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2596,6 +2579,37 @@ static void reset_buffer(void)
|
||||||
filebuflen &= ~3;
|
filebuflen &= ~3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void audio_load_encoder(int enc_id)
|
||||||
|
{
|
||||||
|
#if defined(HAVE_RECORDING) && !defined(SIMULATOR)
|
||||||
|
const char *enc_fn = get_codec_filename(enc_id | CODEC_TYPE_ENCODER);
|
||||||
|
if (!enc_fn)
|
||||||
|
return;
|
||||||
|
|
||||||
|
audio_remove_encoder();
|
||||||
|
|
||||||
|
queue_post(&codec_queue, Q_ENCODER_LOAD_DISK, (void *)enc_fn);
|
||||||
|
|
||||||
|
while (!ci.enc_codec_loaded)
|
||||||
|
yield();
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
(void)enc_id;
|
||||||
|
} /* audio_load_encoder */
|
||||||
|
|
||||||
|
void audio_remove_encoder(void)
|
||||||
|
{
|
||||||
|
#if defined(HAVE_RECORDING) && !defined(SIMULATOR)
|
||||||
|
/* force encoder codec unload (if previously loaded) */
|
||||||
|
if (!ci.enc_codec_loaded)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ci.stop_codec = true;
|
||||||
|
while (ci.enc_codec_loaded)
|
||||||
|
yield();
|
||||||
|
#endif
|
||||||
|
} /* audio_remove_encoder */
|
||||||
|
|
||||||
static void voice_codec_thread(void)
|
static void voice_codec_thread(void)
|
||||||
{
|
{
|
||||||
while (1)
|
while (1)
|
||||||
|
@ -2608,13 +2622,13 @@ static void voice_codec_thread(void)
|
||||||
voice_remaining = 0;
|
voice_remaining = 0;
|
||||||
voice_getmore = NULL;
|
voice_getmore = NULL;
|
||||||
|
|
||||||
codec_load_file(CODEC_MPA_L3, &ci_voice);
|
codec_load_file(get_codec_filename(AFMT_MPA_L3), &ci_voice);
|
||||||
|
|
||||||
logf("Voice codec finished");
|
logf("Voice codec finished");
|
||||||
mutex_unlock(&mutex_codecthread);
|
|
||||||
voice_codec_loaded = false;
|
voice_codec_loaded = false;
|
||||||
|
mutex_unlock(&mutex_codecthread);
|
||||||
}
|
}
|
||||||
}
|
} /* voice_codec_thread */
|
||||||
|
|
||||||
void voice_init(void)
|
void voice_init(void)
|
||||||
{
|
{
|
||||||
|
@ -2642,7 +2656,20 @@ void voice_init(void)
|
||||||
|
|
||||||
while (!voice_codec_loaded)
|
while (!voice_codec_loaded)
|
||||||
yield();
|
yield();
|
||||||
}
|
} /* voice_init */
|
||||||
|
|
||||||
|
void voice_stop(void)
|
||||||
|
{
|
||||||
|
/* Messages should not be posted to voice codec queue unless it is the
|
||||||
|
current codec or deadlocks happen. This will be addressed globally soon.
|
||||||
|
-- jhMikeS */
|
||||||
|
if (current_codec != CODEC_IDX_VOICE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mp3_play_stop();
|
||||||
|
while (voice_is_playing && !queue_empty(&voice_codec_queue))
|
||||||
|
yield();
|
||||||
|
} /* voice_stop */
|
||||||
|
|
||||||
struct mp3entry* audio_current_track(void)
|
struct mp3entry* audio_current_track(void)
|
||||||
{
|
{
|
||||||
|
@ -2803,9 +2830,19 @@ int audio_status(void)
|
||||||
if (paused)
|
if (paused)
|
||||||
ret |= AUDIO_STATUS_PAUSE;
|
ret |= AUDIO_STATUS_PAUSE;
|
||||||
|
|
||||||
|
#ifdef HAVE_RECORDING
|
||||||
|
/* Do this here for constitency with mpeg.c version */
|
||||||
|
ret |= pcm_rec_status();
|
||||||
|
#endif
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool audio_query_poweroff(void)
|
||||||
|
{
|
||||||
|
return !(playing && paused);
|
||||||
|
}
|
||||||
|
|
||||||
int audio_get_file_pos(void)
|
int audio_get_file_pos(void)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -27,8 +27,8 @@
|
||||||
#include "id3.h"
|
#include "id3.h"
|
||||||
#include "mp3data.h"
|
#include "mp3data.h"
|
||||||
|
|
||||||
#define CODEC_IDX_AUDIO 0
|
#define CODEC_IDX_AUDIO 0
|
||||||
#define CODEC_IDX_VOICE 1
|
#define CODEC_IDX_VOICE 1
|
||||||
|
|
||||||
/* Not yet implemented. */
|
/* Not yet implemented. */
|
||||||
#define CODEC_SET_AUDIOBUF_WATERMARK 4
|
#define CODEC_SET_AUDIOBUF_WATERMARK 4
|
||||||
|
@ -66,6 +66,7 @@ void audio_set_track_unbuffer_event(void (*handler)(struct mp3entry *id3,
|
||||||
bool last_track));
|
bool last_track));
|
||||||
void audio_invalidate_tracks(void);
|
void audio_invalidate_tracks(void);
|
||||||
void voice_init(void);
|
void voice_init(void);
|
||||||
|
void voice_stop(void);
|
||||||
|
|
||||||
#if CONFIG_CODEC == SWCODEC /* This #ifdef is better here than gui/gwps.c */
|
#if CONFIG_CODEC == SWCODEC /* This #ifdef is better here than gui/gwps.c */
|
||||||
extern void audio_next_dir(void);
|
extern void audio_next_dir(void);
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#include "mas.h"
|
#include "mas.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "button.h"
|
#include "button.h"
|
||||||
#include "fmradio.h"
|
|
||||||
#include "status.h"
|
#include "status.h"
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "mpeg.h"
|
#include "mpeg.h"
|
||||||
|
@ -63,17 +62,6 @@
|
||||||
|
|
||||||
#ifdef CONFIG_TUNER
|
#ifdef CONFIG_TUNER
|
||||||
|
|
||||||
#if CONFIG_CODEC == SWCODEC
|
|
||||||
#ifdef HAVE_UDA1380
|
|
||||||
#include "uda1380.h"
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_TLV320
|
|
||||||
#include "tlv320.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "pcm_record.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CONFIG_KEYPAD == RECORDER_PAD
|
#if CONFIG_KEYPAD == RECORDER_PAD
|
||||||
#define FM_MENU BUTTON_F1
|
#define FM_MENU BUTTON_F1
|
||||||
#define FM_PRESET BUTTON_F2
|
#define FM_PRESET BUTTON_F2
|
||||||
|
@ -165,6 +153,7 @@ static int curr_freq;
|
||||||
static int radio_mode = RADIO_SCAN_MODE;
|
static int radio_mode = RADIO_SCAN_MODE;
|
||||||
|
|
||||||
static int radio_status = FMRADIO_OFF;
|
static int radio_status = FMRADIO_OFF;
|
||||||
|
static bool in_screen = false;
|
||||||
|
|
||||||
#define MAX_PRESETS 64
|
#define MAX_PRESETS 64
|
||||||
static bool presets_loaded = false, presets_changed = false;
|
static bool presets_loaded = false, presets_changed = false;
|
||||||
|
@ -239,22 +228,87 @@ int get_radio_status(void)
|
||||||
return radio_status;
|
return radio_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool in_radio_screen(void)
|
||||||
|
{
|
||||||
|
return in_screen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* secret flag for starting paused - prevents unmute */
|
||||||
|
#define FMRADIO_START_PAUSED 0x8000
|
||||||
|
void radio_start(void)
|
||||||
|
{
|
||||||
|
bool start_paused;
|
||||||
|
int mute_timeout;
|
||||||
|
|
||||||
|
if(radio_status == FMRADIO_PLAYING)
|
||||||
|
return;
|
||||||
|
|
||||||
|
start_paused = radio_status & FMRADIO_START_PAUSED;
|
||||||
|
/* clear flag before any yielding */
|
||||||
|
radio_status &= ~FMRADIO_START_PAUSED;
|
||||||
|
|
||||||
|
if(radio_status == FMRADIO_OFF)
|
||||||
|
radio_power(true);
|
||||||
|
|
||||||
|
curr_freq = global_settings.last_frequency * FREQ_STEP + MIN_FREQ;
|
||||||
|
|
||||||
|
radio_set(RADIO_SLEEP, 0); /* wake up the tuner */
|
||||||
|
radio_set(RADIO_FREQUENCY, curr_freq);
|
||||||
|
|
||||||
|
if(radio_status == FMRADIO_OFF)
|
||||||
|
{
|
||||||
|
radio_set(RADIO_IF_MEASUREMENT, 0);
|
||||||
|
radio_set(RADIO_SENSITIVITY, 0);
|
||||||
|
radio_set(RADIO_FORCE_MONO, global_settings.fm_force_mono);
|
||||||
|
mute_timeout = current_tick + 1*HZ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* paused */
|
||||||
|
mute_timeout = current_tick + 2*HZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(!radio_get(RADIO_STEREO) && !radio_get(RADIO_TUNED))
|
||||||
|
{
|
||||||
|
if(TIME_AFTER(current_tick, mute_timeout))
|
||||||
|
break;
|
||||||
|
yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* keep radio from sounding initially */
|
||||||
|
if(!start_paused)
|
||||||
|
radio_set(RADIO_MUTE, 0);
|
||||||
|
|
||||||
|
radio_status = FMRADIO_PLAYING;
|
||||||
|
} /* radio_start */
|
||||||
|
|
||||||
|
void radio_pause(void)
|
||||||
|
{
|
||||||
|
if(radio_status == FMRADIO_PAUSED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(radio_status == FMRADIO_OFF)
|
||||||
|
{
|
||||||
|
radio_status |= FMRADIO_START_PAUSED;
|
||||||
|
radio_start();
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_set(RADIO_MUTE, 1);
|
||||||
|
radio_set(RADIO_SLEEP, 1);
|
||||||
|
|
||||||
|
radio_status = FMRADIO_PAUSED;
|
||||||
|
} /* radio_pause */
|
||||||
|
|
||||||
void radio_stop(void)
|
void radio_stop(void)
|
||||||
{
|
{
|
||||||
|
if(radio_status == FMRADIO_OFF)
|
||||||
|
return;
|
||||||
|
|
||||||
radio_set(RADIO_MUTE, 1);
|
radio_set(RADIO_MUTE, 1);
|
||||||
radio_set(RADIO_SLEEP, 1); /* low power mode, if available */
|
radio_set(RADIO_SLEEP, 1); /* low power mode, if available */
|
||||||
radio_status = FMRADIO_OFF;
|
radio_status = FMRADIO_OFF;
|
||||||
radio_power(false); /* status update, power off if avail. */
|
radio_power(false); /* status update, power off if avail. */
|
||||||
|
} /* radio_stop */
|
||||||
#ifndef SIMULATOR /* SIMULATOR. Catch FMRADIO_OFF status for the sim. */
|
|
||||||
#if CONFIG_CODEC == SWCODEC
|
|
||||||
#ifdef HAVE_TLV320
|
|
||||||
tlv320_set_monitor(false);
|
|
||||||
#endif
|
|
||||||
pcm_rec_mux(0); /* Line In */
|
|
||||||
#endif
|
|
||||||
#endif /* SIMULATOR */
|
|
||||||
}
|
|
||||||
|
|
||||||
bool radio_hardware_present(void)
|
bool radio_hardware_present(void)
|
||||||
{
|
{
|
||||||
|
@ -297,7 +351,7 @@ static int find_closest_preset(int freq)
|
||||||
return i;
|
return i;
|
||||||
if(diff < 0)
|
if(diff < 0)
|
||||||
diff = -diff;
|
diff = -diff;
|
||||||
if(diff < min_diff)
|
if(diff < min_diff)
|
||||||
{
|
{
|
||||||
preset = i;
|
preset = i;
|
||||||
min_diff = diff;
|
min_diff = diff;
|
||||||
|
@ -307,8 +361,6 @@ static int find_closest_preset(int freq)
|
||||||
return preset;
|
return preset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void remember_frequency(void)
|
static void remember_frequency(void)
|
||||||
{
|
{
|
||||||
global_settings.last_frequency = (curr_freq - MIN_FREQ) / FREQ_STEP;
|
global_settings.last_frequency = (curr_freq - MIN_FREQ) / FREQ_STEP;
|
||||||
|
@ -366,13 +418,15 @@ bool radio_screen(void)
|
||||||
#endif
|
#endif
|
||||||
bool keep_playing = false;
|
bool keep_playing = false;
|
||||||
bool statusbar = global_settings.statusbar;
|
bool statusbar = global_settings.statusbar;
|
||||||
int mute_timeout = current_tick;
|
|
||||||
int button_timeout = current_tick + (2*HZ);
|
int button_timeout = current_tick + (2*HZ);
|
||||||
#ifdef HAS_BUTTONBAR
|
#ifdef HAS_BUTTONBAR
|
||||||
struct gui_buttonbar buttonbar;
|
struct gui_buttonbar buttonbar;
|
||||||
gui_buttonbar_init(&buttonbar);
|
gui_buttonbar_init(&buttonbar);
|
||||||
gui_buttonbar_set_display(&buttonbar, &(screens[SCREEN_MAIN]) );
|
gui_buttonbar_set_display(&buttonbar, &(screens[SCREEN_MAIN]) );
|
||||||
#endif
|
#endif
|
||||||
|
/* change status to "in screen" */
|
||||||
|
in_screen = true;
|
||||||
|
|
||||||
/* always display status bar in radio screen for now */
|
/* always display status bar in radio screen for now */
|
||||||
global_settings.statusbar = true;
|
global_settings.statusbar = true;
|
||||||
FOR_NB_SCREENS(i)
|
FOR_NB_SCREENS(i)
|
||||||
|
@ -396,20 +450,13 @@ bool radio_screen(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SIMULATOR
|
#ifndef SIMULATOR
|
||||||
#if CONFIG_CODEC != SWCODEC
|
|
||||||
if(rec_create_directory() > 0)
|
|
||||||
have_recorded = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(radio_status == FMRADIO_PLAYING_OUT)
|
|
||||||
radio_status = FMRADIO_PLAYING;
|
|
||||||
else if(radio_status == FMRADIO_PAUSED_OUT)
|
|
||||||
radio_status = FMRADIO_PAUSED;
|
|
||||||
|
|
||||||
if(radio_status == FMRADIO_OFF)
|
if(radio_status == FMRADIO_OFF)
|
||||||
audio_stop();
|
audio_stop();
|
||||||
|
|
||||||
#if CONFIG_CODEC != SWCODEC
|
#if CONFIG_CODEC != SWCODEC
|
||||||
|
if(rec_create_directory() > 0)
|
||||||
|
have_recorded = true;
|
||||||
|
|
||||||
audio_init_recording(talk_get_bufsize());
|
audio_init_recording(talk_get_bufsize());
|
||||||
|
|
||||||
sound_settings_apply();
|
sound_settings_apply();
|
||||||
|
@ -418,58 +465,29 @@ bool radio_screen(void)
|
||||||
|
|
||||||
peak_meter_enabled = true;
|
peak_meter_enabled = true;
|
||||||
|
|
||||||
if (global_settings.rec_prerecord_time)
|
rec_set_recording_options(global_settings.rec_frequency,
|
||||||
talk_buffer_steal(); /* will use the mp3 buffer */
|
global_settings.rec_quality,
|
||||||
|
AUDIO_SRC_LINEIN, 0,
|
||||||
|
global_settings.rec_channels,
|
||||||
|
global_settings.rec_editable,
|
||||||
|
global_settings.rec_prerecord_time);
|
||||||
|
|
||||||
audio_set_recording_options(global_settings.rec_frequency,
|
|
||||||
global_settings.rec_quality,
|
|
||||||
1, /* Line In */
|
|
||||||
global_settings.rec_channels,
|
|
||||||
global_settings.rec_editable,
|
|
||||||
global_settings.rec_prerecord_time);
|
|
||||||
|
|
||||||
|
|
||||||
#else
|
|
||||||
peak_meter_enabled = false;
|
|
||||||
|
|
||||||
#ifdef HAVE_UDA1380
|
|
||||||
uda1380_enable_recording(false);
|
|
||||||
uda1380_set_monitor(true);
|
|
||||||
#elif defined(HAVE_TLV320)
|
|
||||||
//tlv320_enable_recording(false);
|
|
||||||
tlv320_set_recvol(23, 23, AUDIO_GAIN_LINEIN); /* 0dB */
|
|
||||||
tlv320_set_monitor(true);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Set the input multiplexer to FM */
|
|
||||||
pcm_rec_mux(1);
|
|
||||||
#endif
|
|
||||||
audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN),
|
audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN),
|
||||||
sound_default(SOUND_RIGHT_GAIN), AUDIO_GAIN_LINEIN);
|
sound_default(SOUND_RIGHT_GAIN), AUDIO_GAIN_LINEIN);
|
||||||
|
|
||||||
|
#endif /* CONFIG_CODEC != SWCODEC */
|
||||||
|
#endif /* ndef SIMULATOR */
|
||||||
|
|
||||||
|
/* turn on radio */
|
||||||
|
#if CONFIG_CODEC == SWCODEC
|
||||||
|
rec_set_source(AUDIO_SRC_FMRADIO, (radio_status == FMRADIO_PAUSED) ?
|
||||||
|
SRCF_FMRADIO_PAUSED : SRCF_FMRADIO_PLAYING);
|
||||||
|
#else
|
||||||
|
if (radio_status == FMRADIO_OFF)
|
||||||
|
radio_start();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
curr_freq = global_settings.last_frequency * FREQ_STEP + MIN_FREQ;
|
/* I hate this thing with vehement passion (jhMikeS): */
|
||||||
|
|
||||||
if(radio_status == FMRADIO_OFF)
|
|
||||||
{
|
|
||||||
radio_power(true);
|
|
||||||
radio_set(RADIO_SLEEP, 0); /* wake up the tuner */
|
|
||||||
radio_set(RADIO_FREQUENCY, curr_freq);
|
|
||||||
radio_set(RADIO_IF_MEASUREMENT, 0);
|
|
||||||
radio_set(RADIO_SENSITIVITY, 0);
|
|
||||||
radio_set(RADIO_FORCE_MONO, global_settings.fm_force_mono);
|
|
||||||
mute_timeout = current_tick + (1*HZ);
|
|
||||||
while( !radio_get(RADIO_STEREO)
|
|
||||||
&&!radio_get(RADIO_TUNED) )
|
|
||||||
{
|
|
||||||
if(TIME_AFTER(current_tick, mute_timeout))
|
|
||||||
break;
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
radio_set(RADIO_MUTE, 0);
|
|
||||||
radio_status = FMRADIO_PLAYING;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(num_presets == 0 && yesno_pop(str(LANG_FM_FIRST_AUTOSCAN)))
|
if(num_presets == 0 && yesno_pop(str(LANG_FM_FIRST_AUTOSCAN)))
|
||||||
scan_presets();
|
scan_presets();
|
||||||
|
|
||||||
|
@ -478,8 +496,8 @@ bool radio_screen(void)
|
||||||
radio_mode = RADIO_PRESET_MODE;
|
radio_mode = RADIO_PRESET_MODE;
|
||||||
|
|
||||||
#ifdef HAS_BUTTONBAR
|
#ifdef HAS_BUTTONBAR
|
||||||
gui_buttonbar_set(&buttonbar, str(LANG_BUTTONBAR_MENU), str(LANG_FM_BUTTONBAR_PRESETS),
|
gui_buttonbar_set(&buttonbar, str(LANG_BUTTONBAR_MENU),
|
||||||
str(LANG_FM_BUTTONBAR_RECORD));
|
str(LANG_FM_BUTTONBAR_PRESETS), str(LANG_FM_BUTTONBAR_RECORD));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cpu_idle_mode(true);
|
cpu_idle_mode(true);
|
||||||
|
@ -535,7 +553,7 @@ bool radio_screen(void)
|
||||||
if (lastbutton != FM_STOP_PRE)
|
if (lastbutton != FM_STOP_PRE)
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifndef SIMULATOR
|
#if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
|
||||||
if(audio_status() == AUDIO_STATUS_RECORD)
|
if(audio_status() == AUDIO_STATUS_RECORD)
|
||||||
{
|
{
|
||||||
audio_stop();
|
audio_stop();
|
||||||
|
@ -548,7 +566,7 @@ bool radio_screen(void)
|
||||||
{
|
{
|
||||||
if(yesno_pop(str(LANG_FM_SAVE_CHANGES)))
|
if(yesno_pop(str(LANG_FM_SAVE_CHANGES)))
|
||||||
{
|
{
|
||||||
if(filepreset[0] == '\0')
|
if(filepreset[0] == '\0')
|
||||||
save_preset_list();
|
save_preset_list();
|
||||||
else
|
else
|
||||||
radio_save_presets();
|
radio_save_presets();
|
||||||
|
@ -577,14 +595,13 @@ bool radio_screen(void)
|
||||||
#ifndef SIMULATOR
|
#ifndef SIMULATOR
|
||||||
if(audio_status() == AUDIO_STATUS_RECORD)
|
if(audio_status() == AUDIO_STATUS_RECORD)
|
||||||
{
|
{
|
||||||
audio_new_file(rec_create_filename(buf));
|
rec_new_file();
|
||||||
update_screen = true;
|
update_screen = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
have_recorded = true;
|
have_recorded = true;
|
||||||
talk_buffer_steal(); /* we use the mp3 buffer */
|
rec_record();
|
||||||
audio_record(rec_create_filename(buf));
|
|
||||||
update_screen = true;
|
update_screen = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -604,7 +621,7 @@ bool radio_screen(void)
|
||||||
)
|
)
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifndef SIMULATOR
|
#if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
|
||||||
if(audio_status() == AUDIO_STATUS_RECORD)
|
if(audio_status() == AUDIO_STATUS_RECORD)
|
||||||
audio_stop();
|
audio_stop();
|
||||||
#endif
|
#endif
|
||||||
|
@ -615,7 +632,7 @@ bool radio_screen(void)
|
||||||
{
|
{
|
||||||
if(yesno_pop(str(LANG_FM_SAVE_CHANGES)))
|
if(yesno_pop(str(LANG_FM_SAVE_CHANGES)))
|
||||||
{
|
{
|
||||||
if(filepreset[0] == '\0')
|
if(filepreset[0] == '\0')
|
||||||
save_preset_list();
|
save_preset_list();
|
||||||
else
|
else
|
||||||
radio_save_presets();
|
radio_save_presets();
|
||||||
|
@ -734,27 +751,11 @@ bool radio_screen(void)
|
||||||
)
|
)
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
if(radio_status != FMRADIO_PLAYING)
|
if (radio_status == FMRADIO_PLAYING)
|
||||||
{
|
radio_pause();
|
||||||
radio_set(RADIO_SLEEP, 0);
|
|
||||||
radio_set(RADIO_FREQUENCY, curr_freq);
|
|
||||||
mute_timeout = current_tick + (2*HZ);
|
|
||||||
while( !radio_get(RADIO_STEREO)
|
|
||||||
&&!radio_get(RADIO_TUNED) )
|
|
||||||
{
|
|
||||||
if(TIME_AFTER(current_tick, mute_timeout))
|
|
||||||
break;
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
radio_set(RADIO_MUTE, 0);
|
|
||||||
radio_status = FMRADIO_PLAYING;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
radio_start();
|
||||||
radio_set(RADIO_MUTE, 1);
|
|
||||||
radio_set(RADIO_SLEEP, 1);
|
|
||||||
radio_status = FMRADIO_PAUSED;
|
|
||||||
}
|
|
||||||
update_screen = true;
|
update_screen = true;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
@ -918,12 +919,16 @@ bool radio_screen(void)
|
||||||
{
|
{
|
||||||
timeout = current_tick + HZ;
|
timeout = current_tick + HZ;
|
||||||
|
|
||||||
stereo = radio_get(RADIO_STEREO) &&
|
/* keep "mono" from always being displayed when paused */
|
||||||
!global_settings.fm_force_mono;
|
if (radio_status != FMRADIO_PAUSED)
|
||||||
if(stereo != last_stereo_status)
|
|
||||||
{
|
{
|
||||||
update_screen = true;
|
stereo = radio_get(RADIO_STEREO) &&
|
||||||
last_stereo_status = stereo;
|
!global_settings.fm_force_mono;
|
||||||
|
if(stereo != last_stereo_status)
|
||||||
|
{
|
||||||
|
update_screen = true;
|
||||||
|
last_stereo_status = stereo;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -952,9 +957,6 @@ bool radio_screen(void)
|
||||||
FOR_NB_SCREENS(i)
|
FOR_NB_SCREENS(i)
|
||||||
screens[i].puts_scroll(0, top_of_screen + 1, buf);
|
screens[i].puts_scroll(0, top_of_screen + 1, buf);
|
||||||
|
|
||||||
strcat(buf, stereo?str(LANG_CHANNEL_STEREO):
|
|
||||||
str(LANG_CHANNEL_MONO));
|
|
||||||
|
|
||||||
snprintf(buf, 128, stereo?str(LANG_CHANNEL_STEREO):
|
snprintf(buf, 128, stereo?str(LANG_CHANNEL_STEREO):
|
||||||
str(LANG_CHANNEL_MONO));
|
str(LANG_CHANNEL_MONO));
|
||||||
FOR_NB_SCREENS(i)
|
FOR_NB_SCREENS(i)
|
||||||
|
@ -1005,9 +1007,9 @@ bool radio_screen(void)
|
||||||
done = true;
|
done = true;
|
||||||
}
|
}
|
||||||
if (TIME_AFTER(current_tick, button_timeout))
|
if (TIME_AFTER(current_tick, button_timeout))
|
||||||
{
|
{
|
||||||
cpu_idle_mode(true);
|
cpu_idle_mode(true);
|
||||||
}
|
}
|
||||||
} /*while(!done)*/
|
} /*while(!done)*/
|
||||||
|
|
||||||
#ifndef SIMULATOR
|
#ifndef SIMULATOR
|
||||||
|
@ -1033,28 +1035,26 @@ bool radio_screen(void)
|
||||||
|
|
||||||
sound_settings_apply();
|
sound_settings_apply();
|
||||||
#endif /* SIMULATOR */
|
#endif /* SIMULATOR */
|
||||||
|
|
||||||
if(keep_playing)
|
if(keep_playing)
|
||||||
{
|
{
|
||||||
/* Catch FMRADIO_PLAYING_OUT status for the sim. */
|
/* Catch FMRADIO_PLAYING status for the sim. */
|
||||||
#ifndef SIMULATOR
|
#ifndef SIMULATOR
|
||||||
#if CONFIG_CODEC != SWCODEC
|
#if CONFIG_CODEC != SWCODEC
|
||||||
/* Enable the Left and right A/D Converter */
|
/* Enable the Left and right A/D Converter */
|
||||||
audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN),
|
audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN),
|
||||||
sound_default(SOUND_RIGHT_GAIN), AUDIO_GAIN_LINEIN);
|
sound_default(SOUND_RIGHT_GAIN),
|
||||||
|
AUDIO_GAIN_LINEIN);
|
||||||
mas_codec_writereg(6, 0x4000);
|
mas_codec_writereg(6, 0x4000);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
if(radio_status == FMRADIO_PAUSED)
|
|
||||||
radio_status = FMRADIO_PAUSED_OUT;
|
|
||||||
else
|
|
||||||
radio_status = FMRADIO_PLAYING_OUT;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
radio_stop();
|
|
||||||
#if CONFIG_CODEC == SWCODEC
|
#if CONFIG_CODEC == SWCODEC
|
||||||
peak_meter_enabled = true;
|
rec_set_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
|
||||||
|
#else
|
||||||
|
radio_stop();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1063,8 +1063,10 @@ bool radio_screen(void)
|
||||||
/* restore status bar settings */
|
/* restore status bar settings */
|
||||||
global_settings.statusbar = statusbar;
|
global_settings.statusbar = statusbar;
|
||||||
|
|
||||||
|
in_screen = false;
|
||||||
|
|
||||||
return have_recorded;
|
return have_recorded;
|
||||||
}
|
} /* radio_screen */
|
||||||
|
|
||||||
void radio_save_presets(void)
|
void radio_save_presets(void)
|
||||||
{
|
{
|
||||||
|
@ -1106,16 +1108,16 @@ void radio_load_presets(char *filename)
|
||||||
|
|
||||||
/* No Preset in configuration. */
|
/* No Preset in configuration. */
|
||||||
if(filename[0] == '\0')
|
if(filename[0] == '\0')
|
||||||
{
|
{
|
||||||
filepreset[0] = '\0';
|
filepreset[0] = '\0';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Temporary preset, loaded until player shuts down. */
|
/* Temporary preset, loaded until player shuts down. */
|
||||||
else if(filename[0] == '/')
|
else if(filename[0] == '/')
|
||||||
strncpy(filepreset, filename, sizeof(filepreset));
|
strncpy(filepreset, filename, sizeof(filepreset));
|
||||||
/* Preset from default directory. */
|
/* Preset from default directory. */
|
||||||
else
|
else
|
||||||
snprintf(filepreset, sizeof(filepreset), "%s/%s.fmr",
|
snprintf(filepreset, sizeof(filepreset), "%s/%s.fmr",
|
||||||
FMPRESET_PATH, filename);
|
FMPRESET_PATH, filename);
|
||||||
|
|
||||||
fd = open(filepreset, O_RDONLY);
|
fd = open(filepreset, O_RDONLY);
|
||||||
|
@ -1466,30 +1468,6 @@ bool handle_radio_presets(void)
|
||||||
return reload_dir;
|
return reload_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SIMULATOR
|
|
||||||
#if CONFIG_CODEC != SWCODEC
|
|
||||||
static bool fm_recording_settings(void)
|
|
||||||
{
|
|
||||||
bool ret;
|
|
||||||
|
|
||||||
ret = recording_menu(true);
|
|
||||||
if(!ret)
|
|
||||||
{
|
|
||||||
if (global_settings.rec_prerecord_time)
|
|
||||||
talk_buffer_steal(); /* will use the mp3 buffer */
|
|
||||||
|
|
||||||
audio_set_recording_options(global_settings.rec_frequency,
|
|
||||||
global_settings.rec_quality,
|
|
||||||
1, /* Line In */
|
|
||||||
global_settings.rec_channels,
|
|
||||||
global_settings.rec_editable,
|
|
||||||
global_settings.rec_prerecord_time);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char monomode_menu_string[32];
|
char monomode_menu_string[32];
|
||||||
|
|
||||||
static void create_monomode_menu(void)
|
static void create_monomode_menu(void)
|
||||||
|
@ -1628,6 +1606,55 @@ int radio_menu_cb(int key, int m)
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef SIMULATOR
|
||||||
|
#if defined(HAVE_FMRADIO_IN) || CONFIG_CODEC != SWCODEC
|
||||||
|
static bool fm_recording_screen(void)
|
||||||
|
{
|
||||||
|
bool ret;
|
||||||
|
|
||||||
|
#ifdef HAVE_FMRADIO_IN
|
||||||
|
/* switch recording source to FMRADIO for the duration */
|
||||||
|
int rec_source = global_settings.rec_source;
|
||||||
|
global_settings.rec_source = AUDIO_SRC_FMRADIO;
|
||||||
|
|
||||||
|
/* clearing queue seems to cure a spontaneous abort during record */
|
||||||
|
while (button_get(false) != BUTTON_NONE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ret = recording_screen(true);
|
||||||
|
|
||||||
|
#ifdef HAVE_FMRADIO_IN
|
||||||
|
/* safe to reset as changing sources is prohibited here */
|
||||||
|
global_settings.rec_source = rec_source;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool fm_recording_settings(void)
|
||||||
|
{
|
||||||
|
bool ret = recording_menu(true);
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
rec_set_recording_options(global_settings.rec_frequency,
|
||||||
|
global_settings.rec_quality,
|
||||||
|
#if CONFIG_CODEC == SWCODEC
|
||||||
|
AUDIO_SRC_FMRADIO, SRCF_FMRADIO_PLAYING,
|
||||||
|
#else
|
||||||
|
AUDIO_SRC_LINEIN, 0,
|
||||||
|
#endif
|
||||||
|
global_settings.rec_channels,
|
||||||
|
global_settings.rec_editable,
|
||||||
|
global_settings.rec_prerecord_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* SIMULATOR */
|
||||||
|
|
||||||
|
|
||||||
/* main menu of the radio screen */
|
/* main menu of the radio screen */
|
||||||
bool radio_menu(void)
|
bool radio_menu(void)
|
||||||
{
|
{
|
||||||
|
@ -1637,24 +1664,27 @@ bool radio_menu(void)
|
||||||
static const struct menu_item items[] = {
|
static const struct menu_item items[] = {
|
||||||
/* Add functions not accessible via buttons */
|
/* Add functions not accessible via buttons */
|
||||||
#ifndef FM_PRESET
|
#ifndef FM_PRESET
|
||||||
{ ID2P(LANG_FM_BUTTONBAR_PRESETS), handle_radio_presets },
|
{ ID2P(LANG_FM_BUTTONBAR_PRESETS), handle_radio_presets },
|
||||||
#endif
|
#endif
|
||||||
#ifndef FM_PRESET_ADD
|
#ifndef FM_PRESET_ADD
|
||||||
{ ID2P(LANG_FM_ADD_PRESET) , radio_add_preset },
|
{ ID2P(LANG_FM_ADD_PRESET) , radio_add_preset },
|
||||||
#endif
|
#endif
|
||||||
{ ID2P(LANG_FM_PRESET_LOAD) , load_preset_list },
|
{ ID2P(LANG_FM_PRESET_LOAD) , load_preset_list },
|
||||||
{ ID2P(LANG_FM_PRESET_SAVE) , save_preset_list },
|
{ ID2P(LANG_FM_PRESET_SAVE) , save_preset_list },
|
||||||
{ ID2P(LANG_FM_PRESET_CLEAR) , clear_preset_list },
|
{ ID2P(LANG_FM_PRESET_CLEAR) , clear_preset_list },
|
||||||
|
|
||||||
{ monomode_menu_string , toggle_mono_mode },
|
{ monomode_menu_string , toggle_mono_mode },
|
||||||
#ifndef FM_MODE
|
#ifndef FM_MODE
|
||||||
{ radiomode_menu_string , toggle_radio_mode },
|
{ radiomode_menu_string , toggle_radio_mode },
|
||||||
#endif
|
#endif
|
||||||
{ ID2P(LANG_SOUND_SETTINGS) , sound_menu },
|
{ ID2P(LANG_SOUND_SETTINGS) , sound_menu },
|
||||||
#if !defined(SIMULATOR) && (CONFIG_CODEC != SWCODEC)
|
#ifndef SIMULATOR
|
||||||
{ ID2P(LANG_RECORDING_SETTINGS) , fm_recording_settings},
|
#if defined(HAVE_FMRADIO_IN) || CONFIG_CODEC != SWCODEC
|
||||||
|
{ ID2P(LANG_RECORDING_MENU) , fm_recording_screen },
|
||||||
|
{ ID2P(LANG_RECORDING_SETTINGS) , fm_recording_settings },
|
||||||
#endif
|
#endif
|
||||||
{ ID2P(LANG_FM_SCAN_PRESETS) , scan_presets },
|
#endif
|
||||||
|
{ ID2P(LANG_FM_SCAN_PRESETS) , scan_presets },
|
||||||
};
|
};
|
||||||
|
|
||||||
create_monomode_menu();
|
create_monomode_menu();
|
||||||
|
|
|
@ -20,19 +20,19 @@
|
||||||
#define RADIO_H
|
#define RADIO_H
|
||||||
#define FMPRESET_PATH ROCKBOX_DIR "/fmpresets"
|
#define FMPRESET_PATH ROCKBOX_DIR "/fmpresets"
|
||||||
|
|
||||||
#define FMRADIO_OFF 0
|
#ifndef FMRADIO_H
|
||||||
#define FMRADIO_PLAYING 1
|
#include "fmradio.h"
|
||||||
#define FMRADIO_PLAYING_OUT 2
|
#endif
|
||||||
#define FMRADIO_PAUSED 3
|
|
||||||
#define FMRADIO_PAUSED_OUT 4
|
|
||||||
|
|
||||||
#ifdef CONFIG_TUNER
|
#ifdef CONFIG_TUNER
|
||||||
void radio_load_presets(char *filename);
|
void radio_load_presets(char *filename);
|
||||||
void radio_init(void);
|
void radio_init(void);
|
||||||
bool radio_screen(void);
|
bool radio_screen(void);
|
||||||
|
void radio_start(void);
|
||||||
|
void radio_pause(void);
|
||||||
void radio_stop(void);
|
void radio_stop(void);
|
||||||
bool radio_hardware_present(void);
|
bool radio_hardware_present(void);
|
||||||
int get_radio_status(void);
|
bool in_radio_screen(void);
|
||||||
|
|
||||||
#define MAX_FMPRESET_LEN 27
|
#define MAX_FMPRESET_LEN 27
|
||||||
|
|
||||||
|
|
|
@ -24,12 +24,14 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
|
#include "power.h"
|
||||||
#include "lcd.h"
|
#include "lcd.h"
|
||||||
#include "led.h"
|
#include "led.h"
|
||||||
#include "mpeg.h"
|
#include "mpeg.h"
|
||||||
#include "audio.h"
|
#include "audio.h"
|
||||||
#if CONFIG_CODEC == SWCODEC
|
#if CONFIG_CODEC == SWCODEC
|
||||||
#include "pcm_record.h"
|
#include "pcm_record.h"
|
||||||
|
#include "playback.h"
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_UDA1380
|
#ifdef HAVE_UDA1380
|
||||||
#include "uda1380.h"
|
#include "uda1380.h"
|
||||||
|
@ -37,7 +39,7 @@
|
||||||
#ifdef HAVE_TLV320
|
#ifdef HAVE_TLV320
|
||||||
#include "tlv320.h"
|
#include "tlv320.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "recording.h"
|
||||||
#include "mp3_playback.h"
|
#include "mp3_playback.h"
|
||||||
#include "mas.h"
|
#include "mas.h"
|
||||||
#include "button.h"
|
#include "button.h"
|
||||||
|
@ -66,6 +68,7 @@
|
||||||
#include "splash.h"
|
#include "splash.h"
|
||||||
#include "screen_access.h"
|
#include "screen_access.h"
|
||||||
#include "action.h"
|
#include "action.h"
|
||||||
|
#include "radio.h"
|
||||||
#ifdef HAVE_RECORDING
|
#ifdef HAVE_RECORDING
|
||||||
|
|
||||||
#define PM_HEIGHT ((LCD_HEIGHT >= 72) ? 2 : 1)
|
#define PM_HEIGHT ((LCD_HEIGHT >= 72) ? 2 : 1)
|
||||||
|
@ -73,21 +76,6 @@
|
||||||
bool f2_rec_screen(void);
|
bool f2_rec_screen(void);
|
||||||
bool f3_rec_screen(void);
|
bool f3_rec_screen(void);
|
||||||
|
|
||||||
#define SOURCE_MIC 0
|
|
||||||
#define SOURCE_LINE 1
|
|
||||||
#ifdef HAVE_SPDIF_IN
|
|
||||||
#define SOURCE_SPDIF 2
|
|
||||||
#define MAX_SOURCE SOURCE_SPDIF
|
|
||||||
#else
|
|
||||||
#define MAX_SOURCE SOURCE_LINE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CONFIG_CODEC == SWCODEC
|
|
||||||
#define REC_FILE_ENDING ".wav"
|
|
||||||
#else
|
|
||||||
#define REC_FILE_ENDING ".mp3"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MAX_FILE_SIZE 0x7F800000 /* 2 GB - 4 MB */
|
#define MAX_FILE_SIZE 0x7F800000 /* 2 GB - 4 MB */
|
||||||
|
|
||||||
int screen_update = NB_SCREENS;
|
int screen_update = NB_SCREENS;
|
||||||
|
@ -102,6 +90,19 @@ const char* const freq_str[6] =
|
||||||
"16kHz"
|
"16kHz"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if CONFIG_CODEC == SWCODEC
|
||||||
|
#define REC_ENCODER_ID(q) \
|
||||||
|
rec_quality_info_afmt[q]
|
||||||
|
#define REC_QUALITY_LABEL(q) \
|
||||||
|
(audio_formats[REC_ENCODER_ID(q)].label)
|
||||||
|
#define REC_FILE_ENDING(q) \
|
||||||
|
(audio_formats[REC_ENCODER_ID(q)].ext)
|
||||||
|
#else
|
||||||
|
/* default record file extension for HWCODEC */
|
||||||
|
#define REC_QUALITY_LABEL(q) "MP3"
|
||||||
|
#define REC_FILE_ENDING(q) ".mp3"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_AGC
|
#ifdef HAVE_AGC
|
||||||
/* Timing counters:
|
/* Timing counters:
|
||||||
* peak_time is incremented every 0.2s, every 2nd run of record screen loop.
|
* peak_time is incremented every 0.2s, every 2nd run of record screen loop.
|
||||||
|
@ -161,13 +162,14 @@ static short agc_maxgain;
|
||||||
|
|
||||||
static void set_gain(void)
|
static void set_gain(void)
|
||||||
{
|
{
|
||||||
if(global_settings.rec_source == SOURCE_MIC)
|
if(global_settings.rec_source == AUDIO_SRC_MIC)
|
||||||
{
|
{
|
||||||
audio_set_recording_gain(global_settings.rec_mic_gain,
|
audio_set_recording_gain(global_settings.rec_mic_gain,
|
||||||
0, AUDIO_GAIN_MIC);
|
0, AUDIO_GAIN_MIC);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* AUDIO_SRC_LINEIN, AUDIO_SRC_SPDIF, AUDIO_SRC_FMRADIO */
|
||||||
audio_set_recording_gain(global_settings.rec_left_gain,
|
audio_set_recording_gain(global_settings.rec_left_gain,
|
||||||
global_settings.rec_right_gain,
|
global_settings.rec_right_gain,
|
||||||
AUDIO_GAIN_LINEIN);
|
AUDIO_GAIN_LINEIN);
|
||||||
|
@ -217,12 +219,16 @@ bool agc_gain_is_max(bool left, bool right)
|
||||||
if (agc_preset == 0)
|
if (agc_preset == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (global_settings.rec_source == SOURCE_LINE)
|
switch (global_settings.rec_source)
|
||||||
{
|
{
|
||||||
|
case AUDIO_SRC_LINEIN:
|
||||||
|
#ifdef HAVE_FMRADIO_IN
|
||||||
|
case AUDIO_SRC_FMRADIO:
|
||||||
|
#endif
|
||||||
gain_current_l = global_settings.rec_left_gain;
|
gain_current_l = global_settings.rec_left_gain;
|
||||||
gain_current_r = global_settings.rec_right_gain;
|
gain_current_r = global_settings.rec_right_gain;
|
||||||
} else
|
break;
|
||||||
{
|
default:
|
||||||
gain_current_l = global_settings.rec_mic_gain;
|
gain_current_l = global_settings.rec_mic_gain;
|
||||||
gain_current_r = global_settings.rec_mic_gain;
|
gain_current_r = global_settings.rec_mic_gain;
|
||||||
}
|
}
|
||||||
|
@ -235,13 +241,16 @@ void change_recording_gain(bool increment, bool left, bool right)
|
||||||
{
|
{
|
||||||
int factor = (increment ? 1 : -1);
|
int factor = (increment ? 1 : -1);
|
||||||
|
|
||||||
if (global_settings.rec_source == SOURCE_LINE)
|
switch (global_settings.rec_source)
|
||||||
{
|
{
|
||||||
|
case AUDIO_SRC_LINEIN:
|
||||||
|
#ifdef HAVE_FMRADIO_IN
|
||||||
|
case AUDIO_SRC_FMRADIO:
|
||||||
|
#endif
|
||||||
if(left) global_settings.rec_left_gain += factor;
|
if(left) global_settings.rec_left_gain += factor;
|
||||||
if (right) global_settings.rec_right_gain += factor;
|
if (right) global_settings.rec_right_gain += factor;
|
||||||
}
|
break;
|
||||||
else
|
default:
|
||||||
{
|
|
||||||
global_settings.rec_mic_gain += factor;
|
global_settings.rec_mic_gain += factor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -443,12 +452,15 @@ void adjust_cursor(void)
|
||||||
#ifdef HAVE_AGC
|
#ifdef HAVE_AGC
|
||||||
switch(global_settings.rec_source)
|
switch(global_settings.rec_source)
|
||||||
{
|
{
|
||||||
case SOURCE_MIC:
|
case AUDIO_SRC_MIC:
|
||||||
if(cursor == 2)
|
if(cursor == 2)
|
||||||
cursor = 4;
|
cursor = 4;
|
||||||
else if(cursor == 3)
|
else if(cursor == 3)
|
||||||
cursor = 1;
|
cursor = 1;
|
||||||
case SOURCE_LINE:
|
case AUDIO_SRC_LINEIN:
|
||||||
|
#ifdef HAVE_FMRADIO_IN
|
||||||
|
case AUDIO_SRC_FMRADIO:
|
||||||
|
#endif
|
||||||
max_cursor = 5;
|
max_cursor = 5;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -458,10 +470,13 @@ void adjust_cursor(void)
|
||||||
#else
|
#else
|
||||||
switch(global_settings.rec_source)
|
switch(global_settings.rec_source)
|
||||||
{
|
{
|
||||||
case SOURCE_MIC:
|
case AUDIO_SRC_MIC:
|
||||||
max_cursor = 1;
|
max_cursor = 1;
|
||||||
break;
|
break;
|
||||||
case SOURCE_LINE:
|
case AUDIO_SRC_LINEIN:
|
||||||
|
#ifdef HAVE_FMRADIO_IN
|
||||||
|
case AUDIO_SRC_FMRADIO:
|
||||||
|
#endif
|
||||||
max_cursor = 3;
|
max_cursor = 3;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -481,10 +496,13 @@ char *rec_create_filename(char *buffer)
|
||||||
else
|
else
|
||||||
strncpy(buffer, rec_base_directory, MAX_PATH);
|
strncpy(buffer, rec_base_directory, MAX_PATH);
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_RTC
|
#ifdef CONFIG_RTC
|
||||||
create_datetime_filename(buffer, buffer, "R", REC_FILE_ENDING);
|
create_datetime_filename(buffer, buffer, "R",
|
||||||
|
REC_FILE_ENDING(global_settings.rec_quality));
|
||||||
#else
|
#else
|
||||||
create_numbered_filename(buffer, buffer, "rec_", REC_FILE_ENDING, 4);
|
create_numbered_filename(buffer, buffer, "rec_",
|
||||||
|
REC_FILE_ENDING(global_settings.rec_quality), 4);
|
||||||
#endif
|
#endif
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
@ -515,8 +533,190 @@ int rec_create_directory(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_CODEC == SWCODEC && !defined(SIMULATOR)
|
||||||
|
/**
|
||||||
|
* Selects an audio source for recording or playback
|
||||||
|
* powers/unpowers related devices.
|
||||||
|
* Here because it calls app code and used only for HAVE_RECORDING atm.
|
||||||
|
* Would like it in pcm_record.c.
|
||||||
|
*/
|
||||||
|
#if defined(HAVE_UDA1380)
|
||||||
|
#define ac_disable_recording uda1380_disable_recording
|
||||||
|
#define ac_enable_recording uda1380_enable_recording
|
||||||
|
#define ac_set_monitor uda1380_set_monitor
|
||||||
|
#elif defined(HAVE_TLV320)
|
||||||
|
#define ac_disable_recording tlv320_disable_recording
|
||||||
|
#define ac_enable_recording tlv320_enable_recording
|
||||||
|
#define ac_set_monitor tlv320_set_monitor
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void rec_set_source(int source, int flags)
|
||||||
|
{
|
||||||
|
/* Prevent pops from unneeded switching */
|
||||||
|
static int last_source = AUDIO_SRC_PLAYBACK;
|
||||||
|
#ifdef HAVE_TLV320
|
||||||
|
static bool last_recording = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool recording = flags & SRCF_RECORDING;
|
||||||
|
/* Default to peakmeter record. */
|
||||||
|
bool pm_playback = false;
|
||||||
|
bool pm_enabled = true;
|
||||||
|
|
||||||
|
/** Do power up/down of associated device(s) **/
|
||||||
|
|
||||||
|
#ifdef HAVE_SPDIF_IN
|
||||||
|
if ((source == AUDIO_SRC_SPDIF) != (source == last_source))
|
||||||
|
cpu_boost(source == AUDIO_SRC_SPDIF);
|
||||||
|
|
||||||
|
#ifdef HAVE_SPDIF_POWER
|
||||||
|
/* Check if S/PDIF output power should be switched off or on. NOTE: assumes
|
||||||
|
both optical in and out is controlled by the same power source, which is
|
||||||
|
the case on H1x0. */
|
||||||
|
spdif_power_enable((source == AUDIO_SRC_SPDIF) ||
|
||||||
|
global_settings.spdif_enable);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_TUNER
|
||||||
|
/* Switch radio off or on per source and flags. */
|
||||||
|
if (source != AUDIO_SRC_FMRADIO)
|
||||||
|
radio_stop();
|
||||||
|
else if (flags & SRCF_FMRADIO_PAUSED)
|
||||||
|
radio_pause();
|
||||||
|
else
|
||||||
|
radio_start();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch (source)
|
||||||
|
{
|
||||||
|
default: /* playback - no recording */
|
||||||
|
pm_playback = true;
|
||||||
|
if (source == last_source)
|
||||||
|
break;
|
||||||
|
ac_disable_recording();
|
||||||
|
ac_set_monitor(false);
|
||||||
|
pcm_rec_mux(0); /* line in */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AUDIO_SRC_MIC: /* recording only */
|
||||||
|
if (source == last_source)
|
||||||
|
break;
|
||||||
|
ac_enable_recording(true); /* source mic */
|
||||||
|
pcm_rec_mux(0); /* line in */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AUDIO_SRC_LINEIN: /* recording only */
|
||||||
|
if (source == last_source)
|
||||||
|
break;
|
||||||
|
pcm_rec_mux(0); /* line in */
|
||||||
|
ac_enable_recording(false); /* source line */
|
||||||
|
break;
|
||||||
|
|
||||||
|
#ifdef HAVE_SPDIF_IN
|
||||||
|
case AUDIO_SRC_SPDIF: /* recording only */
|
||||||
|
if (recording)
|
||||||
|
{
|
||||||
|
/* This was originally done in audio_set_recording_options only */
|
||||||
|
#ifdef HAVE_SPDIF_POWER
|
||||||
|
EBU1CONFIG = global_settings.spdif_enable ? (1 << 2) : 0;
|
||||||
|
/* Input source is EBUin1, Feed-through monitoring if desired */
|
||||||
|
#else
|
||||||
|
EBU1CONFIG = (1 << 2);
|
||||||
|
/* Input source is EBUin1, Feed-through monitoring */
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (source != last_source)
|
||||||
|
uda1380_disable_recording();
|
||||||
|
break;
|
||||||
|
#endif /* HAVE_SPDIF_IN */
|
||||||
|
|
||||||
|
#ifdef HAVE_FMRADIO_IN
|
||||||
|
case AUDIO_SRC_FMRADIO:
|
||||||
|
if (!recording)
|
||||||
|
{
|
||||||
|
audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN),
|
||||||
|
sound_default(SOUND_RIGHT_GAIN), AUDIO_GAIN_LINEIN);
|
||||||
|
pm_playback = true;
|
||||||
|
pm_enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pcm_rec_mux(1); /* fm radio */
|
||||||
|
|
||||||
|
#ifdef HAVE_UDA1380
|
||||||
|
if (source == last_source)
|
||||||
|
break;
|
||||||
|
/* I2S recording and playback */
|
||||||
|
uda1380_enable_recording(false); /* source line */
|
||||||
|
uda1380_set_monitor(true);
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_TLV320
|
||||||
|
/* I2S recording and analog playback */
|
||||||
|
if (source == last_source && recording == last_recording)
|
||||||
|
break;
|
||||||
|
|
||||||
|
last_recording = recording;
|
||||||
|
|
||||||
|
if (recording)
|
||||||
|
tlv320_enable_recording(false); /* source line */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tlv320_disable_recording();
|
||||||
|
tlv320_set_monitor(true); /* analog bypass */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
/* #elif defined(CONFIG_TUNER) */
|
||||||
|
/* Have radio but cannot record it */
|
||||||
|
/* case AUDIO_SRC_FMRADIO: */
|
||||||
|
/* break; */
|
||||||
|
#endif /* HAVE_FMRADIO_IN */
|
||||||
|
} /* end switch */
|
||||||
|
|
||||||
|
peak_meter_playback(pm_playback);
|
||||||
|
peak_meter_enabled = pm_enabled;
|
||||||
|
|
||||||
|
last_source = source;
|
||||||
|
} /* rec_set_source */
|
||||||
|
#endif /* CONFIG_CODEC == SWCODEC && !defined(SIMULATOR) */
|
||||||
|
|
||||||
|
/* steal the mp3 buffer then actually set options */
|
||||||
|
void rec_set_recording_options(int frequency, int quality,
|
||||||
|
int source, int source_flags,
|
||||||
|
int channel_mode, bool editable,
|
||||||
|
int prerecord_time)
|
||||||
|
{
|
||||||
|
#if CONFIG_CODEC != SWCODEC
|
||||||
|
if (global_settings.rec_prerecord_time)
|
||||||
|
#endif
|
||||||
|
talk_buffer_steal(); /* will use the mp3 buffer */
|
||||||
|
|
||||||
|
#if CONFIG_CODEC == SWCODEC
|
||||||
|
rec_set_source(source, source_flags | SRCF_RECORDING);
|
||||||
|
#else
|
||||||
|
(void)source_flags;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
audio_set_recording_options(frequency, quality, source,
|
||||||
|
channel_mode, editable, prerecord_time);
|
||||||
|
}
|
||||||
|
|
||||||
static char path_buffer[MAX_PATH];
|
static char path_buffer[MAX_PATH];
|
||||||
|
|
||||||
|
/* steals mp3 buffer, creates unique filename and starts recording */
|
||||||
|
void rec_record(void)
|
||||||
|
{
|
||||||
|
talk_buffer_steal(); /* we use the mp3 buffer */
|
||||||
|
audio_record(rec_create_filename(path_buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* creates unique filename and starts recording */
|
||||||
|
void rec_new_file(void)
|
||||||
|
{
|
||||||
|
audio_new_file(rec_create_filename(path_buffer));
|
||||||
|
}
|
||||||
|
|
||||||
/* used in trigger_listerner and recording_screen */
|
/* used in trigger_listerner and recording_screen */
|
||||||
static unsigned int last_seconds = 0;
|
static unsigned int last_seconds = 0;
|
||||||
|
|
||||||
|
@ -533,16 +733,16 @@ static void trigger_listener(int trigger_status)
|
||||||
if((audio_status() & AUDIO_STATUS_RECORD) != AUDIO_STATUS_RECORD)
|
if((audio_status() & AUDIO_STATUS_RECORD) != AUDIO_STATUS_RECORD)
|
||||||
{
|
{
|
||||||
talk_buffer_steal(); /* we use the mp3 buffer */
|
talk_buffer_steal(); /* we use the mp3 buffer */
|
||||||
audio_record(rec_create_filename(path_buffer));
|
rec_record();
|
||||||
|
/* give control to mpeg thread so that it can start
|
||||||
/* give control to mpeg thread so that it can start recording*/
|
recording */
|
||||||
yield(); yield(); yield();
|
yield(); yield(); yield();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if we're already recording this is a retrigger */
|
/* if we're already recording this is a retrigger */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
audio_new_file(rec_create_filename(path_buffer));
|
rec_new_file();
|
||||||
/* tell recording_screen to reset the time */
|
/* tell recording_screen to reset the time */
|
||||||
last_seconds = 0;
|
last_seconds = 0;
|
||||||
}
|
}
|
||||||
|
@ -563,10 +763,9 @@ static void trigger_listener(int trigger_status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool recording_screen(void)
|
bool recording_screen(bool no_source)
|
||||||
{
|
{
|
||||||
long button;
|
long button;
|
||||||
long lastbutton = BUTTON_NONE;
|
|
||||||
bool done = false;
|
bool done = false;
|
||||||
char buf[32];
|
char buf[32];
|
||||||
char buf2[32];
|
char buf2[32];
|
||||||
|
@ -575,11 +774,19 @@ bool recording_screen(void)
|
||||||
bool have_recorded = false;
|
bool have_recorded = false;
|
||||||
unsigned int seconds;
|
unsigned int seconds;
|
||||||
int hours, minutes;
|
int hours, minutes;
|
||||||
char path_buffer[MAX_PATH];
|
|
||||||
char filename[13];
|
char filename[13];
|
||||||
bool been_in_usb_mode = false;
|
bool been_in_usb_mode = false;
|
||||||
int last_audio_stat = -1;
|
int last_audio_stat = -1;
|
||||||
int audio_stat;
|
int audio_stat;
|
||||||
|
#ifdef HAVE_FMRADIO_IN
|
||||||
|
/* Radio is left on if:
|
||||||
|
* 1) Is was on at the start and the initial source is FM Radio
|
||||||
|
* 2) 1) and the source was never changed to something else
|
||||||
|
*/
|
||||||
|
int radio_status = (global_settings.rec_source != AUDIO_SRC_FMRADIO) ?
|
||||||
|
FMRADIO_OFF : get_radio_status();
|
||||||
|
#endif
|
||||||
|
int talk_menu = global_settings.talk_menu;
|
||||||
#if CONFIG_LED == LED_REAL
|
#if CONFIG_LED == LED_REAL
|
||||||
bool led_state = false;
|
bool led_state = false;
|
||||||
int led_countdown = 2;
|
int led_countdown = 2;
|
||||||
|
@ -608,6 +815,18 @@ bool recording_screen(void)
|
||||||
ata_set_led_enabled(false);
|
ata_set_led_enabled(false);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_CODEC == SWCODEC
|
||||||
|
audio_stop();
|
||||||
|
voice_stop();
|
||||||
|
/* recording_menu gets messed up: so reset talk_menu */
|
||||||
|
talk_menu = global_settings.talk_menu;
|
||||||
|
global_settings.talk_menu = 0;
|
||||||
|
#else
|
||||||
|
/* Yes, we use the D/A for monitoring */
|
||||||
|
peak_meter_enabled = true;
|
||||||
|
peak_meter_playback(true);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef SIMULATOR
|
#ifndef SIMULATOR
|
||||||
audio_init_recording(talk_get_bufsize());
|
audio_init_recording(talk_get_bufsize());
|
||||||
#else
|
#else
|
||||||
|
@ -616,44 +835,19 @@ bool recording_screen(void)
|
||||||
|
|
||||||
sound_set_volume(global_settings.volume);
|
sound_set_volume(global_settings.volume);
|
||||||
|
|
||||||
#if CONFIG_CODEC == SWCODEC
|
|
||||||
audio_stop();
|
|
||||||
/* Set peak meter to recording mode */
|
|
||||||
peak_meter_playback(false);
|
|
||||||
|
|
||||||
#if defined(HAVE_SPDIF_IN) && !defined(SIMULATOR)
|
|
||||||
if (global_settings.rec_source == SOURCE_SPDIF)
|
|
||||||
cpu_boost(true);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else
|
|
||||||
/* Yes, we use the D/A for monitoring */
|
|
||||||
peak_meter_playback(true);
|
|
||||||
#endif
|
|
||||||
peak_meter_enabled = true;
|
|
||||||
#ifdef HAVE_AGC
|
#ifdef HAVE_AGC
|
||||||
peak_meter_get_peakhold(&peak_l, &peak_r);
|
peak_meter_get_peakhold(&peak_l, &peak_r);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_CODEC != SWCODEC
|
rec_set_recording_options(global_settings.rec_frequency,
|
||||||
if (global_settings.rec_prerecord_time)
|
global_settings.rec_quality,
|
||||||
#endif
|
global_settings.rec_source,
|
||||||
talk_buffer_steal(); /* will use the mp3 buffer */
|
0,
|
||||||
|
global_settings.rec_channels,
|
||||||
#if defined(HAVE_SPDIF_POWER) && !defined(SIMULATOR)
|
global_settings.rec_editable,
|
||||||
/* Tell recording whether we want S/PDIF power enabled at all times */
|
global_settings.rec_prerecord_time);
|
||||||
audio_set_spdif_power_setting(global_settings.spdif_enable);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
audio_set_recording_options(global_settings.rec_frequency,
|
|
||||||
global_settings.rec_quality,
|
|
||||||
global_settings.rec_source,
|
|
||||||
global_settings.rec_channels,
|
|
||||||
global_settings.rec_editable,
|
|
||||||
global_settings.rec_prerecord_time);
|
|
||||||
|
|
||||||
set_gain();
|
set_gain();
|
||||||
|
|
||||||
settings_apply_trigger();
|
settings_apply_trigger();
|
||||||
|
|
||||||
#ifdef HAVE_AGC
|
#ifdef HAVE_AGC
|
||||||
|
@ -663,7 +857,7 @@ bool recording_screen(void)
|
||||||
agc_preset_str[3] = str(LANG_AGC_DJSET);
|
agc_preset_str[3] = str(LANG_AGC_DJSET);
|
||||||
agc_preset_str[4] = str(LANG_AGC_MEDIUM);
|
agc_preset_str[4] = str(LANG_AGC_MEDIUM);
|
||||||
agc_preset_str[5] = str(LANG_AGC_VOICE);
|
agc_preset_str[5] = str(LANG_AGC_VOICE);
|
||||||
if (global_settings.rec_source == SOURCE_MIC) {
|
if (global_settings.rec_source == AUDIO_SRC_MIC) {
|
||||||
agc_preset = global_settings.rec_agc_preset_mic;
|
agc_preset = global_settings.rec_agc_preset_mic;
|
||||||
agc_maxgain = global_settings.rec_agc_maxgain_mic;
|
agc_maxgain = global_settings.rec_agc_maxgain_mic;
|
||||||
}
|
}
|
||||||
|
@ -697,11 +891,7 @@ bool recording_screen(void)
|
||||||
|
|
||||||
while(!done)
|
while(!done)
|
||||||
{
|
{
|
||||||
#if CONFIG_CODEC == SWCODEC
|
|
||||||
audio_stat = pcm_rec_status();
|
|
||||||
#else
|
|
||||||
audio_stat = audio_status();
|
audio_stat = audio_status();
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CONFIG_LED == LED_REAL
|
#if CONFIG_LED == LED_REAL
|
||||||
|
|
||||||
|
@ -794,8 +984,8 @@ bool recording_screen(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
peak_meter_playback(true);
|
|
||||||
#if CONFIG_CODEC != SWCODEC
|
#if CONFIG_CODEC != SWCODEC
|
||||||
|
peak_meter_playback(true);
|
||||||
peak_meter_enabled = false;
|
peak_meter_enabled = false;
|
||||||
#endif
|
#endif
|
||||||
done = true;
|
done = true;
|
||||||
|
@ -815,14 +1005,13 @@ bool recording_screen(void)
|
||||||
/* manual recording */
|
/* manual recording */
|
||||||
have_recorded = true;
|
have_recorded = true;
|
||||||
talk_buffer_steal(); /* we use the mp3 buffer */
|
talk_buffer_steal(); /* we use the mp3 buffer */
|
||||||
audio_record(rec_create_filename(path_buffer));
|
rec_record();
|
||||||
last_seconds = 0;
|
last_seconds = 0;
|
||||||
if (global_settings.talk_menu)
|
if (talk_menu)
|
||||||
{ /* no voice possible here, but a beep */
|
{ /* no voice possible here, but a beep */
|
||||||
audio_beep(HZ/2); /* longer beep on start */
|
audio_beep(HZ/2); /* longer beep on start */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this is triggered recording */
|
/* this is triggered recording */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -838,7 +1027,7 @@ bool recording_screen(void)
|
||||||
/*if new file button pressed, start new file */
|
/*if new file button pressed, start new file */
|
||||||
if (button == ACTION_REC_NEWFILE)
|
if (button == ACTION_REC_NEWFILE)
|
||||||
{
|
{
|
||||||
audio_new_file(rec_create_filename(path_buffer));
|
rec_new_file();
|
||||||
last_seconds = 0;
|
last_seconds = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -847,7 +1036,7 @@ bool recording_screen(void)
|
||||||
if(audio_stat & AUDIO_STATUS_PAUSE)
|
if(audio_stat & AUDIO_STATUS_PAUSE)
|
||||||
{
|
{
|
||||||
audio_resume_recording();
|
audio_resume_recording();
|
||||||
if (global_settings.talk_menu)
|
if (talk_menu)
|
||||||
{ /* no voice possible here, but a beep */
|
{ /* no voice possible here, but a beep */
|
||||||
audio_beep(HZ/4); /* short beep on resume */
|
audio_beep(HZ/4); /* short beep on resume */
|
||||||
}
|
}
|
||||||
|
@ -883,7 +1072,7 @@ bool recording_screen(void)
|
||||||
sound_set_volume(global_settings.volume);
|
sound_set_volume(global_settings.volume);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
if(global_settings.rec_source == SOURCE_MIC)
|
if(global_settings.rec_source == AUDIO_SRC_MIC)
|
||||||
{
|
{
|
||||||
if(global_settings.rec_mic_gain <
|
if(global_settings.rec_mic_gain <
|
||||||
sound_max(SOUND_MIC_GAIN))
|
sound_max(SOUND_MIC_GAIN))
|
||||||
|
@ -913,7 +1102,7 @@ bool recording_screen(void)
|
||||||
case 4:
|
case 4:
|
||||||
agc_preset = MIN(agc_preset + 1, AGC_MODE_SIZE);
|
agc_preset = MIN(agc_preset + 1, AGC_MODE_SIZE);
|
||||||
agc_enable = (agc_preset != 0);
|
agc_enable = (agc_preset != 0);
|
||||||
if (global_settings.rec_source == SOURCE_MIC) {
|
if (global_settings.rec_source == AUDIO_SRC_MIC) {
|
||||||
global_settings.rec_agc_preset_mic = agc_preset;
|
global_settings.rec_agc_preset_mic = agc_preset;
|
||||||
agc_maxgain = global_settings.rec_agc_maxgain_mic;
|
agc_maxgain = global_settings.rec_agc_maxgain_mic;
|
||||||
} else {
|
} else {
|
||||||
|
@ -922,7 +1111,7 @@ bool recording_screen(void)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
if (global_settings.rec_source == SOURCE_MIC)
|
if (global_settings.rec_source == AUDIO_SRC_MIC)
|
||||||
{
|
{
|
||||||
agc_maxgain = MIN(agc_maxgain + 1,
|
agc_maxgain = MIN(agc_maxgain + 1,
|
||||||
sound_max(SOUND_MIC_GAIN));
|
sound_max(SOUND_MIC_GAIN));
|
||||||
|
@ -951,7 +1140,7 @@ bool recording_screen(void)
|
||||||
sound_set_volume(global_settings.volume);
|
sound_set_volume(global_settings.volume);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
if(global_settings.rec_source == SOURCE_MIC)
|
if(global_settings.rec_source == AUDIO_SRC_MIC)
|
||||||
{
|
{
|
||||||
if(global_settings.rec_mic_gain >
|
if(global_settings.rec_mic_gain >
|
||||||
sound_min(SOUND_MIC_GAIN))
|
sound_min(SOUND_MIC_GAIN))
|
||||||
|
@ -981,7 +1170,7 @@ bool recording_screen(void)
|
||||||
case 4:
|
case 4:
|
||||||
agc_preset = MAX(agc_preset - 1, 0);
|
agc_preset = MAX(agc_preset - 1, 0);
|
||||||
agc_enable = (agc_preset != 0);
|
agc_enable = (agc_preset != 0);
|
||||||
if (global_settings.rec_source == SOURCE_MIC) {
|
if (global_settings.rec_source == AUDIO_SRC_MIC) {
|
||||||
global_settings.rec_agc_preset_mic = agc_preset;
|
global_settings.rec_agc_preset_mic = agc_preset;
|
||||||
agc_maxgain = global_settings.rec_agc_maxgain_mic;
|
agc_maxgain = global_settings.rec_agc_maxgain_mic;
|
||||||
} else {
|
} else {
|
||||||
|
@ -990,7 +1179,7 @@ bool recording_screen(void)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
if (global_settings.rec_source == SOURCE_MIC)
|
if (global_settings.rec_source == AUDIO_SRC_MIC)
|
||||||
{
|
{
|
||||||
agc_maxgain = MAX(agc_maxgain - 1,
|
agc_maxgain = MAX(agc_maxgain - 1,
|
||||||
sound_min(SOUND_MIC_GAIN));
|
sound_min(SOUND_MIC_GAIN));
|
||||||
|
@ -1012,49 +1201,73 @@ bool recording_screen(void)
|
||||||
case ACTION_STD_MENU:
|
case ACTION_STD_MENU:
|
||||||
if(audio_stat != AUDIO_STATUS_RECORD)
|
if(audio_stat != AUDIO_STATUS_RECORD)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_FMRADIO_IN
|
||||||
|
const int prev_rec_source = global_settings.rec_source;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CONFIG_LED == LED_REAL
|
#if CONFIG_LED == LED_REAL
|
||||||
/* led is restored at begin of loop / end of function */
|
/* led is restored at begin of loop / end of function */
|
||||||
led(false);
|
led(false);
|
||||||
#endif
|
#endif
|
||||||
if (recording_menu(false))
|
if (recording_menu(no_source))
|
||||||
{
|
{
|
||||||
return SYS_USB_CONNECTED;
|
done = true;
|
||||||
}
|
been_in_usb_mode = true;
|
||||||
settings_save();
|
#ifdef HAVE_FMRADIO_IN
|
||||||
|
radio_status = FMRADIO_OFF;
|
||||||
#if CONFIG_CODEC != SWCODEC
|
|
||||||
if (global_settings.rec_prerecord_time)
|
|
||||||
#endif
|
#endif
|
||||||
talk_buffer_steal(); /* will use the mp3 buffer */
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
settings_save();
|
||||||
|
|
||||||
|
#ifdef HAVE_FMRADIO_IN
|
||||||
|
/* If input changes away from FM Radio, radio will
|
||||||
|
remain off when recording screen closes. */
|
||||||
|
if (global_settings.rec_source != prev_rec_source
|
||||||
|
&& prev_rec_source == AUDIO_SRC_FMRADIO)
|
||||||
|
radio_status = FMRADIO_OFF;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_CODEC == SWCODEC
|
||||||
|
/* reinit after submenu exit */
|
||||||
|
audio_close_recording();
|
||||||
|
audio_init_recording(talk_get_bufsize());
|
||||||
|
#endif
|
||||||
|
rec_set_recording_options(
|
||||||
|
global_settings.rec_frequency,
|
||||||
|
global_settings.rec_quality,
|
||||||
|
global_settings.rec_source,
|
||||||
|
0,
|
||||||
|
global_settings.rec_channels,
|
||||||
|
global_settings.rec_editable,
|
||||||
|
global_settings.rec_prerecord_time);
|
||||||
|
|
||||||
audio_set_recording_options(global_settings.rec_frequency,
|
|
||||||
global_settings.rec_quality,
|
|
||||||
global_settings.rec_source,
|
|
||||||
global_settings.rec_channels,
|
|
||||||
global_settings.rec_editable,
|
|
||||||
global_settings.rec_prerecord_time);
|
|
||||||
#ifdef HAVE_AGC
|
#ifdef HAVE_AGC
|
||||||
if (global_settings.rec_source == SOURCE_MIC) {
|
if (global_settings.rec_source == AUDIO_SRC_MIC) {
|
||||||
agc_preset = global_settings.rec_agc_preset_mic;
|
agc_preset = global_settings.rec_agc_preset_mic;
|
||||||
agc_maxgain = global_settings.rec_agc_maxgain_mic;
|
agc_maxgain = global_settings.rec_agc_maxgain_mic;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
agc_preset = global_settings.rec_agc_preset_line;
|
agc_preset = global_settings.rec_agc_preset_line;
|
||||||
agc_maxgain = global_settings.rec_agc_maxgain_line;
|
agc_maxgain = global_settings.rec_agc_maxgain_line;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
adjust_cursor();
|
adjust_cursor();
|
||||||
set_gain();
|
set_gain();
|
||||||
update_countdown = 1; /* Update immediately */
|
update_countdown = 1; /* Update immediately */
|
||||||
|
|
||||||
FOR_NB_SCREENS(i)
|
FOR_NB_SCREENS(i)
|
||||||
{
|
{
|
||||||
screens[i].setfont(FONT_SYSFIXED);
|
screens[i].setfont(FONT_SYSFIXED);
|
||||||
screens[i].setmargins(global_settings.invert_cursor ? 0 : w, 8);
|
screens[i].setmargins(
|
||||||
|
global_settings.invert_cursor ? 0 : w, 8);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if CONFIG_KEYPAD == RECORDER_PAD
|
#if CONFIG_KEYPAD == RECORDER_PAD
|
||||||
case ACTION_REC_F2:
|
case ACTION_REC_F2:
|
||||||
if(audio_stat != AUDIO_STATUS_RECORD)
|
if(audio_stat != AUDIO_STATUS_RECORD)
|
||||||
|
@ -1076,7 +1289,7 @@ bool recording_screen(void)
|
||||||
case ACTION_REC_F3:
|
case ACTION_REC_F3:
|
||||||
if(audio_stat & AUDIO_STATUS_RECORD)
|
if(audio_stat & AUDIO_STATUS_RECORD)
|
||||||
{
|
{
|
||||||
audio_new_file(rec_create_filename(path_buffer));
|
rec_new_file();
|
||||||
last_seconds = 0;
|
last_seconds = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1097,7 +1310,7 @@ bool recording_screen(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif /* CONFIG_KEYPAD == RECORDER_PAD */
|
||||||
|
|
||||||
case SYS_USB_CONNECTED:
|
case SYS_USB_CONNECTED:
|
||||||
/* Only accept USB connection when not recording */
|
/* Only accept USB connection when not recording */
|
||||||
|
@ -1106,6 +1319,9 @@ bool recording_screen(void)
|
||||||
default_event_handler(SYS_USB_CONNECTED);
|
default_event_handler(SYS_USB_CONNECTED);
|
||||||
done = true;
|
done = true;
|
||||||
been_in_usb_mode = true;
|
been_in_usb_mode = true;
|
||||||
|
#ifdef HAVE_FMRADIO_IN
|
||||||
|
radio_status = FMRADIO_OFF;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1113,8 +1329,6 @@ bool recording_screen(void)
|
||||||
default_event_handler(button);
|
default_event_handler(button);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (button != BUTTON_NONE)
|
|
||||||
lastbutton = button;
|
|
||||||
|
|
||||||
#ifdef HAVE_AGC
|
#ifdef HAVE_AGC
|
||||||
peak_read = !peak_read;
|
peak_read = !peak_read;
|
||||||
|
@ -1230,7 +1444,7 @@ bool recording_screen(void)
|
||||||
if (!(global_settings.rec_split_type)
|
if (!(global_settings.rec_split_type)
|
||||||
|| (num_recorded_bytes >= MAX_FILE_SIZE))
|
|| (num_recorded_bytes >= MAX_FILE_SIZE))
|
||||||
{
|
{
|
||||||
audio_new_file(rec_create_filename(path_buffer));
|
rec_new_file();
|
||||||
last_seconds = 0;
|
last_seconds = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1259,8 +1473,9 @@ bool recording_screen(void)
|
||||||
screens[i].puts(0, filename_offset[i] + PM_HEIGHT + 2, buf);
|
screens[i].puts(0, filename_offset[i] + PM_HEIGHT + 2, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(global_settings.rec_source == SOURCE_MIC)
|
if(global_settings.rec_source == AUDIO_SRC_MIC)
|
||||||
{
|
{
|
||||||
|
/* Draw MIC recording gain */
|
||||||
snprintf(buf, 32, "%s:%s", str(LANG_SYSFONT_RECORDING_GAIN),
|
snprintf(buf, 32, "%s:%s", str(LANG_SYSFONT_RECORDING_GAIN),
|
||||||
fmt_gain(SOUND_MIC_GAIN,
|
fmt_gain(SOUND_MIC_GAIN,
|
||||||
global_settings.rec_mic_gain,
|
global_settings.rec_mic_gain,
|
||||||
|
@ -1278,8 +1493,13 @@ bool recording_screen(void)
|
||||||
PM_HEIGHT + 3, buf);
|
PM_HEIGHT + 3, buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(global_settings.rec_source == SOURCE_LINE)
|
else if(global_settings.rec_source == AUDIO_SRC_LINEIN
|
||||||
|
#ifdef HAVE_FMRADIO_IN
|
||||||
|
|| global_settings.rec_source == AUDIO_SRC_FMRADIO
|
||||||
|
#endif
|
||||||
|
)
|
||||||
{
|
{
|
||||||
|
/* Draw LINE or FMRADIO recording gain */
|
||||||
snprintf(buf, 32, "%s:%s",
|
snprintf(buf, 32, "%s:%s",
|
||||||
str(LANG_SYSFONT_RECORDING_LEFT),
|
str(LANG_SYSFONT_RECORDING_LEFT),
|
||||||
fmt_gain(SOUND_LEFT_GAIN,
|
fmt_gain(SOUND_LEFT_GAIN,
|
||||||
|
@ -1319,14 +1539,23 @@ bool recording_screen(void)
|
||||||
|
|
||||||
FOR_NB_SCREENS(i)
|
FOR_NB_SCREENS(i)
|
||||||
{
|
{
|
||||||
if (global_settings.rec_source == SOURCE_LINE)
|
switch (global_settings.rec_source)
|
||||||
line[i] = 5;
|
{
|
||||||
else if (global_settings.rec_source == SOURCE_MIC)
|
case AUDIO_SRC_LINEIN:
|
||||||
line[i] = 4;
|
#ifdef HAVE_FMRADIO_IN
|
||||||
#ifdef HAVE_SPDIF_IN
|
case AUDIO_SRC_FMRADIO:
|
||||||
else if (global_settings.rec_source == SOURCE_SPDIF)
|
|
||||||
line[i] = 3;
|
|
||||||
#endif
|
#endif
|
||||||
|
line[i] = 5;
|
||||||
|
break;
|
||||||
|
case AUDIO_SRC_MIC:
|
||||||
|
line[i] = 4;
|
||||||
|
break;
|
||||||
|
#ifdef HAVE_SPDIF_IN
|
||||||
|
case AUDIO_SRC_SPDIF:
|
||||||
|
line[i] = 3;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
} /* end switch */
|
||||||
#ifdef HAVE_AGC
|
#ifdef HAVE_AGC
|
||||||
if (screens[i].height < h * (2 + filename_offset[i] + PM_HEIGHT + line[i]))
|
if (screens[i].height < h * (2 + filename_offset[i] + PM_HEIGHT + line[i]))
|
||||||
{
|
{
|
||||||
|
@ -1358,7 +1587,7 @@ bool recording_screen(void)
|
||||||
snprintf(buf, 32, "%s: %s",
|
snprintf(buf, 32, "%s: %s",
|
||||||
str(LANG_RECORDING_AGC_PRESET),
|
str(LANG_RECORDING_AGC_PRESET),
|
||||||
agc_preset_str[agc_preset]);
|
agc_preset_str[agc_preset]);
|
||||||
else if (global_settings.rec_source == SOURCE_MIC)
|
else if (global_settings.rec_source == AUDIO_SRC_MIC)
|
||||||
snprintf(buf, 32, "%s: %s%s",
|
snprintf(buf, 32, "%s: %s%s",
|
||||||
str(LANG_RECORDING_AGC_PRESET),
|
str(LANG_RECORDING_AGC_PRESET),
|
||||||
agc_preset_str[agc_preset],
|
agc_preset_str[agc_preset],
|
||||||
|
@ -1382,8 +1611,12 @@ bool recording_screen(void)
|
||||||
screens[i].puts_style_offset(0, filename_offset[i] +
|
screens[i].puts_style_offset(0, filename_offset[i] +
|
||||||
PM_HEIGHT + line[i], buf, STYLE_INVERT,0);
|
PM_HEIGHT + line[i], buf, STYLE_INVERT,0);
|
||||||
}
|
}
|
||||||
else if ((global_settings.rec_source == SOURCE_MIC)
|
else if (global_settings.rec_source == AUDIO_SRC_MIC
|
||||||
|| (global_settings.rec_source == SOURCE_LINE))
|
|| global_settings.rec_source == AUDIO_SRC_LINEIN
|
||||||
|
#ifdef HAVE_FMRADIO_IN
|
||||||
|
|| global_settings.rec_source == AUDIO_SRC_FMRADIO
|
||||||
|
#endif
|
||||||
|
)
|
||||||
{
|
{
|
||||||
for(i = 0; i < screen_update; i++) {
|
for(i = 0; i < screen_update; i++) {
|
||||||
if (display_agc[i]) {
|
if (display_agc[i]) {
|
||||||
|
@ -1393,7 +1626,7 @@ bool recording_screen(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (global_settings.rec_source == SOURCE_MIC)
|
if (global_settings.rec_source == AUDIO_SRC_MIC)
|
||||||
{
|
{
|
||||||
if(agc_maxgain < (global_settings.rec_mic_gain))
|
if(agc_maxgain < (global_settings.rec_mic_gain))
|
||||||
change_recording_gain(false, true, true);
|
change_recording_gain(false, true, true);
|
||||||
|
@ -1418,7 +1651,7 @@ bool recording_screen(void)
|
||||||
filename_offset[i] +
|
filename_offset[i] +
|
||||||
PM_HEIGHT + 3, true);
|
PM_HEIGHT + 3, true);
|
||||||
|
|
||||||
if(global_settings.rec_source != SOURCE_MIC)
|
if(global_settings.rec_source != AUDIO_SRC_MIC)
|
||||||
{
|
{
|
||||||
for(i = 0; i < screen_update; i++)
|
for(i = 0; i < screen_update; i++)
|
||||||
screen_put_cursorxy(&screens[i], 0,
|
screen_put_cursorxy(&screens[i], 0,
|
||||||
|
@ -1456,14 +1689,14 @@ bool recording_screen(void)
|
||||||
}
|
}
|
||||||
/* Can't measure S/PDIF sample rate on Archos yet */
|
/* Can't measure S/PDIF sample rate on Archos yet */
|
||||||
#if (CONFIG_CODEC != MAS3587F) && defined(HAVE_SPDIF_IN) && !defined(SIMULATOR)
|
#if (CONFIG_CODEC != MAS3587F) && defined(HAVE_SPDIF_IN) && !defined(SIMULATOR)
|
||||||
if (global_settings.rec_source == SOURCE_SPDIF)
|
if (global_settings.rec_source == AUDIO_SRC_SPDIF)
|
||||||
snprintf(spdif_sfreq, 8, "%dHz", audio_get_spdif_sample_rate());
|
snprintf(spdif_sfreq, 8, "%dHz", audio_get_spdif_sample_rate());
|
||||||
#else
|
#else
|
||||||
(void)spdif_sfreq;
|
(void)spdif_sfreq;
|
||||||
#endif
|
#endif
|
||||||
snprintf(buf, 32, "%s %s",
|
snprintf(buf, 32, "%s %s",
|
||||||
#if (CONFIG_CODEC != MAS3587F) && defined(HAVE_SPDIF_IN) && !defined(SIMULATOR)
|
#if (CONFIG_CODEC != MAS3587F) && defined(HAVE_SPDIF_IN) && !defined(SIMULATOR)
|
||||||
global_settings.rec_source == SOURCE_SPDIF ?
|
global_settings.rec_source == AUDIO_SRC_SPDIF ?
|
||||||
spdif_sfreq :
|
spdif_sfreq :
|
||||||
#endif
|
#endif
|
||||||
freq_str[global_settings.rec_frequency],
|
freq_str[global_settings.rec_frequency],
|
||||||
|
@ -1473,8 +1706,8 @@ bool recording_screen(void)
|
||||||
|
|
||||||
for(i = 0; i < screen_update; i++) {
|
for(i = 0; i < screen_update; i++) {
|
||||||
#ifdef HAVE_AGC
|
#ifdef HAVE_AGC
|
||||||
if ((global_settings.rec_source == SOURCE_MIC)
|
if ((global_settings.rec_source == AUDIO_SRC_MIC)
|
||||||
|| (global_settings.rec_source == SOURCE_LINE))
|
|| (global_settings.rec_source == AUDIO_SRC_LINEIN))
|
||||||
screens[i].puts(0, filename_offset[i] + PM_HEIGHT + line[i] + 1, buf);
|
screens[i].puts(0, filename_offset[i] + PM_HEIGHT + line[i] + 1, buf);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
@ -1484,6 +1717,14 @@ bool recording_screen(void)
|
||||||
#ifdef HAVE_AGC
|
#ifdef HAVE_AGC
|
||||||
hist_time++;
|
hist_time++;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_CODEC == SWCODEC
|
||||||
|
snprintf(buf, 32, "%s",
|
||||||
|
REC_QUALITY_LABEL(global_settings.rec_quality));
|
||||||
|
for(i = 0; i < screen_update; i++)
|
||||||
|
screens[i].puts(0, filename_offset[i] + PM_HEIGHT + 6, buf);
|
||||||
|
#endif
|
||||||
|
|
||||||
for(i = 0; i < screen_update; i++)
|
for(i = 0; i < screen_update; i++)
|
||||||
{
|
{
|
||||||
gui_statusbar_draw(&(statusbars.statusbars[i]), true);
|
gui_statusbar_draw(&(statusbars.statusbars[i]), true);
|
||||||
|
@ -1506,7 +1747,7 @@ bool recording_screen(void)
|
||||||
{
|
{
|
||||||
done = true;
|
done = true;
|
||||||
}
|
}
|
||||||
}
|
} /* end while(!done) */
|
||||||
|
|
||||||
|
|
||||||
#if CONFIG_CODEC == SWCODEC
|
#if CONFIG_CODEC == SWCODEC
|
||||||
|
@ -1535,14 +1776,22 @@ bool recording_screen(void)
|
||||||
audio_stop_recording();
|
audio_stop_recording();
|
||||||
audio_close_recording();
|
audio_close_recording();
|
||||||
|
|
||||||
#if defined(HAVE_SPDIF_IN) && !defined(SIMULATOR)
|
#ifdef HAVE_FMRADIO_IN
|
||||||
if (global_settings.rec_source == SOURCE_SPDIF)
|
if (radio_status != FMRADIO_OFF)
|
||||||
cpu_boost(false);
|
/* Restore radio playback - radio_status should be unchanged if started
|
||||||
|
through fm radio screen (barring usb connect) */
|
||||||
|
rec_set_source(AUDIO_SRC_FMRADIO, (radio_status & FMRADIO_PAUSED) ?
|
||||||
|
SRCF_FMRADIO_PAUSED : SRCF_FMRADIO_PLAYING);
|
||||||
|
else
|
||||||
#endif
|
#endif
|
||||||
|
/* Go back to playback mode */
|
||||||
|
rec_set_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
|
||||||
|
|
||||||
#else
|
/* restore talk_menu setting */
|
||||||
|
global_settings.talk_menu = talk_menu;
|
||||||
|
#else /* !SWCODEC */
|
||||||
audio_init_playback();
|
audio_init_playback();
|
||||||
#endif
|
#endif /* CONFIG_CODEC == SWCODEC */
|
||||||
|
|
||||||
/* make sure the trigger is really turned off */
|
/* make sure the trigger is really turned off */
|
||||||
peak_meter_trigger(false);
|
peak_meter_trigger(false);
|
||||||
|
@ -1560,7 +1809,7 @@ bool recording_screen(void)
|
||||||
ata_set_led_enabled(true);
|
ata_set_led_enabled(true);
|
||||||
#endif
|
#endif
|
||||||
return been_in_usb_mode;
|
return been_in_usb_mode;
|
||||||
}
|
} /* recording_screen */
|
||||||
|
|
||||||
#if CONFIG_KEYPAD == RECORDER_PAD
|
#if CONFIG_KEYPAD == RECORDER_PAD
|
||||||
bool f2_rec_screen(void)
|
bool f2_rec_screen(void)
|
||||||
|
@ -1680,15 +1929,13 @@ bool f2_rec_screen(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (global_settings.rec_prerecord_time)
|
rec_set_recording_options(global_settings.rec_frequency,
|
||||||
talk_buffer_steal(); /* will use the mp3 buffer */
|
global_settings.rec_quality,
|
||||||
|
global_settings.rec_source,
|
||||||
audio_set_recording_options(global_settings.rec_frequency,
|
0,
|
||||||
global_settings.rec_quality,
|
global_settings.rec_channels,
|
||||||
global_settings.rec_source,
|
global_settings.rec_editable,
|
||||||
global_settings.rec_channels,
|
global_settings.rec_prerecord_time);
|
||||||
global_settings.rec_editable,
|
|
||||||
global_settings.rec_prerecord_time);
|
|
||||||
|
|
||||||
set_gain();
|
set_gain();
|
||||||
|
|
||||||
|
@ -1760,7 +2007,7 @@ bool f3_rec_screen(void)
|
||||||
case BUTTON_LEFT:
|
case BUTTON_LEFT:
|
||||||
case BUTTON_F3 | BUTTON_LEFT:
|
case BUTTON_F3 | BUTTON_LEFT:
|
||||||
global_settings.rec_source++;
|
global_settings.rec_source++;
|
||||||
if(global_settings.rec_source > MAX_SOURCE)
|
if(global_settings.rec_source > AUDIO_SRC_MAX)
|
||||||
global_settings.rec_source = 0;
|
global_settings.rec_source = 0;
|
||||||
used = true;
|
used = true;
|
||||||
break;
|
break;
|
||||||
|
@ -1782,16 +2029,13 @@ bool f3_rec_screen(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (global_settings.rec_prerecord_time)
|
rec_set_recording_options(global_settings.rec_frequency,
|
||||||
talk_buffer_steal(); /* will use the mp3 buffer */
|
global_settings.rec_quality,
|
||||||
|
global_settings.rec_source,
|
||||||
audio_set_recording_options(global_settings.rec_frequency,
|
0,
|
||||||
global_settings.rec_quality,
|
global_settings.rec_channels,
|
||||||
global_settings.rec_source,
|
global_settings.rec_editable,
|
||||||
global_settings.rec_channels,
|
global_settings.rec_prerecord_time);
|
||||||
global_settings.rec_editable,
|
|
||||||
global_settings.rec_prerecord_time);
|
|
||||||
|
|
||||||
|
|
||||||
set_gain();
|
set_gain();
|
||||||
|
|
||||||
|
@ -1801,7 +2045,7 @@ bool f3_rec_screen(void)
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif /* #ifdef RECORDER_PAD */
|
#endif /* CONFIG_KEYPAD == RECORDER_PAD */
|
||||||
|
|
||||||
#if CONFIG_CODEC == SWCODEC
|
#if CONFIG_CODEC == SWCODEC
|
||||||
void audio_beep(int duration)
|
void audio_beep(int duration)
|
||||||
|
@ -1831,6 +2075,14 @@ unsigned long audio_num_recorded_bytes(void)
|
||||||
return 5 * 1024 * 1024;
|
return 5 * 1024 * 1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_CODEC == SWCODEC
|
||||||
|
void rec_set_source(int source, int flags)
|
||||||
|
{
|
||||||
|
source = source;
|
||||||
|
flags = flags;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void audio_set_recording_options(int frequency, int quality,
|
void audio_set_recording_options(int frequency, int quality,
|
||||||
int source, int channel_mode,
|
int source, int channel_mode,
|
||||||
bool editable, int prerecord_time)
|
bool editable, int prerecord_time)
|
||||||
|
|
|
@ -19,8 +19,33 @@
|
||||||
#ifndef RECORDING_H
|
#ifndef RECORDING_H
|
||||||
#define RECORDING_H
|
#define RECORDING_H
|
||||||
|
|
||||||
bool recording_screen(void);
|
bool recording_screen(bool no_source);
|
||||||
char *rec_create_filename(char *buf);
|
char *rec_create_filename(char *buf);
|
||||||
int rec_create_directory(void);
|
int rec_create_directory(void);
|
||||||
|
|
||||||
|
#if CONFIG_CODEC == SWCODEC
|
||||||
|
/* selects an audio source for recording or playback */
|
||||||
|
#define SRCF_PLAYBACK 0x0000 /* default */
|
||||||
|
#define SRCF_RECORDING 0x1000
|
||||||
|
#ifdef CONFIG_TUNER
|
||||||
|
/* for AUDIO_SRC_FMRADIO */
|
||||||
|
#define SRCF_FMRADIO_PLAYING 0x0000 /* default */
|
||||||
|
#define SRCF_FMRADIO_PAUSED 0x2000
|
||||||
|
#endif
|
||||||
|
void rec_set_source(int source, int flags);
|
||||||
|
#endif /* CONFIG_CODEC == SW_CODEC */
|
||||||
|
|
||||||
|
/* steals mp3 buffer, sets source and then options */
|
||||||
|
/* SRCF_RECORDING is implied */
|
||||||
|
void rec_set_recording_options(int frequency, int quality,
|
||||||
|
int source, int source_flags,
|
||||||
|
int channel_mode, bool editable,
|
||||||
|
int prerecord_time);
|
||||||
|
|
||||||
|
/* steals mp3 buffer, creates unique filename and starts recording */
|
||||||
|
void rec_record(void);
|
||||||
|
|
||||||
|
/* creates unique filename and starts recording */
|
||||||
|
void rec_new_file(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -92,7 +92,7 @@ const char rec_base_directory[] = REC_BASE_DIR;
|
||||||
#include "dsp.h"
|
#include "dsp.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CONFIG_BLOCK_VERSION 50
|
#define CONFIG_BLOCK_VERSION 51
|
||||||
#define CONFIG_BLOCK_SIZE 512
|
#define CONFIG_BLOCK_SIZE 512
|
||||||
#define RTC_BLOCK_SIZE 44
|
#define RTC_BLOCK_SIZE 44
|
||||||
|
|
||||||
|
@ -473,11 +473,21 @@ static const struct bit_entry hd_bits[] =
|
||||||
{1, S_O(rec_split_type), 0, "rec split type", "Split, Stop" },
|
{1, S_O(rec_split_type), 0, "rec split type", "Split, Stop" },
|
||||||
{1, S_O(rec_split_method), 0, "rec split method", "Time,Filesize" },
|
{1, S_O(rec_split_method), 0, "rec split method", "Time,Filesize" },
|
||||||
|
|
||||||
#ifdef HAVE_SPDIF_IN
|
{
|
||||||
{2, S_O(rec_source), 0 /* 0=mic */, "rec source", "mic,line,spdif" },
|
#if defined(HAVE_SPDIF_IN) || defined(HAVE_FMRADIO_IN)
|
||||||
|
2,
|
||||||
#else
|
#else
|
||||||
{1, S_O(rec_source), 0 /* 0=mic */, "rec source", "mic,line" },
|
1,
|
||||||
#endif
|
#endif
|
||||||
|
S_O(rec_source), 0 /* 0=mic */, "rec source",
|
||||||
|
"mic,line"
|
||||||
|
#ifdef HAVE_SPDIF_IN
|
||||||
|
",spdif"
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_FMRADIO_IN
|
||||||
|
",fmradio"
|
||||||
|
#endif
|
||||||
|
},
|
||||||
{5, S_O(rec_prerecord_time), 0, "prerecording time", NULL }, /* 0...30 */
|
{5, S_O(rec_prerecord_time), 0, "prerecording time", NULL }, /* 0...30 */
|
||||||
{1, S_O(rec_directory), 0, /* rec_base_directory */
|
{1, S_O(rec_directory), 0, /* rec_base_directory */
|
||||||
"rec directory", REC_BASE_DIR ",current" },
|
"rec directory", REC_BASE_DIR ",current" },
|
||||||
|
@ -490,14 +500,21 @@ static const struct bit_entry hd_bits[] =
|
||||||
{4, S_O(rec_right_gain), 2 /* 0dB */, "rec right gain", NULL }, /* 0...15 */
|
{4, S_O(rec_right_gain), 2 /* 0dB */, "rec right gain", NULL }, /* 0...15 */
|
||||||
{3, S_O(rec_frequency), 0, /* 0=44.1kHz */
|
{3, S_O(rec_frequency), 0, /* 0=44.1kHz */
|
||||||
"rec frequency", "44,48,32,22,24,16" },
|
"rec frequency", "44,48,32,22,24,16" },
|
||||||
|
{3, S_O(rec_quality), 5 /* 192 kBit/s max */, "rec quality", NULL },
|
||||||
{1, S_O(rec_editable), false, "editable recordings", off_on },
|
{1, S_O(rec_editable), false, "editable recordings", off_on },
|
||||||
{3, S_O(rec_quality), 5, "rec quality", NULL },
|
#elif defined(HAVE_UDA1380) || defined(HAVE_TLV320)
|
||||||
#elif defined(HAVE_UDA1380)
|
#ifdef HAVE_UDA1380
|
||||||
{8|SIGNED, S_O(rec_mic_gain), 16 /* 8 dB */, "rec mic gain", NULL }, /* -128...+108 */
|
{8|SIGNED, S_O(rec_mic_gain), 16 /* 8 dB */, "rec mic gain", NULL }, /* -128...+108 */
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_TLV320
|
||||||
|
/* TLV320 only has no mic boost or 20db mic boost */
|
||||||
|
{1, S_O(rec_mic_gain), 0 /* 0 dB */, "rec mic gain", NULL }, /* 0db or 20db */
|
||||||
|
#endif
|
||||||
{8|SIGNED, S_O(rec_left_gain), 0, "rec left gain", NULL }, /* -128...+96 */
|
{8|SIGNED, S_O(rec_left_gain), 0, "rec left gain", NULL }, /* -128...+96 */
|
||||||
{8|SIGNED, S_O(rec_right_gain), 0, "rec right gain", NULL }, /* -128...+96 */
|
{8|SIGNED, S_O(rec_right_gain), 0, "rec right gain", NULL }, /* -128...+96 */
|
||||||
{3, S_O(rec_frequency), 0, /* 0=44.1kHz */
|
{3, S_O(rec_frequency), 0, /* 0=44.1kHz */
|
||||||
"rec frequency", "44,48,32,22,24,16" },
|
"rec frequency", "44,48,32,22,24,16" },
|
||||||
|
{4, S_O(rec_quality), 4 /* MP3 L3 192 kBit/s */, "rec quality", NULL },
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* values for the trigger */
|
/* values for the trigger */
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#define BACKDROP_DIR ROCKBOX_DIR"/backdrops"
|
#define BACKDROP_DIR ROCKBOX_DIR"/backdrops"
|
||||||
#define REC_BASE_DIR "/recordings"
|
#define REC_BASE_DIR "/recordings"
|
||||||
#define EQS_DIR ROCKBOX_DIR "/eqs"
|
#define EQS_DIR ROCKBOX_DIR "/eqs"
|
||||||
|
#define CODECS_DIR "/codecs"
|
||||||
|
|
||||||
#define MAX_FILENAME 20
|
#define MAX_FILENAME 20
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,12 @@
|
||||||
#include "talk.h"
|
#include "talk.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
|
#ifdef HAVE_RECORDING
|
||||||
|
#include "audio.h"
|
||||||
|
#ifdef CONFIG_TUNER
|
||||||
|
#include "radio.h"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
#if CONFIG_CODEC == MAS3587F
|
#if CONFIG_CODEC == MAS3587F
|
||||||
#include "peakmeter.h"
|
#include "peakmeter.h"
|
||||||
#include "mas.h"
|
#include "mas.h"
|
||||||
|
@ -290,19 +296,68 @@ static bool avc(void)
|
||||||
#ifdef HAVE_RECORDING
|
#ifdef HAVE_RECORDING
|
||||||
static bool recsource(void)
|
static bool recsource(void)
|
||||||
{
|
{
|
||||||
static const struct opt_items names[] = {
|
int n_opts = AUDIO_NUM_SOURCES;
|
||||||
|
|
||||||
|
struct opt_items names[AUDIO_NUM_SOURCES] = {
|
||||||
{ STR(LANG_RECORDING_SRC_MIC) },
|
{ STR(LANG_RECORDING_SRC_MIC) },
|
||||||
{ STR(LANG_RECORDING_SRC_LINE) },
|
{ STR(LANG_RECORDING_SRC_LINE) },
|
||||||
#ifdef HAVE_SPDIF_IN
|
#ifdef HAVE_SPDIF_IN
|
||||||
{ STR(LANG_RECORDING_SRC_DIGITAL) },
|
{ STR(LANG_RECORDING_SRC_DIGITAL) },
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* caveat: assumes it's the last item! */
|
||||||
|
#ifdef HAVE_FMRADIO_IN
|
||||||
|
if (radio_hardware_present())
|
||||||
|
{
|
||||||
|
names[AUDIO_SRC_FMRADIO].string = ID2P(LANG_FM_RADIO);
|
||||||
|
names[AUDIO_SRC_FMRADIO].voice_id = LANG_FM_RADIO;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
n_opts--;
|
||||||
|
#endif
|
||||||
|
|
||||||
return set_option(str(LANG_RECORDING_SOURCE),
|
return set_option(str(LANG_RECORDING_SOURCE),
|
||||||
&global_settings.rec_source, INT, names,
|
&global_settings.rec_source, INT, names,
|
||||||
sizeof(names)/sizeof(struct opt_items), NULL );
|
n_opts, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* To be removed when we add support for sample rates and channel settings */
|
/* To be removed when we add support for sample rates and channel settings */
|
||||||
|
#if CONFIG_CODEC == SWCODEC
|
||||||
|
static bool recquality(void)
|
||||||
|
{
|
||||||
|
static const struct opt_items names[] = {
|
||||||
|
{ "MP3 64 kBit/s", TALK_ID( 64, UNIT_KBIT) },
|
||||||
|
{ "MP3 96 kBit/s", TALK_ID( 96, UNIT_KBIT) },
|
||||||
|
{ "MP3 128 kBit/s", TALK_ID( 128, UNIT_KBIT) },
|
||||||
|
{ "MP3 160 kBit/s", TALK_ID( 160, UNIT_KBIT) },
|
||||||
|
{ "MP3 192 kBit/s", TALK_ID( 192, UNIT_KBIT) },
|
||||||
|
{ "MP3 224 kBit/s", TALK_ID( 224, UNIT_KBIT) },
|
||||||
|
{ "MP3 320 kBit/s", TALK_ID( 320, UNIT_KBIT) },
|
||||||
|
{ "WV 900 kBit/s", TALK_ID( 900, UNIT_KBIT) },
|
||||||
|
{ "WAV 1411 kBit/s", TALK_ID(1411, UNIT_KBIT) }
|
||||||
|
};
|
||||||
|
|
||||||
|
return set_option(str(LANG_RECORDING_QUALITY),
|
||||||
|
&global_settings.rec_quality, INT,
|
||||||
|
names, sizeof (names)/sizeof(struct opt_items),
|
||||||
|
NULL );
|
||||||
|
}
|
||||||
|
#elif CONFIG_CODEC == MAS3587F
|
||||||
|
static bool recquality(void)
|
||||||
|
{
|
||||||
|
return set_int(str(LANG_RECORDING_QUALITY), "", UNIT_INT,
|
||||||
|
&global_settings.rec_quality,
|
||||||
|
NULL, 1, 0, 7, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool receditable(void)
|
||||||
|
{
|
||||||
|
return set_bool(str(LANG_RECORDING_EDITABLE),
|
||||||
|
&global_settings.rec_editable);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_UDA1380
|
#ifndef HAVE_UDA1380
|
||||||
static bool recfrequency(void)
|
static bool recfrequency(void)
|
||||||
{
|
{
|
||||||
|
@ -331,21 +386,6 @@ static bool recchannels(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_CODEC == MAS3587F
|
|
||||||
static bool recquality(void)
|
|
||||||
{
|
|
||||||
return set_int(str(LANG_RECORDING_QUALITY), "", UNIT_INT,
|
|
||||||
&global_settings.rec_quality,
|
|
||||||
NULL, 1, 0, 7, NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool receditable(void)
|
|
||||||
{
|
|
||||||
return set_bool(str(LANG_RECORDING_EDITABLE),
|
|
||||||
&global_settings.rec_editable);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static bool rectimesplit(void)
|
static bool rectimesplit(void)
|
||||||
{
|
{
|
||||||
static const struct opt_items names[] = {
|
static const struct opt_items names[] = {
|
||||||
|
@ -1011,13 +1051,13 @@ bool recording_menu(bool no_source)
|
||||||
struct menu_item items[13];
|
struct menu_item items[13];
|
||||||
bool result;
|
bool result;
|
||||||
|
|
||||||
#if CONFIG_CODEC == MAS3587F
|
#if CONFIG_CODEC == MAS3587F || CONFIG_CODEC == SWCODEC
|
||||||
items[i].desc = ID2P(LANG_RECORDING_QUALITY);
|
items[i].desc = ID2P(LANG_RECORDING_QUALITY);
|
||||||
items[i++].function = recquality;
|
items[i++].function = recquality;
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef HAVE_UDA1380
|
||||||
/* We don't support frequency selection for UDA1380 yet. Let it just stay at
|
/* We don't support frequency selection for UDA1380 yet. Let it just stay at
|
||||||
the default 44100 Hz. */
|
the default 44100 Hz. */
|
||||||
#ifndef HAVE_UDA1380
|
|
||||||
items[i].desc = ID2P(LANG_RECORDING_FREQUENCY);
|
items[i].desc = ID2P(LANG_RECORDING_FREQUENCY);
|
||||||
items[i++].function = recfrequency;
|
items[i++].function = recfrequency;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -103,10 +103,10 @@ int current_playmode(void)
|
||||||
#ifdef CONFIG_TUNER
|
#ifdef CONFIG_TUNER
|
||||||
audio_stat = get_radio_status();
|
audio_stat = get_radio_status();
|
||||||
|
|
||||||
if(audio_stat == FMRADIO_PLAYING)
|
if(audio_stat & FMRADIO_PLAYING)
|
||||||
return STATUS_RADIO;
|
return STATUS_RADIO;
|
||||||
|
|
||||||
if(audio_stat == FMRADIO_PAUSED)
|
if(audio_stat & FMRADIO_PAUSED)
|
||||||
return STATUS_RADIO_PAUSE;
|
return STATUS_RADIO_PAUSE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -554,6 +554,7 @@ int talk_buffer_steal(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
reset_state();
|
reset_state();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -728,6 +729,7 @@ int talk_value(long n, int unit, bool enqueue)
|
||||||
VOICE_PIXEL,
|
VOICE_PIXEL,
|
||||||
VOICE_PER_SEC,
|
VOICE_PER_SEC,
|
||||||
VOICE_HERTZ,
|
VOICE_HERTZ,
|
||||||
|
VOICE_KBIT_PER_SEC,
|
||||||
};
|
};
|
||||||
|
|
||||||
#if CONFIG_CODEC != SWCODEC
|
#if CONFIG_CODEC != SWCODEC
|
||||||
|
|
|
@ -41,6 +41,7 @@ enum {
|
||||||
UNIT_PER_SEC, /* per second */
|
UNIT_PER_SEC, /* per second */
|
||||||
UNIT_HERTZ, /* hertz */
|
UNIT_HERTZ, /* hertz */
|
||||||
UNIT_MB, /* Megabytes */
|
UNIT_MB, /* Megabytes */
|
||||||
|
UNIT_KBIT, /* kilobits per sec */
|
||||||
UNIT_LAST /* END MARKER */
|
UNIT_LAST /* END MARKER */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -577,7 +577,7 @@ static bool dirbrowse(void)
|
||||||
if (global_settings.rec_startup) {
|
if (global_settings.rec_startup) {
|
||||||
/* We fake being in the menu structure by calling
|
/* We fake being in the menu structure by calling
|
||||||
the appropriate parent when we drop out of each screen */
|
the appropriate parent when we drop out of each screen */
|
||||||
recording_screen();
|
recording_screen(false);
|
||||||
rec_menu();
|
rec_menu();
|
||||||
main_menu();
|
main_menu();
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ bool charger_enabled;
|
||||||
|
|
||||||
static bool powered = false;
|
static bool powered = false;
|
||||||
|
|
||||||
bool radio_powered()
|
bool radio_powered(void)
|
||||||
{
|
{
|
||||||
return powered;
|
return powered;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,9 @@
|
||||||
#define AUDIO_STATUS_PRERECORD 8
|
#define AUDIO_STATUS_PRERECORD 8
|
||||||
#define AUDIO_STATUS_ERROR 16
|
#define AUDIO_STATUS_ERROR 16
|
||||||
|
|
||||||
|
#define AUDIO_STATUS_STAYON_FLAGS \
|
||||||
|
(AUDIO_STATUS_PLAY | AUDIO_STATUS_PAUSE | AUDIO_STATUS_RECORD | AUDIO_)
|
||||||
|
|
||||||
#define AUDIOERR_DISK_FULL 1
|
#define AUDIOERR_DISK_FULL 1
|
||||||
|
|
||||||
#define AUDIO_GAIN_LINEIN 0
|
#define AUDIO_GAIN_LINEIN 0
|
||||||
|
@ -69,6 +72,7 @@ void audio_resume(void);
|
||||||
void audio_next(void);
|
void audio_next(void);
|
||||||
void audio_prev(void);
|
void audio_prev(void);
|
||||||
int audio_status(void);
|
int audio_status(void);
|
||||||
|
bool audio_query_poweroff(void);
|
||||||
int audio_track_count(void); /* SWCODEC only */
|
int audio_track_count(void); /* SWCODEC only */
|
||||||
void audio_pre_ff_rewind(void); /* SWCODEC only */
|
void audio_pre_ff_rewind(void); /* SWCODEC only */
|
||||||
void audio_ff_rewind(long newtime);
|
void audio_ff_rewind(long newtime);
|
||||||
|
@ -93,14 +97,56 @@ void audio_stop_recording(void);
|
||||||
void audio_pause_recording(void);
|
void audio_pause_recording(void);
|
||||||
void audio_resume_recording(void);
|
void audio_resume_recording(void);
|
||||||
void audio_new_file(const char *filename);
|
void audio_new_file(const char *filename);
|
||||||
|
|
||||||
|
/* audio sources */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
AUDIO_SRC_PLAYBACK = -1, /* for audio playback (default) */
|
||||||
|
AUDIO_SRC_MIC, /* monitor mic */
|
||||||
|
AUDIO_SRC_LINEIN, /* monitor line in */
|
||||||
|
#ifdef HAVE_SPDIF_IN
|
||||||
|
AUDIO_SRC_SPDIF, /* monitor spdif */
|
||||||
|
#endif
|
||||||
|
#if defined(HAVE_FMRADIO_IN) || defined(CONFIG_TUNER)
|
||||||
|
AUDIO_SRC_FMRADIO, /* monitor fm radio */
|
||||||
|
#endif
|
||||||
|
/* define new audio sources above this line */
|
||||||
|
AUDIO_SOURCE_LIST_END,
|
||||||
|
/* AUDIO_SRC_FMRADIO must be declared #ifdef CONFIG_TUNER but is not in
|
||||||
|
the list of recordable sources. HAVE_FMRADIO_IN implies CONFIG_TUNER. */
|
||||||
|
#if defined(HAVE_FMRADIO_IN) || !defined(CONFIG_TUNER)
|
||||||
|
AUDIO_NUM_SOURCES = AUDIO_SOURCE_LIST_END,
|
||||||
|
#else
|
||||||
|
AUDIO_NUM_SOURCES = AUDIO_SOURCE_LIST_END-1,
|
||||||
|
#endif
|
||||||
|
AUDIO_SRC_MAX = AUDIO_NUM_SOURCES-1
|
||||||
|
};
|
||||||
|
|
||||||
|
/* channel modes */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CHN_MODE_MONO = 1,
|
||||||
|
CHN_MODE_STEREO,
|
||||||
|
};
|
||||||
void audio_set_recording_options(int frequency, int quality,
|
void audio_set_recording_options(int frequency, int quality,
|
||||||
int source, int channel_mode,
|
int source, int channel_mode,
|
||||||
bool editable, int prerecord_time);
|
bool editable, int prerecord_time);
|
||||||
void audio_set_recording_gain(int left, int right, int type);
|
void audio_set_recording_gain(int left, int right, int type);
|
||||||
unsigned long audio_recorded_time(void);
|
unsigned long audio_recorded_time(void);
|
||||||
unsigned long audio_num_recorded_bytes(void);
|
unsigned long audio_num_recorded_bytes(void);
|
||||||
|
#if 0
|
||||||
|
#ifdef HAVE_SPDIF_POWER
|
||||||
void audio_set_spdif_power_setting(bool on);
|
void audio_set_spdif_power_setting(bool on);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
unsigned long audio_get_spdif_sample_rate(void);
|
unsigned long audio_get_spdif_sample_rate(void);
|
||||||
|
#if CONFIG_CODEC == SWCODEC
|
||||||
|
/* audio encoder functions (defined in playback.c) */
|
||||||
|
int audio_get_encoder_id(void);
|
||||||
|
void audio_load_encoder(int enc_id);
|
||||||
|
void audio_remove_encoder(void);
|
||||||
|
#endif /* CONFIG_CODEC == SWCODEC */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -135,6 +135,9 @@
|
||||||
/* Someone with H100 and BDM, please verify if this works. */
|
/* Someone with H100 and BDM, please verify if this works. */
|
||||||
/* #define HAVE_EEPROM */
|
/* #define HAVE_EEPROM */
|
||||||
|
|
||||||
|
/* Define this for FM radio input available (not for SIMULATOR) */
|
||||||
|
#define HAVE_FMRADIO_IN
|
||||||
|
|
||||||
#endif /* !SIMULATOR */
|
#endif /* !SIMULATOR */
|
||||||
|
|
||||||
/* Define this for S/PDIF input available */
|
/* Define this for S/PDIF input available */
|
||||||
|
|
|
@ -132,6 +132,9 @@
|
||||||
/* Define this if the EEPROM chip is used */
|
/* Define this if the EEPROM chip is used */
|
||||||
#define HAVE_EEPROM_SETTINGS
|
#define HAVE_EEPROM_SETTINGS
|
||||||
|
|
||||||
|
/* Define this for FM radio input available (not for SIMULATOR) */
|
||||||
|
#define HAVE_FMRADIO_IN
|
||||||
|
|
||||||
#endif /* !SIMULATOR */
|
#endif /* !SIMULATOR */
|
||||||
|
|
||||||
/* Define this for S/PDIF input available */
|
/* Define this for S/PDIF input available */
|
||||||
|
|
|
@ -140,4 +140,7 @@
|
||||||
/* Define this if there is an EEPROM chip */
|
/* Define this if there is an EEPROM chip */
|
||||||
#define HAVE_EEPROM
|
#define HAVE_EEPROM
|
||||||
|
|
||||||
|
/* Define this for FM radio input available (not for SIMULATOR) */
|
||||||
|
#define HAVE_FMRADIO_IN
|
||||||
|
|
||||||
#endif /* SIMULATOR */
|
#endif /* SIMULATOR */
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
/* define this if you have access to the quickscreen */
|
/* define this if you have access to the quickscreen */
|
||||||
#define HAVE_QUICKSCREEN
|
#define HAVE_QUICKSCREEN
|
||||||
|
|
||||||
/* define this if you have access to the pitchscreen */
|
/* define this if you have access to the pitchscreen */
|
||||||
#define HAVE_PITCHSCREEN
|
#define HAVE_PITCHSCREEN
|
||||||
|
|
||||||
|
@ -81,6 +82,9 @@
|
||||||
should be defined as well. */
|
should be defined as well. */
|
||||||
#define HAVE_LCD_SLEEP
|
#define HAVE_LCD_SLEEP
|
||||||
|
|
||||||
|
/* Define this for FM radio input available (not for SIMULATOR) */
|
||||||
|
#define HAVE_FMRADIO_IN
|
||||||
|
|
||||||
/* Define this if you have a Motorola SCF5250 */
|
/* Define this if you have a Motorola SCF5250 */
|
||||||
#define CONFIG_CPU MCF5250
|
#define CONFIG_CPU MCF5250
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,22 @@
|
||||||
#ifndef FMRADIO_H
|
#ifndef FMRADIO_H
|
||||||
#define FMRADIO_H
|
#define FMRADIO_H
|
||||||
|
|
||||||
|
/** declare some stuff here so powermgmt.c can properly tell if the radio is
|
||||||
|
actually playing and not just paused. This break in heirarchy is allowed
|
||||||
|
for audio_status(). **/
|
||||||
|
|
||||||
|
/* set when radio is playing or paused within fm radio screen */
|
||||||
|
#define FMRADIO_OFF 0x0
|
||||||
|
#define FMRADIO_PLAYING 0x1
|
||||||
|
#define FMRADIO_PAUSED 0x2
|
||||||
|
|
||||||
|
/* returns the IN flag */
|
||||||
|
#define FMRADIO_IN_SCREEN(s) ((s) & FMRADIO_IN_FLAG)
|
||||||
|
#define FMRADIO_STATUS_PLAYING(s) ((s) & FMRADIO_PLAYING_OUT)
|
||||||
|
#define FMRADIO_STATUS_PAUSED(s) ((s) & FMRADIO_PAUSED_OUT)
|
||||||
|
|
||||||
|
extern int get_radio_status(void);
|
||||||
|
|
||||||
extern int fmradio_read(int addr);
|
extern int fmradio_read(int addr);
|
||||||
extern void fmradio_set(int addr, int data);
|
extern void fmradio_set(int addr, int data);
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
|
|
||||||
/* Audio file types. */
|
/* Audio file types. */
|
||||||
/* NOTE: When adding new audio types, also add to codec_labels[] in id3.c */
|
|
||||||
enum {
|
enum {
|
||||||
AFMT_UNKNOWN = 0, /* Unknown file format */
|
AFMT_UNKNOWN = 0, /* Unknown file format */
|
||||||
|
|
||||||
|
@ -46,9 +45,48 @@ enum {
|
||||||
|
|
||||||
/* New formats must be added to the end of this list */
|
/* New formats must be added to the end of this list */
|
||||||
|
|
||||||
AFMT_NUM_CODECS
|
AFMT_NUM_CODECS,
|
||||||
|
|
||||||
|
#if CONFIG_CODEC == SWCODEC
|
||||||
|
/* masks to decompose parts */
|
||||||
|
CODEC_AFMT_MASK = 0x0fff,
|
||||||
|
CODEC_TYPE_MASK = 0x7000,
|
||||||
|
|
||||||
|
/* switch for specifying codec type when requesting a filename */
|
||||||
|
CODEC_TYPE_DECODER = (0 << 12), /* default */
|
||||||
|
CODEC_TYPE_ENCODER = (1 << 12)
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if CONFIG_CODEC == SWCODEC
|
||||||
|
#define AFMT_ENTRY(label, codec_fname, codec_enc_fname, enc_ext) \
|
||||||
|
{ label, codec_fname, codec_enc_fname, enc_ext }
|
||||||
|
#else
|
||||||
|
#define AFMT_ENTRY(label, codec_fname, codec_enc_fname, enc_ext) \
|
||||||
|
{ label }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* record describing the audio format */
|
||||||
|
struct afmt_entry
|
||||||
|
{
|
||||||
|
#if CONFIG_CODEC == SWCODEC
|
||||||
|
char label[8]; /* format label */
|
||||||
|
char *codec_fn; /* filename of decoder codec */
|
||||||
|
char *codec_enc_fn; /* filename of encoder codec */
|
||||||
|
char *ext; /* default extension for file (enc only for now) */
|
||||||
|
#else
|
||||||
|
char label[4];
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/* database of labels and codecs. add formats per above enum */
|
||||||
|
extern const struct afmt_entry audio_formats[AFMT_NUM_CODECS];
|
||||||
|
|
||||||
|
#if CONFIG_CODEC == SWCODEC
|
||||||
|
/* recording quality to AFMT_* */
|
||||||
|
extern const int rec_quality_info_afmt[9];
|
||||||
|
#endif
|
||||||
|
|
||||||
struct mp3entry {
|
struct mp3entry {
|
||||||
char path[MAX_PATH];
|
char path[MAX_PATH];
|
||||||
char* title;
|
char* title;
|
||||||
|
|
|
@ -20,10 +20,22 @@
|
||||||
#ifndef PCM_RECORD_H
|
#ifndef PCM_RECORD_H
|
||||||
#define PCM_RECORD_H
|
#define PCM_RECORD_H
|
||||||
|
|
||||||
|
void enc_set_parameters(int chunk_size, int num_chunks,
|
||||||
|
int samp_per_chunk, char *head_ptr, int head_size,
|
||||||
|
int enc_id);
|
||||||
|
void enc_get_inputs(int *buffer_size, int *channels, int *quality);
|
||||||
|
unsigned int* enc_alloc_chunk(void);
|
||||||
|
void enc_free_chunk(void);
|
||||||
|
int enc_wavbuf_near_empty(void);
|
||||||
|
char* enc_get_wav_data(int size);
|
||||||
|
extern void (*enc_set_header_callback)(void *head_buffer, int head_size,
|
||||||
|
int num_pcm_samples, bool is_file_header);
|
||||||
|
|
||||||
unsigned long pcm_rec_status(void);
|
unsigned long pcm_rec_status(void);
|
||||||
void pcm_rec_init(void);
|
void pcm_rec_init(void);
|
||||||
void pcm_rec_mux(int source);
|
void pcm_rec_mux(int source);
|
||||||
|
int pcm_rec_current_bitrate(void);
|
||||||
|
int pcm_get_num_unprocessed(void);
|
||||||
void pcm_rec_get_peaks(int *left, int *right);
|
void pcm_rec_get_peaks(int *left, int *right);
|
||||||
|
|
||||||
/* audio.h contains audio recording functions */
|
/* audio.h contains audio recording functions */
|
||||||
|
|
|
@ -85,28 +85,59 @@ static const char* const genres[] = {
|
||||||
"Synthpop"
|
"Synthpop"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char* const codec_labels[] = {
|
/* database of audio formats */
|
||||||
"???", /* Unknown file format */
|
const struct afmt_entry audio_formats[AFMT_NUM_CODECS] =
|
||||||
|
{
|
||||||
"MP1", /* MPEG Audio layer 1 */
|
/* Unknown file format */
|
||||||
"MP2", /* MPEG Audio layer 2 */
|
AFMT_ENTRY("???", NULL, NULL, NULL ),
|
||||||
"MP3", /* MPEG Audio layer 3 */
|
/* MPEG Audio layer 1 */
|
||||||
|
AFMT_ENTRY("MP1", "mpa.codec", NULL, NULL ),
|
||||||
|
/* MPEG Audio layer 2 */
|
||||||
|
AFMT_ENTRY("MP2", "mpa.codec", NULL, NULL ),
|
||||||
|
/* MPEG Audio layer 3 */
|
||||||
|
AFMT_ENTRY("MP3", "mpa.codec", "mp3_enc.codec", ".mp3"),
|
||||||
#if CONFIG_CODEC == SWCODEC
|
#if CONFIG_CODEC == SWCODEC
|
||||||
"WAV", /* Uncompressed PCM in a WAV file */
|
/* Uncompressed PCM in a WAV file */
|
||||||
"Ogg", /* Ogg Vorbis */
|
AFMT_ENTRY("WAV", "wav.codec", "wav_enc.codec", ".wav"),
|
||||||
"FLAC", /* FLAC */
|
/* Ogg Vorbis */
|
||||||
"MPC", /* Musepack */
|
AFMT_ENTRY("Ogg", "vorbis.codec", NULL, NULL ),
|
||||||
"AC3", /* A/52 (aka AC3) audio */
|
/* FLAC */
|
||||||
"WV", /* WavPack */
|
AFMT_ENTRY("FLAC", "flac.codec", NULL, NULL ),
|
||||||
"ALAC", /* Apple Lossless Audio Codec */
|
/* Musepack */
|
||||||
"AAC", /* Advanced Audio Coding in M4A container */
|
AFMT_ENTRY("MPC", "mpc.codec", NULL, NULL ),
|
||||||
"SHN", /* Shorten */
|
/* A/52 (aka AC3) audio */
|
||||||
"AIFF", /* Audio Interchange File Format */
|
AFMT_ENTRY("AC3", "a52.codec", NULL, NULL ),
|
||||||
"SID", /* SID File Format */
|
/* WavPack */
|
||||||
|
AFMT_ENTRY("WV", "wavpack.codec", "wavpack_enc.codec", ".wv" ),
|
||||||
|
/* Apple Lossless Audio Codec */
|
||||||
|
AFMT_ENTRY("ALAC", "alac.codec", NULL, NULL ),
|
||||||
|
/* Advanced Audio Coding in M4A container */
|
||||||
|
AFMT_ENTRY("AAC", "aac.codec", NULL, NULL ),
|
||||||
|
/* Shorten */
|
||||||
|
AFMT_ENTRY("SHN", "shorten.codec", NULL, NULL ),
|
||||||
|
/* Audio Interchange File Format */
|
||||||
|
AFMT_ENTRY("AIFF", "aiff.codec", NULL, NULL ),
|
||||||
|
/* SID File Format */
|
||||||
|
AFMT_ENTRY("SID", "sid.codec", NULL, NULL ),
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if CONFIG_CODEC == SWCODEC
|
||||||
|
/* recording quality to AFMT_* */
|
||||||
|
const int rec_quality_info_afmt[9] =
|
||||||
|
{
|
||||||
|
AFMT_MPA_L3, /* MPEG L3 64 kBit/s */
|
||||||
|
AFMT_MPA_L3, /* MPEG L3 96 kBit/s */
|
||||||
|
AFMT_MPA_L3, /* MPEG L3 128 kBit/s */
|
||||||
|
AFMT_MPA_L3, /* MPEG L3 160 kBit/s */
|
||||||
|
AFMT_MPA_L3, /* MPEG L3 192 kBit/s */
|
||||||
|
AFMT_MPA_L3, /* MPEG L3 224 kBit/s */
|
||||||
|
AFMT_MPA_L3, /* MPEG L3 320 kBit/s */
|
||||||
|
AFMT_WAVPACK, /* WavPack 909 kBit/s */
|
||||||
|
AFMT_PCM_WAV, /* PCM Wav 1411 kBit/s */
|
||||||
|
};
|
||||||
|
#endif /* SWCODEC */
|
||||||
|
|
||||||
char* id3_get_genre(const struct mp3entry* id3)
|
char* id3_get_genre(const struct mp3entry* id3)
|
||||||
{
|
{
|
||||||
if( id3->genre_string )
|
if( id3->genre_string )
|
||||||
|
@ -119,8 +150,8 @@ char* id3_get_genre(const struct mp3entry* id3)
|
||||||
|
|
||||||
char* id3_get_codec(const struct mp3entry* id3)
|
char* id3_get_codec(const struct mp3entry* id3)
|
||||||
{
|
{
|
||||||
if (id3->codectype < sizeof(codec_labels)/sizeof(char*)) {
|
if (id3->codectype < AFMT_NUM_CODECS) {
|
||||||
return (char*)codec_labels[id3->codectype];
|
return (char*)audio_formats[id3->codectype].label;
|
||||||
} else {
|
} else {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2484,7 +2484,7 @@ void audio_set_recording_options(int frequency, int quality,
|
||||||
|
|
||||||
DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
|
DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
|
||||||
|
|
||||||
if(source == 0) /* Mic */
|
if(source == AUDIO_SRC_MIC)
|
||||||
{
|
{
|
||||||
/* Copy left channel to right (mono mode) */
|
/* Copy left channel to right (mono mode) */
|
||||||
mas_codec_writereg(8, 0x8000);
|
mas_codec_writereg(8, 0x8000);
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -424,6 +424,7 @@ static void battery_status_update(void)
|
||||||
* 1) The USB is connected
|
* 1) The USB is connected
|
||||||
* 2) The charger is connected
|
* 2) The charger is connected
|
||||||
* 3) We are recording, or recording with pause
|
* 3) We are recording, or recording with pause
|
||||||
|
* 4) The radio is playing
|
||||||
*/
|
*/
|
||||||
static void handle_auto_poweroff(void)
|
static void handle_auto_poweroff(void)
|
||||||
{
|
{
|
||||||
|
@ -442,7 +443,7 @@ static void handle_auto_poweroff(void)
|
||||||
|
|
||||||
if(timeout &&
|
if(timeout &&
|
||||||
#ifdef CONFIG_TUNER
|
#ifdef CONFIG_TUNER
|
||||||
(!radio_powered()) &&
|
(!(get_radio_status() & FMRADIO_PLAYING)) &&
|
||||||
#endif
|
#endif
|
||||||
!usb_inserted() &&
|
!usb_inserted() &&
|
||||||
((audio_stat == 0) ||
|
((audio_stat == 0) ||
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue