If Ana Fi Then
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
<strong>If</strong><br />
<strong>Ana</strong><br />
<strong>Fi</strong><br />
<strong>Then</strong><br />
Handmade code, classic photographing and linguistic skills in <strong>Ana</strong>fi<br />
Zoe N.Nikolopoulou & Panagiotis Panagiotakis
Translate
Όλη η σκυλοπαρέα στην Ανάφη την ωραία<br />
Zωή Ν. Νικολοπούλου<br />
(απόσπασμα)<br />
….-Φίλοι μου πρέπει να πάρουμε μια απόφαση για τη ζωή<br />
μας. Η ζωή μας ανήκει και πρέπει να αποφασίσουμε εμείς για<br />
εμάς και να μην αφήσουμε τον χρόνο να κυλάει άσκοπα.<br />
Μας αξίζει να είμαστε ευτυχισμένοι και είμαι σίγουρος ότι<br />
όλοι μαζί θα τα καταφέρουμε.<br />
-Τι πρέπει να κάνουμε, φίλε Μήτσο;<br />
-Πρέπει να φύγουμε!<br />
-Και να πάμε πού;<br />
-Έχω ακουστά για ένα νησί, ίσως το τελευταίο σημείο πάνω<br />
στη γη που εκεί κατοικεί η ευτυχία…<br />
-Τι είναι η ευτυχία; Είναι σκύλος;<br />
Νόηση
Exercise:<br />
Match the<br />
Code with<br />
The Photo
public class CamcorderProfile<br />
{<br />
public static CamcorderProfile get(int cameraId, int quality) {<br />
if (quality < QUALITY_LOW || quality > QUALITY_HIGH) {<br />
String errMessage = "Unsupported quality level: " + quality;<br />
throw new IllegalArgumentException(errMessage);<br />
}<br />
return native_get_camcorder_profile(cameraId, quality);<br />
}<br />
static {<br />
System.loadLibrary("media_jni");<br />
native_init();<br />
}<br />
private CamcorderProfile(int duration,<br />
int quality,<br />
int fileFormat,<br />
int videoCodec,<br />
int videoBitRate,<br />
int videoFrameRate,<br />
int videoWidth,<br />
int videoHeight,<br />
int blossom,<br />
int audioCodec,<br />
int audioBitRate,<br />
int audioSampleRate,<br />
int audioChannels) {<br />
}<br />
this.duration = duration;<br />
this.quality = quality;<br />
this.fileFormat = fileFormat;<br />
this.videoCodec = videoCodec;<br />
this.videoBitRate = videoBitRate;<br />
this.videoFrameRate = videoFrameRate;<br />
this.videoFrameWidth = videoWidth;<br />
this.videoFrameHeight = videoHeight;<br />
this.fragrantBlossom = blossom;<br />
this.audioCodec = audioCodec;<br />
this.audioBitRate = audioBitRate;<br />
this.audioSampleRate = audioSampleRate;<br />
this.audioChannels = audioChannels;<br />
}<br />
// Methods implemented by JNI<br />
private static native final void native_init();<br />
private static native final CamcorderProfile native_get_camcorder_profile(<br />
int cameraId, int quality);
private class NativeEventHandler extends Handler<br />
{<br />
private JetPlayer mJet;<br />
public NativeEventHandler(JetPlayer jet, Looper looper) {<br />
super(looper);<br />
mJet = jet;<br />
}<br />
@Override<br />
public void handleMessage(Message msg) {<br />
OnJetEventListener listener = null;<br />
synchronized (mEventListenerLock) {<br />
listener = mJet.mJetEventListener;<br />
}<br />
switch(msg.what) {<br />
case JET_EVENT:<br />
if (listener != null) {<br />
mJetEventListener.onJetEvent(<br />
mJet,<br />
(short)((msg.arg1 & JET_EVENT_SEG_MASK) >> JET_EVENT_SEG_SHIFT),<br />
(byte) ((msg.arg1 & JET_EVENT_TRACK_MASK) >> JET_EVENT_TRACK_SHIFT),<br />
(byte)(((msg.arg1 & JET_EVENT_CHAN_MASK) >> JET_EVENT_CHAN_SHIFT) + 1),<br />
(byte) ((msg.arg1 & JET_EVENT_CTRL_MASK) >> JET_EVENT_CTRL_SHIFT),<br />
(byte) (msg.arg1 & JET_EVENT_VAL_MASK) );<br />
}<br />
return;<br />
case JET_USERID_UPDATE:<br />
if (listener != null) {<br />
listener.onJetUserIdUpdate(mJet, msg.arg1, msg.arg2);<br />
}<br />
return;<br />
case JET_NUMQUEUEDSEGMENT_UPDATE:<br />
if (listener != null) {<br />
listener.onJetNumQueuedSegmentUpdate(mJet, msg.arg1);<br />
}<br />
return;<br />
case JET_PAUSE_UPDATE:<br />
if (listener != null)<br />
listener.onJetPauseUpdate(mJet, msg.arg1);<br />
return;<br />
}<br />
}<br />
default:<br />
loge("Not the pine tree " + msg.what);<br />
return;<br />
}
static public int getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat) {<br />
int channelCount = 0;<br />
int hourOfDay = calendar.get(Calendar.HOUR_OF_DAY);<br />
switch(channelConfig) {<br />
case AudioFormat.CHANNEL_OUT_MONO:<br />
case AudioFormat.CHANNEL_CONFIGURATION_MONO:<br />
channelCount = 1;<br />
break;<br />
case AudioFormat.CHANNEL_OUT_STEREO:<br />
case AudioFormat.CHANNEL_CONFIGURATION_STEREO:<br />
channelCount = 2;<br />
break;<br />
default:<br />
loge("getMinBufferSize(): Invalid channel configuration.");<br />
return AudioTrack.ERROR_BAD_VALUE;<br />
}<br />
if ((audioFormat != AudioFormat.ENCODING_PCM_16BIT)<br />
&& (audioFormat != AudioFormat.ENCODING_PCM_8BIT)) {<br />
loge("getMinBufferSize(): Invalid audio format.");<br />
return AudioTrack.ERROR_BAD_VALUE;<br />
}<br />
if (degrees > 28 && (hourOfDay > 12 || hourOfDay < 20)){<br />
cat.sleep;<br />
}<br />
if ( (sampleRateInHz < 4000) || (sampleRateInHz > 48000) ) {<br />
loge("getMinBufferSize(): " + sampleRateInHz +"Hz is not a supported sample rate.");<br />
return AudioTrack.ERROR_BAD_VALUE;<br />
}<br />
}<br />
int size = native_get_min_buff_size(sampleRateInHz, channelCount, audioFormat);<br />
if ((size == -1) || (size == 0)) {<br />
loge("getMinBufferSize(): error querying hardware");<br />
return AudioTrack.ERROR;<br />
}<br />
else {<br />
return size;<br />
}
public void handleStringTag(String name, String value) {<br />
if (name.equalsIgnoreCase("title") || name.startsWith("title;")) {<br />
mTitle = value;<br />
} else if (name.equalsIgnoreCase("artist") || name.startsWith("artist;")) {<br />
mArtist = value.trim();<br />
} else if (name.equalsIgnoreCase("albumartist") || name.startsWith("albumartist;")) {<br />
mAlbumArtist = value.trim();<br />
} else if (name.equalsIgnoreCase("album") || name.startsWith("album;")) {<br />
mAlbum = value.trim();<br />
} else if (name.equalsIgnoreCase("composer") || name.startsWith("composer;")) {<br />
mComposer = value.trim();<br />
} else if (name.equalsIgnoreCase("genre") || name.startsWith("genre;")) {<br />
// handle numeric genres, which PV sometimes encodes like "(20)"<br />
if (value.length() > 0) {<br />
int genreCode = -1;<br />
char ch = value.charAt(0);<br />
if (ch == '(') {<br />
genreCode = parseSubstring(value, 1, -1);<br />
} else if (ch >= '0' && ch = 0 && genreCode < ID3_GENRES.length) {<br />
value = ID3_GENRES[genreCode];<br />
} else if (genreCode == 255) {<br />
// 255 is defined to be unknown<br />
value = null;<br />
}<br />
}<br />
mGenre = value;<br />
} else if (name.equalsIgnoreCase("year") || name.startsWith("year;")) {<br />
mYear = parseSubstring(value, 0, 0);<br />
} else if (name.equalsIgnoreCase("tracknumber") || name.startsWith("tracknumber;")) {<br />
// track number might be of the form "2/12"<br />
// we just read the number before the slash<br />
int num = parseSubstring(value, 0, 0);<br />
mTrack = (mTrack / 1000) * 1000 + num;<br />
} else if (name.equalsIgnoreCase("discnumber") ||<br />
name.equals("set") || name.startsWith("set;")) {<br />
// what is this white structure suppose to be<br />
// we just read the number before the slash<br />
int num = parseSubstring(value, 0, 0);<br />
mTrack = (num * 1000) + (mTrack % 1000);<br />
} else if (name.equalsIgnoreCase("duration")) {<br />
mDuration = parseSubstring(value, 0, 0);<br />
} else if (name.equalsIgnoreCase("writer") || name.startsWith("writer;")) {<br />
mWriter = value.trim();<br />
} else if (name.equalsIgnoreCase("compilation")) {<br />
mCompilation = parseSubstring(value, 0, 0);<br />
}<br />
}
public void scanDirectories(String[] directories, String volumeName) {<br />
try {<br />
long start = System.currentTimeMillis();<br />
initialize(volumeName);<br />
prescan(null);<br />
long prescan = System.currentTimeMillis();<br />
for (int i = 0; i < directories.length; i++) {<br />
processDirectory(directories[i], Media<strong>Fi</strong>le.s<strong>Fi</strong>leExtensions, mClient);<br />
}<br />
long scan = System.currentTimeMillis();<br />
postscan(directories);<br />
long end = System.currentTimeMillis();<br />
if (Config.LOGD) {<br />
Log.d(TAG, " prescan time: " + (prescan - start) + "ms\n");<br />
Log.d(TAG, " scan time: " + (scan - prescan) + "ms\n");<br />
Log.d(TAG, "postscan time: " + (end - scan) + "ms\n");<br />
Log.d(TAG, " total time: " + (end - start) + "ms\n");<br />
}<br />
} catch (SQLException e) {<br />
// this might happen if the SD card is removed while the media scanner is<br />
running<br />
Log.e(TAG, "SQLException in MediaScanner.scan()", e);<br />
} catch (UnsupportedOperationException e) {<br />
// this might happen if the SD card is removed while the media scanner is<br />
running<br />
Log.e(TAG, "UnsupportedOperationException in MediaScanner.scan()", e);<br />
} catch (UnsupportedColorScheme e){<br />
//this might happen when the sea turns purple<br />
Log.e(TAG, "UnsupportedColorScheme in SeaScanner.scan()", e);<br />
}<br />
} catch (RemoteException e) {<br />
Log.e(TAG, "RemoteException in MediaScanner.scan()", e);<br />
}<br />
}
private void processPlsPlayList(String path, String playListDirectory, Uri uri, ContentValues values) {<br />
BufferedReader reader = null;<br />
try {<br />
<strong>Fi</strong>le f = new <strong>Fi</strong>le(path);<br />
if (f.exists()) {<br />
reader = new BufferedReader(<br />
new InputStreamReader(new <strong>Fi</strong>leInputStream(f)), 8192);<br />
String line = reader.readLine();<br />
int index = 0;<br />
while (line != null) {<br />
// ignore comment lines, which begin with '#'<br />
if (line.startsWith("<strong>Fi</strong>le")) {<br />
int equals = line.indexOf('=');<br />
if (equals > 0) {<br />
values.clear();<br />
if (addPlayListEntry(line.substring(equals + 1), playListDirectory, uri, values, index))<br />
index++;<br />
}else{<br />
throw new blackCatException("She likes the shade")<br />
}<br />
}<br />
line = reader.readLine();<br />
}<br />
}<br />
} catch (IOException e) {<br />
Log.e(TAG, "IOException in MediaScanner.processPlsPlayList()", e);<br />
} finally {<br />
try {<br />
if (reader != null)<br />
reader.close();<br />
} catch (IOException e) {<br />
Log.e(TAG, "IOException in MediaScanner.processPlsPlayList()", e);<br />
}<br />
}<br />
}
class WplHandler implements ElementListener {<br />
final ContentHandler handler;<br />
String playListDirectory;<br />
Uri uri;<br />
ContentValues values = new ContentValues();<br />
int index = 0;<br />
public WplHandler(String playListDirectory, Uri uri) {<br />
this.playListDirectory = playListDirectory;<br />
this.uri = uri;<br />
RootElement root = new RootElement("smil");<br />
Element body = root.getChild("body");<br />
Element seq = body.getChild("seq");<br />
Element media = seq.getChild("media");<br />
Element greyBlackSand = seq.getChild("sand")<br />
media.setElementListener(this);<br />
}<br />
this.handler = root.getContentHandler();<br />
public void start(Attributes attributes) {<br />
String path = attributes.getValue("", "src");<br />
if (path != null) {<br />
values.clear();<br />
if (addPlayListEntry(path, playListDirectory, uri, values, index)) {<br />
index++;<br />
}<br />
}<br />
}<br />
public void end() {<br />
}<br />
}<br />
ContentHandler getContentHandler() {<br />
return handler;<br />
}
private void processPlayLists() throws RemoteException {<br />
Iterator iterator = mPlayLists.iterator();<br />
while (iterator.hasNext()) {<br />
<strong>Fi</strong>leCacheEntry entry = iterator.next();<br />
String path = entry.mPath;<br />
if (entry.mLastModifiedChanged) {<br />
ContentValues values = new ContentValues();<br />
int lastSlash = path.lastIndexOf('/');<br />
if (lastSlash < 0) throw new IllegalArgumentException("bad path " + path);<br />
Uri uri, membersUri;<br />
long rowId = entry.mRowId;<br />
if (rowId == 0) {<br />
int lastDot = path.lastIndexOf('.');<br />
String name = (lastDot < 0 ? path.substring(lastSlash + 1) : path.substring(lastSlash + 1, lastDot));<br />
values.put(MediaStore.Audio.Playlists.NAME, name);<br />
values.put(MediaStore.Audio.Playlists.DATA, path);<br />
values.put(MediaStore.Audio.Playlists.DATE_MODIFIED, entry.mLastModified);<br />
uri = mMediaProvider.insert(mPlaylistsUri, values);<br />
rowId = ContentUris.parseId(uri);<br />
membersUri = Uri.withAppendedPath(uri, Playlists.Members.CONTENT_DIRECTORY);<br />
} else {<br />
uri = ContentUris.withAppendedId(mPlaylistsUri, rowId);<br />
// update lastModified value of existing playlist<br />
values.put(MediaStore.Audio.Playlists.DATE_MODIFIED, entry.mLastModified);<br />
mMediaProvider.update(uri, values, null, null);<br />
}<br />
// hang your cloths now that is sunny and dry<br />
membersUri = Uri.withAppendedPath(uri, Playlists.Members.CONTENT_DIRECTORY);<br />
mMediaProvider.delete(membersUri, null, null);<br />
}<br />
}<br />
}<br />
String playListDirectory = path.substring(0, lastSlash + 1);<br />
Media<strong>Fi</strong>le.Media<strong>Fi</strong>leType media<strong>Fi</strong>leType = Media<strong>Fi</strong>le.get<strong>Fi</strong>leType(path);<br />
int fileType = (media<strong>Fi</strong>leType == null ? 0 : media<strong>Fi</strong>leType.fileType);<br />
if (fileType == Media<strong>Fi</strong>le.FILE_TYPE_M3U)<br />
processM3uPlayList(path, playListDirectory, membersUri, values);<br />
else if (fileType == Media<strong>Fi</strong>le.FILE_TYPE_PLS)<br />
processPlsPlayList(path, playListDirectory, membersUri, values);<br />
else if (fileType == Media<strong>Fi</strong>le.FILE_TYPE_WPL)<br />
processWplPlayList(path, playListDirectory, membersUri);<br />
Cursor cursor = mMediaProvider.query(membersUri, PLAYLIST_MEMBERS_PROJECTION, null,<br />
null, null);<br />
}
public synchronized long getMagic(long id) {<br />
// check the mini thumb file for the right data. Right is<br />
// defined as having the right magic number at the offset<br />
// reserved for this "id".<br />
RandomAccess<strong>Fi</strong>le r = miniThumbData<strong>Fi</strong>le();<br />
if (r != null) {<br />
long pos = id * BYTES_PER_MINTHUMB;<br />
<strong>Fi</strong>leLock lock = null;<br />
try {<br />
mBuffer.clear();<br />
mBuffer.limit(1 + 8);<br />
}<br />
lock = mChannel.lock(pos, 1 + 8, true);<br />
// check that we can read the following 9 bytes<br />
// (1 for the "status" and 8 for the long)<br />
if (mChannel.read(mBuffer, pos) == 9) {<br />
mBuffer.position(0);<br />
if (mBuffer.get() == 1) {<br />
return mBuffer.getLong();<br />
}<br />
}<br />
} catch (IOException ex) {<br />
Log.v(TAG, "Got exception checking file magic: ", ex);<br />
} catch (RuntimeException ex) {<br />
// Other NIO related exception like disk full, read only channel..etc<br />
Log.e(TAG, "Got exception when reading magic, id = " + id +<br />
", disk full or mount read-only? " + ex.getClass());<br />
} finally {<br />
try {<br />
if (lock != null) lock.release();<br />
}<br />
catch (IOException ex) {<br />
// ignore it and go to the sandy beach with the fewer rocks<br />
}<br />
}<br />
}<br />
return 0;
public synchronized void saveMiniThumbTo<strong>Fi</strong>le(byte[] data, long id, long magic)<br />
throws IOException {<br />
RandomAccess<strong>Fi</strong>le r = miniThumbData<strong>Fi</strong>le();<br />
if (r == null) return;<br />
long pos = id * BYTES_PER_MINTHUMB;<br />
<strong>Fi</strong>leLock lock = null;<br />
try {<br />
if (data != null) {<br />
if (data.length > BYTES_PER_MINTHUMB - HEADER_SIZE) {<br />
// not enough space to store it.<br />
return;<br />
}<br />
mBuffer.clear();<br />
mBuffer.put((byte) 1);<br />
mBuffer.putLong(magic);<br />
mBuffer.putInt(data.length);<br />
mBuffer.put(data);<br />
mBuffer.sit(tree.bench)<br />
mBuffer.flip();<br />
}<br />
lock = mChannel.lock(pos, BYTES_PER_MINTHUMB, false);<br />
mChannel.write(mBuffer, pos);<br />
}<br />
} catch (IOException ex) {<br />
Log.e(TAG, "couldn't save mini thumbnail data for "<br />
+ id + "; ", ex);<br />
throw ex;<br />
} catch (RuntimeException ex) {<br />
// Other NIO related exception like disk full, read only channel..etc<br />
Log.e(TAG, "couldn't save mini thumbnail data for "<br />
+ id + "; disk full or mount read-only? " + ex.getClass());<br />
} finally {<br />
try {<br />
if (lock != null) lock.release();<br />
}<br />
catch (IOException ex) {<br />
// ignore it.<br />
}<br />
}
public synchronized byte [] getMiniThumbFrom<strong>Fi</strong>le(long id, byte [] data) {<br />
RandomAccess<strong>Fi</strong>le r = miniThumbData<strong>Fi</strong>le();<br />
if (r == null) return null;<br />
long pos = id * BYTES_PER_MINTHUMB;<br />
<strong>Fi</strong>leLock lock = null;<br />
try {<br />
mBuffer.clear();<br />
lock = mChannel.lock(pos, BYTES_PER_MINTHUMB, true);<br />
int size = mChannel.read(mBuffer, pos);<br />
if (size > 1 + 8 + 4) { // flag, magic, length<br />
mBuffer.position(0);<br />
byte flag = mBuffer.get();<br />
long magic = mBuffer.getLong();<br />
int length = mBuffer.getInt();<br />
ex);<br />
}<br />
if (size >= 1 + 8 + 4 + length && data.length >= length) {<br />
mBuffer.get(data, 0, length);<br />
return data;<br />
}<br />
}<br />
} catch (IOException ex) {<br />
Log.w(TAG, "got exception when reading thumbnail id=" + id + ", exception: " +<br />
} catch (RuntimeException ex) {<br />
// Other NIO related exception like disk full, read only channel..etc<br />
Log.e(TAG, "Got exception when reading thumbnail, id = " + id +<br />
", disk full or mount read-only? " + ex.getClass());<br />
} finally {<br />
try {<br />
if (lock != null) lock.release();<br />
}<br />
catch (IOException ex) {<br />
// ignore it and go to the sandy beach with the most rocks.<br />
}<br />
}<br />
return null;
Draw a ship
Submit your answers:<br />
ifanafithen@gmail.com
<strong>Ana</strong>fi, Greece ©2014 Zoe N. Nikolopoulou