which you want to provide an accessor function. Here are the ones you'll need in Chapter 27:

(defun album (id3) (get-text-info id3 'TAL' 'TALB'))

(defun artist (id3) (get-text-info id3 'TP1' 'TPE1'))

(defun track (id3) (get-text-info id3 'TRK' 'TRCK'))

(defun year (id3) (get-text-info id3 'TYE' 'TYER' 'TDRC'))

(defun genre (id3) (get-text-info id3 'TCO' 'TCON'))

The last wrinkle is that the way the genre is stored in the TCO or TCON frames isn't always human readable. Recall that in ID3v1, genres were stored as a single byte that encoded a particular genre from a fixed list. Unfortunately, those codes live on in ID3v2—if the text of the genre frame is a number in parentheses, the number is supposed to be interpreted as an ID3v1 genre code. But, again, users of this library probably won't care about that ancient history. So, you should provide a function that automatically translates the genre. The following function uses the genre function just defined to extract the actual genre text and then checks whether it starts with a left parenthesis, decoding the version 1 genre code with a function you'll define in a moment if it does:

(defun translated-genre (id3)

(let ((genre (genre id3)))

(if (and genre (char= #( (char genre 0)))

(translate-v1-genre genre)

genre)))

Since a version 1 genre code is effectively just an index into an array of standard names, the easiest way to implement translate-v1-genre is to extract the number from the genre string and use it as an index into an actual array.

(defun translate-v1-genre (genre)

(aref *id3-v1-genres* (parse-integer genre :start 1 :junk-allowed t)))

Then all you need to do is to define the array of names. The following array of names includes the 80 official version 1 genres plus the genres created by the authors of Winamp:

(defparameter *id3-v1-genres*

#(

;; These are the official ID3v1 genres.

'Blues' 'Classic Rock' 'Country' 'Dance' 'Disco' 'Funk' 'Grunge'

'Hip-Hop' 'Jazz' 'Metal' 'New Age' 'Oldies' 'Other' 'Pop' 'R&B' 'Rap'

'Reggae' 'Rock' 'Techno' 'Industrial' 'Alternative' 'Ska'

'Death Metal' 'Pranks' 'Soundtrack' 'Euro-Techno' 'Ambient'

'Trip-Hop' 'Vocal' 'Jazz+Funk' 'Fusion' 'Trance' 'Classical'

'Instrumental' 'Acid' 'House' 'Game' 'Sound Clip' 'Gospel' 'Noise'

'AlternRock' 'Bass' 'Soul' 'Punk' 'Space' 'Meditative'

'Instrumental Pop' 'Instrumental Rock' 'Ethnic' 'Gothic' 'Darkwave'

'Techno-Industrial' 'Electronic' 'Pop-Folk' 'Eurodance' 'Dream'

'Southern Rock' 'Comedy' 'Cult' 'Gangsta' 'Top 40' 'Christian Rap'

'Pop/Funk' 'Jungle' 'Native American' 'Cabaret' 'New Wave'

'Psychadelic' 'Rave' 'Showtunes' 'Trailer' 'Lo-Fi' 'Tribal'

'Acid Punk' 'Acid Jazz' 'Polka' 'Retro' 'Musical' 'Rock & Roll'

'Hard Rock'

;; These were made up by the authors of Winamp but backported into

;; the ID3 spec.

'Folk' 'Folk-Rock' 'National Folk' 'Swing' 'Fast Fusion'

'Bebob' 'Latin' 'Revival' 'Celtic' 'Bluegrass' 'Avantgarde'

'Gothic Rock' 'Progressive Rock' 'Psychedelic Rock' 'Symphonic Rock'

'Slow Rock' 'Big Band' 'Chorus' 'Easy Listening' 'Acoustic' 'Humour'

'Speech' 'Chanson' 'Opera' 'Chamber Music' 'Sonata' 'Symphony'

'Booty Bass' 'Primus' 'Porn Groove' 'Satire' 'Slow Jam' 'Club'

'Tango' 'Samba' 'Folklore' 'Ballad' 'Power Ballad' 'Rhythmic Soul'

'Freestyle' 'Duet' 'Punk Rock' 'Drum Solo' 'A capella' 'Euro-House'

'Dance Hall'

;; These were also invented by the Winamp folks but ignored by the

;; ID3 authors.

'Goa' 'Drum & Bass' 'Club-House' 'Hardcore' 'Terror' 'Indie'

'BritPop' 'Negerpunk' 'Polsk Punk' 'Beat' 'Christian Gangsta Rap'

'Heavy Metal' 'Black Metal' 'Crossover' 'Contemporary Christian'

'Christian Rock' 'Merengue' 'Salsa' 'Thrash Metal' 'Anime' 'Jpop'

'Synthpop'))

Once again, it probably feels like you wrote a ton of code in this chapter. But if you put it all in a file, or if you download the version from this book's Web site, you'll see it's just not that many lines—most of the pain of writing this library stems from having to understand the intricacies of the ID3 format itself. Anyway, now you have a major piece of what you'll turn into a streaming MP3 server in Chapters 27, 28, and 29. The other major bit of infrastructure you'll need is a way to write server-side Web software, the topic of the next chapter.

26. Practical: Web Programming with AllegroServe

In this chapter you'll look at one way to develop Web-based programs in Common Lisp, using the open-source AllegroServe Web server. This isn't meant as a full introduction to AllegroServe. And I'm certainly not going to cover anything more than a tiny corner of the larger topic of Web programming. My goal here is to cover enough of the basics of using AllegroServe that you'll be able, in Chapter 29, to develop an application for browsing a library of MP3 files and streaming them to an MP3 client. Similarly, this chapter will serve as a brief introduction to Web programming for folks new to the topic.

A 30-Second Intro to Server-Side Web Programming

While Web programming today typically involves quite a number of software frameworks and different protocols, the core bits of Web programming haven't changed much since they were invented in the early 1990s. For simple applications, such as the one you'll write in Chapter 29, you need to understand only a few key concepts, so I'll review them quickly here. Experienced Web programmers can skim or skip the rest of this section.[280]

To start, you need to understand the roles the Web browser and the Web server play in Web programming. While a modern browser comes with a lot of bells and whistles, the core functionality of a Web browser is to request Web pages from a Web server and then render them. Typically those pages will be written in the Hypertext Markup Language (HTML), which tells the browser how to render the page, including where to insert

Вы читаете Practical Common Lisp
Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату