source: trunk/src/org/apollo/io/AudioPathManager.java@ 1023

Last change on this file since 1023 was 1023, checked in by davidb, 8 years ago

Change to make the 'audio' folder to be defined/located the same way as the 'images' folder

File size: 6.6 KB
Line 
1package org.apollo.io;
2
3import java.io.BufferedReader;
4import java.io.File;
5import java.io.FileReader;
6import java.io.FileWriter;
7import java.io.IOException;
8import java.io.UnsupportedEncodingException;
9import java.util.Random;
10
11import org.apollo.audio.structure.AudioStructureModel;
12import org.apollo.util.ApolloSystemLog;
13import org.apollo.util.RegExpFileFilter;
14
15import org.expeditee.gui.FrameIO;
16
17/**
18 * Generates audio paths.
19 *
20 * @author Brook Novak
21 *
22 */
23public class AudioPathManager {
24
25 private AudioPathManager() {
26 // util constructor
27 }
28
29 /** Suffixed with the native file separator */
30 public static String AUDIO_HOME_DIRECTORY = "audio" + File.separatorChar;
31
32 /** Stores all virtual names created by this repository. */
33 private static final String VIRTUAL_NAME_BASEFILE = ".vnames";
34
35 public static final int PREAMBLE_LENGTH = 6;
36
37 private static long counter = 0;
38
39 private static Random rand = new Random(System.currentTimeMillis());
40
41 /**
42 * Class initializer.
43 * Ensures that the home directory(ies) exist and preps the counter
44 */
45 static {
46 String expeditee_home = System.getProperty("expeditee.home");
47
48 /*
49 if (expeditee_home != null) {
50 AUDIO_HOME_DIRECTORY = expeditee_home + File.separator + AUDIO_HOME_DIRECTORY;
51 }*/
52 AUDIO_HOME_DIRECTORY = FrameIO.PARENT_FOLDER + AUDIO_HOME_DIRECTORY;
53 //System.err.println("*** audio_home_dir = " + AUDIO_HOME_DIRECTORY);
54
55 // Ensure audio directory exists
56 File dir = new File(AUDIO_HOME_DIRECTORY);
57 if (!dir.exists()) {
58 if (!dir.mkdir()) {
59 ApolloSystemLog.println("Unable to create missing audio home directory");
60 }
61 }
62
63 // Load counter
64 loadCounter(dir);
65 }
66
67 /**
68 * Loads the counter
69 * @param dir The dir where the audio files live.
70 */
71 private static void loadCounter(File dir) {
72 String[] files = getAudioFileNames(dir);
73 if (files == null) { // Due to IO exception
74 ApolloSystemLog.printError("Failed to read audio directory");
75 return;
76 }
77 long count = 0;
78 if (files != null) {
79 for (String f : files) {
80
81 int start = -1, end = -1;
82 for (int i = 0; i < f.length(); i++) {
83 if (Character.isDigit(f.charAt(i)) && start == -1) {
84 start = i;
85 } else if (!Character.isDigit(f.charAt(i)) && start != -1) {
86 end = i;
87 break;
88 }
89 }
90
91 if (start >= 0 && end == -1) end = f.length();
92
93 if (start > 0 && end >= start) { // not start >= 0 since missing preable
94
95 String tmp = f.substring(start, end);
96 long l = Long.parseLong(tmp);
97 if (l >= count)
98 count = l + 1;
99 }
100 }
101 }
102
103 counter = count;
104 }
105
106 /**
107 * @param dir
108 * @return
109 * Null if an IO exception occurs
110 */
111 private static String[] getAudioFileNames(File dir) {
112 return dir.list(new RegExpFileFilter("^[A-Z]+\\d+.*$"));
113 }
114
115 /**
116 * @return
117 * The list of audio files in the audio home directory.
118 * Can be empty. Null if directory does not exist or failed to
119 * read list of files.
120 */
121 public static String[] getAudioFileNames() {
122 File audioDir = new File(AUDIO_HOME_DIRECTORY);
123 if (!audioDir.exists() || !audioDir.isDirectory()) return null;
124 return getAudioFileNames(audioDir);
125 }
126
127
128 /**
129 * @return The current counter.
130 */
131 public static long getCounter() {
132 return counter;
133 }
134
135 /**
136 * Generates a filename that is unique within the AUDIO_HOME_DIRECTORY.
137 *
138 * @param extension
139 * The extension of the filename to generate. Exclude period.
140 *
141 * @return
142 * A free unused filename with the given extension. Excludes directory.
143 * Even if the path return is not used, it will never be re-generated.
144 */
145 public static String generateLocateFileName(String extension) {
146
147 String filename = generateRandomFilenameBase() + "." + extension;
148
149 File f = new File(AUDIO_HOME_DIRECTORY + filename);
150
151 if (AudioStructureModel.getInstance().getTrackGraphInfo(filename, null) != null ||
152 f.exists()) { // recurse: until found a free path:
153 return generateLocateFileName(extension);
154 }
155
156 return filename;
157 }
158
159 private static String generateRandomFilenameBase() {
160
161 counter++;
162 if (counter < 0) counter = 0; // wraps positivey
163
164 // Generate random alpha preamble
165 byte[] bytes = new byte[PREAMBLE_LENGTH];
166 rand.nextBytes(bytes);
167
168
169 for (int i = 0; i < PREAMBLE_LENGTH; i++) {
170 if (bytes[i] < 0) bytes[i] *= -1;
171 int alphacap = (65 + (Math.abs(bytes[i]) % 26)); // A-Z in US ASCII encoding
172 bytes[i] = (byte) alphacap;
173
174 }
175
176 // Decode ASCII Byte array to javas UTF-16 encoding
177 String preamble = null;
178
179 try {
180 preamble = new String(bytes, "US-ASCII");
181 } catch (UnsupportedEncodingException e) {
182 e.printStackTrace();
183 preamble = "AUDIO";
184 }
185
186 // Build the filename string
187 return preamble + counter;
188
189 }
190
191
192
193 /**
194 * Lots of room for improvement here, ensures that a virtual filename is unique .. stores
195 * allocated virtual filenames on file.
196 *
197 * @return
198 * The new virtual filename.
199 */
200 public static String generateVirtualFilename() {
201
202 // Ensure that the name base file exists. Assumes the audio home directory exists.
203 File vnameBase = new File(AUDIO_HOME_DIRECTORY + VIRTUAL_NAME_BASEFILE);
204 if (!vnameBase.exists()) {
205 try {
206 vnameBase.createNewFile();
207 } catch (IOException e) {
208 e.printStackTrace();
209 }
210 }
211
212 String vname = null;
213
214 while (vname == null) {
215 vname = generateRandomFilenameBase() + ".vrt";
216 assert(vname != null);
217
218 BufferedReader in = null;
219 String line = null;
220
221 try {
222
223 // Open the vbase for reading
224 in = new BufferedReader(new FileReader(vnameBase));
225
226 // Read the sbase file and check all names
227 while ((line = in.readLine()) != null) {
228 line = line.trim();
229 if (line.equalsIgnoreCase(vname)) break;
230 }
231
232 } catch (Exception e) {
233 e.printStackTrace();
234 break; // just use the last generated filename...
235
236 // Clean up
237 } finally {
238 if (in != null) {
239 try {
240 in.close();
241 } catch (IOException e) {
242 e.printStackTrace();
243 }
244 }
245 }
246
247 // Check to see if name is infact unique
248 if (AudioStructureModel.getInstance().getLinkedTrackGraphInfo(vname, null) == null &&
249 (line == null || !line.equalsIgnoreCase(vname))) {
250 // If so, then enter new entry into the db.
251 FileWriter out = null;
252
253 try {
254 // Open the vbase for appending
255 out = new FileWriter(vnameBase, true);
256 out.write("\n" + vname);
257
258 } catch (IOException e) {
259 e.printStackTrace();
260
261 // Clean up
262 } finally {
263 if (out != null) {
264 try {
265 out.close();
266 } catch (IOException e) {
267 e.printStackTrace();
268 }
269 }
270 }
271
272 } else vname = null;
273 }
274
275 // Return the generated vname
276 return vname;
277
278 }
279}
Note: See TracBrowser for help on using the repository browser.