A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 218 lines 6.9 kB view raw
1/*************************************************************************** 2 * __________ __ ___. 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 * \/ \/ \/ \/ \/ 8 * $Id$ 9 * 10 * Copyright (C) 2004 by Jörg Hohensohn 11 * 12 * This program is free software; you can redistribute it and/or 13 * modify it under the terms of the GNU General Public License 14 * as published by the Free Software Foundation; either version 2 15 * of the License, or (at your option) any later version. 16 * 17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 18 * KIND, either express or implied. 19 * 20 * A tool to generate the Rockbox "voicefont", a collection of all the UI 21 * strings. 22 * 23 * Details at http://www.rockbox.org/wiki/VoiceBuilding 24 * 25 ****************************************************************************/ 26 27#include "voicefont.h" 28 29#include <stdio.h> 30#include <string.h> 31 32#define HEADER_SIZE (20) 33#define MAX_NAME_LEN (80) 34#define MAX_VOICE_ENTRIES (2048) 35/* endian conversion macros */ 36#if defined(__BIG_ENDIAN__) 37#define UINT_TO_BE(x) (x) 38#else 39#define UINT_TO_BE(x) ((((unsigned)(x)>>24) & 0x000000ff) |\ 40 (((unsigned)(x)>>8) & 0x0000ff00) |\ 41 (((unsigned)(x)<<8) & 0x00ff0000) |\ 42 (((unsigned)(x)<<24) & 0xff000000)) 43#endif 44 45int voicefont(FILE* voicefontids,int targetnum,char* filedir, FILE* output, unsigned int version) 46{ 47 48 int i,j; 49 50 /* two tables, one for normal strings, one for voice-only (>0x8000) */ 51 static char names[MAX_VOICE_ENTRIES][MAX_NAME_LEN]; /* worst-case space */ 52 char name[MAX_NAME_LEN]; /* one string ID */ 53 static int pos[MAX_VOICE_ENTRIES]; /* position of sample */ 54 static int size[MAX_VOICE_ENTRIES]; /* length of clip */ 55 int voiceonly[MAX_VOICE_ENTRIES]; /* flag if this is voice only */ 56 int count = 0; 57 int count_voiceonly = 0; 58 unsigned int value; /* value to be written to file */ 59 static unsigned char buffer[65535]; /* clip buffer, allow only 64K */ 60 int fields; 61 char line[255]; /* one line from the .lang file */ 62 char encfilename1[1024]; 63 char encfilename2[1024]; 64 char* encfilename; 65 FILE* pEncFile; 66 67 memset(voiceonly, 0, sizeof(voiceonly)); 68 while (!feof(voicefontids)) 69 { 70 if (!fgets(line, sizeof(line), voicefontids)) 71 break; 72 if (line[0] == '#') /* comment */ 73 continue; 74 75 fields = sscanf(line, " id: %s", name); 76 if (fields == 1) 77 { 78 strcpy(names[count], name); 79 if (strncmp("VOICE_", name, 6) == 0) /* voice-only id? */ 80 { 81 count_voiceonly++; 82 voiceonly[count] = 1; 83 } 84 count++; /* next entry started */ 85 continue; 86 } 87 } 88 fclose(voicefontids); 89 90 if (count > MAX_VOICE_ENTRIES) 91 { 92 return -1; 93 } 94 95 fseek(output, HEADER_SIZE + count*8, SEEK_SET); /* space for header */ 96 97 for (i=0; i<count; i++) 98 { 99 pos[i] = ftell(output); 100 sprintf(encfilename1, "%s%s.enc", filedir, names[i]); 101 sprintf(encfilename2, "%s%s.wav.enc", filedir, names[i]); 102 encfilename = encfilename1; 103 pEncFile = fopen(encfilename, "rb"); 104 if (pEncFile == NULL) 105 { /* alternatively, try the lame default filename */ 106 encfilename = encfilename2; 107 pEncFile = fopen(encfilename, "rb"); 108 if (pEncFile == NULL) 109 { 110 printf("enc file %s not found!\n", encfilename1); 111 size[i] = 0; 112 continue; 113 } 114 } 115 printf("processing %s", encfilename); 116 117 size[i] = fread(buffer, 1, sizeof(buffer), pEncFile); 118 fclose(pEncFile); 119 fwrite(buffer, 1, size[i], output); 120 121 printf(": %d %s %d\n", i, names[i], size[i]); /* debug */ 122 } /* for i */ 123 124 125 fseek(output, 0, SEEK_SET); 126 127 /* Create the file format: */ 128 129 /* 1st 32 bit value in the file is the version number */ 130 value = UINT_TO_BE(version); 131 fwrite(&value, sizeof(value), 1, output); 132 133 /* 2nd 32 bit value in the file is the id number for the target 134 we made the voce file for */ 135 value = UINT_TO_BE(targetnum); 136 fwrite(&value, sizeof(value), 1, output); 137 138 /* 3rd 32 bit value in the file is the header size (= 1st table position) */ 139 value = UINT_TO_BE(HEADER_SIZE); /* version, target id, header size, number1, number2 */ 140 fwrite(&value, sizeof(value), 1, output); 141 142 /* 4th 32 bit value in the file is the number of clips in 1st table */ 143 value = UINT_TO_BE(count-count_voiceonly); 144 fwrite(&value, sizeof(value), 1, output); 145 146 /* 5th bit value in the file is the number of clips in 2nd table */ 147 value = UINT_TO_BE(count_voiceonly); 148 fwrite(&value, sizeof(value), 1, output); 149 150 /* then followed by offset/size pairs for each clip */ 151 for (j=0; j<2; j++) /* now 2 tables */ 152 { 153 for (i=0; i<count; i++) 154 { 155 if (j == 0) /* first run, skip the voice only ones */ 156 { 157 if (voiceonly[i] == 1) 158 continue; 159 } 160 else /* second run, skip the non voice only ones */ 161 { 162 if (!(voiceonly[i] == 1)) 163 continue; 164 } 165 166 value = UINT_TO_BE(pos[i]); /* position */ 167 fwrite(&value, sizeof(value), 1,output); 168 value = UINT_TO_BE(size[i]); /* size */ 169 fwrite(&value, sizeof(value), 1, output); 170 printf(": [%d]%s : %s {%x, %x}\n", i, 171 (voiceonly[i] ==1 ? "[V]":""), names[i], 172 UINT_TO_BE(pos[i]), UINT_TO_BE(size[i])); /* debug */ 173 } /* for i */ 174 } /* for j */ 175 176 fclose(output); 177 178 return 0; 179 180 181} 182#ifndef RBUTIL 183int main (int argc, char** argv) 184{ 185 FILE *ids, *output; 186 187 if (argc < 2) 188 { 189 printf("Makes a Rockbox voicefont from a collection of encoded clips.\n"); 190 printf("Usage: voicefont <string id list file> <target id> <enc path> <output file>\n"); 191 printf("\n"); 192 printf("Example: \n"); 193 printf("voicefont voicefontids.txt 2 voice/ voicefont.bin\n"); 194 return -1; 195 } 196 197 ids = fopen(argv[1], "r"); 198 if (ids == NULL) 199 { 200 printf("Error opening language file %s\n", argv[1]); 201 return -2; 202 } 203 204 output = fopen(argv[4], "wb"); 205 if (output == NULL) 206 { 207 printf("Error opening output file %s\n", argv[4]); 208 return -2; 209 } 210 211 if (voicefont(ids, atoi(argv[2]),argv[3],output, 400) < 0) 212 { 213 printf("Error too many voicefont entries!\n"); 214 return -3; 215 } 216 return 0; 217} 218#endif