1/* flac_mac - wedge utility to add FLAC support to Monkey's Audio 2 * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007 Josh Coalson 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 2 7 * of the License, or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 */ 18 19/* 20 * This program can be used to allow FLAC to masquerade as one of the other 21 * supported lossless codecs in Monkey's Audio. See the documentation for 22 * how to do this. 23 */ 24 25#if HAVE_CONFIG_H 26# include <config.h> 27#endif 28 29#include<stdio.h> 30#include<stdlib.h> 31#include<string.h> 32#include<wtypes.h> 33#include<process.h> 34#include<winbase.h> 35 36static int execit(char *prog, char *args); 37static int forkit(char *prog, char *args); 38 39int main(int argc, char *argv[]) 40{ 41 int flac_return_val = 0, opt_arg = 1, from_arg = -1, to_arg = -1, flac_level = 5, i; 42 char prog[MAX_PATH], cmdline[MAX_PATH*2], from[MAX_PATH], to[MAX_PATH], macdir[MAX_PATH], options[256], *p; 43 enum { WAVPACK, RKAU, SHORTEN } codec; 44 45 /* get the directory where MAC external codecs reside */ 46 if(0 != (p = strrchr(argv[0],'\\'))) { 47 strcpy(macdir, argv[0]); 48 *(strrchr(macdir,'\\')+1) = '\0'; 49 } 50 else { 51 strcpy(macdir, ""); 52 } 53 54 /* determine which codec we were called as and parse the options */ 55 if(p == 0) 56 p = argv[0]; 57 else 58 p++; 59 if(0 == strnicmp(p, "short", 5)) { 60 codec = SHORTEN; 61 } 62 else if(0 == strnicmp(p, "rkau", 4)) { 63 codec = RKAU; 64 if(argv[1][0] == '-' && argv[1][1] == 'l') { 65 opt_arg = 2; 66 switch(argv[1][2]) { 67 case '1': flac_level = 1; break; 68 case '2': flac_level = 5; break; 69 case '3': flac_level = 8; break; 70 } 71 } 72 } 73 else if(0 == strnicmp(p, "wavpack", 7)) { 74 codec = WAVPACK; 75 if(argv[1][0] == '-') { 76 opt_arg = 2; 77 switch(argv[1][1]) { 78 case 'f': flac_level = 1; break; 79 case 'h': flac_level = 8; break; 80 default: opt_arg = 1; 81 } 82 } 83 } 84 else { 85 return -5; 86 } 87 88 /* figure out which arguments are the source and destination files */ 89 for(i = 1; i < argc; i++) 90 if(argv[i][0] != '-') { 91 from_arg = i++; 92 break; 93 } 94 for( ; i < argc; i++) 95 if(argv[i][0] != '-') { 96 to_arg = i++; 97 break; 98 } 99 if(to_arg < 0) 100 return -4; 101 102 /* build the command to call flac with */ 103 sprintf(prog, "%sflac.exe", macdir); 104 sprintf(options, "-%d", flac_level); 105 for(i = opt_arg; i < argc; i++) 106 if(argv[i][0] == '-') { 107 strcat(options, " "); 108 strcat(options, argv[i]); 109 } 110 sprintf(cmdline, "\"%s\" %s -o \"%s\" \"%s\"", prog, options, argv[to_arg], argv[from_arg]); 111 112 flac_return_val = execit(prog, cmdline); 113 114 /* 115 * Now that flac has finished, we need to fork a process that will rename 116 * the resulting file with the correct extension once MAC has moved it to 117 * it's final resting place. 118 */ 119 if(0 == flac_return_val) { 120 /* get the destination directory, if any */ 121 if(0 != (p = strchr(argv[to_arg],'\\'))) { 122 strcpy(from, argv[to_arg]); 123 *(strrchr(from,'\\')+1) = '\0'; 124 } 125 else { 126 strcpy(from, ""); 127 } 128 129 /* for the full 'from' and 'to' paths for the renamer process */ 130 p = strrchr(argv[from_arg],'\\'); 131 strcat(from, p? p+1 : argv[from_arg]); 132 strcpy(to, from); 133 if(0 == strchr(from,'.')) 134 return -3; 135 switch(codec) { 136 case SHORTEN: strcpy(strrchr(from,'.'), ".shn"); break; 137 case WAVPACK: strcpy(strrchr(from,'.'), ".wv"); break; 138 case RKAU: strcpy(strrchr(from,'.'), ".rka"); break; 139 } 140 strcpy(strrchr(to,'.'), ".flac"); 141 142 sprintf(prog, "%sflac_ren.exe", macdir); 143 sprintf(cmdline, "\"%s\" \"%s\" \"%s\"", prog, from, to); 144 145 flac_return_val = forkit(prog, cmdline); 146 } 147 148 return flac_return_val; 149} 150 151int execit(char *prog, char *args) 152{ 153 BOOL ok; 154 STARTUPINFO startup_info; 155 PROCESS_INFORMATION proc_info; 156 157 GetStartupInfo(&startup_info); 158 159 ok = CreateProcess( 160 prog, 161 args, 162 0, /*process security attributes*/ 163 0, /*thread security attributes*/ 164 FALSE, 165 0, /*dwCreationFlags*/ 166 0, /*environment*/ 167 0, /*lpCurrentDirectory*/ 168 &startup_info, 169 &proc_info 170 ); 171 if(ok) { 172 DWORD dw; 173 dw = WaitForSingleObject(proc_info.hProcess, INFINITE); 174 ok = (dw != 0xFFFFFFFF); 175 CloseHandle(proc_info.hThread); 176 CloseHandle(proc_info.hProcess); 177 } 178 179 return ok? 0 : -1; 180} 181 182int forkit(char *prog, char *args) 183{ 184 BOOL ok; 185 STARTUPINFO startup_info; 186 PROCESS_INFORMATION proc_info; 187 188 GetStartupInfo(&startup_info); 189 190 ok = CreateProcess( 191 prog, 192 args, 193 0, /*process security attributes*/ 194 0, /*thread security attributes*/ 195 FALSE, 196 DETACHED_PROCESS, /*dwCreationFlags*/ 197 0, /*environment*/ 198 0, /*lpCurrentDirectory*/ 199 &startup_info, 200 &proc_info 201 ); 202 if(ok) { 203 CloseHandle(proc_info.hThread); 204 CloseHandle(proc_info.hProcess); 205 } 206 207 return ok? 0 : -2; 208} 209